1import React, { ComponentType, forwardRef } from 'react';
2import { StyleSheet } from 'react-native';
3
4import { em } from '../css/units';
5import Text, { TextProps } from '../primitives/Text';
6import View, { ViewProps } from '../primitives/View';
7import { BlockQuoteProps, QuoteProps, TimeProps } from './Text.types';
8
9export const P = forwardRef(({ style, ...props }: TextProps, ref) => {
10  return <Text {...props} style={[styles.p, style]} ref={ref} />;
11}) as ComponentType<TextProps>;
12
13export const B = forwardRef(({ style, ...props }: TextProps, ref) => {
14  return <P {...props} style={[styles.b, style]} ref={ref} />;
15}) as ComponentType<TextProps>;
16
17export const S = forwardRef(({ style, ...props }: TextProps, ref) => {
18  return <P {...props} style={[styles.s, style]} ref={ref} />;
19}) as ComponentType<TextProps>;
20
21export const I = forwardRef(({ style, ...props }: TextProps, ref) => {
22  return <P {...props} style={[styles.i, style]} ref={ref} />;
23}) as ComponentType<TextProps>;
24
25export const Q = forwardRef(({ children, cite, style, ...props }: QuoteProps, ref) => {
26  return (
27    <P {...props} style={[styles.q, style]} ref={ref}>
28      "{children}"
29    </P>
30  );
31}) as ComponentType<QuoteProps>;
32
33export const BlockQuote = forwardRef(({ style, cite, ...props }: BlockQuoteProps, ref) => {
34  return <View {...props} style={[styles.blockQuote, style]} ref={ref} />;
35}) as ComponentType<BlockQuoteProps>;
36
37export const BR = forwardRef(({ style, ...props }: TextProps, ref) => {
38  return <Text {...props} style={[styles.br, style]} ref={ref} />;
39}) as ComponentType<TextProps>;
40
41export const Small = forwardRef(({ style, ...props }: TextProps, ref) => {
42  return <Text {...props} style={[styles.small, style]} ref={ref} />;
43}) as ComponentType<TextProps>;
44
45export const Mark = forwardRef(({ style, ...props }: TextProps, ref) => {
46  return <Text {...props} style={[styles.mark, style]} ref={ref} />;
47}) as ComponentType<TextProps>;
48
49export const Code = forwardRef(({ style, ...props }: TextProps, ref) => {
50  return <Text {...props} style={[styles.code, style]} ref={ref} />;
51}) as ComponentType<TextProps>;
52
53function isTextProps(props: any): props is TextProps {
54  return typeof props.children === 'string';
55}
56
57type PreProps = TextProps | ViewProps;
58
59export const Pre = forwardRef((props: PreProps, ref: any) => {
60  if (isTextProps(props)) {
61    return <Text {...props} style={[styles.code, styles.pre, props.style]} ref={ref} />;
62  }
63  return <View {...props} style={[styles.pre, props.style]} ref={ref} />;
64}) as ComponentType<PreProps>;
65
66// Extract dateTime to prevent passing it to the native Text element
67export const Time = forwardRef(({ dateTime, ...props }: TimeProps, ref) => {
68  return <Text {...props} ref={ref} />;
69}) as ComponentType<TimeProps>;
70
71export const Strong = B;
72export const Del = S;
73export const EM = I;
74
75const styles = StyleSheet.create({
76  p: {
77    marginVertical: em(1),
78    fontSize: em(1),
79  },
80  b: {
81    fontWeight: 'bold',
82  },
83  q: {
84    fontStyle: 'italic',
85  },
86  code: {
87    fontFamily: 'Courier',
88    fontWeight: '500',
89  },
90  pre: {
91    marginVertical: em(1),
92  },
93  blockQuote: {
94    marginVertical: em(1),
95  },
96  br: {
97    width: 0,
98    height: 8,
99  },
100  small: {
101    fontSize: 12,
102  },
103  s: {
104    textDecorationLine: 'line-through',
105    textDecorationStyle: 'solid',
106  },
107  mark: {
108    backgroundColor: 'yellow',
109    color: 'black',
110  },
111  i: {
112    fontStyle: 'italic',
113  },
114});
115