@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
@@ -0,0 +1,35 @@
1
+ import { type BaseProps } from "./~utils.js";
2
+ interface ToolbarProps extends BaseProps {
3
+ /** Must be set to `"solid"` for now. */
4
+ variant: "solid";
5
+ }
6
+ /**
7
+ * A toolbar for grouping related interactive elements.
8
+ *
9
+ * Follows the [ARIA Toolbar pattern](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/) for reducing the number of tab stops.
10
+ *
11
+ * Example:
12
+ * ```jsx
13
+ * <Toolbar.Group variant="solid">
14
+ * <Toolbar.Item render={…} />
15
+ * <Toolbar.Item render={…} />
16
+ * <Toolbar.Item render={…} />
17
+ * </Toolbar.Group>
18
+ * ```
19
+ */
20
+ declare const ToolbarGroup: import("react").ForwardRefExoticComponent<ToolbarProps & import("react").RefAttributes<HTMLElement | HTMLDivElement>>;
21
+ interface ToolbarItemProps extends Omit<BaseProps<"button">, "render">, Required<Pick<BaseProps, "render">> {
22
+ }
23
+ /**
24
+ * An item within the toolbar.
25
+ * Should be used with the `render` prop.
26
+ *
27
+ * Example:
28
+ * ```jsx
29
+ * <Toolbar.Item
30
+ * render={<IconButton variant="ghost" … />}
31
+ * />
32
+ * ```
33
+ */
34
+ declare const ToolbarItem: import("react").ForwardRefExoticComponent<ToolbarItemProps & import("react").RefAttributes<HTMLElement | HTMLButtonElement>>;
35
+ export { ToolbarGroup as Group, ToolbarItem as Item };
@@ -0,0 +1,23 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import cx from "classnames";
3
+ import * as Toolbar from "@ariakit/react/toolbar";
4
+ import { forwardRef } from "./~utils.js";
5
+ const ToolbarGroup = forwardRef((props, forwardedRef) => {
6
+ return /* @__PURE__ */ jsx(
7
+ Toolbar.Toolbar,
8
+ {
9
+ ...props,
10
+ className: cx("\u{1F95D}-toolbar", props.className),
11
+ ref: forwardedRef
12
+ }
13
+ );
14
+ });
15
+ const ToolbarItem = forwardRef(
16
+ (props, forwardedRef) => {
17
+ return /* @__PURE__ */ jsx(Toolbar.ToolbarItem, { ...props, ref: forwardedRef });
18
+ }
19
+ );
20
+ export {
21
+ ToolbarGroup as Group,
22
+ ToolbarItem as Item
23
+ };
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import { IconButton } from "./IconButton.js";
3
2
  import { type BaseProps } from "./~utils.js";
4
3
  interface TreeItemRootProps extends Omit<BaseProps, "content" | "children"> {
5
4
  /** Specifies the nesting level of the tree item. Nesting levels start at 1. */
@@ -62,23 +61,46 @@ interface TreeItemRootProps extends Omit<BaseProps, "content" | "children"> {
62
61
  /** Secondary line of text to display additional information about the tree item. */
63
62
  description?: React.ReactNode;
64
63
  /**
65
- * The actions available for the tree item. Must be a list of `Tree.ItemAction` components.
64
+ * The secondary actions available for the tree item. Must be a list of `Tree.ItemAction` components.
66
65
  *
67
66
  * Example:
68
67
  * ```tsx
69
68
  * actions={[
69
+ * error && <Tree.ItemAction key={…} icon={…} label={…} />,
70
70
  * <Tree.ItemAction key={…} icon={…} label={…} />,
71
71
  * <Tree.ItemAction key={…} icon={…} label={…} />,
72
72
  * ]}
73
73
  * ```
74
+ *
75
+ * Excess actions will automatically get collapsed into an overflow menu.
76
+ * - Normally, the third action and onwards will overflow.
77
+ * - When the `error` prop is set, the _second_ action and onwards will overflow.
78
+ *
79
+ * The actions are normally hidden until the treeitem is hovered or focused.
80
+ * When the `error` prop is set, the actions will be made visible by default. The first
81
+ * action slot can be used to display an error-related action.
82
+ *
83
+ * ```tsx
84
+ * actions={[
85
+ * error && <Tree.ItemAction key={…} icon={…} label={…} />,
86
+ * <Tree.ItemAction key={…} icon={…} label={…} />,
87
+ * <Tree.ItemAction key={…} icon={…} label={…} />,
88
+ * ]}
89
+ * ```
90
+ *
91
+ * @experimental
74
92
  */
75
93
  actions?: React.ReactNode[];
76
94
  /**
77
95
  * Specifies if the tree item is in an error state.
96
+ * The id for an associated error message (e.g. `<ErrorRegion.Item>`) can be passed as a string.
97
+ *
98
+ * Can be combined with the `actions` prop to display an error-related action (e.g. "Retry").
99
+ * The first action will be made visible by default.
78
100
  *
79
101
  * @default false
80
102
  */
81
- error?: boolean;
103
+ error?: boolean | string;
82
104
  }
83
105
  /**
84
106
  * A treeitem is a node in a tree structure that may be expanded or collapsed to reveal or hide its descendants.
@@ -107,23 +129,55 @@ interface TreeItemRootProps extends Omit<BaseProps, "content" | "children"> {
107
129
  * Secondary actions can be passed into the `actions` prop.
108
130
  */
109
131
  declare const TreeItemRoot: React.ForwardRefExoticComponent<TreeItemRootProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
110
- type IconButtonProps = React.ComponentProps<typeof IconButton>;
111
- interface TreeItemActionProps extends BaseProps<"button">, Pick<IconButtonProps, "label" | "icon"> {
132
+ interface TreeItemActionProps extends Omit<BaseProps<"button">, "children"> {
133
+ /**
134
+ * Label for the action.
135
+ *
136
+ * Will be displayed as a tooltip when the action is an icon-button,
137
+ * otherwise will be displayed as a label inside the menu-item.
138
+ */
139
+ label: string;
140
+ /**
141
+ * Icon for the action.
142
+ *
143
+ * Can be a URL of an SVG from the `@itwin/itwinui-icons` package, or a JSX element.
144
+ *
145
+ * Required when the action is displayed as an icon-button (i.e. not overflowing).
146
+ */
147
+ icon?: string | React.JSX.Element;
112
148
  /**
113
- * Controls the visibility of the action.
149
+ * Controls the visibility of the action (only when the action is displayed as icon-button).
114
150
  *
115
151
  * If `true`, the action is always visible.
116
152
  * If `false`, the action is hidden and becomes inaccessible, but still occupies space.
117
153
  *
118
- * By default, the action is shown only when the treeitem receives hover/focus.
154
+ * By default, the action is shown only when the treeitem receives hover/focus. When the
155
+ * treeitem has an `error`, the action will become always visible (i.e. it will default
156
+ * to `true` when `error` is set).
119
157
  */
120
158
  visible?: boolean;
159
+ /**
160
+ * A small dot displayed in the corner of the action.
161
+ *
162
+ * The value of this prop gets used as the button's "accessible description".
163
+ *
164
+ * Example:
165
+ * ```tsx
166
+ * <Tree.ItemAction
167
+ * label="Filter"
168
+ * dot="Some filters applied"
169
+ * icon={…}
170
+ * />
171
+ * ```
172
+ */
173
+ dot?: string;
121
174
  }
122
175
  /**
123
176
  * A secondary action for `<Tree.Item>`, to be passed into the `actions` prop. The action is typically
124
- * displayed as an icon-button on the right end of the treeitem.
177
+ * displayed as an icon-button or a menu-item (e.g. when overflowing).
125
178
  *
126
- * By default, the action appears only on hover/focus. This can be controlled by the `visible` prop.
179
+ * By default, the action appears only when the treeitem has hover/focus or an error. This behavior can
180
+ * be overridden using the `visible` prop.
127
181
  */
128
182
  declare const TreeItemAction: React.ForwardRefExoticComponent<TreeItemActionProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
129
183
  export { TreeItemRoot as Root, TreeItemAction as Action };
@@ -2,15 +2,17 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import cx from "classnames";
4
4
  import { Role } from "@ariakit/react/role";
5
+ import { PopoverProvider } from "@ariakit/react/popover";
5
6
  import {
6
7
  CompositeItem
7
8
  } from "@ariakit/react/composite";
8
- import { Toolbar } from "@ariakit/react/toolbar";
9
+ import { Toolbar, ToolbarItem } from "@ariakit/react/toolbar";
9
10
  import * as ListItem from "./~utils.ListItem.js";
10
11
  import { IconButton } from "./IconButton.js";
11
- import { Icon, StatusWarning } from "./Icon.js";
12
+ import * as DropdownMenu from "./DropdownMenu.js";
13
+ import { ChevronDown, Icon, StatusWarning, MoreHorizontal } from "./Icon.js";
12
14
  import { forwardRef } from "./~utils.js";
13
- import { useEventHandlers } from "./~hooks.js";
15
+ import { useEventHandlers, useSafeContext } from "./~hooks.js";
14
16
  import { GhostAligner, useGhostAlignment } from "./~utils.GhostAligner.js";
15
17
  const TreeItemContext = React.createContext(void 0);
16
18
  const TreeItemRoot = forwardRef(
@@ -49,13 +51,22 @@ const TreeItemRoot = forwardRef(
49
51
  const labelId = React.useId();
50
52
  const descriptionId = React.useId();
51
53
  const decorationId = React.useId();
54
+ const errorId = typeof error === "string" ? error : void 0;
52
55
  const icon = error ? /* @__PURE__ */ jsx(StatusWarning, {}) : iconProp;
53
56
  const describedBy = React.useMemo(() => {
54
57
  const idRefs = [];
55
58
  if (description) idRefs.push(descriptionId);
56
59
  if (unstable_decorations || icon) idRefs.push(decorationId);
60
+ if (errorId) idRefs.push(errorId);
57
61
  return idRefs.length > 0 ? idRefs.join(" ") : void 0;
58
- }, [unstable_decorations, icon, decorationId, description, descriptionId]);
62
+ }, [
63
+ unstable_decorations,
64
+ icon,
65
+ decorationId,
66
+ description,
67
+ descriptionId,
68
+ errorId
69
+ ]);
59
70
  return /* @__PURE__ */ jsx(
60
71
  TreeItemContext.Provider,
61
72
  {
@@ -63,9 +74,10 @@ const TreeItemRoot = forwardRef(
63
74
  () => ({
64
75
  level,
65
76
  expanded,
66
- selected
77
+ selected,
78
+ error
67
79
  }),
68
- [level, expanded, selected]
80
+ [level, expanded, selected, error]
69
81
  ),
70
82
  children: /* @__PURE__ */ jsx(
71
83
  CompositeItem,
@@ -142,30 +154,103 @@ const TreeItemRoot = forwardRef(
142
154
  }
143
155
  );
144
156
  const TreeItemActions = forwardRef((props, forwardedRef) => {
145
- return /* @__PURE__ */ jsx(
157
+ const { children, ...rest } = props;
158
+ const actions = React.Children.toArray(children).filter(Boolean);
159
+ const { error } = useSafeContext(TreeItemContext);
160
+ const limit = error ? 2 : 3;
161
+ return /* @__PURE__ */ jsxs(
146
162
  Toolbar,
147
163
  {
148
- ...props,
164
+ ...rest,
149
165
  onClick: useEventHandlers(props.onClick, (e) => e.stopPropagation()),
150
166
  onKeyDown: useEventHandlers(props.onKeyDown, (e) => e.stopPropagation()),
151
167
  className: cx("\u{1F95D}-tree-item-actions-container", props.className),
168
+ focusLoop: false,
152
169
  ref: forwardedRef,
153
- children: props.children
170
+ children: [
171
+ actions.slice(0, limit - 1),
172
+ actions.length === limit ? actions[limit - 1] : null,
173
+ actions.length > limit ? /* @__PURE__ */ jsx(TreeItemActionsOverflowMenu, { children: actions.slice(limit - 1) }) : null
174
+ ]
154
175
  }
155
176
  );
156
177
  });
178
+ const arrowKeys = ["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight"];
179
+ const TreeItemActionsOverflowMenuContext = React.createContext(false);
180
+ function TreeItemActionsOverflowMenu({ children }) {
181
+ const [open, setOpen] = React.useState(false);
182
+ const isArrowKeyPressed = React.useRef(false);
183
+ return /* @__PURE__ */ jsx(PopoverProvider, { placement: "right-start", children: /* @__PURE__ */ jsxs(
184
+ DropdownMenu.Root,
185
+ {
186
+ open,
187
+ setOpen: React.useCallback((value) => {
188
+ if (value && !isArrowKeyPressed.current) {
189
+ setOpen(true);
190
+ } else {
191
+ setOpen(false);
192
+ }
193
+ }, []),
194
+ children: [
195
+ /* @__PURE__ */ jsx(
196
+ DropdownMenu.Button,
197
+ {
198
+ onKeyDown: (e) => {
199
+ if (arrowKeys.includes(e.key)) {
200
+ isArrowKeyPressed.current = true;
201
+ }
202
+ queueMicrotask(() => {
203
+ isArrowKeyPressed.current = false;
204
+ });
205
+ },
206
+ render: /* @__PURE__ */ jsx(TreeItemAction, { label: "More", icon: /* @__PURE__ */ jsx(MoreHorizontal, {}) })
207
+ }
208
+ ),
209
+ /* @__PURE__ */ jsx(TreeItemActionsOverflowMenuContext.Provider, { value: true, children: /* @__PURE__ */ jsx(DropdownMenu.Content, { children }) })
210
+ ]
211
+ }
212
+ ) });
213
+ }
157
214
  const TreeItemAction = forwardRef(
158
215
  (props, forwardedRef) => {
159
- const { visible, ...rest } = props;
216
+ const { error } = useSafeContext(TreeItemContext);
217
+ const {
218
+ visible = error ? true : void 0,
219
+ // visible by default during error state
220
+ label,
221
+ icon,
222
+ dot,
223
+ ...rest
224
+ } = props;
225
+ if (React.useContext(TreeItemActionsOverflowMenuContext)) {
226
+ return /* @__PURE__ */ jsx(
227
+ DropdownMenu.Item,
228
+ {
229
+ ...rest,
230
+ label,
231
+ icon,
232
+ unstable_dot: dot,
233
+ ref: forwardedRef
234
+ }
235
+ );
236
+ }
160
237
  return /* @__PURE__ */ jsx(
161
- IconButton,
238
+ ToolbarItem,
162
239
  {
163
- inert: visible === false ? true : void 0,
164
- ...rest,
165
- variant: "ghost",
166
- className: cx("\u{1F95D}-tree-item-action", props.className),
167
- "data-kiwi-visible": visible,
168
- ref: forwardedRef
240
+ render: /* @__PURE__ */ jsx(
241
+ IconButton,
242
+ {
243
+ label,
244
+ icon,
245
+ inert: visible === false ? true : void 0,
246
+ ...rest,
247
+ dot,
248
+ variant: "ghost",
249
+ className: cx("\u{1F95D}-tree-item-action", props.className),
250
+ "data-kiwi-visible": visible,
251
+ ref: forwardedRef
252
+ }
253
+ )
169
254
  }
170
255
  );
171
256
  }
@@ -188,30 +273,7 @@ const TreeItemExpander = forwardRef(
188
273
  "data-kiwi-variant": "ghost",
189
274
  "data-kiwi-ghost-align": useGhostAlignment(),
190
275
  ref: forwardedRef,
191
- children: /* @__PURE__ */ jsx(TreeChevron, {})
192
- }
193
- );
194
- }
195
- );
196
- const TreeChevron = forwardRef(
197
- (props, forwardedRef) => {
198
- return /* @__PURE__ */ jsx(
199
- Icon,
200
- {
201
- ...props,
202
- render: /* @__PURE__ */ jsx(
203
- Role.svg,
204
- {
205
- width: "16",
206
- height: "16",
207
- fill: "currentColor",
208
- viewBox: "0 0 16 16",
209
- render: props.render,
210
- 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" })
211
- }
212
- ),
213
- className: cx("\u{1F95D}-tree-chevron", props.className),
214
- ref: forwardedRef
276
+ children: /* @__PURE__ */ jsx(ChevronDown, {})
215
277
  }
216
278
  );
217
279
  }
@@ -7,10 +7,11 @@ export { Checkbox } from "./Checkbox.js";
7
7
  export { Chip } from "./Chip.js";
8
8
  export { Description } from "./Description.js";
9
9
  export * as DropdownMenu from "./DropdownMenu.js";
10
+ export * as unstable_ErrorRegion from "./ErrorRegion.js";
10
11
  export { Divider } from "./Divider.js";
11
12
  export { Icon } from "./Icon.js";
12
13
  export { IconButton } from "./IconButton.js";
13
- export { Field } from "./Field.js";
14
+ export * as Field from "./Field.js";
14
15
  export { Kbd } from "./Kbd.js";
15
16
  export { Label } from "./Label.js";
16
17
  export { ProgressBar } from "./ProgressBar.js";
@@ -19,9 +20,11 @@ export * as Select from "./Select.js";
19
20
  export { Spinner } from "./Spinner.js";
20
21
  export { Skeleton } from "./Skeleton.js";
21
22
  export { Switch } from "./Switch.js";
23
+ export * as Table from "./Table.js";
22
24
  export * as Tabs from "./Tabs.js";
23
25
  export { Text } from "./Text.js";
24
26
  export * as TextBox from "./TextBox.js";
25
- export * as Tree from "./Tree.js";
27
+ export * as unstable_Toolbar from "./Toolbar.js";
26
28
  export { Tooltip } from "./Tooltip.js";
29
+ export * as Tree from "./Tree.js";
27
30
  export { VisuallyHidden } from "./VisuallyHidden.js";
@@ -8,10 +8,11 @@ import { Checkbox } from "./Checkbox.js";
8
8
  import { Chip } from "./Chip.js";
9
9
  import { Description } from "./Description.js";
10
10
  import * as DropdownMenu from "./DropdownMenu.js";
11
+ import * as unstable_ErrorRegion from "./ErrorRegion.js";
11
12
  import { Divider } from "./Divider.js";
12
13
  import { Icon } from "./Icon.js";
13
14
  import { IconButton } from "./IconButton.js";
14
- import { Field } from "./Field.js";
15
+ import * as Field from "./Field.js";
15
16
  import { Kbd } from "./Kbd.js";
16
17
  import { Label } from "./Label.js";
17
18
  import { ProgressBar } from "./ProgressBar.js";
@@ -20,11 +21,13 @@ import * as Select from "./Select.js";
20
21
  import { Spinner } from "./Spinner.js";
21
22
  import { Skeleton } from "./Skeleton.js";
22
23
  import { Switch } from "./Switch.js";
24
+ import * as Table from "./Table.js";
23
25
  import * as Tabs from "./Tabs.js";
24
26
  import { Text } from "./Text.js";
25
27
  import * as TextBox from "./TextBox.js";
26
- import * as Tree from "./Tree.js";
28
+ import * as unstable_Toolbar from "./Toolbar.js";
27
29
  import { Tooltip } from "./Tooltip.js";
30
+ import * as Tree from "./Tree.js";
28
31
  import { VisuallyHidden } from "./VisuallyHidden.js";
29
32
  export {
30
33
  Anchor,
@@ -48,10 +51,13 @@ export {
48
51
  Skeleton,
49
52
  Spinner,
50
53
  Switch,
54
+ Table,
51
55
  Tabs,
52
56
  Text,
53
57
  TextBox,
54
58
  Tooltip,
55
59
  Tree,
56
- VisuallyHidden
60
+ VisuallyHidden,
61
+ unstable_ErrorRegion,
62
+ unstable_Toolbar
57
63
  };