Skip to content

Commit 0b1a1b5

Browse files
authored
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`.
1 parent 3d129e8 commit 0b1a1b5

File tree

27 files changed

+134
-76
lines changed

27 files changed

+134
-76
lines changed

packages/richtext-lexical/src/field/Field.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ const RichTextComponent: React.FC<
6868

6969
const {
7070
customComponents: { AfterInput, BeforeInput, Description, Error, Label } = {},
71-
formInitializing,
72-
formProcessing,
71+
disabled: disabledFromField,
7372
initialValue,
7473
setValue,
7574
showError,
@@ -79,7 +78,7 @@ const RichTextComponent: React.FC<
7978
validate: memoizedValidate,
8079
})
8180

82-
const disabled = readOnlyFromProps || formProcessing || formInitializing
81+
const disabled = readOnlyFromProps || disabledFromField
8382

8483
const [isSmallWidthViewport, setIsSmallWidthViewport] = useState<boolean>(false)
8584
const [rerenderProviderKey, setRerenderProviderKey] = useState<Date>()

packages/richtext-slate/src/field/RichText.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
9595

9696
const {
9797
customComponents: { Description, Error, Label } = {},
98-
formInitializing,
98+
disabled: disabledFromField,
9999
initialValue,
100100
setValue,
101101
showError,
@@ -105,7 +105,7 @@ const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
105105
validate: memoizedValidate,
106106
})
107107

108-
const disabled = readOnlyFromProps || formInitializing
108+
const disabled = readOnlyFromProps || disabledFromField
109109

110110
const editor = useMemo(() => {
111111
let CreatedEditor = withEnterBreakOut(withHistory(withReact(createEditor())))

packages/ui/src/elements/DocumentFields/index.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const DocumentFields: React.FC<Args> = ({
2929
docPermissions,
3030
fields,
3131
forceSidebarWrap,
32-
readOnly: readOnlyProp,
32+
readOnly,
3333
schemaPathSegments,
3434
}) => {
3535
const { hasSidebarFields, mainFields, sidebarFields } = useMemo(() => {
@@ -53,11 +53,6 @@ export const DocumentFields: React.FC<Args> = ({
5353
)
5454
}, [fields])
5555

56-
const formInitializing = useFormInitializing()
57-
const formProcessing = useFormProcessing()
58-
59-
const readOnly = readOnlyProp || formInitializing || formProcessing
60-
6156
return (
6257
<div
6358
className={[

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => {
111111

112112
const {
113113
customComponents: { AfterInput, BeforeInput, Description, Error, Label, RowLabels } = {},
114+
disabled,
114115
errorPaths,
115116
rows: rowsData = [],
116117
showError,
@@ -197,7 +198,7 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => {
197198
const fieldErrorCount = errorPaths.length
198199
const fieldHasErrors = submitted && errorPaths.length > 0
199200

200-
const showRequired = readOnly && rowsData.length === 0
201+
const showRequired = (readOnly || disabled) && rowsData.length === 0
201202
const showMinRows = rowsData.length < minRows || (required && rowsData.length === 0)
202203

203204
return (
@@ -285,7 +286,11 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => {
285286
).length
286287

287288
return (
288-
<DraggableSortableItem disabled={readOnly || !isSortable} id={rowID} key={rowID}>
289+
<DraggableSortableItem
290+
disabled={readOnly || disabled || !isSortable}
291+
id={rowID}
292+
key={rowID}
293+
>
289294
{(draggableSortableItemProps) => (
290295
<ArrayRow
291296
{...draggableSortableItemProps}
@@ -303,7 +308,7 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => {
303308
parentPath={path}
304309
path={rowPath}
305310
permissions={permissions}
306-
readOnly={readOnly}
311+
readOnly={readOnly || disabled}
307312
removeRow={removeRow}
308313
row={rowData}
309314
rowCount={rowsData?.length}

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
5454
schemaPath: schemaPathFromProps,
5555
validate,
5656
} = props
57+
5758
const schemaPath = schemaPathFromProps ?? name
5859

5960
const minRows = (minRowsProp ?? required) ? 1 : 0
@@ -98,6 +99,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
9899

99100
const {
100101
customComponents: { AfterInput, BeforeInput, Description, Error, Label, RowLabels } = {},
102+
disabled,
101103
errorPaths,
102104
rows = [],
103105
showError,
@@ -276,7 +278,11 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
276278
).length
277279

278280
return (
279-
<DraggableSortableItem disabled={readOnly || !isSortable} id={row.id} key={row.id}>
281+
<DraggableSortableItem
282+
disabled={readOnly || disabled || !isSortable}
283+
id={row.id}
284+
key={row.id}
285+
>
280286
{(draggableSortableItemProps) => (
281287
<BlockRow
282288
{...draggableSortableItemProps}
@@ -295,7 +301,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
295301
parentPath={path}
296302
path={rowPath}
297303
permissions={permissions}
298-
readOnly={readOnly}
304+
readOnly={readOnly || disabled}
299305
removeRow={removeRow}
300306
row={row}
301307
rowCount={rows.length}
@@ -335,12 +341,12 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
335341
<Fragment>
336342
<DrawerToggler
337343
className={`${baseClass}__drawer-toggler`}
338-
disabled={readOnly}
344+
disabled={readOnly || disabled}
339345
slug={drawerSlug}
340346
>
341347
<Button
342348
buttonStyle="icon-label"
343-
disabled={readOnly}
349+
disabled={readOnly || disabled}
344350
el="span"
345351
icon="plus"
346352
iconPosition="left"

packages/ui/src/fields/Checkbox/index.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import { withCondition } from '../../forms/withCondition/index.js'
1818
import { useEditDepth } from '../../providers/EditDepth/index.js'
1919
import { generateFieldID } from '../../utilities/generateFieldID.js'
2020
import { mergeFieldStyles } from '../mergeFieldStyles.js'
21-
import './index.scss'
2221
import { fieldBaseClass } from '../shared/index.js'
2322
import { CheckboxInput } from './Input.js'
23+
import './index.scss'
2424

2525
const baseClass = 'checkbox'
2626

@@ -59,6 +59,7 @@ const CheckboxFieldComponent: CheckboxFieldClientComponent = (props) => {
5959

6060
const {
6161
customComponents: { AfterInput, BeforeInput, Description, Error, Label } = {},
62+
disabled,
6263
setValue,
6364
showError,
6465
value,
@@ -91,7 +92,7 @@ const CheckboxFieldComponent: CheckboxFieldClientComponent = (props) => {
9192
showError && 'error',
9293
className,
9394
value && `${baseClass}--checked`,
94-
readOnly && `${baseClass}--read-only`,
95+
(readOnly || disabled) && `${baseClass}--read-only`,
9596
]
9697
.filter(Boolean)
9798
.join(' ')}
@@ -112,7 +113,7 @@ const CheckboxFieldComponent: CheckboxFieldClientComponent = (props) => {
112113
name={path}
113114
onToggle={onToggle}
114115
partialChecked={partialChecked}
115-
readOnly={readOnly}
116+
readOnly={readOnly || disabled}
116117
required={required}
117118
/>
118119
<RenderCustomComponent

packages/ui/src/fields/Code/index.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const CodeFieldComponent: CodeFieldClientComponent = (props) => {
4747

4848
const {
4949
customComponents: { AfterInput, BeforeInput, Description, Error, Label } = {},
50+
disabled,
5051
setValue,
5152
showError,
5253
value,
@@ -64,7 +65,7 @@ const CodeFieldComponent: CodeFieldClientComponent = (props) => {
6465
baseClass,
6566
className,
6667
showError && 'error',
67-
readOnly && 'read-only',
68+
(readOnly || disabled) && 'read-only',
6869
]
6970
.filter(Boolean)
7071
.join(' ')}
@@ -84,10 +85,10 @@ const CodeFieldComponent: CodeFieldClientComponent = (props) => {
8485
{BeforeInput}
8586
<CodeEditor
8687
defaultLanguage={prismToMonacoLanguageMap[language] || language}
87-
onChange={readOnly ? () => null : (val) => setValue(val)}
88+
onChange={readOnly || disabled ? () => null : (val) => setValue(val)}
8889
onMount={onMount}
8990
options={editorOptions}
90-
readOnly={readOnly}
91+
readOnly={readOnly || disabled}
9192
value={(value as string) || ''}
9293
/>
9394
{AfterInput}

packages/ui/src/fields/Collapsible/index.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ const CollapsibleFieldComponent: CollapsibleFieldClientComponent = (props) => {
4242
const [errorCount, setErrorCount] = useState(0)
4343
const fieldHasErrors = errorCount > 0
4444

45-
const { customComponents: { AfterInput, BeforeInput, Description, Label } = {} } = useField({
46-
path,
47-
})
45+
const { customComponents: { AfterInput, BeforeInput, Description, Label } = {}, disabled } =
46+
useField({
47+
path,
48+
})
4849

4950
const onToggle = useCallback(
5051
async (newCollapsedState: boolean): Promise<void> => {
@@ -145,7 +146,7 @@ const CollapsibleFieldComponent: CollapsibleFieldClientComponent = (props) => {
145146
parentPath={parentPath}
146147
parentSchemaPath={parentSchemaPath}
147148
permissions={permissions}
148-
readOnly={readOnly}
149+
readOnly={readOnly || disabled}
149150
/>
150151
</CollapsibleElement>
151152
{AfterInput}

packages/ui/src/fields/ConfirmPassword/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ export type ConfirmPasswordFieldProps = {
1616
}
1717

1818
export const ConfirmPasswordField: React.FC<ConfirmPasswordFieldProps> = (props) => {
19-
const { disabled, path = 'confirm-password' } = props
19+
const { disabled: disabledFromProps, path = 'confirm-password' } = props
2020
const { t } = useTranslation()
2121

22-
const { setValue, showError, value } = useField({
22+
const { disabled, setValue, showError, value } = useField({
2323
path,
2424
validate: (value, options) => {
2525
return confirmPassword(value, {
@@ -47,7 +47,7 @@ export const ConfirmPasswordField: React.FC<ConfirmPasswordFieldProps> = (props)
4747
<input
4848
aria-label={t('authentication:confirmPassword')}
4949
autoComplete="off"
50-
disabled={!!disabled}
50+
disabled={!!(disabled || disabledFromProps)}
5151
id="field-confirm-password"
5252
name="confirm-password"
5353
onChange={setValue}

packages/ui/src/fields/DateTime/index.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
5858

5959
const {
6060
customComponents: { AfterInput, BeforeInput, Description, Error, Label } = {},
61+
disabled,
6162
setValue,
6263
showError,
6364
value,
@@ -102,7 +103,7 @@ const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
102103

103104
const onChange = useCallback(
104105
(incomingDate: Date) => {
105-
if (!readOnly) {
106+
if (!(readOnly || disabled)) {
106107
if (timezone && selectedTimezone && incomingDate) {
107108
// Create TZDate instances for the selected timezone
108109
const TZDateWithSelectedTz = TZDate.tz(selectedTimezone)
@@ -132,7 +133,7 @@ const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
132133
}
133134
}
134135
},
135-
[readOnly, setValue, timezone, selectedTimezone],
136+
[readOnly, disabled, timezone, selectedTimezone, isDateOnly, setValue],
136137
)
137138

138139
const onChangeTimezone = useCallback(
@@ -157,7 +158,7 @@ const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
157158
baseClass,
158159
className,
159160
showError && `${baseClass}--has-error`,
160-
readOnly && 'read-only',
161+
(readOnly || disabled) && 'read-only',
161162
]
162163
.filter(Boolean)
163164
.join(' ')}
@@ -180,7 +181,7 @@ const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
180181
...datePickerProps?.overrides,
181182
}}
182183
placeholder={getTranslation(placeholder, i18n)}
183-
readOnly={readOnly}
184+
readOnly={readOnly || disabled}
184185
value={displayedValue}
185186
/>
186187
{timezone && supportedTimezones.length > 0 && (

0 commit comments

Comments
 (0)