Skip to content

Commit 57f7218

Browse files
authored
chore(deps): upgrades react-diff-viewer-continued to v4.0.4 to suppress react 19 warnings and use ESM imports (#10834)
The `react-diff-viewer-continued` package now includes React 19 in its peer dependencies thanks to Aeolun/react-diff-viewer-continued#56. This new version also exports as ESM by default ftw.
1 parent 9c31a52 commit 57f7218

File tree

9 files changed

+3310
-8874
lines changed

9 files changed

+3310
-8874
lines changed

packages/next/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
"http-status": "2.1.0",
9494
"path-to-regexp": "6.3.0",
9595
"qs-esm": "7.0.2",
96-
"react-diff-viewer-continued": "3.2.6",
96+
"react-diff-viewer-continued": "4.0.4",
9797
"sass": "1.77.4",
9898
"sonner": "^1.7.0",
9999
"uuid": "10.0.0"

packages/next/src/views/Version/RenderFieldsToDiff/fields/Relationship/index.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,14 @@ import { getTranslation } from '@payloadcms/translations'
55
import { useConfig } from '@payloadcms/ui'
66
import { fieldAffectsData, fieldIsPresentationalOnly } from 'payload/shared'
77
import React from 'react'
8-
import ReactDiffViewerImport from 'react-diff-viewer-continued'
8+
import ReactDiffViewer from 'react-diff-viewer-continued'
99

1010
import type { DiffComponentProps } from '../types.js'
1111

1212
import Label from '../../Label/index.js'
1313
import { diffStyles } from '../styles.js'
1414
import './index.scss'
1515

16-
const ReactDiffViewer = (ReactDiffViewerImport.default ||
17-
ReactDiffViewerImport) as unknown as typeof ReactDiffViewerImport.default
18-
1916
const baseClass = 'relationship-diff'
2017

2118
type RelationshipValue = Record<string, any>

packages/next/src/views/Version/RenderFieldsToDiff/fields/Select/DiffViewer/index.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
'use client'
22
import React from 'react'
3-
import ReactDiffViewerImport, { DiffMethod } from 'react-diff-viewer-continued'
4-
5-
const ReactDiffViewer = (ReactDiffViewerImport.default ||
6-
ReactDiffViewerImport) as unknown as typeof ReactDiffViewerImport.default
3+
import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer-continued'
74

85
export const DiffViewer: React.FC<{
96
comparisonToRender: string

packages/next/src/views/Version/RenderFieldsToDiff/fields/Text/DiffViewer/index.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
'use client'
22
import React from 'react'
3-
import ReactDiffViewerImport, { DiffMethod } from 'react-diff-viewer-continued'
3+
import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer-continued'
44

5-
const ReactDiffViewer = (ReactDiffViewerImport.default ||
6-
ReactDiffViewerImport) as unknown as typeof ReactDiffViewerImport.default
75
export const DiffViewer: React.FC<{
86
comparisonToRender: string
97
diffMethod: string

packages/next/src/views/Version/RenderFieldsToDiff/fields/styles.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
export const diffStyles = {
2+
diffContainer: {
3+
minWidth: 'unset',
4+
},
25
variables: {
36
dark: {
47
addedBackground: 'var(--theme-success-900)',

packages/next/src/views/Version/RenderFieldsToDiff/index.scss

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
flex-direction: column;
77
gap: var(--base);
88

9+
[role='banner'] {
10+
display: none !important;
11+
}
12+
913
&__field {
1014
overflow-wrap: anywhere;
1115
display: flex;
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
'use client'
22
import type { DiffMethod } from 'react-diff-viewer-continued'
33

4+
import { ShimmerEffect, StaggeredShimmers } from '@payloadcms/ui'
45
import { fieldAffectsData, fieldIsID } from 'payload/shared'
5-
import React from 'react'
6+
import React, { Fragment, useEffect } from 'react'
67

78
import type { diffComponents as _diffComponents } from './fields/index.js'
89
import type { FieldDiffProps, Props } from './types.js'
@@ -25,129 +26,145 @@ export const RenderFieldsToDiff: React.FC<Props> = ({
2526
// Without it, you could pass a UI field to the Tabs component, without it erroring
2627
const diffComponents: typeof _diffComponents = __diffComponents as typeof _diffComponents
2728

28-
return (
29-
<div className={baseClass}>
30-
{fields?.map((field, i) => {
31-
if (fieldIsID(field)) {
32-
return null
33-
}
34-
35-
const Component = diffComponents[field.type]
36-
37-
const isRichText = field.type === 'richText'
38-
const diffMethod: DiffMethod = diffMethods[field.type] || 'CHARS'
39-
40-
if (Component) {
41-
if (fieldAffectsData(field)) {
42-
const fieldName = field.name
43-
const valueIsObject = field.type === 'code' || field.type === 'json'
44-
45-
const versionValue = valueIsObject
46-
? JSON.stringify(version?.[fieldName])
47-
: version?.[fieldName]
29+
const [hasMounted, setHasMounted] = React.useState(false)
4830

49-
const comparisonValue = valueIsObject
50-
? JSON.stringify(comparison?.[fieldName])
51-
: comparison?.[fieldName]
31+
// defer rendering until after the first mount as the CSS is loaded with Emotion
32+
// this will ensure that the CSS is loaded before rendering the diffs and prevent CLS
33+
useEffect(() => {
34+
setHasMounted(true)
35+
}, [])
5236

53-
const hasPermission =
54-
fieldPermissions === true ||
55-
fieldPermissions?.[fieldName] === true ||
56-
fieldPermissions?.[fieldName]?.read
57-
58-
const subFieldPermissions =
59-
fieldPermissions === true ||
60-
fieldPermissions?.[fieldName] === true ||
61-
fieldPermissions?.[fieldName]?.fields
62-
63-
if (!hasPermission) {
37+
return (
38+
<div className={baseClass}>
39+
{!hasMounted ? (
40+
<Fragment>
41+
<ShimmerEffect height="8rem" width="100%" />
42+
</Fragment>
43+
) : (
44+
<Fragment>
45+
{fields?.map((field, i) => {
46+
if (fieldIsID(field)) {
6447
return null
6548
}
6649

67-
const baseCellProps: FieldDiffProps = {
68-
comparison: comparisonValue,
69-
diffComponents,
70-
diffMethod,
71-
field,
72-
fieldPermissions: subFieldPermissions,
73-
fields: 'fields' in field ? field?.fields : fields,
74-
i18n,
75-
isRichText,
76-
locales,
77-
version: versionValue,
78-
}
79-
80-
if (field.localized) {
81-
return (
82-
<div className={`${baseClass}__field`} key={i}>
83-
{locales.map((locale, index) => {
84-
const versionLocaleValue = versionValue?.[locale]
85-
const comparisonLocaleValue = comparisonValue?.[locale]
86-
87-
const cellProps = {
88-
...baseCellProps,
89-
comparison: comparisonLocaleValue,
90-
version: versionLocaleValue,
91-
}
92-
93-
return (
94-
<div className={`${baseClass}__locale`} key={[locale, index].join('-')}>
95-
<div className={`${baseClass}__locale-value`}>
96-
<Component {...cellProps} locale={locale} />
97-
</div>
98-
</div>
99-
)
100-
})}
101-
</div>
102-
)
50+
const Component = diffComponents[field.type]
51+
52+
const isRichText = field.type === 'richText'
53+
const diffMethod: DiffMethod = diffMethods[field.type] || 'CHARS'
54+
55+
if (Component) {
56+
if (fieldAffectsData(field)) {
57+
const fieldName = field.name
58+
const valueIsObject = field.type === 'code' || field.type === 'json'
59+
60+
const versionValue = valueIsObject
61+
? JSON.stringify(version?.[fieldName])
62+
: version?.[fieldName]
63+
64+
const comparisonValue = valueIsObject
65+
? JSON.stringify(comparison?.[fieldName])
66+
: comparison?.[fieldName]
67+
68+
const hasPermission =
69+
fieldPermissions === true ||
70+
fieldPermissions?.[fieldName] === true ||
71+
fieldPermissions?.[fieldName]?.read
72+
73+
const subFieldPermissions =
74+
fieldPermissions === true ||
75+
fieldPermissions?.[fieldName] === true ||
76+
fieldPermissions?.[fieldName]?.fields
77+
78+
if (!hasPermission) {
79+
return null
80+
}
81+
82+
const baseCellProps: FieldDiffProps = {
83+
comparison: comparisonValue,
84+
diffComponents,
85+
diffMethod,
86+
field,
87+
fieldPermissions: subFieldPermissions,
88+
fields: 'fields' in field ? field?.fields : fields,
89+
i18n,
90+
isRichText,
91+
locales,
92+
version: versionValue,
93+
}
94+
95+
if (field.localized) {
96+
return (
97+
<div className={`${baseClass}__field`} key={i}>
98+
{locales.map((locale, index) => {
99+
const versionLocaleValue = versionValue?.[locale]
100+
const comparisonLocaleValue = comparisonValue?.[locale]
101+
102+
const cellProps = {
103+
...baseCellProps,
104+
comparison: comparisonLocaleValue,
105+
version: versionLocaleValue,
106+
}
107+
108+
return (
109+
<div className={`${baseClass}__locale`} key={[locale, index].join('-')}>
110+
<div className={`${baseClass}__locale-value`}>
111+
<Component {...cellProps} locale={locale} />
112+
</div>
113+
</div>
114+
)
115+
})}
116+
</div>
117+
)
118+
}
119+
120+
return (
121+
<div className={`${baseClass}__field`} key={i}>
122+
<Component {...baseCellProps} />
123+
</div>
124+
)
125+
}
126+
127+
if (field.type === 'tabs' && 'tabs' in field) {
128+
const Tabs = diffComponents.tabs
129+
130+
return (
131+
<Tabs
132+
comparison={comparison}
133+
diffComponents={diffComponents}
134+
field={field}
135+
fieldPermissions={fieldPermissions}
136+
fields={[]}
137+
i18n={i18n}
138+
key={i}
139+
locales={locales}
140+
version={version}
141+
/>
142+
)
143+
}
144+
145+
// At this point, we are dealing with a field with subfields but no
146+
// nested data, eg. row, collapsible, etc.
147+
if ('fields' in field) {
148+
return (
149+
<Component
150+
comparison={comparison}
151+
diffComponents={diffComponents}
152+
field={field}
153+
fieldPermissions={fieldPermissions}
154+
fields={field.fields}
155+
i18n={i18n}
156+
key={i}
157+
locales={locales}
158+
version={version}
159+
/>
160+
)
161+
}
103162
}
104163

105-
return (
106-
<div className={`${baseClass}__field`} key={i}>
107-
<Component {...baseCellProps} />
108-
</div>
109-
)
110-
}
111-
112-
if (field.type === 'tabs' && 'tabs' in field) {
113-
const Tabs = diffComponents.tabs
114-
115-
return (
116-
<Tabs
117-
comparison={comparison}
118-
diffComponents={diffComponents}
119-
field={field}
120-
fieldPermissions={fieldPermissions}
121-
fields={[]}
122-
i18n={i18n}
123-
key={i}
124-
locales={locales}
125-
version={version}
126-
/>
127-
)
128-
}
129-
130-
// At this point, we are dealing with a field with subfields but no
131-
// nested data, eg. row, collapsible, etc.
132-
if ('fields' in field) {
133-
return (
134-
<Component
135-
comparison={comparison}
136-
diffComponents={diffComponents}
137-
field={field}
138-
fieldPermissions={fieldPermissions}
139-
fields={field.fields}
140-
i18n={i18n}
141-
key={i}
142-
locales={locales}
143-
version={version}
144-
/>
145-
)
146-
}
147-
}
148-
149-
return null
150-
})}
164+
return null
165+
})}
166+
</Fragment>
167+
)}
151168
</div>
152169
)
153170
}

0 commit comments

Comments
 (0)