Skip to content

Commit ea94ff9

Browse files
committed
fix(ui-form-field): disable child inputs when FormFieldGroup is disabled
INSTUI-4841
1 parent 028c54b commit ea94ff9

4 files changed

Lines changed: 73 additions & 12 deletions

File tree

docs/guides/upgrade-guide.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ type: embed
585585

586586
`error` or `success` messages are no longer displayed when the component is `readOnly` or `disabled`.
587587

588+
Setting `disabled` on `FormFieldGroup` now also disables its children. Previously, the `disabled` prop only applied disabled styles to the group container while leaving child inputs interactive.
589+
588590
```js
589591
---
590592
type: embed

packages/ui-form-field/src/FormFieldGroup/__tests__/FormFieldGroup.test.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,52 @@ describe('<FormFieldGroup />', () => {
157157
expect(legend).toHaveTextContent(description)
158158
})
159159

160+
it('disables children when disabled', () => {
161+
const TestComponent = ({ disabled }: { disabled?: boolean }) => (
162+
<input data-testid="test-input" disabled={disabled} />
163+
)
164+
165+
render(
166+
<FormFieldGroup description="Test group" disabled>
167+
<TestComponent />
168+
</FormFieldGroup>
169+
)
170+
171+
expect(screen.getByTestId('test-input')).toBeDisabled()
172+
})
173+
174+
it('disables all children when disabled', () => {
175+
const TestComponent = ({ disabled }: { disabled?: boolean }) => (
176+
<input data-testid="test-input" disabled={disabled} />
177+
)
178+
179+
render(
180+
<FormFieldGroup description="Test group" disabled>
181+
<TestComponent data-testid="first" />
182+
<TestComponent data-testid="second" />
183+
<TestComponent data-testid="third" />
184+
</FormFieldGroup>
185+
)
186+
187+
screen.getAllByTestId('test-input').forEach((input) => {
188+
expect(input).toBeDisabled()
189+
})
190+
})
191+
192+
it('does not disable children when not disabled', () => {
193+
const TestComponent = ({ disabled }: { disabled?: boolean }) => (
194+
<input data-testid="test-input" disabled={disabled} />
195+
)
196+
197+
render(
198+
<FormFieldGroup description="Test group">
199+
<TestComponent />
200+
</FormFieldGroup>
201+
)
202+
203+
expect(screen.getByTestId('test-input')).not.toBeDisabled()
204+
})
205+
160206
it('should meet a11y standards', async () => {
161207
const { container } = render(
162208
<FormFieldGroup description="Please enter your full name">

packages/ui-form-field/src/FormFieldGroup/v2/index.tsx

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,20 @@
2222
* SOFTWARE.
2323
*/
2424

25-
import { Component, Children, ReactElement, AriaAttributes } from 'react'
25+
import {
26+
Component,
27+
Children,
28+
ReactElement,
29+
AriaAttributes,
30+
isValidElement
31+
} from 'react'
2632

2733
import { Grid } from '@instructure/ui-grid/latest'
28-
import { pickProps, omitProps } from '@instructure/ui-react-utils'
34+
import {
35+
pickProps,
36+
omitProps,
37+
safeCloneElement
38+
} from '@instructure/ui-react-utils'
2939
import { withStyleNew } from '@instructure/emotion'
3040

3141
import { allowedProps as formFieldLayoutAllowedProps } from '../../FormFieldLayout/v2/props'
@@ -86,20 +96,22 @@ class FormFieldGroup extends Component<FormFieldGroupProps> {
8696
}
8797

8898
renderColumns() {
99+
const { disabled } = this.props
89100
return Children.map(this.props.children, (child, index) => {
90-
return child ? (
101+
if (!child) return null
102+
const el = child as ReactElement<any>
103+
const renderedChild =
104+
disabled && isValidElement(el)
105+
? safeCloneElement(el, { disabled: true })
106+
: child
107+
return (
91108
<Grid.Col
92-
width={
93-
(child as ReactElement).props &&
94-
(child as ReactElement<any>).props.width
95-
? 'auto'
96-
: undefined
97-
}
109+
width={el.props && el.props.width ? 'auto' : undefined}
98110
key={index}
99111
>
100-
{child}
112+
{renderedChild}
101113
</Grid.Col>
102-
) : null
114+
)
103115
})
104116
}
105117

packages/ui-form-field/src/FormFieldGroup/v2/props.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ type FormFieldGroupOwnProps = {
4848
*/
4949
messagesId?: string
5050
/**
51-
* Whether the field group is disabled. When true, error and success messages will be hidden.
51+
* Whether the field group is disabled. When true, the disabled prop is propagated to all
52+
* child components, error and success messages will be hidden.
5253
*/
5354
disabled?: boolean
5455
/**

0 commit comments

Comments
 (0)