@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,269 @@
1
+ 'use strict';
2
+
3
+ var chunk774WBLDR_cjs = require('./chunk-774WBLDR.cjs');
4
+ var chunk6732H4BQ_cjs = require('./chunk-6732H4BQ.cjs');
5
+ var vue = require('vue');
6
+
7
+ var SidebarItem = vue.defineComponent({
8
+ name: "AnshSidebarItem",
9
+ props: {
10
+ item: { type: Object, required: true },
11
+ activeId: { type: String, default: void 0 },
12
+ collapsed: { type: Boolean, required: true },
13
+ depth: { type: Number, required: true }
14
+ },
15
+ emits: ["navigate"],
16
+ setup(props, { emit }) {
17
+ const hasChildren = vue.computed(() => Boolean(props.item.items && props.item.items.length > 0));
18
+ const containsActive = vue.computed(
19
+ () => hasChildren.value && props.item.items.some((child) => child.id === props.activeId)
20
+ );
21
+ const open = vue.ref(containsActive.value);
22
+ const panelId = chunk6732H4BQ_cjs.useId();
23
+ vue.watch(containsActive, (value) => {
24
+ if (value) open.value = true;
25
+ });
26
+ const isActive = vue.computed(() => props.item.id === props.activeId);
27
+ return () => {
28
+ const item = props.item;
29
+ if (hasChildren.value) {
30
+ return vue.h("li", { class: "ansh-sidebar__item" }, [
31
+ vue.h(
32
+ "button",
33
+ {
34
+ type: "button",
35
+ class: chunk6732H4BQ_cjs.cx(
36
+ "ansh-sidebar__link",
37
+ "ansh-sidebar__link--group",
38
+ containsActive.value && "ansh-sidebar__link--within",
39
+ "ansh-focusable"
40
+ ),
41
+ "aria-expanded": open.value,
42
+ "aria-controls": panelId,
43
+ disabled: item.disabled,
44
+ onClick: () => {
45
+ open.value = !open.value;
46
+ }
47
+ },
48
+ [
49
+ item.icon !== void 0 ? vue.h("span", { class: "ansh-sidebar__icon" }, [chunk6732H4BQ_cjs.resolveSlotContent(item.icon)]) : null,
50
+ vue.h(
51
+ "span",
52
+ { class: chunk6732H4BQ_cjs.cx("ansh-sidebar__label", props.collapsed && "ansh-visually-hidden") },
53
+ item.label
54
+ ),
55
+ vue.h(
56
+ "span",
57
+ {
58
+ class: chunk6732H4BQ_cjs.cx("ansh-sidebar__chevron", open.value && "ansh-sidebar__chevron--open"),
59
+ "aria-hidden": "true"
60
+ },
61
+ [
62
+ vue.h("svg", { viewBox: "0 0 12 12", width: "10", height: "10" }, [
63
+ vue.h("path", {
64
+ d: "M3 4.5L6 7.5l3-3",
65
+ stroke: "currentColor",
66
+ "stroke-width": "1.5",
67
+ fill: "none",
68
+ "stroke-linecap": "round",
69
+ "stroke-linejoin": "round"
70
+ })
71
+ ])
72
+ ]
73
+ )
74
+ ]
75
+ ),
76
+ // `hidden` rather than unmounting: the group's open state is cheap to keep, and
77
+ // unmounting would lose scroll position within a long nested list.
78
+ vue.h(
79
+ "ul",
80
+ {
81
+ class: "ansh-sidebar__list ansh-sidebar__list--nested",
82
+ id: panelId,
83
+ hidden: !open.value
84
+ },
85
+ item.items.map(
86
+ (child) => vue.h(SidebarItem, {
87
+ key: child.id,
88
+ item: child,
89
+ activeId: props.activeId,
90
+ collapsed: props.collapsed,
91
+ depth: props.depth + 1,
92
+ onNavigate: (navigated) => emit("navigate", navigated)
93
+ })
94
+ )
95
+ )
96
+ ]);
97
+ }
98
+ const tag = item.href ? "a" : "button";
99
+ return vue.h("li", { class: "ansh-sidebar__item" }, [
100
+ vue.h(
101
+ tag,
102
+ {
103
+ ...item.href ? { href: item.href } : { type: "button" },
104
+ class: chunk6732H4BQ_cjs.cx(
105
+ "ansh-sidebar__link",
106
+ isActive.value && "ansh-sidebar__link--active",
107
+ "ansh-focusable"
108
+ ),
109
+ // The current page, announced. A colour change alone conveys nothing.
110
+ "aria-current": isActive.value ? "page" : void 0,
111
+ "aria-disabled": item.disabled || void 0,
112
+ // A collapsed rail shows only icons, so the label becomes the accessible name via
113
+ // `title` for pointer users and stays in the DOM for everyone else.
114
+ title: props.collapsed ? item.label : void 0,
115
+ onClick: (event) => {
116
+ if (item.disabled) {
117
+ event.preventDefault();
118
+ return;
119
+ }
120
+ item.onClick?.();
121
+ emit("navigate", item);
122
+ }
123
+ },
124
+ [
125
+ item.icon !== void 0 ? vue.h("span", { class: "ansh-sidebar__icon" }, [chunk6732H4BQ_cjs.resolveSlotContent(item.icon)]) : null,
126
+ vue.h(
127
+ "span",
128
+ { class: chunk6732H4BQ_cjs.cx("ansh-sidebar__label", props.collapsed && "ansh-visually-hidden") },
129
+ item.label
130
+ ),
131
+ item.badge !== void 0 && !props.collapsed ? vue.h("span", { class: "ansh-sidebar__badge" }, [chunk6732H4BQ_cjs.resolveSlotContent(item.badge)]) : null
132
+ ]
133
+ )
134
+ ]);
135
+ };
136
+ }
137
+ });
138
+ var Sidebar = vue.defineComponent({
139
+ name: "AnshSidebar",
140
+ inheritAttrs: false,
141
+ props: {
142
+ sections: { type: Array, required: true },
143
+ /** Id of the active item. */
144
+ activeId: { type: String, default: void 0 },
145
+ /** Collapse to an icon rail. */
146
+ collapsed: { type: Boolean, default: void 0 },
147
+ defaultCollapsed: { type: Boolean, default: false },
148
+ /** Show the collapse toggle. Default `true`. */
149
+ collapsible: { type: Boolean, default: true },
150
+ label: { type: String, default: "Main" }
151
+ },
152
+ emits: ["update:collapsed", "navigate"],
153
+ setup(props, { attrs, emit, slots }) {
154
+ const [isCollapsed, setCollapsed] = chunk774WBLDR_cjs.useControllableState(
155
+ () => props.collapsed,
156
+ props.defaultCollapsed,
157
+ (next) => emit("update:collapsed", next)
158
+ );
159
+ return () => {
160
+ const { class: attrClass, ...restAttrs } = attrs;
161
+ return vue.h(
162
+ "nav",
163
+ {
164
+ class: chunk6732H4BQ_cjs.cx(
165
+ "ansh-sidebar",
166
+ isCollapsed.value && "ansh-sidebar--collapsed",
167
+ attrClass
168
+ ),
169
+ "aria-label": props.label,
170
+ "data-collapsed": isCollapsed.value || void 0,
171
+ ...restAttrs
172
+ },
173
+ [
174
+ slots.header ? vue.h("div", { class: "ansh-sidebar__header" }, slots.header()) : null,
175
+ vue.h(
176
+ "div",
177
+ { class: "ansh-sidebar__scroll" },
178
+ props.sections.map(
179
+ (section) => vue.h("div", { class: "ansh-sidebar__section", key: section.id }, [
180
+ section.label ? vue.h(
181
+ "h2",
182
+ {
183
+ // Hidden visually when collapsed but kept for assistive technology, so the
184
+ // grouping survives the rail layout.
185
+ class: chunk6732H4BQ_cjs.cx(
186
+ "ansh-sidebar__heading",
187
+ isCollapsed.value && "ansh-visually-hidden"
188
+ )
189
+ },
190
+ section.label
191
+ ) : null,
192
+ vue.h(
193
+ "ul",
194
+ { class: "ansh-sidebar__list" },
195
+ section.items.map(
196
+ (item) => vue.h(SidebarItem, {
197
+ key: item.id,
198
+ item,
199
+ activeId: props.activeId,
200
+ collapsed: isCollapsed.value,
201
+ depth: 0,
202
+ onNavigate: (navigated) => emit("navigate", navigated)
203
+ })
204
+ )
205
+ )
206
+ ])
207
+ )
208
+ ),
209
+ slots.footer ? vue.h("div", { class: "ansh-sidebar__footer" }, slots.footer()) : null,
210
+ props.collapsible ? vue.h(
211
+ "button",
212
+ {
213
+ type: "button",
214
+ class: "ansh-sidebar__toggle ansh-focusable",
215
+ "aria-label": isCollapsed.value ? "Expand sidebar" : "Collapse sidebar",
216
+ "aria-pressed": isCollapsed.value,
217
+ onClick: () => setCollapsed(!isCollapsed.value)
218
+ },
219
+ [
220
+ vue.h(
221
+ "svg",
222
+ { viewBox: "0 0 16 16", width: "14", height: "14", "aria-hidden": "true" },
223
+ [
224
+ vue.h("path", {
225
+ d: isCollapsed.value ? "M6 3.5L10.5 8L6 12.5" : "M10 3.5L5.5 8L10 12.5",
226
+ stroke: "currentColor",
227
+ "stroke-width": "1.6",
228
+ fill: "none",
229
+ "stroke-linecap": "round",
230
+ "stroke-linejoin": "round"
231
+ })
232
+ ]
233
+ )
234
+ ]
235
+ ) : null
236
+ ]
237
+ );
238
+ };
239
+ }
240
+ });
241
+ var AppShell = vue.defineComponent({
242
+ name: "AnshAppShell",
243
+ inheritAttrs: false,
244
+ setup(_props, { attrs, slots }) {
245
+ return () => {
246
+ const { class: attrClass } = attrs;
247
+ const hasSidebar = Boolean(slots.sidebar);
248
+ return vue.h(
249
+ "div",
250
+ { class: chunk6732H4BQ_cjs.cx("ansh-shell", hasSidebar && "ansh-shell--with-sidebar", attrClass) },
251
+ [
252
+ vue.h("a", { href: "#ansh-main", class: "ansh-skip-link" }, "Skip to main content"),
253
+ slots.header ? vue.h("header", { class: "ansh-shell__header" }, slots.header()) : null,
254
+ hasSidebar ? vue.h("aside", { class: "ansh-shell__sidebar" }, slots.sidebar()) : null,
255
+ vue.h(
256
+ "main",
257
+ { class: "ansh-shell__main", id: "ansh-main", tabindex: "-1" },
258
+ slots.default?.()
259
+ )
260
+ ]
261
+ );
262
+ };
263
+ }
264
+ });
265
+
266
+ exports.AppShell = AppShell;
267
+ exports.Sidebar = Sidebar;
268
+ //# sourceMappingURL=chunk-SHX2JGID.cjs.map
269
+ //# sourceMappingURL=chunk-SHX2JGID.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/navigation/sidebar.ts"],"names":["defineComponent","computed","ref","useId","watch","h","cx","resolveSlotContent","useControllableState"],"mappings":";;;;;;AAyBA,IAAM,cAAcA,mBAAA,CAAgB;AAAA,EAClC,IAAA,EAAM,iBAAA;AAAA,EACN,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAA6B,UAAU,IAAA,EAAK;AAAA,IAC1D,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,MAAA,EAAU;AAAA,IAC7C,SAAA,EAAW,EAAE,IAAA,EAAM,OAAA,EAAS,UAAU,IAAA,EAAK;AAAA,IAC3C,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA;AAAK,GACxC;AAAA,EACA,KAAA,EAAO,CAAC,UAAU,CAAA;AAAA,EAClB,KAAA,CAAM,KAAA,EAAO,EAAE,IAAA,EAAK,EAAG;AACrB,IAAA,MAAM,WAAA,GAAcC,YAAA,CAAS,MAAM,OAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,KAAA,IAAS,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,CAAC,CAAC,CAAA;AAC3F,IAAA,MAAM,cAAA,GAAiBA,YAAA;AAAA,MACrB,MAAM,WAAA,CAAY,KAAA,IAAS,KAAA,CAAM,IAAA,CAAK,KAAA,CAAO,IAAA,CAAK,CAAC,KAAA,KAAU,KAAA,CAAM,EAAA,KAAO,KAAA,CAAM,QAAQ;AAAA,KAC1F;AAGA,IAAA,MAAM,IAAA,GAAOC,OAAA,CAAI,cAAA,CAAe,KAAK,CAAA;AACrC,IAAA,MAAM,UAAUC,uBAAA,EAAM;AAEtB,IAAAC,SAAA,CAAM,cAAA,EAAgB,CAAC,KAAA,KAAU;AAC/B,MAAA,IAAI,KAAA,OAAY,KAAA,GAAQ,IAAA;AAAA,IAC1B,CAAC,CAAA;AAED,IAAA,MAAM,WAAWH,YAAA,CAAS,MAAM,MAAM,IAAA,CAAK,EAAA,KAAO,MAAM,QAAQ,CAAA;AAEhE,IAAA,OAAO,MAAa;AAClB,MAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AAEnB,MAAA,IAAI,YAAY,KAAA,EAAO;AACrB,QAAA,OAAOI,KAAA,CAAE,IAAA,EAAM,EAAE,KAAA,EAAO,sBAAqB,EAAG;AAAA,UAC9CA,KAAA;AAAA,YACE,QAAA;AAAA,YACA;AAAA,cACE,IAAA,EAAM,QAAA;AAAA,cACN,KAAA,EAAOC,oBAAA;AAAA,gBACL,oBAAA;AAAA,gBACA,2BAAA;AAAA,gBACA,eAAe,KAAA,IAAS,4BAAA;AAAA,gBACxB;AAAA,eACF;AAAA,cACA,iBAAiB,IAAA,CAAK,KAAA;AAAA,cACtB,eAAA,EAAiB,OAAA;AAAA,cACjB,UAAU,IAAA,CAAK,QAAA;AAAA,cACf,SAAS,MAAM;AACb,gBAAA,IAAA,CAAK,KAAA,GAAQ,CAAC,IAAA,CAAK,KAAA;AAAA,cACrB;AAAA,aACF;AAAA,YACA;AAAA,cACE,IAAA,CAAK,IAAA,KAAS,MAAA,GACVD,KAAA,CAAE,QAAQ,EAAE,KAAA,EAAO,oBAAA,EAAqB,EAAG,CAACE,oCAAA,CAAmB,IAAA,CAAK,IAAI,CAAC,CAAC,CAAA,GAC1E,IAAA;AAAA,cACJF,KAAA;AAAA,gBACE,MAAA;AAAA,gBACA,EAAE,KAAA,EAAOC,oBAAA,CAAG,uBAAuB,KAAA,CAAM,SAAA,IAAa,sBAAsB,CAAA,EAAE;AAAA,gBAC9E,IAAA,CAAK;AAAA,eACP;AAAA,cACAD,KAAA;AAAA,gBACE,MAAA;AAAA,gBACA;AAAA,kBACE,KAAA,EAAOC,oBAAA,CAAG,uBAAA,EAAyB,IAAA,CAAK,SAAS,6BAA6B,CAAA;AAAA,kBAC9E,aAAA,EAAe;AAAA,iBACjB;AAAA,gBACA;AAAA,kBACED,KAAA,CAAE,OAAO,EAAE,OAAA,EAAS,aAAa,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK,EAAG;AAAA,oBAC5DA,MAAE,MAAA,EAAQ;AAAA,sBACR,CAAA,EAAG,kBAAA;AAAA,sBACH,MAAA,EAAQ,cAAA;AAAA,sBACR,cAAA,EAAgB,KAAA;AAAA,sBAChB,IAAA,EAAM,MAAA;AAAA,sBACN,gBAAA,EAAkB,OAAA;AAAA,sBAClB,iBAAA,EAAmB;AAAA,qBACpB;AAAA,mBACF;AAAA;AACH;AACF;AACF,WACF;AAAA;AAAA;AAAA,UAIAA,KAAA;AAAA,YACE,IAAA;AAAA,YACA;AAAA,cACE,KAAA,EAAO,+CAAA;AAAA,cACP,EAAA,EAAI,OAAA;AAAA,cACJ,MAAA,EAAQ,CAAC,IAAA,CAAK;AAAA,aAChB;AAAA,YACA,KAAK,KAAA,CAAO,GAAA;AAAA,cAAI,CAAC,KAAA,KACfA,KAAA,CAAE,WAAA,EAAa;AAAA,gBACb,KAAK,KAAA,CAAM,EAAA;AAAA,gBACX,IAAA,EAAM,KAAA;AAAA,gBACN,UAAU,KAAA,CAAM,QAAA;AAAA,gBAChB,WAAW,KAAA,CAAM,SAAA;AAAA,gBACjB,KAAA,EAAO,MAAM,KAAA,GAAQ,CAAA;AAAA,gBACrB,UAAA,EAAY,CAAC,SAAA,KAAuB,IAAA,CAAK,YAAY,SAAS;AAAA,eAC/D;AAAA;AACH;AACF,SACD,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,GAAO,GAAA,GAAM,QAAA;AAE9B,MAAA,OAAOA,KAAA,CAAE,IAAA,EAAM,EAAE,KAAA,EAAO,sBAAqB,EAAG;AAAA,QAC9CA,KAAA;AAAA,UACE,GAAA;AAAA,UACA;AAAA,YACE,GAAI,IAAA,CAAK,IAAA,GAAO,EAAE,IAAA,EAAM,KAAK,IAAA,EAAK,GAAI,EAAE,IAAA,EAAM,QAAA,EAAkB;AAAA,YAChE,KAAA,EAAOC,oBAAA;AAAA,cACL,oBAAA;AAAA,cACA,SAAS,KAAA,IAAS,4BAAA;AAAA,cAClB;AAAA,aACF;AAAA;AAAA,YAEA,cAAA,EAAgB,QAAA,CAAS,KAAA,GAAQ,MAAA,GAAS,MAAA;AAAA,YAC1C,eAAA,EAAiB,KAAK,QAAA,IAAY,MAAA;AAAA;AAAA;AAAA,YAGlC,KAAA,EAAO,KAAA,CAAM,SAAA,GAAY,IAAA,CAAK,KAAA,GAAQ,MAAA;AAAA,YACtC,OAAA,EAAS,CAAC,KAAA,KAAsB;AAC9B,cAAA,IAAI,KAAK,QAAA,EAAU;AACjB,gBAAA,KAAA,CAAM,cAAA,EAAe;AACrB,gBAAA;AAAA,cACF;AACA,cAAA,IAAA,CAAK,OAAA,IAAU;AACf,cAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAAA,YACvB;AAAA,WACF;AAAA,UACA;AAAA,YACE,IAAA,CAAK,IAAA,KAAS,MAAA,GACVD,KAAA,CAAE,QAAQ,EAAE,KAAA,EAAO,oBAAA,EAAqB,EAAG,CAACE,oCAAA,CAAmB,IAAA,CAAK,IAAI,CAAC,CAAC,CAAA,GAC1E,IAAA;AAAA,YACJF,KAAA;AAAA,cACE,MAAA;AAAA,cACA,EAAE,KAAA,EAAOC,oBAAA,CAAG,uBAAuB,KAAA,CAAM,SAAA,IAAa,sBAAsB,CAAA,EAAE;AAAA,cAC9E,IAAA,CAAK;AAAA,aACP;AAAA,YACA,KAAK,KAAA,KAAU,MAAA,IAAa,CAAC,KAAA,CAAM,SAAA,GAC/BD,MAAE,MAAA,EAAQ,EAAE,KAAA,EAAO,qBAAA,IAAyB,CAACE,oCAAA,CAAmB,KAAK,KAAK,CAAC,CAAC,CAAA,GAC5E;AAAA;AACN;AACF,OACD,CAAA;AAAA,IACH,CAAA;AAAA,EACF;AACF,CAAC,CAAA;AAiBM,IAAM,UAAUP,mBAAA,CAAgB;AAAA,EACrC,IAAA,EAAM,aAAA;AAAA,EACN,YAAA,EAAc,KAAA;AAAA,EACd,KAAA,EAAO;AAAA,IACL,QAAA,EAAU,EAAE,IAAA,EAAM,KAAA,EAA0C,UAAU,IAAA,EAAK;AAAA;AAAA,IAE3E,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,MAAA,EAAU;AAAA;AAAA,IAE7C,SAAA,EAAW,EAAE,IAAA,EAAM,OAAA,EAAS,SAAS,MAAA,EAAU;AAAA,IAC/C,gBAAA,EAAkB,EAAE,IAAA,EAAM,OAAA,EAAS,SAAS,KAAA,EAAM;AAAA;AAAA,IAElD,WAAA,EAAa,EAAE,IAAA,EAAM,OAAA,EAAS,SAAS,IAAA,EAAK;AAAA,IAC5C,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,MAAA;AAAO,GACzC;AAAA,EACA,KAAA,EAAO,CAAC,kBAAA,EAAoB,UAAU,CAAA;AAAA,EACtC,MAAM,KAAA,EAAO,EAAE,KAAA,EAAO,IAAA,EAAM,OAAM,EAAG;AACnC,IAAA,MAAM,CAAC,WAAA,EAAa,YAAY,CAAA,GAAIQ,sCAAA;AAAA,MAClC,MAAM,KAAA,CAAM,SAAA;AAAA,MACZ,KAAA,CAAM,gBAAA;AAAA,MACN,CAAC,IAAA,KAAS,IAAA,CAAK,kBAAA,EAAoB,IAAI;AAAA,KACzC;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAW,GAAG,WAAU,GAAI,KAAA;AAE3C,MAAA,OAAOH,KAAA;AAAA,QACL,KAAA;AAAA,QACA;AAAA,UACE,KAAA,EAAOC,oBAAA;AAAA,YACL,cAAA;AAAA,YACA,YAAY,KAAA,IAAS,yBAAA;AAAA,YACrB;AAAA,WACF;AAAA,UACA,cAAc,KAAA,CAAM,KAAA;AAAA,UACpB,gBAAA,EAAkB,YAAY,KAAA,IAAS,MAAA;AAAA,UACvC,GAAG;AAAA,SACL;AAAA,QACA;AAAA,UACE,KAAA,CAAM,MAAA,GAASD,KAAA,CAAE,KAAA,EAAO,EAAE,KAAA,EAAO,sBAAA,EAAuB,EAAG,KAAA,CAAM,MAAA,EAAQ,CAAA,GAAI,IAAA;AAAA,UAE7EA,KAAA;AAAA,YACE,KAAA;AAAA,YACA,EAAE,OAAO,sBAAA,EAAuB;AAAA,YAChC,MAAM,QAAA,CAAS,GAAA;AAAA,cAAI,CAAC,OAAA,KAClBA,KAAA,CAAE,KAAA,EAAO,EAAE,OAAO,uBAAA,EAAyB,GAAA,EAAK,OAAA,CAAQ,EAAA,EAAG,EAAG;AAAA,gBAC5D,QAAQ,KAAA,GACJA,KAAA;AAAA,kBACE,IAAA;AAAA,kBACA;AAAA;AAAA;AAAA,oBAGE,KAAA,EAAOC,oBAAA;AAAA,sBACL,uBAAA;AAAA,sBACA,YAAY,KAAA,IAAS;AAAA;AACvB,mBACF;AAAA,kBACA,OAAA,CAAQ;AAAA,iBACV,GACA,IAAA;AAAA,gBAEJD,KAAA;AAAA,kBACE,IAAA;AAAA,kBACA,EAAE,OAAO,oBAAA,EAAqB;AAAA,kBAC9B,QAAQ,KAAA,CAAM,GAAA;AAAA,oBAAI,CAAC,IAAA,KACjBA,KAAA,CAAE,WAAA,EAAa;AAAA,sBACb,KAAK,IAAA,CAAK,EAAA;AAAA,sBACV,IAAA;AAAA,sBACA,UAAU,KAAA,CAAM,QAAA;AAAA,sBAChB,WAAW,WAAA,CAAY,KAAA;AAAA,sBACvB,KAAA,EAAO,CAAA;AAAA,sBACP,UAAA,EAAY,CAAC,SAAA,KAAuB,IAAA,CAAK,YAAY,SAAS;AAAA,qBAC/D;AAAA;AACH;AACF,eACD;AAAA;AACH,WACF;AAAA,UAEA,KAAA,CAAM,MAAA,GAASA,KAAA,CAAE,KAAA,EAAO,EAAE,KAAA,EAAO,sBAAA,EAAuB,EAAG,KAAA,CAAM,MAAA,EAAQ,CAAA,GAAI,IAAA;AAAA,UAE7E,MAAM,WAAA,GACFA,KAAA;AAAA,YACE,QAAA;AAAA,YACA;AAAA,cACE,IAAA,EAAM,QAAA;AAAA,cACN,KAAA,EAAO,qCAAA;AAAA,cACP,YAAA,EAAc,WAAA,CAAY,KAAA,GAAQ,gBAAA,GAAmB,kBAAA;AAAA,cACrD,gBAAgB,WAAA,CAAY,KAAA;AAAA,cAC5B,OAAA,EAAS,MAAM,YAAA,CAAa,CAAC,YAAY,KAAK;AAAA,aAChD;AAAA,YACA;AAAA,cACEA,KAAA;AAAA,gBACE,KAAA;AAAA,gBACA,EAAE,SAAS,WAAA,EAAa,KAAA,EAAO,MAAM,MAAA,EAAQ,IAAA,EAAM,eAAe,MAAA,EAAO;AAAA,gBACzE;AAAA,kBACEA,MAAE,MAAA,EAAQ;AAAA,oBACR,CAAA,EAAG,WAAA,CAAY,KAAA,GAAQ,sBAAA,GAAyB,uBAAA;AAAA,oBAChD,MAAA,EAAQ,cAAA;AAAA,oBACR,cAAA,EAAgB,KAAA;AAAA,oBAChB,IAAA,EAAM,MAAA;AAAA,oBACN,gBAAA,EAAkB,OAAA;AAAA,oBAClB,iBAAA,EAAmB;AAAA,mBACpB;AAAA;AACH;AACF;AACF,WACF,GACA;AAAA;AACN,OACF;AAAA,IACF,CAAA;AAAA,EACF;AACF,CAAC;AAgBM,IAAM,WAAWL,mBAAA,CAAgB;AAAA,EACtC,IAAA,EAAM,cAAA;AAAA,EACN,YAAA,EAAc,KAAA;AAAA,EACd,KAAA,CAAM,MAAA,EAAQ,EAAE,KAAA,EAAO,OAAM,EAAG;AAC9B,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,KAAA;AAC7B,MAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA;AAExC,MAAA,OAAOK,KAAA;AAAA,QACL,KAAA;AAAA,QACA,EAAE,KAAA,EAAOC,oBAAA,CAAG,cAAc,UAAA,IAAc,0BAAA,EAA4B,SAAmB,CAAA,EAAE;AAAA,QACzF;AAAA,UACED,KAAA,CAAE,KAAK,EAAE,IAAA,EAAM,cAAc,KAAA,EAAO,gBAAA,IAAoB,sBAAsB,CAAA;AAAA,UAC9E,KAAA,CAAM,MAAA,GAASA,KAAA,CAAE,QAAA,EAAU,EAAE,KAAA,EAAO,oBAAA,EAAqB,EAAG,KAAA,CAAM,MAAA,EAAQ,CAAA,GAAI,IAAA;AAAA,UAC9E,UAAA,GAAaA,KAAA,CAAE,OAAA,EAAS,EAAE,KAAA,EAAO,uBAAsB,EAAG,KAAA,CAAM,OAAA,EAAU,CAAA,GAAI,IAAA;AAAA,UAC9EA,KAAA;AAAA,YACE,MAAA;AAAA,YACA,EAAE,KAAA,EAAO,kBAAA,EAAoB,EAAA,EAAI,WAAA,EAAa,UAAU,IAAA,EAAK;AAAA,YAC7D,MAAM,OAAA;AAAU;AAClB;AACF,OACF;AAAA,IACF,CAAA;AAAA,EACF;AACF,CAAC","file":"chunk-SHX2JGID.cjs","sourcesContent":["import { type PropType, type VNode, computed, defineComponent, h, ref, watch } from 'vue'\nimport { type SlotContent, cx, resolveSlotContent, useId } from '../../primitives/utils'\nimport { useControllableState } from '../../primitives/use-controllable-state'\n\nexport interface NavItem {\n id: string\n label: string\n href?: string\n icon?: SlotContent\n /** Count or status shown on the right. */\n badge?: SlotContent\n disabled?: boolean\n onClick?: () => void\n /** Nested items, rendered in a collapsible group. */\n items?: readonly NavItem[]\n}\n\nexport interface NavSection {\n id: string\n /** Heading above the group. Omit for an unlabelled block. */\n label?: string\n items: readonly NavItem[]\n}\n\n/** Internal — a single entry (leaf link or expandable group) inside `Sidebar`. Not exported. */\nconst SidebarItem = defineComponent({\n name: 'AnshSidebarItem',\n props: {\n item: { type: Object as PropType<NavItem>, required: true },\n activeId: { type: String, default: undefined },\n collapsed: { type: Boolean, required: true },\n depth: { type: Number, required: true },\n },\n emits: ['navigate'],\n setup(props, { emit }) {\n const hasChildren = computed(() => Boolean(props.item.items && props.item.items.length > 0))\n const containsActive = computed(\n () => hasChildren.value && props.item.items!.some((child) => child.id === props.activeId),\n )\n // Groups start open when they contain the active page — landing on a nested route with the\n // group collapsed leaves the user with no visible indication of where they are.\n const open = ref(containsActive.value)\n const panelId = useId()\n\n watch(containsActive, (value) => {\n if (value) open.value = true\n })\n\n const isActive = computed(() => props.item.id === props.activeId)\n\n return (): VNode => {\n const item = props.item\n\n if (hasChildren.value) {\n return h('li', { class: 'ansh-sidebar__item' }, [\n h(\n 'button',\n {\n type: 'button',\n class: cx(\n 'ansh-sidebar__link',\n 'ansh-sidebar__link--group',\n containsActive.value && 'ansh-sidebar__link--within',\n 'ansh-focusable',\n ),\n 'aria-expanded': open.value,\n 'aria-controls': panelId,\n disabled: item.disabled,\n onClick: () => {\n open.value = !open.value\n },\n },\n [\n item.icon !== undefined\n ? h('span', { class: 'ansh-sidebar__icon' }, [resolveSlotContent(item.icon)])\n : null,\n h(\n 'span',\n { class: cx('ansh-sidebar__label', props.collapsed && 'ansh-visually-hidden') },\n item.label,\n ),\n h(\n 'span',\n {\n class: cx('ansh-sidebar__chevron', open.value && 'ansh-sidebar__chevron--open'),\n 'aria-hidden': 'true',\n },\n [\n h('svg', { viewBox: '0 0 12 12', width: '10', height: '10' }, [\n h('path', {\n d: 'M3 4.5L6 7.5l3-3',\n stroke: 'currentColor',\n 'stroke-width': '1.5',\n fill: 'none',\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n }),\n ]),\n ],\n ),\n ],\n ),\n\n // `hidden` rather than unmounting: the group's open state is cheap to keep, and\n // unmounting would lose scroll position within a long nested list.\n h(\n 'ul',\n {\n class: 'ansh-sidebar__list ansh-sidebar__list--nested',\n id: panelId,\n hidden: !open.value,\n },\n item.items!.map((child) =>\n h(SidebarItem, {\n key: child.id,\n item: child,\n activeId: props.activeId,\n collapsed: props.collapsed,\n depth: props.depth + 1,\n onNavigate: (navigated: NavItem) => emit('navigate', navigated),\n }),\n ),\n ),\n ])\n }\n\n const tag = item.href ? 'a' : 'button'\n\n return h('li', { class: 'ansh-sidebar__item' }, [\n h(\n tag,\n {\n ...(item.href ? { href: item.href } : { type: 'button' as const }),\n class: cx(\n 'ansh-sidebar__link',\n isActive.value && 'ansh-sidebar__link--active',\n 'ansh-focusable',\n ),\n // The current page, announced. A colour change alone conveys nothing.\n 'aria-current': isActive.value ? 'page' : undefined,\n 'aria-disabled': item.disabled || undefined,\n // A collapsed rail shows only icons, so the label becomes the accessible name via\n // `title` for pointer users and stays in the DOM for everyone else.\n title: props.collapsed ? item.label : undefined,\n onClick: (event: MouseEvent) => {\n if (item.disabled) {\n event.preventDefault()\n return\n }\n item.onClick?.()\n emit('navigate', item)\n },\n },\n [\n item.icon !== undefined\n ? h('span', { class: 'ansh-sidebar__icon' }, [resolveSlotContent(item.icon)])\n : null,\n h(\n 'span',\n { class: cx('ansh-sidebar__label', props.collapsed && 'ansh-visually-hidden') },\n item.label,\n ),\n item.badge !== undefined && !props.collapsed\n ? h('span', { class: 'ansh-sidebar__badge' }, [resolveSlotContent(item.badge)])\n : null,\n ],\n ),\n ])\n }\n },\n})\n\n/**\n * The application sidebar — the Vue counterpart of `@ansh-ui/react`'s `Sidebar`.\n *\n * A `<nav>` containing lists of links — the structure a screen reader user navigates by landmark,\n * and the reason this isn't a stack of divs. Nested groups are `<button aria-expanded>` controlling\n * a `<ul>`, so their state is announced.\n *\n * Collapsing to an icon rail keeps the labels in the DOM (visually hidden), rather than removing\n * them. Removing them would leave a rail of unlabelled icons for anyone using assistive technology,\n * which is exactly the population for whom the space saving is irrelevant.\n *\n * `header`/`footer` are React props of arbitrary content in the source; here they are the `#header`\n * and `#footer` slots — passing a whole render tree through a prop is idiomatic React and awkward\n * Vue, the same reasoning `HoverCard`'s `#content` slot documents.\n */\nexport const Sidebar = defineComponent({\n name: 'AnshSidebar',\n inheritAttrs: false,\n props: {\n sections: { type: Array as PropType<readonly NavSection[]>, required: true },\n /** Id of the active item. */\n activeId: { type: String, default: undefined },\n /** Collapse to an icon rail. */\n collapsed: { type: Boolean, default: undefined },\n defaultCollapsed: { type: Boolean, default: false },\n /** Show the collapse toggle. Default `true`. */\n collapsible: { type: Boolean, default: true },\n label: { type: String, default: 'Main' },\n },\n emits: ['update:collapsed', 'navigate'],\n setup(props, { attrs, emit, slots }) {\n const [isCollapsed, setCollapsed] = useControllableState(\n () => props.collapsed,\n props.defaultCollapsed,\n (next) => emit('update:collapsed', next),\n )\n\n return () => {\n const { class: attrClass, ...restAttrs } = attrs as Record<string, unknown>\n\n return h(\n 'nav',\n {\n class: cx(\n 'ansh-sidebar',\n isCollapsed.value && 'ansh-sidebar--collapsed',\n attrClass as string,\n ),\n 'aria-label': props.label,\n 'data-collapsed': isCollapsed.value || undefined,\n ...restAttrs,\n },\n [\n slots.header ? h('div', { class: 'ansh-sidebar__header' }, slots.header()) : null,\n\n h(\n 'div',\n { class: 'ansh-sidebar__scroll' },\n props.sections.map((section) =>\n h('div', { class: 'ansh-sidebar__section', key: section.id }, [\n section.label\n ? h(\n 'h2',\n {\n // Hidden visually when collapsed but kept for assistive technology, so the\n // grouping survives the rail layout.\n class: cx(\n 'ansh-sidebar__heading',\n isCollapsed.value && 'ansh-visually-hidden',\n ),\n },\n section.label,\n )\n : null,\n\n h(\n 'ul',\n { class: 'ansh-sidebar__list' },\n section.items.map((item) =>\n h(SidebarItem, {\n key: item.id,\n item,\n activeId: props.activeId,\n collapsed: isCollapsed.value,\n depth: 0,\n onNavigate: (navigated: NavItem) => emit('navigate', navigated),\n }),\n ),\n ),\n ]),\n ),\n ),\n\n slots.footer ? h('div', { class: 'ansh-sidebar__footer' }, slots.footer()) : null,\n\n props.collapsible\n ? h(\n 'button',\n {\n type: 'button',\n class: 'ansh-sidebar__toggle ansh-focusable',\n 'aria-label': isCollapsed.value ? 'Expand sidebar' : 'Collapse sidebar',\n 'aria-pressed': isCollapsed.value,\n onClick: () => setCollapsed(!isCollapsed.value),\n },\n [\n h(\n 'svg',\n { viewBox: '0 0 16 16', width: '14', height: '14', 'aria-hidden': 'true' },\n [\n h('path', {\n d: isCollapsed.value ? 'M6 3.5L10.5 8L6 12.5' : 'M10 3.5L5.5 8L10 12.5',\n stroke: 'currentColor',\n 'stroke-width': '1.6',\n fill: 'none',\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n }),\n ],\n ),\n ],\n )\n : null,\n ],\n )\n }\n },\n})\n\n/**\n * The header + sidebar + content frame — the Vue counterpart of `@ansh-ui/react`'s `AppShell`.\n *\n * A grid rather than nested flex containers, so the sidebar and header can be `position: sticky`\n * without the content needing compensating margins — the arrangement that breaks the moment the\n * header's height changes.\n *\n * The skip link is the first focusable element on the page. It is the cheapest accessibility win\n * available and it is missing from almost every application shell: without it, a keyboard user\n * traverses the entire navigation on every single page load.\n *\n * `sidebar`/`header` are the `#sidebar`/`#header` slots (see `Sidebar`'s doc comment for why); the\n * main content is the default slot.\n */\nexport const AppShell = defineComponent({\n name: 'AnshAppShell',\n inheritAttrs: false,\n setup(_props, { attrs, slots }) {\n return () => {\n const { class: attrClass } = attrs as Record<string, unknown>\n const hasSidebar = Boolean(slots.sidebar)\n\n return h(\n 'div',\n { class: cx('ansh-shell', hasSidebar && 'ansh-shell--with-sidebar', attrClass as string) },\n [\n h('a', { href: '#ansh-main', class: 'ansh-skip-link' }, 'Skip to main content'),\n slots.header ? h('header', { class: 'ansh-shell__header' }, slots.header()) : null,\n hasSidebar ? h('aside', { class: 'ansh-shell__sidebar' }, slots.sidebar!()) : null,\n h(\n 'main',\n { class: 'ansh-shell__main', id: 'ansh-main', tabindex: '-1' },\n slots.default?.(),\n ),\n ],\n )\n }\n },\n})\n"]}