@itwin/itwinui-react 5.0.0-alpha.12 → 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.
@@ -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
+ };
@@ -50,6 +50,12 @@ interface FieldCollectionItemControlProps extends Pick<CollectionItemProps, "ren
50
50
  /**
51
51
  * The control component for the field.
52
52
  *
53
+ * Use the `render` prop to render the control component.
54
+ *
55
+ * ```tsx
56
+ * <Field.Control render={<TextBox.Input />} />
57
+ * ```
58
+ *
53
59
  * If the rendered component uses a compositional API, then use a function
54
60
  * within `render` to apply the `controlProps` to the correct sub-component:
55
61
  *
@@ -34,11 +34,12 @@ const FieldRoot = forwardRef((props, forwardedRef) => {
34
34
  const FieldLabel = forwardRef(
35
35
  (props, forwardedRef) => {
36
36
  const store = useCollectionContext();
37
- const renderedItems = useStoreState(store, "renderedItems");
37
+ const renderedItems = useStoreState(
38
+ store,
39
+ "renderedItems"
40
+ );
38
41
  const fieldId = React.useMemo(
39
- () => renderedItems?.find(
40
- (item) => item.elementType === "control"
41
- )?.id,
42
+ () => renderedItems?.find((item) => item.elementType === "control")?.id,
42
43
  [renderedItems]
43
44
  );
44
45
  const getData = React.useCallback(
@@ -84,7 +85,10 @@ const FieldControl = forwardRef(
84
85
  const store = useCollectionContext();
85
86
  const generatedId = React.useId();
86
87
  const { id = store ? generatedId : void 0, ...rest } = props;
87
- const renderedItems = useStoreState(store, "renderedItems");
88
+ const renderedItems = useStoreState(
89
+ store,
90
+ "renderedItems"
91
+ );
88
92
  const describedBy = React.useMemo(() => {
89
93
  const idRefList = renderedItems?.filter(
90
94
  (item) => item.elementType === "description" || item.elementType === "error"
@@ -74,4 +74,7 @@ export declare const StatusWarning: React.ForwardRefExoticComponent<StatusWarnin
74
74
  interface MoreHorizontalProps extends Omit<BaseProps<"svg">, "children"> {
75
75
  }
76
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>>;
77
80
  export {};
@@ -245,8 +245,32 @@ const MoreHorizontal = forwardRef(
245
245
  );
246
246
  }
247
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
+ );
248
271
  export {
249
272
  Checkmark,
273
+ ChevronDown,
250
274
  DisclosureArrow,
251
275
  Dismiss,
252
276
  Icon,
@@ -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
  );
@@ -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"
@@ -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
+ };
@@ -93,13 +93,14 @@ interface TreeItemRootProps extends Omit<BaseProps, "content" | "children"> {
93
93
  actions?: React.ReactNode[];
94
94
  /**
95
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.
96
97
  *
97
- * Can be combined with the `actions` prop to display an error-related action. The first
98
- * action will be made visible by default.
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.
99
100
  *
100
101
  * @default false
101
102
  */
102
- error?: boolean;
103
+ error?: boolean | string;
103
104
  }
104
105
  /**
105
106
  * A treeitem is a node in a tree structure that may be expanded or collapsed to reveal or hide its descendants.
@@ -155,6 +156,21 @@ interface TreeItemActionProps extends Omit<BaseProps<"button">, "children"> {
155
156
  * to `true` when `error` is set).
156
157
  */
157
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;
158
174
  }
159
175
  /**
160
176
  * A secondary action for `<Tree.Item>`, to be passed into the `actions` prop. The action is typically
@@ -6,11 +6,11 @@ import { PopoverProvider } from "@ariakit/react/popover";
6
6
  import {
7
7
  CompositeItem
8
8
  } from "@ariakit/react/composite";
9
- import { Toolbar } from "@ariakit/react/toolbar";
9
+ import { Toolbar, ToolbarItem } from "@ariakit/react/toolbar";
10
10
  import * as ListItem from "./~utils.ListItem.js";
11
11
  import { IconButton } from "./IconButton.js";
12
12
  import * as DropdownMenu from "./DropdownMenu.js";
13
- import { Icon, StatusWarning, MoreHorizontal } from "./Icon.js";
13
+ import { ChevronDown, Icon, StatusWarning, MoreHorizontal } from "./Icon.js";
14
14
  import { forwardRef } from "./~utils.js";
15
15
  import { useEventHandlers, useSafeContext } from "./~hooks.js";
16
16
  import { GhostAligner, useGhostAlignment } from "./~utils.GhostAligner.js";
@@ -51,13 +51,22 @@ const TreeItemRoot = forwardRef(
51
51
  const labelId = React.useId();
52
52
  const descriptionId = React.useId();
53
53
  const decorationId = React.useId();
54
+ const errorId = typeof error === "string" ? error : void 0;
54
55
  const icon = error ? /* @__PURE__ */ jsx(StatusWarning, {}) : iconProp;
55
56
  const describedBy = React.useMemo(() => {
56
57
  const idRefs = [];
57
58
  if (description) idRefs.push(descriptionId);
58
59
  if (unstable_decorations || icon) idRefs.push(decorationId);
60
+ if (errorId) idRefs.push(errorId);
59
61
  return idRefs.length > 0 ? idRefs.join(" ") : void 0;
60
- }, [unstable_decorations, icon, decorationId, description, descriptionId]);
62
+ }, [
63
+ unstable_decorations,
64
+ icon,
65
+ decorationId,
66
+ description,
67
+ descriptionId,
68
+ errorId
69
+ ]);
61
70
  return /* @__PURE__ */ jsx(
62
71
  TreeItemContext.Provider,
63
72
  {
@@ -210,6 +219,7 @@ const TreeItemAction = forwardRef(
210
219
  // visible by default during error state
211
220
  label,
212
221
  icon,
222
+ dot,
213
223
  ...rest
214
224
  } = props;
215
225
  if (React.useContext(TreeItemActionsOverflowMenuContext)) {
@@ -219,21 +229,28 @@ const TreeItemAction = forwardRef(
219
229
  ...rest,
220
230
  label,
221
231
  icon,
232
+ unstable_dot: dot,
222
233
  ref: forwardedRef
223
234
  }
224
235
  );
225
236
  }
226
237
  return /* @__PURE__ */ jsx(
227
- IconButton,
238
+ ToolbarItem,
228
239
  {
229
- label,
230
- icon,
231
- inert: visible === false ? true : void 0,
232
- ...rest,
233
- variant: "ghost",
234
- className: cx("\u{1F95D}-tree-item-action", props.className),
235
- "data-kiwi-visible": visible,
236
- 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
+ )
237
254
  }
238
255
  );
239
256
  }
@@ -256,30 +273,7 @@ const TreeItemExpander = forwardRef(
256
273
  "data-kiwi-variant": "ghost",
257
274
  "data-kiwi-ghost-align": useGhostAlignment(),
258
275
  ref: forwardedRef,
259
- children: /* @__PURE__ */ jsx(TreeChevron, {})
260
- }
261
- );
262
- }
263
- );
264
- const TreeChevron = forwardRef(
265
- (props, forwardedRef) => {
266
- return /* @__PURE__ */ jsx(
267
- Icon,
268
- {
269
- ...props,
270
- render: /* @__PURE__ */ jsx(
271
- Role.svg,
272
- {
273
- width: "16",
274
- height: "16",
275
- fill: "currentColor",
276
- viewBox: "0 0 16 16",
277
- render: props.render,
278
- 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" })
279
- }
280
- ),
281
- className: cx("\u{1F95D}-tree-chevron", props.className),
282
- ref: forwardedRef
276
+ children: /* @__PURE__ */ jsx(ChevronDown, {})
283
277
  }
284
278
  );
285
279
  }
@@ -7,6 +7,7 @@ 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";
@@ -23,6 +24,7 @@ export * as Table from "./Table.js";
23
24
  export * as Tabs from "./Tabs.js";
24
25
  export { Text } from "./Text.js";
25
26
  export * as TextBox from "./TextBox.js";
26
- export * as Tree from "./Tree.js";
27
+ export * as unstable_Toolbar from "./Toolbar.js";
27
28
  export { Tooltip } from "./Tooltip.js";
29
+ export * as Tree from "./Tree.js";
28
30
  export { VisuallyHidden } from "./VisuallyHidden.js";
@@ -8,6 +8,7 @@ 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";
@@ -24,8 +25,9 @@ import * as Table from "./Table.js";
24
25
  import * as Tabs from "./Tabs.js";
25
26
  import { Text } from "./Text.js";
26
27
  import * as TextBox from "./TextBox.js";
27
- import * as Tree from "./Tree.js";
28
+ import * as unstable_Toolbar from "./Toolbar.js";
28
29
  import { Tooltip } from "./Tooltip.js";
30
+ import * as Tree from "./Tree.js";
29
31
  import { VisuallyHidden } from "./VisuallyHidden.js";
30
32
  export {
31
33
  Anchor,
@@ -55,5 +57,7 @@ export {
55
57
  TextBox,
56
58
  Tooltip,
57
59
  Tree,
58
- VisuallyHidden
60
+ VisuallyHidden,
61
+ unstable_ErrorRegion,
62
+ unstable_Toolbar
59
63
  };