From 0b1a1b585b9a11b574341ed3bbdc3ecdc4c9b235 Mon Sep 17 00:00:00 2001 From: Jacob Fletcher Date: Mon, 17 Mar 2025 10:27:21 -0400 Subject: [PATCH] fix(ui): processing and initializing form does not disable standalone fields (#11714) The form component's `initializing` and `processing` states do not disable fields that are rendered outside of `DocumentFields`. Fields currently rely on the `readOnly` prop provided by `DocumentFields` and do not subscribe to these states for themselves. This means that fields that are rendered outright, such as within the bulk edit drawer, they do not receive a `readOnly` prop and are therefore never disabled. The fix is add a `disabled` property to the `useField` hook. This subscribes to the `initializing` and `processing` states in the same way as `DocumentFields`, however, now each field can determine its own disabled state instead of relying solely on the `readOnly` prop. Adding this new prop has no overhead as `processing` and `initializing` is already being subscribed to within `useField`. --- packages/richtext-lexical/src/field/Field.tsx | 5 +-- .../richtext-slate/src/field/RichText.tsx | 4 +- .../ui/src/elements/DocumentFields/index.tsx | 7 +--- packages/ui/src/fields/Array/index.tsx | 11 ++++-- packages/ui/src/fields/Blocks/index.tsx | 14 +++++-- packages/ui/src/fields/Checkbox/index.tsx | 7 ++-- packages/ui/src/fields/Code/index.tsx | 7 ++-- packages/ui/src/fields/Collapsible/index.tsx | 9 +++-- .../ui/src/fields/ConfirmPassword/index.tsx | 6 +-- packages/ui/src/fields/DateTime/index.tsx | 9 +++-- packages/ui/src/fields/Email/index.tsx | 11 +++++- packages/ui/src/fields/Group/index.tsx | 2 + packages/ui/src/fields/JSON/index.tsx | 10 +++-- packages/ui/src/fields/Number/index.tsx | 11 +++--- packages/ui/src/fields/Password/index.tsx | 7 +--- packages/ui/src/fields/Point/index.tsx | 7 ++-- packages/ui/src/fields/RadioGroup/index.tsx | 7 ++-- packages/ui/src/fields/Relationship/index.tsx | 11 +++--- packages/ui/src/fields/Select/index.tsx | 7 ++-- packages/ui/src/fields/Tabs/index.tsx | 2 + packages/ui/src/fields/Text/index.tsx | 7 ++-- packages/ui/src/fields/Textarea/index.tsx | 3 +- packages/ui/src/fields/Upload/index.tsx | 3 +- packages/ui/src/forms/useField/index.tsx | 1 + packages/ui/src/forms/useField/types.ts | 1 + test/form-state/e2e.spec.ts | 39 ++++++++++++++++--- tsconfig.base.json | 2 +- 27 files changed, 134 insertions(+), 76 deletions(-) diff --git a/packages/richtext-lexical/src/field/Field.tsx b/packages/richtext-lexical/src/field/Field.tsx index 98a4fbeb7..3b10ed529 100644 --- a/packages/richtext-lexical/src/field/Field.tsx +++ b/packages/richtext-lexical/src/field/Field.tsx @@ -68,8 +68,7 @@ const RichTextComponent: React.FC< const { customComponents: { AfterInput, BeforeInput, Description, Error, Label } = {}, - formInitializing, - formProcessing, + disabled: disabledFromField, initialValue, setValue, showError, @@ -79,7 +78,7 @@ const RichTextComponent: React.FC< validate: memoizedValidate, }) - const disabled = readOnlyFromProps || formProcessing || formInitializing + const disabled = readOnlyFromProps || disabledFromField const [isSmallWidthViewport, setIsSmallWidthViewport] = useState(false) const [rerenderProviderKey, setRerenderProviderKey] = useState() diff --git a/packages/richtext-slate/src/field/RichText.tsx b/packages/richtext-slate/src/field/RichText.tsx index 03a0ca15c..1effc7eb0 100644 --- a/packages/richtext-slate/src/field/RichText.tsx +++ b/packages/richtext-slate/src/field/RichText.tsx @@ -95,7 +95,7 @@ const RichTextField: React.FC = (props) => { const { customComponents: { Description, Error, Label } = {}, - formInitializing, + disabled: disabledFromField, initialValue, setValue, showError, @@ -105,7 +105,7 @@ const RichTextField: React.FC = (props) => { validate: memoizedValidate, }) - const disabled = readOnlyFromProps || formInitializing + const disabled = readOnlyFromProps || disabledFromField const editor = useMemo(() => { let CreatedEditor = withEnterBreakOut(withHistory(withReact(createEditor()))) diff --git a/packages/ui/src/elements/DocumentFields/index.tsx b/packages/ui/src/elements/DocumentFields/index.tsx index 303f6ba67..bf65c01cd 100644 --- a/packages/ui/src/elements/DocumentFields/index.tsx +++ b/packages/ui/src/elements/DocumentFields/index.tsx @@ -29,7 +29,7 @@ export const DocumentFields: React.FC = ({ docPermissions, fields, forceSidebarWrap, - readOnly: readOnlyProp, + readOnly, schemaPathSegments, }) => { const { hasSidebarFields, mainFields, sidebarFields } = useMemo(() => { @@ -53,11 +53,6 @@ export const DocumentFields: React.FC = ({ ) }, [fields]) - const formInitializing = useFormInitializing() - const formProcessing = useFormProcessing() - - const readOnly = readOnlyProp || formInitializing || formProcessing - return (
{ const { customComponents: { AfterInput, BeforeInput, Description, Error, Label, RowLabels } = {}, + disabled, errorPaths, rows: rowsData = [], showError, @@ -197,7 +198,7 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => { const fieldErrorCount = errorPaths.length const fieldHasErrors = submitted && errorPaths.length > 0 - const showRequired = readOnly && rowsData.length === 0 + const showRequired = (readOnly || disabled) && rowsData.length === 0 const showMinRows = rowsData.length < minRows || (required && rowsData.length === 0) return ( @@ -285,7 +286,11 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => { ).length return ( - + {(draggableSortableItemProps) => ( { parentPath={path} path={rowPath} permissions={permissions} - readOnly={readOnly} + readOnly={readOnly || disabled} removeRow={removeRow} row={rowData} rowCount={rowsData?.length} diff --git a/packages/ui/src/fields/Blocks/index.tsx b/packages/ui/src/fields/Blocks/index.tsx index e0904f650..8b68ebf6d 100644 --- a/packages/ui/src/fields/Blocks/index.tsx +++ b/packages/ui/src/fields/Blocks/index.tsx @@ -54,6 +54,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { schemaPath: schemaPathFromProps, validate, } = props + const schemaPath = schemaPathFromProps ?? name const minRows = (minRowsProp ?? required) ? 1 : 0 @@ -98,6 +99,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { const { customComponents: { AfterInput, BeforeInput, Description, Error, Label, RowLabels } = {}, + disabled, errorPaths, rows = [], showError, @@ -276,7 +278,11 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => { ).length return ( - + {(draggableSortableItemProps) => ( { parentPath={path} path={rowPath} permissions={permissions} - readOnly={readOnly} + readOnly={readOnly || disabled} removeRow={removeRow} row={row} rowCount={rows.length} @@ -335,12 +341,12 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {