-
Notifications
You must be signed in to change notification settings - Fork 3
/
components.tsx
139 lines (117 loc) · 4.28 KB
/
components.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import * as Fabric from '@centrifuge/fabric'
import * as FabricFlex from '@centrifuge/fabric/dist/components/Flex'
import React, { AnchorHTMLAttributes } from 'react'
import styled, { DefaultTheme } from 'styled-components'
import { ColorProps, system, TypographyProps } from 'styled-system'
export function forwardAs<T, P>(
Component: React.ComponentType<P & { forwardedAs?: T }>
): React.ComponentType<P & { as?: T }> {
return ({ as, ...rest }: any) => <Component forwardedAs={as as any} {...rest} />
}
// Box
export interface BoxProps extends Omit<React.HTMLAttributes<never>, 'color'>, Fabric.StyledBoxProps {
as?: string | React.ComponentType
transform?: string
children?: React.ReactNode
}
export const Box = styled(Fabric.Box)<BoxProps>(system({ transform: true }))
// Layout
export interface ContainerProps extends Fabric.ContainerProps {
children?: React.ReactNode
}
export const Container: React.ComponentType<ContainerProps> = Fabric.Container
export interface FlexProps extends FabricFlex.FlexProps {
children?: React.ReactNode
}
export const Flex: React.ComponentType<FlexProps> = FabricFlex.Flex
export interface GridProps extends Fabric.GridProps {
children?: React.ReactNode
}
export const Grid: React.ComponentType<GridProps> = Fabric.Grid
// Text
export interface TextProps extends TypographyProps, ColorProps {
as?: string | React.ComponentType
cursor?: string
textDecoration?: string
whiteSpace?: string
children?: React.ReactNode
}
export const Text = forwardAs(
styled(({ as = 'span', ...rest }: TextProps) => {
return <Fabric.Text as={as} {...rest} />
})<TextProps>(system({ cursor: true, whiteSpace: true, textDecoration: true }))
)
export const span = Text
// Paragraph
export type ParagraphProps = BoxProps & {
Text?: React.ComponentType<TextProps>
variant?: keyof DefaultTheme['typography']
}
export function Paragraph(props: ParagraphProps) {
const { Text: TextComponent = Text, variant = `body1`, children, ...rest } = props
return (
<Box as="p" my={[1, 2]} {...rest}>
<TextComponent variant={variant}>{children}</TextComponent>
</Box>
)
}
export const p = Paragraph
// Headings
export type HeadingProps = BoxProps & {
Text?: React.ComponentType<TextProps>
as?: string | React.ComponentType
variant?: keyof DefaultTheme['typography']
badge?: React.ReactNode
}
export function Heading(props: HeadingProps) {
const { Text: TextComponent = Text, as = `h2`, variant = `heading2`, badge, children, ...rest } = props
return (
<Box as={as} position="relative" m={0} mb={2} {...rest}>
<TextComponent variant={variant}>{children}</TextComponent>
{badge}
</Box>
)
}
export const h1 = (props: BoxProps) => <Heading as="h1" variant="heading1" {...props} />
export const h2 = (props: BoxProps) => <Heading as="h2" variant="heading2" {...props} />
export const h3 = (props: BoxProps) => <Heading as="h3" variant="heading3" {...props} />
export const h4 = (props: BoxProps) => <Heading as="h4" variant="heading4" {...props} />
export const h5 = (props: BoxProps) => <Heading as="h5" variant="heading5" {...props} />
export const h6 = (props: BoxProps) => <Heading as="h6" variant="heading6" {...props} />
// Links
export interface LinkProps extends TextProps, Omit<AnchorHTMLAttributes<'a'>, 'color'> {}
export function Link(props: LinkProps) {
return <Text as="a" cursor="pointer" textDecoration="underline" {...props} />
}
export const a = Link
// Images
export interface ImageProps
extends Fabric.StyledBoxProps,
Omit<React.ImgHTMLAttributes<never>, 'width' | 'height' | 'color'> {
as?: string | React.ComponentType
transform?: string
children?: React.ReactNode
}
export function Image(props: ImageProps) {
return <Box as="img" {...props} />
}
export const img = Image
// Lists
export type ListProps = BoxProps
export function List(props: ListProps) {
return <Box as="ul" {...props} />
}
export const ul = List
export type ItemProps = BoxProps & {
Text?: React.ComponentType<TextProps>
}
export function Item({ Text: TextComponent = Text, children, ...rest }: ItemProps) {
return (
<Box as="li" {...rest}>
<TextComponent>{children}</TextComponent>
</Box>
)
}
export const li = Item
// Export component shortcodes for MDX integration
export const shortcodes = { h1, h2, h3, h4, h5, h6, span, a, p, img, ul, li }