@fluentui/react-field 9.0.0-alpha.16 → 9.0.0-alpha.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.json +67 -1
  2. package/CHANGELOG.md +26 -2
  3. package/dist/index.d.ts +75 -91
  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 +1 -3
  10. package/lib/components/Field/renderField.js.map +1 -1
  11. package/lib/components/Field/useField.js +42 -74
  12. package/lib/components/Field/useField.js.map +1 -1
  13. package/lib/components/Field/useFieldStyles.js +15 -18
  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 +1 -1
  25. package/lib-amd/components/Field/renderField.js.map +1 -1
  26. package/lib-amd/components/Field/useField.js +34 -55
  27. package/lib-amd/components/Field/useField.js.map +1 -1
  28. package/lib-amd/components/Field/useFieldStyles.js +13 -19
  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 +1 -3
  39. package/lib-commonjs/components/Field/renderField.js.map +1 -1
  40. package/lib-commonjs/components/Field/useField.js +43 -76
  41. package/lib-commonjs/components/Field/useField.js.map +1 -1
  42. package/lib-commonjs/components/Field/useFieldStyles.js +16 -20
  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, 23 Jan 2023 16:41:42 GMT",
5
+ "date": "Tue, 31 Jan 2023 19:50:40 GMT",
6
+ "tag": "@fluentui/react-field_v9.0.0-alpha.18",
7
+ "version": "9.0.0-alpha.18",
8
+ "comments": {
9
+ "prerelease": [
10
+ {
11
+ "author": "behowell@microsoft.com",
12
+ "package": "@fluentui/react-field",
13
+ "commit": "d59cee0443fc357a3033d0e71e23659a2ce2d57d",
14
+ "comment": "chore: Change the default value of validationState to error when a validationMessage is set."
15
+ },
16
+ {
17
+ "author": "beachball",
18
+ "package": "@fluentui/react-field",
19
+ "comment": "Bump @fluentui/react-context-selector to v9.1.7",
20
+ "commit": "22477ef4202cd24add6ebf823196b5888c9d8083"
21
+ },
22
+ {
23
+ "author": "beachball",
24
+ "package": "@fluentui/react-field",
25
+ "comment": "Bump @fluentui/react-label to v9.0.19",
26
+ "commit": "22477ef4202cd24add6ebf823196b5888c9d8083"
27
+ },
28
+ {
29
+ "author": "beachball",
30
+ "package": "@fluentui/react-field",
31
+ "comment": "Bump @fluentui/react-utilities to v9.5.1",
32
+ "commit": "22477ef4202cd24add6ebf823196b5888c9d8083"
33
+ }
34
+ ]
35
+ }
36
+ },
37
+ {
38
+ "date": "Thu, 26 Jan 2023 13:30:56 GMT",
39
+ "tag": "@fluentui/react-field_v9.0.0-alpha.17",
40
+ "version": "9.0.0-alpha.17",
41
+ "comments": {
42
+ "prerelease": [
43
+ {
44
+ "author": "behowell@microsoft.com",
45
+ "package": "@fluentui/react-field",
46
+ "commit": "d6e98c0b5390c5c7e03601537b2026307e01a8d4",
47
+ "comment": "Implement Field component to replace InputField, ComboboxField, etc."
48
+ },
49
+ {
50
+ "author": "beachball",
51
+ "package": "@fluentui/react-field",
52
+ "comment": "Bump @fluentui/react-context-selector to v9.1.6",
53
+ "commit": "403e1370f1effca7d3db131eda381abf31cf66b1"
54
+ },
55
+ {
56
+ "author": "beachball",
57
+ "package": "@fluentui/react-field",
58
+ "comment": "Bump @fluentui/react-label to v9.0.18",
59
+ "commit": "403e1370f1effca7d3db131eda381abf31cf66b1"
60
+ },
61
+ {
62
+ "author": "beachball",
63
+ "package": "@fluentui/react-field",
64
+ "comment": "Bump @fluentui/react-utilities to v9.5.0",
65
+ "commit": "403e1370f1effca7d3db131eda381abf31cf66b1"
66
+ }
67
+ ]
68
+ }
69
+ },
70
+ {
71
+ "date": "Mon, 23 Jan 2023 16:43:09 GMT",
6
72
  "tag": "@fluentui/react-field_v9.0.0-alpha.16",
7
73
  "version": "9.0.0-alpha.16",
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, 23 Jan 2023 16:41:42 GMT and should not be manually modified.
3
+ This log was last generated on Tue, 31 Jan 2023 19:50:40 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.0.0-alpha.18](https://github.com/microsoft/fluentui/tree/@fluentui/react-field_v9.0.0-alpha.18)
8
+
9
+ Tue, 31 Jan 2023 19:50:40 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-field_v9.0.0-alpha.17..@fluentui/react-field_v9.0.0-alpha.18)
11
+
12
+ ### Changes
13
+
14
+ - chore: Change the default value of validationState to error when a validationMessage is set. ([PR #26523](https://github.com/microsoft/fluentui/pull/26523) by behowell@microsoft.com)
15
+ - Bump @fluentui/react-context-selector to v9.1.7 ([PR #26491](https://github.com/microsoft/fluentui/pull/26491) by beachball)
16
+ - Bump @fluentui/react-label to v9.0.19 ([PR #26491](https://github.com/microsoft/fluentui/pull/26491) by beachball)
17
+ - Bump @fluentui/react-utilities to v9.5.1 ([PR #26491](https://github.com/microsoft/fluentui/pull/26491) by beachball)
18
+
19
+ ## [9.0.0-alpha.17](https://github.com/microsoft/fluentui/tree/@fluentui/react-field_v9.0.0-alpha.17)
20
+
21
+ Thu, 26 Jan 2023 13:30:56 GMT
22
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-field_v9.0.0-alpha.16..@fluentui/react-field_v9.0.0-alpha.17)
23
+
24
+ ### Changes
25
+
26
+ - Implement Field component to replace InputField, ComboboxField, etc. ([PR #26430](https://github.com/microsoft/fluentui/pull/26430) by behowell@microsoft.com)
27
+ - Bump @fluentui/react-context-selector to v9.1.6 ([PR #26496](https://github.com/microsoft/fluentui/pull/26496) by beachball)
28
+ - Bump @fluentui/react-label to v9.0.18 ([PR #26496](https://github.com/microsoft/fluentui/pull/26496) by beachball)
29
+ - Bump @fluentui/react-utilities to v9.5.0 ([PR #26496](https://github.com/microsoft/fluentui/pull/26496) by beachball)
30
+
7
31
  ## [9.0.0-alpha.16](https://github.com/microsoft/fluentui/tree/@fluentui/react-field_v9.0.0-alpha.16)
8
32
 
9
- Mon, 23 Jan 2023 16:41:42 GMT
33
+ Mon, 23 Jan 2023 16:43:09 GMT
10
34
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-field_v9.0.0-alpha.15..@fluentui/react-field_v9.0.0-alpha.16)
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,60 +49,53 @@ 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 display of the `validationMessage` and `validationMessageIcon`.
64
53
  *
65
- * @default undefined
66
- */
67
- 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
- /**
79
- * A ref to the underlying control.
54
+ * * `error` - (default) The validation message has a red error icon and red text, with `role="alert"` so it is
55
+ * announced by screen readers. Additionally, the control inside the field has `aria-invalid` set, which adds a
56
+ * red border to some field components (such as `Input`).
57
+ * * `success` - The validation message has a green checkmark icon and gray text.
58
+ * * `warning` - The validation message has a yellow exclamation icon and gray text.
59
+ * * `none` - The validation message has no icon and gray text.
60
+ *
61
+ * @default error when `validationMessage` is set; none otherwise.
80
62
  */
81
- ref?: React_2.Ref<HTMLElement>;
63
+ validationState?: 'error' | 'warning' | 'success' | 'none';
82
64
  /**
83
- * Whether the field label should be marked as required.
65
+ * Marks the Field as required. If `true`, an asterisk will be appended to the label, and `aria-required` will be set
66
+ * on the Field's child.
84
67
  */
85
68
  required?: boolean;
86
69
  /**
87
- * Size of the field label.
70
+ * The size of the Field's label.
88
71
  *
89
- * Number sizes will be ignored, but are allowed because the HTML `<input>` element has a prop `size?: number`.
72
+ * @default medium
90
73
  */
91
- size?: 'small' | 'medium' | 'large' | number;
74
+ size?: 'small' | 'medium' | 'large';
92
75
  };
93
76
 
94
77
  /**
95
- * Slots added by Field
78
+ * Slots of the Field component
96
79
  */
97
- export declare type FieldSlots<T extends FieldControl> = {
80
+ export declare type FieldSlots = {
98
81
  root: NonNullable<Slot<'div'>>;
99
- /**
100
- * The underlying component wrapped by this field.
101
- */
102
- control: SlotComponent<T>;
103
82
  /**
104
83
  * The label associated with the field.
105
84
  */
106
85
  label?: Slot<typeof Label>;
107
86
  /**
108
- * A message about the validation state. The appearance of the `validationMessage` depends on `validationState`.
87
+ * A message about the validation state. By default, this is an error message, but it can be a success, warning,
88
+ * or custom message by setting `validationState`.
109
89
  */
110
90
  validationMessage?: Slot<'div'>;
111
91
  /**
112
- * The icon associated with the `validationMessage`. If the `validationState` prop is set, this will default to an
113
- * icon corresponding to that state.
92
+ * The icon associated with the `validationMessage`. This will only be displayed if `validationMessage` is set.
114
93
  *
115
- * This will only be displayed if `validationMessage` is set.
94
+ * The default depends on `validationState`:
95
+ * * `error` - `<ErrorCircle12Filled />`
96
+ * * `warning` - `<Warning12Filled />`
97
+ * * `success` - `<CheckmarkCircle12Filled />`
98
+ * * `none` - `null`
116
99
  */
117
100
  validationMessageIcon?: Slot<'span'>;
118
101
  /**
@@ -124,22 +107,34 @@ export declare type FieldSlots<T extends FieldControl> = {
124
107
  /**
125
108
  * State used in rendering Field
126
109
  */
127
- export declare type FieldState<T extends FieldControl> = ComponentState<Required<FieldSlots<T>>> & Pick<FieldProps<T>, 'orientation' | 'validationState'> & {
128
- classNames: SlotClassNames<FieldSlots<T>>;
110
+ export declare type FieldState = ComponentState<Required<FieldSlots>> & Required<Pick<FieldProps, 'orientation' | 'validationState'>>;
111
+
112
+ /**
113
+ * @deprecated Only for use to make deprecated [Control]Field shim components.
114
+ * @internal
115
+ */
116
+ export declare const getDeprecatedFieldClassNames: (controlRootClassName: string) => {
117
+ control: string;
118
+ root: string;
119
+ label: string;
120
+ validationMessage: string;
121
+ validationMessageIcon: string;
122
+ hint: string;
129
123
  };
130
124
 
131
- export declare const getFieldClassNames: (name: string) => SlotClassNames<FieldSlots<FieldControl>>;
125
+ /**
126
+ * @deprecated Only for use to make deprecated [Control]Field shim components.
127
+ * @internal
128
+ */
129
+ export declare function makeDeprecatedField<ControlProps>(Control: React_2.ComponentType<ControlProps>, options?: {
130
+ mapProps?: (props: DeprecatedFieldProps<ControlProps>) => DeprecatedFieldProps<ControlProps>;
131
+ displayName?: string;
132
+ }): ForwardRefComponent<DeprecatedFieldProps<ControlProps>>;
132
133
 
133
134
  /**
134
135
  * Render the final JSX of Field
135
136
  */
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>;
137
+ export declare const renderField_unstable: (state: FieldState) => JSX.Element;
143
138
 
144
139
  /**
145
140
  * Create the state required to render Field.
@@ -148,24 +143,13 @@ declare type SlotComponent<Type extends React_2.ComponentType | React_2.VoidFunc
148
143
  * before being passed to renderField_unstable.
149
144
  *
150
145
  * @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
146
+ * @param ref - Ref to the root
153
147
  */
154
- export declare const useField_unstable: <T extends FieldControl>(props: FieldPropsWithOptionalComponentProps<T>, ref: React_2.Ref<HTMLElement>, params: FieldConfig<T>) => FieldState<T>;
148
+ export declare const useField_unstable: (props: FieldProps, ref: React_2.Ref<HTMLDivElement>) => FieldState;
155
149
 
156
150
  /**
157
151
  * Apply styling to the Field slots based on the state
158
152
  */
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']>;
153
+ export declare const useFieldStyles_unstable: (state: FieldState) => void;
170
154
 
171
155
  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. By default, this is an error message, but it can be a success, warning,\n * or custom message by setting `validationState`.\n */\n validationMessage?: Slot<'div'>;\n\n /**\n * The icon associated with the `validationMessage`. This will only be displayed if `validationMessage` is set.\n *\n * The default depends on `validationState`:\n * * `error` - `<ErrorCircle12Filled />`\n * * `warning` - `<Warning12Filled />`\n * * `success` - `<CheckmarkCircle12Filled />`\n * * `none` - `null`\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 display of the `validationMessage` and `validationMessageIcon`.\n *\n * * `error` - (default) The validation message has a red error icon and red text, with `role=\"alert\"` so it is\n * announced by screen readers. Additionally, the control inside the field has `aria-invalid` set, which adds a\n * red border to some field components (such as `Input`).\n * * `success` - The validation message has a green checkmark icon and gray text.\n * * `warning` - The validation message has a yellow exclamation icon and gray text.\n * * `none` - The validation message has no icon and gray text.\n *\n * @default error when `validationMessage` is set; none otherwise.\n */\n validationState?: 'error' | 'warning' | 'success' | 'none';\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>> &\n Required<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,9 +12,7 @@ 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 && /*#__PURE__*/React.createElement(slots.validationMessage, {
15
+ }), slotProps.root.children, slots.validationMessage && /*#__PURE__*/React.createElement(slots.validationMessage, {
18
16
  ...slotProps.validationMessage
19
17
  }, slots.validationMessageIcon && /*#__PURE__*/React.createElement(slots.validationMessageIcon, {
20
18
  ...slotProps.validationMessageIcon
@@ -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,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,CAACE,QAAQ,CAExC,EACAP,KAAK,CAACQ,IAAI,iBAAIZ,oBAACI,KAAK,CAACQ,IAAI;IAAA,GAAKP,SAAS,CAACO;EAAI,EAAI,CACtC;AAEjB,CAAC","names":["React","getSlots","renderField_unstable","state","slots","slotProps","root","label","control","validationMessage","validationMessageIcon","children","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 && (\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"]}
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"]}
@@ -5,38 +5,8 @@ import { getNativeElementProps, resolveShorthand, useId } from '@fluentui/react-
5
5
  const validationMessageIcons = {
6
6
  error: /*#__PURE__*/React.createElement(ErrorCircle12Filled, null),
7
7
  warning: /*#__PURE__*/React.createElement(Warning12Filled, null),
8
- success: /*#__PURE__*/React.createElement(CheckmarkCircle12Filled, null)
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];
8
+ success: /*#__PURE__*/React.createElement(CheckmarkCircle12Filled, null),
9
+ none: undefined
40
10
  };
41
11
  /**
42
12
  * Create the state required to render Field.
@@ -45,54 +15,59 @@ export const getPartitionedFieldProps = props => {
45
15
  * before being passed to renderField_unstable.
46
16
  *
47
17
  * @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
18
+ * @param ref - Ref to the root
50
19
  */
51
- export const useField_unstable = (props, ref, params) => {
52
- var _a, _b, _c;
53
- const [fieldProps, controlProps] = getPartitionedFieldProps(props);
20
+ export const useField_unstable = (props, ref) => {
21
+ var _a, _b, _c, _d;
54
22
  const {
23
+ children,
55
24
  orientation = 'vertical',
56
- validationState
57
- } = fieldProps;
58
- const {
59
- labelConnection = 'htmlFor',
60
- ariaInvalidOnError = true
61
- } = params;
25
+ required,
26
+ validationState = props.validationMessage ? 'error' : 'none',
27
+ size
28
+ } = props;
62
29
  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, {
30
+ const root = getNativeElementProps('div', {
31
+ ...props,
32
+ ref
33
+ }, /*excludedPropNames:*/['children']);
34
+ const label = resolveShorthand(props.label, {
68
35
  defaultProps: {
69
36
  id: baseId + '__label',
70
- required: controlProps.required,
71
- size: typeof controlProps.size === 'string' ? controlProps.size : undefined
37
+ required,
38
+ size
72
39
  // htmlFor is handled below
73
40
  }
74
41
  });
75
42
 
76
- const validationMessage = resolveShorthand(fieldProps.validationMessage, {
43
+ const validationMessage = resolveShorthand(props.validationMessage, {
77
44
  defaultProps: {
78
45
  id: baseId + '__validationMessage',
79
46
  role: validationState === 'error' ? 'alert' : undefined
80
47
  }
81
48
  });
82
- const hint = resolveShorthand(fieldProps.hint, {
49
+ const hint = resolveShorthand(props.hint, {
83
50
  defaultProps: {
84
51
  id: baseId + '__hint'
85
52
  }
86
53
  });
87
- const validationMessageIcon = resolveShorthand(fieldProps.validationMessageIcon, {
88
- required: !!validationState,
54
+ const defaultIcon = validationMessageIcons[validationState];
55
+ const validationMessageIcon = resolveShorthand(props.validationMessageIcon, {
56
+ required: !!defaultIcon,
89
57
  defaultProps: {
90
- children: validationState ? validationMessageIcons[validationState] : undefined
58
+ children: defaultIcon
91
59
  }
92
60
  });
93
- // Hook up aria props on the control
94
- if (label && labelConnection === 'aria-labelledby') {
61
+ const controlProps = /*#__PURE__*/React.isValidElement(children) ? {
62
+ ...children.props
63
+ } : {};
64
+ if (label) {
95
65
  (_a = controlProps['aria-labelledby']) !== null && _a !== void 0 ? _a : controlProps['aria-labelledby'] = label.id;
66
+ if (!label.htmlFor) {
67
+ // Assign the child a generated ID if doesn't already have an ID
68
+ (_b = controlProps.id) !== null && _b !== void 0 ? _b : controlProps.id = baseId + '__control';
69
+ label.htmlFor = controlProps.id;
70
+ }
96
71
  }
97
72
  if (validationMessage || hint) {
98
73
  // The control is described by the validation message, or hint, or both
@@ -100,39 +75,32 @@ export const useField_unstable = (props, ref, params) => {
100
75
  // For reference: https://github.com/microsoft/fluentui/pull/25580#discussion_r1017259933
101
76
  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(' ');
102
77
  }
103
- if (validationState === 'error' && ariaInvalidOnError) {
104
- (_b = controlProps['aria-invalid']) !== null && _b !== void 0 ? _b : controlProps['aria-invalid'] = true;
78
+ if (validationState === 'error') {
79
+ (_c = controlProps['aria-invalid']) !== null && _c !== void 0 ? _c : controlProps['aria-invalid'] = true;
105
80
  }
106
- const control = resolveShorthand(fieldProps.control, {
107
- required: true,
108
- defaultProps: {
109
- ref,
110
- id: baseId + '__control',
111
- ...controlProps
112
- }
113
- });
114
- if (label && labelConnection === 'htmlFor') {
115
- (_c = label.htmlFor) !== null && _c !== void 0 ? _c : label.htmlFor = control.id;
81
+ if (required) {
82
+ (_d = controlProps['aria-required']) !== null && _d !== void 0 ? _d : controlProps['aria-required'] = true;
83
+ }
84
+ if ( /*#__PURE__*/React.isValidElement(children)) {
85
+ root.children = /*#__PURE__*/React.cloneElement(children, controlProps);
86
+ } else if (typeof children === 'function') {
87
+ root.children = children(controlProps);
116
88
  }
117
- const state = {
89
+ return {
118
90
  orientation,
119
91
  validationState,
120
- classNames: params.classNames,
121
92
  components: {
122
93
  root: 'div',
123
- control: params.component,
124
94
  label: Label,
125
95
  validationMessage: 'div',
126
96
  validationMessageIcon: 'span',
127
97
  hint: 'div'
128
98
  },
129
99
  root,
130
- control,
131
100
  label,
132
101
  validationMessageIcon,
133
102
  validationMessage,
134
103
  hint
135
104
  };
136
- return state;
137
105
  };
138
106
  //# sourceMappingURL=useField.js.map