@stratakit/structures 0.1.0 → 0.2.0

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/dist/Tree.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { Action as TreeItemAction, Root as TreeItemRoot } from "./TreeItem.js";
2
+ import type { BaseProps } from "@stratakit/foundations/secret-internals";
3
+ interface TreeProps extends BaseProps {
4
+ }
5
+ /**
6
+ * A tree is a hierarchical list of items that can be expanded or collapsed, or optionally selected.
7
+ *
8
+ * `Tree.Root` is the root component for a tree. `Tree.Item`s are rendered as a flat list in the `Tree.Root` component to create a hierarchical tree structure.
9
+ *
10
+ * Example:
11
+ * ```tsx
12
+ * <Tree.Root>
13
+ * <Tree.Item label="Parent 1" aria-level={1} aria-posinset={1} aria-setsize={2} />
14
+ * <Tree.Item label="Child 1.1" aria-level={2} aria-posinset={1} aria-setsize={2} />
15
+ * <Tree.Item label="Child 1.2" aria-level={2} aria-posinset={2} aria-setsize={2} />
16
+ * <Tree.Item label="Parent 2" aria-level={1} aria-posinset={2} aria-setsize={2} />
17
+ * <Tree.Item label="Child 2.1" aria-level={2} aria-posinset={1} aria-setsize={1} />
18
+ * </Tree.Root>
19
+ * ```
20
+ */
21
+ declare const Tree: import("react").ForwardRefExoticComponent<TreeProps & import("react").RefAttributes<HTMLDivElement | HTMLElement>>;
22
+ export { Tree as Root, TreeItemRoot as Item, TreeItemAction as ItemAction };
package/dist/Tree.js ADDED
@@ -0,0 +1,25 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Composite, useCompositeStore } from "@ariakit/react/composite";
3
+ import { Role } from "@ariakit/react/role";
4
+ import { forwardRef } from "@stratakit/foundations/secret-internals";
5
+ import cx from "classnames";
6
+ import { Action as TreeItemAction, Root as TreeItemRoot } from "./TreeItem.js";
7
+ const Tree = forwardRef((props, forwardedRef) => {
8
+ const composite = useCompositeStore({ orientation: "vertical" });
9
+ return /* @__PURE__ */ jsx(
10
+ Role.div,
11
+ {
12
+ role: "tree",
13
+ ...props,
14
+ render: /* @__PURE__ */ jsx(Composite, { store: composite }),
15
+ className: cx("\u{1F95D}-tree", props.className),
16
+ ref: forwardedRef,
17
+ children: props.children
18
+ }
19
+ );
20
+ });
21
+ export {
22
+ TreeItemRoot as Item,
23
+ TreeItemAction as ItemAction,
24
+ Tree as Root
25
+ };
@@ -0,0 +1,183 @@
1
+ import * as React from "react";
2
+ import type { BaseProps } from "@stratakit/foundations/secret-internals";
3
+ interface TreeItemProps extends Omit<BaseProps, "content" | "children"> {
4
+ /** Specifies the nesting level of the tree item. Nesting levels start at 1. */
5
+ "aria-level": number;
6
+ /** Defines tree item position in the current level of tree items. Integer greater than or equal to 1. */
7
+ "aria-posinset": number;
8
+ /** Defines tree item set size of the current level. */
9
+ "aria-setsize": number;
10
+ /**
11
+ * Specifies if the tree item is selected.
12
+ *
13
+ * If `undefined`, the tree item is not selectable.
14
+ *
15
+ * @default undefined
16
+ */
17
+ selected?: boolean;
18
+ /**
19
+ * Callback fired when the tree item is selected.
20
+ *
21
+ * Should be used with the `selected` prop.
22
+ */
23
+ onSelectedChange?: (selected: boolean) => void;
24
+ /**
25
+ * Specifies if the tree item is expanded.
26
+ *
27
+ * Used to determine if a tree item is a parent node. If `undefined`, it is a leaf node (i.e. not expandable).
28
+ *
29
+ * @default undefined
30
+ */
31
+ expanded?: boolean;
32
+ /**
33
+ * Callback fired when the tree item is expanded.
34
+ *
35
+ * Should be used with the `expanded` prop.
36
+ */
37
+ onExpandedChange?: (expanded: boolean) => void;
38
+ /**
39
+ * Icon to be displayed inside the tree item.
40
+ *
41
+ * Can be a URL of an SVG from the `@stratakit/icons` package, or a JSX element.
42
+ *
43
+ * For multiple icons/decorations, use the `unstable_decorations` prop.
44
+ */
45
+ icon?: string | React.JSX.Element;
46
+ /**
47
+ * Decoration(s) to be displayed inside the tree item.
48
+ *
49
+ * This is an alternative to the `icon` prop, and can be used to
50
+ * display multiple icons or other decorations before the label.
51
+ *
52
+ * Note: This should _not_ be used together with the `icon` prop.
53
+ *
54
+ * @experimental
55
+ */
56
+ unstable_decorations?: React.ReactNode;
57
+ /**
58
+ * The primary label that identifies the tree item and is displayed inside it.
59
+ */
60
+ label?: React.ReactNode;
61
+ /** Secondary line of text to display additional information about the tree item. */
62
+ description?: React.ReactNode;
63
+ /**
64
+ * The secondary actions available for the tree item. Must be a list of `Tree.ItemAction` components.
65
+ *
66
+ * Example:
67
+ * ```tsx
68
+ * actions={[
69
+ * error && <Tree.ItemAction key={…} icon={…} label={…} />,
70
+ * <Tree.ItemAction key={…} icon={…} label={…} />,
71
+ * <Tree.ItemAction key={…} icon={…} label={…} />,
72
+ * ]}
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
92
+ */
93
+ actions?: React.ReactNode[];
94
+ /**
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.
100
+ *
101
+ * @default false
102
+ */
103
+ error?: boolean | string;
104
+ }
105
+ /**
106
+ * A treeitem is a node in a tree structure that may be expanded or collapsed to reveal or hide its descendants.
107
+ *
108
+ * `Tree.Item`s can be rendered inside a `Tree.Root`. Additional properties are specified to the `Tree.Item`s to create a hierarchical tree structure.
109
+ *
110
+ * Example:
111
+ * ```tsx
112
+ * <Tree.Root>
113
+ * <Tree.Item label="Parent" aria-level={1} aria-posinset={1} aria-setsize={1} />
114
+ * <Tree.Item label="Child 1" aria-level={2} aria-posinset={1} aria-setsize={2} />
115
+ * <Tree.Item label="Child 2" aria-level={2} aria-posinset={2} aria-setsize={2} />
116
+ * </Tree.Root>
117
+ * ```
118
+ *
119
+ * The `label` and `icon` props can be used to specify the treeitem's own content.
120
+ *
121
+ * The `aria-level` prop is used to specify the nesting level of the treeitem. Nesting levels start at 1.
122
+ *
123
+ * The `aria-posinset` and `aria-setsize` props are used to define the treeitem's position in the current level of tree items.
124
+ *
125
+ * The `expanded` and `onExpandedChange` props can be used to control the expansion state of a treeitem.
126
+ *
127
+ * The `selected` and `onSelectedChange` props can be used to control the selection state of a treeitem.
128
+ *
129
+ * Secondary actions can be passed into the `actions` prop.
130
+ */
131
+ declare const TreeItem: React.NamedExoticComponent<TreeItemProps & React.RefAttributes<HTMLDivElement | HTMLElement>>;
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 `@stratakit/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;
148
+ /**
149
+ * Controls the visibility of the action (only when the action is displayed as icon-button).
150
+ *
151
+ * If `true`, the action is always visible.
152
+ * If `false`, the action is hidden and becomes inaccessible, but still occupies space.
153
+ *
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).
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;
174
+ }
175
+ /**
176
+ * A secondary action for `<Tree.Item>`, to be passed into the `actions` prop. The action is typically
177
+ * displayed as an icon-button or a menu-item (e.g. when overflowing).
178
+ *
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.
181
+ */
182
+ declare const TreeItemAction: React.NamedExoticComponent<TreeItemActionProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
183
+ export { TreeItem as Root, TreeItemAction as Action };
@@ -0,0 +1,370 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { CompositeItem } from "@ariakit/react/composite";
3
+ import { PopoverProvider } from "@ariakit/react/popover";
4
+ import { Role } from "@ariakit/react/role";
5
+ import { Toolbar, ToolbarItem } from "@ariakit/react/toolbar";
6
+ import { IconButton } from "@stratakit/bricks";
7
+ import {
8
+ GhostAligner,
9
+ IconButtonPresentation
10
+ } from "@stratakit/bricks/secret-internals";
11
+ import { Icon } from "@stratakit/foundations";
12
+ import {
13
+ forwardRef,
14
+ useEventHandlers
15
+ } from "@stratakit/foundations/secret-internals";
16
+ import cx from "classnames";
17
+ import * as React from "react";
18
+ import * as DropdownMenu from "./DropdownMenu.js";
19
+ import * as ListItem from "./~utils.ListItem.js";
20
+ import { ChevronDown, MoreHorizontal, StatusIcon } from "./~utils.icons.js";
21
+ const TreeItemErrorContext = React.createContext(void 0);
22
+ const TreeItemActionsContext = React.createContext(void 0);
23
+ const TreeItemDecorationsContext = React.createContext(void 0);
24
+ const TreeItemIconContext = React.createContext(void 0);
25
+ const TreeItemDecorationIdContext = React.createContext(
26
+ void 0
27
+ );
28
+ const TreeItemLabelContext = React.createContext(void 0);
29
+ const TreeItemLabelIdContext = React.createContext(
30
+ void 0
31
+ );
32
+ const TreeItemDescriptionContext = React.createContext(void 0);
33
+ const TreeItemDescriptionIdContext = React.createContext(
34
+ void 0
35
+ );
36
+ const TreeItemInlineActionsContext = React.createContext(void 0);
37
+ const TreeItemOverflowActionsContext = React.createContext(void 0);
38
+ const TreeItemHasOverflowActionsContext = React.createContext(false);
39
+ const TreeItem = React.memo(
40
+ forwardRef((props, forwardedRef) => {
41
+ const { expanded, selected } = props;
42
+ const {
43
+ onSelectedChange,
44
+ onExpandedChange,
45
+ icon,
46
+ unstable_decorations,
47
+ label,
48
+ description,
49
+ actions,
50
+ onClick: onClickProp,
51
+ onKeyDown: onKeyDownProp,
52
+ ...rest
53
+ } = props;
54
+ const onExpanderClick = useEventHandlers(() => {
55
+ if (expanded === void 0) return;
56
+ onExpandedChange?.(!expanded);
57
+ });
58
+ const handleClick = (event) => {
59
+ if (selected === void 0) return;
60
+ event.stopPropagation();
61
+ onSelectedChange?.(!selected);
62
+ };
63
+ const handleKeyDown = (event) => {
64
+ if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
65
+ return;
66
+ }
67
+ if (expanded === void 0) return;
68
+ if (event.key === "ArrowRight" || event.key === "ArrowLeft") {
69
+ event.preventDefault();
70
+ onExpandedChange?.(event.key === "ArrowRight");
71
+ }
72
+ };
73
+ return /* @__PURE__ */ jsx(TreeItemRootProvider, { ...props, children: /* @__PURE__ */ jsx(
74
+ TreeItemRoot,
75
+ {
76
+ ...rest,
77
+ onClick: useEventHandlers(onClickProp, handleClick),
78
+ onKeyDown: useEventHandlers(onKeyDownProp, handleKeyDown),
79
+ ref: forwardedRef,
80
+ children: React.useMemo(
81
+ () => /* @__PURE__ */ jsx(
82
+ TreeItemNode,
83
+ {
84
+ onExpanderClick,
85
+ expanded,
86
+ selected
87
+ }
88
+ ),
89
+ [onExpanderClick, expanded, selected]
90
+ )
91
+ }
92
+ ) });
93
+ })
94
+ );
95
+ function TreeItemRootProvider(props) {
96
+ const {
97
+ actions,
98
+ label,
99
+ description,
100
+ icon: iconProp,
101
+ unstable_decorations: decorations,
102
+ error
103
+ } = props;
104
+ const labelId = React.useId();
105
+ const descriptionId = React.useId();
106
+ const decorationId = React.useId();
107
+ const icon = error ? /* @__PURE__ */ jsx(StatusIcon, { tone: "attention" }) : iconProp;
108
+ const hasDecoration = icon || decorations;
109
+ return /* @__PURE__ */ jsx(TreeItemErrorContext.Provider, { value: error, children: /* @__PURE__ */ jsx(TreeItemActionsContext.Provider, { value: actions, children: /* @__PURE__ */ jsx(
110
+ TreeItemDecorationIdContext.Provider,
111
+ {
112
+ value: hasDecoration ? decorationId : void 0,
113
+ children: /* @__PURE__ */ jsx(TreeItemDecorationsContext.Provider, { value: decorations, children: /* @__PURE__ */ jsx(TreeItemIconContext.Provider, { value: icon, children: /* @__PURE__ */ jsx(TreeItemLabelIdContext.Provider, { value: labelId, children: /* @__PURE__ */ jsx(TreeItemLabelContext.Provider, { value: label, children: /* @__PURE__ */ jsx(TreeItemDescriptionContext.Provider, { value: description, children: /* @__PURE__ */ jsx(
114
+ TreeItemDescriptionIdContext.Provider,
115
+ {
116
+ value: description ? descriptionId : void 0,
117
+ children: props.children
118
+ }
119
+ ) }) }) }) }) })
120
+ }
121
+ ) }) });
122
+ }
123
+ const TreeItemRoot = React.memo(
124
+ forwardRef((props, forwardedRef) => {
125
+ const {
126
+ style: styleProp,
127
+ "aria-level": level,
128
+ selected,
129
+ expanded,
130
+ ...rest
131
+ } = props;
132
+ const labelId = React.useContext(TreeItemLabelIdContext);
133
+ const decorationId = React.useContext(TreeItemDecorationIdContext);
134
+ const descriptionId = React.useContext(TreeItemDescriptionIdContext);
135
+ const error = React.useContext(TreeItemErrorContext);
136
+ const errorId = typeof error === "string" ? error : void 0;
137
+ const describedBy = React.useMemo(() => {
138
+ const ids = [];
139
+ if (descriptionId) ids.push(descriptionId);
140
+ if (decorationId) ids.push(decorationId);
141
+ if (errorId) ids.push(errorId);
142
+ return ids.length > 0 ? ids.join(" ") : void 0;
143
+ }, [decorationId, descriptionId, errorId]);
144
+ const style = React.useMemo(
145
+ () => ({
146
+ ...styleProp,
147
+ "--\u{1F95D}tree-item-level": level
148
+ }),
149
+ [styleProp, level]
150
+ );
151
+ return /* @__PURE__ */ jsx(
152
+ CompositeItem,
153
+ {
154
+ render: /* @__PURE__ */ jsx(
155
+ Role,
156
+ {
157
+ ...rest,
158
+ role: "treeitem",
159
+ "aria-expanded": expanded,
160
+ "aria-selected": selected,
161
+ "aria-labelledby": labelId,
162
+ "aria-describedby": describedBy,
163
+ "aria-level": level,
164
+ className: cx("\u{1F95D}-tree-item", props.className),
165
+ style,
166
+ ref: forwardedRef
167
+ }
168
+ ),
169
+ children: props.children
170
+ }
171
+ );
172
+ })
173
+ );
174
+ const TreeItemNode = React.memo((props) => {
175
+ const { expanded, selected, onExpanderClick } = props;
176
+ const error = React.useContext(TreeItemErrorContext);
177
+ return /* @__PURE__ */ jsxs(
178
+ ListItem.Root,
179
+ {
180
+ "data-kiwi-expanded": expanded,
181
+ "data-kiwi-selected": selected,
182
+ "data-kiwi-error": error ? true : void 0,
183
+ className: "\u{1F95D}-tree-item-node",
184
+ role: void 0,
185
+ children: [
186
+ /* @__PURE__ */ jsx(TreeItemDecorations, { onExpanderClick }),
187
+ /* @__PURE__ */ jsx(TreeItemContent, {}),
188
+ /* @__PURE__ */ jsx(TreeItemDescription, {}),
189
+ /* @__PURE__ */ jsx(TreeItemActions, {})
190
+ ]
191
+ }
192
+ );
193
+ });
194
+ const TreeItemDecorations = React.memo((props) => {
195
+ return /* @__PURE__ */ jsxs(ListItem.Decoration, { children: [
196
+ /* @__PURE__ */ jsx(TreeItemExpander, { onClick: props.onExpanderClick }),
197
+ /* @__PURE__ */ jsx(TreeItemDecoration, {})
198
+ ] });
199
+ });
200
+ function TreeItemDecoration() {
201
+ const decorationId = React.useContext(TreeItemDecorationIdContext);
202
+ const decorations = React.useContext(TreeItemDecorationsContext);
203
+ const icon = React.useContext(TreeItemIconContext);
204
+ return icon || decorations ? /* @__PURE__ */ jsx(
205
+ Role,
206
+ {
207
+ className: "\u{1F95D}-tree-item-decoration",
208
+ id: decorationId,
209
+ render: React.isValidElement(icon) ? icon : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { href: icon }) : void 0,
210
+ children: !icon ? decorations : null
211
+ }
212
+ ) : null;
213
+ }
214
+ const TreeItemContent = React.memo(() => {
215
+ const labelId = React.useContext(TreeItemLabelIdContext);
216
+ const label = React.useContext(TreeItemLabelContext);
217
+ return /* @__PURE__ */ jsx(ListItem.Content, { id: labelId, className: "\u{1F95D}-tree-item-content", children: label });
218
+ });
219
+ const TreeItemDescription = React.memo(() => {
220
+ const description = React.useContext(TreeItemDescriptionContext);
221
+ const descriptionId = React.useContext(TreeItemDescriptionIdContext);
222
+ return description ? /* @__PURE__ */ jsx(ListItem.Content, { id: descriptionId, className: "\u{1F95D}-tree-item-description", children: description }) : void 0;
223
+ });
224
+ const TreeItemActions = React.memo(
225
+ forwardRef((props, forwardedRef) => {
226
+ return /* @__PURE__ */ jsx(TreeItemActionsProvider, { children: /* @__PURE__ */ jsx(
227
+ ListItem.Decoration,
228
+ {
229
+ ...props,
230
+ onClick: useEventHandlers(props.onClick, (e) => e.stopPropagation()),
231
+ onKeyDown: useEventHandlers(
232
+ props.onKeyDown,
233
+ (e) => e.stopPropagation()
234
+ ),
235
+ className: cx("\u{1F95D}-tree-item-actions-container", props.className),
236
+ ref: forwardedRef,
237
+ render: /* @__PURE__ */ jsxs(Toolbar, { focusLoop: false, children: [
238
+ /* @__PURE__ */ jsx(TreeItemInlineActions, {}),
239
+ /* @__PURE__ */ jsx(TreeItemActionsOverflowMenu, {})
240
+ ] })
241
+ }
242
+ ) });
243
+ })
244
+ );
245
+ function TreeItemActionsProvider(props) {
246
+ const actionsProp = React.useContext(TreeItemActionsContext);
247
+ const error = React.useContext(TreeItemErrorContext);
248
+ const actionsLimit = error ? 2 : 3;
249
+ const { inline, overflow } = React.useMemo(() => {
250
+ const actions = React.Children.toArray(actionsProp).filter(Boolean);
251
+ const inline2 = /* @__PURE__ */ jsxs(Fragment, { children: [
252
+ actions.slice(0, actionsLimit - 1),
253
+ actions.length === actionsLimit ? actions[actionsLimit - 1] : null
254
+ ] });
255
+ const overflow2 = actions.length > actionsLimit ? actions.slice(actionsLimit - 1) : void 0;
256
+ return { inline: inline2, overflow: overflow2 };
257
+ }, [actionsProp, actionsLimit]);
258
+ return /* @__PURE__ */ jsx(TreeItemInlineActionsContext.Provider, { value: inline, children: /* @__PURE__ */ jsx(TreeItemOverflowActionsContext.Provider, { value: overflow, children: /* @__PURE__ */ jsx(TreeItemHasOverflowActionsContext.Provider, { value: !!overflow, children: props.children }) }) });
259
+ }
260
+ function TreeItemInlineActions() {
261
+ const actions = React.useContext(TreeItemInlineActionsContext);
262
+ return actions;
263
+ }
264
+ const arrowKeys = ["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight"];
265
+ const TreeItemActionsOverflowMenuContext = React.createContext(false);
266
+ function TreeItemActionsOverflowMenu() {
267
+ const overflow = React.useContext(TreeItemHasOverflowActionsContext);
268
+ const [open, setOpen] = React.useState(false);
269
+ const isArrowKeyPressed = React.useRef(false);
270
+ if (!overflow) return null;
271
+ return /* @__PURE__ */ jsx(PopoverProvider, { placement: "right-start", children: /* @__PURE__ */ jsxs(
272
+ DropdownMenu.Root,
273
+ {
274
+ open,
275
+ setOpen: React.useCallback((value) => {
276
+ if (value && !isArrowKeyPressed.current) {
277
+ setOpen(true);
278
+ } else {
279
+ setOpen(false);
280
+ }
281
+ }, []),
282
+ children: [
283
+ /* @__PURE__ */ jsx(
284
+ DropdownMenu.Button,
285
+ {
286
+ onKeyDown: (e) => {
287
+ if (arrowKeys.includes(e.key)) {
288
+ isArrowKeyPressed.current = true;
289
+ }
290
+ queueMicrotask(() => {
291
+ isArrowKeyPressed.current = false;
292
+ });
293
+ },
294
+ render: /* @__PURE__ */ jsx(TreeItemAction, { label: "More", icon: /* @__PURE__ */ jsx(MoreHorizontal, {}) })
295
+ }
296
+ ),
297
+ /* @__PURE__ */ jsx(TreeItemActionsOverflowMenuContext.Provider, { value: true, children: /* @__PURE__ */ jsx(TreeItemActionsOverflowMenuContent, {}) })
298
+ ]
299
+ }
300
+ ) });
301
+ }
302
+ function TreeItemActionsOverflowMenuContent() {
303
+ const actions = React.useContext(TreeItemOverflowActionsContext);
304
+ return /* @__PURE__ */ jsx(DropdownMenu.Content, { children: actions });
305
+ }
306
+ const TreeItemAction = React.memo(
307
+ forwardRef((props, forwardedRef) => {
308
+ const error = React.useContext(TreeItemErrorContext);
309
+ const {
310
+ visible = error ? true : void 0,
311
+ // visible by default during error state
312
+ label,
313
+ icon,
314
+ dot,
315
+ ...rest
316
+ } = props;
317
+ if (React.useContext(TreeItemActionsOverflowMenuContext)) {
318
+ return /* @__PURE__ */ jsx(
319
+ DropdownMenu.Item,
320
+ {
321
+ ...rest,
322
+ label,
323
+ icon,
324
+ unstable_dot: dot,
325
+ ref: forwardedRef
326
+ }
327
+ );
328
+ }
329
+ return /* @__PURE__ */ jsx(
330
+ ToolbarItem,
331
+ {
332
+ render: /* @__PURE__ */ jsx(
333
+ IconButton,
334
+ {
335
+ label,
336
+ icon,
337
+ inert: visible === false ? true : void 0,
338
+ ...rest,
339
+ dot,
340
+ variant: "ghost",
341
+ className: cx("\u{1F95D}-tree-item-action", props.className),
342
+ "data-kiwi-visible": visible,
343
+ ref: forwardedRef
344
+ }
345
+ )
346
+ }
347
+ );
348
+ })
349
+ );
350
+ const TreeItemExpander = forwardRef(
351
+ (props, forwardedRef) => {
352
+ const descriptionId = React.useContext(TreeItemDescriptionIdContext);
353
+ return /* @__PURE__ */ jsx(GhostAligner, { align: descriptionId ? "block" : void 0, children: /* @__PURE__ */ jsx(
354
+ IconButtonPresentation,
355
+ {
356
+ "aria-hidden": "true",
357
+ ...props,
358
+ onClick: useEventHandlers(props.onClick, (e) => e.stopPropagation()),
359
+ className: cx("\u{1F95D}-tree-item-expander", props.className),
360
+ variant: "ghost",
361
+ ref: forwardedRef,
362
+ children: /* @__PURE__ */ jsx(ChevronDown, {})
363
+ }
364
+ ) });
365
+ }
366
+ );
367
+ export {
368
+ TreeItemAction as Action,
369
+ TreeItem as Root
370
+ };
@@ -0,0 +1,9 @@
1
+ export * as unstable_AccordionItem from "./AccordionItem.js";
2
+ export { Banner as unstable_Banner } from "./Banner.js";
3
+ export { Chip } from "./Chip.js";
4
+ export * as DropdownMenu from "./DropdownMenu.js";
5
+ export * as unstable_ErrorRegion from "./ErrorRegion.js";
6
+ export * as Table from "./Table.js";
7
+ export * as Tabs from "./Tabs.js";
8
+ export * as unstable_Toolbar from "./Toolbar.js";
9
+ export * as Tree from "./Tree.js";
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import * as unstable_AccordionItem from "./AccordionItem.js";
3
+ import { Banner } from "./Banner.js";
4
+ import { Chip } from "./Chip.js";
5
+ import * as DropdownMenu from "./DropdownMenu.js";
6
+ import * as unstable_ErrorRegion from "./ErrorRegion.js";
7
+ import * as Table from "./Table.js";
8
+ import * as Tabs from "./Tabs.js";
9
+ import * as unstable_Toolbar from "./Toolbar.js";
10
+ import * as Tree from "./Tree.js";
11
+ export {
12
+ Chip,
13
+ DropdownMenu,
14
+ Table,
15
+ Tabs,
16
+ Tree,
17
+ unstable_AccordionItem,
18
+ Banner as unstable_Banner,
19
+ unstable_ErrorRegion,
20
+ unstable_Toolbar
21
+ };