@itwin/itwinui-react 5.0.0-alpha.3 → 5.0.0-alpha.5

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.0.0-alpha.5
4
+
5
+ - **breaking**: `Tree` API has changed to require flat structure, with explicit ARIA props (see [#300](https://github.com/iTwin/kiwi/pull/300)). `<Tree.Item>` no longer allows passing `children`.
6
+ - **breaking**: `Tree.Item`s `action` prop now requires a list of `<Tree.ItemAction>` components (see [#355](https://github.com/iTwin/kiwi/pull/355) and [#362](https://github.com/iTwin/kiwi/pull/362)).
7
+ - **breaking**: Replaced `<Chip>` children with new `label` prop (see [#349](https://github.com/iTwin/kiwi/pull/349)).
8
+ - Added `<Tree.ItemAction>` component with `visible` prop for more granular control over action visibility.
9
+ - Updated the layout of `<Field>` so that `<Description>` is placed in the best spot according on the label position and control type.
10
+ - `<Field>` now considers the presence of explicit control `id`s when creating associations.
11
+
12
+ ## 5.0.0-alpha.4
13
+
14
+ - Added `onDismiss` prop and dismiss button to `<Chip>`.
15
+ - Fixed a rare issue where `TextBox` was still editable when `disabled`.
16
+ - Fixed "forced colors" mode styling for `<Button>` and `<IconButton>`.
17
+ - Explicitly set typography styles on `<Root>` to improve compatibility with iTwinUI theme bridge.
18
+ - Updated `DropdownMenu` visuals.
19
+
3
20
  ## 5.0.0-alpha.3
4
21
 
5
22
  - Added `<DropdownMenu.CheckboxItem>` component for rendering menu items with a checkable state.
@@ -1,21 +1,27 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
3
  import * as Ariakit from "@ariakit/react";
4
- import { useFieldDescribedBy, useFieldId } from "./Field.js";
4
+ import { FieldControl, useFieldDescribedBy } from "./Field.js";
5
5
  import { forwardRef } from "./~utils.js";
6
6
  const Checkbox = forwardRef(
7
7
  (props, forwardedRef) => {
8
- const fieldId = useFieldId();
8
+ const { id, ...rest } = props;
9
9
  const describedBy = useFieldDescribedBy(props["aria-describedby"]);
10
10
  return /* @__PURE__ */ jsx(
11
- Ariakit.Checkbox,
11
+ FieldControl,
12
12
  {
13
- accessibleWhenDisabled: true,
14
- id: fieldId,
15
- ...props,
16
- className: cx("\u{1F95D}-checkbox", props.className),
17
- "aria-describedby": describedBy,
18
- ref: forwardedRef
13
+ type: "checkable",
14
+ id,
15
+ render: /* @__PURE__ */ jsx(
16
+ Ariakit.Checkbox,
17
+ {
18
+ accessibleWhenDisabled: true,
19
+ ...rest,
20
+ className: cx("\u{1F95D}-checkbox", props.className),
21
+ "aria-describedby": describedBy,
22
+ ref: forwardedRef
23
+ }
24
+ )
19
25
  }
20
26
  );
21
27
  }
@@ -1,17 +1,38 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
+ import * as React from "react";
3
4
  import * as Ariakit from "@ariakit/react";
4
5
  import { forwardRef } from "./~utils.js";
6
+ import { IconButton } from "./IconButton.js";
7
+ import { Dismiss } from "./Icon.js";
5
8
  const Chip = forwardRef((props, forwardedRef) => {
6
- const { variant = "solid", children, ...rest } = props;
7
- return /* @__PURE__ */ jsx(
9
+ const { variant = "solid", onDismiss, label, ...rest } = props;
10
+ const baseId = React.useId();
11
+ const labelId = `${baseId}-label`;
12
+ const dismissIconId = `${baseId}-dismiss`;
13
+ return /* @__PURE__ */ jsxs(
8
14
  Ariakit.Role.div,
9
15
  {
10
16
  "data-kiwi-variant": variant,
11
17
  ...rest,
12
18
  className: cx("\u{1F95D}-chip", props.className),
13
19
  ref: forwardedRef,
14
- children
20
+ children: [
21
+ /* @__PURE__ */ jsx("span", { id: labelId, children: label }),
22
+ onDismiss && /* @__PURE__ */ jsx(
23
+ IconButton,
24
+ {
25
+ id: dismissIconId,
26
+ className: "\u{1F95D}-chip-dismiss-button",
27
+ variant: "ghost",
28
+ "aria-labelledby": `${dismissIconId} ${labelId}`,
29
+ label: "Dismiss",
30
+ labelVariant: "visually-hidden",
31
+ icon: /* @__PURE__ */ jsx(Dismiss, {}),
32
+ onClick: onDismiss
33
+ }
34
+ )
35
+ ]
15
36
  }
16
37
  );
17
38
  });
@@ -47,6 +47,7 @@ const DropdownMenuContent = forwardRef(
47
47
  portal: !supportsPopover,
48
48
  unmountOnHide: true,
49
49
  ...props,
50
+ gutter: 4,
50
51
  style: { zIndex: supportsPopover ? void 0 : 9999, ...props.style },
51
52
  wrapperProps: { popover: "manual" },
52
53
  className: cx("\u{1F95D}-dropdown-menu", props.className),
@@ -88,6 +89,7 @@ const DropdownMenuItem = forwardRef(
88
89
  accessibleWhenDisabled: true,
89
90
  ...rest,
90
91
  render: /* @__PURE__ */ jsx(ListItem.Root, { render: props.render }),
92
+ className: cx("\u{1F95D}-dropdown-menu-item", props.className),
91
93
  ref: forwardedRef,
92
94
  children: [
93
95
  /* @__PURE__ */ jsx(ListItem.Content, { children: props.children }),
@@ -106,7 +108,7 @@ const DropdownMenuCheckboxItem = forwardRef((props, forwardedRef) => {
106
108
  value: props.defaultChecked ? "on" : void 0,
107
109
  ...props,
108
110
  render: /* @__PURE__ */ jsx(ListItem.Root, { render: props.render }),
109
- className: cx("\u{1F95D}-dropdown-menu-checkbox-item", props.className),
111
+ className: cx("\u{1F95D}-dropdown-menu-item", props.className),
110
112
  ref: forwardedRef,
111
113
  children: [
112
114
  /* @__PURE__ */ jsx(ListItem.Content, { children: props.children }),
@@ -4,17 +4,21 @@ import * as Ariakit from "@ariakit/react";
4
4
  import cx from "classnames";
5
5
  import { forwardRef } from "./~utils.js";
6
6
  const Field = forwardRef((props, forwardedRef) => {
7
- const fieldId = React.useId();
8
7
  const { layout, ...rest } = props;
9
- return /* @__PURE__ */ jsx(FieldIdContext.Provider, { value: fieldId, children: /* @__PURE__ */ jsx(FieldDescribedByProvider, { children: /* @__PURE__ */ jsx(
10
- Ariakit.Role,
8
+ return /* @__PURE__ */ jsx(FieldDescribedByProvider, { children: /* @__PURE__ */ jsx(
9
+ FieldCollection,
11
10
  {
12
- ...rest,
13
- className: cx("\u{1F95D}-field", props.className),
14
- "data-kiwi-layout": layout,
15
- ref: forwardedRef
11
+ render: /* @__PURE__ */ jsx(
12
+ Ariakit.Role.div,
13
+ {
14
+ ...rest,
15
+ className: cx("\u{1F95D}-field", props.className),
16
+ "data-kiwi-layout": layout,
17
+ ref: forwardedRef
18
+ }
19
+ )
16
20
  }
17
- ) }) });
21
+ ) });
18
22
  });
19
23
  DEV: Field.displayName = "Field";
20
24
  const FieldDescribedByContext = React.createContext(void 0);
@@ -66,13 +70,78 @@ function useFieldRegisterDescribedBy(id) {
66
70
  return () => unregister(id);
67
71
  }, [id, register, unregister]);
68
72
  }
69
- const FieldIdContext = React.createContext(void 0);
70
- function useFieldId() {
71
- return React.useContext(FieldIdContext);
73
+ function FieldCollection(props) {
74
+ const fieldElementCollection = Ariakit.useCollectionStore({
75
+ defaultItems: []
76
+ });
77
+ const renderedItems = Ariakit.useStoreState(
78
+ fieldElementCollection,
79
+ "renderedItems"
80
+ );
81
+ const [controlType, controlIndex] = React.useMemo(() => {
82
+ const controlIndex2 = renderedItems.findIndex(
83
+ (item) => item.elementType === "control"
84
+ );
85
+ return [renderedItems[controlIndex2]?.controlType, controlIndex2];
86
+ }, [renderedItems]);
87
+ const labelPlacement = React.useMemo(() => {
88
+ const labelIndex = renderedItems.findIndex(
89
+ (item) => item.elementType === "label"
90
+ );
91
+ if (controlIndex === -1 || labelIndex === -1) return;
92
+ return labelIndex < controlIndex ? "before" : "after";
93
+ }, [renderedItems, controlIndex]);
94
+ return /* @__PURE__ */ jsx(
95
+ Ariakit.Collection,
96
+ {
97
+ ...props,
98
+ store: fieldElementCollection,
99
+ "data-kiwi-label-placement": labelPlacement,
100
+ "data-kiwi-control-type": controlType
101
+ }
102
+ );
103
+ }
104
+ function FieldControl(props) {
105
+ const generatedId = React.useId();
106
+ const { id = generatedId, type, ...rest } = props;
107
+ const getData = React.useCallback(
108
+ (data) => ({
109
+ ...data,
110
+ elementType: "control",
111
+ controlType: type
112
+ }),
113
+ [type]
114
+ );
115
+ return /* @__PURE__ */ jsx(Ariakit.CollectionItem, { ...rest, id, getItem: getData });
116
+ }
117
+ function FieldLabel(props) {
118
+ const store = Ariakit.useCollectionContext();
119
+ const renderedItems = Ariakit.useStoreState(store, "renderedItems");
120
+ const fieldId = React.useMemo(
121
+ () => renderedItems?.find(
122
+ (item) => item.elementType === "control"
123
+ )?.id,
124
+ [renderedItems]
125
+ );
126
+ const getData = React.useCallback(
127
+ (data) => ({
128
+ ...data,
129
+ elementType: "label"
130
+ }),
131
+ []
132
+ );
133
+ return /* @__PURE__ */ jsx(
134
+ Ariakit.CollectionItem,
135
+ {
136
+ getItem: getData,
137
+ render: /* @__PURE__ */ jsx(Ariakit.Role.label, { ...props, htmlFor: fieldId })
138
+ }
139
+ );
72
140
  }
73
141
  export {
74
142
  Field,
143
+ FieldControl,
144
+ FieldLabel,
75
145
  useFieldDescribedBy,
76
- useFieldId,
77
146
  useFieldRegisterDescribedBy
78
147
  };
@@ -86,8 +86,32 @@ const Checkmark = forwardRef(
86
86
  }
87
87
  );
88
88
  DEV: Checkmark.displayName = "Checkmark";
89
+ const Dismiss = forwardRef(
90
+ (props, forwardedRef) => {
91
+ return /* @__PURE__ */ jsx(
92
+ Icon,
93
+ {
94
+ ...props,
95
+ render: /* @__PURE__ */ jsx(
96
+ Ariakit.Role.svg,
97
+ {
98
+ width: "16",
99
+ height: "16",
100
+ viewBox: "0 0 16 16",
101
+ fill: "currentColor",
102
+ render: props.render,
103
+ children: /* @__PURE__ */ jsx("path", { d: "M4.853 4.146a.5.5 0 1 0-.707.708L7.293 8l-3.147 3.146a.5.5 0 0 0 .707.708L8 8.707l3.146 3.147a.5.5 0 0 0 .707-.708L8.707 8l3.146-3.146a.5.5 0 1 0-.707-.708L8 7.293 4.853 4.146Z" })
104
+ }
105
+ ),
106
+ ref: forwardedRef
107
+ }
108
+ );
109
+ }
110
+ );
111
+ DEV: Dismiss.displayName = "Dismiss";
89
112
  export {
90
113
  Checkmark,
91
114
  DisclosureArrow,
115
+ Dismiss,
92
116
  Icon
93
117
  };
@@ -1,17 +1,20 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
3
  import * as Ariakit from "@ariakit/react";
4
- import { useFieldId } from "./Field.js";
5
4
  import { forwardRef } from "./~utils.js";
5
+ import { FieldLabel } from "./Field.js";
6
6
  const Label = forwardRef((props, forwardedRef) => {
7
- const fieldId = useFieldId();
8
7
  return /* @__PURE__ */ jsx(
9
- Ariakit.Role.label,
8
+ FieldLabel,
10
9
  {
11
- htmlFor: fieldId,
12
- ...props,
13
- className: cx("\u{1F95D}-label", props.className),
14
- ref: forwardedRef
10
+ render: /* @__PURE__ */ jsx(
11
+ Ariakit.Role.label,
12
+ {
13
+ ...props,
14
+ className: cx("\u{1F95D}-label", props.className),
15
+ ref: forwardedRef
16
+ }
17
+ )
15
18
  }
16
19
  );
17
20
  });
@@ -1,20 +1,26 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
3
  import * as Ariakit from "@ariakit/react";
4
- import { useFieldDescribedBy, useFieldId } from "./Field.js";
4
+ import { FieldControl, useFieldDescribedBy } from "./Field.js";
5
5
  import { forwardRef } from "./~utils.js";
6
6
  const Radio = forwardRef((props, forwardedRef) => {
7
- const fieldId = useFieldId();
7
+ const { id, ...rest } = props;
8
8
  const describedBy = useFieldDescribedBy(props["aria-describedby"]);
9
9
  return /* @__PURE__ */ jsx(
10
- Ariakit.Radio,
10
+ FieldControl,
11
11
  {
12
- accessibleWhenDisabled: true,
13
- id: fieldId,
14
- ...props,
15
- className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
16
- "aria-describedby": describedBy,
17
- ref: forwardedRef
12
+ type: "checkable",
13
+ id,
14
+ render: /* @__PURE__ */ jsx(
15
+ Ariakit.Radio,
16
+ {
17
+ accessibleWhenDisabled: true,
18
+ ...rest,
19
+ className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
20
+ "aria-describedby": describedBy,
21
+ ref: forwardedRef
22
+ }
23
+ )
18
24
  }
19
25
  );
20
26
  });
@@ -7,7 +7,7 @@ import {
7
7
  isBrowser
8
8
  } from "./~utils.js";
9
9
  import { DisclosureArrow } from "./Icon.js";
10
- import { useFieldDescribedBy, useFieldId } from "./Field.js";
10
+ import { FieldControl, useFieldDescribedBy } from "./Field.js";
11
11
  const supportsHas = isBrowser && CSS?.supports?.("selector(:has(+ *))");
12
12
  const HtmlSelectContext = React.createContext(() => {
13
13
  });
@@ -25,9 +25,8 @@ const SelectRoot = forwardRef((props, forwardedRef) => {
25
25
  });
26
26
  const HtmlSelect = forwardRef(
27
27
  (props, forwardedRef) => {
28
- const { variant = "solid", ...rest } = props;
28
+ const { id, variant = "solid", ...rest } = props;
29
29
  const setIsHtmlSelect = React.useContext(HtmlSelectContext);
30
- const fieldId = useFieldId();
31
30
  const describedBy = useFieldDescribedBy(props["aria-describedby"]);
32
31
  React.useEffect(
33
32
  function updateContext() {
@@ -37,15 +36,21 @@ const HtmlSelect = forwardRef(
37
36
  );
38
37
  return /* @__PURE__ */ jsxs(Fragment, { children: [
39
38
  /* @__PURE__ */ jsx(
40
- Ariakit.Role.select,
39
+ FieldControl,
41
40
  {
42
- id: fieldId,
43
- ...rest,
44
- className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
45
- "aria-describedby": describedBy,
46
- "data-kiwi-tone": "neutral",
47
- "data-kiwi-variant": variant,
48
- ref: forwardedRef
41
+ type: "textlike",
42
+ id,
43
+ render: /* @__PURE__ */ jsx(
44
+ Ariakit.Role.select,
45
+ {
46
+ ...rest,
47
+ className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
48
+ "aria-describedby": describedBy,
49
+ "data-kiwi-tone": "neutral",
50
+ "data-kiwi-variant": variant,
51
+ ref: forwardedRef
52
+ }
53
+ )
49
54
  }
50
55
  ),
51
56
  /* @__PURE__ */ jsx(DisclosureArrow, { className: "\u{1F95D}-select-arrow" })
@@ -1,22 +1,28 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
3
  import * as Ariakit from "@ariakit/react";
4
- import { useFieldDescribedBy, useFieldId } from "./Field.js";
4
+ import { FieldControl, useFieldDescribedBy } from "./Field.js";
5
5
  import { forwardRef } from "./~utils.js";
6
6
  const Switch = forwardRef(
7
7
  (props, forwardedRef) => {
8
- const fieldId = useFieldId();
8
+ const { id, ...rest } = props;
9
9
  const describedBy = useFieldDescribedBy(props["aria-describedby"]);
10
10
  return /* @__PURE__ */ jsx(
11
- Ariakit.Checkbox,
11
+ FieldControl,
12
12
  {
13
- accessibleWhenDisabled: true,
14
- id: fieldId,
15
- ...props,
16
- className: cx("\u{1F95D}-switch", props.className),
17
- "aria-describedby": describedBy,
18
- role: "switch",
19
- ref: forwardedRef
13
+ type: "checkable",
14
+ id,
15
+ render: /* @__PURE__ */ jsx(
16
+ Ariakit.Checkbox,
17
+ {
18
+ accessibleWhenDisabled: true,
19
+ ...rest,
20
+ className: cx("\u{1F95D}-switch", props.className),
21
+ "aria-describedby": describedBy,
22
+ role: "switch",
23
+ ref: forwardedRef
24
+ }
25
+ )
20
26
  }
21
27
  );
22
28
  }
@@ -2,35 +2,42 @@ import { jsx } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import * as Ariakit from "@ariakit/react";
4
4
  import cx from "classnames";
5
- import { useFieldDescribedBy, useFieldId } from "./Field.js";
5
+ import { FieldControl, useFieldDescribedBy } from "./Field.js";
6
6
  import { Icon } from "./Icon.js";
7
7
  import { useMergedRefs } from "./~hooks.js";
8
8
  import { forwardRef } from "./~utils.js";
9
9
  const TextBoxInput = forwardRef(
10
10
  (props, forwardedRef) => {
11
+ const { id, ...rest } = props;
11
12
  const describedBy = useFieldDescribedBy(props["aria-describedby"]);
12
- const fieldId = useFieldId();
13
13
  const rootContext = React.useContext(TextBoxRootContext);
14
14
  const setDisabled = rootContext?.setDisabled;
15
15
  React.useEffect(() => {
16
16
  setDisabled?.(props.disabled);
17
17
  }, [setDisabled, props.disabled]);
18
18
  return /* @__PURE__ */ jsx(
19
- Ariakit.Role.input,
19
+ FieldControl,
20
20
  {
21
- id: fieldId,
22
- ...props,
23
- "aria-describedby": describedBy,
24
- className: cx({ "\u{1F95D}-text-box": !rootContext }, props.className),
25
- placeholder: props.placeholder ?? " ",
21
+ type: "textlike",
22
+ id,
26
23
  render: /* @__PURE__ */ jsx(
27
- Ariakit.Focusable,
24
+ Ariakit.Role.input,
28
25
  {
29
- accessibleWhenDisabled: true,
30
- render: props.render || /* @__PURE__ */ jsx("input", {})
26
+ readOnly: props.disabled,
27
+ ...rest,
28
+ "aria-describedby": describedBy,
29
+ className: cx({ "\u{1F95D}-text-box": !rootContext }, props.className),
30
+ placeholder: props.placeholder ?? " ",
31
+ render: /* @__PURE__ */ jsx(
32
+ Ariakit.Focusable,
33
+ {
34
+ accessibleWhenDisabled: true,
35
+ render: props.render || /* @__PURE__ */ jsx("input", {})
36
+ }
37
+ ),
38
+ ref: useMergedRefs(rootContext?.inputRef, forwardedRef)
31
39
  }
32
- ),
33
- ref: useMergedRefs(rootContext?.inputRef, forwardedRef)
40
+ )
34
41
  }
35
42
  );
36
43
  }
@@ -38,24 +45,31 @@ const TextBoxInput = forwardRef(
38
45
  DEV: TextBoxInput.displayName = "TextBox.Input";
39
46
  const TextBoxTextarea = forwardRef(
40
47
  (props, forwardedRef) => {
41
- const fieldId = useFieldId();
48
+ const { id, ...rest } = props;
42
49
  const describedBy = useFieldDescribedBy(props["aria-describedby"]);
43
50
  return /* @__PURE__ */ jsx(
44
- Ariakit.Role.textarea,
51
+ FieldControl,
45
52
  {
46
- id: fieldId,
47
- ...props,
48
- className: cx("\u{1F95D}-text-box", props.className),
49
- "aria-describedby": describedBy,
50
- placeholder: props.placeholder ?? " ",
53
+ type: "textlike",
54
+ id,
51
55
  render: /* @__PURE__ */ jsx(
52
- Ariakit.Focusable,
56
+ Ariakit.Role.textarea,
53
57
  {
54
- accessibleWhenDisabled: true,
55
- render: props.render || /* @__PURE__ */ jsx("textarea", {})
58
+ readOnly: props.disabled,
59
+ ...rest,
60
+ className: cx("\u{1F95D}-text-box", props.className),
61
+ "aria-describedby": describedBy,
62
+ placeholder: props.placeholder ?? " ",
63
+ render: /* @__PURE__ */ jsx(
64
+ Ariakit.Focusable,
65
+ {
66
+ accessibleWhenDisabled: true,
67
+ render: props.render || /* @__PURE__ */ jsx("textarea", {})
68
+ }
69
+ ),
70
+ ref: forwardedRef
56
71
  }
57
- ),
58
- ref: forwardedRef
72
+ )
59
73
  }
60
74
  );
61
75
  }
@@ -24,6 +24,7 @@ const Tree = forwardRef((props, forwardedRef) => {
24
24
  DEV: Tree.displayName = "Tree.Root";
25
25
  const TreeItem = forwardRef((props, forwardedRef) => {
26
26
  const {
27
+ "aria-level": level,
27
28
  selected,
28
29
  children,
29
30
  expanded,
@@ -37,8 +38,6 @@ const TreeItem = forwardRef((props, forwardedRef) => {
37
38
  onKeyDown: onKeyDownProp,
38
39
  ...rest
39
40
  } = props;
40
- const parentContext = React.useContext(TreeItemContext);
41
- const level = parentContext ? parentContext.level + 1 : 1;
42
41
  const handleClick = (event) => {
43
42
  if (selected === void 0) return;
44
43
  event.stopPropagation();
@@ -67,7 +66,7 @@ const TreeItem = forwardRef((props, forwardedRef) => {
67
66
  }),
68
67
  [level, expanded, selected, contentId]
69
68
  ),
70
- children: /* @__PURE__ */ jsxs(
69
+ children: /* @__PURE__ */ jsx(
71
70
  Ariakit.CompositeItem,
72
71
  {
73
72
  render: /* @__PURE__ */ jsx(Ariakit.Role, { ...rest }),
@@ -83,35 +82,33 @@ const TreeItem = forwardRef((props, forwardedRef) => {
83
82
  "aria-expanded": expanded,
84
83
  "aria-selected": selected,
85
84
  "aria-labelledby": contentId,
85
+ "aria-level": level,
86
86
  className: cx("\u{1F95D}-tree-item", props.className),
87
87
  ref: forwardedRef,
88
- children: [
89
- /* @__PURE__ */ jsxs(
90
- ListItem.Root,
91
- {
92
- "data-kiwi-expanded": expanded,
93
- "data-kiwi-selected": selected,
94
- className: "\u{1F95D}-tree-item-node",
95
- style: { "--\u{1F95D}tree-item-level": level },
96
- role: void 0,
97
- children: [
98
- /* @__PURE__ */ jsx(
99
- TreeItemExpander,
100
- {
101
- onClick: () => {
102
- if (expanded === void 0) return;
103
- onExpandedChange?.(!expanded);
104
- }
88
+ children: /* @__PURE__ */ jsxs(
89
+ ListItem.Root,
90
+ {
91
+ "data-kiwi-expanded": expanded,
92
+ "data-kiwi-selected": selected,
93
+ className: "\u{1F95D}-tree-item-node",
94
+ style: { "--\u{1F95D}tree-item-level": level },
95
+ role: void 0,
96
+ children: [
97
+ /* @__PURE__ */ jsx(
98
+ TreeItemExpander,
99
+ {
100
+ onClick: () => {
101
+ if (expanded === void 0) return;
102
+ onExpandedChange?.(!expanded);
105
103
  }
106
- ),
107
- typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { href: icon }) : icon,
108
- /* @__PURE__ */ jsx(TreeItemContent, { label }),
109
- /* @__PURE__ */ jsx(TreeItemActions, { children: actions })
110
- ]
111
- }
112
- ),
113
- children && /* @__PURE__ */ jsx("div", { role: "group", children })
114
- ]
104
+ }
105
+ ),
106
+ typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { href: icon }) : icon,
107
+ /* @__PURE__ */ jsx(TreeItemContent, { label }),
108
+ /* @__PURE__ */ jsx(TreeItemActions, { children: actions })
109
+ ]
110
+ }
111
+ )
115
112
  }
116
113
  )
117
114
  }
@@ -135,23 +132,36 @@ const TreeItemContent = forwardRef(
135
132
  }
136
133
  );
137
134
  DEV: TreeItemContent.displayName = "TreeItemContent";
138
- const TreeItemActions = forwardRef(
135
+ const TreeItemActions = forwardRef((props, forwardedRef) => {
136
+ return /* @__PURE__ */ jsx(
137
+ Ariakit.Toolbar,
138
+ {
139
+ ...props,
140
+ onClick: useEventHandlers(props.onClick, (e) => e.stopPropagation()),
141
+ className: cx("\u{1F95D}-tree-item-actions", props.className),
142
+ ref: forwardedRef,
143
+ children: props.children
144
+ }
145
+ );
146
+ });
147
+ DEV: TreeItemActions.displayName = "TreeItemActions";
148
+ const TreeItemAction = forwardRef(
139
149
  (props, forwardedRef) => {
140
150
  const { visible, ...rest } = props;
141
151
  return /* @__PURE__ */ jsx(
142
- Ariakit.Toolbar,
152
+ IconButton,
143
153
  {
154
+ inert: visible === false ? true : void 0,
144
155
  ...rest,
145
- onClick: useEventHandlers(props.onClick, (e) => e.stopPropagation()),
146
- className: cx("\u{1F95D}-tree-item-actions", props.className),
156
+ variant: "ghost",
157
+ className: cx("\u{1F95D}-tree-item-action", props.className),
147
158
  "data-kiwi-visible": visible,
148
- ref: forwardedRef,
149
- children: props.children
159
+ ref: forwardedRef
150
160
  }
151
161
  );
152
162
  }
153
163
  );
154
- DEV: TreeItemActions.displayName = "TreeItemActions";
164
+ DEV: TreeItemAction.displayName = "Tree.ItemAction";
155
165
  const TreeItemExpander = forwardRef(
156
166
  (props, forwardedRef) => {
157
167
  return /* @__PURE__ */ jsx(
@@ -199,5 +209,6 @@ DEV: TreeChevron.displayName = "TreeChevron";
199
209
  const TreeItemContext = React.createContext(void 0);
200
210
  export {
201
211
  TreeItem as Item,
212
+ TreeItemAction as ItemAction,
202
213
  Tree as Root
203
214
  };