@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.
@@ -0,0 +1,151 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Role } from "@ariakit/react/role";
3
+ import { forwardRef } from "@stratakit/foundations/secret-internals";
4
+ import {
5
+ useMergedRefs,
6
+ useSafeContext
7
+ } from "@stratakit/foundations/secret-internals";
8
+ import cx from "classnames";
9
+ import * as React from "react";
10
+ const TableContext = React.createContext(void 0);
11
+ const TableHeaderContext = React.createContext(false);
12
+ const HtmlTable = forwardRef((props, forwardedRef) => {
13
+ const tableContextValue = React.useMemo(
14
+ () => ({ mode: "html" }),
15
+ []
16
+ );
17
+ return /* @__PURE__ */ jsx(TableContext.Provider, { value: tableContextValue, children: /* @__PURE__ */ jsx(
18
+ Role,
19
+ {
20
+ render: /* @__PURE__ */ jsx("table", {}),
21
+ ...props,
22
+ ref: forwardedRef,
23
+ className: cx("\u{1F95D}-table", props.className)
24
+ }
25
+ ) });
26
+ });
27
+ DEV: HtmlTable.displayName = "Table.HtmlTable";
28
+ const CustomTable = forwardRef(
29
+ (props, forwardedRef) => {
30
+ const [captionId, setCaptionId] = React.useState();
31
+ const tableContextValue = React.useMemo(
32
+ () => ({ captionId, setCaptionId, mode: "aria" }),
33
+ [captionId]
34
+ );
35
+ return /* @__PURE__ */ jsx(TableContext.Provider, { value: tableContextValue, children: /* @__PURE__ */ jsx(
36
+ Role.div,
37
+ {
38
+ role: "table",
39
+ "aria-labelledby": captionId,
40
+ ...props,
41
+ ref: forwardedRef,
42
+ className: cx("\u{1F95D}-table", props.className)
43
+ }
44
+ ) });
45
+ }
46
+ );
47
+ DEV: CustomTable.displayName = "Table.CustomTable";
48
+ const TableHeader = forwardRef(
49
+ (props, forwardedRef) => {
50
+ const { mode } = useSafeContext(TableContext);
51
+ const render = mode === "html" ? /* @__PURE__ */ jsx("thead", {}) : void 0;
52
+ const role = mode === "aria" ? "rowgroup" : void 0;
53
+ return /* @__PURE__ */ jsx(TableHeaderContext.Provider, { value: true, children: /* @__PURE__ */ jsx(
54
+ Role.div,
55
+ {
56
+ render,
57
+ role,
58
+ ...props,
59
+ ref: forwardedRef,
60
+ className: cx("\u{1F95D}-table-header", props.className)
61
+ }
62
+ ) });
63
+ }
64
+ );
65
+ DEV: TableHeader.displayName = "Table.Header";
66
+ const TableBody = forwardRef((props, forwardedRef) => {
67
+ const { mode } = useSafeContext(TableContext);
68
+ const render = mode === "html" ? /* @__PURE__ */ jsx("tbody", {}) : void 0;
69
+ return /* @__PURE__ */ jsx(
70
+ Role.div,
71
+ {
72
+ render,
73
+ role: void 0,
74
+ ...props,
75
+ ref: forwardedRef,
76
+ className: cx("\u{1F95D}-table-body", props.className)
77
+ }
78
+ );
79
+ });
80
+ DEV: TableBody.displayName = "Table.Body";
81
+ const TableRow = forwardRef((props, forwardedRef) => {
82
+ const { mode } = useSafeContext(TableContext);
83
+ const render = mode === "html" ? /* @__PURE__ */ jsx("tr", {}) : void 0;
84
+ const role = mode === "aria" ? "row" : void 0;
85
+ return /* @__PURE__ */ jsx(
86
+ Role.div,
87
+ {
88
+ render,
89
+ role,
90
+ ...props,
91
+ ref: forwardedRef,
92
+ className: cx("\u{1F95D}-table-row", props.className)
93
+ }
94
+ );
95
+ });
96
+ DEV: TableRow.displayName = "Table.Row";
97
+ const TableCaption = forwardRef(
98
+ (props, forwardedRef) => {
99
+ const fallbackId = React.useId();
100
+ const { id = fallbackId, ...rest } = props;
101
+ const { mode, setCaptionId } = useSafeContext(TableContext);
102
+ const render = mode === "html" ? /* @__PURE__ */ jsx("caption", {}) : void 0;
103
+ const captionIdRef = React.useCallback(
104
+ (element) => {
105
+ setCaptionId?.(element ? id : void 0);
106
+ },
107
+ [id, setCaptionId]
108
+ );
109
+ return /* @__PURE__ */ jsx(
110
+ Role.div,
111
+ {
112
+ render,
113
+ ...rest,
114
+ id,
115
+ ref: useMergedRefs(forwardedRef, captionIdRef),
116
+ className: cx("\u{1F95D}-table-caption", props.className)
117
+ }
118
+ );
119
+ }
120
+ );
121
+ DEV: TableCaption.displayName = "Table.Caption";
122
+ const TableCell = forwardRef((props, forwardedRef) => {
123
+ const isWithinTableHeader = useSafeContext(TableHeaderContext);
124
+ const { mode } = useSafeContext(TableContext);
125
+ const { render, role } = React.useMemo(() => {
126
+ if (mode === "aria") {
127
+ return { role: isWithinTableHeader ? "columnheader" : "cell" };
128
+ }
129
+ return { render: isWithinTableHeader ? /* @__PURE__ */ jsx("th", {}) : /* @__PURE__ */ jsx("td", {}) };
130
+ }, [isWithinTableHeader, mode]);
131
+ return /* @__PURE__ */ jsx(
132
+ Role.div,
133
+ {
134
+ render,
135
+ role,
136
+ ...props,
137
+ ref: forwardedRef,
138
+ className: cx("\u{1F95D}-table-cell", props.className)
139
+ }
140
+ );
141
+ });
142
+ DEV: TableCell.displayName = "Table.Cell";
143
+ export {
144
+ TableBody as Body,
145
+ TableCaption as Caption,
146
+ TableCell as Cell,
147
+ CustomTable,
148
+ TableHeader as Header,
149
+ HtmlTable,
150
+ TableRow as Row
151
+ };
@@ -0,0 +1,66 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import * as AkTab from "@ariakit/react/tab";
3
+ import { forwardRef } from "@stratakit/foundations/secret-internals";
4
+ import cx from "classnames";
5
+ function Tabs(props) {
6
+ const {
7
+ defaultSelectedId,
8
+ selectedId,
9
+ setSelectedId,
10
+ selectOnMove,
11
+ children
12
+ } = props;
13
+ return /* @__PURE__ */ jsx(
14
+ AkTab.TabProvider,
15
+ {
16
+ defaultSelectedId,
17
+ selectedId,
18
+ setSelectedId,
19
+ selectOnMove,
20
+ children
21
+ }
22
+ );
23
+ }
24
+ DEV: Tabs.displayName = "Tabs.Root";
25
+ const TabList = forwardRef((props, forwardedRef) => {
26
+ const { tone = "neutral", ...rest } = props;
27
+ return /* @__PURE__ */ jsx(
28
+ AkTab.TabList,
29
+ {
30
+ ...rest,
31
+ "data-kiwi-tone": tone,
32
+ className: cx("\u{1F95D}-tab-list", props.className),
33
+ ref: forwardedRef
34
+ }
35
+ );
36
+ });
37
+ DEV: TabList.displayName = "Tabs.TabList";
38
+ const Tab = forwardRef((props, forwardedRef) => {
39
+ return /* @__PURE__ */ jsx(
40
+ AkTab.Tab,
41
+ {
42
+ accessibleWhenDisabled: true,
43
+ ...props,
44
+ className: cx("\u{1F95D}-tab", props.className),
45
+ ref: forwardedRef
46
+ }
47
+ );
48
+ });
49
+ DEV: Tab.displayName = "Tabs.Tab";
50
+ const TabPanel = forwardRef((props, forwardedRef) => {
51
+ return /* @__PURE__ */ jsx(
52
+ AkTab.TabPanel,
53
+ {
54
+ ...props,
55
+ className: cx("\u{1F95D}-tab-panel", props.className),
56
+ ref: forwardedRef
57
+ }
58
+ );
59
+ });
60
+ DEV: TabPanel.displayName = "Tabs.TabPanel";
61
+ export {
62
+ Tabs as Root,
63
+ Tab,
64
+ TabList,
65
+ TabPanel
66
+ };
@@ -0,0 +1,27 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import * as Toolbar from "@ariakit/react/toolbar";
3
+ import { IconButtonContext } from "@stratakit/bricks/secret-internals";
4
+ import { forwardRef } from "@stratakit/foundations/secret-internals";
5
+ import cx from "classnames";
6
+ import * as React from "react";
7
+ const ToolbarGroup = forwardRef((props, forwardedRef) => {
8
+ return /* @__PURE__ */ jsx(IconButtonContext, { value: React.useMemo(() => ({ iconSize: "large" }), []), children: /* @__PURE__ */ jsx(
9
+ Toolbar.Toolbar,
10
+ {
11
+ ...props,
12
+ className: cx("\u{1F95D}-toolbar", props.className),
13
+ ref: forwardedRef
14
+ }
15
+ ) });
16
+ });
17
+ DEV: ToolbarGroup.displayName = "Toolbar.Group";
18
+ const ToolbarItem = forwardRef(
19
+ (props, forwardedRef) => {
20
+ return /* @__PURE__ */ jsx(Toolbar.ToolbarItem, { ...props, ref: forwardedRef });
21
+ }
22
+ );
23
+ DEV: ToolbarItem.displayName = "Toolbar.Item";
24
+ export {
25
+ ToolbarGroup as Group,
26
+ ToolbarItem as Item
27
+ };
@@ -0,0 +1,26 @@
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
+ DEV: Tree.displayName = "Tree.Root";
22
+ export {
23
+ TreeItemRoot as Item,
24
+ TreeItemAction as ItemAction,
25
+ Tree as Root
26
+ };
@@ -0,0 +1,395 @@
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
+ DEV: TreeItem.displayName = "Tree.Item";
96
+ function TreeItemRootProvider(props) {
97
+ const {
98
+ actions,
99
+ label,
100
+ description,
101
+ icon: iconProp,
102
+ unstable_decorations: decorations,
103
+ error
104
+ } = props;
105
+ const labelId = React.useId();
106
+ const descriptionId = React.useId();
107
+ const decorationId = React.useId();
108
+ const icon = error ? /* @__PURE__ */ jsx(StatusIcon, { tone: "attention" }) : iconProp;
109
+ const hasDecoration = icon || decorations;
110
+ return /* @__PURE__ */ jsx(TreeItemErrorContext.Provider, { value: error, children: /* @__PURE__ */ jsx(TreeItemActionsContext.Provider, { value: actions, children: /* @__PURE__ */ jsx(
111
+ TreeItemDecorationIdContext.Provider,
112
+ {
113
+ value: hasDecoration ? decorationId : void 0,
114
+ 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(
115
+ TreeItemDescriptionIdContext.Provider,
116
+ {
117
+ value: description ? descriptionId : void 0,
118
+ children: props.children
119
+ }
120
+ ) }) }) }) }) })
121
+ }
122
+ ) }) });
123
+ }
124
+ DEV: TreeItemRootProvider.displayName = "TreeItemRootProvider";
125
+ const TreeItemRoot = React.memo(
126
+ forwardRef((props, forwardedRef) => {
127
+ const {
128
+ style: styleProp,
129
+ "aria-level": level,
130
+ selected,
131
+ expanded,
132
+ ...rest
133
+ } = props;
134
+ const labelId = React.useContext(TreeItemLabelIdContext);
135
+ const decorationId = React.useContext(TreeItemDecorationIdContext);
136
+ const descriptionId = React.useContext(TreeItemDescriptionIdContext);
137
+ const error = React.useContext(TreeItemErrorContext);
138
+ const errorId = typeof error === "string" ? error : void 0;
139
+ const describedBy = React.useMemo(() => {
140
+ const ids = [];
141
+ if (descriptionId) ids.push(descriptionId);
142
+ if (decorationId) ids.push(decorationId);
143
+ if (errorId) ids.push(errorId);
144
+ return ids.length > 0 ? ids.join(" ") : void 0;
145
+ }, [decorationId, descriptionId, errorId]);
146
+ const style = React.useMemo(
147
+ () => ({
148
+ ...styleProp,
149
+ "--\u{1F95D}tree-item-level": level
150
+ }),
151
+ [styleProp, level]
152
+ );
153
+ return /* @__PURE__ */ jsx(
154
+ CompositeItem,
155
+ {
156
+ render: /* @__PURE__ */ jsx(
157
+ Role,
158
+ {
159
+ ...rest,
160
+ role: "treeitem",
161
+ "aria-expanded": expanded,
162
+ "aria-selected": selected,
163
+ "aria-labelledby": labelId,
164
+ "aria-describedby": describedBy,
165
+ "aria-level": level,
166
+ className: cx("\u{1F95D}-tree-item", props.className),
167
+ style,
168
+ ref: forwardedRef
169
+ }
170
+ ),
171
+ children: props.children
172
+ }
173
+ );
174
+ })
175
+ );
176
+ DEV: TreeItemRoot.displayName = "TreeItemRoot";
177
+ const TreeItemNode = React.memo((props) => {
178
+ const { expanded, selected, onExpanderClick } = props;
179
+ const error = React.useContext(TreeItemErrorContext);
180
+ return /* @__PURE__ */ jsxs(
181
+ ListItem.Root,
182
+ {
183
+ "data-kiwi-expanded": expanded,
184
+ "data-kiwi-selected": selected,
185
+ "data-kiwi-error": error ? true : void 0,
186
+ className: "\u{1F95D}-tree-item-node",
187
+ role: void 0,
188
+ children: [
189
+ /* @__PURE__ */ jsx(TreeItemDecorations, { onExpanderClick }),
190
+ /* @__PURE__ */ jsx(TreeItemContent, {}),
191
+ /* @__PURE__ */ jsx(TreeItemDescription, {}),
192
+ /* @__PURE__ */ jsx(TreeItemActions, {})
193
+ ]
194
+ }
195
+ );
196
+ });
197
+ DEV: TreeItemNode.displayName = "TreeItemNode";
198
+ const TreeItemDecorations = React.memo((props) => {
199
+ return /* @__PURE__ */ jsxs(ListItem.Decoration, { children: [
200
+ /* @__PURE__ */ jsx(TreeItemExpander, { onClick: props.onExpanderClick }),
201
+ /* @__PURE__ */ jsx(TreeItemDecoration, {})
202
+ ] });
203
+ });
204
+ DEV: TreeItemDecorations.displayName = "TreeItemDecorations";
205
+ function TreeItemDecoration() {
206
+ const decorationId = React.useContext(TreeItemDecorationIdContext);
207
+ const decorations = React.useContext(TreeItemDecorationsContext);
208
+ const icon = React.useContext(TreeItemIconContext);
209
+ return icon || decorations ? /* @__PURE__ */ jsx(
210
+ Role,
211
+ {
212
+ className: "\u{1F95D}-tree-item-decoration",
213
+ id: decorationId,
214
+ render: React.isValidElement(icon) ? icon : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { href: icon }) : void 0,
215
+ children: !icon ? decorations : null
216
+ }
217
+ ) : null;
218
+ }
219
+ DEV: TreeItemDecoration.displayName = "TreeItemDecoration";
220
+ const TreeItemContent = React.memo(() => {
221
+ const labelId = React.useContext(TreeItemLabelIdContext);
222
+ const label = React.useContext(TreeItemLabelContext);
223
+ return /* @__PURE__ */ jsx(ListItem.Content, { id: labelId, className: "\u{1F95D}-tree-item-content", children: label });
224
+ });
225
+ DEV: TreeItemContent.displayName = "TreeItemContent";
226
+ const TreeItemDescription = React.memo(() => {
227
+ const description = React.useContext(TreeItemDescriptionContext);
228
+ const descriptionId = React.useContext(TreeItemDescriptionIdContext);
229
+ return description ? /* @__PURE__ */ jsx(ListItem.Content, { id: descriptionId, className: "\u{1F95D}-tree-item-description", children: description }) : void 0;
230
+ });
231
+ DEV: TreeItemDescription.displayName = "TreeItemDescription";
232
+ const TreeItemActions = React.memo(
233
+ forwardRef((props, forwardedRef) => {
234
+ return /* @__PURE__ */ jsx(TreeItemActionsProvider, { children: /* @__PURE__ */ jsx(
235
+ ListItem.Decoration,
236
+ {
237
+ ...props,
238
+ onClick: useEventHandlers(props.onClick, (e) => e.stopPropagation()),
239
+ onKeyDown: useEventHandlers(
240
+ props.onKeyDown,
241
+ (e) => e.stopPropagation()
242
+ ),
243
+ className: cx("\u{1F95D}-tree-item-actions-container", props.className),
244
+ ref: forwardedRef,
245
+ render: /* @__PURE__ */ jsxs(Toolbar, { focusLoop: false, children: [
246
+ /* @__PURE__ */ jsx(TreeItemInlineActions, {}),
247
+ /* @__PURE__ */ jsx(TreeItemActionsOverflowMenu, {})
248
+ ] })
249
+ }
250
+ ) });
251
+ })
252
+ );
253
+ DEV: TreeItemActions.displayName = "TreeItemActions";
254
+ function TreeItemActionsProvider(props) {
255
+ const actionsProp = React.useContext(TreeItemActionsContext);
256
+ const error = React.useContext(TreeItemErrorContext);
257
+ const actionsLimit = error ? 2 : 3;
258
+ const { inline, overflow } = React.useMemo(() => {
259
+ const actions = React.Children.toArray(actionsProp).filter(Boolean);
260
+ const inline2 = /* @__PURE__ */ jsxs(Fragment, { children: [
261
+ actions.slice(0, actionsLimit - 1),
262
+ actions.length === actionsLimit ? actions[actionsLimit - 1] : null
263
+ ] });
264
+ const overflow2 = actions.length > actionsLimit ? actions.slice(actionsLimit - 1) : void 0;
265
+ return { inline: inline2, overflow: overflow2 };
266
+ }, [actionsProp, actionsLimit]);
267
+ return /* @__PURE__ */ jsx(TreeItemInlineActionsContext.Provider, { value: inline, children: /* @__PURE__ */ jsx(TreeItemOverflowActionsContext.Provider, { value: overflow, children: /* @__PURE__ */ jsx(TreeItemHasOverflowActionsContext.Provider, { value: !!overflow, children: props.children }) }) });
268
+ }
269
+ DEV: TreeItemActionsProvider.displayName = "TreeItemActionsProvider";
270
+ function TreeItemInlineActions() {
271
+ const actions = React.useContext(TreeItemInlineActionsContext);
272
+ return actions;
273
+ }
274
+ DEV: TreeItemInlineActions.displayName = "TreeItemInlineActions";
275
+ const arrowKeys = ["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight"];
276
+ const TreeItemActionsOverflowMenuContext = React.createContext(false);
277
+ function TreeItemActionsOverflowMenu() {
278
+ const overflow = React.useContext(TreeItemHasOverflowActionsContext);
279
+ const [open, setOpen] = React.useState(false);
280
+ const isArrowKeyPressed = React.useRef(false);
281
+ if (!overflow) return null;
282
+ return /* @__PURE__ */ jsx(PopoverProvider, { placement: "right-start", children: /* @__PURE__ */ jsxs(
283
+ DropdownMenu.Root,
284
+ {
285
+ open,
286
+ setOpen: React.useCallback((value) => {
287
+ if (value && !isArrowKeyPressed.current) {
288
+ setOpen(true);
289
+ } else {
290
+ setOpen(false);
291
+ }
292
+ }, []),
293
+ children: [
294
+ /* @__PURE__ */ jsx(
295
+ DropdownMenu.Button,
296
+ {
297
+ onKeyDown: (e) => {
298
+ if (arrowKeys.includes(e.key)) {
299
+ isArrowKeyPressed.current = true;
300
+ }
301
+ queueMicrotask(() => {
302
+ isArrowKeyPressed.current = false;
303
+ });
304
+ },
305
+ render: /* @__PURE__ */ jsx(TreeItemAction, { label: "More", icon: /* @__PURE__ */ jsx(MoreHorizontal, {}) })
306
+ }
307
+ ),
308
+ /* @__PURE__ */ jsx(TreeItemActionsOverflowMenuContext.Provider, { value: true, children: /* @__PURE__ */ jsx(TreeItemActionsOverflowMenuContent, {}) })
309
+ ]
310
+ }
311
+ ) });
312
+ }
313
+ DEV: TreeItemActionsOverflowMenu.displayName = "TreeItemActionsOverflowMenu";
314
+ function TreeItemActionsOverflowMenuContent() {
315
+ const actions = React.useContext(TreeItemOverflowActionsContext);
316
+ return /* @__PURE__ */ jsx(DropdownMenu.Content, { children: actions });
317
+ }
318
+ DEV: TreeItemActionsOverflowMenu.displayName = "TreeItemActionsOverflowMenu";
319
+ const TreeItemAction = React.memo(
320
+ forwardRef((props, forwardedRef) => {
321
+ const error = React.useContext(TreeItemErrorContext);
322
+ const {
323
+ visible = error ? true : void 0,
324
+ // visible by default during error state
325
+ label,
326
+ icon,
327
+ dot,
328
+ ...rest
329
+ } = props;
330
+ if (React.useContext(TreeItemActionsOverflowMenuContext)) {
331
+ DEV: {
332
+ if (visible !== void 0)
333
+ console.warn("overflowing actions should not use `visible` prop");
334
+ }
335
+ return /* @__PURE__ */ jsx(
336
+ DropdownMenu.Item,
337
+ {
338
+ ...rest,
339
+ label,
340
+ icon,
341
+ unstable_dot: dot,
342
+ ref: forwardedRef
343
+ }
344
+ );
345
+ }
346
+ DEV: {
347
+ if (!icon)
348
+ throw new Error(
349
+ "`icon` prop is required when the action is displayed as a button"
350
+ );
351
+ }
352
+ return /* @__PURE__ */ jsx(
353
+ ToolbarItem,
354
+ {
355
+ render: /* @__PURE__ */ jsx(
356
+ IconButton,
357
+ {
358
+ label,
359
+ icon,
360
+ inert: visible === false ? true : void 0,
361
+ ...rest,
362
+ dot,
363
+ variant: "ghost",
364
+ className: cx("\u{1F95D}-tree-item-action", props.className),
365
+ "data-kiwi-visible": visible,
366
+ ref: forwardedRef
367
+ }
368
+ )
369
+ }
370
+ );
371
+ })
372
+ );
373
+ DEV: TreeItemAction.displayName = "TreeItem.Action";
374
+ const TreeItemExpander = forwardRef(
375
+ (props, forwardedRef) => {
376
+ const descriptionId = React.useContext(TreeItemDescriptionIdContext);
377
+ return /* @__PURE__ */ jsx(GhostAligner, { align: descriptionId ? "block" : void 0, children: /* @__PURE__ */ jsx(
378
+ IconButtonPresentation,
379
+ {
380
+ "aria-hidden": "true",
381
+ ...props,
382
+ onClick: useEventHandlers(props.onClick, (e) => e.stopPropagation()),
383
+ className: cx("\u{1F95D}-tree-item-expander", props.className),
384
+ variant: "ghost",
385
+ ref: forwardedRef,
386
+ children: /* @__PURE__ */ jsx(ChevronDown, {})
387
+ }
388
+ ) });
389
+ }
390
+ );
391
+ DEV: TreeItemExpander.displayName = "TreeItemExpander";
392
+ export {
393
+ TreeItemAction as Action,
394
+ TreeItem as Root
395
+ };
@@ -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
+ };