@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
@@ -24,8 +24,8 @@ interface DropdownMenuProps extends Pick<MenuProviderProps, "children" | "placem
24
24
  *
25
25
  * **Note**: `DropdownMenu` should not be used for navigation; it is only intended for actions.
26
26
  */
27
- declare function DropdownMenu(props: DropdownMenuProps): import("react/jsx-runtime").JSX.Element;
28
- declare namespace DropdownMenu {
27
+ declare function DropdownMenuRoot(props: DropdownMenuProps): import("react/jsx-runtime").JSX.Element;
28
+ declare namespace DropdownMenuRoot {
29
29
  var displayName: string;
30
30
  }
31
31
  interface DropdownMenuContentProps extends FocusableProps {
@@ -56,9 +56,11 @@ interface DropdownMenuButtonProps extends FocusableProps<"button"> {
56
56
  * ```
57
57
  */
58
58
  declare const DropdownMenuButton: React.ForwardRefExoticComponent<DropdownMenuButtonProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
59
- interface DropdownMenuItemProps extends Omit<FocusableProps, "children">, Partial<Pick<DropdownMenuItemShortcutsProps, "shortcuts"> & Pick<DropdownMenuIconProps, "icon">> {
59
+ interface DropdownMenuItemProps extends Omit<FocusableProps<"button">, "children">, Partial<Pick<DropdownMenuItemShortcutsProps, "shortcuts"> & Pick<DropdownMenuIconProps, "icon">> {
60
60
  /** The primary text label for the menu-item. */
61
61
  label: React.ReactNode;
62
+ /** Dot shown on the right end of the menu-item. Value will be used as accessible description. */
63
+ unstable_dot?: string;
62
64
  }
63
65
  /**
64
66
  * A single menu item within the dropdown menu. Should be used as a child of `DropdownMenu.Content`.
@@ -69,8 +71,8 @@ interface DropdownMenuItemProps extends Omit<FocusableProps, "children">, Partia
69
71
  * <DropdownMenu.Item label="Edit" />
70
72
  * ```
71
73
  */
72
- declare const DropdownMenuItem: React.ForwardRefExoticComponent<DropdownMenuItemProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
73
- interface DropdownMenuItemShortcutsProps extends BaseProps {
74
+ declare const DropdownMenuItem: React.ForwardRefExoticComponent<DropdownMenuItemProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
75
+ interface DropdownMenuItemShortcutsProps extends Omit<BaseProps<"span">, "children"> {
74
76
  /**
75
77
  * A string defining the keyboard shortcut(s) associated with the menu item.
76
78
  *
@@ -87,7 +89,7 @@ interface DropdownMenuItemShortcutsProps extends BaseProps {
87
89
  */
88
90
  shortcuts: AnyString | `${PredefinedSymbol}+${AnyString}`;
89
91
  }
90
- interface DropdownMenuIconProps extends BaseProps {
92
+ interface DropdownMenuIconProps extends BaseProps<"svg"> {
91
93
  /**
92
94
  * An optional icon displayed before the menu-item label.
93
95
  *
@@ -96,7 +98,7 @@ interface DropdownMenuIconProps extends BaseProps {
96
98
  */
97
99
  icon?: string | React.JSX.Element;
98
100
  }
99
- interface DropdownMenuCheckboxItemProps extends Omit<FocusableProps, "onChange" | "children">, Pick<MenuItemCheckboxProps, "checked" | "onChange" | "name" | "value">, Pick<DropdownMenuItemProps, "label" | "icon"> {
101
+ interface DropdownMenuCheckboxItemProps extends Omit<FocusableProps<"button">, "onChange" | "children" | "name">, Pick<MenuItemCheckboxProps, "defaultChecked" | "checked" | "onChange" | "name" | "value">, Pick<DropdownMenuItemProps, "label" | "icon"> {
100
102
  }
101
103
  /**
102
104
  * A single menu item within the dropdown menu. Should be used as a child of `DropdownMenu.Content`.
@@ -107,5 +109,5 @@ interface DropdownMenuCheckboxItemProps extends Omit<FocusableProps, "onChange"
107
109
  * <DropdownMenu.CheckboxItem name="edit" label="Edit" />
108
110
  * ```
109
111
  */
110
- declare const DropdownMenuCheckboxItem: React.ForwardRefExoticComponent<DropdownMenuCheckboxItemProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
111
- export { DropdownMenu as Root, DropdownMenuButton as Button, DropdownMenuContent as Content, DropdownMenuItem as Item, DropdownMenuCheckboxItem as CheckboxItem, };
112
+ declare const DropdownMenuCheckboxItem: React.ForwardRefExoticComponent<DropdownMenuCheckboxItemProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
113
+ export { DropdownMenuRoot as Root, DropdownMenuButton as Button, DropdownMenuContent as Content, DropdownMenuItem as Item, DropdownMenuCheckboxItem as CheckboxItem, };
@@ -3,6 +3,7 @@ import * as React from "react";
3
3
  import cx from "classnames";
4
4
  import * as ListItem from "./~utils.ListItem.js";
5
5
  import { Button } from "./Button.js";
6
+ import { Button as ButtonAk } from "@ariakit/react/button";
6
7
  import { Kbd } from "./Kbd.js";
7
8
  import { Checkmark, DisclosureArrow, Icon } from "./Icon.js";
8
9
  import {
@@ -19,7 +20,9 @@ import {
19
20
  } from "@ariakit/react/menu";
20
21
  import { useStoreState } from "@ariakit/react/store";
21
22
  import { predefinedSymbols } from "./Kbd.internal.js";
22
- function DropdownMenu(props) {
23
+ import { usePopoverContext } from "@ariakit/react/popover";
24
+ import { Dot } from "./~utils.Dot.js";
25
+ function DropdownMenuRoot(props) {
23
26
  const {
24
27
  children,
25
28
  placement,
@@ -34,6 +37,7 @@ function DropdownMenu(props) {
34
37
  defaultOpen: defaultOpenProp,
35
38
  open: openProp,
36
39
  setOpen: setOpenProp,
40
+ popover: usePopoverContext(),
37
41
  children
38
42
  }
39
43
  );
@@ -78,19 +82,37 @@ const DropdownMenuButton = forwardRef(
78
82
  );
79
83
  const DropdownMenuItem = forwardRef(
80
84
  (props, forwardedRef) => {
81
- const { label, shortcuts, icon, ...rest } = props;
85
+ const { label, shortcuts, icon, unstable_dot, ...rest } = props;
86
+ const dotId = React.useId();
82
87
  return /* @__PURE__ */ jsxs(
83
88
  MenuItem,
84
89
  {
85
90
  accessibleWhenDisabled: true,
86
- ...rest,
87
- render: /* @__PURE__ */ jsx(ListItem.Root, { render: props.render }),
88
- className: cx("\u{1F95D}-dropdown-menu-item", props.className),
89
- ref: forwardedRef,
91
+ render: /* @__PURE__ */ jsx(
92
+ ListItem.Root,
93
+ {
94
+ render: /* @__PURE__ */ jsx(
95
+ ButtonAk,
96
+ {
97
+ accessibleWhenDisabled: true,
98
+ "aria-describedby": dotId,
99
+ ...rest,
100
+ className: cx("\u{1F95D}-dropdown-menu-item", props.className),
101
+ ref: forwardedRef
102
+ }
103
+ )
104
+ }
105
+ ),
90
106
  children: [
91
107
  icon ? /* @__PURE__ */ jsx(DropdownMenuIcon, { icon }) : null,
92
- /* @__PURE__ */ jsx(ListItem.Content, { children: label }),
93
- shortcuts ? /* @__PURE__ */ jsx(DropdownMenuItemShortcuts, { shortcuts }) : null
108
+ /* @__PURE__ */ jsx(ListItem.Content, { render: /* @__PURE__ */ jsx("span", {}), children: label }),
109
+ shortcuts ? /* @__PURE__ */ jsx(DropdownMenuItemShortcuts, { shortcuts }) : null,
110
+ unstable_dot ? /* @__PURE__ */ jsx(
111
+ ListItem.Decoration,
112
+ {
113
+ render: /* @__PURE__ */ jsx(Dot, { id: dotId, className: "\u{1F95D}-dropdown-menu-item-dot", children: unstable_dot })
114
+ }
115
+ ) : null
94
116
  ]
95
117
  }
96
118
  );
@@ -107,6 +129,7 @@ const DropdownMenuItemShortcuts = forwardRef((props, forwardedRef) => {
107
129
  return /* @__PURE__ */ jsx(
108
130
  ListItem.Decoration,
109
131
  {
132
+ render: /* @__PURE__ */ jsx("span", {}),
110
133
  ...rest,
111
134
  className: cx("\u{1F95D}-dropdown-menu-item-shortcuts", props.className),
112
135
  ref: forwardedRef,
@@ -136,29 +159,53 @@ const DropdownMenuIcon = forwardRef(
136
159
  Icon,
137
160
  {
138
161
  href: typeof icon === "string" ? icon : void 0,
139
- render: React.isValidElement(icon) ? icon : void 0
162
+ render: React.isValidElement(icon) ? icon : void 0,
163
+ ...rest,
164
+ ref: forwardedRef
140
165
  }
141
- ),
142
- ...rest,
143
- ref: forwardedRef
166
+ )
144
167
  }
145
168
  );
146
169
  }
147
170
  );
148
171
  const DropdownMenuCheckboxItem = forwardRef((props, forwardedRef) => {
149
- const { label, icon, ...rest } = props;
172
+ const {
173
+ label,
174
+ icon,
175
+ defaultChecked,
176
+ checked,
177
+ onChange,
178
+ name,
179
+ value = defaultChecked ? "on" : void 0,
180
+ // For defaultChecked to work
181
+ ...rest
182
+ } = props;
150
183
  return /* @__PURE__ */ jsxs(
151
184
  MenuItemCheckbox,
152
185
  {
153
186
  accessibleWhenDisabled: true,
154
- value: props.defaultChecked ? "on" : void 0,
155
- ...rest,
156
- render: /* @__PURE__ */ jsx(ListItem.Root, { render: props.render }),
157
- className: cx("\u{1F95D}-dropdown-menu-item", props.className),
158
- ref: forwardedRef,
187
+ defaultChecked,
188
+ checked,
189
+ name,
190
+ value,
191
+ onChange,
192
+ render: /* @__PURE__ */ jsx(
193
+ ListItem.Root,
194
+ {
195
+ render: /* @__PURE__ */ jsx(
196
+ ButtonAk,
197
+ {
198
+ accessibleWhenDisabled: true,
199
+ ...rest,
200
+ className: cx("\u{1F95D}-dropdown-menu-item", props.className),
201
+ ref: forwardedRef
202
+ }
203
+ )
204
+ }
205
+ ),
159
206
  children: [
160
207
  icon ? /* @__PURE__ */ jsx(DropdownMenuIcon, { icon }) : null,
161
- /* @__PURE__ */ jsx(ListItem.Content, { children: label }),
208
+ /* @__PURE__ */ jsx(ListItem.Content, { render: /* @__PURE__ */ jsx("span", {}), children: label }),
162
209
  /* @__PURE__ */ jsx(
163
210
  ListItem.Decoration,
164
211
  {
@@ -174,5 +221,5 @@ export {
174
221
  DropdownMenuCheckboxItem as CheckboxItem,
175
222
  DropdownMenuContent as Content,
176
223
  DropdownMenuItem as Item,
177
- DropdownMenu as Root
224
+ DropdownMenuRoot as Root
178
225
  };
@@ -0,0 +1,88 @@
1
+ import * as React from "react";
2
+ import { type BaseProps } from "./~utils.js";
3
+ interface ErrorRegionRootProps extends Omit<BaseProps, "children"> {
4
+ /**
5
+ * Label for the error header, usually indicating the number of errors displayed.
6
+ * By default this is used as a name of the region navigational landmark, however an explicit `aria-label` or `aria-labelledby` is strongly suggested.
7
+ *
8
+ * Use `undefined` if you don't want to display errors rather than conditionally rendering the component.
9
+ */
10
+ label?: React.ReactNode;
11
+ /**
12
+ * A list of error items where each item describes an individual error. Must be a list of `ErrorRegion.Item` components.
13
+ */
14
+ items?: React.ReactNode;
15
+ /**
16
+ * The controlled expanded state of the error.
17
+ */
18
+ expanded?: boolean;
19
+ /**
20
+ * Callback fired when the error is expanded.
21
+ *
22
+ * Should be used with the `expanded` prop.
23
+ */
24
+ onExpandedChange?: (expanded: boolean) => void;
25
+ }
26
+ /**
27
+ * A collapsible region that displays a list of error messages, which might originate from another
28
+ * component, such as `Tree`.
29
+ *
30
+ * This component is rendered as a [region landmark](https://www.w3.org/WAI/ARIA/apg/patterns/landmarks/examples/region.html)
31
+ * and should be labelled either using `label` or `aria-label`/`aria-labelledby`. Changes to the `label` prop will be
32
+ * announced communicated using a [live region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions).
33
+ *
34
+ * Example:
35
+ * ```tsx
36
+ * <ErrorRegion.Root
37
+ * label="3 issues found"
38
+ * items={
39
+ * <>
40
+ * <ErrorRegion.Item message="…" />
41
+ * <ErrorRegion.Item message="…" />
42
+ * <ErrorRegion.Item message="…" />
43
+ * </>
44
+ * }
45
+ * />
46
+ */
47
+ declare const ErrorRegionRoot: React.ForwardRefExoticComponent<ErrorRegionRootProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
48
+ interface ErrorRegionItemProps extends Omit<BaseProps, "children"> {
49
+ /**
50
+ * The error message. Consumers might consider using `Anchor` component to link to the associated element in the UI.
51
+ */
52
+ message?: React.ReactNode;
53
+ /**
54
+ * The `id` of the message node which can be used to semantically associate the error item with the related UI item i.e. `Tree.Item`.
55
+ */
56
+ messageId?: string;
57
+ /**
58
+ * The actions available for this item. Must be a list of anchors, each rendered as a button using `<Anchor render={<button />} />`.
59
+ */
60
+ actions?: React.ReactNode;
61
+ /**
62
+ * Callback fired when the error item is dismissed.
63
+ */
64
+ onDismiss?: () => void;
65
+ }
66
+ /**
67
+ * An individual error item within the `ErrorRegion` component. It displays an error message and optional actions.
68
+ *
69
+ * The `messageId` prop can be used to semantically associate the error item with the related UI item, such as a `Tree.Item`.
70
+ *
71
+ * Example:
72
+ * ```tsx
73
+ * <ErrorRegion.Item
74
+ * message={<>Something went wrong with <Anchor href="item-10001">Item 10001</Anchor>.</>}
75
+ * messageId="item-10001-error"
76
+ * actions={<Button>Retry</Button>}
77
+ * onDismiss={() => {}}
78
+ * />
79
+ *
80
+ * <Tree.Item
81
+ * id="item-10001"
82
+ * label="Item 10001"
83
+ * error="item-10001-error"
84
+ * />
85
+ * ```
86
+ */
87
+ declare const ErrorRegionItem: React.ForwardRefExoticComponent<ErrorRegionItemProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
88
+ export { ErrorRegionRoot as Root, ErrorRegionItem as Item };
@@ -0,0 +1,135 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import cx from "classnames";
4
+ import {
5
+ DialogProvider,
6
+ DialogDisclosure,
7
+ Dialog
8
+ } from "@ariakit/react/dialog";
9
+ import { Role } from "@ariakit/react/role";
10
+ import { forwardRef } from "./~utils.js";
11
+ import { ChevronDown, Dismiss, StatusWarning } from "./Icon.js";
12
+ import { Text } from "./Text.js";
13
+ import { IconButton } from "./IconButton.js";
14
+ import { Button } from "./Button.js";
15
+ import { useControlledState } from "./~hooks.js";
16
+ import { VisuallyHidden } from "./VisuallyHidden.js";
17
+ const ErrorRegionRoot = forwardRef(
18
+ (props, forwardedRef) => {
19
+ const { label, items, expanded, onExpandedChange, ...rest } = props;
20
+ const labelId = React.useId();
21
+ const sectionLabelledBy = props["aria-labelledby"] ?? (props["aria-label"] ? void 0 : labelId);
22
+ const [open, setOpen] = useControlledState(
23
+ false,
24
+ expanded,
25
+ onExpandedChange
26
+ );
27
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
28
+ /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "polite", "aria-atomic": true, children: label }),
29
+ /* @__PURE__ */ jsx(DialogProvider, { open, setOpen, children: /* @__PURE__ */ jsx(
30
+ Role.section,
31
+ {
32
+ ...rest,
33
+ "aria-labelledby": sectionLabelledBy,
34
+ className: cx("\u{1F95D}-error-region", props.className),
35
+ "data-kiwi-visible": !!label,
36
+ "data-kiwi-expanded": open,
37
+ ref: forwardedRef,
38
+ children: /* @__PURE__ */ jsxs("div", { className: "\u{1F95D}-error-region-container", children: [
39
+ /* @__PURE__ */ jsxs(
40
+ DialogDisclosure,
41
+ {
42
+ className: "\u{1F95D}-error-region-header",
43
+ render: /* @__PURE__ */ jsx(Button, { variant: "ghost" }),
44
+ children: [
45
+ /* @__PURE__ */ jsx(StatusWarning, { className: "\u{1F95D}-error-region-icon" }),
46
+ /* @__PURE__ */ jsx(
47
+ Text,
48
+ {
49
+ id: labelId,
50
+ className: "\u{1F95D}-error-region-label",
51
+ variant: "body-sm",
52
+ children: label
53
+ }
54
+ ),
55
+ /* @__PURE__ */ jsx(
56
+ IconButton,
57
+ {
58
+ inert: true,
59
+ render: /* @__PURE__ */ jsx("span", {}),
60
+ role: void 0,
61
+ label: "",
62
+ icon: /* @__PURE__ */ jsx(ChevronDown, {}),
63
+ variant: "ghost"
64
+ }
65
+ )
66
+ ]
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsx(
70
+ Dialog,
71
+ {
72
+ className: "\u{1F95D}-error-region-dialog",
73
+ portal: false,
74
+ modal: false,
75
+ autoFocusOnShow: false,
76
+ "aria-labelledby": labelId,
77
+ children: /* @__PURE__ */ jsx("div", { className: "\u{1F95D}-error-region-items", role: "list", children: items })
78
+ }
79
+ )
80
+ ] })
81
+ }
82
+ ) })
83
+ ] });
84
+ }
85
+ );
86
+ const ErrorRegionItem = forwardRef(
87
+ (props, forwardedRef) => {
88
+ const generatedId = React.useId();
89
+ const {
90
+ message,
91
+ messageId = `${generatedId}-message`,
92
+ actions,
93
+ onDismiss,
94
+ ...rest
95
+ } = props;
96
+ const dismissButtonId = `${generatedId}-dismiss`;
97
+ return /* @__PURE__ */ jsxs(
98
+ Role.div,
99
+ {
100
+ ...rest,
101
+ role: "listitem",
102
+ className: cx("\u{1F95D}-error-region-item", props.className),
103
+ ref: forwardedRef,
104
+ children: [
105
+ /* @__PURE__ */ jsx(
106
+ Text,
107
+ {
108
+ id: messageId,
109
+ variant: "body-sm",
110
+ className: "\u{1F95D}-error-region-item-message",
111
+ children: message
112
+ }
113
+ ),
114
+ onDismiss && /* @__PURE__ */ jsx(
115
+ IconButton,
116
+ {
117
+ id: dismissButtonId,
118
+ className: "\u{1F95D}-error-region-item-dismiss",
119
+ variant: "ghost",
120
+ label: "Dismiss",
121
+ "aria-labelledby": `${dismissButtonId} ${messageId}`,
122
+ icon: /* @__PURE__ */ jsx(Dismiss, {}),
123
+ onClick: onDismiss
124
+ }
125
+ ),
126
+ /* @__PURE__ */ jsx("div", { className: "\u{1F95D}-error-region-item-actions", children: actions })
127
+ ]
128
+ }
129
+ );
130
+ }
131
+ );
132
+ export {
133
+ ErrorRegionItem as Item,
134
+ ErrorRegionRoot as Root
135
+ };
@@ -1,53 +1,95 @@
1
1
  import * as React from "react";
2
- import { useCollectionStore, type CollectionItemProps } from "@ariakit/react/collection";
2
+ import { type CollectionItemProps } from "@ariakit/react/collection";
3
3
  import { type BaseProps } from "./~utils.js";
4
- interface FieldProps extends BaseProps {
4
+ interface FieldRootProps extends BaseProps {
5
5
  /**
6
6
  * Allows overriding the default block layout for text controls.
7
7
  */
8
8
  layout?: "inline";
9
9
  }
10
10
  /**
11
- * A container for form controls. It manages ID associations provides a consistent layout and spacing.
11
+ * A container for form controls. It manages ID associations, and provides a
12
+ * consistent layout and spacing.
12
13
  *
13
14
  * Example:
14
15
  * ```tsx
15
- * <Field>
16
- * <Label>Label</Label>
17
- * <TextBox.Input />
18
- * </Field>
16
+ * <Field.Root>
17
+ * <Field.Label>Label</Field.Label>
18
+ * <Field.Control render={<TextBox.Input />} />
19
+ * </Field.Root>
19
20
  * ```
20
21
  *
21
- * Supports a `layout` prop, which can be set to `inline` to align the label and control horizontally.
22
+ * Supports a `layout` prop, which can be set to `inline` to align the label and
23
+ * control horizontally.
22
24
  *
23
- * Should contain a `Label` component paired with a form control. Supported form controls include:
25
+ * Should contain a `Field.Label` component paired with a form control.
26
+ *
27
+ * Supported form controls include:
24
28
  * - `TextBox.Input`
25
29
  * - `TextBox.Textarea`
26
30
  * - `Checkbox`
27
31
  * - `Radio`
28
32
  * - `Switch`
29
33
  */
30
- export declare const Field: React.ForwardRefExoticComponent<FieldProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
31
- type CollectionStoreItem = NonNullable<ReturnType<ReturnType<typeof useCollectionStore>["item"]>>;
32
- interface FieldCollectionStoreItem extends CollectionStoreItem {
33
- /** The type of field element being tracked */
34
- elementType: "label" | "control" | "description";
35
- /** If a control, the type of control. */
36
- controlType?: "textlike" | "checkable";
37
- }
38
- interface FieldCollectionItemControlProps extends Pick<CollectionItemProps, "render" | "id"> {
39
- type: FieldCollectionStoreItem["controlType"];
40
- }
34
+ declare const FieldRoot: React.ForwardRefExoticComponent<FieldRootProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
41
35
  /**
42
- * An element tracked as a control in the `Field`’s collection.
36
+ * A label for the field’s control element. This is automatically associated
37
+ * with the control’s `id`.
43
38
  */
44
- export declare function FieldControl(props: FieldCollectionItemControlProps): import("react/jsx-runtime").JSX.Element;
39
+ declare const FieldLabel: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
45
40
  /**
46
- * An element tracked as a label in the `Field`’s collection.
41
+ * A description for the field’s control element. This is automatically
42
+ * associated with the control.
43
+ *
44
+ * Should not include content without an adequate text alternative (e.g.
45
+ * interactive elements).
47
46
  */
48
- export declare function FieldLabel(props: Pick<CollectionItemProps, "render">): import("react/jsx-runtime").JSX.Element;
47
+ declare const FieldDescription: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
48
+ interface FieldCollectionItemControlProps extends Pick<CollectionItemProps, "render" | "id"> {
49
+ }
49
50
  /**
50
- * An element tracked as a description in the `Field`’s collection.
51
+ * The control component for the field.
52
+ *
53
+ * Use the `render` prop to render the control component.
54
+ *
55
+ * ```tsx
56
+ * <Field.Control render={<TextBox.Input />} />
57
+ * ```
58
+ *
59
+ * If the rendered component uses a compositional API, then use a function
60
+ * within `render` to apply the `controlProps` to the correct sub-component:
61
+ *
62
+ * ```tsx
63
+ * <Field.Control
64
+ * render={(controlProps) => (
65
+ * <TextBox.Root>
66
+ * <TextBox.Icon href={placeholder} />
67
+ * <TextBox.Input {...controlProps} />
68
+ * </TextBox.Root>
69
+ * )}
70
+ * />
71
+ * ```
72
+ *
73
+ * If you need a custom `id` set for the control, set it on this component
74
+ * instead of the control component within `render`.
75
+ *
76
+ * ```tsx
77
+ * <Field.Control id="custom" render={<TextBox.Input />} />
78
+ * ```
79
+ */
80
+ declare const FieldControl: React.ForwardRefExoticComponent<FieldCollectionItemControlProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
81
+ /**
82
+ * An associated error message for a field. When used within `<Field.Root>`, the
83
+ * associated form control will be rendered with `aria-invalid="true"`.
84
+ *
85
+ * Example:
86
+ * ```tsx
87
+ * <Field.Root>
88
+ * <Field.Label>Label</Field.Label>
89
+ * <Field.Control render={<TextBox.Input />} />
90
+ * <Field.ErrorMessage>Something is wrong!</Field.ErrorMessage>
91
+ * </Field.Root>
92
+ * ```
51
93
  */
52
- export declare function FieldDescription(props: Pick<CollectionItemProps, "render" | "id">): import("react/jsx-runtime").JSX.Element;
53
- export {};
94
+ declare const FieldErrorMessage: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
95
+ export { FieldRoot as Root, FieldControl as Control, FieldLabel as Label, FieldDescription as Description, FieldErrorMessage as ErrorMessage, };
@@ -0,0 +1,33 @@
1
+ import * as React from "react";
2
+ import { useCollectionStore, type CollectionProps } from "@ariakit/react/collection";
3
+ /**
4
+ * Ariakit’s unexported `CollectionStoreItem` type inferred.
5
+ * @private
6
+ */
7
+ export type CollectionStoreItem = NonNullable<ReturnType<ReturnType<typeof useCollectionStore>["item"]>>;
8
+ /**
9
+ * An extension of `CollectionStoreItem` to track element and control types.
10
+ * @private
11
+ */
12
+ export interface FieldCollectionStoreItem extends CollectionStoreItem {
13
+ /** The type of field element being tracked */
14
+ elementType: "label" | "control" | "description" | "error";
15
+ /** If a control, the type of control. */
16
+ controlType?: "textlike" | "checkable";
17
+ }
18
+ /**
19
+ * A collection that tracks labels, controls, and descriptions which provides
20
+ * information about IDs, placement of labels, and control types.
21
+ * @private
22
+ */
23
+ export declare function FieldCollection(props: Pick<CollectionProps, "render">): import("react/jsx-runtime").JSX.Element;
24
+ /**
25
+ * Control type context for the field.
26
+ * @private
27
+ */
28
+ export declare const FieldControlTypeContext: React.Context<React.Dispatch<React.SetStateAction<"textlike" | "checkable" | undefined>> | undefined>;
29
+ /**
30
+ * Sets the control type for the field. Necessary for layout.
31
+ * @private
32
+ */
33
+ export declare function useFieldControlType(controlType: NonNullable<FieldCollectionStoreItem["controlType"]>): void;
@@ -0,0 +1,47 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import {
4
+ useCollectionStore,
5
+ Collection
6
+ } from "@ariakit/react/collection";
7
+ import { useStoreState } from "@ariakit/react/store";
8
+ function FieldCollection(props) {
9
+ const fieldElementCollection = useCollectionStore({
10
+ defaultItems: []
11
+ });
12
+ const renderedItems = useStoreState(fieldElementCollection, "renderedItems");
13
+ const [controlType, controlIndex] = React.useMemo(() => {
14
+ const controlIndex2 = renderedItems.findIndex(
15
+ (item) => item.elementType === "control"
16
+ );
17
+ return [renderedItems[controlIndex2]?.controlType, controlIndex2];
18
+ }, [renderedItems]);
19
+ const labelPlacement = React.useMemo(() => {
20
+ const labelIndex = renderedItems.findIndex(
21
+ (item) => item.elementType === "label"
22
+ );
23
+ if (controlIndex === -1 || labelIndex === -1) return;
24
+ return labelIndex < controlIndex ? "before" : "after";
25
+ }, [renderedItems, controlIndex]);
26
+ return /* @__PURE__ */ jsx(
27
+ Collection,
28
+ {
29
+ ...props,
30
+ store: fieldElementCollection,
31
+ "data-kiwi-label-placement": labelPlacement,
32
+ "data-kiwi-control-type": controlType
33
+ }
34
+ );
35
+ }
36
+ const FieldControlTypeContext = React.createContext(void 0);
37
+ function useFieldControlType(controlType) {
38
+ const setControlType = React.useContext(FieldControlTypeContext);
39
+ React.useEffect(() => {
40
+ setControlType?.(controlType);
41
+ }, [controlType, setControlType]);
42
+ }
43
+ export {
44
+ FieldCollection,
45
+ FieldControlTypeContext,
46
+ useFieldControlType
47
+ };