@petrarca/sonnet-playground 0.7.0 → 0.9.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.
Files changed (76) hide show
  1. package/README.md +10 -8
  2. package/dist/{PlayAdvancedComponents-ZYK66UII.js → PlayAdvancedComponents-VMUI472R.js} +2 -2
  3. package/dist/PlayCodeEditor-AMTFE5SW.js +8 -0
  4. package/dist/PlayCodedValues-G2EVIVMO.js +9 -0
  5. package/dist/{PlayCoreComponents-YTEAS3GL.js → PlayCoreComponents-EQ2BMY2S.js} +2 -2
  6. package/dist/{PlayDataComponents-W44OITT5.js → PlayDataComponents-W2KQHOI7.js} +2 -2
  7. package/dist/PlayFhirQuestionnaire-TO35Q7CP.js +8 -0
  8. package/dist/{PlayFormWidgets-6JYFRTAL.js → PlayFormWidgets-HP3VF2LK.js} +2 -2
  9. package/dist/PlayForms-4CQNEBLS.js +7 -0
  10. package/dist/PlayGraph-25ZKQAQR.js +7 -0
  11. package/dist/PlayGraph-25ZKQAQR.js.map +1 -0
  12. package/dist/PlayMarkdownViewer-X6AIFO2U.js +8 -0
  13. package/dist/PlayMarkdownViewer-X6AIFO2U.js.map +1 -0
  14. package/dist/PlayQuestionnaireDesigner-IR7TKSOT.js +9 -0
  15. package/dist/PlayQuestionnaireDesigner-IR7TKSOT.js.map +1 -0
  16. package/dist/PlaySchemaDesigner-ZQBA7AYO.js +8 -0
  17. package/dist/PlaySchemaDesigner-ZQBA7AYO.js.map +1 -0
  18. package/dist/{PlayShellApi-5O6VYR2X.js → PlayShellApi-MMCQ2AKK.js} +2 -2
  19. package/dist/PlayShellApi-MMCQ2AKK.js.map +1 -0
  20. package/dist/chunk-3FYM6B3E.js +1163 -0
  21. package/dist/chunk-3FYM6B3E.js.map +1 -0
  22. package/dist/{chunk-CQ6PGFRV.js → chunk-3RZHYZRL.js} +57 -1
  23. package/dist/chunk-3RZHYZRL.js.map +1 -0
  24. package/dist/chunk-7IMCPUSI.js +100 -0
  25. package/dist/chunk-7IMCPUSI.js.map +1 -0
  26. package/dist/{chunk-2XMWOZ5O.js → chunk-EPCUUTBZ.js} +48 -41
  27. package/dist/chunk-EPCUUTBZ.js.map +1 -0
  28. package/dist/{chunk-I2FLG6ZD.js → chunk-LDCNLHO2.js} +195 -18
  29. package/dist/chunk-LDCNLHO2.js.map +1 -0
  30. package/dist/chunk-LVV32F7G.js +104 -0
  31. package/dist/chunk-LVV32F7G.js.map +1 -0
  32. package/dist/chunk-OUL3DN2E.js +510 -0
  33. package/dist/chunk-OUL3DN2E.js.map +1 -0
  34. package/dist/chunk-QKFQI4VX.js +83 -0
  35. package/dist/chunk-QKFQI4VX.js.map +1 -0
  36. package/dist/{chunk-6WI3N7JI.js → chunk-RGBSHXS5.js} +145 -4
  37. package/dist/chunk-RGBSHXS5.js.map +1 -0
  38. package/dist/{chunk-UB7462QG.js → chunk-RLJI5VMP.js} +72 -1
  39. package/dist/chunk-RLJI5VMP.js.map +1 -0
  40. package/dist/chunk-VGAS5Z6X.js +543 -0
  41. package/dist/chunk-VGAS5Z6X.js.map +1 -0
  42. package/dist/chunk-VKZ2RJFL.js +647 -0
  43. package/dist/chunk-VKZ2RJFL.js.map +1 -0
  44. package/dist/chunk-WR74TMW4.js +219 -0
  45. package/dist/chunk-WR74TMW4.js.map +1 -0
  46. package/dist/{chunk-E5X7GVLU.js → chunk-XNDD4UN4.js} +2 -2
  47. package/dist/chunk-XNDD4UN4.js.map +1 -0
  48. package/dist/chunk-YTGQRDD2.js +343 -0
  49. package/dist/chunk-YTGQRDD2.js.map +1 -0
  50. package/dist/index.d.ts +13 -10
  51. package/dist/index.js +72 -11
  52. package/dist/index.js.map +1 -1
  53. package/dist/pages/index.d.ts +56 -20
  54. package/dist/pages/index.js +39 -17
  55. package/package.json +15 -14
  56. package/dist/PlayForms-L532W3JL.js +0 -7
  57. package/dist/PlayGraph-M4KQSFI7.js +0 -7
  58. package/dist/PlaySchemaDesigner-S4DBB53G.js +0 -7
  59. package/dist/chunk-2XMWOZ5O.js.map +0 -1
  60. package/dist/chunk-4Y4JFKAK.js +0 -240
  61. package/dist/chunk-4Y4JFKAK.js.map +0 -1
  62. package/dist/chunk-6WI3N7JI.js.map +0 -1
  63. package/dist/chunk-CQ6PGFRV.js.map +0 -1
  64. package/dist/chunk-E5X7GVLU.js.map +0 -1
  65. package/dist/chunk-I2FLG6ZD.js.map +0 -1
  66. package/dist/chunk-O2QMWJZI.js +0 -881
  67. package/dist/chunk-O2QMWJZI.js.map +0 -1
  68. package/dist/chunk-UB7462QG.js.map +0 -1
  69. /package/dist/{PlayAdvancedComponents-ZYK66UII.js.map → PlayAdvancedComponents-VMUI472R.js.map} +0 -0
  70. /package/dist/{PlayCoreComponents-YTEAS3GL.js.map → PlayCodeEditor-AMTFE5SW.js.map} +0 -0
  71. /package/dist/{PlayDataComponents-W44OITT5.js.map → PlayCodedValues-G2EVIVMO.js.map} +0 -0
  72. /package/dist/{PlayFormWidgets-6JYFRTAL.js.map → PlayCoreComponents-EQ2BMY2S.js.map} +0 -0
  73. /package/dist/{PlayForms-L532W3JL.js.map → PlayDataComponents-W2KQHOI7.js.map} +0 -0
  74. /package/dist/{PlayGraph-M4KQSFI7.js.map → PlayFhirQuestionnaire-TO35Q7CP.js.map} +0 -0
  75. /package/dist/{PlaySchemaDesigner-S4DBB53G.js.map → PlayFormWidgets-HP3VF2LK.js.map} +0 -0
  76. /package/dist/{PlayShellApi-5O6VYR2X.js.map → PlayForms-4CQNEBLS.js.map} +0 -0
@@ -0,0 +1,343 @@
1
+ import {
2
+ PlaygroundSection
3
+ } from "./chunk-C2EZ2ECG.js";
4
+
5
+ // src/pages/PlayAdvancedComponents.tsx
6
+ import { useState as useState2 } from "react";
7
+ import {
8
+ TreeView as TreeView2,
9
+ Button,
10
+ Separator,
11
+ Stepper,
12
+ StepperContent,
13
+ StepperDescription,
14
+ StepperIndicator,
15
+ StepperItem,
16
+ StepperList,
17
+ StepperNext,
18
+ StepperPrev,
19
+ StepperSeparator,
20
+ StepperTitle,
21
+ StepperTrigger
22
+ } from "@petrarca/sonnet-ui";
23
+ import { useTreeExpansion } from "@petrarca/sonnet-core/hooks";
24
+
25
+ // src/pages/TreeLargeLevelsDemo.tsx
26
+ import { useMemo, useState } from "react";
27
+ import { TreeView } from "@petrarca/sonnet-ui";
28
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
29
+ var PRODUCTS = 5e3;
30
+ var NODES = [
31
+ {
32
+ id: "product",
33
+ data: { label: `product (${PRODUCTS})` },
34
+ hasChildren: true,
35
+ children: Array.from({ length: PRODUCTS }, (_, i) => ({
36
+ id: `product-${i}`,
37
+ data: { label: `product-${String(i).padStart(4, "0")}` },
38
+ hasChildren: false
39
+ }))
40
+ },
41
+ {
42
+ id: "source",
43
+ data: { label: "source (3)" },
44
+ hasChildren: true,
45
+ children: ["billing", "portal", "search"].map((name) => ({
46
+ id: `source-${name}`,
47
+ data: { label: name },
48
+ hasChildren: false
49
+ }))
50
+ }
51
+ ];
52
+ function TreeLargeLevelsDemo() {
53
+ const [virtualize, setVirtualize] = useState(true);
54
+ const [expandedIds, setExpandedIds] = useState(/* @__PURE__ */ new Set(["product"]));
55
+ const [activeId, setActiveId] = useState();
56
+ const [rendered, setRendered] = useState(0);
57
+ const countRef = useMemo(
58
+ () => (el) => {
59
+ if (!el) return;
60
+ const observer = new MutationObserver(
61
+ () => setRendered(el.querySelectorAll('[role="treeitem"]').length)
62
+ );
63
+ observer.observe(el, { childList: true, subtree: true });
64
+ setRendered(el.querySelectorAll('[role="treeitem"]').length);
65
+ },
66
+ []
67
+ );
68
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
69
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
70
+ /* @__PURE__ */ jsx(
71
+ "input",
72
+ {
73
+ type: "checkbox",
74
+ checked: virtualize,
75
+ onChange: (e) => setVirtualize(e.target.checked)
76
+ }
77
+ ),
78
+ "virtualize"
79
+ ] }),
80
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
81
+ 'Click a row, then type a name -- "product-4321" -- to jump to it; the parent stays pinned at the top, a click away; Home/End. Rows in the DOM:',
82
+ " ",
83
+ /* @__PURE__ */ jsx("span", { className: "font-mono", children: rendered }),
84
+ activeId && /* @__PURE__ */ jsxs(Fragment, { children: [
85
+ " ",
86
+ "-- open: ",
87
+ /* @__PURE__ */ jsx("span", { className: "font-mono", children: activeId })
88
+ ] })
89
+ ] }),
90
+ /* @__PURE__ */ jsx(
91
+ "div",
92
+ {
93
+ ref: countRef,
94
+ className: "h-80 max-w-sm overflow-y-auto rounded-md border p-1",
95
+ children: /* @__PURE__ */ jsx(
96
+ TreeView,
97
+ {
98
+ nodes: NODES,
99
+ expandedIds,
100
+ onExpand: (id) => setExpandedIds((s) => /* @__PURE__ */ new Set([...s, id])),
101
+ onCollapse: (id) => setExpandedIds((s) => new Set([...s].filter((x) => x !== id))),
102
+ onNodeClick: (node) => setActiveId(node.id),
103
+ activeId,
104
+ virtualize,
105
+ getTypeAheadLabel: (node) => node.data.label,
106
+ stickyParents: true,
107
+ label: "Products",
108
+ renderNode: (node) => /* @__PURE__ */ jsx("span", { className: "truncate", children: node.data.label })
109
+ },
110
+ String(virtualize)
111
+ )
112
+ }
113
+ )
114
+ ] });
115
+ }
116
+
117
+ // src/pages/PlayAdvancedComponents.tsx
118
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
119
+ function PlayAdvancedComponents() {
120
+ return /* @__PURE__ */ jsxs2("div", { className: "space-y-6", children: [
121
+ /* @__PURE__ */ jsxs2("div", { children: [
122
+ /* @__PURE__ */ jsx2("h1", { children: "Advanced Components" }),
123
+ /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground mt-1", children: "Multi-step workflows and hierarchical data structures." })
124
+ ] }),
125
+ /* @__PURE__ */ jsxs2("div", { className: "space-y-6", children: [
126
+ /* @__PURE__ */ jsx2(
127
+ PlaygroundSection,
128
+ {
129
+ title: "Stepper",
130
+ description: "Dice UI Stepper \u2014 horizontal, controlled via built-in Prev/Next or external state.",
131
+ variant: "card",
132
+ children: /* @__PURE__ */ jsxs2("div", { className: "space-y-6", children: [
133
+ /* @__PURE__ */ jsxs2("div", { children: [
134
+ /* @__PURE__ */ jsx2("h4", { className: "mb-4", children: "Interactive (built-in navigation)" }),
135
+ /* @__PURE__ */ jsxs2(Stepper, { defaultValue: "step-1", className: "max-w-lg", children: [
136
+ /* @__PURE__ */ jsx2(StepperList, { className: "gap-2", children: ["step-1", "step-2", "step-3"].map((value, i) => /* @__PURE__ */ jsxs2(StepperItem, { value, children: [
137
+ /* @__PURE__ */ jsxs2(StepperTrigger, { children: [
138
+ /* @__PURE__ */ jsx2(StepperIndicator, {}),
139
+ /* @__PURE__ */ jsxs2("div", { className: "flex flex-col min-w-16", children: [
140
+ /* @__PURE__ */ jsxs2(StepperTitle, { children: [
141
+ "Step ",
142
+ i + 1
143
+ ] }),
144
+ /* @__PURE__ */ jsx2(StepperDescription, { children: "Description" })
145
+ ] })
146
+ ] }),
147
+ /* @__PURE__ */ jsx2(StepperSeparator, {})
148
+ ] }, value)) }),
149
+ /* @__PURE__ */ jsx2(StepperContent, { value: "step-1", children: /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground", children: "Content for step 1." }) }),
150
+ /* @__PURE__ */ jsx2(StepperContent, { value: "step-2", children: /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground", children: "Content for step 2." }) }),
151
+ /* @__PURE__ */ jsx2(StepperContent, { value: "step-3", children: /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground", children: "Content for step 3." }) }),
152
+ /* @__PURE__ */ jsxs2("div", { className: "flex justify-between max-w-lg", children: [
153
+ /* @__PURE__ */ jsx2(StepperPrev, { asChild: true, children: /* @__PURE__ */ jsx2(Button, { variant: "outline", size: "sm", children: "Back" }) }),
154
+ /* @__PURE__ */ jsx2(StepperNext, { asChild: true, children: /* @__PURE__ */ jsx2(Button, { size: "sm", children: "Next" }) })
155
+ ] })
156
+ ] })
157
+ ] }),
158
+ /* @__PURE__ */ jsx2(Separator, {}),
159
+ /* @__PURE__ */ jsxs2("div", { children: [
160
+ /* @__PURE__ */ jsx2("h4", { className: "mb-4", children: "Non-interactive (controlled)" }),
161
+ /* @__PURE__ */ jsx2(StepperControlled, {})
162
+ ] })
163
+ ] })
164
+ }
165
+ ),
166
+ /* @__PURE__ */ jsx2(
167
+ PlaygroundSection,
168
+ {
169
+ title: "TreeView",
170
+ description: "Generic accessible tree component with expand/collapse, keyboard navigation (ArrowUp/Down/Left/Right, Enter/Space), and optional row selection.",
171
+ variant: "card",
172
+ children: /* @__PURE__ */ jsx2(TreeViewDemo, {})
173
+ }
174
+ ),
175
+ /* @__PURE__ */ jsx2(
176
+ PlaygroundSection,
177
+ {
178
+ title: "TreeView -- a large level",
179
+ description: "5,000 children under one node. With virtualize, only the rows in view are in the DOM; the tree scrolls itself in a box of bounded height, and focus and the open node follow rows out of view. Typing a name jumps to it (type-to-find).",
180
+ variant: "card",
181
+ children: /* @__PURE__ */ jsx2(TreeLargeLevelsDemo, {})
182
+ }
183
+ )
184
+ ] })
185
+ ] });
186
+ }
187
+ var CONTROLLED_STEPS = [
188
+ { value: "account", title: "Account", description: "Your details" },
189
+ { value: "profile", title: "Profile", description: "About you" },
190
+ { value: "review", title: "Review", description: "Confirm" }
191
+ ];
192
+ function StepperControlled() {
193
+ const [step, setStep] = useState2("account");
194
+ return /* @__PURE__ */ jsxs2(
195
+ Stepper,
196
+ {
197
+ value: step,
198
+ onValueChange: setStep,
199
+ nonInteractive: true,
200
+ className: "max-w-lg",
201
+ children: [
202
+ /* @__PURE__ */ jsx2(StepperList, { className: "gap-2", children: CONTROLLED_STEPS.map((s) => /* @__PURE__ */ jsxs2(StepperItem, { value: s.value, children: [
203
+ /* @__PURE__ */ jsxs2(StepperTrigger, { children: [
204
+ /* @__PURE__ */ jsx2(StepperIndicator, {}),
205
+ /* @__PURE__ */ jsxs2("div", { className: "flex flex-col min-w-16", children: [
206
+ /* @__PURE__ */ jsx2(StepperTitle, { children: s.title }),
207
+ /* @__PURE__ */ jsx2(StepperDescription, { children: s.description })
208
+ ] })
209
+ ] }),
210
+ /* @__PURE__ */ jsx2(StepperSeparator, {})
211
+ ] }, s.value)) }),
212
+ CONTROLLED_STEPS.map((s) => /* @__PURE__ */ jsx2(StepperContent, { value: s.value, children: /* @__PURE__ */ jsxs2("p", { className: "text-sm text-muted-foreground", children: [
213
+ "Content for ",
214
+ s.title,
215
+ "."
216
+ ] }) }, s.value)),
217
+ /* @__PURE__ */ jsxs2("div", { className: "flex justify-between max-w-lg", children: [
218
+ /* @__PURE__ */ jsx2(
219
+ Button,
220
+ {
221
+ variant: "outline",
222
+ size: "sm",
223
+ disabled: step === CONTROLLED_STEPS[0].value,
224
+ onClick: () => {
225
+ const i = CONTROLLED_STEPS.findIndex((s) => s.value === step);
226
+ if (i > 0) setStep(CONTROLLED_STEPS[i - 1].value);
227
+ },
228
+ children: "Back"
229
+ }
230
+ ),
231
+ /* @__PURE__ */ jsx2(
232
+ Button,
233
+ {
234
+ size: "sm",
235
+ disabled: step === CONTROLLED_STEPS[CONTROLLED_STEPS.length - 1].value,
236
+ onClick: () => {
237
+ const i = CONTROLLED_STEPS.findIndex((s) => s.value === step);
238
+ if (i < CONTROLLED_STEPS.length - 1)
239
+ setStep(CONTROLLED_STEPS[i + 1].value);
240
+ },
241
+ children: "Next"
242
+ }
243
+ )
244
+ ] })
245
+ ]
246
+ }
247
+ );
248
+ }
249
+ var TREE_NODES = [
250
+ {
251
+ id: "fruits",
252
+ data: { label: "Fruits" },
253
+ hasChildren: true,
254
+ children: [
255
+ {
256
+ id: "citrus",
257
+ data: { label: "Citrus" },
258
+ hasChildren: true,
259
+ children: [
260
+ { id: "lemon", data: { label: "Lemon" }, hasChildren: false },
261
+ { id: "orange", data: { label: "Orange" }, hasChildren: false }
262
+ ]
263
+ },
264
+ { id: "apple", data: { label: "Apple" }, hasChildren: false },
265
+ { id: "banana", data: { label: "Banana" }, hasChildren: false }
266
+ ]
267
+ },
268
+ {
269
+ id: "vegetables",
270
+ data: { label: "Vegetables" },
271
+ hasChildren: true,
272
+ children: [
273
+ { id: "carrot", data: { label: "Carrot" }, hasChildren: false },
274
+ { id: "broccoli", data: { label: "Broccoli" }, hasChildren: false }
275
+ ]
276
+ },
277
+ {
278
+ id: "grains",
279
+ data: { label: "Grains" },
280
+ hasChildren: false
281
+ }
282
+ ];
283
+ function TreeViewDemo() {
284
+ const { expandedIds, onExpand, onCollapse } = useTreeExpansion();
285
+ const [selectedIds, setSelectedIds] = useState2(/* @__PURE__ */ new Set());
286
+ const [lastClicked, setLastClicked] = useState2(null);
287
+ const handleSelectionChange = (id, selected) => setSelectedIds((prev) => {
288
+ const next = new Set(prev);
289
+ if (selected) next.add(id);
290
+ else next.delete(id);
291
+ return next;
292
+ });
293
+ return /* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-8", children: [
294
+ /* @__PURE__ */ jsxs2("div", { children: [
295
+ /* @__PURE__ */ jsx2("h4", { className: "mb-3", children: "Default (click to activate)" }),
296
+ /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground mb-3", children: "Keyboard: ArrowUp/Down to move, ArrowRight to expand, ArrowLeft to collapse or go to parent, Enter/Space to activate." }),
297
+ /* @__PURE__ */ jsx2(
298
+ TreeView2,
299
+ {
300
+ nodes: TREE_NODES,
301
+ expandedIds,
302
+ onExpand,
303
+ onCollapse,
304
+ onNodeClick: (node) => setLastClicked(node.id),
305
+ onNodeActivate: (node) => setLastClicked(node.id),
306
+ renderNode: (node) => /* @__PURE__ */ jsx2("span", { className: "text-sm", children: node.data.label }),
307
+ className: "max-w-xs"
308
+ }
309
+ ),
310
+ lastClicked && /* @__PURE__ */ jsxs2("p", { className: "mt-3 text-xs text-muted-foreground", children: [
311
+ "Last activated: ",
312
+ /* @__PURE__ */ jsx2("span", { className: "font-mono", children: lastClicked })
313
+ ] })
314
+ ] }),
315
+ /* @__PURE__ */ jsxs2("div", { children: [
316
+ /* @__PURE__ */ jsx2("h4", { className: "mb-3", children: "With row selection" }),
317
+ /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground mb-3", children: "Checkboxes appear when onSelectionChange is provided. State is independent of expand/collapse." }),
318
+ /* @__PURE__ */ jsx2(
319
+ TreeView2,
320
+ {
321
+ nodes: TREE_NODES,
322
+ expandedIds,
323
+ onExpand,
324
+ onCollapse,
325
+ selectedIds,
326
+ onSelectionChange: handleSelectionChange,
327
+ renderNode: (node) => /* @__PURE__ */ jsx2("span", { className: "text-sm", children: node.data.label }),
328
+ className: "max-w-xs"
329
+ }
330
+ ),
331
+ selectedIds.size > 0 && /* @__PURE__ */ jsxs2("p", { className: "mt-3 text-xs text-muted-foreground", children: [
332
+ "Selected:",
333
+ " ",
334
+ /* @__PURE__ */ jsx2("span", { className: "font-mono", children: [...selectedIds].join(", ") })
335
+ ] })
336
+ ] })
337
+ ] });
338
+ }
339
+
340
+ export {
341
+ PlayAdvancedComponents
342
+ };
343
+ //# sourceMappingURL=chunk-YTGQRDD2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pages/PlayAdvancedComponents.tsx","../src/pages/TreeLargeLevelsDemo.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport {\n TreeView,\n type TreeNode,\n Button,\n Separator,\n Stepper,\n StepperContent,\n StepperDescription,\n StepperIndicator,\n StepperItem,\n StepperList,\n StepperNext,\n StepperPrev,\n StepperSeparator,\n StepperTitle,\n StepperTrigger,\n} from \"@petrarca/sonnet-ui\";\nimport { useTreeExpansion } from \"@petrarca/sonnet-core/hooks\";\nimport { PlaygroundSection } from \"../PlaygroundSection\";\nimport { TreeLargeLevelsDemo } from \"./TreeLargeLevelsDemo\";\n\n/**\n * PlayAdvancedComponents — Stepper and TreeView demos.\n *\n * Split from PlayCoreComponents to keep files manageable.\n */\nexport default function PlayAdvancedComponents() {\n return (\n <div className=\"space-y-6\">\n <div>\n <h1>Advanced Components</h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n Multi-step workflows and hierarchical data structures.\n </p>\n </div>\n\n <div className=\"space-y-6\">\n {/* Stepper */}\n <PlaygroundSection\n title=\"Stepper\"\n description=\"Dice UI Stepper — horizontal, controlled via built-in Prev/Next or external state.\"\n variant=\"card\"\n >\n <div className=\"space-y-6\">\n {/* Interactive — uses built-in StepperPrev / StepperNext */}\n <div>\n <h4 className=\"mb-4\">Interactive (built-in navigation)</h4>\n <Stepper defaultValue=\"step-1\" className=\"max-w-lg\">\n <StepperList className=\"gap-2\">\n {[\"step-1\", \"step-2\", \"step-3\"].map((value, i) => (\n <StepperItem key={value} value={value}>\n <StepperTrigger>\n <StepperIndicator />\n <div className=\"flex flex-col min-w-16\">\n <StepperTitle>Step {i + 1}</StepperTitle>\n <StepperDescription>Description</StepperDescription>\n </div>\n </StepperTrigger>\n <StepperSeparator />\n </StepperItem>\n ))}\n </StepperList>\n <StepperContent value=\"step-1\">\n <p className=\"text-sm text-muted-foreground\">\n Content for step 1.\n </p>\n </StepperContent>\n <StepperContent value=\"step-2\">\n <p className=\"text-sm text-muted-foreground\">\n Content for step 2.\n </p>\n </StepperContent>\n <StepperContent value=\"step-3\">\n <p className=\"text-sm text-muted-foreground\">\n Content for step 3.\n </p>\n </StepperContent>\n <div className=\"flex justify-between max-w-lg\">\n <StepperPrev asChild>\n <Button variant=\"outline\" size=\"sm\">\n Back\n </Button>\n </StepperPrev>\n <StepperNext asChild>\n <Button size=\"sm\">Next</Button>\n </StepperNext>\n </div>\n </Stepper>\n </div>\n\n <Separator />\n\n {/* Non-interactive — controlled externally */}\n <div>\n <h4 className=\"mb-4\">Non-interactive (controlled)</h4>\n <StepperControlled />\n </div>\n </div>\n </PlaygroundSection>\n\n {/* TreeView */}\n <PlaygroundSection\n title=\"TreeView\"\n description=\"Generic accessible tree component with expand/collapse, keyboard navigation (ArrowUp/Down/Left/Right, Enter/Space), and optional row selection.\"\n variant=\"card\"\n >\n <TreeViewDemo />\n </PlaygroundSection>\n\n {/* TreeView on a large level */}\n <PlaygroundSection\n title=\"TreeView -- a large level\"\n description=\"5,000 children under one node. With virtualize, only the rows in view are in the DOM; the tree scrolls itself in a box of bounded height, and focus and the open node follow rows out of view. Typing a name jumps to it (type-to-find).\"\n variant=\"card\"\n >\n <TreeLargeLevelsDemo />\n </PlaygroundSection>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Stepper — controlled demo\n// ---------------------------------------------------------------------------\n\nconst CONTROLLED_STEPS = [\n { value: \"account\", title: \"Account\", description: \"Your details\" },\n { value: \"profile\", title: \"Profile\", description: \"About you\" },\n { value: \"review\", title: \"Review\", description: \"Confirm\" },\n];\n\nfunction StepperControlled() {\n const [step, setStep] = useState(\"account\");\n return (\n <Stepper\n value={step}\n onValueChange={setStep}\n nonInteractive\n className=\"max-w-lg\"\n >\n <StepperList className=\"gap-2\">\n {CONTROLLED_STEPS.map((s) => (\n <StepperItem key={s.value} value={s.value}>\n <StepperTrigger>\n <StepperIndicator />\n <div className=\"flex flex-col min-w-16\">\n <StepperTitle>{s.title}</StepperTitle>\n <StepperDescription>{s.description}</StepperDescription>\n </div>\n </StepperTrigger>\n <StepperSeparator />\n </StepperItem>\n ))}\n </StepperList>\n {CONTROLLED_STEPS.map((s) => (\n <StepperContent key={s.value} value={s.value}>\n <p className=\"text-sm text-muted-foreground\">\n Content for {s.title}.\n </p>\n </StepperContent>\n ))}\n <div className=\"flex justify-between max-w-lg\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={step === CONTROLLED_STEPS[0].value}\n onClick={() => {\n const i = CONTROLLED_STEPS.findIndex((s) => s.value === step);\n if (i > 0) setStep(CONTROLLED_STEPS[i - 1].value);\n }}\n >\n Back\n </Button>\n <Button\n size=\"sm\"\n disabled={\n step === CONTROLLED_STEPS[CONTROLLED_STEPS.length - 1].value\n }\n onClick={() => {\n const i = CONTROLLED_STEPS.findIndex((s) => s.value === step);\n if (i < CONTROLLED_STEPS.length - 1)\n setStep(CONTROLLED_STEPS[i + 1].value);\n }}\n >\n Next\n </Button>\n </div>\n </Stepper>\n );\n}\n\n// ---------------------------------------------------------------------------\n// TreeView demo\n// ---------------------------------------------------------------------------\n\ninterface DemoData extends Record<string, unknown> {\n label: string;\n}\n\nconst TREE_NODES: TreeNode<DemoData>[] = [\n {\n id: \"fruits\",\n data: { label: \"Fruits\" },\n hasChildren: true,\n children: [\n {\n id: \"citrus\",\n data: { label: \"Citrus\" },\n hasChildren: true,\n children: [\n { id: \"lemon\", data: { label: \"Lemon\" }, hasChildren: false },\n { id: \"orange\", data: { label: \"Orange\" }, hasChildren: false },\n ],\n },\n { id: \"apple\", data: { label: \"Apple\" }, hasChildren: false },\n { id: \"banana\", data: { label: \"Banana\" }, hasChildren: false },\n ],\n },\n {\n id: \"vegetables\",\n data: { label: \"Vegetables\" },\n hasChildren: true,\n children: [\n { id: \"carrot\", data: { label: \"Carrot\" }, hasChildren: false },\n { id: \"broccoli\", data: { label: \"Broccoli\" }, hasChildren: false },\n ],\n },\n {\n id: \"grains\",\n data: { label: \"Grains\" },\n hasChildren: false,\n },\n];\n\nfunction TreeViewDemo() {\n const { expandedIds, onExpand, onCollapse } = useTreeExpansion();\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n const [lastClicked, setLastClicked] = useState<string | null>(null);\n\n const handleSelectionChange = (id: string, selected: boolean) =>\n setSelectedIds((prev) => {\n const next = new Set(prev);\n if (selected) next.add(id);\n else next.delete(id);\n return next;\n });\n\n return (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-8\">\n {/* Without selection */}\n <div>\n <h4 className=\"mb-3\">Default (click to activate)</h4>\n <p className=\"text-sm text-muted-foreground mb-3\">\n Keyboard: ArrowUp/Down to move, ArrowRight to expand, ArrowLeft to\n collapse or go to parent, Enter/Space to activate.\n </p>\n <TreeView<DemoData>\n nodes={TREE_NODES}\n expandedIds={expandedIds}\n onExpand={onExpand}\n onCollapse={onCollapse}\n onNodeClick={(node) => setLastClicked(node.id)}\n onNodeActivate={(node) => setLastClicked(node.id)}\n renderNode={(node) => (\n <span className=\"text-sm\">{node.data.label}</span>\n )}\n className=\"max-w-xs\"\n />\n {lastClicked && (\n <p className=\"mt-3 text-xs text-muted-foreground\">\n Last activated: <span className=\"font-mono\">{lastClicked}</span>\n </p>\n )}\n </div>\n\n {/* With row selection */}\n <div>\n <h4 className=\"mb-3\">With row selection</h4>\n <p className=\"text-sm text-muted-foreground mb-3\">\n Checkboxes appear when onSelectionChange is provided. State is\n independent of expand/collapse.\n </p>\n <TreeView<DemoData>\n nodes={TREE_NODES}\n expandedIds={expandedIds}\n onExpand={onExpand}\n onCollapse={onCollapse}\n selectedIds={selectedIds}\n onSelectionChange={handleSelectionChange}\n renderNode={(node) => (\n <span className=\"text-sm\">{node.data.label}</span>\n )}\n className=\"max-w-xs\"\n />\n {selectedIds.size > 0 && (\n <p className=\"mt-3 text-xs text-muted-foreground\">\n Selected:{\" \"}\n <span className=\"font-mono\">{[...selectedIds].join(\", \")}</span>\n </p>\n )}\n </div>\n </div>\n );\n}\n","/**\n * TreeView on a large level: an entity type with 5,000 products under one node,\n * in a box of fixed height -- with virtualize (only the rows in view are in the\n * DOM) or without, to compare. A click opens a node (activeId); the arrow keys\n * move through rows out of view; typing a name (\"product-4321\") jumps to it;\n * scrolled deep, the parent stays pinned at the top (stickyParents), one click\n * away; Home and End go to the first and the last row.\n */\nimport React, { useMemo, useState } from \"react\";\nimport { TreeView, type TreeNode } from \"@petrarca/sonnet-ui\";\n\ninterface Item {\n label: string;\n}\n\nconst PRODUCTS = 5000;\n\nconst NODES: TreeNode<Item>[] = [\n {\n id: \"product\",\n data: { label: `product (${PRODUCTS})` },\n hasChildren: true,\n children: Array.from({ length: PRODUCTS }, (_, i) => ({\n id: `product-${i}`,\n data: { label: `product-${String(i).padStart(4, \"0\")}` },\n hasChildren: false,\n })),\n },\n {\n id: \"source\",\n data: { label: \"source (3)\" },\n hasChildren: true,\n children: [\"billing\", \"portal\", \"search\"].map((name) => ({\n id: `source-${name}`,\n data: { label: name },\n hasChildren: false,\n })),\n },\n];\n\nexport function TreeLargeLevelsDemo(): React.ReactElement {\n const [virtualize, setVirtualize] = useState(true);\n const [expandedIds, setExpandedIds] = useState(new Set([\"product\"]));\n const [activeId, setActiveId] = useState<string>();\n // How many rows the DOM holds, to see what virtualize saves.\n const [rendered, setRendered] = useState(0);\n const countRef = useMemo(\n () => (el: HTMLDivElement | null) => {\n if (!el) return;\n const observer = new MutationObserver(() =>\n setRendered(el.querySelectorAll('[role=\"treeitem\"]').length),\n );\n observer.observe(el, { childList: true, subtree: true });\n setRendered(el.querySelectorAll('[role=\"treeitem\"]').length);\n },\n [],\n );\n\n return (\n <div className=\"space-y-3\">\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={virtualize}\n onChange={(e) => setVirtualize(e.target.checked)}\n />\n virtualize\n </label>\n <p className=\"text-xs text-muted-foreground\">\n Click a row, then type a name -- \"product-4321\" -- to jump to it; the\n parent stays pinned at the top, a click away; Home/End. Rows in the DOM:{\" \"}\n <span className=\"font-mono\">{rendered}</span>\n {activeId && (\n <>\n {\" \"}\n -- open: <span className=\"font-mono\">{activeId}</span>\n </>\n )}\n </p>\n <div\n ref={countRef}\n className=\"h-80 max-w-sm overflow-y-auto rounded-md border p-1\"\n >\n <TreeView<Item>\n key={String(virtualize)}\n nodes={NODES}\n expandedIds={expandedIds}\n onExpand={(id) => setExpandedIds((s) => new Set([...s, id]))}\n onCollapse={(id) =>\n setExpandedIds((s) => new Set([...s].filter((x) => x !== id)))\n }\n onNodeClick={(node) => setActiveId(node.id)}\n activeId={activeId}\n virtualize={virtualize}\n getTypeAheadLabel={(node) => node.data.label}\n stickyParents\n label=\"Products\"\n renderNode={(node) => (\n <span className=\"truncate\">{node.data.label}</span>\n )}\n />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["useState","TreeView","jsx","jsxs","useState","TreeView"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { LucideIcon } from 'lucide-react';
2
2
  import { ShellModule } from '@petrarca/sonnet-shell';
3
- import React$1 from 'react';
3
+ import react__default from 'react';
4
4
 
5
5
  /**
6
6
  * Playground entry types.
@@ -17,6 +17,8 @@ interface PlaygroundEntry {
17
17
  id: string;
18
18
  /** Display title on the overview tile. */
19
19
  title: string;
20
+ /** A shorter label for the navigation; default: the title. */
21
+ navLabel?: string;
20
22
  /** Short description shown below the title. */
21
23
  description: string;
22
24
  /** Lucide icon component for the tile. */
@@ -116,7 +118,7 @@ interface PlaygroundOverviewProps {
116
118
  grouped?: boolean;
117
119
  }
118
120
  /** Developer playground overview -- card grid linking to all registered pages. */
119
- declare function PlaygroundOverview({ registry, basePath, title, subtitle, grouped: initialGrouped, }: PlaygroundOverviewProps): React$1.ReactElement;
121
+ declare function PlaygroundOverview({ registry, basePath, title, subtitle, grouped: initialGrouped, }: PlaygroundOverviewProps): react__default.ReactElement;
120
122
 
121
123
  /**
122
124
  * Shared section wrapper for playground pages.
@@ -131,17 +133,17 @@ declare function PlaygroundOverview({ registry, basePath, title, subtitle, group
131
133
  interface PlaygroundSectionProps {
132
134
  title: string;
133
135
  description?: string;
134
- children: React$1.ReactNode;
136
+ children: react__default.ReactNode;
135
137
  variant?: "default" | "card";
136
138
  }
137
139
  interface ExampleBlockProps {
138
140
  label: string;
139
- children: React$1.ReactNode;
141
+ children: react__default.ReactNode;
140
142
  }
141
143
  /** Labeled divider wrapper for individual component examples within a section. */
142
- declare function ExampleBlock({ label, children, }: ExampleBlockProps): React$1.ReactElement;
144
+ declare function ExampleBlock({ label, children, }: ExampleBlockProps): react__default.ReactElement;
143
145
  /** Titled section wrapper used across playground pages. */
144
- declare function PlaygroundSection({ title, description, children, variant, }: PlaygroundSectionProps): React$1.ReactElement;
146
+ declare function PlaygroundSection({ title, description, children, variant, }: PlaygroundSectionProps): react__default.ReactElement;
145
147
 
146
148
  /**
147
149
  * Playground-scoped settings (locale, ...).
@@ -166,9 +168,9 @@ interface PlaygroundSettingsContextValue {
166
168
  setSettings: (next: Partial<PlaygroundSettings>) => void;
167
169
  }
168
170
  interface PlaygroundSettingsProviderProps {
169
- children: React$1.ReactNode;
171
+ children: react__default.ReactNode;
170
172
  }
171
- declare function PlaygroundSettingsProvider({ children, }: PlaygroundSettingsProviderProps): React$1.ReactElement;
173
+ declare function PlaygroundSettingsProvider({ children, }: PlaygroundSettingsProviderProps): react__default.ReactElement;
172
174
  /** Access playground settings. Returns defaults when no provider is present. */
173
175
  declare function usePlaygroundSettings(): PlaygroundSettingsContextValue;
174
176
 
@@ -180,7 +182,7 @@ declare function usePlaygroundSettings(): PlaygroundSettingsContextValue;
180
182
  * playground routes.
181
183
  */
182
184
 
183
- declare function PlaygroundSettingsPanel(): React$1.ReactElement;
185
+ declare function PlaygroundSettingsPanel(): react__default.ReactElement;
184
186
 
185
187
  declare const builtinEntries: PlaygroundEntry[];
186
188
 
@@ -210,4 +212,5 @@ declare const builtinEntries: PlaygroundEntry[];
210
212
  */
211
213
  declare function createPlaygroundRegistry(): PlaygroundRegistry;
212
214
 
213
- export { ExampleBlock, type PlaygroundColor, type PlaygroundEntry, type PlaygroundModuleOptions, PlaygroundOverview, PlaygroundRegistry, PlaygroundSection, type PlaygroundSettings, PlaygroundSettingsPanel, PlaygroundSettingsProvider, builtinEntries, createPlaygroundModule, createPlaygroundRegistry, usePlaygroundSettings };
215
+ export { ExampleBlock, PlaygroundOverview, PlaygroundRegistry, PlaygroundSection, PlaygroundSettingsPanel, PlaygroundSettingsProvider, builtinEntries, createPlaygroundModule, createPlaygroundRegistry, usePlaygroundSettings };
216
+ export type { PlaygroundColor, PlaygroundEntry, PlaygroundModuleOptions, PlaygroundSettings };
package/dist/index.js CHANGED
@@ -113,6 +113,8 @@ import {
113
113
  Grid,
114
114
  Layers,
115
115
  Braces,
116
+ FileCode,
117
+ FileText,
116
118
  Check,
117
119
  Edit,
118
120
  Package,
@@ -120,7 +122,10 @@ import {
120
122
  Network,
121
123
  SquareTerminal,
122
124
  PencilRuler,
123
- ShieldCheck
125
+ ClipboardList,
126
+ ShieldCheck,
127
+ FileJson,
128
+ ListTree
124
129
  } from "lucide-react";
125
130
  var builtinEntries = [
126
131
  {
@@ -152,7 +157,7 @@ var builtinEntries = [
152
157
  icon: Grid,
153
158
  color: "indigo",
154
159
  path: "core-components",
155
- component: lazy(() => import("./PlayCoreComponents-YTEAS3GL.js")),
160
+ component: lazy(() => import("./PlayCoreComponents-EQ2BMY2S.js")),
156
161
  group: "Components",
157
162
  order: 0
158
163
  },
@@ -163,7 +168,7 @@ var builtinEntries = [
163
168
  icon: Layers,
164
169
  color: "emerald",
165
170
  path: "advanced-components",
166
- component: lazy(() => import("./PlayAdvancedComponents-ZYK66UII.js")),
171
+ component: lazy(() => import("./PlayAdvancedComponents-VMUI472R.js")),
167
172
  group: "Components",
168
173
  order: 1
169
174
  },
@@ -175,7 +180,29 @@ var builtinEntries = [
175
180
  color: "amber",
176
181
  path: "json-editor",
177
182
  component: lazy(() => import("./PlayJsonEditor-SYZYEJEA.js")),
178
- group: "Components",
183
+ group: "Content",
184
+ order: 0
185
+ },
186
+ {
187
+ id: "sonnet.code-editor",
188
+ title: "Code Editor",
189
+ description: "CodeMirror with the sonnet look: code read-only (full and compact), and text editing. Languages load on demand; large files draw only the visible lines.",
190
+ icon: FileCode,
191
+ color: "amber",
192
+ path: "code-editor",
193
+ component: lazy(() => import("./PlayCodeEditor-AMTFE5SW.js")),
194
+ group: "Content",
195
+ order: 1
196
+ },
197
+ {
198
+ id: "sonnet.markdown-viewer",
199
+ title: "Markdown Viewer",
200
+ description: "Markdown for reading: GitHub-flavoured, code blocks in the code editor, Mermaid diagrams, untrusted content sanitized; also streamed, for a chat.",
201
+ icon: FileText,
202
+ color: "amber",
203
+ path: "markdown-viewer",
204
+ component: lazy(() => import("./PlayMarkdownViewer-X6AIFO2U.js")),
205
+ group: "Content",
179
206
  order: 2
180
207
  },
181
208
  {
@@ -196,7 +223,7 @@ var builtinEntries = [
196
223
  icon: Edit,
197
224
  color: "purple",
198
225
  path: "forms",
199
- component: lazy(() => import("./PlayForms-L532W3JL.js")),
226
+ component: lazy(() => import("./PlayForms-4CQNEBLS.js")),
200
227
  group: "Forms",
201
228
  order: 1
202
229
  },
@@ -207,10 +234,21 @@ var builtinEntries = [
207
234
  icon: Package,
208
235
  color: "indigo",
209
236
  path: "form-widgets",
210
- component: lazy(() => import("./PlayFormWidgets-6JYFRTAL.js")),
237
+ component: lazy(() => import("./PlayFormWidgets-HP3VF2LK.js")),
211
238
  group: "Forms",
212
239
  order: 2
213
240
  },
241
+ {
242
+ id: "sonnet.coded-values",
243
+ title: "Coded Values",
244
+ description: "Codes from a list a terminology service serves: the coded-value widget -- a list or a search, a code or a coding, one or several -- its display, the coding table cell, and the codeable concept: one answer coded in several lists.",
245
+ icon: ListTree,
246
+ color: "indigo",
247
+ path: "coded-values",
248
+ component: lazy(() => import("./PlayCodedValues-G2EVIVMO.js")),
249
+ group: "Forms",
250
+ order: 3
251
+ },
214
252
  {
215
253
  id: "sonnet.schema-designer",
216
254
  title: "Schema Designer",
@@ -218,10 +256,21 @@ var builtinEntries = [
218
256
  icon: PencilRuler,
219
257
  color: "teal",
220
258
  path: "schema-designer",
221
- component: lazy(() => import("./PlaySchemaDesigner-S4DBB53G.js")),
259
+ component: lazy(() => import("./PlaySchemaDesigner-ZQBA7AYO.js")),
222
260
  group: "Schemas",
223
261
  order: 0
224
262
  },
263
+ {
264
+ id: "sonnet.questionnaire-designer",
265
+ title: "Questionnaire Designer",
266
+ description: "Author a questionnaire as sections and questions, over the same JSON Schema and uiSchema as the Schema Designer. Parts it does not understand are kept as they are.",
267
+ icon: ClipboardList,
268
+ color: "teal",
269
+ path: "questionnaire-designer",
270
+ component: lazy(() => import("./PlayQuestionnaireDesigner-IR7TKSOT.js")),
271
+ group: "Schemas",
272
+ order: 1
273
+ },
225
274
  {
226
275
  id: "sonnet.data-components",
227
276
  title: "Data Components",
@@ -229,7 +278,7 @@ var builtinEntries = [
229
278
  icon: Table2,
230
279
  color: "teal",
231
280
  path: "data-components",
232
- component: lazy(() => import("./PlayDataComponents-W44OITT5.js")),
281
+ component: lazy(() => import("./PlayDataComponents-W2KQHOI7.js")),
233
282
  group: "Data",
234
283
  order: 0
235
284
  },
@@ -240,7 +289,7 @@ var builtinEntries = [
240
289
  icon: Network,
241
290
  color: "cyan",
242
291
  path: "graph",
243
- component: lazy(() => import("./PlayGraph-M4KQSFI7.js")),
292
+ component: lazy(() => import("./PlayGraph-25ZKQAQR.js")),
244
293
  group: "Graph",
245
294
  order: 0
246
295
  },
@@ -251,7 +300,7 @@ var builtinEntries = [
251
300
  icon: SquareTerminal,
252
301
  color: "orange",
253
302
  path: "shell-api",
254
- component: lazy(() => import("./PlayShellApi-5O6VYR2X.js")),
303
+ component: lazy(() => import("./PlayShellApi-MMCQ2AKK.js")),
255
304
  group: "Shell",
256
305
  order: 0
257
306
  },
@@ -265,6 +314,18 @@ var builtinEntries = [
265
314
  component: lazy(() => import("./PlayAuth-SOEYPOOL.js")),
266
315
  group: "Shell",
267
316
  order: 1
317
+ },
318
+ {
319
+ id: "sonnet.fhir-questionnaire",
320
+ title: "HL7 FHIR Questionnaire",
321
+ navLabel: "FHIR Questionnaire",
322
+ description: "End to end, in FHIR R4 and R5: read a Questionnaire as a questionnaire on JSON Schema, fill its form, submit it as a QuestionnaireResponse, and read a response back.",
323
+ icon: FileJson,
324
+ color: "teal",
325
+ path: "fhir-questionnaire",
326
+ component: lazy(() => import("./PlayFhirQuestionnaire-TO35Q7CP.js")),
327
+ group: "HL7 FHIR",
328
+ order: 0
268
329
  }
269
330
  ];
270
331
 
@@ -514,7 +575,7 @@ function buildNavigation(registry, basePath) {
514
575
  id: `playground-${groupLabel.toLowerCase().replace(/\s+/g, "-")}`,
515
576
  heading: groupLabel,
516
577
  links: entries.map((e) => ({
517
- label: e.title,
578
+ label: e.navLabel ?? e.title,
518
579
  path: `${basePath}/${e.path}`
519
580
  }))
520
581
  });