@itwin/itwinui-react 5.0.0-alpha.11 → 5.0.0-alpha.13

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 (65) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +13 -2
  3. package/dist/DEV/bricks/Checkbox.js +7 -14
  4. package/dist/DEV/bricks/Description.js +7 -14
  5. package/dist/DEV/bricks/DropdownMenu.js +68 -21
  6. package/dist/DEV/bricks/ErrorRegion.js +137 -0
  7. package/dist/DEV/bricks/Field.internal.js +47 -0
  8. package/dist/DEV/bricks/Field.js +120 -85
  9. package/dist/DEV/bricks/Icon.js +57 -0
  10. package/dist/DEV/bricks/IconButton.js +2 -5
  11. package/dist/DEV/bricks/Label.js +4 -10
  12. package/dist/DEV/bricks/Radio.js +7 -14
  13. package/dist/DEV/bricks/Select.js +9 -15
  14. package/dist/DEV/bricks/Switch.js +8 -15
  15. package/dist/DEV/bricks/Table.js +71 -37
  16. package/dist/DEV/bricks/Tabs.js +4 -29
  17. package/dist/DEV/bricks/TextBox.js +23 -37
  18. package/dist/DEV/bricks/Toolbar.js +25 -0
  19. package/dist/DEV/bricks/TreeItem.js +114 -42
  20. package/dist/DEV/bricks/index.js +9 -3
  21. package/dist/DEV/bricks/styles.css.js +1 -1
  22. package/dist/DEV/bricks/~utils.Dot.js +22 -0
  23. package/dist/DEV/foundations/styles.css.js +1 -1
  24. package/dist/bricks/Checkbox.d.ts +13 -5
  25. package/dist/bricks/Checkbox.js +7 -14
  26. package/dist/bricks/Description.d.ts +2 -6
  27. package/dist/bricks/Description.js +7 -14
  28. package/dist/bricks/DropdownMenu.d.ts +11 -9
  29. package/dist/bricks/DropdownMenu.js +67 -20
  30. package/dist/bricks/ErrorRegion.d.ts +88 -0
  31. package/dist/bricks/ErrorRegion.js +135 -0
  32. package/dist/bricks/Field.d.ts +69 -27
  33. package/dist/bricks/Field.internal.d.ts +33 -0
  34. package/dist/bricks/Field.internal.js +47 -0
  35. package/dist/bricks/Field.js +115 -84
  36. package/dist/bricks/Icon.d.ts +6 -0
  37. package/dist/bricks/Icon.js +55 -0
  38. package/dist/bricks/IconButton.js +2 -5
  39. package/dist/bricks/Label.d.ts +5 -12
  40. package/dist/bricks/Label.js +4 -10
  41. package/dist/bricks/ProgressBar.d.ts +7 -1
  42. package/dist/bricks/Radio.d.ts +14 -5
  43. package/dist/bricks/Radio.js +7 -14
  44. package/dist/bricks/Select.d.ts +29 -12
  45. package/dist/bricks/Select.js +9 -15
  46. package/dist/bricks/Switch.d.ts +12 -5
  47. package/dist/bricks/Switch.js +8 -15
  48. package/dist/bricks/Table.d.ts +94 -37
  49. package/dist/bricks/Table.js +69 -36
  50. package/dist/bricks/Tabs.d.ts +3 -4
  51. package/dist/bricks/Tabs.js +4 -29
  52. package/dist/bricks/TextBox.d.ts +42 -19
  53. package/dist/bricks/TextBox.js +23 -37
  54. package/dist/bricks/Toolbar.d.ts +35 -0
  55. package/dist/bricks/Toolbar.js +23 -0
  56. package/dist/bricks/TreeItem.d.ts +63 -9
  57. package/dist/bricks/TreeItem.js +103 -41
  58. package/dist/bricks/index.d.ts +5 -2
  59. package/dist/bricks/index.js +9 -3
  60. package/dist/bricks/styles.css.js +1 -1
  61. package/dist/bricks/~hooks.d.ts +1 -1
  62. package/dist/bricks/~utils.Dot.d.ts +11 -0
  63. package/dist/bricks/~utils.Dot.js +21 -0
  64. package/dist/foundations/styles.css.js +1 -1
  65. package/package.json +1 -1
@@ -3,14 +3,18 @@ import * as React from "react";
3
3
  import cx from "classnames";
4
4
  import { Role } from "@ariakit/react/role";
5
5
  import {
6
- useCollectionStore,
7
- Collection,
8
6
  useCollectionContext,
9
7
  CollectionItem
10
8
  } from "@ariakit/react/collection";
11
9
  import { useStoreState } from "@ariakit/react/store";
12
10
  import { forwardRef } from "./~utils.js";
13
- const Field = forwardRef((props, forwardedRef) => {
11
+ import {
12
+ FieldCollection,
13
+ FieldControlTypeContext
14
+ } from "./Field.internal.js";
15
+ import { Label } from "./Label.js";
16
+ import { Description } from "./Description.js";
17
+ const FieldRoot = forwardRef((props, forwardedRef) => {
14
18
  const { layout, ...rest } = props;
15
19
  return /* @__PURE__ */ jsx(
16
20
  FieldCollection,
@@ -27,75 +31,41 @@ const Field = forwardRef((props, forwardedRef) => {
27
31
  }
28
32
  );
29
33
  });
30
- function FieldCollection(props) {
31
- const fieldElementCollection = useCollectionStore({
32
- defaultItems: []
33
- });
34
- const renderedItems = useStoreState(fieldElementCollection, "renderedItems");
35
- const [controlType, controlIndex] = React.useMemo(() => {
36
- const controlIndex2 = renderedItems.findIndex(
37
- (item) => item.elementType === "control"
34
+ const FieldLabel = forwardRef(
35
+ (props, forwardedRef) => {
36
+ const store = useCollectionContext();
37
+ const renderedItems = useStoreState(
38
+ store,
39
+ "renderedItems"
38
40
  );
39
- return [renderedItems[controlIndex2]?.controlType, controlIndex2];
40
- }, [renderedItems]);
41
- const labelPlacement = React.useMemo(() => {
42
- const labelIndex = renderedItems.findIndex(
43
- (item) => item.elementType === "label"
41
+ const fieldId = React.useMemo(
42
+ () => renderedItems?.find((item) => item.elementType === "control")?.id,
43
+ [renderedItems]
44
44
  );
45
- if (controlIndex === -1 || labelIndex === -1) return;
46
- return labelIndex < controlIndex ? "before" : "after";
47
- }, [renderedItems, controlIndex]);
48
- return /* @__PURE__ */ jsx(
49
- Collection,
50
- {
51
- ...props,
52
- store: fieldElementCollection,
53
- "data-kiwi-label-placement": labelPlacement,
54
- "data-kiwi-control-type": controlType
55
- }
56
- );
57
- }
58
- function FieldControl(props) {
59
- const store = useCollectionContext();
45
+ const getData = React.useCallback(
46
+ (data) => ({
47
+ ...data,
48
+ elementType: "label"
49
+ }),
50
+ []
51
+ );
52
+ return /* @__PURE__ */ jsx(
53
+ CollectionItem,
54
+ {
55
+ getItem: getData,
56
+ render: /* @__PURE__ */ jsx(Label, { ...props, htmlFor: fieldId }),
57
+ ref: forwardedRef
58
+ }
59
+ );
60
+ }
61
+ );
62
+ const FieldDescription = forwardRef((props, forwardedRef) => {
60
63
  const generatedId = React.useId();
61
- const { id = store ? generatedId : void 0, type, ...rest } = props;
62
- const renderedItems = useStoreState(store, "renderedItems");
63
- const describedBy = React.useMemo(() => {
64
- const idRefList = renderedItems?.filter(
65
- (item) => item.elementType === "description"
66
- )?.map((item) => item.id).join(" ");
67
- return idRefList || void 0;
68
- }, [renderedItems]);
69
- const getData = React.useCallback(
70
- (data) => ({
71
- ...data,
72
- elementType: "control",
73
- controlType: type
74
- }),
75
- [type]
76
- );
77
- return /* @__PURE__ */ jsx(
78
- CollectionItem,
79
- {
80
- id,
81
- getItem: getData,
82
- render: /* @__PURE__ */ jsx(Role, { ...rest, "aria-describedby": describedBy })
83
- }
84
- );
85
- }
86
- function FieldLabel(props) {
87
- const store = useCollectionContext();
88
- const renderedItems = useStoreState(store, "renderedItems");
89
- const fieldId = React.useMemo(
90
- () => renderedItems?.find(
91
- (item) => item.elementType === "control"
92
- )?.id,
93
- [renderedItems]
94
- );
64
+ const { id = generatedId, ...rest } = props;
95
65
  const getData = React.useCallback(
96
66
  (data) => ({
97
67
  ...data,
98
- elementType: "label"
68
+ elementType: "description"
99
69
  }),
100
70
  []
101
71
  );
@@ -103,25 +73,86 @@ function FieldLabel(props) {
103
73
  CollectionItem,
104
74
  {
105
75
  getItem: getData,
106
- render: /* @__PURE__ */ jsx(Role.label, { ...props, htmlFor: fieldId })
76
+ id,
77
+ render: /* @__PURE__ */ jsx(Description, { ...rest }),
78
+ ref: forwardedRef
107
79
  }
108
80
  );
109
- }
110
- function FieldDescription(props) {
111
- const generatedId = React.useId();
112
- const { id = generatedId, ...rest } = props;
113
- const getData = React.useCallback(
114
- (data) => ({
115
- ...data,
116
- elementType: "description"
117
- }),
118
- []
119
- );
120
- return /* @__PURE__ */ jsx(CollectionItem, { ...rest, id, getItem: getData });
121
- }
81
+ });
82
+ const FieldControl = forwardRef(
83
+ (props, forwardedRef) => {
84
+ const [controlType, setControlType] = React.useState();
85
+ const store = useCollectionContext();
86
+ const generatedId = React.useId();
87
+ const { id = store ? generatedId : void 0, ...rest } = props;
88
+ const renderedItems = useStoreState(
89
+ store,
90
+ "renderedItems"
91
+ );
92
+ const describedBy = React.useMemo(() => {
93
+ const idRefList = renderedItems?.filter(
94
+ (item) => item.elementType === "description" || item.elementType === "error"
95
+ )?.map((item) => item.id).join(" ");
96
+ return idRefList || void 0;
97
+ }, [renderedItems]);
98
+ const getData = React.useCallback(
99
+ (data) => ({
100
+ ...data,
101
+ elementType: "control",
102
+ controlType
103
+ }),
104
+ [controlType]
105
+ );
106
+ const invalid = React.useMemo(
107
+ () => renderedItems?.some(
108
+ (item) => item.elementType === "error"
109
+ ),
110
+ [renderedItems]
111
+ );
112
+ return /* @__PURE__ */ jsx(FieldControlTypeContext.Provider, { value: setControlType, children: /* @__PURE__ */ jsx(
113
+ CollectionItem,
114
+ {
115
+ id,
116
+ getItem: getData,
117
+ render: /* @__PURE__ */ jsx(
118
+ Role,
119
+ {
120
+ ...rest,
121
+ "aria-invalid": invalid ? "true" : void 0,
122
+ "aria-describedby": describedBy
123
+ }
124
+ ),
125
+ ref: forwardedRef
126
+ }
127
+ ) });
128
+ }
129
+ );
130
+ const FieldErrorMessage = forwardRef(
131
+ (props, forwardedRef) => {
132
+ const generatedId = React.useId();
133
+ const { id = generatedId, ...rest } = props;
134
+ const getData = React.useCallback(
135
+ (data) => ({
136
+ ...data,
137
+ elementType: "error"
138
+ }),
139
+ []
140
+ );
141
+ return /* @__PURE__ */ jsx(
142
+ CollectionItem,
143
+ {
144
+ id,
145
+ getItem: getData,
146
+ render: /* @__PURE__ */ jsx(Description, { ...rest, tone: "critical" }),
147
+ ref: forwardedRef
148
+ }
149
+ );
150
+ }
151
+ );
122
152
  export {
123
- Field,
124
- FieldControl,
125
- FieldDescription,
126
- FieldLabel
153
+ FieldControl as Control,
154
+ FieldDescription as Description,
155
+ FieldErrorMessage as ErrorMessage,
156
+ FieldLabel as Label,
157
+ FieldRoot as Root
127
158
  };
@@ -71,4 +71,10 @@ export declare const Dismiss: React.ForwardRefExoticComponent<DismissProps & Rea
71
71
  interface StatusWarningProps extends Omit<BaseProps<"svg">, "children"> {
72
72
  }
73
73
  export declare const StatusWarning: React.ForwardRefExoticComponent<StatusWarningProps & React.RefAttributes<HTMLElement | SVGSVGElement>>;
74
+ interface MoreHorizontalProps extends Omit<BaseProps<"svg">, "children"> {
75
+ }
76
+ export declare const MoreHorizontal: React.ForwardRefExoticComponent<MoreHorizontalProps & React.RefAttributes<HTMLElement | SVGSVGElement>>;
77
+ interface ChevronDownProps extends Omit<BaseProps<"svg">, "children"> {
78
+ }
79
+ export declare const ChevronDown: React.ForwardRefExoticComponent<ChevronDownProps & React.RefAttributes<HTMLElement | SVGSVGElement>>;
74
80
  export {};
@@ -215,10 +215,65 @@ const StatusWarning = forwardRef(
215
215
  );
216
216
  }
217
217
  );
218
+ const MoreHorizontal = forwardRef(
219
+ (props, forwardedRef) => {
220
+ return /* @__PURE__ */ jsx(
221
+ Icon,
222
+ {
223
+ ...props,
224
+ render: /* @__PURE__ */ jsx(
225
+ Role.svg,
226
+ {
227
+ width: "16",
228
+ height: "16",
229
+ viewBox: "0 0 16 16",
230
+ fill: "none",
231
+ render: props.render,
232
+ children: /* @__PURE__ */ jsx(
233
+ "path",
234
+ {
235
+ fill: "currentColor",
236
+ fillRule: "evenodd",
237
+ d: "M3 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm6-1a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm5 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z",
238
+ clipRule: "evenodd"
239
+ }
240
+ )
241
+ }
242
+ ),
243
+ ref: forwardedRef
244
+ }
245
+ );
246
+ }
247
+ );
248
+ const ChevronDown = forwardRef(
249
+ (props, forwardedRef) => {
250
+ return /* @__PURE__ */ jsx(
251
+ Icon,
252
+ {
253
+ ...props,
254
+ render: /* @__PURE__ */ jsx(
255
+ Role.svg,
256
+ {
257
+ width: "16",
258
+ height: "16",
259
+ fill: "currentColor",
260
+ viewBox: "0 0 16 16",
261
+ render: props.render,
262
+ children: /* @__PURE__ */ jsx("path", { d: "M4.146 6.146a.5.5 0 0 1 .708 0L8 9.293l3.146-3.147a.5.5 0 0 1 .708.708l-3.5 3.5a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 0 1 0-.708Z" })
263
+ }
264
+ ),
265
+ className: cx("\u{1F95D}-chevron-down", props.className),
266
+ ref: forwardedRef
267
+ }
268
+ );
269
+ }
270
+ );
218
271
  export {
219
272
  Checkmark,
273
+ ChevronDown,
220
274
  DisclosureArrow,
221
275
  Dismiss,
222
276
  Icon,
277
+ MoreHorizontal,
223
278
  StatusWarning
224
279
  };
@@ -1,19 +1,18 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import cx from "classnames";
4
- import { useToolbarContext, ToolbarItem } from "@ariakit/react/toolbar";
5
4
  import { Button } from "./Button.js";
6
5
  import { VisuallyHidden } from "./VisuallyHidden.js";
7
6
  import { Icon } from "./Icon.js";
8
7
  import { Tooltip } from "./Tooltip.js";
9
8
  import { forwardRef } from "./~utils.js";
9
+ import { Dot } from "./~utils.Dot.js";
10
10
  const IconButton = forwardRef(
11
11
  (props, forwardedRef) => {
12
12
  const { label, icon, isActive, labelVariant, dot, ...rest } = props;
13
13
  const baseId = React.useId();
14
14
  const labelId = `${baseId}-label`;
15
15
  const dotId = `${baseId}-dot`;
16
- const toolbar = useToolbarContext();
17
16
  const button = /* @__PURE__ */ jsxs(
18
17
  Button,
19
18
  {
@@ -21,14 +20,12 @@ const IconButton = forwardRef(
21
20
  "aria-labelledby": labelId,
22
21
  "aria-describedby": dot ? dotId : void 0,
23
22
  ...rest,
24
- "data-kiwi-dot": dot ? "true" : void 0,
25
- render: toolbar ? /* @__PURE__ */ jsx(ToolbarItem, { render: props.render }) : props.render,
26
23
  className: cx("\u{1F95D}-icon-button", props.className),
27
24
  ref: forwardedRef,
28
25
  children: [
29
26
  /* @__PURE__ */ jsx(VisuallyHidden, { id: labelId, children: label }),
30
27
  typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { href: icon }) : icon,
31
- dot ? /* @__PURE__ */ jsx(VisuallyHidden, { id: dotId, "aria-hidden": "true", children: dot }) : null
28
+ dot ? /* @__PURE__ */ jsx(Dot, { id: dotId, className: "\u{1F95D}-icon-button-dot", children: dot }) : null
32
29
  ]
33
30
  }
34
31
  );
@@ -2,24 +2,17 @@ import { type BaseProps } from "./~utils.js";
2
2
  interface LabelProps extends BaseProps<"label"> {
3
3
  }
4
4
  /**
5
- * A styled wrapper over the HTML `<label>` element, used for labelling form controls.
5
+ * A styled wrapper over the HTML `<label>` element, used for labelling form
6
+ * controls.
6
7
  *
7
- * Can be used standalone:
8
-
8
+ * Example usage:
9
9
  * ```tsx
10
10
  * <Label htmlFor="my-input">Label</Label>
11
11
  * <TextBox.Input id="my-input" />
12
12
  * ```
13
13
  *
14
- * Or within a `Field` component to automatically manage ID associations:
15
- *
16
- * ```tsx
17
- * <Field>
18
- * <Label>Label</Label>
19
- * <TextBox.Input />
20
- * </Field>
21
- * ```
22
- *
14
+ * See `Field.Label` for convenient usage with form controls (e.g. automatic
15
+ * association with adjacent form control).
23
16
  */
24
17
  export declare const Label: import("react").ForwardRefExoticComponent<LabelProps & import("react").RefAttributes<HTMLElement | HTMLLabelElement>>;
25
18
  export {};
@@ -2,19 +2,13 @@ import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
3
  import { Role } from "@ariakit/react/role";
4
4
  import { forwardRef } from "./~utils.js";
5
- import { FieldLabel } from "./Field.js";
6
5
  const Label = forwardRef((props, forwardedRef) => {
7
6
  return /* @__PURE__ */ jsx(
8
- FieldLabel,
7
+ Role.label,
9
8
  {
10
- render: /* @__PURE__ */ jsx(
11
- Role.label,
12
- {
13
- ...props,
14
- className: cx("\u{1F95D}-label", props.className),
15
- ref: forwardedRef
16
- }
17
- )
9
+ ...props,
10
+ className: cx("\u{1F95D}-label", props.className),
11
+ ref: forwardedRef
18
12
  }
19
13
  );
20
14
  });
@@ -1,5 +1,11 @@
1
1
  import { type BaseProps } from "./~utils.js";
2
- interface ProgressBarProps extends Omit<BaseProps, "aria-labelledby">, Required<Pick<BaseProps, "aria-labelledby">> {
2
+ interface ProgressBarProps extends Omit<BaseProps, "aria-labelledby"> {
3
+ /**
4
+ * Label for the progress bar.
5
+ *
6
+ * This prop is required because `role="progressbar"` requires an accessible name.
7
+ */
8
+ "aria-labelledby": string;
3
9
  /**
4
10
  * The size of the progress bar.
5
11
  * @default "medium"
@@ -7,13 +7,22 @@ interface RadioProps extends InputBaseProps, RadioOwnProps {
7
7
  /**
8
8
  * A styled radio input element, typically used for selecting a single option from a list.
9
9
  *
10
- * Works well with the `Field` and `Label` components.
10
+ * Use with the `Field` components to automatically handle ID associations for
11
+ * labels and descriptions:
12
+ * ```tsx
13
+ * <Field.Root>
14
+ * <Field.Label>Choose one</Field.Label>
15
+ * <Field.Control render={<Radio />} />
16
+ * </Field.Root>
17
+ * ```
11
18
  *
19
+ * Without the `Field` components you will need to manually associate labels,
20
+ * descriptions, etc.:
12
21
  * ```tsx
13
- * <Field>
14
- * <Label>Choose one</Label>
15
- * <Radio />
16
- * </Field>
22
+ * <Radio id="editor-vim" name="editor" value="vim" />
23
+ * <Label htmlFor="editor-vim">Vim</Label>
24
+ * <Radio id="editor-emacs" name="editor" value="emacs" />
25
+ * <Label htmlFor="editor-emacs">Emacs</Label>
17
26
  * ```
18
27
  *
19
28
  * Underneath, it's an HTML radio input, i.e. `<input type="radio">`, so it supports the same props,
@@ -3,24 +3,17 @@ import cx from "classnames";
3
3
  import {
4
4
  Radio as AkRadio
5
5
  } from "@ariakit/react/radio";
6
- import { FieldControl } from "./Field.js";
7
6
  import { forwardRef } from "./~utils.js";
7
+ import { useFieldControlType } from "./Field.internal.js";
8
8
  const Radio = forwardRef((props, forwardedRef) => {
9
- const { id, ...rest } = props;
9
+ useFieldControlType("checkable");
10
10
  return /* @__PURE__ */ jsx(
11
- FieldControl,
11
+ AkRadio,
12
12
  {
13
- type: "checkable",
14
- id,
15
- render: /* @__PURE__ */ jsx(
16
- AkRadio,
17
- {
18
- accessibleWhenDisabled: true,
19
- ...rest,
20
- className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
21
- ref: forwardedRef
22
- }
23
- )
13
+ accessibleWhenDisabled: true,
14
+ ...props,
15
+ className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
16
+ ref: forwardedRef
24
17
  }
25
18
  );
26
19
  });
@@ -3,20 +3,37 @@ import { type FocusableProps } from "./~utils.js";
3
3
  /**
4
4
  * Compound component for a select element, which allows the user to select a value from a list of options.
5
5
  *
6
- * Works well with the `Field` and `Label` components.
6
+ * Use with the `Field` components to automatically handle ID associations for
7
+ * labels and descriptions:
8
+ * ```tsx
9
+ * <Field.Root>
10
+ * <Field.Label>Fruit</Field.Label>
11
+ * <Field.Control
12
+ * render={(controlProps) => (
13
+ * <Select.Root>
14
+ * <Select.HtmlSelect name="fruit" {...controlProps}>
15
+ * <option value="kiwi">Kiwi</option>
16
+ * <option value="mango">Mango</option>
17
+ * <option value="papaya">Papaya</option>
18
+ * </Select.HtmlSelect>
19
+ * </Select.Root>
20
+ * )}
21
+ * />
22
+ * </Field.Root>
23
+ * ```
7
24
  *
8
- * Example usage:
25
+ * Without the `Field` components you will need to manually associate labels,
26
+ * descriptions, etc.:
9
27
  * ```tsx
10
- * <Field>
11
- * <Label>Select an option</Label>
12
- * <Select.Root>
13
- * <Select.HtmlSelect>
14
- * <option value="1">Option 1</option>
15
- * <option value="2">Option 2</option>
16
- * <option value="3">Option 3</option>
17
- * </Select.HtmlSelect>
18
- * </Select.Root>
19
- * </Field>
28
+ * <Label htmlFor="fruit">Fruit</Label>
29
+ * <Description id="fruit-description">Something to include in a fruit salad.</Description>
30
+ * <Select.Root>
31
+ * <Select.HtmlSelect id="fruit" aria-labelledby="fruit-description">
32
+ * <option value="kiwi">Kiwi</option>
33
+ * <option value="mango">Mango</option>
34
+ * <option value="papaya">Papaya</option>
35
+ * </Select.HtmlSelect>
36
+ * </Select.Root>
20
37
  * ```
21
38
  */
22
39
  declare const SelectRoot: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
@@ -7,11 +7,12 @@ import {
7
7
  isBrowser
8
8
  } from "./~utils.js";
9
9
  import { DisclosureArrow } from "./Icon.js";
10
- import { FieldControl } from "./Field.js";
10
+ import { useFieldControlType } from "./Field.internal.js";
11
11
  const supportsHas = isBrowser && CSS?.supports?.("selector(:has(+ *))");
12
12
  const HtmlSelectContext = React.createContext(() => {
13
13
  });
14
14
  const SelectRoot = forwardRef((props, forwardedRef) => {
15
+ useFieldControlType("textlike");
15
16
  const [isHtmlSelect, setIsHtmlSelect] = React.useState(false);
16
17
  return /* @__PURE__ */ jsx(HtmlSelectContext.Provider, { value: setIsHtmlSelect, children: /* @__PURE__ */ jsx(
17
18
  Role.div,
@@ -25,7 +26,7 @@ const SelectRoot = forwardRef((props, forwardedRef) => {
25
26
  });
26
27
  const HtmlSelect = forwardRef(
27
28
  (props, forwardedRef) => {
28
- const { id, variant = "solid", ...rest } = props;
29
+ const { variant = "solid", ...rest } = props;
29
30
  const setIsHtmlSelect = React.useContext(HtmlSelectContext);
30
31
  React.useEffect(
31
32
  function updateContext() {
@@ -35,20 +36,13 @@ const HtmlSelect = forwardRef(
35
36
  );
36
37
  return /* @__PURE__ */ jsxs(Fragment, { children: [
37
38
  /* @__PURE__ */ jsx(
38
- FieldControl,
39
+ Role.select,
39
40
  {
40
- type: "textlike",
41
- id,
42
- render: /* @__PURE__ */ jsx(
43
- Role.select,
44
- {
45
- ...rest,
46
- className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
47
- "data-kiwi-tone": "neutral",
48
- "data-kiwi-variant": variant,
49
- ref: forwardedRef
50
- }
51
- )
41
+ ...rest,
42
+ className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
43
+ "data-kiwi-tone": "neutral",
44
+ "data-kiwi-variant": variant,
45
+ ref: forwardedRef
52
46
  }
53
47
  ),
54
48
  /* @__PURE__ */ jsx(DisclosureArrow, { className: "\u{1F95D}-select-arrow" })
@@ -11,13 +11,20 @@ interface SwitchProps extends InputBaseProps, CheckboxOwnProps {
11
11
  /**
12
12
  * A toggle switch element, typically used for enabling or disabling a feature.
13
13
  *
14
- * Works well with the `Field` and `Label` components.
14
+ * Use with the `Field` components to automatically handle ID associations for
15
+ * labels and descriptions:
16
+ * ```tsx
17
+ * <Field.Root>
18
+ * <Field.Label>Enable feature</Field.Label>
19
+ * <Field.Control render={<Switch />} />
20
+ * </Field.Root>
21
+ * ```
15
22
  *
23
+ * Without the `Field` components you will need to manually associate labels,
24
+ * descriptions, etc.:
16
25
  * ```tsx
17
- * <Field>
18
- * <Label>Enable feature</Label>
19
- * <Switch />
20
- * </Field>
26
+ * <Switch id="dark-mode" />
27
+ * <Label htmlFor="dark-mode">Dark mode</Label>
21
28
  * ```
22
29
  *
23
30
  * Underneath, it's an HTML checkbox, i.e. `<input type="checkbox">`, so it supports the same props,
@@ -3,26 +3,19 @@ import cx from "classnames";
3
3
  import {
4
4
  Checkbox as AkCheckbox
5
5
  } from "@ariakit/react/checkbox";
6
- import { FieldControl } from "./Field.js";
7
6
  import { forwardRef } from "./~utils.js";
7
+ import { useFieldControlType } from "./Field.internal.js";
8
8
  const Switch = forwardRef(
9
9
  (props, forwardedRef) => {
10
- const { id, ...rest } = props;
10
+ useFieldControlType("checkable");
11
11
  return /* @__PURE__ */ jsx(
12
- FieldControl,
12
+ AkCheckbox,
13
13
  {
14
- type: "checkable",
15
- id,
16
- render: /* @__PURE__ */ jsx(
17
- AkCheckbox,
18
- {
19
- accessibleWhenDisabled: true,
20
- ...rest,
21
- className: cx("\u{1F95D}-switch", props.className),
22
- role: "switch",
23
- ref: forwardedRef
24
- }
25
- )
14
+ accessibleWhenDisabled: true,
15
+ ...props,
16
+ className: cx("\u{1F95D}-switch", props.className),
17
+ role: "switch",
18
+ ref: forwardedRef
26
19
  }
27
20
  );
28
21
  }