diff --git a/packages/react-components/react-field/docs/Spec.md b/packages/react-components/react-field/docs/Spec.md index a1283134468bec..5b10dc8868b63e 100644 --- a/packages/react-components/react-field/docs/Spec.md +++ b/packages/react-components/react-field/docs/Spec.md @@ -2,7 +2,7 @@ ## Background -Field adds a label, validation text, and hint text to form input components. It can be added around any input components, such as `` or `` from this library, or intrinsic `` elements, or custom form controls. +Field adds a label, validation text, and hint text to form input components. It can be added around any form components from this library, such as `` or ``. Its child can also be a render function, which allows it to be used with intrinsic `` elements, or custom form controls. Epic issue tracking implementation: https://github.com/microsoft/fluentui/issues/19627 @@ -22,19 +22,24 @@ Existing libraries take one of several approaches to Field. The basic problem th - **Ant** - [`Form.Item`](https://ant.design/components/form/#Form.Item) (uses context to do some of the hooking up between the control and the Form.Item component). - **Atlaskit** - [`Field`](https://atlaskit.atlassian.com/packages/design-system/form/docs/fields) (uses a render function as the child of the Field to pass props). -The Field implementation in this spec follows pattern (4). Field passes props to its child to connect the field's label and message text. There are several reasons: +The Field implementation in this spec follows pattern (4). Field uses context for its child child to connect the field's label and message text. There are several reasons: -- **Accessibility**: All of the accessibility props like `aria-labelledby` and `aria-describedby` are set correctly on the child for "free". -- **Simplicity**: Passing props down to the children allows any form control to be used as the child of Field. -- **Consistency**: The Field component provides props like label, validationState, hint, etc. for any form control. +- **Accessibility**: All of the accessibility props like `aria-labelledby` and `aria-describedby` can be set correctly on the child via context. - **Bundle size**: When the label and other field functionality is not needed, it is still possible to use the core components like `Input` without pulling in unnecessary dependencies (like `Label` and the field styling). +- **Flexibility**: Using a context allows other components like Form validators or Tooltips between the field and its component. ## Sample Code ```jsx <> - - + + @@ -74,39 +79,10 @@ The Field implementation in this spec follows pattern (4). Field passes props to Field also forwards some props to its Label: - **Size**: Affects the size of the Label text (but not validationMessage or hint text). -- **Required**: If set, the Label will get a required asterisk: `*` +- **Required**: If set, the Label will get a required asterisk: `*`, and the component will set either `required` (if supported), or `aria-required`. ## API -`Field` applies props to its child component, to connect the label and message text to the control, and make the component accessible by default. - -The props added are: - -- `id` - Uses the child's `id` prop if set; otherwise generates an ID and sets it on the child. This is used as the label's `htmlFor`. -- `aria-labelledby` - The label's ID. -- `aria-describedby` - The validationMessage and/or hint's ID. -- `aria-invalid` - If validationState is error (which is the default when a validationMessage is set). -- `aria-required` - If the required prop is set. - -This is done one of two ways: - -- If the child is a component, uses `cloneElement` to add the props to the child's props. -- If the child is a render function, passes the props to the render function. That function is expected to spread the props in the appropriate place in its render tree. - -### FieldChildProps - -The `FieldChildProps` type defines the props that may be set on the child of Field (or passed to the child render function). - -```ts -/** - * The props added to the Field's child element. Or if the child is a render function, the props passed to the function. - */ -export type FieldChildProps = Pick< - React.HTMLAttributes, - 'id' | 'aria-labelledby' | 'aria-describedby' | 'aria-invalid' | 'aria-required' ->; -``` - ### Slots ```ts @@ -152,11 +128,11 @@ export type FieldProps = Omit, 'children'> & { * * All form controls in this library can be used directly as children (such as `` or ``), as well * as intrinsic form controls like `` or `