fix(ui): awaits form state before rendering conditional fields (#9933)
When a condition exists on a field and it resolves to `false`, it currently "blinks" in and out when rendered within an array or block row. This is because when add rows to form state, we iterate over the _fields_ of that row and render their respective components. Then when conditions are checked for that field, we're expecting `passesCondition` to be explicitly `false`, ultimately _rendering_ the field for a brief moment before form state returns with evaluated conditions. The fix is to set these fields into local form state with a new `isLoading: true` prop, then display a loader within the row until form state returns with its proper conditions.
This commit is contained in:
@@ -9,11 +9,13 @@ import type { UseDraggableSortableReturn } from '../../elements/DraggableSortabl
|
||||
import { ArrayAction } from '../../elements/ArrayAction/index.js'
|
||||
import { Collapsible } from '../../elements/Collapsible/index.js'
|
||||
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
||||
import { ShimmerEffect } from '../../elements/ShimmerEffect/index.js'
|
||||
import { useFormSubmitted } from '../../forms/Form/context.js'
|
||||
import { RenderFields } from '../../forms/RenderFields/index.js'
|
||||
import { RowLabel } from '../../forms/RowLabel/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { useThrottledValue } from '../../hooks/useThrottledValue.js'
|
||||
import './index.scss'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
|
||||
const baseClass = 'array-field'
|
||||
|
||||
@@ -25,6 +27,7 @@ type ArrayRowProps = {
|
||||
readonly fields: ClientField[]
|
||||
readonly forceRender?: boolean
|
||||
readonly hasMaxRows?: boolean
|
||||
readonly isLoading?: boolean
|
||||
readonly isSortable?: boolean
|
||||
readonly labels: Partial<ArrayField['labels']>
|
||||
readonly moveRow: (fromIndex: number, toIndex: number) => void
|
||||
@@ -50,6 +53,7 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
|
||||
forceRender = false,
|
||||
hasMaxRows,
|
||||
isDragging,
|
||||
isLoading: isLoadingFromProps,
|
||||
isSortable,
|
||||
labels,
|
||||
listeners,
|
||||
@@ -68,6 +72,8 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
|
||||
transform,
|
||||
transition,
|
||||
}) => {
|
||||
const isLoading = useThrottledValue(isLoadingFromProps, 500)
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
const hasSubmitted = useFormSubmitted()
|
||||
|
||||
@@ -136,17 +142,21 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
|
||||
isCollapsed={row.collapsed}
|
||||
onToggle={(collapsed) => setCollapse(row.id, collapsed)}
|
||||
>
|
||||
<RenderFields
|
||||
className={`${baseClass}__fields`}
|
||||
fields={fields}
|
||||
forceRender={forceRender}
|
||||
margins="small"
|
||||
parentIndexPath=""
|
||||
parentPath={path}
|
||||
parentSchemaPath={schemaPath}
|
||||
permissions={permissions === true ? permissions : permissions?.fields}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
{isLoading ? (
|
||||
<ShimmerEffect />
|
||||
) : (
|
||||
<RenderFields
|
||||
className={`${baseClass}__fields`}
|
||||
fields={fields}
|
||||
forceRender={forceRender}
|
||||
margins="small"
|
||||
parentIndexPath=""
|
||||
parentPath={path}
|
||||
parentSchemaPath={schemaPath}
|
||||
permissions={permissions === true ? permissions : permissions?.fields}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
)}
|
||||
</Collapsible>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -276,7 +276,7 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => {
|
||||
onDragEnd={({ moveFromIndex, moveToIndex }) => moveRow(moveFromIndex, moveToIndex)}
|
||||
>
|
||||
{rowsData.map((rowData, i) => {
|
||||
const { id: rowID } = rowData
|
||||
const { id: rowID, isLoading } = rowData
|
||||
|
||||
const rowPath = `${path}.${i}`
|
||||
|
||||
@@ -296,6 +296,7 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => {
|
||||
fields={fields}
|
||||
forceRender={forceRender}
|
||||
hasMaxRows={hasMaxRows}
|
||||
isLoading={isLoading}
|
||||
isSortable={isSortable}
|
||||
labels={labels}
|
||||
moveRow={moveRow}
|
||||
|
||||
Reference in New Issue
Block a user