@fluentui/react-field 9.0.0-alpha.15 → 9.0.0-alpha.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. package/CHANGELOG.json +67 -1
  2. package/CHANGELOG.md +26 -2
  3. package/dist/index.d.ts +60 -86
  4. package/lib/components/Field/Field.js +11 -0
  5. package/lib/components/Field/Field.js.map +1 -0
  6. package/lib/components/Field/Field.types.js.map +1 -1
  7. package/lib/components/Field/index.js +1 -0
  8. package/lib/components/Field/index.js.map +1 -1
  9. package/lib/components/Field/renderField.js +4 -6
  10. package/lib/components/Field/renderField.js.map +1 -1
  11. package/lib/components/Field/useField.js +39 -72
  12. package/lib/components/Field/useField.js.map +1 -1
  13. package/lib/components/Field/useFieldStyles.js +48 -70
  14. package/lib/components/Field/useFieldStyles.js.map +1 -1
  15. package/lib/index.js +3 -1
  16. package/lib/index.js.map +1 -1
  17. package/lib/util/makeDeprecatedField.js +71 -0
  18. package/lib/util/makeDeprecatedField.js.map +1 -0
  19. package/lib-amd/components/Field/Field.js +12 -0
  20. package/lib-amd/components/Field/Field.js.map +1 -0
  21. package/lib-amd/components/Field/Field.types.js.map +1 -1
  22. package/lib-amd/components/Field/index.js +2 -1
  23. package/lib-amd/components/Field/index.js.map +1 -1
  24. package/lib-amd/components/Field/renderField.js +4 -3
  25. package/lib-amd/components/Field/renderField.js.map +1 -1
  26. package/lib-amd/components/Field/useField.js +31 -53
  27. package/lib-amd/components/Field/useField.js.map +1 -1
  28. package/lib-amd/components/Field/useFieldStyles.js +55 -58
  29. package/lib-amd/components/Field/useFieldStyles.js.map +1 -1
  30. package/lib-amd/index.js +6 -3
  31. package/lib-amd/index.js.map +1 -1
  32. package/lib-amd/util/makeDeprecatedField.js +38 -0
  33. package/lib-amd/util/makeDeprecatedField.js.map +1 -0
  34. package/lib-commonjs/components/Field/Field.js +17 -0
  35. package/lib-commonjs/components/Field/Field.js.map +1 -0
  36. package/lib-commonjs/components/Field/index.js +1 -0
  37. package/lib-commonjs/components/Field/index.js.map +1 -1
  38. package/lib-commonjs/components/Field/renderField.js +4 -6
  39. package/lib-commonjs/components/Field/renderField.js.map +1 -1
  40. package/lib-commonjs/components/Field/useField.js +40 -74
  41. package/lib-commonjs/components/Field/useField.js.map +1 -1
  42. package/lib-commonjs/components/Field/useFieldStyles.js +48 -71
  43. package/lib-commonjs/components/Field/useFieldStyles.js.map +1 -1
  44. package/lib-commonjs/index.js +23 -3
  45. package/lib-commonjs/index.js.map +1 -1
  46. package/lib-commonjs/util/makeDeprecatedField.js +79 -0
  47. package/lib-commonjs/util/makeDeprecatedField.js.map +1 -0
  48. package/package.json +5 -4
  49. package/lib/components/Field/SlotComponent.types.js +0 -2
  50. package/lib/components/Field/SlotComponent.types.js.map +0 -1
  51. package/lib-amd/components/Field/SlotComponent.types.js +0 -5
  52. package/lib-amd/components/Field/SlotComponent.types.js.map +0 -1
  53. package/lib-commonjs/components/Field/SlotComponent.types.js +0 -6
  54. package/lib-commonjs/components/Field/SlotComponent.types.js.map +0 -1
package/CHANGELOG.json CHANGED
@@ -2,7 +2,73 @@
2
2
  "name": "@fluentui/react-field",
3
3
  "entries": [
4
4
  {
5
- "date": "Mon, 16 Jan 2023 08:35:37 GMT",
5
+ "date": "Thu, 26 Jan 2023 13:27:46 GMT",
6
+ "tag": "@fluentui/react-field_v9.0.0-alpha.17",
7
+ "version": "9.0.0-alpha.17",
8
+ "comments": {
9
+ "prerelease": [
10
+ {
11
+ "author": "behowell@microsoft.com",
12
+ "package": "@fluentui/react-field",
13
+ "commit": "d6e98c0b5390c5c7e03601537b2026307e01a8d4",
14
+ "comment": "Implement Field component to replace InputField, ComboboxField, etc."
15
+ },
16
+ {
17
+ "author": "beachball",
18
+ "package": "@fluentui/react-field",
19
+ "comment": "Bump @fluentui/react-context-selector to v9.1.6",
20
+ "commit": "403e1370f1effca7d3db131eda381abf31cf66b1"
21
+ },
22
+ {
23
+ "author": "beachball",
24
+ "package": "@fluentui/react-field",
25
+ "comment": "Bump @fluentui/react-label to v9.0.18",
26
+ "commit": "403e1370f1effca7d3db131eda381abf31cf66b1"
27
+ },
28
+ {
29
+ "author": "beachball",
30
+ "package": "@fluentui/react-field",
31
+ "comment": "Bump @fluentui/react-utilities to v9.5.0",
32
+ "commit": "403e1370f1effca7d3db131eda381abf31cf66b1"
33
+ }
34
+ ]
35
+ }
36
+ },
37
+ {
38
+ "date": "Mon, 23 Jan 2023 16:43:09 GMT",
39
+ "tag": "@fluentui/react-field_v9.0.0-alpha.16",
40
+ "version": "9.0.0-alpha.16",
41
+ "comments": {
42
+ "prerelease": [
43
+ {
44
+ "author": "behowell@microsoft.com",
45
+ "package": "@fluentui/react-field",
46
+ "commit": "1f145044a1ef3707e0724d75f9b70e7d2af69375",
47
+ "comment": "chore: Simplify Field layout styles"
48
+ },
49
+ {
50
+ "author": "behowell@microsoft.com",
51
+ "package": "@fluentui/react-field",
52
+ "commit": "b04b2f0c02f2ccd7960905a886ce27f2321fee72",
53
+ "comment": "fix: Stretch Field components to full width"
54
+ },
55
+ {
56
+ "author": "behowell@microsoft.com",
57
+ "package": "@fluentui/react-field",
58
+ "commit": "48a6fc95e6eb7530c162390fb70db7fac88b15ab",
59
+ "comment": "fix: Update Field label padding to match spec"
60
+ },
61
+ {
62
+ "author": "behowell@microsoft.com",
63
+ "package": "@fluentui/react-field",
64
+ "commit": "014041b7447b02856ae50638de71bdb829b0a759",
65
+ "comment": "fix: Field sets role=\"alert\" on its error message so it is announced by screen readers"
66
+ }
67
+ ]
68
+ }
69
+ },
70
+ {
71
+ "date": "Mon, 16 Jan 2023 08:39:01 GMT",
6
72
  "tag": "@fluentui/react-field_v9.0.0-alpha.15",
7
73
  "version": "9.0.0-alpha.15",
8
74
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,12 +1,36 @@
1
1
  # Change Log - @fluentui/react-field
2
2
 
3
- This log was last generated on Mon, 16 Jan 2023 08:35:37 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 26 Jan 2023 13:27:46 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.0.0-alpha.17](https://github.com/microsoft/fluentui/tree/@fluentui/react-field_v9.0.0-alpha.17)
8
+
9
+ Thu, 26 Jan 2023 13:27:46 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-field_v9.0.0-alpha.16..@fluentui/react-field_v9.0.0-alpha.17)
11
+
12
+ ### Changes
13
+
14
+ - Implement Field component to replace InputField, ComboboxField, etc. ([PR #26430](https://github.com/microsoft/fluentui/pull/26430) by behowell@microsoft.com)
15
+ - Bump @fluentui/react-context-selector to v9.1.6 ([PR #26496](https://github.com/microsoft/fluentui/pull/26496) by beachball)
16
+ - Bump @fluentui/react-label to v9.0.18 ([PR #26496](https://github.com/microsoft/fluentui/pull/26496) by beachball)
17
+ - Bump @fluentui/react-utilities to v9.5.0 ([PR #26496](https://github.com/microsoft/fluentui/pull/26496) by beachball)
18
+
19
+ ## [9.0.0-alpha.16](https://github.com/microsoft/fluentui/tree/@fluentui/react-field_v9.0.0-alpha.16)
20
+
21
+ Mon, 23 Jan 2023 16:43:09 GMT
22
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-field_v9.0.0-alpha.15..@fluentui/react-field_v9.0.0-alpha.16)
23
+
24
+ ### Changes
25
+
26
+ - chore: Simplify Field layout styles ([PR #26352](https://github.com/microsoft/fluentui/pull/26352) by behowell@microsoft.com)
27
+ - fix: Stretch Field components to full width ([PR #26412](https://github.com/microsoft/fluentui/pull/26412) by behowell@microsoft.com)
28
+ - fix: Update Field label padding to match spec ([PR #26413](https://github.com/microsoft/fluentui/pull/26413) by behowell@microsoft.com)
29
+ - fix: Field sets role="alert" on its error message so it is announced by screen readers ([PR #26414](https://github.com/microsoft/fluentui/pull/26414) by behowell@microsoft.com)
30
+
7
31
  ## [9.0.0-alpha.15](https://github.com/microsoft/fluentui/tree/@fluentui/react-field_v9.0.0-alpha.15)
8
32
 
9
- Mon, 16 Jan 2023 08:35:37 GMT
33
+ Mon, 16 Jan 2023 08:39:01 GMT
10
34
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-field_v9.0.0-alpha.14..@fluentui/react-field_v9.0.0-alpha.15)
11
35
 
12
36
  ### Changes
package/dist/index.d.ts CHANGED
@@ -2,55 +2,45 @@
2
2
 
3
3
  import type { ComponentProps } from '@fluentui/react-utilities';
4
4
  import type { ComponentState } from '@fluentui/react-utilities';
5
+ import { ForwardRefComponent } from '@fluentui/react-utilities';
5
6
  import { Label } from '@fluentui/react-label';
6
7
  import * as React_2 from 'react';
7
8
  import type { Slot } from '@fluentui/react-utilities';
8
9
  import type { SlotClassNames } from '@fluentui/react-utilities';
9
- import type { SlotRenderFunction } from '@fluentui/react-utilities';
10
- import type { SlotShorthandValue } from '@fluentui/react-utilities';
11
10
 
12
11
  /**
13
- * Configuration parameters for a Field class, passed to useField_unstable
12
+ * @deprecated Only for use to make deprecated [Control]Field shim components.
13
+ * @internal
14
14
  */
15
- export declare type FieldConfig<T extends FieldControl> = {
16
- /**
17
- * The underlying input component that this field is wrapping.
18
- */
19
- component: T;
20
- /**
21
- * Class names for this component, created by `getFieldClassNames`.
22
- */
23
- classNames: SlotClassNames<FieldSlots<T>>;
24
- /**
25
- * How the label be connected to the control.
26
- * * htmlFor - Set the Label's htmlFor prop to the component's ID (and generate an ID if not provided).
27
- * This is the preferred method for components that use the underlying <input> tag.
28
- * * aria-labelledby - Set the component's aria-labelledby prop to the Label's ID. Use this for components
29
- * that are not directly <input> elements (such as RadioGroup).
30
- *
31
- * @default htmlFor
32
- */
33
- labelConnection?: 'htmlFor' | 'aria-labelledby';
34
- /**
35
- * Should the aria-invalid attribute be set when validationState="error".
36
- *
37
- * @default true
38
- */
39
- ariaInvalidOnError?: boolean;
40
- };
15
+ export declare type DeprecatedFieldProps<ControlProps> = ControlProps & {
16
+ root?: FieldProps;
17
+ control?: ControlProps;
18
+ } & Pick<FieldProps, 'className' | 'hint' | 'label' | 'orientation' | 'style' | 'validationMessage' | 'validationMessageIcon' | 'validationState'>;
19
+
20
+ export declare const Field: ForwardRefComponent<FieldProps>;
41
21
 
42
22
  /**
43
- * The minimum requirement for a component used by Field.
44
- *
45
- * Note: the use of VoidFunctionComponent means that component is not *required* to have a children prop,
46
- * but it is still allowed to have a children prop.
23
+ * The props added to the Field's child element.
47
24
  */
48
- export declare type FieldControl = React_2.VoidFunctionComponent<Pick<React_2.HTMLAttributes<HTMLElement>, 'id' | 'className' | 'style' | 'aria-labelledby' | 'aria-describedby' | 'aria-invalid'>>;
25
+ declare type FieldChildProps = Pick<React_2.HTMLAttributes<HTMLElement>, 'id' | 'aria-labelledby' | 'aria-describedby' | 'aria-invalid' | 'aria-required'>;
26
+
27
+ export declare const fieldClassNames: SlotClassNames<FieldSlots>;
49
28
 
50
29
  /**
51
30
  * Field Props
52
31
  */
53
- export declare type FieldProps<T extends FieldControl> = ComponentProps<Partial<FieldSlots<T>>, 'control'> & {
32
+ export declare type FieldProps = Omit<ComponentProps<FieldSlots>, 'children'> & {
33
+ /**
34
+ * The Field's child can be a single form control, or a render function that takes the props that should be spread on
35
+ * a form control.
36
+ *
37
+ * All form controls in this library can be used directly as children (such as `<Input>` or `<RadioGroup>`), as well
38
+ * as intrinsic form controls like `<input>` or `<textarea>`. Custom controls can also be used as long as they
39
+ * accept FieldChildProps and spread them on the appropriate element.
40
+ *
41
+ * For more complex scenarios, a render function can be used to pass the FieldChildProps to the appropriate control.
42
+ */
43
+ children?: React_2.ReactElement<FieldChildProps> | null | ((props: FieldChildProps) => React_2.ReactNode);
54
44
  /**
55
45
  * The orientation of the label relative to the field component.
56
46
  * This only affects the label, and not the validationMessage or hint (which always appear below the field component).
@@ -59,47 +49,30 @@ export declare type FieldProps<T extends FieldControl> = ComponentProps<Partial<
59
49
  */
60
50
  orientation?: 'vertical' | 'horizontal';
61
51
  /**
62
- * The `validationState` affects the color of the `validationMessage`, the `validationMessageIcon`, and for some
63
- * field components, an `validationState="error"` causes the border to become red.
52
+ * The `validationState` affects the color of the `validationMessage`, the `validationMessageIcon`
64
53
  *
65
- * @default undefined
54
+ * Setting `validationState` to `error` will also set `aria-invalid` to `true` on the Field's child,
55
+ * `role="alert"` on the `validationMessage`, and for some field components, causes the border to become red.
66
56
  */
67
57
  validationState?: 'error' | 'warning' | 'success';
68
- };
69
-
70
- /**
71
- * FieldProps plus extra optional props that are supported by useField_unstable, but not required to be part of the
72
- * API of every Field component.
73
- *
74
- * This allows Field to forward the required and size props to the label if the underlying component supports them,
75
- * but doesn't add them to the public API of fields that don't support them.
76
- */
77
- declare type FieldPropsWithOptionalComponentProps<T extends FieldControl> = FieldProps<T> & {
78
58
  /**
79
- * A ref to the underlying control.
80
- */
81
- ref?: React_2.Ref<HTMLElement>;
82
- /**
83
- * Whether the field label should be marked as required.
59
+ * Marks the Field as required. If `true`, an asterisk will be appended to the label, and `aria-required` will be set
60
+ * on the Field's child.
84
61
  */
85
62
  required?: boolean;
86
63
  /**
87
- * Size of the field label.
64
+ * The size of the Field's label.
88
65
  *
89
- * Number sizes will be ignored, but are allowed because the HTML `<input>` element has a prop `size?: number`.
66
+ * @default medium
90
67
  */
91
- size?: 'small' | 'medium' | 'large' | number;
68
+ size?: 'small' | 'medium' | 'large';
92
69
  };
93
70
 
94
71
  /**
95
- * Slots added by Field
72
+ * Slots of the Field component
96
73
  */
97
- export declare type FieldSlots<T extends FieldControl> = {
74
+ export declare type FieldSlots = {
98
75
  root: NonNullable<Slot<'div'>>;
99
- /**
100
- * The underlying component wrapped by this field.
101
- */
102
- control: SlotComponent<T>;
103
76
  /**
104
77
  * The label associated with the field.
105
78
  */
@@ -124,22 +97,34 @@ export declare type FieldSlots<T extends FieldControl> = {
124
97
  /**
125
98
  * State used in rendering Field
126
99
  */
127
- export declare type FieldState<T extends FieldControl> = ComponentState<Required<FieldSlots<T>>> & Pick<FieldProps<T>, 'orientation' | 'validationState'> & {
128
- classNames: SlotClassNames<FieldSlots<T>>;
100
+ export declare type FieldState = ComponentState<Required<FieldSlots>> & Pick<FieldProps, 'orientation' | 'validationState'>;
101
+
102
+ /**
103
+ * @deprecated Only for use to make deprecated [Control]Field shim components.
104
+ * @internal
105
+ */
106
+ export declare const getDeprecatedFieldClassNames: (controlRootClassName: string) => {
107
+ control: string;
108
+ root: string;
109
+ label: string;
110
+ validationMessage: string;
111
+ validationMessageIcon: string;
112
+ hint: string;
129
113
  };
130
114
 
131
- export declare const getFieldClassNames: (name: string) => SlotClassNames<FieldSlots<FieldControl>>;
115
+ /**
116
+ * @deprecated Only for use to make deprecated [Control]Field shim components.
117
+ * @internal
118
+ */
119
+ export declare function makeDeprecatedField<ControlProps>(Control: React_2.ComponentType<ControlProps>, options?: {
120
+ mapProps?: (props: DeprecatedFieldProps<ControlProps>) => DeprecatedFieldProps<ControlProps>;
121
+ displayName?: string;
122
+ }): ForwardRefComponent<DeprecatedFieldProps<ControlProps>>;
132
123
 
133
124
  /**
134
125
  * Render the final JSX of Field
135
126
  */
136
- export declare const renderField_unstable: <T extends FieldControl>(state: FieldState<T>) => JSX.Element;
137
-
138
- declare type SlotComponent<Type extends React_2.ComponentType | React_2.VoidFunctionComponent> = WithSlotShorthandValue<Type extends React_2.ComponentType<infer Props> ? WithSlotRenderFunction<Props extends {
139
- children?: unknown;
140
- } ? Props : Props & {
141
- children?: never;
142
- }> : never>;
127
+ export declare const renderField_unstable: (state: FieldState) => JSX.Element;
143
128
 
144
129
  /**
145
130
  * Create the state required to render Field.
@@ -148,24 +133,13 @@ declare type SlotComponent<Type extends React_2.ComponentType | React_2.VoidFunc
148
133
  * before being passed to renderField_unstable.
149
134
  *
150
135
  * @param props - Props passed to this field
151
- * @param ref - Ref to the control slot (primary slot)
152
- * @param params - Configuration parameters for this Field
136
+ * @param ref - Ref to the root
153
137
  */
154
- export declare const useField_unstable: <T extends FieldControl>(props: FieldPropsWithOptionalComponentProps<T>, ref: React_2.Ref<HTMLElement>, params: FieldConfig<T>) => FieldState<T>;
138
+ export declare const useField_unstable: (props: FieldProps, ref: React_2.Ref<HTMLDivElement>) => FieldState;
155
139
 
156
140
  /**
157
141
  * Apply styling to the Field slots based on the state
158
142
  */
159
- export declare const useFieldStyles_unstable: <T extends FieldControl>(state: FieldState<T>) => void;
160
-
161
- declare type WithSlotRenderFunction<Props extends {
162
- children?: unknown;
163
- }> = Props & {
164
- children?: Props['children'] | SlotRenderFunction<Props>;
165
- };
166
-
167
- declare type WithSlotShorthandValue<Props extends {
168
- children?: unknown;
169
- }> = Props | Extract<SlotShorthandValue, Props['children']>;
143
+ export declare const useFieldStyles_unstable: (state: FieldState) => void;
170
144
 
171
145
  export { }
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ import { renderField_unstable } from './renderField';
3
+ import { useField_unstable } from './useField';
4
+ import { useFieldStyles_unstable } from './useFieldStyles';
5
+ export const Field = /*#__PURE__*/React.forwardRef((props, ref) => {
6
+ const state = useField_unstable(props, ref);
7
+ useFieldStyles_unstable(state);
8
+ return renderField_unstable(state);
9
+ });
10
+ Field.displayName = 'Field';
11
+ //# sourceMappingURL=Field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAG9B,SAASC,oBAAoB,QAAQ,eAAe;AACpD,SAASC,iBAAiB,QAAQ,YAAY;AAC9C,SAASC,uBAAuB,QAAQ,kBAAkB;AAE1D,OAAO,MAAMC,KAAK,gBAAoCJ,KAAK,CAACK,UAAU,CAAC,CAACC,KAAK,EAAEC,GAAG,KAAI;EACpF,MAAMC,KAAK,GAAGN,iBAAiB,CAACI,KAAK,EAAEC,GAAG,CAAC;EAC3CJ,uBAAuB,CAACK,KAAK,CAAC;EAC9B,OAAOP,oBAAoB,CAACO,KAAK,CAAC;AACpC,CAAC,CAAC;AAEFJ,KAAK,CAACK,WAAW,GAAG,OAAO","names":["React","renderField_unstable","useField_unstable","useFieldStyles_unstable","Field","forwardRef","props","ref","state","displayName"],"sourceRoot":"../src/","sources":["packages/react-components/react-field/src/components/Field/Field.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport type { FieldProps } from './Field.types';\nimport { renderField_unstable } from './renderField';\nimport { useField_unstable } from './useField';\nimport { useFieldStyles_unstable } from './useFieldStyles';\n\nexport const Field: ForwardRefComponent<FieldProps> = React.forwardRef((props, ref) => {\n const state = useField_unstable(props, ref);\n useFieldStyles_unstable(state);\n return renderField_unstable(state);\n});\n\nField.displayName = 'Field';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Field.types.js","sourceRoot":"../src/","sources":["packages/react-components/react-field/src/components/Field/Field.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { Label } from '@fluentui/react-label';\nimport type { ComponentProps, ComponentState, Slot, SlotClassNames } from '@fluentui/react-utilities';\nimport type { SlotComponent } from './SlotComponent.types';\n\n/**\n * The minimum requirement for a component used by Field.\n *\n * Note: the use of VoidFunctionComponent means that component is not *required* to have a children prop,\n * but it is still allowed to have a children prop.\n */\nexport type FieldControl = React.VoidFunctionComponent<\n Pick<\n React.HTMLAttributes<HTMLElement>,\n 'id' | 'className' | 'style' | 'aria-labelledby' | 'aria-describedby' | 'aria-invalid'\n >\n>;\n\n/**\n * Slots added by Field\n */\nexport type FieldSlots<T extends FieldControl> = {\n root: NonNullable<Slot<'div'>>;\n\n /**\n * The underlying component wrapped by this field.\n */\n control: SlotComponent<T>;\n\n /**\n * The label associated with the field.\n */\n label?: Slot<typeof Label>;\n\n /**\n * A message about the validation state. The appearance of the `validationMessage` depends on `validationState`.\n */\n validationMessage?: Slot<'div'>;\n\n /**\n * The icon associated with the `validationMessage`. If the `validationState` prop is set, this will default to an\n * icon corresponding to that state.\n *\n * This will only be displayed if `validationMessage` is set.\n */\n validationMessageIcon?: Slot<'span'>;\n\n /**\n * Additional hint text below the field.\n */\n hint?: Slot<'div'>;\n};\n\n/**\n * Field Props\n */\nexport type FieldProps<T extends FieldControl> = ComponentProps<Partial<FieldSlots<T>>, 'control'> & {\n /**\n * The orientation of the label relative to the field component.\n * This only affects the label, and not the validationMessage or hint (which always appear below the field component).\n *\n * @default vertical\n */\n orientation?: 'vertical' | 'horizontal';\n\n /**\n * The `validationState` affects the color of the `validationMessage`, the `validationMessageIcon`, and for some\n * field components, an `validationState=\"error\"` causes the border to become red.\n *\n * @default undefined\n */\n validationState?: 'error' | 'warning' | 'success';\n};\n\n/**\n * FieldProps plus extra optional props that are supported by useField_unstable, but not required to be part of the\n * API of every Field component.\n *\n * This allows Field to forward the required and size props to the label if the underlying component supports them,\n * but doesn't add them to the public API of fields that don't support them.\n */\nexport type FieldPropsWithOptionalComponentProps<T extends FieldControl> = FieldProps<T> & {\n /**\n * A ref to the underlying control.\n */\n ref?: React.Ref<HTMLElement>;\n\n /**\n * Whether the field label should be marked as required.\n */\n required?: boolean;\n\n /**\n * Size of the field label.\n *\n * Number sizes will be ignored, but are allowed because the HTML `<input>` element has a prop `size?: number`.\n */\n size?: 'small' | 'medium' | 'large' | number;\n};\n\n/**\n * Configuration parameters for a Field class, passed to useField_unstable\n */\nexport type FieldConfig<T extends FieldControl> = {\n /**\n * The underlying input component that this field is wrapping.\n */\n component: T;\n\n /**\n * Class names for this component, created by `getFieldClassNames`.\n */\n classNames: SlotClassNames<FieldSlots<T>>;\n\n /**\n * How the label be connected to the control.\n * * htmlFor - Set the Label's htmlFor prop to the component's ID (and generate an ID if not provided).\n * This is the preferred method for components that use the underlying <input> tag.\n * * aria-labelledby - Set the component's aria-labelledby prop to the Label's ID. Use this for components\n * that are not directly <input> elements (such as RadioGroup).\n *\n * @default htmlFor\n */\n labelConnection?: 'htmlFor' | 'aria-labelledby';\n\n /**\n * Should the aria-invalid attribute be set when validationState=\"error\".\n *\n * @default true\n */\n ariaInvalidOnError?: boolean;\n};\n\n/**\n * State used in rendering Field\n */\nexport type FieldState<T extends FieldControl> = ComponentState<Required<FieldSlots<T>>> &\n Pick<FieldProps<T>, 'orientation' | 'validationState'> & {\n classNames: SlotClassNames<FieldSlots<T>>;\n };\n"]}
1
+ {"version":3,"file":"Field.types.js","sourceRoot":"../src/","sources":["packages/react-components/react-field/src/components/Field/Field.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { Label } from '@fluentui/react-label';\nimport type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\n\n/**\n * The props added to the Field's child element.\n */\nexport type FieldChildProps = Pick<\n React.HTMLAttributes<HTMLElement>,\n 'id' | 'aria-labelledby' | 'aria-describedby' | 'aria-invalid' | 'aria-required'\n>;\n\n/**\n * Slots of the Field component\n */\nexport type FieldSlots = {\n root: NonNullable<Slot<'div'>>;\n\n /**\n * The label associated with the field.\n */\n label?: Slot<typeof Label>;\n\n /**\n * A message about the validation state. The appearance of the `validationMessage` depends on `validationState`.\n */\n validationMessage?: Slot<'div'>;\n\n /**\n * The icon associated with the `validationMessage`. If the `validationState` prop is set, this will default to an\n * icon corresponding to that state.\n *\n * This will only be displayed if `validationMessage` is set.\n */\n validationMessageIcon?: Slot<'span'>;\n\n /**\n * Additional hint text below the field.\n */\n hint?: Slot<'div'>;\n};\n\n/**\n * Field Props\n */\nexport type FieldProps = Omit<ComponentProps<FieldSlots>, 'children'> & {\n /**\n * The Field's child can be a single form control, or a render function that takes the props that should be spread on\n * a form control.\n *\n * All form controls in this library can be used directly as children (such as `<Input>` or `<RadioGroup>`), as well\n * as intrinsic form controls like `<input>` or `<textarea>`. Custom controls can also be used as long as they\n * accept FieldChildProps and spread them on the appropriate element.\n *\n * For more complex scenarios, a render function can be used to pass the FieldChildProps to the appropriate control.\n */\n children?: React.ReactElement<FieldChildProps> | null | ((props: FieldChildProps) => React.ReactNode);\n\n /**\n * The orientation of the label relative to the field component.\n * This only affects the label, and not the validationMessage or hint (which always appear below the field component).\n *\n * @default vertical\n */\n orientation?: 'vertical' | 'horizontal';\n\n /**\n * The `validationState` affects the color of the `validationMessage`, the `validationMessageIcon`\n *\n * Setting `validationState` to `error` will also set `aria-invalid` to `true` on the Field's child,\n * `role=\"alert\"` on the `validationMessage`, and for some field components, causes the border to become red.\n */\n validationState?: 'error' | 'warning' | 'success';\n\n /**\n * Marks the Field as required. If `true`, an asterisk will be appended to the label, and `aria-required` will be set\n * on the Field's child.\n */\n required?: boolean;\n\n /**\n * The size of the Field's label.\n *\n * @default medium\n */\n size?: 'small' | 'medium' | 'large';\n};\n\n/**\n * State used in rendering Field\n */\nexport type FieldState = ComponentState<Required<FieldSlots>> & Pick<FieldProps, 'orientation' | 'validationState'>;\n"]}
@@ -1,4 +1,5 @@
1
1
  export * from './Field.types';
2
+ export * from './Field';
2
3
  export * from './renderField';
3
4
  export * from './useField';
4
5
  export * from './useFieldStyles';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../src/","sources":["packages/react-components/react-field/src/components/Field/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC","sourcesContent":["export * from './Field.types';\nexport * from './renderField';\nexport * from './useField';\nexport * from './useFieldStyles';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../src/","sources":["packages/react-components/react-field/src/components/Field/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC","sourcesContent":["export * from './Field.types';\nexport * from './Field';\nexport * from './renderField';\nexport * from './useField';\nexport * from './useFieldStyles';\n"]}
@@ -12,13 +12,11 @@ export const renderField_unstable = state => {
12
12
  ...slotProps.root
13
13
  }, slots.label && /*#__PURE__*/React.createElement(slots.label, {
14
14
  ...slotProps.label
15
- }), slots.control && /*#__PURE__*/React.createElement(slots.control, {
16
- ...slotProps.control
17
- }), slots.validationMessage && slots.validationMessageIcon && /*#__PURE__*/React.createElement(slots.validationMessageIcon, {
18
- ...slotProps.validationMessageIcon
19
- }), slots.validationMessage && /*#__PURE__*/React.createElement(slots.validationMessage, {
15
+ }), slotProps.root.children, slots.validationMessage && /*#__PURE__*/React.createElement(slots.validationMessage, {
20
16
  ...slotProps.validationMessage
21
- }), slots.hint && /*#__PURE__*/React.createElement(slots.hint, {
17
+ }, slots.validationMessageIcon && /*#__PURE__*/React.createElement(slots.validationMessageIcon, {
18
+ ...slotProps.validationMessageIcon
19
+ }), slotProps.validationMessage.children), slots.hint && /*#__PURE__*/React.createElement(slots.hint, {
22
20
  ...slotProps.hint
23
21
  }));
24
22
  };
@@ -1 +1 @@
1
- {"version":3,"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAASC,QAAQ,QAAQ,2BAA2B;AAGpD;;;AAGA,OAAO,MAAMC,oBAAoB,GAA4BC,KAAoB,IAAI;EACnF,MAAM;IAAEC,KAAK;IAAEC;EAAS,CAAE,GAAGJ,QAAQ,CAA2BE,KAAiC,CAAC;EAElG,oBACEH,oBAACI,KAAK,CAACE,IAAI;IAAA,GAAKD,SAAS,CAACC;EAAI,GAC3BF,KAAK,CAACG,KAAK,iBAAIP,oBAACI,KAAK,CAACG,KAAK;IAAA,GAAKF,SAAS,CAACE;EAAK,EAAI,EAEnDH,KAAK,CAACI,OAAO,iBAAIR,oBAACI,KAAK,CAACI,OAAO;IAAA,GAAMH,SAAS,CAACG;EAAe,EAAI,EAClEJ,KAAK,CAACK,iBAAiB,IAAIL,KAAK,CAACM,qBAAqB,iBACrDV,oBAACI,KAAK,CAACM,qBAAqB;IAAA,GAAKL,SAAS,CAACK;EAAqB,EACjE,EACAN,KAAK,CAACK,iBAAiB,iBAAIT,oBAACI,KAAK,CAACK,iBAAiB;IAAA,GAAKJ,SAAS,CAACI;EAAiB,EAAI,EACvFL,KAAK,CAACO,IAAI,iBAAIX,oBAACI,KAAK,CAACO,IAAI;IAAA,GAAKN,SAAS,CAACM;EAAI,EAAI,CACtC;AAEjB,CAAC","names":["React","getSlots","renderField_unstable","state","slots","slotProps","root","label","control","validationMessage","validationMessageIcon","hint"],"sourceRoot":"../src/","sources":["packages/react-components/react-field/src/components/Field/renderField.tsx"],"sourcesContent":["import * as React from 'react';\nimport { getSlots } from '@fluentui/react-utilities';\nimport type { FieldControl, FieldSlots, FieldState } from './Field.types';\n\n/**\n * Render the final JSX of Field\n */\nexport const renderField_unstable = <T extends FieldControl>(state: FieldState<T>) => {\n const { slots, slotProps } = getSlots<FieldSlots<FieldControl>>(state as FieldState<FieldControl>);\n\n return (\n <slots.root {...slotProps.root}>\n {slots.label && <slots.label {...slotProps.label} />}\n {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}\n {slots.control && <slots.control {...(slotProps.control as any)} />}\n {slots.validationMessage && slots.validationMessageIcon && (\n <slots.validationMessageIcon {...slotProps.validationMessageIcon} />\n )}\n {slots.validationMessage && <slots.validationMessage {...slotProps.validationMessage} />}\n {slots.hint && <slots.hint {...slotProps.hint} />}\n </slots.root>\n );\n};\n"]}
1
+ {"version":3,"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAASC,QAAQ,QAAQ,2BAA2B;AAGpD;;;AAGA,OAAO,MAAMC,oBAAoB,GAAIC,KAAiB,IAAI;EACxD,MAAM;IAAEC,KAAK;IAAEC;EAAS,CAAE,GAAGJ,QAAQ,CAAaE,KAAK,CAAC;EAExD,oBACEH,oBAACI,KAAK,CAACE,IAAI;IAAA,GAAKD,SAAS,CAACC;EAAI,GAC3BF,KAAK,CAACG,KAAK,iBAAIP,oBAACI,KAAK,CAACG,KAAK;IAAA,GAAKF,SAAS,CAACE;EAAK,EAAI,EACnDF,SAAS,CAACC,IAAI,CAACE,QAAQ,EACvBJ,KAAK,CAACK,iBAAiB,iBACtBT,oBAACI,KAAK,CAACK,iBAAiB;IAAA,GAAKJ,SAAS,CAACI;EAAiB,GACrDL,KAAK,CAACM,qBAAqB,iBAAIV,oBAACI,KAAK,CAACM,qBAAqB;IAAA,GAAKL,SAAS,CAACK;EAAqB,EAAI,EACnGL,SAAS,CAACI,iBAAiB,CAACD,QAAQ,CAExC,EACAJ,KAAK,CAACO,IAAI,iBAAIX,oBAACI,KAAK,CAACO,IAAI;IAAA,GAAKN,SAAS,CAACM;EAAI,EAAI,CACtC;AAEjB,CAAC","names":["React","getSlots","renderField_unstable","state","slots","slotProps","root","label","children","validationMessage","validationMessageIcon","hint"],"sourceRoot":"../src/","sources":["packages/react-components/react-field/src/components/Field/renderField.tsx"],"sourcesContent":["import * as React from 'react';\nimport { getSlots } from '@fluentui/react-utilities';\nimport type { FieldSlots, FieldState } from './Field.types';\n\n/**\n * Render the final JSX of Field\n */\nexport const renderField_unstable = (state: FieldState) => {\n const { slots, slotProps } = getSlots<FieldSlots>(state);\n\n return (\n <slots.root {...slotProps.root}>\n {slots.label && <slots.label {...slotProps.label} />}\n {slotProps.root.children}\n {slots.validationMessage && (\n <slots.validationMessage {...slotProps.validationMessage}>\n {slots.validationMessageIcon && <slots.validationMessageIcon {...slotProps.validationMessageIcon} />}\n {slotProps.validationMessage.children}\n </slots.validationMessage>\n )}\n {slots.hint && <slots.hint {...slotProps.hint} />}\n </slots.root>\n );\n};\n"]}
@@ -7,37 +7,6 @@ const validationMessageIcons = {
7
7
  warning: /*#__PURE__*/React.createElement(Warning12Filled, null),
8
8
  success: /*#__PURE__*/React.createElement(CheckmarkCircle12Filled, null)
9
9
  };
10
- /**
11
- * Partition the props used by the Field itself, from the props that are passed to the underlying field component.
12
- */
13
- export const getPartitionedFieldProps = props => {
14
- const {
15
- className,
16
- control,
17
- hint,
18
- label,
19
- orientation,
20
- root,
21
- style,
22
- validationMessage,
23
- validationMessageIcon,
24
- validationState,
25
- ...restOfProps
26
- } = props;
27
- const fieldProps = {
28
- className,
29
- control,
30
- hint,
31
- label,
32
- orientation,
33
- root,
34
- style,
35
- validationMessage,
36
- validationMessageIcon,
37
- validationState
38
- };
39
- return [fieldProps, restOfProps];
40
- };
41
10
  /**
42
11
  * Create the state required to render Field.
43
12
  *
@@ -45,53 +14,58 @@ export const getPartitionedFieldProps = props => {
45
14
  * before being passed to renderField_unstable.
46
15
  *
47
16
  * @param props - Props passed to this field
48
- * @param ref - Ref to the control slot (primary slot)
49
- * @param params - Configuration parameters for this Field
17
+ * @param ref - Ref to the root
50
18
  */
51
- export const useField_unstable = (props, ref, params) => {
52
- var _a, _b, _c;
53
- const [fieldProps, controlProps] = getPartitionedFieldProps(props);
19
+ export const useField_unstable = (props, ref) => {
20
+ var _a, _b, _c, _d;
54
21
  const {
22
+ children,
55
23
  orientation = 'vertical',
56
- validationState
57
- } = fieldProps;
58
- const {
59
- labelConnection = 'htmlFor',
60
- ariaInvalidOnError = true
61
- } = params;
24
+ required,
25
+ validationState,
26
+ size
27
+ } = props;
62
28
  const baseId = useId('field-');
63
- const root = resolveShorthand(fieldProps.root, {
64
- required: true,
65
- defaultProps: getNativeElementProps('div', fieldProps)
66
- });
67
- const label = resolveShorthand(fieldProps.label, {
29
+ const root = getNativeElementProps('div', {
30
+ ...props,
31
+ ref
32
+ }, /*excludedPropNames:*/['children']);
33
+ const label = resolveShorthand(props.label, {
68
34
  defaultProps: {
69
35
  id: baseId + '__label',
70
- required: controlProps.required,
71
- size: typeof controlProps.size === 'string' ? controlProps.size : undefined
36
+ required,
37
+ size
72
38
  // htmlFor is handled below
73
39
  }
74
40
  });
75
41
 
76
- const validationMessage = resolveShorthand(fieldProps.validationMessage, {
42
+ const validationMessage = resolveShorthand(props.validationMessage, {
77
43
  defaultProps: {
78
- id: baseId + '__validationMessage'
44
+ id: baseId + '__validationMessage',
45
+ role: validationState === 'error' ? 'alert' : undefined
79
46
  }
80
47
  });
81
- const hint = resolveShorthand(fieldProps.hint, {
48
+ const hint = resolveShorthand(props.hint, {
82
49
  defaultProps: {
83
50
  id: baseId + '__hint'
84
51
  }
85
52
  });
86
- const validationMessageIcon = resolveShorthand(fieldProps.validationMessageIcon, {
53
+ const validationMessageIcon = resolveShorthand(props.validationMessageIcon, {
87
54
  required: !!validationState,
88
55
  defaultProps: {
89
56
  children: validationState ? validationMessageIcons[validationState] : undefined
90
57
  }
91
58
  });
92
- // Hook up aria props on the control
93
- if (label && labelConnection === 'aria-labelledby') {
59
+ const controlProps = /*#__PURE__*/React.isValidElement(children) ? {
60
+ ...children.props
61
+ } : {};
62
+ if (label) {
94
63
  (_a = controlProps['aria-labelledby']) !== null && _a !== void 0 ? _a : controlProps['aria-labelledby'] = label.id;
64
+ if (!label.htmlFor) {
65
+ // Assign the child a generated ID if doesn't already have an ID
66
+ (_b = controlProps.id) !== null && _b !== void 0 ? _b : controlProps.id = baseId + '__control';
67
+ label.htmlFor = controlProps.id;
68
+ }
95
69
  }
96
70
  if (validationMessage || hint) {
97
71
  // The control is described by the validation message, or hint, or both
@@ -99,39 +73,32 @@ export const useField_unstable = (props, ref, params) => {
99
73
  // For reference: https://github.com/microsoft/fluentui/pull/25580#discussion_r1017259933
100
74
  controlProps['aria-describedby'] = [validationMessage === null || validationMessage === void 0 ? void 0 : validationMessage.id, hint === null || hint === void 0 ? void 0 : hint.id, controlProps['aria-describedby']].filter(Boolean).join(' ');
101
75
  }
102
- if (validationState === 'error' && ariaInvalidOnError) {
103
- (_b = controlProps['aria-invalid']) !== null && _b !== void 0 ? _b : controlProps['aria-invalid'] = true;
76
+ if (validationState === 'error') {
77
+ (_c = controlProps['aria-invalid']) !== null && _c !== void 0 ? _c : controlProps['aria-invalid'] = true;
104
78
  }
105
- const control = resolveShorthand(fieldProps.control, {
106
- required: true,
107
- defaultProps: {
108
- ref,
109
- id: baseId + '__control',
110
- ...controlProps
111
- }
112
- });
113
- if (label && labelConnection === 'htmlFor') {
114
- (_c = label.htmlFor) !== null && _c !== void 0 ? _c : label.htmlFor = control.id;
79
+ if (required) {
80
+ (_d = controlProps['aria-required']) !== null && _d !== void 0 ? _d : controlProps['aria-required'] = true;
81
+ }
82
+ if ( /*#__PURE__*/React.isValidElement(children)) {
83
+ root.children = /*#__PURE__*/React.cloneElement(children, controlProps);
84
+ } else if (typeof children === 'function') {
85
+ root.children = children(controlProps);
115
86
  }
116
- const state = {
87
+ return {
117
88
  orientation,
118
89
  validationState,
119
- classNames: params.classNames,
120
90
  components: {
121
91
  root: 'div',
122
- control: params.component,
123
92
  label: Label,
124
93
  validationMessage: 'div',
125
94
  validationMessageIcon: 'span',
126
95
  hint: 'div'
127
96
  },
128
97
  root,
129
- control,
130
98
  label,
131
99
  validationMessageIcon,
132
100
  validationMessage,
133
101
  hint
134
102
  };
135
- return state;
136
103
  };
137
104
  //# sourceMappingURL=useField.js.map