@graphcommerce/graphcms-ui 9.0.0-canary.99 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -939
- package/index.ts +1 -3
- package/package.json +2 -12
- package/Config.graphqls +0 -17
- package/README.md +0 -4
- package/components/Asset/Asset.graphql +0 -7
- package/components/Asset/Asset.tsx +0 -59
- package/components/RichText/RichText.tsx +0 -199
- package/components/RichText/defaultRenderers.tsx +0 -58
- package/components/RichText/defaultSxRenderer.ts +0 -108
- package/components/RichText/getNodeLength.tsx +0 -11
- package/components/RichText/index.ts +0 -2
- package/components/RichText/types.ts +0 -117
- package/components/index.ts +0 -2
- package/graphql/HygraphAllPages.graphql +0 -11
- package/graphql/HygraphPage.graphql +0 -16
- package/graphql/HygraphPages.graphql +0 -7
- package/graphql/HygraphStaticPaths.graphql +0 -11
- package/graphql/PageLink.graphql +0 -10
- package/graphql/PagesStaticPaths.graphql +0 -6
- package/graphql/index.ts +0 -5
- package/lib/getAllHygraphPages.ts +0 -43
- package/lib/getHygraphPaths.ts +0 -43
- package/lib/hygraphPageContent.ts +0 -48
- package/lib/index.ts +0 -2
- package/plugins/HygraphPreviewModeToolbar.tsx +0 -80
- package/plugins/hygraphGraphqlConfig.ts +0 -35
- package/plugins/hygraphPreviewModeDefaults.ts +0 -12
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/graphcms-ui",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "9.0.0
|
|
5
|
+
"version": "9.0.0",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -12,16 +12,6 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@graphcommerce/
|
|
16
|
-
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.99",
|
|
17
|
-
"@graphcommerce/graphql": "^9.0.0-canary.99",
|
|
18
|
-
"@graphcommerce/image": "^9.0.0-canary.99",
|
|
19
|
-
"@graphcommerce/next-ui": "^9.0.0-canary.99",
|
|
20
|
-
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.99",
|
|
21
|
-
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.99",
|
|
22
|
-
"@mui/material": "^5.10.16",
|
|
23
|
-
"next": "*",
|
|
24
|
-
"react": "^18.2.0",
|
|
25
|
-
"react-dom": "^18.2.0"
|
|
15
|
+
"@graphcommerce/hygraph-ui": "^9.0.0"
|
|
26
16
|
}
|
|
27
17
|
}
|
package/Config.graphqls
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
extend input GraphCommerceConfig {
|
|
2
|
-
"""
|
|
3
|
-
The HyGraph endpoint.
|
|
4
|
-
|
|
5
|
-
> Read-only endpoint that allows low latency and high read-throughput content delivery.
|
|
6
|
-
|
|
7
|
-
Project settings -> API Access -> High Performance Read-only Content API
|
|
8
|
-
"""
|
|
9
|
-
hygraphEndpoint: String!
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
extend input GraphCommerceStorefrontConfig {
|
|
13
|
-
"""
|
|
14
|
-
Add a gcms-locales header to make sure queries return in a certain language, can be an array to define fallbacks.
|
|
15
|
-
"""
|
|
16
|
-
hygraphLocales: [String!]
|
|
17
|
-
}
|
package/README.md
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Image, ImageProps } from '@graphcommerce/image'
|
|
2
|
-
import { styled, SxProps, Theme } from '@mui/material'
|
|
3
|
-
import { memo } from 'react'
|
|
4
|
-
import { AssetFragment } from './Asset.gql'
|
|
5
|
-
|
|
6
|
-
export type { AssetFragment } from './Asset.gql'
|
|
7
|
-
|
|
8
|
-
type ImageAsset = Omit<AssetFragment, 'width' | 'height'> & {
|
|
9
|
-
width: number
|
|
10
|
-
height: number
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function isImage(asset: AssetFragment): asset is ImageAsset {
|
|
14
|
-
return !!(asset.width && asset.height)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type AssetProps = {
|
|
18
|
-
asset: AssetFragment
|
|
19
|
-
sx?: SxProps<Theme>
|
|
20
|
-
} & Omit<ImageProps, 'src' | 'width' | 'height' | 'alt' | 'sx'>
|
|
21
|
-
|
|
22
|
-
export const Asset = memo<AssetProps>((props) => {
|
|
23
|
-
const { asset, sx = [], ...imgProps } = props
|
|
24
|
-
|
|
25
|
-
if (isImage(asset)) {
|
|
26
|
-
const { url, height, mimeType, size, width, alt, ...assetProps } = asset
|
|
27
|
-
return (
|
|
28
|
-
<Image
|
|
29
|
-
src={url}
|
|
30
|
-
height={height}
|
|
31
|
-
width={width}
|
|
32
|
-
alt={alt ?? undefined}
|
|
33
|
-
{...imgProps}
|
|
34
|
-
{...assetProps}
|
|
35
|
-
unoptimized={mimeType === 'image/svg+xml'}
|
|
36
|
-
sx={[...(Array.isArray(sx) ? sx : [sx])]}
|
|
37
|
-
/>
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (asset.mimeType === 'video/mp4') {
|
|
42
|
-
const Video = styled('video')({})
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<Video
|
|
46
|
-
src={asset.url}
|
|
47
|
-
autoPlay
|
|
48
|
-
muted
|
|
49
|
-
loop
|
|
50
|
-
playsInline
|
|
51
|
-
disableRemotePlayback
|
|
52
|
-
sx={[...(Array.isArray(sx) ? sx : [sx])]}
|
|
53
|
-
/>
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (process.env.NODE_ENV !== 'production') return <div>{asset.mimeType} not supported</div>
|
|
58
|
-
return null
|
|
59
|
-
})
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
|
-
import { SxProps, Theme } from '@mui/material'
|
|
3
|
-
import React from 'react'
|
|
4
|
-
import { defaultRenderers } from './defaultRenderers'
|
|
5
|
-
import { defaultSxRenderer } from './defaultSxRenderer'
|
|
6
|
-
import {
|
|
7
|
-
AdditionalProps,
|
|
8
|
-
Renderers,
|
|
9
|
-
Renderer,
|
|
10
|
-
SxRenderer,
|
|
11
|
-
TextNode,
|
|
12
|
-
ElementOrTextNode,
|
|
13
|
-
ElementNode,
|
|
14
|
-
SimpleElement,
|
|
15
|
-
} from './types'
|
|
16
|
-
|
|
17
|
-
const sxArr = (sxAny?: SxProps<Theme> | false) => {
|
|
18
|
-
if (!sxAny) return []
|
|
19
|
-
return Array.isArray(sxAny) ? sxAny : [sxAny]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function useRenderProps(
|
|
23
|
-
{ first, last, sxRenderer }: Pick<AdditionalProps, 'first' | 'last' | 'sxRenderer'>,
|
|
24
|
-
type?: ElementNode['type'],
|
|
25
|
-
) {
|
|
26
|
-
if (!type) return []
|
|
27
|
-
const sx: SxProps<Theme> = sxRenderer?.[type] ?? []
|
|
28
|
-
|
|
29
|
-
return [
|
|
30
|
-
...sxArr(sxRenderer.all),
|
|
31
|
-
...sxArr(sx),
|
|
32
|
-
...sxArr(first && sxRenderer.first),
|
|
33
|
-
...sxArr(last && sxRenderer.last),
|
|
34
|
-
]
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function LineBreakToBr(props: { text: string }) {
|
|
38
|
-
const { text } = props
|
|
39
|
-
|
|
40
|
-
const textA = text.split('\n')
|
|
41
|
-
const textArray: React.ReactNode[] = []
|
|
42
|
-
textA.forEach((val, index) => {
|
|
43
|
-
textArray.push(val)
|
|
44
|
-
if (index < textA.length - 1) textArray.push(<br />)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
// eslint-disable-next-line react/no-array-index-key
|
|
48
|
-
return textArray.map((val, idx) => <React.Fragment key={idx}>{val}</React.Fragment>)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function RenderText({
|
|
52
|
-
text,
|
|
53
|
-
renderers,
|
|
54
|
-
sxRenderer,
|
|
55
|
-
first,
|
|
56
|
-
last,
|
|
57
|
-
...textProps
|
|
58
|
-
}: TextNode & AdditionalProps) {
|
|
59
|
-
let type: 'bold' | 'italic' | 'underlined' | undefined
|
|
60
|
-
|
|
61
|
-
if (textProps.bold) type = 'bold'
|
|
62
|
-
if (textProps.italic) type = 'italic'
|
|
63
|
-
if (textProps.underlined) type = 'underlined'
|
|
64
|
-
|
|
65
|
-
const sx = useRenderProps({ first, last, sxRenderer }, type)
|
|
66
|
-
|
|
67
|
-
if (!type) return <LineBreakToBr text={text} />
|
|
68
|
-
const Component: Renderer<SimpleElement> = renderers[type]
|
|
69
|
-
return (
|
|
70
|
-
<Component sx={sx}>
|
|
71
|
-
<LineBreakToBr text={text} />
|
|
72
|
-
</Component>
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function isTextNode(node: ElementOrTextNode): node is TextNode {
|
|
77
|
-
return (node as TextNode).text !== undefined
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function isElementNode(node: ElementOrTextNode): node is ElementNode {
|
|
81
|
-
return (node as ElementNode).children !== undefined
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function RenderNode(node: ElementOrTextNode & AdditionalProps) {
|
|
85
|
-
if (isTextNode(node)) {
|
|
86
|
-
return <RenderText {...node} />
|
|
87
|
-
}
|
|
88
|
-
if (isElementNode(node)) {
|
|
89
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
90
|
-
return <RenderElement {...node} />
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
94
|
-
console.error(node)
|
|
95
|
-
throw Error(`RichText: Node not recognized`)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return null
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function RenderChildren({
|
|
102
|
-
childNodes,
|
|
103
|
-
noMargin,
|
|
104
|
-
...props
|
|
105
|
-
}: { childNodes: ElementNode['children']; noMargin?: boolean } & AdditionalProps) {
|
|
106
|
-
return (
|
|
107
|
-
<>
|
|
108
|
-
{childNodes.map((node, key) => (
|
|
109
|
-
<RenderNode
|
|
110
|
-
{...node}
|
|
111
|
-
{...props}
|
|
112
|
-
// Since we don't know any unique identifiers of the element and since this doesn't rerender often this is fine.
|
|
113
|
-
// eslint-disable-next-line react/no-array-index-key
|
|
114
|
-
key={key}
|
|
115
|
-
first={noMargin && key === 0}
|
|
116
|
-
last={noMargin && key === childNodes.length - 1}
|
|
117
|
-
/>
|
|
118
|
-
))}
|
|
119
|
-
</>
|
|
120
|
-
)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function RenderElement(element: ElementNode & AdditionalProps) {
|
|
124
|
-
const { type, children, sxRenderer, renderers, first, last, ...props } = element
|
|
125
|
-
|
|
126
|
-
// todo: this has the any type, could be improved
|
|
127
|
-
const Component: Renderer<SimpleElement> = renderers[type]
|
|
128
|
-
const sx = useRenderProps({ first, last, sxRenderer }, type)
|
|
129
|
-
|
|
130
|
-
if (Component) {
|
|
131
|
-
return (
|
|
132
|
-
<Component {...props} sx={sx}>
|
|
133
|
-
<RenderChildren childNodes={children} sxRenderer={sxRenderer} renderers={renderers} />
|
|
134
|
-
</Component>
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
139
|
-
console.error(element)
|
|
140
|
-
throw Error(`RichText: Unknown Element: ${type}`)
|
|
141
|
-
}
|
|
142
|
-
return <RenderChildren childNodes={children} sxRenderer={sxRenderer} renderers={renderers} />
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function mergeSxRenderer(base: SxRenderer, sxRenderer?: SxRenderer) {
|
|
146
|
-
if (!sxRenderer) return base
|
|
147
|
-
|
|
148
|
-
return Object.fromEntries(
|
|
149
|
-
Object.entries<SxProps<Theme>>(base).map(([key, sx]) => {
|
|
150
|
-
const sxOverride: SxProps<Theme> = sxRenderer?.[key]
|
|
151
|
-
|
|
152
|
-
return sxOverride
|
|
153
|
-
? [
|
|
154
|
-
key,
|
|
155
|
-
[
|
|
156
|
-
...(Array.isArray(sx) ? sx : [sx]),
|
|
157
|
-
...(Array.isArray(sxOverride) ? sxOverride : [sxOverride]),
|
|
158
|
-
],
|
|
159
|
-
]
|
|
160
|
-
: [key, sx]
|
|
161
|
-
}),
|
|
162
|
-
) as SxRenderer
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export type RichTextProps = { raw: ElementNode } & {
|
|
166
|
-
renderers?: Partial<Renderers>
|
|
167
|
-
/**
|
|
168
|
-
* Allows you to theme all the types of components
|
|
169
|
-
*
|
|
170
|
-
* ```tsx
|
|
171
|
-
* function MyComponent()f {
|
|
172
|
-
* return <RichText
|
|
173
|
-
* sxRenderer={{
|
|
174
|
-
* paragraph: (theme) => ({
|
|
175
|
-
* columnCount: { xs: 1, md: getColumnCount(props, 2) },
|
|
176
|
-
* columnGap: theme.spacings.md,
|
|
177
|
-
* }),
|
|
178
|
-
* //other props here
|
|
179
|
-
* }}
|
|
180
|
-
* />
|
|
181
|
-
* }
|
|
182
|
-
* ```
|
|
183
|
-
*/
|
|
184
|
-
sxRenderer?: SxRenderer
|
|
185
|
-
|
|
186
|
-
/** By default the component will render the first and last element without any margins */
|
|
187
|
-
withMargin?: boolean
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export function RichText({ raw, sxRenderer, renderers, withMargin = false }: RichTextProps) {
|
|
191
|
-
return (
|
|
192
|
-
<RenderChildren
|
|
193
|
-
childNodes={raw.children}
|
|
194
|
-
sxRenderer={mergeSxRenderer(defaultSxRenderer, sxRenderer)}
|
|
195
|
-
renderers={{ ...defaultRenderers, ...renderers }}
|
|
196
|
-
noMargin={!withMargin}
|
|
197
|
-
/>
|
|
198
|
-
)
|
|
199
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Box, Typography, Link } from '@mui/material'
|
|
2
|
-
import { Asset } from '../Asset/Asset'
|
|
3
|
-
import { Renderers } from './types'
|
|
4
|
-
|
|
5
|
-
export const defaultRenderers: Renderers = {
|
|
6
|
-
'heading-one': (props) => <Typography variant='h1' {...props} />,
|
|
7
|
-
'heading-two': (props) => <Typography variant='h2' {...props} />,
|
|
8
|
-
'heading-three': (props) => <Typography variant='h3' {...props} />,
|
|
9
|
-
'heading-four': (props) => <Typography variant='h4' {...props} />,
|
|
10
|
-
'heading-five': (props) => <Typography variant='h5' {...props} />,
|
|
11
|
-
'heading-six': (props) => <Typography variant='h6' {...props} />,
|
|
12
|
-
paragraph: (props) => <Typography variant='body1' gutterBottom {...props} />,
|
|
13
|
-
'bulleted-list': (props) => <Box component='ul' {...props} />,
|
|
14
|
-
'numbered-list': (props) => <Box component='ol' {...props} />,
|
|
15
|
-
'list-item': (props) => <Box component='li' {...props} />,
|
|
16
|
-
'list-item-child': (props) => <Box component='span' {...props} />,
|
|
17
|
-
'block-quote': (props) => <Box component='blockquote' {...props} />,
|
|
18
|
-
iframe: (props) => {
|
|
19
|
-
const { url, width, height, sx = [] } = props
|
|
20
|
-
return (
|
|
21
|
-
// todo add security attributes to iframe
|
|
22
|
-
// todo make iframe responsive (generic IFrame component?)
|
|
23
|
-
<Box
|
|
24
|
-
component='iframe'
|
|
25
|
-
src={url}
|
|
26
|
-
loading='lazy'
|
|
27
|
-
sx={[
|
|
28
|
-
{ aspectRatio: `${width} / ${height}`, width: '100%' },
|
|
29
|
-
...(Array.isArray(sx) ? sx : [sx]),
|
|
30
|
-
]}
|
|
31
|
-
/>
|
|
32
|
-
)
|
|
33
|
-
},
|
|
34
|
-
image: ({ src, width, height, title, altText, mimeType, sx }) => (
|
|
35
|
-
<Box sx={sx}>
|
|
36
|
-
<Asset asset={{ url: src, alt: altText ?? title, width, height, mimeType }} />
|
|
37
|
-
</Box>
|
|
38
|
-
),
|
|
39
|
-
video: ({ src, width, height, title, mimeType, sx }) => (
|
|
40
|
-
<Box sx={sx}>
|
|
41
|
-
<Asset asset={{ url: src, alt: title, width, height, mimeType }} />
|
|
42
|
-
</Box>
|
|
43
|
-
),
|
|
44
|
-
link: ({ href, openInNewTab, ...props }) => (
|
|
45
|
-
<Link href={href} underline='hover' {...props} target={openInNewTab ? '_blank' : undefined} />
|
|
46
|
-
),
|
|
47
|
-
table: (props) => <Box component='table' {...props} />,
|
|
48
|
-
table_head: (props) => <Box component='thead' {...props} />,
|
|
49
|
-
table_header_cell: (props) => <Box component='th' {...props} />,
|
|
50
|
-
table_body: (props) => <Box component='tbody' {...props} />,
|
|
51
|
-
table_row: (props) => <Box component='tr' {...props} />,
|
|
52
|
-
table_cell: (props) => <Box component='td' {...props} />,
|
|
53
|
-
code: (props) => <Box component='code' {...props} />,
|
|
54
|
-
bold: (props) => <Box component='strong' fontWeight='bold' {...props} />,
|
|
55
|
-
italic: (props) => <Box component='em' fontStyle='italic' {...props} />,
|
|
56
|
-
underlined: (props) => <Box component='span' {...props} />,
|
|
57
|
-
class: (props) => <Box component='div' {...props} />,
|
|
58
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { SxRenderer } from './types'
|
|
2
|
-
|
|
3
|
-
export const defaultSxRenderer: SxRenderer = {
|
|
4
|
-
all: {
|
|
5
|
-
'&:empty:not(iframe)': {
|
|
6
|
-
display: 'none',
|
|
7
|
-
},
|
|
8
|
-
},
|
|
9
|
-
first: {
|
|
10
|
-
marginTop: 0,
|
|
11
|
-
},
|
|
12
|
-
last: {
|
|
13
|
-
marginBottom: 0,
|
|
14
|
-
},
|
|
15
|
-
paragraph: {
|
|
16
|
-
marginBottom: '1em',
|
|
17
|
-
wordBreak: 'break-word',
|
|
18
|
-
},
|
|
19
|
-
'heading-one': {
|
|
20
|
-
marginTop: '0.5em',
|
|
21
|
-
marginBottom: '0.5em',
|
|
22
|
-
},
|
|
23
|
-
'heading-two': {
|
|
24
|
-
marginTop: '0.5em',
|
|
25
|
-
marginBottom: '0.5em',
|
|
26
|
-
},
|
|
27
|
-
'heading-three': {
|
|
28
|
-
marginTop: '0.5em',
|
|
29
|
-
marginBottom: '0.5em',
|
|
30
|
-
},
|
|
31
|
-
'heading-four': {
|
|
32
|
-
marginTop: '0.5em',
|
|
33
|
-
marginBottom: '0.5em',
|
|
34
|
-
},
|
|
35
|
-
'heading-five': {
|
|
36
|
-
marginTop: '0.5em',
|
|
37
|
-
marginBottom: '0.5em',
|
|
38
|
-
},
|
|
39
|
-
image: {
|
|
40
|
-
width: '100%',
|
|
41
|
-
height: 'auto',
|
|
42
|
-
},
|
|
43
|
-
video: {
|
|
44
|
-
width: '100%',
|
|
45
|
-
height: 'auto',
|
|
46
|
-
},
|
|
47
|
-
'block-quote': (theme) => ({
|
|
48
|
-
paddingLeft: theme.spacings.sm,
|
|
49
|
-
margin: `${theme.spacings.md} 0`,
|
|
50
|
-
}),
|
|
51
|
-
'bulleted-list': {
|
|
52
|
-
marginBottom: '1em',
|
|
53
|
-
},
|
|
54
|
-
'numbered-list': {
|
|
55
|
-
marginBottom: '1em',
|
|
56
|
-
},
|
|
57
|
-
code: {
|
|
58
|
-
width: 'fit-content',
|
|
59
|
-
maxWidth: '100%',
|
|
60
|
-
padding: 5,
|
|
61
|
-
overflow: 'scroll',
|
|
62
|
-
},
|
|
63
|
-
table: (theme) => ({
|
|
64
|
-
display: 'table',
|
|
65
|
-
width: '100%',
|
|
66
|
-
borderSpacing: '2px',
|
|
67
|
-
borderCollapse: 'collapse',
|
|
68
|
-
marginTop: theme.spacings.md,
|
|
69
|
-
marginBottom: theme.spacings.sm,
|
|
70
|
-
'& thead, tbody': {
|
|
71
|
-
'& td': {
|
|
72
|
-
padding: '10px 20px',
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
'& thead': {
|
|
76
|
-
'& tr': {
|
|
77
|
-
'& td': {
|
|
78
|
-
'& p': {
|
|
79
|
-
fontWeight: theme.typography.fontWeightBold,
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
'& tbody': {
|
|
85
|
-
display: 'table-row-group',
|
|
86
|
-
verticalAlign: 'center',
|
|
87
|
-
borderColor: 'inherit',
|
|
88
|
-
'& tr': {
|
|
89
|
-
'&:nth-of-type(odd)': {
|
|
90
|
-
background: theme.palette.background.paper,
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
'& td': {
|
|
94
|
-
[theme.breakpoints.up('sm')]: {
|
|
95
|
-
minWidth: '150px',
|
|
96
|
-
},
|
|
97
|
-
'& p': {},
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
}),
|
|
101
|
-
link: {
|
|
102
|
-
wordBreak: 'break-word',
|
|
103
|
-
},
|
|
104
|
-
underlined: {
|
|
105
|
-
textDecoration: 'underline',
|
|
106
|
-
},
|
|
107
|
-
iframe: {},
|
|
108
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { isElementNode, isTextNode } from './RichText'
|
|
2
|
-
import { ElementOrTextNode } from './types'
|
|
3
|
-
|
|
4
|
-
export function getNodeLength(node: ElementOrTextNode): number {
|
|
5
|
-
if (isElementNode(node))
|
|
6
|
-
return node.children.map(getNodeLength).reduce<number>((prev, curr) => prev + curr, 0)
|
|
7
|
-
|
|
8
|
-
if (isTextNode(node)) return node.text.length
|
|
9
|
-
|
|
10
|
-
return 0
|
|
11
|
-
}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { SxProps, Theme } from '@mui/material'
|
|
2
|
-
import type { LiteralUnion } from 'type-fest'
|
|
3
|
-
|
|
4
|
-
type BaseElementTypes =
|
|
5
|
-
| 'heading-one'
|
|
6
|
-
| 'heading-two'
|
|
7
|
-
| 'heading-three'
|
|
8
|
-
| 'heading-four'
|
|
9
|
-
| 'heading-five'
|
|
10
|
-
| 'heading-six'
|
|
11
|
-
| 'paragraph'
|
|
12
|
-
| 'numbered-list'
|
|
13
|
-
| 'bulleted-list'
|
|
14
|
-
| 'block-quote'
|
|
15
|
-
| 'list-item'
|
|
16
|
-
| 'list-item-child'
|
|
17
|
-
| 'table'
|
|
18
|
-
| 'table_head'
|
|
19
|
-
| 'table_header_cell'
|
|
20
|
-
| 'table_body'
|
|
21
|
-
| 'table_row'
|
|
22
|
-
| 'table_cell'
|
|
23
|
-
| 'code'
|
|
24
|
-
| 'bold'
|
|
25
|
-
| 'italic'
|
|
26
|
-
| 'underlined'
|
|
27
|
-
|
|
28
|
-
export type SimpleElement = {
|
|
29
|
-
children: ElementOrTextNode[]
|
|
30
|
-
type: LiteralUnion<BaseElementTypes, string>
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type TextNode = {
|
|
34
|
-
text: string
|
|
35
|
-
bold?: true
|
|
36
|
-
italic?: true
|
|
37
|
-
underlined?: true
|
|
38
|
-
[key: string]: unknown
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
type LinkElement = {
|
|
42
|
-
type: 'link'
|
|
43
|
-
children: ElementOrTextNode[]
|
|
44
|
-
href: string
|
|
45
|
-
openInNewTab?: boolean
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
type ClassElement = {
|
|
49
|
-
type: 'class'
|
|
50
|
-
children: ElementOrTextNode[]
|
|
51
|
-
className: string
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
type ImageElement = {
|
|
55
|
-
type: 'image'
|
|
56
|
-
children: ElementOrTextNode[]
|
|
57
|
-
src: string
|
|
58
|
-
title: string
|
|
59
|
-
altText: string
|
|
60
|
-
width: number
|
|
61
|
-
height: number
|
|
62
|
-
mimeType: string
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
type VideoElement = {
|
|
66
|
-
type: 'image'
|
|
67
|
-
children: ElementOrTextNode[]
|
|
68
|
-
src: string
|
|
69
|
-
title: string
|
|
70
|
-
width: number
|
|
71
|
-
height: number
|
|
72
|
-
mimeType: string
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
type IframeElement = {
|
|
76
|
-
type: 'iframe'
|
|
77
|
-
children: ElementOrTextNode[]
|
|
78
|
-
url: string
|
|
79
|
-
width?: number
|
|
80
|
-
height?: number
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export type ElementNode =
|
|
84
|
-
| SimpleElement
|
|
85
|
-
| LinkElement
|
|
86
|
-
| ImageElement
|
|
87
|
-
| VideoElement
|
|
88
|
-
| IframeElement
|
|
89
|
-
| ClassElement
|
|
90
|
-
export type ElementOrTextNode = ElementNode | TextNode
|
|
91
|
-
|
|
92
|
-
type RendererBase = { sx?: SxProps<Theme>; children?: React.ReactNode }
|
|
93
|
-
export type Renderer<P extends ElementNode> = (
|
|
94
|
-
props: Omit<P, 'children' | 'type'> & RendererBase,
|
|
95
|
-
) => React.ReactElement | null
|
|
96
|
-
|
|
97
|
-
export type Renderers = {
|
|
98
|
-
[k in BaseElementTypes]: Renderer<SimpleElement>
|
|
99
|
-
} & {
|
|
100
|
-
link: Renderer<LinkElement>
|
|
101
|
-
image: Renderer<ImageElement>
|
|
102
|
-
video: Renderer<VideoElement>
|
|
103
|
-
iframe: Renderer<IframeElement>
|
|
104
|
-
class: Renderer<ClassElement>
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export type SxRenderer = {
|
|
108
|
-
[k in keyof Renderers | 'all' | 'first' | 'last']?: SxProps<Theme>
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export type AdditionalProps = {
|
|
112
|
-
renderers: Renderers
|
|
113
|
-
sxRenderer: SxRenderer
|
|
114
|
-
first?: boolean
|
|
115
|
-
last?: boolean
|
|
116
|
-
className?: string
|
|
117
|
-
}
|
package/components/index.ts
DELETED