@stealthscale/component-collections 0.1.2 → 0.1.3

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 (34) hide show
  1. package/dist/cyclonedx/bom.json +1 -1
  2. package/dist/index.js +1 -5700
  3. package/dist/pages/data-list/data-list.js +351 -0
  4. package/dist/pages/data-list/data-list.props.js +3 -0
  5. package/dist/pages/listbox/listbox.js +1277 -0
  6. package/dist/pages/listbox/listbox.props.js +3 -0
  7. package/dist/pages/pages.json +105 -0
  8. package/dist/pages/sortable/sortable.js +576 -0
  9. package/dist/pages/sortable/sortable.props.js +3 -0
  10. package/dist/pages/status-matrix/status-matrix.js +1403 -0
  11. package/dist/pages/status-matrix/status-matrix.props.js +3 -0
  12. package/dist/pages/swipe-actions/swipe-actions.js +212 -0
  13. package/dist/pages/swipe-actions/swipe-actions.props.js +3 -0
  14. package/dist/pages/table/table.js +1701 -0
  15. package/dist/pages/table/table.props.js +3 -0
  16. package/dist/pages/timeline/timeline.js +380 -0
  17. package/dist/pages/timeline/timeline.props.js +3 -0
  18. package/dist/pages/transfer/transfer.js +465 -0
  19. package/dist/pages/transfer/transfer.props.js +3 -0
  20. package/dist/pages/tree-view/tree-view.js +1059 -0
  21. package/dist/pages/tree-view/tree-view.props.js +3 -0
  22. package/dist/shared-DVn824MJ.js +5701 -0
  23. package/dist/theme.js +1 -1
  24. package/locales/en/specimen/data-list.json +64 -0
  25. package/locales/en/specimen/listbox.json +98 -0
  26. package/locales/en/specimen/sortable.json +65 -0
  27. package/locales/en/specimen/status-matrix.json +47 -0
  28. package/locales/en/specimen/swipe-actions.json +32 -0
  29. package/locales/en/specimen/table.json +94 -0
  30. package/locales/en/specimen/timeline.json +72 -0
  31. package/locales/en/specimen/transfer.json +34 -0
  32. package/locales/en/specimen/tree-view.json +107 -0
  33. package/package.json +9 -8
  34. /package/dist/{recipe-C1oaF8pO.js → recipes-C1oaF8pO.js} +0 -0
@@ -0,0 +1,1059 @@
1
+ import { t as __exportAll } from "../../rolldown-runtime-D7D4PA-g.js";
2
+ import { a as NodeRenameInput, c as Item, d as BranchText, f as BranchIndicator, i as Nodes, l as ItemText, m as BranchControl, n as Tree, o as NodeCheckbox, p as BranchIndentGuide, r as Root, rt as TreeCollection, s as Label, u as BranchTrigger } from "../../shared-DVn824MJ.js";
3
+ import { t as recipe } from "../../recipes-C1oaF8pO.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import { useState } from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Button } from "@stealthscale/component-actions";
8
+ import { Matrix, Room, scenesOf, specimen, useWords } from "@stealthscale/specimen";
9
+ import { CheckIcon, ChevronRightIcon, FileIcon, FileTextIcon, FolderIcon, FolderOpenIcon, LoaderCircleIcon, LockIcon, MinusIcon, SearchIcon, XIcon } from "lucide-react";
10
+ import { Icon, Kbd, Text } from "@stealthscale/component-typography";
11
+ import { Group, Stack } from "@stealthscale/component-layout";
12
+ import { SearchInput } from "@stealthscale/component-forms";
13
+ //#region src/tree-view/examples/docs.example.tsx
14
+ var docs_example_exports = /* @__PURE__ */ __exportAll({
15
+ Docs: () => Docs,
16
+ source: () => source$6
17
+ });
18
+ const PAGES = new TreeCollection({
19
+ nodeToValue: (node) => node.id,
20
+ rootNode: {
21
+ children: [
22
+ {
23
+ children: [
24
+ { id: "install" },
25
+ { id: "configure" },
26
+ { id: "themes" }
27
+ ],
28
+ id: "start"
29
+ },
30
+ {
31
+ children: [{
32
+ children: [{ id: "button" }, { id: "toggle-group" }],
33
+ id: "actions"
34
+ }, {
35
+ children: [{ id: "listbox" }, { id: "tree-view" }],
36
+ id: "collections"
37
+ }],
38
+ id: "components"
39
+ },
40
+ { id: "changelog" }
41
+ ],
42
+ id: "root"
43
+ }
44
+ });
45
+ function Docs() {
46
+ const $ = c(12);
47
+ const { t } = useWords("tree-view");
48
+ let t0;
49
+ let t1;
50
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
51
+ t0 = ["components", "collections"];
52
+ t1 = ["tree-view"];
53
+ $[0] = t0;
54
+ $[1] = t1;
55
+ } else {
56
+ t0 = $[0];
57
+ t1 = $[1];
58
+ }
59
+ let t2;
60
+ if ($[2] !== t) {
61
+ t2 = t("docs.label");
62
+ $[2] = t;
63
+ $[3] = t2;
64
+ } else t2 = $[3];
65
+ let t3;
66
+ if ($[4] !== t2) {
67
+ t3 = /* @__PURE__ */ jsx(Label, { children: t2 });
68
+ $[4] = t2;
69
+ $[5] = t3;
70
+ } else t3 = $[5];
71
+ let t4;
72
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
73
+ t4 = /* @__PURE__ */ jsx(BranchIndentGuide, {});
74
+ $[6] = t4;
75
+ } else t4 = $[6];
76
+ let t5;
77
+ if ($[7] !== t) {
78
+ t5 = /* @__PURE__ */ jsx(Tree, { children: /* @__PURE__ */ jsx(Nodes, {
79
+ indentGuide: t4,
80
+ render: (t6) => {
81
+ const { node, nodeState } = t6;
82
+ return nodeState.isBranch ? /* @__PURE__ */ jsxs(BranchControl, { children: [/* @__PURE__ */ jsx(BranchIndicator, { children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) }), /* @__PURE__ */ jsx(BranchText, { children: t(`docs.${node.id}`) })] }) : /* @__PURE__ */ jsx(Item, {
83
+ href: `#docs-${node.id}`,
84
+ children: /* @__PURE__ */ jsx(ItemText, { children: t(`docs.${node.id}`) })
85
+ });
86
+ }
87
+ }) });
88
+ $[7] = t;
89
+ $[8] = t5;
90
+ } else t5 = $[8];
91
+ let t6;
92
+ if ($[9] !== t3 || $[10] !== t5) {
93
+ t6 = /* @__PURE__ */ jsxs(Root, {
94
+ collection: PAGES,
95
+ defaultExpandedValue: t0,
96
+ defaultSelectedValue: t1,
97
+ size: "sm",
98
+ children: [t3, t5]
99
+ });
100
+ $[9] = t3;
101
+ $[10] = t5;
102
+ $[11] = t6;
103
+ } else t6 = $[11];
104
+ return t6;
105
+ }
106
+ const source$6 = "import { type ReactElement } from \"react\";\n\nimport { ChevronRightIcon } from \"lucide-react\";\n\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { TreeCollection, TreeView } from \"@stealthscale/component-collections\";\n\ninterface Page {\n children?: Page[];\n id: string;\n}\n\nconst PAGES = new TreeCollection<Page>({\n nodeToValue: (node): string => node.id,\n rootNode: {\n children: [\n { children: [{ id: \"install\" }, { id: \"configure\" }, { id: \"themes\" }], id: \"start\" },\n {\n children: [\n { children: [{ id: \"button\" }, { id: \"toggle-group\" }], id: \"actions\" },\n { children: [{ id: \"listbox\" }, { id: \"tree-view\" }], id: \"collections\" },\n ],\n id: \"components\",\n },\n { id: \"changelog\" },\n ],\n id: \"root\",\n },\n});\n\nexport function Docs(): ReactElement {\n const { t } = useWords(\"tree-view\");\n\n return (\n <TreeView.Root\n collection={PAGES}\n defaultExpandedValue={[\"components\", \"collections\"]}\n defaultSelectedValue={[\"tree-view\"]}\n size=\"sm\"\n >\n <TreeView.Label>{t(\"docs.label\")}</TreeView.Label>\n <TreeView.Tree>\n <TreeView.Nodes\n indentGuide={<TreeView.BranchIndentGuide />}\n render={({ node, nodeState }: TreeView.NodeDetails<Page>) =>\n nodeState.isBranch ? (\n <TreeView.BranchControl>\n <TreeView.BranchIndicator>\n <ChevronRightIcon />\n </TreeView.BranchIndicator>\n <TreeView.BranchText>{t(`docs.${node.id}`)}</TreeView.BranchText>\n </TreeView.BranchControl>\n ) : (\n <TreeView.Item href={`#docs-${node.id}`}>\n <TreeView.ItemText>{t(`docs.${node.id}`)}</TreeView.ItemText>\n </TreeView.Item>\n )\n }\n />\n </TreeView.Tree>\n </TreeView.Root>\n );\n}\n";
107
+ //#endregion
108
+ //#region src/tree-view/examples/explorer.example.tsx
109
+ var explorer_example_exports = /* @__PURE__ */ __exportAll({
110
+ Explorer: () => Explorer,
111
+ source: () => source$5
112
+ });
113
+ const FILES = new TreeCollection({
114
+ nodeToString: (node) => node.name,
115
+ nodeToValue: (node) => node.id,
116
+ rootNode: {
117
+ children: [
118
+ {
119
+ children: [{
120
+ children: [{
121
+ id: "src/components/button.tsx",
122
+ name: "button.tsx"
123
+ }, {
124
+ id: "src/components/card.tsx",
125
+ name: "card.tsx"
126
+ }],
127
+ id: "src/components",
128
+ name: "components"
129
+ }, {
130
+ id: "src/index.ts",
131
+ name: "index.ts"
132
+ }],
133
+ id: "src",
134
+ name: "src"
135
+ },
136
+ {
137
+ id: "package.json",
138
+ name: "package.json"
139
+ },
140
+ {
141
+ id: "README.md",
142
+ name: "README.md"
143
+ }
144
+ ],
145
+ id: "root",
146
+ name: ""
147
+ }
148
+ });
149
+ function Explorer(props) {
150
+ const $ = c(10);
151
+ const { t } = useWords("tree-view");
152
+ let t0;
153
+ let t1;
154
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
155
+ t0 = ["src", "src/components"];
156
+ t1 = ["src/components/card.tsx"];
157
+ $[0] = t0;
158
+ $[1] = t1;
159
+ } else {
160
+ t0 = $[0];
161
+ t1 = $[1];
162
+ }
163
+ let t2;
164
+ if ($[2] !== t) {
165
+ t2 = t("explorer.label");
166
+ $[2] = t;
167
+ $[3] = t2;
168
+ } else t2 = $[3];
169
+ let t3;
170
+ if ($[4] !== t2) {
171
+ t3 = /* @__PURE__ */ jsx(Label, { children: t2 });
172
+ $[4] = t2;
173
+ $[5] = t3;
174
+ } else t3 = $[5];
175
+ let t4;
176
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
177
+ t4 = /* @__PURE__ */ jsx(Tree, { children: /* @__PURE__ */ jsx(Nodes, { render: _temp$2 }) });
178
+ $[6] = t4;
179
+ } else t4 = $[6];
180
+ let t5;
181
+ if ($[7] !== props || $[8] !== t3) {
182
+ t5 = /* @__PURE__ */ jsxs(Root, {
183
+ collection: FILES,
184
+ defaultExpandedValue: t0,
185
+ defaultSelectedValue: t1,
186
+ ...props,
187
+ children: [t3, t4]
188
+ });
189
+ $[7] = props;
190
+ $[8] = t3;
191
+ $[9] = t5;
192
+ } else t5 = $[9];
193
+ return t5;
194
+ }
195
+ function _temp$2(t0) {
196
+ const { node, nodeState } = t0;
197
+ return nodeState.isBranch ? /* @__PURE__ */ jsxs(BranchControl, { children: [
198
+ /* @__PURE__ */ jsx(BranchIndicator, { children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) }),
199
+ nodeState.expanded ? /* @__PURE__ */ jsx(FolderOpenIcon, {}) : /* @__PURE__ */ jsx(FolderIcon, {}),
200
+ /* @__PURE__ */ jsx(BranchText, { children: node.name })
201
+ ] }) : /* @__PURE__ */ jsxs(Item, { children: [/* @__PURE__ */ jsx(FileIcon, {}), /* @__PURE__ */ jsx(ItemText, { children: node.name })] });
202
+ }
203
+ const source$5 = "import { type ReactElement } from \"react\";\n\nimport { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from \"lucide-react\";\n\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { TreeCollection, TreeView } from \"@stealthscale/component-collections\";\n\ninterface FileNode {\n children?: FileNode[];\n id: string;\n name: string;\n}\n\nconst FILES = new TreeCollection<FileNode>({\n nodeToString: (node): string => node.name,\n nodeToValue: (node): string => node.id,\n rootNode: {\n children: [\n {\n children: [\n {\n children: [\n { id: \"src/components/button.tsx\", name: \"button.tsx\" },\n { id: \"src/components/card.tsx\", name: \"card.tsx\" },\n ],\n id: \"src/components\",\n name: \"components\",\n },\n { id: \"src/index.ts\", name: \"index.ts\" },\n ],\n id: \"src\",\n name: \"src\",\n },\n { id: \"package.json\", name: \"package.json\" },\n { id: \"README.md\", name: \"README.md\" },\n ],\n id: \"root\",\n name: \"\",\n },\n});\n\nexport function Explorer(props: TreeView.RootProps): ReactElement {\n const { t } = useWords(\"tree-view\");\n\n return (\n <TreeView.Root\n collection={FILES}\n defaultExpandedValue={[\"src\", \"src/components\"]}\n defaultSelectedValue={[\"src/components/card.tsx\"]}\n {...props}\n >\n <TreeView.Label>{t(\"explorer.label\")}</TreeView.Label>\n <TreeView.Tree>\n <TreeView.Nodes\n render={({ node, nodeState }: TreeView.NodeDetails<FileNode>) =>\n nodeState.isBranch ? (\n <TreeView.BranchControl>\n <TreeView.BranchIndicator>\n <ChevronRightIcon />\n </TreeView.BranchIndicator>\n {nodeState.expanded ? <FolderOpenIcon /> : <FolderIcon />}\n <TreeView.BranchText>{node.name}</TreeView.BranchText>\n </TreeView.BranchControl>\n ) : (\n <TreeView.Item>\n <FileIcon />\n <TreeView.ItemText>{node.name}</TreeView.ItemText>\n </TreeView.Item>\n )\n }\n />\n </TreeView.Tree>\n </TreeView.Root>\n );\n}\n";
204
+ //#endregion
205
+ //#region src/tree-view/examples/lazy.example.tsx
206
+ var lazy_example_exports = /* @__PURE__ */ __exportAll({
207
+ Lazy: () => Lazy,
208
+ source: () => source$4
209
+ });
210
+ const OFFICES = {
211
+ americas: ["new-york", "sao-paulo"],
212
+ asia: ["singapore", "tokyo"],
213
+ europe: [
214
+ "amsterdam",
215
+ "berlin",
216
+ "lisbon"
217
+ ]
218
+ };
219
+ const REGIONS = new TreeCollection({
220
+ nodeToValue: (node) => node.id,
221
+ rootNode: {
222
+ children: Object.entries(OFFICES).map(([id, cities]) => ({
223
+ childrenCount: cities.length,
224
+ id
225
+ })),
226
+ id: "root"
227
+ }
228
+ });
229
+ function load({ signal, valuePath }) {
230
+ return new Promise((resolve) => {
231
+ const timer = setTimeout(() => {
232
+ resolve((OFFICES[valuePath.at(-1) ?? ""] ?? []).map((id) => ({ id })));
233
+ }, 800);
234
+ signal.addEventListener("abort", () => {
235
+ clearTimeout(timer);
236
+ });
237
+ });
238
+ }
239
+ function Lazy() {
240
+ const $ = c(11);
241
+ const { t } = useWords("tree-view");
242
+ const [collection, setCollection] = useState(REGIONS);
243
+ let t0;
244
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
245
+ t0 = (details) => {
246
+ setCollection(details.collection);
247
+ };
248
+ $[0] = t0;
249
+ } else t0 = $[0];
250
+ let t1;
251
+ if ($[1] !== t) {
252
+ t1 = t("lazy.label");
253
+ $[1] = t;
254
+ $[2] = t1;
255
+ } else t1 = $[2];
256
+ let t2;
257
+ if ($[3] !== t1) {
258
+ t2 = /* @__PURE__ */ jsx(Label, { children: t1 });
259
+ $[3] = t1;
260
+ $[4] = t2;
261
+ } else t2 = $[4];
262
+ let t3;
263
+ if ($[5] !== t) {
264
+ t3 = /* @__PURE__ */ jsx(Tree, { children: /* @__PURE__ */ jsx(Nodes, { render: (t4) => {
265
+ const { node, nodeState } = t4;
266
+ return nodeState.isBranch ? /* @__PURE__ */ jsxs(BranchControl, { children: [/* @__PURE__ */ jsx(BranchIndicator, { children: nodeState.loading ? /* @__PURE__ */ jsx(Icon, {
267
+ as: LoaderCircleIcon,
268
+ motion: "spin"
269
+ }) : /* @__PURE__ */ jsx(ChevronRightIcon, {}) }), /* @__PURE__ */ jsx(BranchText, { children: t(`lazy.${node.id}`) })] }) : /* @__PURE__ */ jsx(Item, { children: /* @__PURE__ */ jsx(ItemText, { children: t(`lazy.${node.id}`) }) });
270
+ } }) });
271
+ $[5] = t;
272
+ $[6] = t3;
273
+ } else t3 = $[6];
274
+ let t4;
275
+ if ($[7] !== collection || $[8] !== t2 || $[9] !== t3) {
276
+ t4 = /* @__PURE__ */ jsxs(Root, {
277
+ collection,
278
+ loadChildren: load,
279
+ onLoadChildrenComplete: t0,
280
+ children: [t2, t3]
281
+ });
282
+ $[7] = collection;
283
+ $[8] = t2;
284
+ $[9] = t3;
285
+ $[10] = t4;
286
+ } else t4 = $[10];
287
+ return t4;
288
+ }
289
+ const source$4 = "import { type ReactElement, useState } from \"react\";\n\nimport { ChevronRightIcon, LoaderCircleIcon } from \"lucide-react\";\n\nimport { Icon } from \"@stealthscale/component-typography\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { TreeCollection, TreeView } from \"@stealthscale/component-collections\";\n\ninterface Place {\n children?: Place[];\n childrenCount?: number;\n id: string;\n}\n\nconst OFFICES: Readonly<Record<string, readonly string[]>> = {\n americas: [\"new-york\", \"sao-paulo\"],\n asia: [\"singapore\", \"tokyo\"],\n europe: [\"amsterdam\", \"berlin\", \"lisbon\"],\n};\n\nconst REGIONS = new TreeCollection<Place>({\n nodeToValue: (node): string => node.id,\n rootNode: {\n children: Object.entries(OFFICES).map(([id, cities]) => ({ childrenCount: cities.length, id })),\n id: \"root\",\n },\n});\n\nfunction load({\n signal,\n valuePath,\n}: {\n signal: AbortSignal;\n valuePath: string[];\n}): Promise<Place[]> {\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n resolve((OFFICES[valuePath.at(-1) ?? \"\"] ?? []).map((id) => ({ id })));\n }, 800);\n\n signal.addEventListener(\"abort\", () => {\n clearTimeout(timer);\n });\n });\n}\n\nexport function Lazy(): ReactElement {\n const { t } = useWords(\"tree-view\");\n const [collection, setCollection] = useState(REGIONS);\n\n return (\n <TreeView.Root\n collection={collection}\n loadChildren={load}\n onLoadChildrenComplete={(details: { collection: TreeCollection<Place> }) => {\n setCollection(details.collection);\n }}\n >\n <TreeView.Label>{t(\"lazy.label\")}</TreeView.Label>\n <TreeView.Tree>\n <TreeView.Nodes\n render={({ node, nodeState }: TreeView.NodeDetails<Place>) =>\n nodeState.isBranch ? (\n <TreeView.BranchControl>\n <TreeView.BranchIndicator>\n {nodeState.loading ? (\n <Icon as={LoaderCircleIcon} motion=\"spin\" />\n ) : (\n <ChevronRightIcon />\n )}\n </TreeView.BranchIndicator>\n <TreeView.BranchText>{t(`lazy.${node.id}`)}</TreeView.BranchText>\n </TreeView.BranchControl>\n ) : (\n <TreeView.Item>\n <TreeView.ItemText>{t(`lazy.${node.id}`)}</TreeView.ItemText>\n </TreeView.Item>\n )\n }\n />\n </TreeView.Tree>\n </TreeView.Root>\n );\n}\n";
290
+ //#endregion
291
+ //#region src/tree-view/examples/outline.example.tsx
292
+ var outline_example_exports = /* @__PURE__ */ __exportAll({
293
+ Outline: () => Outline,
294
+ source: () => source$3
295
+ });
296
+ const OUTLINE = new TreeCollection({
297
+ nodeToValue: (node) => node.id,
298
+ rootNode: {
299
+ children: [
300
+ {
301
+ children: [{ id: "summary" }, { id: "goals" }],
302
+ id: "introduction"
303
+ },
304
+ {
305
+ children: [{ id: "survey" }, {
306
+ children: [{ id: "latency" }, { id: "errors" }],
307
+ id: "results"
308
+ }],
309
+ id: "findings"
310
+ },
311
+ {
312
+ children: [{ id: "raw-data" }],
313
+ disabled: true,
314
+ id: "appendix"
315
+ }
316
+ ],
317
+ id: "root"
318
+ }
319
+ });
320
+ function Outline() {
321
+ const $ = c(28);
322
+ const { t } = useWords("tree-view");
323
+ let t0;
324
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
325
+ t0 = ["introduction"];
326
+ $[0] = t0;
327
+ } else t0 = $[0];
328
+ const [expanded, setExpanded] = useState(t0);
329
+ let t1;
330
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
331
+ t1 = () => {
332
+ setExpanded(OUTLINE.getBranchValues());
333
+ };
334
+ $[1] = t1;
335
+ } else t1 = $[1];
336
+ let t2;
337
+ if ($[2] !== t) {
338
+ t2 = t("outline.expand");
339
+ $[2] = t;
340
+ $[3] = t2;
341
+ } else t2 = $[3];
342
+ let t3;
343
+ if ($[4] !== t2) {
344
+ t3 = /* @__PURE__ */ jsx(Button, {
345
+ onClick: t1,
346
+ size: "sm",
347
+ variant: "outline",
348
+ children: t2
349
+ });
350
+ $[4] = t2;
351
+ $[5] = t3;
352
+ } else t3 = $[5];
353
+ let t4;
354
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
355
+ t4 = () => {
356
+ setExpanded([]);
357
+ };
358
+ $[6] = t4;
359
+ } else t4 = $[6];
360
+ let t5;
361
+ if ($[7] !== t) {
362
+ t5 = t("outline.collapse");
363
+ $[7] = t;
364
+ $[8] = t5;
365
+ } else t5 = $[8];
366
+ let t6;
367
+ if ($[9] !== t5) {
368
+ t6 = /* @__PURE__ */ jsx(Button, {
369
+ onClick: t4,
370
+ size: "sm",
371
+ variant: "outline",
372
+ children: t5
373
+ });
374
+ $[9] = t5;
375
+ $[10] = t6;
376
+ } else t6 = $[10];
377
+ let t7;
378
+ if ($[11] !== t3 || $[12] !== t6) {
379
+ t7 = /* @__PURE__ */ jsxs(Group, {
380
+ gap: "xs",
381
+ children: [t3, t6]
382
+ });
383
+ $[11] = t3;
384
+ $[12] = t6;
385
+ $[13] = t7;
386
+ } else t7 = $[13];
387
+ let t8;
388
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
389
+ t8 = (details) => {
390
+ setExpanded(details.expandedValue);
391
+ };
392
+ $[14] = t8;
393
+ } else t8 = $[14];
394
+ let t9;
395
+ if ($[15] !== t) {
396
+ t9 = t("outline.label");
397
+ $[15] = t;
398
+ $[16] = t9;
399
+ } else t9 = $[16];
400
+ let t10;
401
+ if ($[17] !== t9) {
402
+ t10 = /* @__PURE__ */ jsx(Label, { children: t9 });
403
+ $[17] = t9;
404
+ $[18] = t10;
405
+ } else t10 = $[18];
406
+ let t11;
407
+ if ($[19] !== t) {
408
+ t11 = /* @__PURE__ */ jsx(Tree, { children: /* @__PURE__ */ jsx(Nodes, { render: (t12) => {
409
+ const { node, nodeState } = t12;
410
+ return nodeState.isBranch ? /* @__PURE__ */ jsxs(BranchControl, { children: [
411
+ /* @__PURE__ */ jsx(BranchTrigger, { children: /* @__PURE__ */ jsx(BranchIndicator, { children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) }) }),
412
+ /* @__PURE__ */ jsx(BranchText, { children: t(`outline.${node.id}`) }),
413
+ nodeState.disabled ? /* @__PURE__ */ jsx(LockIcon, {}) : null
414
+ ] }) : /* @__PURE__ */ jsx(Item, { children: /* @__PURE__ */ jsx(ItemText, { children: t(`outline.${node.id}`) }) });
415
+ } }) });
416
+ $[19] = t;
417
+ $[20] = t11;
418
+ } else t11 = $[20];
419
+ let t12;
420
+ if ($[21] !== expanded || $[22] !== t10 || $[23] !== t11) {
421
+ t12 = /* @__PURE__ */ jsxs(Root, {
422
+ collection: OUTLINE,
423
+ expandedValue: expanded,
424
+ expandOnClick: false,
425
+ onExpandedChange: t8,
426
+ children: [t10, t11]
427
+ });
428
+ $[21] = expanded;
429
+ $[22] = t10;
430
+ $[23] = t11;
431
+ $[24] = t12;
432
+ } else t12 = $[24];
433
+ let t13;
434
+ if ($[25] !== t12 || $[26] !== t7) {
435
+ t13 = /* @__PURE__ */ jsxs(Stack, {
436
+ gap: "sm",
437
+ children: [t7, t12]
438
+ });
439
+ $[25] = t12;
440
+ $[26] = t7;
441
+ $[27] = t13;
442
+ } else t13 = $[27];
443
+ return t13;
444
+ }
445
+ const source$3 = "import { type ReactElement, useState } from \"react\";\n\nimport { ChevronRightIcon, LockIcon } from \"lucide-react\";\n\nimport { Button } from \"@stealthscale/component-actions\";\nimport { Group, Stack } from \"@stealthscale/component-layout\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { TreeCollection, TreeView } from \"@stealthscale/component-collections\";\n\ninterface Section {\n children?: Section[];\n disabled?: boolean;\n id: string;\n}\n\nconst OUTLINE = new TreeCollection<Section>({\n nodeToValue: (node): string => node.id,\n rootNode: {\n children: [\n { children: [{ id: \"summary\" }, { id: \"goals\" }], id: \"introduction\" },\n {\n children: [\n { id: \"survey\" },\n { children: [{ id: \"latency\" }, { id: \"errors\" }], id: \"results\" },\n ],\n id: \"findings\",\n },\n { children: [{ id: \"raw-data\" }], disabled: true, id: \"appendix\" },\n ],\n id: \"root\",\n },\n});\n\nexport function Outline(): ReactElement {\n const { t } = useWords(\"tree-view\");\n const [expanded, setExpanded] = useState([\"introduction\"]);\n\n return (\n <Stack gap=\"sm\">\n <Group gap=\"xs\">\n <Button\n onClick={() => {\n setExpanded(OUTLINE.getBranchValues());\n }}\n size=\"sm\"\n variant=\"outline\"\n >\n {t(\"outline.expand\")}\n </Button>\n <Button\n onClick={() => {\n setExpanded([]);\n }}\n size=\"sm\"\n variant=\"outline\"\n >\n {t(\"outline.collapse\")}\n </Button>\n </Group>\n <TreeView.Root\n collection={OUTLINE}\n expandedValue={expanded}\n expandOnClick={false}\n onExpandedChange={(details) => {\n setExpanded(details.expandedValue);\n }}\n >\n <TreeView.Label>{t(\"outline.label\")}</TreeView.Label>\n <TreeView.Tree>\n <TreeView.Nodes\n render={({ node, nodeState }: TreeView.NodeDetails<Section>) =>\n nodeState.isBranch ? (\n <TreeView.BranchControl>\n <TreeView.BranchTrigger>\n <TreeView.BranchIndicator>\n <ChevronRightIcon />\n </TreeView.BranchIndicator>\n </TreeView.BranchTrigger>\n <TreeView.BranchText>{t(`outline.${node.id}`)}</TreeView.BranchText>\n {nodeState.disabled ? <LockIcon /> : null}\n </TreeView.BranchControl>\n ) : (\n <TreeView.Item>\n <TreeView.ItemText>{t(`outline.${node.id}`)}</TreeView.ItemText>\n </TreeView.Item>\n )\n }\n />\n </TreeView.Tree>\n </TreeView.Root>\n </Stack>\n );\n}\n";
446
+ //#endregion
447
+ //#region src/tree-view/examples/permissions.example.tsx
448
+ var permissions_example_exports = /* @__PURE__ */ __exportAll({
449
+ Permissions: () => Permissions,
450
+ source: () => source$2
451
+ });
452
+ const GROUPS = {
453
+ billing: [
454
+ "view-invoices",
455
+ "download-invoices",
456
+ "change-plan"
457
+ ],
458
+ members: ["invite-members", "remove-members"],
459
+ settings: ["rename-workspace", "delete-workspace"]
460
+ };
461
+ const LEAVES = Object.values(GROUPS).flat();
462
+ const PERMISSIONS = new TreeCollection({
463
+ nodeToValue: (node) => node.id,
464
+ rootNode: {
465
+ children: Object.entries(GROUPS).map(([id, leaves]) => ({
466
+ children: leaves.map((leaf) => ({ id: leaf })),
467
+ id
468
+ })),
469
+ id: "root"
470
+ }
471
+ });
472
+ function Permissions() {
473
+ const $ = c(36);
474
+ const { t } = useWords("tree-view");
475
+ let t0;
476
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
477
+ t0 = ["view-invoices", "download-invoices"];
478
+ $[0] = t0;
479
+ } else t0 = $[0];
480
+ const [checked, setChecked] = useState(t0);
481
+ let T0;
482
+ let T1;
483
+ let t1;
484
+ let t2;
485
+ let t3;
486
+ let t4;
487
+ let t5;
488
+ let t6;
489
+ if ($[1] !== checked || $[2] !== t) {
490
+ let t7;
491
+ if ($[11] !== checked) {
492
+ t7 = (leaf) => checked.includes(leaf);
493
+ $[11] = checked;
494
+ $[12] = t7;
495
+ } else t7 = $[12];
496
+ const granted = LEAVES.filter(t7).length;
497
+ T1 = Stack;
498
+ t5 = "sm";
499
+ let t8;
500
+ let t9;
501
+ if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
502
+ t8 = ["billing", "members"];
503
+ t9 = (details) => {
504
+ setChecked(details.checkedValue);
505
+ };
506
+ $[13] = t8;
507
+ $[14] = t9;
508
+ } else {
509
+ t8 = $[13];
510
+ t9 = $[14];
511
+ }
512
+ let t10;
513
+ if ($[15] !== t) {
514
+ t10 = t("permissions.label");
515
+ $[15] = t;
516
+ $[16] = t10;
517
+ } else t10 = $[16];
518
+ let t11;
519
+ if ($[17] !== t10) {
520
+ t11 = /* @__PURE__ */ jsx(Label, { children: t10 });
521
+ $[17] = t10;
522
+ $[18] = t11;
523
+ } else t11 = $[18];
524
+ let t12;
525
+ if ($[19] !== t) {
526
+ t12 = /* @__PURE__ */ jsx(Tree, { children: /* @__PURE__ */ jsx(Nodes, { render: (t13) => {
527
+ const { node, nodeState } = t13;
528
+ const box = /* @__PURE__ */ jsx(NodeCheckbox, { children: nodeState.checked === "indeterminate" ? /* @__PURE__ */ jsx(MinusIcon, {}) : /* @__PURE__ */ jsx(CheckIcon, {}) });
529
+ return nodeState.isBranch ? /* @__PURE__ */ jsxs(BranchControl, { children: [
530
+ /* @__PURE__ */ jsx(BranchIndicator, { children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) }),
531
+ box,
532
+ /* @__PURE__ */ jsx(BranchText, { children: t(`permissions.${node.id}`) })
533
+ ] }) : /* @__PURE__ */ jsxs(Item, { children: [box, /* @__PURE__ */ jsx(ItemText, { children: t(`permissions.${node.id}`) })] });
534
+ } }) });
535
+ $[19] = t;
536
+ $[20] = t12;
537
+ } else t12 = $[20];
538
+ if ($[21] !== checked || $[22] !== t11 || $[23] !== t12) {
539
+ t6 = /* @__PURE__ */ jsxs(Root, {
540
+ checkable: true,
541
+ checkedValue: checked,
542
+ collection: PERMISSIONS,
543
+ defaultExpandedValue: t8,
544
+ onCheckedChange: t9,
545
+ children: [t11, t12]
546
+ });
547
+ $[21] = checked;
548
+ $[22] = t11;
549
+ $[23] = t12;
550
+ $[24] = t6;
551
+ } else t6 = $[24];
552
+ T0 = Text;
553
+ t1 = "output";
554
+ t2 = "sm";
555
+ t3 = "muted";
556
+ t4 = t("permissions.count", {
557
+ count: granted,
558
+ total: LEAVES.length
559
+ });
560
+ $[1] = checked;
561
+ $[2] = t;
562
+ $[3] = T0;
563
+ $[4] = T1;
564
+ $[5] = t1;
565
+ $[6] = t2;
566
+ $[7] = t3;
567
+ $[8] = t4;
568
+ $[9] = t5;
569
+ $[10] = t6;
570
+ } else {
571
+ T0 = $[3];
572
+ T1 = $[4];
573
+ t1 = $[5];
574
+ t2 = $[6];
575
+ t3 = $[7];
576
+ t4 = $[8];
577
+ t5 = $[9];
578
+ t6 = $[10];
579
+ }
580
+ let t7;
581
+ if ($[25] !== T0 || $[26] !== t1 || $[27] !== t2 || $[28] !== t3 || $[29] !== t4) {
582
+ t7 = /* @__PURE__ */ jsx(T0, {
583
+ as: t1,
584
+ size: t2,
585
+ tone: t3,
586
+ children: t4
587
+ });
588
+ $[25] = T0;
589
+ $[26] = t1;
590
+ $[27] = t2;
591
+ $[28] = t3;
592
+ $[29] = t4;
593
+ $[30] = t7;
594
+ } else t7 = $[30];
595
+ let t8;
596
+ if ($[31] !== T1 || $[32] !== t5 || $[33] !== t6 || $[34] !== t7) {
597
+ t8 = /* @__PURE__ */ jsxs(T1, {
598
+ gap: t5,
599
+ children: [t6, t7]
600
+ });
601
+ $[31] = T1;
602
+ $[32] = t5;
603
+ $[33] = t6;
604
+ $[34] = t7;
605
+ $[35] = t8;
606
+ } else t8 = $[35];
607
+ return t8;
608
+ }
609
+ const source$2 = "import { type ReactElement, useState } from \"react\";\n\nimport { CheckIcon, ChevronRightIcon, MinusIcon } from \"lucide-react\";\n\nimport { Stack } from \"@stealthscale/component-layout\";\nimport { Text } from \"@stealthscale/component-typography\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { TreeCollection, TreeView } from \"@stealthscale/component-collections\";\n\ninterface Permission {\n children?: Permission[];\n id: string;\n}\n\nconst GROUPS = {\n billing: [\"view-invoices\", \"download-invoices\", \"change-plan\"],\n members: [\"invite-members\", \"remove-members\"],\n settings: [\"rename-workspace\", \"delete-workspace\"],\n};\n\nconst LEAVES = Object.values(GROUPS).flat();\n\nconst PERMISSIONS = new TreeCollection<Permission>({\n nodeToValue: (node): string => node.id,\n rootNode: {\n children: Object.entries(GROUPS).map(([id, leaves]) => ({\n children: leaves.map((leaf) => ({ id: leaf })),\n id,\n })),\n id: \"root\",\n },\n});\n\nexport function Permissions(): ReactElement {\n const { t } = useWords(\"tree-view\");\n const [checked, setChecked] = useState([\"view-invoices\", \"download-invoices\"]);\n const granted = LEAVES.filter((leaf) => checked.includes(leaf)).length;\n\n return (\n <Stack gap=\"sm\">\n <TreeView.Root\n checkable\n checkedValue={checked}\n collection={PERMISSIONS}\n defaultExpandedValue={[\"billing\", \"members\"]}\n onCheckedChange={(details) => {\n setChecked(details.checkedValue);\n }}\n >\n <TreeView.Label>{t(\"permissions.label\")}</TreeView.Label>\n <TreeView.Tree>\n <TreeView.Nodes\n render={({ node, nodeState }: TreeView.NodeDetails<Permission>) => {\n const box = (\n <TreeView.NodeCheckbox>\n {nodeState.checked === \"indeterminate\" ? <MinusIcon /> : <CheckIcon />}\n </TreeView.NodeCheckbox>\n );\n\n return nodeState.isBranch ? (\n <TreeView.BranchControl>\n <TreeView.BranchIndicator>\n <ChevronRightIcon />\n </TreeView.BranchIndicator>\n {box}\n <TreeView.BranchText>{t(`permissions.${node.id}`)}</TreeView.BranchText>\n </TreeView.BranchControl>\n ) : (\n <TreeView.Item>\n {box}\n <TreeView.ItemText>{t(`permissions.${node.id}`)}</TreeView.ItemText>\n </TreeView.Item>\n );\n }}\n />\n </TreeView.Tree>\n </TreeView.Root>\n <Text as=\"output\" size=\"sm\" tone=\"muted\">\n {t(\"permissions.count\", { count: granted, total: LEAVES.length })}\n </Text>\n </Stack>\n );\n}\n";
610
+ //#endregion
611
+ //#region src/tree-view/examples/rename.example.tsx
612
+ var rename_example_exports = /* @__PURE__ */ __exportAll({
613
+ Rename: () => Rename,
614
+ source: () => source$1
615
+ });
616
+ const DRAFTS = new TreeCollection({
617
+ nodeToString: (node) => node.name,
618
+ nodeToValue: (node) => node.id,
619
+ rootNode: {
620
+ children: [{
621
+ children: [{
622
+ id: "brief",
623
+ name: "Brief.md"
624
+ }, {
625
+ id: "moodboard",
626
+ name: "Moodboard.png"
627
+ }],
628
+ id: "launch",
629
+ name: "Launch"
630
+ }, {
631
+ id: "notes",
632
+ name: "Notes.md"
633
+ }],
634
+ id: "root",
635
+ name: ""
636
+ }
637
+ });
638
+ function Rename() {
639
+ const $ = c(22);
640
+ const { t } = useWords("tree-view");
641
+ const [collection, setCollection] = useState(DRAFTS);
642
+ let t0;
643
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
644
+ t0 = ["launch"];
645
+ $[0] = t0;
646
+ } else t0 = $[0];
647
+ let t1;
648
+ if ($[1] !== collection) {
649
+ t1 = (t2) => {
650
+ const { indexPath, label } = t2;
651
+ const node = collection.at(indexPath);
652
+ if (node !== void 0) setCollection(collection.replace(indexPath, {
653
+ ...node,
654
+ name: label
655
+ }));
656
+ };
657
+ $[1] = collection;
658
+ $[2] = t1;
659
+ } else t1 = $[2];
660
+ let t2;
661
+ if ($[3] !== t) {
662
+ t2 = t("rename.label");
663
+ $[3] = t;
664
+ $[4] = t2;
665
+ } else t2 = $[4];
666
+ let t3;
667
+ if ($[5] !== t2) {
668
+ t3 = /* @__PURE__ */ jsx(Label, { children: t2 });
669
+ $[5] = t2;
670
+ $[6] = t3;
671
+ } else t3 = $[6];
672
+ let t4;
673
+ if ($[7] !== t) {
674
+ t4 = /* @__PURE__ */ jsx(Tree, { children: /* @__PURE__ */ jsx(Nodes, { render: (t5) => {
675
+ const { node: node_0, nodeState } = t5;
676
+ return nodeState.isBranch ? /* @__PURE__ */ jsxs(BranchControl, { children: [
677
+ /* @__PURE__ */ jsx(BranchIndicator, { children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) }),
678
+ /* @__PURE__ */ jsx(FolderIcon, {}),
679
+ /* @__PURE__ */ jsx(BranchText, { children: node_0.name }),
680
+ /* @__PURE__ */ jsx(NodeRenameInput, { label: t("rename.input") })
681
+ ] }) : /* @__PURE__ */ jsxs(Item, { children: [
682
+ /* @__PURE__ */ jsx(FileIcon, {}),
683
+ /* @__PURE__ */ jsx(ItemText, { children: node_0.name }),
684
+ /* @__PURE__ */ jsx(NodeRenameInput, { label: t("rename.input") })
685
+ ] });
686
+ } }) });
687
+ $[7] = t;
688
+ $[8] = t4;
689
+ } else t4 = $[8];
690
+ let t5;
691
+ if ($[9] !== collection || $[10] !== t1 || $[11] !== t3 || $[12] !== t4) {
692
+ t5 = /* @__PURE__ */ jsxs(Root, {
693
+ canRename: _temp$1,
694
+ collection,
695
+ defaultExpandedValue: t0,
696
+ onRenameComplete: t1,
697
+ children: [t3, t4]
698
+ });
699
+ $[9] = collection;
700
+ $[10] = t1;
701
+ $[11] = t3;
702
+ $[12] = t4;
703
+ $[13] = t5;
704
+ } else t5 = $[13];
705
+ let t6;
706
+ if ($[14] !== t) {
707
+ t6 = t("rename.hint");
708
+ $[14] = t;
709
+ $[15] = t6;
710
+ } else t6 = $[15];
711
+ let t7;
712
+ if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
713
+ t7 = /* @__PURE__ */ jsx(Kbd.Root, { children: "F2" });
714
+ $[16] = t7;
715
+ } else t7 = $[16];
716
+ let t8;
717
+ if ($[17] !== t6) {
718
+ t8 = /* @__PURE__ */ jsxs(Text, {
719
+ size: "sm",
720
+ tone: "muted",
721
+ children: [
722
+ t6,
723
+ " ",
724
+ t7
725
+ ]
726
+ });
727
+ $[17] = t6;
728
+ $[18] = t8;
729
+ } else t8 = $[18];
730
+ let t9;
731
+ if ($[19] !== t5 || $[20] !== t8) {
732
+ t9 = /* @__PURE__ */ jsxs(Stack, {
733
+ gap: "sm",
734
+ children: [t5, t8]
735
+ });
736
+ $[19] = t5;
737
+ $[20] = t8;
738
+ $[21] = t9;
739
+ } else t9 = $[21];
740
+ return t9;
741
+ }
742
+ function _temp$1() {
743
+ return true;
744
+ }
745
+ const source$1 = "import { type ReactElement, useState } from \"react\";\n\nimport { ChevronRightIcon, FileIcon, FolderIcon } from \"lucide-react\";\n\nimport { Stack } from \"@stealthscale/component-layout\";\nimport { Kbd, Text } from \"@stealthscale/component-typography\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { TreeCollection, TreeView } from \"@stealthscale/component-collections\";\n\ninterface Entry {\n children?: Entry[];\n id: string;\n name: string;\n}\n\nconst DRAFTS = new TreeCollection<Entry>({\n nodeToString: (node): string => node.name,\n nodeToValue: (node): string => node.id,\n rootNode: {\n children: [\n {\n children: [\n { id: \"brief\", name: \"Brief.md\" },\n { id: \"moodboard\", name: \"Moodboard.png\" },\n ],\n id: \"launch\",\n name: \"Launch\",\n },\n { id: \"notes\", name: \"Notes.md\" },\n ],\n id: \"root\",\n name: \"\",\n },\n});\n\nexport function Rename(): ReactElement {\n const { t } = useWords(\"tree-view\");\n const [collection, setCollection] = useState(DRAFTS);\n\n return (\n <Stack gap=\"sm\">\n <TreeView.Root\n canRename={() => true}\n collection={collection}\n defaultExpandedValue={[\"launch\"]}\n onRenameComplete={({ indexPath, label }) => {\n const node = collection.at(indexPath);\n\n if (node !== undefined)\n setCollection(collection.replace(indexPath, { ...node, name: label }));\n }}\n >\n <TreeView.Label>{t(\"rename.label\")}</TreeView.Label>\n <TreeView.Tree>\n <TreeView.Nodes\n render={({ node, nodeState }: TreeView.NodeDetails<Entry>) =>\n nodeState.isBranch ? (\n <TreeView.BranchControl>\n <TreeView.BranchIndicator>\n <ChevronRightIcon />\n </TreeView.BranchIndicator>\n <FolderIcon />\n <TreeView.BranchText>{node.name}</TreeView.BranchText>\n <TreeView.NodeRenameInput label={t(\"rename.input\")} />\n </TreeView.BranchControl>\n ) : (\n <TreeView.Item>\n <FileIcon />\n <TreeView.ItemText>{node.name}</TreeView.ItemText>\n <TreeView.NodeRenameInput label={t(\"rename.input\")} />\n </TreeView.Item>\n )\n }\n />\n </TreeView.Tree>\n </TreeView.Root>\n <Text size=\"sm\" tone=\"muted\">\n {t(\"rename.hint\")} <Kbd.Root>F2</Kbd.Root>\n </Text>\n </Stack>\n );\n}\n";
746
+ //#endregion
747
+ //#region src/tree-view/examples/search.example.tsx
748
+ var search_example_exports = /* @__PURE__ */ __exportAll({
749
+ Search: () => Search,
750
+ source: () => source
751
+ });
752
+ const DOCS = new TreeCollection({
753
+ nodeToString: (node) => node.name,
754
+ nodeToValue: (node) => node.id,
755
+ rootNode: {
756
+ children: [
757
+ {
758
+ children: [
759
+ {
760
+ id: "q3-plan",
761
+ name: "Q3 plan.md"
762
+ },
763
+ {
764
+ id: "q3-review",
765
+ name: "Q3 review.md"
766
+ },
767
+ {
768
+ id: "hiring",
769
+ name: "Hiring plan.md"
770
+ }
771
+ ],
772
+ id: "planning",
773
+ name: "Planning"
774
+ },
775
+ {
776
+ children: [{
777
+ id: "invoice-2031",
778
+ name: "Invoice 2031.pdf"
779
+ }, {
780
+ id: "invoice-2032",
781
+ name: "Invoice 2032.pdf"
782
+ }],
783
+ id: "finance",
784
+ name: "Finance"
785
+ },
786
+ {
787
+ id: "handbook",
788
+ name: "Handbook.md"
789
+ }
790
+ ],
791
+ id: "root",
792
+ name: ""
793
+ }
794
+ });
795
+ function Search() {
796
+ const $ = c(48);
797
+ const { t } = useWords("tree-view");
798
+ const [query, setQuery] = useState("");
799
+ let t0;
800
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
801
+ t0 = [];
802
+ $[0] = t0;
803
+ } else t0 = $[0];
804
+ const [expanded, setExpanded] = useState(t0);
805
+ let T0;
806
+ let T1;
807
+ let empty;
808
+ let t1;
809
+ let t2;
810
+ let t3;
811
+ let t4;
812
+ let typed;
813
+ if ($[1] !== expanded || $[2] !== query || $[3] !== t) {
814
+ typed = query.trim().toLowerCase();
815
+ const shown = typed === "" ? DOCS : DOCS.filter((node) => node.name.toLowerCase().includes(typed));
816
+ empty = shown.getNodeChildren(shown.rootNode).length === 0;
817
+ T1 = Stack;
818
+ t3 = "sm";
819
+ let t5;
820
+ if ($[12] !== t) {
821
+ t5 = t("search.field");
822
+ $[12] = t;
823
+ $[13] = t5;
824
+ } else t5 = $[13];
825
+ let t6;
826
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
827
+ t6 = /* @__PURE__ */ jsx(XIcon, {});
828
+ $[14] = t6;
829
+ } else t6 = $[14];
830
+ let t7;
831
+ if ($[15] !== t) {
832
+ t7 = t("search.clear");
833
+ $[15] = t;
834
+ $[16] = t7;
835
+ } else t7 = $[16];
836
+ let t8;
837
+ if ($[17] !== t) {
838
+ t8 = t("search.field");
839
+ $[17] = t;
840
+ $[18] = t8;
841
+ } else t8 = $[18];
842
+ let t9;
843
+ if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
844
+ t9 = /* @__PURE__ */ jsx(SearchIcon, {});
845
+ $[19] = t9;
846
+ } else t9 = $[19];
847
+ if ($[20] !== query || $[21] !== t5 || $[22] !== t7 || $[23] !== t8) {
848
+ t4 = /* @__PURE__ */ jsx(SearchInput, {
849
+ "aria-label": t5,
850
+ clearIndicator: t6,
851
+ clearLabel: t7,
852
+ onValueChange: setQuery,
853
+ placeholder: t8,
854
+ searchIndicator: t9,
855
+ value: query
856
+ });
857
+ $[20] = query;
858
+ $[21] = t5;
859
+ $[22] = t7;
860
+ $[23] = t8;
861
+ $[24] = t4;
862
+ } else t4 = $[24];
863
+ T0 = Root;
864
+ t1 = shown;
865
+ t2 = typed === "" ? expanded : shown.getBranchValues();
866
+ $[1] = expanded;
867
+ $[2] = query;
868
+ $[3] = t;
869
+ $[4] = T0;
870
+ $[5] = T1;
871
+ $[6] = empty;
872
+ $[7] = t1;
873
+ $[8] = t2;
874
+ $[9] = t3;
875
+ $[10] = t4;
876
+ $[11] = typed;
877
+ } else {
878
+ T0 = $[4];
879
+ T1 = $[5];
880
+ empty = $[6];
881
+ t1 = $[7];
882
+ t2 = $[8];
883
+ t3 = $[9];
884
+ t4 = $[10];
885
+ typed = $[11];
886
+ }
887
+ let t5;
888
+ if ($[25] !== typed) {
889
+ t5 = (details) => {
890
+ if (typed === "") setExpanded(details.expandedValue);
891
+ };
892
+ $[25] = typed;
893
+ $[26] = t5;
894
+ } else t5 = $[26];
895
+ let t6;
896
+ if ($[27] !== t) {
897
+ t6 = t("search.label");
898
+ $[27] = t;
899
+ $[28] = t6;
900
+ } else t6 = $[28];
901
+ let t7;
902
+ if ($[29] === Symbol.for("react.memo_cache_sentinel")) {
903
+ t7 = /* @__PURE__ */ jsx(Nodes, { render: _temp });
904
+ $[29] = t7;
905
+ } else t7 = $[29];
906
+ let t8;
907
+ if ($[30] !== t6) {
908
+ t8 = /* @__PURE__ */ jsx(Tree, {
909
+ "aria-label": t6,
910
+ children: t7
911
+ });
912
+ $[30] = t6;
913
+ $[31] = t8;
914
+ } else t8 = $[31];
915
+ let t9;
916
+ if ($[32] !== T0 || $[33] !== t1 || $[34] !== t2 || $[35] !== t5 || $[36] !== t8) {
917
+ t9 = /* @__PURE__ */ jsx(T0, {
918
+ collection: t1,
919
+ expandedValue: t2,
920
+ onExpandedChange: t5,
921
+ children: t8
922
+ });
923
+ $[32] = T0;
924
+ $[33] = t1;
925
+ $[34] = t2;
926
+ $[35] = t5;
927
+ $[36] = t8;
928
+ $[37] = t9;
929
+ } else t9 = $[37];
930
+ let t10;
931
+ if ($[38] !== empty || $[39] !== query || $[40] !== t) {
932
+ t10 = empty ? /* @__PURE__ */ jsx(Text, {
933
+ size: "sm",
934
+ tone: "muted",
935
+ children: t("search.empty", { query })
936
+ }) : null;
937
+ $[38] = empty;
938
+ $[39] = query;
939
+ $[40] = t;
940
+ $[41] = t10;
941
+ } else t10 = $[41];
942
+ let t11;
943
+ if ($[42] !== T1 || $[43] !== t10 || $[44] !== t3 || $[45] !== t4 || $[46] !== t9) {
944
+ t11 = /* @__PURE__ */ jsxs(T1, {
945
+ gap: t3,
946
+ children: [
947
+ t4,
948
+ t9,
949
+ t10
950
+ ]
951
+ });
952
+ $[42] = T1;
953
+ $[43] = t10;
954
+ $[44] = t3;
955
+ $[45] = t4;
956
+ $[46] = t9;
957
+ $[47] = t11;
958
+ } else t11 = $[47];
959
+ return t11;
960
+ }
961
+ function _temp(t0) {
962
+ const { node: node_0, nodeState } = t0;
963
+ return nodeState.isBranch ? /* @__PURE__ */ jsxs(BranchControl, { children: [
964
+ /* @__PURE__ */ jsx(BranchIndicator, { children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) }),
965
+ /* @__PURE__ */ jsx(FolderIcon, {}),
966
+ /* @__PURE__ */ jsx(BranchText, { children: node_0.name })
967
+ ] }) : /* @__PURE__ */ jsxs(Item, { children: [/* @__PURE__ */ jsx(FileTextIcon, {}), /* @__PURE__ */ jsx(ItemText, { children: node_0.name })] });
968
+ }
969
+ const source = "import { type ReactElement, useState } from \"react\";\n\nimport { ChevronRightIcon, FileTextIcon, FolderIcon, SearchIcon, XIcon } from \"lucide-react\";\n\nimport { SearchInput } from \"@stealthscale/component-forms\";\nimport { Stack } from \"@stealthscale/component-layout\";\nimport { Text } from \"@stealthscale/component-typography\";\nimport { useWords } from \"@stealthscale/specimen\";\n\nimport { TreeCollection, TreeView } from \"@stealthscale/component-collections\";\n\ninterface Doc {\n children?: Doc[];\n id: string;\n name: string;\n}\n\nconst DOCS = new TreeCollection<Doc>({\n nodeToString: (node): string => node.name,\n nodeToValue: (node): string => node.id,\n rootNode: {\n children: [\n {\n children: [\n { id: \"q3-plan\", name: \"Q3 plan.md\" },\n { id: \"q3-review\", name: \"Q3 review.md\" },\n { id: \"hiring\", name: \"Hiring plan.md\" },\n ],\n id: \"planning\",\n name: \"Planning\",\n },\n {\n children: [\n { id: \"invoice-2031\", name: \"Invoice 2031.pdf\" },\n { id: \"invoice-2032\", name: \"Invoice 2032.pdf\" },\n ],\n id: \"finance\",\n name: \"Finance\",\n },\n { id: \"handbook\", name: \"Handbook.md\" },\n ],\n id: \"root\",\n name: \"\",\n },\n});\n\nexport function Search(): ReactElement {\n const { t } = useWords(\"tree-view\");\n const [query, setQuery] = useState(\"\");\n const [expanded, setExpanded] = useState<string[]>([]);\n const typed = query.trim().toLowerCase();\n const shown =\n typed === \"\" ? DOCS : DOCS.filter((node) => node.name.toLowerCase().includes(typed));\n const empty = shown.getNodeChildren(shown.rootNode).length === 0;\n\n return (\n <Stack gap=\"sm\">\n <SearchInput\n aria-label={t(\"search.field\")}\n clearIndicator={<XIcon />}\n clearLabel={t(\"search.clear\")}\n onValueChange={setQuery}\n placeholder={t(\"search.field\")}\n searchIndicator={<SearchIcon />}\n value={query}\n />\n <TreeView.Root\n collection={shown}\n expandedValue={typed === \"\" ? expanded : shown.getBranchValues()}\n onExpandedChange={(details) => {\n if (typed === \"\") setExpanded(details.expandedValue);\n }}\n >\n <TreeView.Tree aria-label={t(\"search.label\")}>\n <TreeView.Nodes\n render={({ node, nodeState }: TreeView.NodeDetails<Doc>) =>\n nodeState.isBranch ? (\n <TreeView.BranchControl>\n <TreeView.BranchIndicator>\n <ChevronRightIcon />\n </TreeView.BranchIndicator>\n <FolderIcon />\n <TreeView.BranchText>{node.name}</TreeView.BranchText>\n </TreeView.BranchControl>\n ) : (\n <TreeView.Item>\n <FileTextIcon />\n <TreeView.ItemText>{node.name}</TreeView.ItemText>\n </TreeView.Item>\n )\n }\n />\n </TreeView.Tree>\n </TreeView.Root>\n {empty ? (\n <Text size=\"sm\" tone=\"muted\">\n {t(\"search.empty\", { query })}\n </Text>\n ) : null}\n </Stack>\n );\n}\n";
970
+ //#endregion
971
+ //#region src/tree-view/tree-view.specimen.tsx
972
+ /**
973
+ * Selection modes of the selection scene.
974
+ */
975
+ const MODES = ["single", "multiple"];
976
+ /**
977
+ * Selected rows per mode, so the multiple cell shows two.
978
+ */
979
+ const SELECTED = {
980
+ multiple: ["src/components/button.tsx", "src/components/card.tsx"],
981
+ single: ["src/components/card.tsx"]
982
+ };
983
+ /**
984
+ * Hand-written scene for each selection mode.
985
+ */
986
+ const selection = {
987
+ about: "tree-view.selection.about",
988
+ draw: () => /* @__PURE__ */ jsx(Matrix, {
989
+ knob: "selectionMode",
990
+ of: MODES,
991
+ children: (mode) => /* @__PURE__ */ jsx(Room, {
992
+ size: "xs",
993
+ children: /* @__PURE__ */ jsx(Explorer, {
994
+ defaultSelectedValue: SELECTED[mode],
995
+ selectionMode: mode
996
+ })
997
+ })
998
+ }),
999
+ example: explorer_example_exports,
1000
+ props: {
1001
+ defaultSelectedValue: SELECTED.single,
1002
+ selectionMode: "single"
1003
+ },
1004
+ title: "tree-view.selection.title"
1005
+ };
1006
+ /**
1007
+ * Builds a hand-written scene for one example in a sidebar's room.
1008
+ *
1009
+ * @param name - The key of the scene's words under `tree-view`.
1010
+ * @param example - The example module.
1011
+ * @param Drawn - The example's component.
1012
+ * @returns The scene.
1013
+ */
1014
+ function roomed(name, example, Drawn) {
1015
+ return {
1016
+ about: `tree-view.${name}.about`,
1017
+ draw: () => /* @__PURE__ */ jsx(Room, {
1018
+ size: "xs",
1019
+ children: /* @__PURE__ */ jsx(Drawn, {})
1020
+ }),
1021
+ example,
1022
+ title: `tree-view.${name}.title`
1023
+ };
1024
+ }
1025
+ var tree_view_specimen_default = specimen({
1026
+ about: "tree-view.about",
1027
+ id: "components/collections/tree-view",
1028
+ imports: "import { TreeCollection, TreeView } from \"@stealthscale/component-collections\";",
1029
+ scenes: [
1030
+ ...scenesOf(recipe, {
1031
+ axes: {
1032
+ selected: { direction: "row" },
1033
+ size: { direction: "row" }
1034
+ },
1035
+ draw: (props) => /* @__PURE__ */ jsx(Room, {
1036
+ size: "xs",
1037
+ children: /* @__PURE__ */ jsx(Explorer, { ...props })
1038
+ }),
1039
+ example: explorer_example_exports,
1040
+ namespace: "tree-view",
1041
+ order: [
1042
+ "size",
1043
+ "selected",
1044
+ "palette",
1045
+ "effect"
1046
+ ]
1047
+ }),
1048
+ selection,
1049
+ roomed("permissions", permissions_example_exports, Permissions),
1050
+ roomed("docs", docs_example_exports, Docs),
1051
+ roomed("lazy", lazy_example_exports, Lazy),
1052
+ roomed("search", search_example_exports, Search),
1053
+ roomed("rename", rename_example_exports, Rename),
1054
+ roomed("outline", outline_example_exports, Outline)
1055
+ ],
1056
+ title: "tree-view.title"
1057
+ });
1058
+ //#endregion
1059
+ export { tree_view_specimen_default as default, selection };