@ansh-ui/vue 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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/dist/chunk-2VSROZ2N.js +1281 -0
  3. package/dist/chunk-2VSROZ2N.js.map +1 -0
  4. package/dist/chunk-5BQEZYG6.cjs +1294 -0
  5. package/dist/chunk-5BQEZYG6.cjs.map +1 -0
  6. package/dist/chunk-6732H4BQ.cjs +28 -0
  7. package/dist/chunk-6732H4BQ.cjs.map +1 -0
  8. package/dist/chunk-6ABPGOJP.js +722 -0
  9. package/dist/chunk-6ABPGOJP.js.map +1 -0
  10. package/dist/chunk-6XJOB6LE.js +62 -0
  11. package/dist/chunk-6XJOB6LE.js.map +1 -0
  12. package/dist/chunk-774WBLDR.cjs +24 -0
  13. package/dist/chunk-774WBLDR.cjs.map +1 -0
  14. package/dist/chunk-B6OXKW5Q.js +567 -0
  15. package/dist/chunk-B6OXKW5Q.js.map +1 -0
  16. package/dist/chunk-DMPNT3MY.cjs +64 -0
  17. package/dist/chunk-DMPNT3MY.cjs.map +1 -0
  18. package/dist/chunk-EISHOEB6.cjs +158 -0
  19. package/dist/chunk-EISHOEB6.cjs.map +1 -0
  20. package/dist/chunk-EVO23GUS.js +223 -0
  21. package/dist/chunk-EVO23GUS.js.map +1 -0
  22. package/dist/chunk-FVKLCGA4.js +1035 -0
  23. package/dist/chunk-FVKLCGA4.js.map +1 -0
  24. package/dist/chunk-IOXGBPOV.cjs +3681 -0
  25. package/dist/chunk-IOXGBPOV.cjs.map +1 -0
  26. package/dist/chunk-J2LA4GRP.cjs +1051 -0
  27. package/dist/chunk-J2LA4GRP.cjs.map +1 -0
  28. package/dist/chunk-JQ4YLXXM.cjs +580 -0
  29. package/dist/chunk-JQ4YLXXM.cjs.map +1 -0
  30. package/dist/chunk-KCA7RNJ4.cjs +781 -0
  31. package/dist/chunk-KCA7RNJ4.cjs.map +1 -0
  32. package/dist/chunk-NJDDNO4C.js +23 -0
  33. package/dist/chunk-NJDDNO4C.js.map +1 -0
  34. package/dist/chunk-OAQ7MDYX.js +22 -0
  35. package/dist/chunk-OAQ7MDYX.js.map +1 -0
  36. package/dist/chunk-PP6OYURM.cjs +238 -0
  37. package/dist/chunk-PP6OYURM.cjs.map +1 -0
  38. package/dist/chunk-SHX2JGID.cjs +269 -0
  39. package/dist/chunk-SHX2JGID.cjs.map +1 -0
  40. package/dist/chunk-SOYRICHU.js +3645 -0
  41. package/dist/chunk-SOYRICHU.js.map +1 -0
  42. package/dist/chunk-T425FIC7.js +773 -0
  43. package/dist/chunk-T425FIC7.js.map +1 -0
  44. package/dist/chunk-TMG3M6TK.js +152 -0
  45. package/dist/chunk-TMG3M6TK.js.map +1 -0
  46. package/dist/chunk-XLLSS464.cjs +286 -0
  47. package/dist/chunk-XLLSS464.cjs.map +1 -0
  48. package/dist/chunk-XZ5ZFLZM.js +280 -0
  49. package/dist/chunk-XZ5ZFLZM.js.map +1 -0
  50. package/dist/chunk-Z7XOFKM4.cjs +733 -0
  51. package/dist/chunk-Z7XOFKM4.cjs.map +1 -0
  52. package/dist/chunk-ZGMXOMCB.js +266 -0
  53. package/dist/chunk-ZGMXOMCB.js.map +1 -0
  54. package/dist/data.cjs +70 -0
  55. package/dist/data.cjs.map +1 -0
  56. package/dist/data.d.cts +963 -0
  57. package/dist/data.d.ts +963 -0
  58. package/dist/data.js +5 -0
  59. package/dist/data.js.map +1 -0
  60. package/dist/form.cjs +151 -0
  61. package/dist/form.cjs.map +1 -0
  62. package/dist/form.d.cts +2639 -0
  63. package/dist/form.d.ts +2639 -0
  64. package/dist/form.js +6 -0
  65. package/dist/form.js.map +1 -0
  66. package/dist/index.cjs +1158 -0
  67. package/dist/index.cjs.map +1 -0
  68. package/dist/index.d.cts +439 -0
  69. package/dist/index.d.ts +439 -0
  70. package/dist/index.js +547 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/layout.cjs +67 -0
  73. package/dist/layout.cjs.map +1 -0
  74. package/dist/layout.d.cts +729 -0
  75. package/dist/layout.d.ts +729 -0
  76. package/dist/layout.js +6 -0
  77. package/dist/layout.js.map +1 -0
  78. package/dist/motion.cjs +50 -0
  79. package/dist/motion.cjs.map +1 -0
  80. package/dist/motion.d.cts +681 -0
  81. package/dist/motion.d.ts +681 -0
  82. package/dist/motion.js +5 -0
  83. package/dist/motion.js.map +1 -0
  84. package/dist/navigation.cjs +48 -0
  85. package/dist/navigation.cjs.map +1 -0
  86. package/dist/navigation.d.cts +515 -0
  87. package/dist/navigation.d.ts +515 -0
  88. package/dist/navigation.js +7 -0
  89. package/dist/navigation.js.map +1 -0
  90. package/dist/overlay.cjs +61 -0
  91. package/dist/overlay.cjs.map +1 -0
  92. package/dist/overlay.d.cts +772 -0
  93. package/dist/overlay.d.ts +772 -0
  94. package/dist/overlay.js +8 -0
  95. package/dist/overlay.js.map +1 -0
  96. package/dist/position-Cn7qP1pn.d.cts +50 -0
  97. package/dist/position-Cn7qP1pn.d.ts +50 -0
  98. package/dist/primitives.cjs +129 -0
  99. package/dist/primitives.cjs.map +1 -0
  100. package/dist/primitives.d.cts +300 -0
  101. package/dist/primitives.d.ts +300 -0
  102. package/dist/primitives.js +8 -0
  103. package/dist/primitives.js.map +1 -0
  104. package/dist/sidebar-CQqEmpid.d.cts +124 -0
  105. package/dist/sidebar-CTZ-Ckko.d.ts +124 -0
  106. package/dist/styles.css +5593 -0
  107. package/dist/utils-IKPG3zcC.d.cts +46 -0
  108. package/dist/utils-IKPG3zcC.d.ts +46 -0
  109. package/package.json +91 -0
@@ -0,0 +1,781 @@
1
+ 'use strict';
2
+
3
+ var chunkEISHOEB6_cjs = require('./chunk-EISHOEB6.cjs');
4
+ var chunk774WBLDR_cjs = require('./chunk-774WBLDR.cjs');
5
+ var chunk6732H4BQ_cjs = require('./chunk-6732H4BQ.cjs');
6
+ var vue = require('vue');
7
+
8
+ var Tabs = vue.defineComponent({
9
+ name: "AnshTabs",
10
+ inheritAttrs: false,
11
+ props: {
12
+ items: { type: Array, required: true },
13
+ modelValue: { type: String, default: void 0 },
14
+ defaultValue: { type: String, default: void 0 },
15
+ variant: { type: String, default: "underline" },
16
+ orientation: { type: String, default: "horizontal" },
17
+ size: { type: String, default: "md" },
18
+ /** Stretch tabs to fill the available width. */
19
+ fitted: { type: Boolean, default: false },
20
+ /**
21
+ * Activate on arrow-key focus, rather than requiring Enter/Space.
22
+ *
23
+ * Automatic is the ARIA-preferred default for cheap panels. Set `false` when switching a tab
24
+ * triggers a fetch — arrowing past three tabs would fire three requests.
25
+ */
26
+ activateOnFocus: { type: Boolean, default: true },
27
+ /** Accessible name for the tab list. */
28
+ label: { type: String, required: true }
29
+ },
30
+ emits: ["update:modelValue"],
31
+ setup(props, { attrs, emit, slots }) {
32
+ const initialActive = props.defaultValue ?? props.items.find((item) => !item.disabled)?.id ?? "";
33
+ const [active, setActive] = chunk774WBLDR_cjs.useControllableState(
34
+ () => props.modelValue,
35
+ initialActive,
36
+ (next) => emit("update:modelValue", next)
37
+ );
38
+ const baseId = chunk6732H4BQ_cjs.useId();
39
+ const tabRefs = vue.ref([]);
40
+ const activeItem = vue.computed(() => props.items.find((item) => item.id === active.value));
41
+ const enabledIds = vue.computed(
42
+ () => props.items.filter((item) => !item.disabled).map((item) => item.id)
43
+ );
44
+ const onRovingActiveChange = (position) => {
45
+ const id = enabledIds.value[position];
46
+ if (id !== void 0 && props.activateOnFocus) setActive(id);
47
+ };
48
+ const onKeydown = chunkEISHOEB6_cjs.useRovingFocus({
49
+ items: tabRefs,
50
+ active: () => enabledIds.value.indexOf(active.value),
51
+ onActiveChange: onRovingActiveChange,
52
+ orientation: props.orientation,
53
+ loop: true
54
+ });
55
+ return () => {
56
+ const { class: attrClass, ...restAttrs } = attrs;
57
+ const currentActive = active.value;
58
+ const currentActiveItem = activeItem.value;
59
+ const hasPanel = currentActiveItem?.content !== void 0 || Boolean(slots.default);
60
+ return vue.h(
61
+ "div",
62
+ {
63
+ class: chunk6732H4BQ_cjs.cx(
64
+ "ansh-tabs",
65
+ `ansh-tabs--${props.variant}`,
66
+ `ansh-tabs--${props.orientation}`,
67
+ `ansh-tabs--${props.size}`,
68
+ attrClass
69
+ ),
70
+ ...restAttrs
71
+ },
72
+ [
73
+ vue.h(
74
+ "div",
75
+ {
76
+ role: "tablist",
77
+ "aria-label": props.label,
78
+ "aria-orientation": props.orientation,
79
+ class: chunk6732H4BQ_cjs.cx("ansh-tabs__list", props.fitted && "ansh-tabs__list--fitted"),
80
+ onKeydown
81
+ },
82
+ props.items.map((item, index) => {
83
+ const selected = item.id === currentActive;
84
+ return vue.h(
85
+ "button",
86
+ {
87
+ key: item.id,
88
+ ref: (node) => {
89
+ tabRefs.value[index] = item.disabled ? null : node;
90
+ },
91
+ type: "button",
92
+ role: "tab",
93
+ id: `${baseId}-tab-${item.id}`,
94
+ "aria-selected": selected,
95
+ "aria-controls": `${baseId}-panel-${item.id}`,
96
+ // Exactly one tab is in the tab order. Without this, a bar of eight tabs costs a
97
+ // keyboard user eight presses to pass.
98
+ tabindex: selected ? "0" : "-1",
99
+ disabled: item.disabled,
100
+ class: chunk6732H4BQ_cjs.cx(
101
+ "ansh-tabs__tab",
102
+ selected && "ansh-tabs__tab--active",
103
+ "ansh-focusable"
104
+ ),
105
+ onClick: () => setActive(item.id)
106
+ },
107
+ [
108
+ item.icon !== void 0 ? vue.h("span", { class: "ansh-tabs__icon" }, [chunk6732H4BQ_cjs.resolveSlotContent(item.icon)]) : null,
109
+ vue.h("span", {}, [chunk6732H4BQ_cjs.resolveSlotContent(item.label)]),
110
+ item.badge !== void 0 ? vue.h("span", { class: "ansh-tabs__badge" }, [chunk6732H4BQ_cjs.resolveSlotContent(item.badge)]) : null
111
+ ]
112
+ );
113
+ })
114
+ ),
115
+ hasPanel ? vue.h(
116
+ "div",
117
+ {
118
+ role: "tabpanel",
119
+ id: `${baseId}-panel-${currentActive}`,
120
+ "aria-labelledby": `${baseId}-tab-${currentActive}`,
121
+ // Focusable so a keyboard user can Tab from the tab into its panel and scroll it,
122
+ // which is required when the panel has no focusable content of its own.
123
+ tabindex: "0",
124
+ class: "ansh-tabs__panel ansh-focusable"
125
+ },
126
+ [
127
+ currentActiveItem?.content !== void 0 ? chunk6732H4BQ_cjs.resolveSlotContent(currentActiveItem.content) : slots.default?.()
128
+ ]
129
+ ) : null
130
+ ]
131
+ );
132
+ };
133
+ }
134
+ });
135
+ var Breadcrumbs = vue.defineComponent({
136
+ name: "AnshBreadcrumbs",
137
+ inheritAttrs: false,
138
+ props: {
139
+ items: { type: Array, required: true },
140
+ /** Collapse the middle when there are more than this many. Default `Infinity`. */
141
+ maxItems: { type: Number, default: Number.POSITIVE_INFINITY },
142
+ separator: { type: [String, Object, Function], default: void 0 }
143
+ },
144
+ setup(props, { attrs }) {
145
+ const expanded = vue.ref(false);
146
+ const defaultChevron = () => vue.h("svg", { viewBox: "0 0 12 12", width: "12", height: "12", "aria-hidden": "true" }, [
147
+ vue.h("path", {
148
+ d: "M4.5 2.5L8 6l-3.5 3.5",
149
+ stroke: "currentColor",
150
+ "stroke-width": "1.5",
151
+ fill: "none",
152
+ "stroke-linecap": "round",
153
+ "stroke-linejoin": "round"
154
+ })
155
+ ]);
156
+ const renderChevron = () => props.separator !== void 0 ? chunk6732H4BQ_cjs.resolveSlotContent(props.separator) : defaultChevron();
157
+ return () => {
158
+ const { class: attrClass, ...restAttrs } = attrs;
159
+ const items = props.items;
160
+ const collapsed = !expanded.value && items.length > props.maxItems && props.maxItems >= 2;
161
+ const shown = collapsed ? [items[0], ...items.slice(-2)] : items;
162
+ const gapAfter = collapsed ? 0 : -1;
163
+ return vue.h(
164
+ "nav",
165
+ {
166
+ "aria-label": "Breadcrumb",
167
+ class: chunk6732H4BQ_cjs.cx("ansh-breadcrumbs", attrClass),
168
+ ...restAttrs
169
+ },
170
+ [
171
+ vue.h(
172
+ "ol",
173
+ { class: "ansh-breadcrumbs__list" },
174
+ shown.map((crumb, index) => {
175
+ const isLast = index === shown.length - 1;
176
+ return vue.h("li", { key: index, class: "ansh-breadcrumbs__item" }, [
177
+ index > 0 ? vue.h("span", { class: "ansh-breadcrumbs__separator", "aria-hidden": "true" }, [
178
+ renderChevron()
179
+ ]) : null,
180
+ isLast ? vue.h("span", { class: "ansh-breadcrumbs__current", "aria-current": "page" }, [
181
+ crumb.icon !== void 0 ? chunk6732H4BQ_cjs.resolveSlotContent(crumb.icon) : null,
182
+ chunk6732H4BQ_cjs.resolveSlotContent(crumb.label)
183
+ ]) : vue.h(
184
+ "a",
185
+ {
186
+ href: crumb.href ?? "#",
187
+ class: "ansh-breadcrumbs__link ansh-focusable",
188
+ onClick: crumb.onClick ? (event) => {
189
+ event.preventDefault();
190
+ crumb.onClick();
191
+ } : void 0
192
+ },
193
+ [
194
+ crumb.icon !== void 0 ? chunk6732H4BQ_cjs.resolveSlotContent(crumb.icon) : null,
195
+ chunk6732H4BQ_cjs.resolveSlotContent(crumb.label)
196
+ ]
197
+ ),
198
+ index === gapAfter ? [
199
+ vue.h("span", { class: "ansh-breadcrumbs__separator", "aria-hidden": "true" }, [
200
+ renderChevron()
201
+ ]),
202
+ vue.h(
203
+ "button",
204
+ {
205
+ type: "button",
206
+ class: "ansh-breadcrumbs__more ansh-focusable",
207
+ "aria-label": `Show ${items.length - 3} hidden breadcrumbs`,
208
+ "aria-expanded": false,
209
+ onClick: () => {
210
+ expanded.value = true;
211
+ }
212
+ },
213
+ "\u2026"
214
+ )
215
+ ] : null
216
+ ]);
217
+ })
218
+ )
219
+ ]
220
+ );
221
+ };
222
+ }
223
+ });
224
+ var Stepper = vue.defineComponent({
225
+ name: "AnshStepper",
226
+ inheritAttrs: false,
227
+ props: {
228
+ steps: { type: Array, required: true },
229
+ /** Index of the current step. Steps before it are complete. */
230
+ current: { type: Number, required: true },
231
+ orientation: { type: String, default: "horizontal" }
232
+ },
233
+ emits: ["update:current"],
234
+ setup(props, { attrs, emit }) {
235
+ return () => {
236
+ const { class: attrClass, ...restAttrs } = attrs;
237
+ return vue.h(
238
+ "nav",
239
+ {
240
+ class: chunk6732H4BQ_cjs.cx("ansh-stepper", `ansh-stepper--${props.orientation}`, attrClass),
241
+ "aria-label": "Progress",
242
+ ...restAttrs
243
+ },
244
+ [
245
+ vue.h(
246
+ "ol",
247
+ { class: "ansh-stepper__list" },
248
+ props.steps.map((step, index) => {
249
+ const complete = index < props.current;
250
+ const active = index === props.current;
251
+ const state = step.error ? "error" : complete ? "complete" : active ? "current" : "upcoming";
252
+ const interactive = step.clickable && index !== props.current;
253
+ const inner = [
254
+ vue.h(
255
+ "span",
256
+ {
257
+ class: chunk6732H4BQ_cjs.cx("ansh-stepper__marker", `ansh-stepper__marker--${state}`),
258
+ "aria-hidden": "true"
259
+ },
260
+ [
261
+ step.error ? "!" : complete ? vue.h("svg", { viewBox: "0 0 14 14", width: "12", height: "12" }, [
262
+ vue.h("path", {
263
+ d: "M2.5 7.5l3 3 6-6.5",
264
+ stroke: "currentColor",
265
+ "stroke-width": "2",
266
+ "stroke-linecap": "round",
267
+ "stroke-linejoin": "round",
268
+ fill: "none"
269
+ })
270
+ ]) : String(index + 1)
271
+ ]
272
+ ),
273
+ vue.h("span", { class: "ansh-stepper__text" }, [
274
+ vue.h("span", { class: "ansh-stepper__label" }, [chunk6732H4BQ_cjs.resolveSlotContent(step.label)]),
275
+ step.description ? vue.h("span", { class: "ansh-stepper__description" }, [
276
+ chunk6732H4BQ_cjs.resolveSlotContent(step.description)
277
+ ]) : null,
278
+ vue.h("span", { class: "ansh-visually-hidden" }, [
279
+ step.error ? " \u2014 has errors" : complete ? " \u2014 completed" : active ? " \u2014 current step" : " \u2014 not started"
280
+ ])
281
+ ])
282
+ ];
283
+ return vue.h(
284
+ "li",
285
+ {
286
+ key: step.id,
287
+ class: chunk6732H4BQ_cjs.cx("ansh-stepper__item", `ansh-stepper__item--${state}`),
288
+ "aria-current": active ? "step" : void 0
289
+ },
290
+ [
291
+ interactive ? vue.h(
292
+ "button",
293
+ {
294
+ type: "button",
295
+ class: "ansh-stepper__button ansh-focusable",
296
+ onClick: () => emit("update:current", index)
297
+ },
298
+ inner
299
+ ) : vue.h("span", { class: "ansh-stepper__button" }, inner)
300
+ ]
301
+ );
302
+ })
303
+ )
304
+ ]
305
+ );
306
+ };
307
+ }
308
+ });
309
+ var NavigationMenu = vue.defineComponent({
310
+ name: "AnshNavigationMenu",
311
+ inheritAttrs: false,
312
+ props: {
313
+ items: { type: Array, required: true },
314
+ label: { type: String, default: "Main navigation" }
315
+ },
316
+ setup(props, { attrs }) {
317
+ const openId = vue.ref(null);
318
+ const rootRef = vue.ref(null);
319
+ const baseId = chunk6732H4BQ_cjs.useId();
320
+ let timer;
321
+ const schedule = (next, delay) => {
322
+ clearTimeout(timer);
323
+ timer = setTimeout(() => {
324
+ openId.value = next;
325
+ }, delay);
326
+ };
327
+ vue.onBeforeUnmount(() => clearTimeout(timer));
328
+ vue.watch(openId, (id, _previous, onCleanup) => {
329
+ if (!id) return;
330
+ const root = rootRef.value;
331
+ if (!root) return;
332
+ const onFocusOut = (event) => {
333
+ const next = event.relatedTarget;
334
+ if (next && root.contains(next)) return;
335
+ openId.value = null;
336
+ };
337
+ const onKeyDown = (event) => {
338
+ if (event.key !== "Escape") return;
339
+ openId.value = null;
340
+ root.querySelector('[aria-expanded="true"]')?.focus();
341
+ };
342
+ root.addEventListener("focusout", onFocusOut);
343
+ document.addEventListener("keydown", onKeyDown);
344
+ onCleanup(() => {
345
+ root.removeEventListener("focusout", onFocusOut);
346
+ document.removeEventListener("keydown", onKeyDown);
347
+ });
348
+ });
349
+ return () => {
350
+ const { class: attrClass, ...restAttrs } = attrs;
351
+ return vue.h(
352
+ "nav",
353
+ {
354
+ ref: rootRef,
355
+ class: chunk6732H4BQ_cjs.cx("ansh-navmenu", attrClass),
356
+ "aria-label": props.label,
357
+ onMouseleave: () => schedule(null, 200),
358
+ ...restAttrs
359
+ },
360
+ [
361
+ vue.h(
362
+ "ul",
363
+ { class: "ansh-navmenu__list" },
364
+ props.items.map((item) => {
365
+ const hasPanel = Boolean(item.columns?.length);
366
+ const open = openId.value === item.id;
367
+ const panelId = `${baseId}-${item.id}`;
368
+ if (!hasPanel) {
369
+ return vue.h("li", { key: item.id, class: "ansh-navmenu__item" }, [
370
+ vue.h(
371
+ "a",
372
+ { href: item.href ?? "#", class: "ansh-navmenu__link ansh-focusable" },
373
+ item.label
374
+ )
375
+ ]);
376
+ }
377
+ return vue.h(
378
+ "li",
379
+ {
380
+ key: item.id,
381
+ class: chunk6732H4BQ_cjs.cx("ansh-navmenu__item", open && "ansh-navmenu__item--open"),
382
+ onMouseenter: () => schedule(item.id, 80)
383
+ },
384
+ [
385
+ vue.h(
386
+ "button",
387
+ {
388
+ type: "button",
389
+ class: "ansh-navmenu__link ansh-navmenu__link--trigger ansh-focusable",
390
+ "aria-expanded": open,
391
+ "aria-controls": panelId,
392
+ onClick: () => {
393
+ openId.value = open ? null : item.id;
394
+ },
395
+ onKeydown: (event) => {
396
+ if (event.key !== "ArrowDown") return;
397
+ event.preventDefault();
398
+ openId.value = item.id;
399
+ requestAnimationFrame(() => {
400
+ document.getElementById(panelId)?.querySelector("a, button")?.focus();
401
+ });
402
+ }
403
+ },
404
+ [
405
+ item.label,
406
+ vue.h(
407
+ "span",
408
+ {
409
+ class: chunk6732H4BQ_cjs.cx("ansh-navmenu__chevron", open && "ansh-navmenu__chevron--open"),
410
+ "aria-hidden": "true"
411
+ },
412
+ [
413
+ vue.h("svg", { viewBox: "0 0 12 12", width: "10", height: "10" }, [
414
+ vue.h("path", {
415
+ d: "M3 4.5L6 7.5l3-3",
416
+ stroke: "currentColor",
417
+ "stroke-width": "1.5",
418
+ fill: "none",
419
+ "stroke-linecap": "round",
420
+ "stroke-linejoin": "round"
421
+ })
422
+ ])
423
+ ]
424
+ )
425
+ ]
426
+ ),
427
+ vue.h(
428
+ "div",
429
+ {
430
+ id: panelId,
431
+ class: "ansh-navmenu__panel",
432
+ hidden: !open,
433
+ onMouseenter: () => clearTimeout(timer)
434
+ },
435
+ [
436
+ vue.h("div", { class: "ansh-navmenu__grid" }, [
437
+ ...item.columns.map(
438
+ (column) => vue.h("div", { class: "ansh-navmenu__column", key: column.id }, [
439
+ column.heading ? vue.h("p", { class: "ansh-navmenu__heading" }, column.heading) : null,
440
+ vue.h(
441
+ "ul",
442
+ { class: "ansh-navmenu__links" },
443
+ column.links.map(
444
+ (link) => vue.h("li", { key: link.id }, [
445
+ vue.h(
446
+ "a",
447
+ {
448
+ href: link.href ?? "#",
449
+ class: "ansh-navmenu__entry ansh-focusable",
450
+ onClick: link.onClick ? (event) => {
451
+ event.preventDefault();
452
+ link.onClick();
453
+ openId.value = null;
454
+ } : () => {
455
+ openId.value = null;
456
+ }
457
+ },
458
+ [
459
+ link.icon !== void 0 ? vue.h(
460
+ "span",
461
+ { class: "ansh-navmenu__icon", "aria-hidden": "true" },
462
+ [chunk6732H4BQ_cjs.resolveSlotContent(link.icon)]
463
+ ) : null,
464
+ vue.h("span", { class: "ansh-navmenu__entry-text" }, [
465
+ vue.h(
466
+ "span",
467
+ { class: "ansh-navmenu__entry-label" },
468
+ link.label
469
+ ),
470
+ link.description ? vue.h(
471
+ "span",
472
+ { class: "ansh-navmenu__entry-description" },
473
+ link.description
474
+ ) : null
475
+ ])
476
+ ]
477
+ )
478
+ ])
479
+ )
480
+ )
481
+ ])
482
+ ),
483
+ item.feature !== void 0 ? vue.h("div", { class: "ansh-navmenu__feature" }, [
484
+ chunk6732H4BQ_cjs.resolveSlotContent(item.feature)
485
+ ]) : null
486
+ ])
487
+ ]
488
+ )
489
+ ]
490
+ );
491
+ })
492
+ )
493
+ ]
494
+ );
495
+ };
496
+ }
497
+ });
498
+ var Collapsible = vue.defineComponent({
499
+ name: "AnshCollapsible",
500
+ inheritAttrs: false,
501
+ props: {
502
+ open: { type: Boolean, default: void 0 },
503
+ defaultOpen: { type: Boolean, default: false },
504
+ trigger: { type: [String, Object, Function], required: true },
505
+ bare: { type: Boolean, default: false }
506
+ },
507
+ emits: ["update:open"],
508
+ setup(props, { attrs, emit, slots }) {
509
+ const [isOpen, setOpen] = chunk774WBLDR_cjs.useControllableState(
510
+ () => props.open,
511
+ props.defaultOpen,
512
+ (next) => emit("update:open", next)
513
+ );
514
+ const id = chunk6732H4BQ_cjs.useId();
515
+ return () => {
516
+ const { class: attrClass, ...restAttrs } = attrs;
517
+ return vue.h(
518
+ "div",
519
+ {
520
+ class: chunk6732H4BQ_cjs.cx("ansh-collapsible", attrClass),
521
+ "data-state": isOpen.value ? "open" : "closed",
522
+ ...restAttrs
523
+ },
524
+ [
525
+ vue.h(
526
+ "button",
527
+ {
528
+ type: "button",
529
+ class: chunk6732H4BQ_cjs.cx(
530
+ props.bare ? "ansh-collapsible__bare" : "ansh-collapsible__trigger",
531
+ "ansh-focusable"
532
+ ),
533
+ "aria-expanded": isOpen.value,
534
+ "aria-controls": id,
535
+ onClick: () => setOpen(!isOpen.value)
536
+ },
537
+ [
538
+ chunk6732H4BQ_cjs.resolveSlotContent(props.trigger),
539
+ vue.h(
540
+ "span",
541
+ {
542
+ class: chunk6732H4BQ_cjs.cx(
543
+ "ansh-collapsible__chevron",
544
+ isOpen.value && "ansh-collapsible__chevron--open"
545
+ ),
546
+ "aria-hidden": "true"
547
+ },
548
+ [
549
+ vue.h("svg", { viewBox: "0 0 12 12", width: "12", height: "12" }, [
550
+ vue.h("path", {
551
+ d: "M3 4.5L6 7.5l3-3",
552
+ stroke: "currentColor",
553
+ "stroke-width": "1.5",
554
+ fill: "none",
555
+ "stroke-linecap": "round",
556
+ "stroke-linejoin": "round"
557
+ })
558
+ ])
559
+ ]
560
+ )
561
+ ]
562
+ ),
563
+ vue.h(
564
+ "div",
565
+ {
566
+ class: "ansh-collapsible__region",
567
+ id,
568
+ role: "region",
569
+ "data-state": isOpen.value ? "open" : "closed"
570
+ },
571
+ [
572
+ // `inert` on the collapsed panel removes its contents from the tab order and the
573
+ // accessibility tree. Without it, a keyboard user tabs into links inside a section
574
+ // that is visually closed — invisible focus, and no way to tell where they are.
575
+ vue.h(
576
+ "div",
577
+ { class: "ansh-collapsible__inner", ...isOpen.value ? null : { inert: true } },
578
+ slots.default?.()
579
+ )
580
+ ]
581
+ )
582
+ ]
583
+ );
584
+ };
585
+ }
586
+ });
587
+ var Accordion = vue.defineComponent({
588
+ name: "AnshAccordion",
589
+ inheritAttrs: false,
590
+ props: {
591
+ items: { type: Array, required: true },
592
+ /** Allow several panels open at once. Default `false`. */
593
+ multiple: { type: Boolean, default: false },
594
+ modelValue: { type: Array, default: void 0 },
595
+ defaultValue: { type: Array, default: () => [] },
596
+ variant: { type: String, default: "bordered" }
597
+ },
598
+ emits: ["update:modelValue"],
599
+ setup(props, { attrs, emit }) {
600
+ const [openIds, setOpenIds] = chunk774WBLDR_cjs.useControllableState(
601
+ () => props.modelValue,
602
+ props.defaultValue,
603
+ (next) => emit("update:modelValue", next)
604
+ );
605
+ const baseId = chunk6732H4BQ_cjs.useId();
606
+ const headerRefs = vue.ref([]);
607
+ const toggle = (id) => {
608
+ if (openIds.value.includes(id)) {
609
+ setOpenIds(openIds.value.filter((entry) => entry !== id));
610
+ } else {
611
+ setOpenIds(props.multiple ? [...openIds.value, id] : [id]);
612
+ }
613
+ };
614
+ const onKeydown = chunkEISHOEB6_cjs.useRovingFocus({
615
+ items: headerRefs,
616
+ // There is no single "active" header the way `Tabs` has a selected tab — arrow keys move
617
+ // relative to whichever header currently owns focus.
618
+ active: () => {
619
+ const enabled = headerRefs.value.filter((node) => node !== null);
620
+ return enabled.indexOf(document.activeElement);
621
+ },
622
+ // The hook already moves focus to the target header; there is no selection model to sync.
623
+ onActiveChange: () => {
624
+ },
625
+ orientation: "vertical",
626
+ loop: true
627
+ });
628
+ return () => {
629
+ const { class: attrClass, ...restAttrs } = attrs;
630
+ return vue.h(
631
+ "div",
632
+ {
633
+ class: chunk6732H4BQ_cjs.cx("ansh-accordion", `ansh-accordion--${props.variant}`, attrClass),
634
+ onKeydown,
635
+ ...restAttrs
636
+ },
637
+ props.items.map((item, index) => {
638
+ const open = openIds.value.includes(item.id);
639
+ const panelId = `${baseId}-panel-${item.id}`;
640
+ const headerId = `${baseId}-header-${item.id}`;
641
+ return vue.h(
642
+ "div",
643
+ {
644
+ key: item.id,
645
+ class: chunk6732H4BQ_cjs.cx("ansh-accordion__item", open && "ansh-accordion__item--open"),
646
+ "data-state": open ? "open" : "closed"
647
+ },
648
+ [
649
+ vue.h("h3", { class: "ansh-accordion__heading" }, [
650
+ vue.h(
651
+ "button",
652
+ {
653
+ ref: (node) => {
654
+ headerRefs.value[index] = item.disabled ? null : node;
655
+ },
656
+ type: "button",
657
+ id: headerId,
658
+ class: "ansh-accordion__trigger ansh-focusable",
659
+ "aria-expanded": open,
660
+ "aria-controls": panelId,
661
+ disabled: item.disabled,
662
+ onClick: () => toggle(item.id)
663
+ },
664
+ [
665
+ item.icon !== void 0 ? vue.h("span", { class: "ansh-accordion__icon" }, [
666
+ chunk6732H4BQ_cjs.resolveSlotContent(item.icon)
667
+ ]) : null,
668
+ vue.h("span", { class: "ansh-accordion__text" }, [
669
+ vue.h("span", { class: "ansh-accordion__title" }, [
670
+ chunk6732H4BQ_cjs.resolveSlotContent(item.title)
671
+ ]),
672
+ item.subtitle ? vue.h("span", { class: "ansh-accordion__subtitle" }, [
673
+ chunk6732H4BQ_cjs.resolveSlotContent(item.subtitle)
674
+ ]) : null
675
+ ]),
676
+ vue.h(
677
+ "span",
678
+ {
679
+ class: chunk6732H4BQ_cjs.cx(
680
+ "ansh-accordion__chevron",
681
+ open && "ansh-accordion__chevron--open"
682
+ ),
683
+ "aria-hidden": "true"
684
+ },
685
+ [
686
+ vue.h("svg", { viewBox: "0 0 12 12", width: "12", height: "12" }, [
687
+ vue.h("path", {
688
+ d: "M3 4.5L6 7.5l3-3",
689
+ stroke: "currentColor",
690
+ "stroke-width": "1.5",
691
+ fill: "none",
692
+ "stroke-linecap": "round",
693
+ "stroke-linejoin": "round"
694
+ })
695
+ ])
696
+ ]
697
+ )
698
+ ]
699
+ )
700
+ ]),
701
+ vue.h(
702
+ "div",
703
+ {
704
+ class: "ansh-accordion__region",
705
+ id: panelId,
706
+ role: "region",
707
+ "aria-labelledby": headerId,
708
+ "data-state": open ? "open" : "closed"
709
+ },
710
+ [
711
+ vue.h("div", { class: "ansh-accordion__panel", ...open ? null : { inert: true } }, [
712
+ chunk6732H4BQ_cjs.resolveSlotContent(item.content)
713
+ ])
714
+ ]
715
+ )
716
+ ]
717
+ );
718
+ })
719
+ );
720
+ };
721
+ }
722
+ });
723
+ var DisclosureList = vue.defineComponent({
724
+ name: "AnshDisclosureList",
725
+ inheritAttrs: false,
726
+ props: {
727
+ items: { type: Array, required: true },
728
+ initial: { type: Number, default: 3 },
729
+ moreLabel: {
730
+ type: Function,
731
+ default: (hidden) => `Show ${hidden} more`
732
+ },
733
+ lessLabel: { type: String, default: "Show less" }
734
+ },
735
+ setup(props, { attrs }) {
736
+ const expanded = vue.ref(false);
737
+ const id = chunk6732H4BQ_cjs.useId();
738
+ return () => {
739
+ const { class: attrClass, ...restAttrs } = attrs;
740
+ const hidden = props.items.length - props.initial;
741
+ if (hidden <= 0) {
742
+ return vue.h(
743
+ "ul",
744
+ { class: chunk6732H4BQ_cjs.cx("ansh-disclosure-list", attrClass), ...restAttrs },
745
+ props.items.map((item, index) => vue.h("li", { key: index }, [chunk6732H4BQ_cjs.resolveSlotContent(item)]))
746
+ );
747
+ }
748
+ const shown = expanded.value ? props.items : props.items.slice(0, props.initial);
749
+ return vue.h("div", { class: attrClass, ...restAttrs }, [
750
+ vue.h(
751
+ "ul",
752
+ { class: "ansh-disclosure-list", id },
753
+ shown.map((item, index) => vue.h("li", { key: index }, [chunk6732H4BQ_cjs.resolveSlotContent(item)]))
754
+ ),
755
+ vue.h(
756
+ "button",
757
+ {
758
+ type: "button",
759
+ class: "ansh-disclosure-list__toggle ansh-focusable",
760
+ "aria-expanded": expanded.value,
761
+ "aria-controls": id,
762
+ onClick: () => {
763
+ expanded.value = !expanded.value;
764
+ }
765
+ },
766
+ expanded.value ? props.lessLabel : props.moreLabel(hidden)
767
+ )
768
+ ]);
769
+ };
770
+ }
771
+ });
772
+
773
+ exports.Accordion = Accordion;
774
+ exports.Breadcrumbs = Breadcrumbs;
775
+ exports.Collapsible = Collapsible;
776
+ exports.DisclosureList = DisclosureList;
777
+ exports.NavigationMenu = NavigationMenu;
778
+ exports.Stepper = Stepper;
779
+ exports.Tabs = Tabs;
780
+ //# sourceMappingURL=chunk-KCA7RNJ4.cjs.map
781
+ //# sourceMappingURL=chunk-KCA7RNJ4.cjs.map