Skip to content

Commit ed44ec0

Browse files
authored
fix(ui): does not render row labels until form state returns (#10002)
Extension of #9933. Custom components are returned by form state, meaning that if we don't wait for form state to return before rendering row labels, the default row label component will render in briefly before being swapped by a custom component (if applicable). Using the new `isLoading` prop on array and block rows, we can conditionally render them just as we currently do for the row fields themselves.
1 parent fa49e04 commit ed44ec0

File tree

6 files changed

+367
-177
lines changed

6 files changed

+367
-177
lines changed

packages/ui/src/fields/Array/ArrayRow.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,14 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
130130
}
131131
header={
132132
<div className={`${baseClass}__row-header`}>
133-
<RowLabel
134-
CustomComponent={CustomRowLabel}
135-
label={fallbackLabel}
136-
path={path}
137-
rowNumber={rowIndex}
138-
/>
133+
{isLoading ? null : (
134+
<RowLabel
135+
CustomComponent={CustomRowLabel}
136+
label={fallbackLabel}
137+
path={path}
138+
rowNumber={rowIndex}
139+
/>
140+
)}
139141
{fieldHasErrors && <ErrorPill count={errorCount} i18n={i18n} withMessage />}
140142
</div>
141143
}

packages/ui/src/fields/Blocks/BlockRow.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,21 +140,23 @@ export const BlockRow: React.FC<BlocksFieldProps> = ({
140140
: undefined
141141
}
142142
header={
143-
Label || (
144-
<div className={`${baseClass}__block-header`}>
145-
<span className={`${baseClass}__block-number`}>
146-
{String(rowIndex + 1).padStart(2, '0')}
147-
</span>
148-
<Pill
149-
className={`${baseClass}__block-pill ${baseClass}__block-pill-${row.blockType}`}
150-
pillStyle="white"
151-
>
152-
{getTranslation(block.labels.singular, i18n)}
153-
</Pill>
154-
<SectionTitle path={`${path}.blockName`} readOnly={readOnly} />
155-
{fieldHasErrors && <ErrorPill count={errorCount} i18n={i18n} withMessage />}
156-
</div>
157-
)
143+
isLoading
144+
? null
145+
: Label || (
146+
<div className={`${baseClass}__block-header`}>
147+
<span className={`${baseClass}__block-number`}>
148+
{String(rowIndex + 1).padStart(2, '0')}
149+
</span>
150+
<Pill
151+
className={`${baseClass}__block-pill ${baseClass}__block-pill-${row.blockType}`}
152+
pillStyle="white"
153+
>
154+
{getTranslation(block.labels.singular, i18n)}
155+
</Pill>
156+
<SectionTitle path={`${path}.blockName`} readOnly={readOnly} />
157+
{fieldHasErrors && <ErrorPill count={errorCount} i18n={i18n} withMessage />}
158+
</div>
159+
)
158160
}
159161
isCollapsed={row.collapsed}
160162
key={row.id}

packages/ui/src/forms/RowLabel/Context/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const RowLabelProvider: React.FC<Props<unknown>> = ({ children, path, row
2525
const { getDataByPath, getSiblingData } = useWatchForm()
2626
const collapsibleData = getSiblingData(path)
2727
const arrayData = getDataByPath(path)
28+
2829
const data = arrayData || collapsibleData
2930

3031
return <RowLabel.Provider value={{ data, path, rowNumber }}>{children}</RowLabel.Provider>

test/fields/collections/Array/LabelComponent.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import React from 'react'
88
export const ArrayRowLabel: PayloadClientReactComponent<RowLabelComponent> = () => {
99
const { data } = useRowLabel<{ title: string }>()
1010
return (
11-
<div style={{ color: 'coral', textTransform: 'uppercase' }}>{data.title || 'Untitled'}</div>
11+
<div id="custom-array-row-label" style={{ color: 'coral', textTransform: 'uppercase' }}>
12+
{data.title || 'Untitled'}
13+
</div>
1214
)
1315
}

test/fields/collections/Array/e2e.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,25 @@ describe('Array', () => {
8484
await page.goto(url.create)
8585
await page.locator('#field-rowLabelAsComponent >> .array-field__add-row').click()
8686

87+
// ensure the default label does not blink in before form state returns
88+
const defaultRowLabelWasAttached = await page
89+
.waitForSelector('#field-rowLabelAsComponent .array-field__row-header .row-label', {
90+
state: 'attached',
91+
timeout: 100, // A small timeout to catch any transient rendering
92+
})
93+
.catch(() => false) // If it doesn't appear, this resolves to `false`
94+
95+
expect(defaultRowLabelWasAttached).toBeFalsy()
96+
97+
await expect(page.locator('#field-rowLabelAsComponent #custom-array-row-label')).toBeVisible()
98+
8799
await page.locator('#field-rowLabelAsComponent__0__title').fill(label)
88100
await wait(100)
101+
89102
const customRowLabel = page.locator(
90103
'#rowLabelAsComponent-row-0 >> .array-field__row-header > :text("custom row label")',
91104
)
105+
92106
await expect(customRowLabel).toHaveCSS('text-transform', 'uppercase')
93107
})
94108

0 commit comments

Comments
 (0)