@graphcommerce/graphcms-ui 3.0.5 → 3.0.8
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
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 3.0.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1369](https://github.com/graphcommerce-org/graphcommerce/pull/1369) [`ae6449502`](https://github.com/graphcommerce-org/graphcommerce/commit/ae64495024a455bbe5188588604368c1542840c9) Thanks [@paales](https://github.com/paales)! - Upgraded dependencies
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`892018809`](https://github.com/graphcommerce-org/graphcommerce/commit/8920188093d0422ec50580e408dc28ac5f93e46a), [`892018809`](https://github.com/graphcommerce-org/graphcommerce/commit/8920188093d0422ec50580e408dc28ac5f93e46a), [`ae6449502`](https://github.com/graphcommerce-org/graphcommerce/commit/ae64495024a455bbe5188588604368c1542840c9), [`892018809`](https://github.com/graphcommerce-org/graphcommerce/commit/8920188093d0422ec50580e408dc28ac5f93e46a), [`892018809`](https://github.com/graphcommerce-org/graphcommerce/commit/8920188093d0422ec50580e408dc28ac5f93e46a)]:
|
|
10
|
+
- @graphcommerce/graphql@3.0.6
|
|
11
|
+
- @graphcommerce/next-ui@4.5.0
|
|
12
|
+
- @graphcommerce/image@3.1.2
|
|
13
|
+
|
|
14
|
+
## 3.0.7
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- [#1353](https://github.com/graphcommerce-org/graphcommerce/pull/1353) [`0e5ee7ba8`](https://github.com/graphcommerce-org/graphcommerce/commit/0e5ee7ba89698e5e711001e846ed182528060cba) Thanks [@paales](https://github.com/paales)! - Eslint: enable rules that were previously disabled and make fixes
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [[`49a2d6617`](https://github.com/graphcommerce-org/graphcommerce/commit/49a2d661712e1787fba46c6195f7b559189e23d9), [`f67da3cfb`](https://github.com/graphcommerce-org/graphcommerce/commit/f67da3cfbe2dcf5ea23519d088c5aa0074029182), [`218766869`](https://github.com/graphcommerce-org/graphcommerce/commit/218766869f7468c067a590857c942f3819f8add4), [`0e5ee7ba8`](https://github.com/graphcommerce-org/graphcommerce/commit/0e5ee7ba89698e5e711001e846ed182528060cba), [`829b8690b`](https://github.com/graphcommerce-org/graphcommerce/commit/829b8690bc5d0a46e596299e4120e9837a9f179c)]:
|
|
21
|
+
- @graphcommerce/next-ui@4.4.0
|
|
22
|
+
|
|
23
|
+
## 3.0.6
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- [#1322](https://github.com/graphcommerce-org/graphcommerce/pull/1322) [`ae7385b94`](https://github.com/graphcommerce-org/graphcommerce/commit/ae7385b943e591fcd6fe9e5747f22e03a73e481a) Thanks [@paales](https://github.com/paales)! - RichText component’s first and last element should have no marginTop and marginBottom respectively unless withMargin is specified
|
|
28
|
+
|
|
29
|
+
- Updated dependencies [[`5266388ea`](https://github.com/graphcommerce-org/graphcommerce/commit/5266388eaffda41592623ef7a3ddbbe03c8e0dad), [`9b35403d9`](https://github.com/graphcommerce-org/graphcommerce/commit/9b35403d9dbb2606ac7cf3bb641a0f9cc3d8a2ba), [`0298a0de1`](https://github.com/graphcommerce-org/graphcommerce/commit/0298a0de1d13e543c4124a6a099297b4e27e2b05), [`815132ea4`](https://github.com/graphcommerce-org/graphcommerce/commit/815132ea43937b4b84b59ec9974ac593cb4eb456), [`3326742a0`](https://github.com/graphcommerce-org/graphcommerce/commit/3326742a0dceb45f0cac4741ca09dc4d4f09ad90), [`7a3799bfc`](https://github.com/graphcommerce-org/graphcommerce/commit/7a3799bfc107f26aa9991a91db5f228e3476f4aa), [`9a77f88ed`](https://github.com/graphcommerce-org/graphcommerce/commit/9a77f88ed26cbecdae9a135c3cb234a5b7ecf4df), [`0eeaad304`](https://github.com/graphcommerce-org/graphcommerce/commit/0eeaad30461b1d5b486438f0287fa76d49429044), [`bc5213547`](https://github.com/graphcommerce-org/graphcommerce/commit/bc52135471479c83d989449dad24798112e898f4), [`3f1912f55`](https://github.com/graphcommerce-org/graphcommerce/commit/3f1912f553318d5888f8af2b841918ef4ae96a84), [`b6c68cda8`](https://github.com/graphcommerce-org/graphcommerce/commit/b6c68cda8836a1d0c78ef351899cec9ec1037385)]:
|
|
30
|
+
- @graphcommerce/next-ui@4.3.0
|
|
31
|
+
|
|
3
32
|
## 3.0.5
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
|
@@ -1,22 +1,59 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
1
2
|
import { SxProps, Theme } from '@mui/material'
|
|
2
3
|
import { defaultRenderers } from './defaultRenderers'
|
|
3
4
|
import { defaultSxRenderer } from './defaultSxRenderer'
|
|
4
5
|
import {
|
|
5
6
|
AdditionalProps,
|
|
6
7
|
Renderers,
|
|
8
|
+
Renderer,
|
|
7
9
|
SxRenderer,
|
|
8
10
|
TextNode,
|
|
9
11
|
ElementOrTextNode,
|
|
10
12
|
ElementNode,
|
|
13
|
+
SimpleElement,
|
|
11
14
|
} from './types'
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const sxArr = (sxAny?: SxProps<Theme> | false) => {
|
|
17
|
+
if (!sxAny) return []
|
|
18
|
+
return Array.isArray(sxAny) ? sxAny : [sxAny]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function useRenderProps(
|
|
22
|
+
{ first, last, sxRenderer }: Pick<AdditionalProps, 'first' | 'last' | 'sxRenderer'>,
|
|
23
|
+
type?: ElementNode['type'],
|
|
24
|
+
) {
|
|
25
|
+
if (!type) return []
|
|
26
|
+
const sx: SxProps<Theme> = sxRenderer?.[type] ?? []
|
|
27
|
+
|
|
28
|
+
return [
|
|
29
|
+
...sxArr(sxRenderer.all),
|
|
30
|
+
...sxArr(sx),
|
|
31
|
+
...sxArr(first && sxRenderer.first),
|
|
32
|
+
...sxArr(last && sxRenderer.last),
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function RenderText({
|
|
37
|
+
text,
|
|
38
|
+
renderers,
|
|
39
|
+
sxRenderer,
|
|
40
|
+
first,
|
|
41
|
+
last,
|
|
42
|
+
...textProps
|
|
43
|
+
}: TextNode & AdditionalProps) {
|
|
44
|
+
let type: 'bold' | 'italic' | 'underlined' | undefined
|
|
45
|
+
|
|
46
|
+
if (textProps.bold) type = 'bold'
|
|
47
|
+
if (textProps.italic) type = 'italic'
|
|
48
|
+
if (textProps.underlined) type = 'underlined'
|
|
18
49
|
|
|
19
|
-
|
|
50
|
+
const sx = useRenderProps({ first, last, sxRenderer }, type)
|
|
51
|
+
|
|
52
|
+
if (!type) return <>{text}</>
|
|
53
|
+
|
|
54
|
+
const Component: Renderer<SimpleElement> = renderers[type]
|
|
55
|
+
|
|
56
|
+
return <Component sx={sx}>{text}</Component>
|
|
20
57
|
}
|
|
21
58
|
|
|
22
59
|
export function isTextNode(node: ElementOrTextNode): node is TextNode {
|
|
@@ -46,29 +83,37 @@ function RenderNode(node: ElementOrTextNode & AdditionalProps) {
|
|
|
46
83
|
|
|
47
84
|
function RenderChildren({
|
|
48
85
|
childNodes,
|
|
86
|
+
noMargin,
|
|
49
87
|
...props
|
|
50
|
-
}: { childNodes: ElementNode['children'] } & AdditionalProps) {
|
|
88
|
+
}: { childNodes: ElementNode['children']; noMargin?: boolean } & AdditionalProps) {
|
|
51
89
|
return (
|
|
52
90
|
<>
|
|
53
91
|
{childNodes.map((node, key) => (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
92
|
+
<RenderNode
|
|
93
|
+
{...node}
|
|
94
|
+
{...props}
|
|
95
|
+
// Since we don't know any unique identifiers of the element and since this doesn't rerender often this is fine.
|
|
96
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
97
|
+
key={key}
|
|
98
|
+
first={noMargin && key === 0}
|
|
99
|
+
last={noMargin && key === childNodes.length - 1}
|
|
100
|
+
/>
|
|
57
101
|
))}
|
|
58
102
|
</>
|
|
59
103
|
)
|
|
60
104
|
}
|
|
61
105
|
|
|
62
106
|
function RenderElement(element: ElementNode & AdditionalProps) {
|
|
63
|
-
const { type, children, sxRenderer, renderers, ...props } = element
|
|
107
|
+
const { type, children, sxRenderer, renderers, first, last, ...props } = element
|
|
64
108
|
|
|
65
109
|
// todo: this has the any type, could be improved
|
|
66
|
-
const Component = renderers[type]
|
|
67
|
-
|
|
110
|
+
const Component: Renderer<SimpleElement> = renderers[type]
|
|
111
|
+
|
|
112
|
+
const sx = useRenderProps({ first, last, sxRenderer }, type)
|
|
68
113
|
|
|
69
114
|
if (Component) {
|
|
70
115
|
return (
|
|
71
|
-
<Component {...props} sx={
|
|
116
|
+
<Component {...props} sx={sx}>
|
|
72
117
|
<RenderChildren childNodes={children} sxRenderer={sxRenderer} renderers={renderers} />
|
|
73
118
|
</Component>
|
|
74
119
|
)
|
|
@@ -76,17 +121,12 @@ function RenderElement(element: ElementNode & AdditionalProps) {
|
|
|
76
121
|
|
|
77
122
|
if (process.env.NODE_ENV !== 'production') {
|
|
78
123
|
console.error(element)
|
|
79
|
-
throw Error(`RichText: Unknown Element: ${
|
|
124
|
+
throw Error(`RichText: Unknown Element: ${type}`)
|
|
80
125
|
}
|
|
81
126
|
return <RenderChildren childNodes={children} sxRenderer={sxRenderer} renderers={renderers} />
|
|
82
127
|
}
|
|
83
128
|
|
|
84
|
-
|
|
85
|
-
renderers?: Partial<Renderers>
|
|
86
|
-
sxRenderer?: SxRenderer
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function mergeSxRenderer(base: SxRenderer, sxRenderer?: SxRenderer) {
|
|
129
|
+
function mergeSxRenderer(base: SxRenderer, sxRenderer?: SxRenderer) {
|
|
90
130
|
if (!sxRenderer) return base
|
|
91
131
|
|
|
92
132
|
return Object.fromEntries(
|
|
@@ -106,12 +146,38 @@ export function mergeSxRenderer(base: SxRenderer, sxRenderer?: SxRenderer) {
|
|
|
106
146
|
) as SxRenderer
|
|
107
147
|
}
|
|
108
148
|
|
|
109
|
-
export
|
|
149
|
+
export type RichTextProps = { raw: ElementNode } & {
|
|
150
|
+
renderers?: Partial<Renderers>
|
|
151
|
+
/**
|
|
152
|
+
* Allows you to theme all the types of components
|
|
153
|
+
*
|
|
154
|
+
* ```tsx
|
|
155
|
+
* function MyComponent()f {
|
|
156
|
+
* return <RichText
|
|
157
|
+
* sxRenderer={{
|
|
158
|
+
* paragraph: (theme) => ({
|
|
159
|
+
* columnCount: { xs: 1, md: getColumnCount(props, 2) },
|
|
160
|
+
* columnGap: theme.spacings.md,
|
|
161
|
+
* }),
|
|
162
|
+
* //other props here
|
|
163
|
+
* }}
|
|
164
|
+
* />
|
|
165
|
+
* }
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
sxRenderer?: SxRenderer
|
|
169
|
+
|
|
170
|
+
/** By default the component will render the first and last element without any margins */
|
|
171
|
+
withMargin?: boolean
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function RichText({ raw, sxRenderer, renderers, withMargin = false }: RichTextProps) {
|
|
110
175
|
return (
|
|
111
176
|
<RenderChildren
|
|
112
177
|
childNodes={raw.children}
|
|
113
178
|
sxRenderer={mergeSxRenderer(defaultSxRenderer, sxRenderer)}
|
|
114
179
|
renderers={{ ...defaultRenderers, ...renderers }}
|
|
180
|
+
noMargin={!withMargin}
|
|
115
181
|
/>
|
|
116
182
|
)
|
|
117
183
|
}
|
|
@@ -27,9 +27,9 @@ export const defaultRenderers: Renderers = {
|
|
|
27
27
|
video: ({ src, width, height, title, mimeType }) => (
|
|
28
28
|
<Asset asset={{ url: src, alt: title, width, height, mimeType }} />
|
|
29
29
|
),
|
|
30
|
-
link: ({ href, ...props }) => (
|
|
30
|
+
link: ({ href, openInNewTab, ...props }) => (
|
|
31
31
|
<PageLink href={href} passHref>
|
|
32
|
-
<Link underline='hover' {...props} />
|
|
32
|
+
<Link underline='hover' {...props} target={openInNewTab ? '_blank' : undefined} />
|
|
33
33
|
</PageLink>
|
|
34
34
|
),
|
|
35
35
|
table: (props) => <Box component='table' {...props} />,
|
|
@@ -39,4 +39,7 @@ export const defaultRenderers: Renderers = {
|
|
|
39
39
|
table_row: (props) => <Box component='tr' {...props} />,
|
|
40
40
|
table_cell: (props) => <Box component='td' {...props} />,
|
|
41
41
|
code: (props) => <Box component='code' {...props} />,
|
|
42
|
+
bold: (props) => <Box component='strong' fontWeight='bold' {...props} />,
|
|
43
|
+
italic: (props) => <Box component='em' fontStyle='italic' {...props} />,
|
|
44
|
+
underlined: (props) => <Box component='span' {...props} />,
|
|
42
45
|
}
|
|
@@ -5,7 +5,12 @@ export const defaultSxRenderer: SxRenderer = {
|
|
|
5
5
|
'&:empty': {
|
|
6
6
|
display: 'none',
|
|
7
7
|
},
|
|
8
|
-
|
|
8
|
+
},
|
|
9
|
+
first: {
|
|
10
|
+
marginTop: 0,
|
|
11
|
+
},
|
|
12
|
+
last: {
|
|
13
|
+
marginBottom: 0,
|
|
9
14
|
},
|
|
10
15
|
paragraph: {
|
|
11
16
|
marginBottom: '1em',
|
|
@@ -18,22 +23,18 @@ export const defaultSxRenderer: SxRenderer = {
|
|
|
18
23
|
'heading-two': {
|
|
19
24
|
marginTop: '0.5em',
|
|
20
25
|
marginBottom: '0.5em',
|
|
21
|
-
'&:first-of-type': { marginTop: 0 },
|
|
22
26
|
},
|
|
23
27
|
'heading-three': {
|
|
24
28
|
marginTop: '0.5em',
|
|
25
29
|
marginBottom: '0.5em',
|
|
26
|
-
'&:first-of-type': { marginTop: 0 },
|
|
27
30
|
},
|
|
28
31
|
'heading-four': {
|
|
29
32
|
marginTop: '0.5em',
|
|
30
33
|
marginBottom: '0.5em',
|
|
31
|
-
'&:first-of-type': { marginTop: 0 },
|
|
32
34
|
},
|
|
33
35
|
'heading-five': {
|
|
34
36
|
marginTop: '0.5em',
|
|
35
37
|
marginBottom: '0.5em',
|
|
36
|
-
'&:first-of-type': { marginTop: 0 },
|
|
37
38
|
},
|
|
38
39
|
image: {
|
|
39
40
|
width: '100%',
|
|
@@ -100,4 +101,7 @@ export const defaultSxRenderer: SxRenderer = {
|
|
|
100
101
|
link: {
|
|
101
102
|
wordBreak: 'break-word',
|
|
102
103
|
},
|
|
104
|
+
underlined: {
|
|
105
|
+
textDecoration: 'underline',
|
|
106
|
+
},
|
|
103
107
|
}
|
|
@@ -22,8 +22,11 @@ type BaseElementTypes =
|
|
|
22
22
|
| 'table_row'
|
|
23
23
|
| 'table_cell'
|
|
24
24
|
| 'code'
|
|
25
|
+
| 'bold'
|
|
26
|
+
| 'italic'
|
|
27
|
+
| 'underlined'
|
|
25
28
|
|
|
26
|
-
type SimpleElement = {
|
|
29
|
+
export type SimpleElement = {
|
|
27
30
|
children: ElementOrTextNode[]
|
|
28
31
|
type: LiteralUnion<BaseElementTypes, string>
|
|
29
32
|
}
|
|
@@ -40,6 +43,7 @@ type LinkElement = {
|
|
|
40
43
|
type: 'link'
|
|
41
44
|
children: ElementOrTextNode[]
|
|
42
45
|
href: string
|
|
46
|
+
openInNewTab?: boolean
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
type ImageElement = {
|
|
@@ -72,8 +76,8 @@ export type ElementNode = SimpleElement | LinkElement | ImageElement | VideoElem
|
|
|
72
76
|
export type ElementOrTextNode = ElementNode | TextNode
|
|
73
77
|
|
|
74
78
|
type RendererBase = { sx?: SxProps<Theme>; children?: React.ReactNode }
|
|
75
|
-
type Renderer<P extends ElementNode> = (
|
|
76
|
-
props: Omit<P, 'children'> & RendererBase,
|
|
79
|
+
export type Renderer<P extends ElementNode> = (
|
|
80
|
+
props: Omit<P, 'children' | 'type'> & RendererBase,
|
|
77
81
|
) => React.ReactElement | null
|
|
78
82
|
|
|
79
83
|
export type Renderers = {
|
|
@@ -86,7 +90,12 @@ export type Renderers = {
|
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
export type SxRenderer = {
|
|
89
|
-
[k in keyof Renderers | 'all']?: SxProps<Theme>
|
|
93
|
+
[k in keyof Renderers | 'all' | 'first' | 'last']?: SxProps<Theme>
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
export type AdditionalProps = {
|
|
96
|
+
export type AdditionalProps = {
|
|
97
|
+
renderers: Renderers
|
|
98
|
+
sxRenderer: SxRenderer
|
|
99
|
+
first?: boolean
|
|
100
|
+
last?: boolean
|
|
101
|
+
}
|
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": "3.0.
|
|
5
|
+
"version": "3.0.8",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@graphcommerce/eslint-config-pwa": "^4.
|
|
16
|
-
"@graphcommerce/prettier-config-pwa": "^4.0.
|
|
15
|
+
"@graphcommerce/eslint-config-pwa": "^4.1.3",
|
|
16
|
+
"@graphcommerce/prettier-config-pwa": "^4.0.5",
|
|
17
17
|
"@graphcommerce/typescript-config-pwa": "^4.0.2",
|
|
18
|
-
"@playwright/test": "^1.
|
|
18
|
+
"@playwright/test": "^1.20.1",
|
|
19
|
+
"type-fest": "2.12.1"
|
|
19
20
|
},
|
|
20
21
|
"dependencies": {
|
|
21
|
-
"@graphcommerce/graphql": "^3.0.
|
|
22
|
-
"@graphcommerce/image": "^3.1.
|
|
23
|
-
"@graphcommerce/next-ui": "^4.
|
|
24
|
-
"type-fest": "^2.12.0"
|
|
22
|
+
"@graphcommerce/graphql": "^3.0.6",
|
|
23
|
+
"@graphcommerce/image": "^3.1.2",
|
|
24
|
+
"@graphcommerce/next-ui": "^4.5.0"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"@mui/material": "^5.4.1",
|