@juxtui/ui 0.2.0 → 0.3.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 (37) hide show
  1. package/README.md +1 -1
  2. package/dist/components/aspect-ratio/JAspectRatio.vue.d.ts +18 -0
  3. package/dist/components/avatar/JAvatar.vue.d.ts +1 -1
  4. package/dist/components/avatar-group/JAvatarGroup.vue.d.ts +19 -0
  5. package/dist/components/banner/JBanner.vue.d.ts +30 -0
  6. package/dist/components/breadcrumb/JBreadcrumb.vue.d.ts +29 -0
  7. package/dist/components/card/JCard.vue.d.ts +1 -1
  8. package/dist/components/collapsible/JCollapsible.vue.d.ts +28 -0
  9. package/dist/components/command-palette/JCommandPalette.vue.d.ts +1 -1
  10. package/dist/components/dropdown-menu/JDropdownMenu.vue.d.ts +1 -1
  11. package/dist/components/empty-state/JEmptyState.vue.d.ts +23 -0
  12. package/dist/components/field/JFieldShell.vue.d.ts +1 -1
  13. package/dist/components/pagination/JPagination.vue.d.ts +25 -0
  14. package/dist/components/primitives/JSlot.d.ts +1 -1
  15. package/dist/components/rating/JRating.vue.d.ts +27 -0
  16. package/dist/components/slider/JSlider.vue.d.ts +31 -0
  17. package/dist/components/stat/JStat.vue.d.ts +22 -0
  18. package/dist/components/tag/JTag.vue.d.ts +28 -0
  19. package/dist/components/timeline/JTimeline.vue.d.ts +12 -0
  20. package/dist/components/timeline/JTimelineItem.vue.d.ts +24 -0
  21. package/dist/components/toast/JToaster.vue.d.ts +1 -1
  22. package/dist/components/toggle-group/JToggleGroup.vue.d.ts +33 -0
  23. package/dist/components/toggle-group/JToggleGroupItem.vue.d.ts +19 -0
  24. package/dist/components/toggle-group/context.d.ts +9 -0
  25. package/dist/components/visually-hidden/JVisuallyHidden.vue.d.ts +19 -0
  26. package/dist/components.d.ts +16 -0
  27. package/dist/composables/useModal.d.ts +1 -1
  28. package/dist/composables/useToast.d.ts +1 -1
  29. package/dist/icons.d.ts +4 -0
  30. package/dist/index.d.ts +16 -0
  31. package/dist/index.js +1161 -196
  32. package/dist/index.js.map +1 -1
  33. package/dist/nuxt.js +17 -1
  34. package/dist/nuxt.js.map +1 -1
  35. package/dist/style.css +1526 -548
  36. package/dist/tokens.css +5 -5
  37. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Comment, Fragment, Teleport, Text, Transition, TransitionGroup, cloneVNode, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createTextVNode, createVNode, defineComponent, h, inject, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, provide, reactive, readonly, ref, renderList, renderSlot, resolveDynamicComponent, shallowRef, toDisplayString, toRef, toValue, unref, useId, useModel, vModelDynamic, vModelText, watch, watchEffect, withCtx, withDirectives, withModifiers } from "vue";
1
+ import { Comment, Fragment, Teleport, Text, Transition, TransitionGroup, cloneVNode, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createTextVNode, createVNode, defineComponent, h, inject, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, provide, reactive, readonly, ref, renderList, renderSlot, resolveDynamicComponent, shallowRef, toDisplayString, toRef, toValue, unref, useId, useModel, useSlots, vModelDynamic, vModelText, watch, watchEffect, withCtx, withDirectives, withModifiers } from "vue";
2
2
  import { autoUpdate, computePosition, flip, offset, shift, size } from "@floating-ui/dom";
3
3
  //#region \0rolldown/runtime.js
4
4
  var __defProp = Object.defineProperty;
@@ -192,6 +192,32 @@ var IconInfo = icon("IconInfo", () => [
192
192
  })
193
193
  ]);
194
194
  icon("IconCornerDownLeft", () => [h("path", { d: "M12.5 3.5v4.25a2 2 0 0 1-2 2h-7" }), h("path", { d: "M6 7l-2.5 2.75L6 12.5" })]);
195
+ var IconChevronLeft = icon("IconChevronLeft", () => [h("path", { d: "M9.75 4.5L6.25 8l3.5 3.5" })]);
196
+ var IconMoreHorizontal = icon("IconMoreHorizontal", () => [
197
+ h("circle", {
198
+ cx: 3.5,
199
+ cy: 8,
200
+ r: 1,
201
+ "fill": "currentColor",
202
+ "stroke": "none"
203
+ }),
204
+ h("circle", {
205
+ cx: 8,
206
+ cy: 8,
207
+ r: 1,
208
+ "fill": "currentColor",
209
+ "stroke": "none"
210
+ }),
211
+ h("circle", {
212
+ cx: 12.5,
213
+ cy: 8,
214
+ r: 1,
215
+ "fill": "currentColor",
216
+ "stroke": "none"
217
+ })
218
+ ]);
219
+ var IconArrowUpRight = icon("IconArrowUpRight", () => [h("path", { d: "M5 11L11 5M5.5 5h5.5v5.5" })]);
220
+ var IconArrowDownRight = icon("IconArrowDownRight", () => [h("path", { d: "M5 5l6 6M10.5 11H5V5.5" })]);
195
221
  /** The loading spinner used across Juxt. A quarter arc over a faint track. */
196
222
  var Spinner = (props) => {
197
223
  const size = props.size ?? 16;
@@ -220,12 +246,12 @@ var Spinner = (props) => {
220
246
  Spinner.displayName = "JSpinner";
221
247
  //#endregion
222
248
  //#region src/components/accordion/JAccordionItem.vue?vue&type=script&setup=true&lang.ts
223
- var _hoisted_1$28 = ["data-state"];
224
- var _hoisted_2$22 = ["aria-expanded", "disabled"];
225
- var _hoisted_3$19 = { class: "j-accordion__title" };
226
- var _hoisted_4$14 = ["inert"];
227
- var _hoisted_5$10 = { class: "j-accordion__panel-inner" };
228
- var _hoisted_6$6 = { class: "j-accordion__content" };
249
+ var _hoisted_1$43 = ["data-state"];
250
+ var _hoisted_2$33 = ["aria-expanded", "disabled"];
251
+ var _hoisted_3$27 = { class: "j-accordion__title" };
252
+ var _hoisted_4$21 = ["inert"];
253
+ var _hoisted_5$16 = { class: "j-accordion__panel-inner" };
254
+ var _hoisted_6$10 = { class: "j-accordion__content" };
229
255
  //#endregion
230
256
  //#region src/components/accordion/JAccordionItem.vue
231
257
  var JAccordionItem_default = /* @__PURE__ */ defineComponent({
@@ -256,7 +282,7 @@ var JAccordionItem_default = /* @__PURE__ */ defineComponent({
256
282
  "aria-controls": panelId,
257
283
  disabled: __props.disabled,
258
284
  onClick: _cache[0] || (_cache[0] = ($event) => unref(accordion).toggle(__props.value))
259
- }, [createElementVNode("span", _hoisted_3$19, [renderSlot(_ctx.$slots, "title", {}, () => [createTextVNode(toDisplayString(__props.title), 1)])]), createVNode(unref(IconChevronDown), { class: "j-accordion__chevron" })], 8, _hoisted_2$22)]),
285
+ }, [createElementVNode("span", _hoisted_3$27, [renderSlot(_ctx.$slots, "title", {}, () => [createTextVNode(toDisplayString(__props.title), 1)])]), createVNode(unref(IconChevronDown), { class: "j-accordion__chevron" })], 8, _hoisted_2$33)]),
260
286
  _: 3
261
287
  })), createElementVNode("div", {
262
288
  id: panelId,
@@ -264,27 +290,27 @@ var JAccordionItem_default = /* @__PURE__ */ defineComponent({
264
290
  class: "j-accordion__panel",
265
291
  "aria-labelledby": triggerId,
266
292
  inert: !open.value
267
- }, [createElementVNode("div", _hoisted_5$10, [createElementVNode("div", _hoisted_6$6, [renderSlot(_ctx.$slots, "default")])])], 8, _hoisted_4$14)], 10, _hoisted_1$28);
293
+ }, [createElementVNode("div", _hoisted_5$16, [createElementVNode("div", _hoisted_6$10, [renderSlot(_ctx.$slots, "default")])])], 8, _hoisted_4$21)], 10, _hoisted_1$43);
268
294
  };
269
295
  }
270
296
  });
271
297
  //#endregion
272
298
  //#region src/components/alert/JAlert.vue?vue&type=script&setup=true&lang.ts
273
- var _hoisted_1$27 = {
299
+ var _hoisted_1$42 = {
274
300
  key: 0,
275
301
  class: "j-alert__icon",
276
302
  "aria-hidden": "true"
277
303
  };
278
- var _hoisted_2$21 = { class: "j-alert__body" };
279
- var _hoisted_3$18 = {
304
+ var _hoisted_2$32 = { class: "j-alert__body" };
305
+ var _hoisted_3$26 = {
280
306
  key: 0,
281
307
  class: "j-alert__title"
282
308
  };
283
- var _hoisted_4$13 = {
309
+ var _hoisted_4$20 = {
284
310
  key: 1,
285
311
  class: "j-alert__description"
286
312
  };
287
- var _hoisted_5$9 = {
313
+ var _hoisted_5$15 = {
288
314
  key: 2,
289
315
  class: "j-alert__actions"
290
316
  };
@@ -311,11 +337,11 @@ var JAlert_default = /* @__PURE__ */ defineComponent({
311
337
  };
312
338
  return (_ctx, _cache) => {
313
339
  return openBlock(), createElementBlock("div", { class: normalizeClass(["j-alert", `j-alert--${__props.variant}`]) }, [
314
- !__props.hideIcon ? (openBlock(), createElementBlock("span", _hoisted_1$27, [renderSlot(_ctx.$slots, "icon", {}, () => [(openBlock(), createBlock(resolveDynamicComponent(icons[__props.variant])))])])) : createCommentVNode("", true),
315
- createElementVNode("div", _hoisted_2$21, [
316
- __props.title ? (openBlock(), createElementBlock("p", _hoisted_3$18, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
317
- __props.description || _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_4$13, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])])) : createCommentVNode("", true),
318
- _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_5$9, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true)
340
+ !__props.hideIcon ? (openBlock(), createElementBlock("span", _hoisted_1$42, [renderSlot(_ctx.$slots, "icon", {}, () => [(openBlock(), createBlock(resolveDynamicComponent(icons[__props.variant])))])])) : createCommentVNode("", true),
341
+ createElementVNode("div", _hoisted_2$32, [
342
+ __props.title ? (openBlock(), createElementBlock("p", _hoisted_3$26, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
343
+ __props.description || _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_4$20, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])])) : createCommentVNode("", true),
344
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_5$15, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true)
319
345
  ]),
320
346
  __props.dismissible ? (openBlock(), createElementBlock("button", {
321
347
  key: 1,
@@ -329,20 +355,39 @@ var JAlert_default = /* @__PURE__ */ defineComponent({
329
355
  }
330
356
  });
331
357
  //#endregion
358
+ //#region src/components/aspect-ratio/JAspectRatio.vue?vue&type=script&setup=true&lang.ts
359
+ var _hoisted_1$41 = { class: "j-aspect-ratio__content" };
360
+ //#endregion
361
+ //#region src/components/aspect-ratio/JAspectRatio.vue
362
+ var JAspectRatio_default = /* @__PURE__ */ defineComponent({
363
+ __name: "JAspectRatio",
364
+ props: { ratio: { default: 16 / 9 } },
365
+ setup(__props) {
366
+ const props = __props;
367
+ const style = computed(() => ({ "--j-aspect-ratio": String(props.ratio) }));
368
+ return (_ctx, _cache) => {
369
+ return openBlock(), createElementBlock("div", {
370
+ class: "j-aspect-ratio",
371
+ style: normalizeStyle(style.value)
372
+ }, [createElementVNode("div", _hoisted_1$41, [renderSlot(_ctx.$slots, "default")])], 4);
373
+ };
374
+ }
375
+ });
376
+ //#endregion
332
377
  //#region src/components/avatar/JAvatar.vue?vue&type=script&setup=true&lang.ts
333
- var _hoisted_1$26 = [
378
+ var _hoisted_1$40 = [
334
379
  "role",
335
380
  "aria-label",
336
381
  "data-state"
337
382
  ];
338
- var _hoisted_2$20 = { class: "j-avatar__frame" };
339
- var _hoisted_3$17 = ["src"];
340
- var _hoisted_4$12 = {
383
+ var _hoisted_2$31 = { class: "j-avatar__frame" };
384
+ var _hoisted_3$25 = ["src"];
385
+ var _hoisted_4$19 = {
341
386
  key: 1,
342
387
  class: "j-avatar__fallback",
343
388
  "aria-hidden": "true"
344
389
  };
345
- var _hoisted_5$8 = {
390
+ var _hoisted_5$14 = {
346
391
  key: 1,
347
392
  viewBox: "0 0 16 16",
348
393
  fill: "currentColor",
@@ -394,7 +439,7 @@ var JAvatar_default = /* @__PURE__ */ defineComponent({
394
439
  role: label.value ? "img" : void 0,
395
440
  "aria-label": label.value,
396
441
  "data-state": state.value
397
- }, [createElementVNode("span", _hoisted_2$20, [__props.src && state.value !== "error" ? (openBlock(), createElementBlock("img", {
442
+ }, [createElementVNode("span", _hoisted_2$31, [__props.src && state.value !== "error" ? (openBlock(), createElementBlock("img", {
398
443
  key: 0,
399
444
  ref_key: "img",
400
445
  ref: img,
@@ -403,7 +448,7 @@ var JAvatar_default = /* @__PURE__ */ defineComponent({
403
448
  alt: "",
404
449
  onLoad: _cache[0] || (_cache[0] = ($event) => state.value = "loaded"),
405
450
  onError: _cache[1] || (_cache[1] = ($event) => state.value = "error")
406
- }, null, 40, _hoisted_3$17)) : createCommentVNode("", true), state.value !== "loaded" ? (openBlock(), createElementBlock("span", _hoisted_4$12, [renderSlot(_ctx.$slots, "fallback", {}, () => [initials.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(initials.value), 1)], 64)) : (openBlock(), createElementBlock("svg", _hoisted_5$8, [..._cache[2] || (_cache[2] = [createElementVNode("circle", {
451
+ }, null, 40, _hoisted_3$25)) : createCommentVNode("", true), state.value !== "loaded" ? (openBlock(), createElementBlock("span", _hoisted_4$19, [renderSlot(_ctx.$slots, "fallback", {}, () => [initials.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(initials.value), 1)], 64)) : (openBlock(), createElementBlock("svg", _hoisted_5$14, [..._cache[2] || (_cache[2] = [createElementVNode("circle", {
407
452
  cx: "8",
408
453
  cy: "6",
409
454
  r: "2.75"
@@ -411,18 +456,67 @@ var JAvatar_default = /* @__PURE__ */ defineComponent({
411
456
  key: 0,
412
457
  class: normalizeClass(["j-avatar__status", `j-avatar__status--${__props.status}`]),
413
458
  "aria-hidden": "true"
414
- }, null, 2)) : createCommentVNode("", true)], 10, _hoisted_1$26);
459
+ }, null, 2)) : createCommentVNode("", true)], 10, _hoisted_1$40);
460
+ };
461
+ }
462
+ });
463
+ //#endregion
464
+ //#region src/components/avatar-group/JAvatarGroup.vue?vue&type=script&setup=true&lang.ts
465
+ var _hoisted_1$39 = ["aria-label"];
466
+ var _hoisted_2$30 = ["aria-label"];
467
+ //#endregion
468
+ //#region src/components/avatar-group/JAvatarGroup.vue
469
+ var JAvatarGroup_default = /* @__PURE__ */ defineComponent({
470
+ __name: "JAvatarGroup",
471
+ props: {
472
+ items: {},
473
+ max: {},
474
+ size: { default: "md" },
475
+ shape: { default: "circle" },
476
+ label: {}
477
+ },
478
+ setup(__props) {
479
+ const props = __props;
480
+ const visible = computed(() => props.max ? props.items.slice(0, props.max) : props.items);
481
+ const overflow = computed(() => Math.max(0, props.items.length - visible.value.length));
482
+ const groupLabel = computed(() => props.label ?? `${props.items.length} ${props.items.length === 1 ? "avatar" : "avatars"}`);
483
+ return (_ctx, _cache) => {
484
+ return openBlock(), createElementBlock("div", {
485
+ class: normalizeClass(["j-avatar-group", `j-avatar-group--${__props.size}`]),
486
+ role: "group",
487
+ "aria-label": groupLabel.value
488
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(visible.value, (item, index) => {
489
+ return openBlock(), createElementBlock("span", {
490
+ key: index,
491
+ class: "j-avatar-group__item"
492
+ }, [createVNode(JAvatar_default, {
493
+ src: item.src,
494
+ name: item.name,
495
+ size: __props.size,
496
+ shape: __props.shape
497
+ }, null, 8, [
498
+ "src",
499
+ "name",
500
+ "size",
501
+ "shape"
502
+ ])]);
503
+ }), 128)), overflow.value > 0 ? (openBlock(), createElementBlock("span", {
504
+ key: 0,
505
+ class: normalizeClass(["j-avatar-group__item j-avatar-group__overflow j-focusable", { "j-avatar-group__overflow--square": __props.shape === "square" }]),
506
+ tabindex: "0",
507
+ "aria-label": `${overflow.value} more`
508
+ }, " +" + toDisplayString(overflow.value), 11, _hoisted_2$30)) : createCommentVNode("", true)], 10, _hoisted_1$39);
415
509
  };
416
510
  }
417
511
  });
418
512
  //#endregion
419
513
  //#region src/components/badge/JBadge.vue?vue&type=script&setup=true&lang.ts
420
- var _hoisted_1$25 = {
514
+ var _hoisted_1$38 = {
421
515
  key: 0,
422
516
  class: "j-badge__marker",
423
517
  "aria-hidden": "true"
424
518
  };
425
- var _hoisted_2$19 = {
519
+ var _hoisted_2$29 = {
426
520
  key: 1,
427
521
  class: "j-badge__icon"
428
522
  };
@@ -441,22 +535,145 @@ var JBadge_default = /* @__PURE__ */ defineComponent({
441
535
  `j-badge--${__props.variant}`,
442
536
  `j-badge--${__props.size}`,
443
537
  { "j-badge--status": __props.dot }
444
- ]]) }, [__props.dot ? (openBlock(), createElementBlock("span", _hoisted_1$25)) : _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$19, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true), renderSlot(_ctx.$slots, "default")], 2);
538
+ ]]) }, [__props.dot ? (openBlock(), createElementBlock("span", _hoisted_1$38)) : _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$29, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true), renderSlot(_ctx.$slots, "default")], 2);
539
+ };
540
+ }
541
+ });
542
+ //#endregion
543
+ //#region src/components/banner/JBanner.vue?vue&type=script&setup=true&lang.ts
544
+ var _hoisted_1$37 = ["aria-label"];
545
+ var _hoisted_2$28 = {
546
+ key: 0,
547
+ class: "j-banner__icon",
548
+ "aria-hidden": "true"
549
+ };
550
+ var _hoisted_3$24 = { class: "j-banner__body" };
551
+ var _hoisted_4$18 = {
552
+ key: 0,
553
+ class: "j-banner__title"
554
+ };
555
+ var _hoisted_5$13 = {
556
+ key: 1,
557
+ class: "j-banner__description"
558
+ };
559
+ var _hoisted_6$9 = {
560
+ key: 1,
561
+ class: "j-banner__actions"
562
+ };
563
+ //#endregion
564
+ //#region src/components/banner/JBanner.vue
565
+ var JBanner_default = /* @__PURE__ */ defineComponent({
566
+ __name: "JBanner",
567
+ props: {
568
+ variant: { default: "neutral" },
569
+ title: {},
570
+ description: {},
571
+ dismissible: { type: Boolean },
572
+ hideIcon: { type: Boolean }
573
+ },
574
+ emits: ["dismiss"],
575
+ setup(__props, { emit: __emit }) {
576
+ const emit = __emit;
577
+ const icons = {
578
+ neutral: IconInfo,
579
+ info: IconInfo,
580
+ success: IconCircleCheck,
581
+ warning: IconAlert,
582
+ destructive: IconCircleX
583
+ };
584
+ return (_ctx, _cache) => {
585
+ return openBlock(), createElementBlock("div", {
586
+ class: normalizeClass(["j-banner", `j-banner--${__props.variant}`]),
587
+ role: "region",
588
+ "aria-label": __props.title
589
+ }, [
590
+ !__props.hideIcon ? (openBlock(), createElementBlock("span", _hoisted_2$28, [renderSlot(_ctx.$slots, "icon", {}, () => [(openBlock(), createBlock(resolveDynamicComponent(icons[__props.variant])))])])) : createCommentVNode("", true),
591
+ createElementVNode("div", _hoisted_3$24, [__props.title ? (openBlock(), createElementBlock("p", _hoisted_4$18, toDisplayString(__props.title), 1)) : createCommentVNode("", true), __props.description || _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_5$13, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])])) : createCommentVNode("", true)]),
592
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_6$9, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true),
593
+ __props.dismissible ? (openBlock(), createElementBlock("button", {
594
+ key: 2,
595
+ type: "button",
596
+ class: "j-banner__close j-focusable",
597
+ "aria-label": "Dismiss",
598
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("dismiss"))
599
+ }, [createVNode(unref(IconX))])) : createCommentVNode("", true)
600
+ ], 10, _hoisted_1$37);
601
+ };
602
+ }
603
+ });
604
+ //#endregion
605
+ //#region src/components/breadcrumb/JBreadcrumb.vue?vue&type=script&setup=true&lang.ts
606
+ var _hoisted_1$36 = ["aria-label"];
607
+ var _hoisted_2$27 = { class: "j-breadcrumb__list" };
608
+ var _hoisted_3$23 = {
609
+ key: 0,
610
+ class: "j-breadcrumb__ellipsis",
611
+ "aria-hidden": "true"
612
+ };
613
+ var _hoisted_4$17 = ["href"];
614
+ var _hoisted_5$12 = ["aria-current"];
615
+ //#endregion
616
+ //#region src/components/breadcrumb/JBreadcrumb.vue
617
+ var JBreadcrumb_default = /* @__PURE__ */ defineComponent({
618
+ __name: "JBreadcrumb",
619
+ props: {
620
+ items: {},
621
+ label: {},
622
+ maxItems: {}
623
+ },
624
+ setup(__props) {
625
+ const props = __props;
626
+ /**
627
+ * Provide `items` for the common case, or omit it and pass your own `<li>`
628
+ * elements (with class `j-breadcrumb__item`) into the default slot for full
629
+ * control over each crumb.
630
+ */
631
+ const visibleItems = computed(() => {
632
+ const list = props.items ?? [];
633
+ if (!props.maxItems || list.length <= props.maxItems) return list;
634
+ const tailCount = Math.max(1, props.maxItems - 2);
635
+ return [
636
+ list[0],
637
+ {
638
+ label: "…",
639
+ ellipsis: true
640
+ },
641
+ ...list.slice(-tailCount)
642
+ ];
643
+ });
644
+ return (_ctx, _cache) => {
645
+ return openBlock(), createElementBlock("nav", {
646
+ class: "j-breadcrumb",
647
+ "aria-label": __props.label || "Breadcrumb"
648
+ }, [createElementVNode("ol", _hoisted_2$27, [__props.items && __props.items.length ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(visibleItems.value, (item, index) => {
649
+ return openBlock(), createElementBlock("li", {
650
+ key: `${item.label}-${index}`,
651
+ class: "j-breadcrumb__item"
652
+ }, [item.ellipsis ? (openBlock(), createElementBlock("span", _hoisted_3$23, toDisplayString(item.label), 1)) : item.href && index !== visibleItems.value.length - 1 ? (openBlock(), createElementBlock("a", {
653
+ key: 1,
654
+ class: "j-breadcrumb__link j-focusable",
655
+ href: item.href
656
+ }, toDisplayString(item.label), 9, _hoisted_4$17)) : (openBlock(), createElementBlock("span", {
657
+ key: 2,
658
+ class: "j-breadcrumb__current",
659
+ "aria-current": index === visibleItems.value.length - 1 ? "page" : void 0
660
+ }, toDisplayString(item.label), 9, _hoisted_5$12))]);
661
+ }), 128)) : renderSlot(_ctx.$slots, "default", {}, void 0, void 0, 1)])], 8, _hoisted_1$36);
445
662
  };
446
663
  }
447
664
  });
448
665
  //#endregion
449
666
  //#region src/components/button/JButton.vue?vue&type=script&setup=true&lang.ts
450
- var _hoisted_1$24 = { class: "j-button__content" };
451
- var _hoisted_2$18 = {
667
+ var _hoisted_1$35 = { class: "j-button__content" };
668
+ var _hoisted_2$26 = {
452
669
  key: 0,
453
670
  class: "j-button__icon"
454
671
  };
455
- var _hoisted_3$16 = {
672
+ var _hoisted_3$22 = {
456
673
  key: 1,
457
674
  class: "j-button__icon"
458
675
  };
459
- var _hoisted_4$11 = {
676
+ var _hoisted_4$16 = {
460
677
  key: 0,
461
678
  class: "j-button__spinner"
462
679
  };
@@ -510,12 +727,12 @@ var JButton_default = /* @__PURE__ */ defineComponent({
510
727
  "data-disabled": __props.disabled || void 0,
511
728
  onClickCapture: onClick
512
729
  }), {
513
- default: withCtx(() => [createElementVNode("span", _hoisted_1$24, [
514
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$18, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
730
+ default: withCtx(() => [createElementVNode("span", _hoisted_1$35, [
731
+ _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$26, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
515
732
  renderSlot(_ctx.$slots, "default"),
516
- _ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_3$16, [renderSlot(_ctx.$slots, "trailing")])) : createCommentVNode("", true)
733
+ _ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_3$22, [renderSlot(_ctx.$slots, "trailing")])) : createCommentVNode("", true)
517
734
  ]), createVNode(Transition, { name: "j-button-spinner" }, {
518
- default: withCtx(() => [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_4$11, [createVNode(unref(Spinner), { size: __props.size === "xs" ? 12 : __props.size === "lg" ? 16 : 14 }, null, 8, ["size"])])) : createCommentVNode("", true)]),
735
+ default: withCtx(() => [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_4$16, [createVNode(unref(Spinner), { size: __props.size === "xs" ? 12 : __props.size === "lg" ? 16 : 14 }, null, 8, ["size"])])) : createCommentVNode("", true)]),
519
736
  _: 1
520
737
  })]),
521
738
  _: 3
@@ -529,28 +746,28 @@ var JButton_default = /* @__PURE__ */ defineComponent({
529
746
  });
530
747
  //#endregion
531
748
  //#region src/components/card/JCard.vue?vue&type=script&setup=true&lang.ts
532
- var _hoisted_1$23 = {
749
+ var _hoisted_1$34 = {
533
750
  key: 0,
534
751
  class: "j-card__header"
535
752
  };
536
- var _hoisted_2$17 = { class: "j-card__heading" };
537
- var _hoisted_3$15 = {
753
+ var _hoisted_2$25 = { class: "j-card__heading" };
754
+ var _hoisted_3$21 = {
538
755
  key: 0,
539
756
  class: "j-card__title"
540
757
  };
541
- var _hoisted_4$10 = {
758
+ var _hoisted_4$15 = {
542
759
  key: 1,
543
760
  class: "j-card__description"
544
761
  };
545
- var _hoisted_5$7 = {
762
+ var _hoisted_5$11 = {
546
763
  key: 0,
547
764
  class: "j-card__actions"
548
765
  };
549
- var _hoisted_6$5 = {
766
+ var _hoisted_6$8 = {
550
767
  key: 1,
551
768
  class: "j-card__body"
552
769
  };
553
- var _hoisted_7$2 = {
770
+ var _hoisted_7$4 = {
554
771
  key: 2,
555
772
  class: "j-card__footer"
556
773
  };
@@ -569,9 +786,9 @@ var JCard_default = /* @__PURE__ */ defineComponent({
569
786
  return (_ctx, _cache) => {
570
787
  return openBlock(), createBlock(resolveDynamicComponent(__props.as), { class: normalizeClass(["j-card", [`j-card--${__props.variant}`, `j-card--p-${__props.padding}`]]) }, {
571
788
  default: withCtx(() => [
572
- __props.title || __props.description || _ctx.$slots.header || _ctx.$slots.actions ? (openBlock(), createElementBlock("header", _hoisted_1$23, [renderSlot(_ctx.$slots, "header", {}, () => [createElementVNode("div", _hoisted_2$17, [__props.title ? (openBlock(), createElementBlock("h3", _hoisted_3$15, toDisplayString(__props.title), 1)) : createCommentVNode("", true), __props.description ? (openBlock(), createElementBlock("p", _hoisted_4$10, toDisplayString(__props.description), 1)) : createCommentVNode("", true)])]), _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_5$7, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true)])) : createCommentVNode("", true),
573
- _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_6$5, [renderSlot(_ctx.$slots, "default")])) : createCommentVNode("", true),
574
- _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_7$2, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)
789
+ __props.title || __props.description || _ctx.$slots.header || _ctx.$slots.actions ? (openBlock(), createElementBlock("header", _hoisted_1$34, [renderSlot(_ctx.$slots, "header", {}, () => [createElementVNode("div", _hoisted_2$25, [__props.title ? (openBlock(), createElementBlock("h3", _hoisted_3$21, toDisplayString(__props.title), 1)) : createCommentVNode("", true), __props.description ? (openBlock(), createElementBlock("p", _hoisted_4$15, toDisplayString(__props.description), 1)) : createCommentVNode("", true)])]), _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_5$11, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true)])) : createCommentVNode("", true),
790
+ _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_6$8, [renderSlot(_ctx.$slots, "default")])) : createCommentVNode("", true),
791
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_7$4, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)
575
792
  ]),
576
793
  _: 3
577
794
  }, 8, ["class"]);
@@ -580,9 +797,9 @@ var JCard_default = /* @__PURE__ */ defineComponent({
580
797
  });
581
798
  //#endregion
582
799
  //#region src/components/checkbox/JCheckbox.vue?vue&type=script&setup=true&lang.ts
583
- var _hoisted_1$22 = ["data-state"];
584
- var _hoisted_2$16 = { class: "j-checkbox__control" };
585
- var _hoisted_3$14 = [
800
+ var _hoisted_1$33 = ["data-state"];
801
+ var _hoisted_2$24 = { class: "j-checkbox__control" };
802
+ var _hoisted_3$20 = [
586
803
  "id",
587
804
  "checked",
588
805
  "disabled",
@@ -591,12 +808,12 @@ var _hoisted_3$14 = [
591
808
  "value",
592
809
  "aria-describedby"
593
810
  ];
594
- var _hoisted_4$9 = {
811
+ var _hoisted_4$14 = {
595
812
  key: 0,
596
813
  class: "j-checkbox__text"
597
814
  };
598
- var _hoisted_5$6 = ["for"];
599
- var _hoisted_6$4 = ["id"];
815
+ var _hoisted_5$10 = ["for"];
816
+ var _hoisted_6$7 = ["id"];
600
817
  //#endregion
601
818
  //#region src/components/checkbox/JCheckbox.vue
602
819
  var JCheckbox_default = /* @__PURE__ */ defineComponent({
@@ -642,7 +859,7 @@ var JCheckbox_default = /* @__PURE__ */ defineComponent({
642
859
  class: normalizeClass(["j-checkbox", [_ctx.$attrs.class, { "is-disabled": __props.disabled }]]),
643
860
  style: normalizeStyle(_ctx.$attrs.style),
644
861
  "data-state": state.value
645
- }, [createElementVNode("span", _hoisted_2$16, [createElementVNode("input", mergeProps({
862
+ }, [createElementVNode("span", _hoisted_2$24, [createElementVNode("input", mergeProps({
646
863
  id: id.value,
647
864
  ref_key: "input",
648
865
  ref: input
@@ -660,15 +877,69 @@ var JCheckbox_default = /* @__PURE__ */ defineComponent({
660
877
  value: __props.value,
661
878
  "aria-describedby": __props.description || _ctx.$slots.description ? descriptionId.value : void 0,
662
879
  onChange
663
- }), null, 16, _hoisted_3$14), _cache[0] || (_cache[0] = createStaticVNode("<span class=\"j-checkbox__box\" aria-hidden=\"true\"><svg class=\"j-checkbox__check\" viewBox=\"0 0 16 16\" fill=\"none\"><path d=\"M4 8.25l2.75 2.75L12 5.5\" pathLength=\"1\"></path></svg><svg class=\"j-checkbox__dash\" viewBox=\"0 0 16 16\" fill=\"none\"><path d=\"M4.5 8h7\"></path></svg></span>", 1))]), __props.label || _ctx.$slots.default || __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_4$9, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("label", {
880
+ }), null, 16, _hoisted_3$20), _cache[0] || (_cache[0] = createStaticVNode("<span class=\"j-checkbox__box\" aria-hidden=\"true\"><svg class=\"j-checkbox__check\" viewBox=\"0 0 16 16\" fill=\"none\"><path d=\"M4 8.25l2.75 2.75L12 5.5\" pathLength=\"1\"></path></svg><svg class=\"j-checkbox__dash\" viewBox=\"0 0 16 16\" fill=\"none\"><path d=\"M4.5 8h7\"></path></svg></span>", 1))]), __props.label || _ctx.$slots.default || __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_4$14, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("label", {
664
881
  key: 0,
665
882
  for: id.value,
666
883
  class: "j-checkbox__label"
667
- }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])], 8, _hoisted_5$6)) : createCommentVNode("", true), __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", {
884
+ }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])], 8, _hoisted_5$10)) : createCommentVNode("", true), __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", {
668
885
  key: 1,
669
886
  id: descriptionId.value,
670
887
  class: "j-checkbox__description"
671
- }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])], 8, _hoisted_6$4)) : createCommentVNode("", true)])) : createCommentVNode("", true)], 14, _hoisted_1$22);
888
+ }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])], 8, _hoisted_6$7)) : createCommentVNode("", true)])) : createCommentVNode("", true)], 14, _hoisted_1$33);
889
+ };
890
+ }
891
+ });
892
+ //#endregion
893
+ //#region src/components/collapsible/JCollapsible.vue?vue&type=script&setup=true&lang.ts
894
+ var _hoisted_1$32 = ["data-state"];
895
+ var _hoisted_2$23 = ["aria-expanded", "disabled"];
896
+ var _hoisted_3$19 = { class: "j-collapsible__label" };
897
+ var _hoisted_4$13 = ["inert"];
898
+ var _hoisted_5$9 = { class: "j-collapsible__panel-inner" };
899
+ var _hoisted_6$6 = { class: "j-collapsible__content" };
900
+ //#endregion
901
+ //#region src/components/collapsible/JCollapsible.vue
902
+ var JCollapsible_default = /* @__PURE__ */ defineComponent({
903
+ __name: "JCollapsible",
904
+ props: /*@__PURE__*/ mergeModels({
905
+ label: {},
906
+ disabled: { type: Boolean }
907
+ }, {
908
+ "modelValue": {
909
+ type: Boolean,
910
+ default: false
911
+ },
912
+ "modelModifiers": {}
913
+ }),
914
+ emits: ["update:modelValue"],
915
+ setup(__props) {
916
+ /** A single disclosure primitive | for a group of them, use `JAccordion`. */
917
+ const model = useModel(__props, "modelValue");
918
+ const id = `j-${useId()}`;
919
+ const triggerId = `${id}-trigger`;
920
+ const panelId = `${id}-panel`;
921
+ function toggle() {
922
+ model.value = !model.value;
923
+ }
924
+ return (_ctx, _cache) => {
925
+ return openBlock(), createElementBlock("div", {
926
+ class: "j-collapsible",
927
+ "data-state": model.value ? "open" : "closed"
928
+ }, [createElementVNode("button", {
929
+ id: triggerId,
930
+ type: "button",
931
+ class: "j-collapsible__trigger j-focusable",
932
+ "aria-expanded": model.value,
933
+ "aria-controls": panelId,
934
+ disabled: __props.disabled,
935
+ onClick: toggle
936
+ }, [createVNode(unref(IconChevronDown), { class: "j-collapsible__chevron" }), createElementVNode("span", _hoisted_3$19, [renderSlot(_ctx.$slots, "trigger", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])])], 8, _hoisted_2$23), createElementVNode("div", {
937
+ id: panelId,
938
+ role: "region",
939
+ class: "j-collapsible__panel",
940
+ "aria-labelledby": triggerId,
941
+ inert: !model.value
942
+ }, [createElementVNode("div", _hoisted_5$9, [createElementVNode("div", _hoisted_6$6, [renderSlot(_ctx.$slots, "default")])])], 8, _hoisted_4$13)], 8, _hoisted_1$32);
672
943
  };
673
944
  }
674
945
  });
@@ -963,7 +1234,7 @@ function findWordStart(t, q) {
963
1234
  }
964
1235
  return -1;
965
1236
  }
966
- /** Letters in order, not necessarily adjacent — "gtst" finds "Go to settings". */
1237
+ /** Letters in order, not necessarily adjacent | "gtst" finds "Go to settings". */
967
1238
  function subsequence(q, t) {
968
1239
  const ranges = [];
969
1240
  let ti = 0;
@@ -1025,7 +1296,7 @@ var JPortal_default = /* @__PURE__ */ defineComponent({
1025
1296
  *
1026
1297
  * Server-rendered teleports to `body` never make it into the HTML, so a plain
1027
1298
  * `<Teleport>` hydrates against nothing and warns. Rendering nothing until
1028
- * mount keeps server and client output identical — and overlays are closed on
1299
+ * mount keeps server and client output identical | and overlays are closed on
1029
1300
  * first paint anyway.
1030
1301
  */
1031
1302
  const mounted = ref(false);
@@ -1040,25 +1311,25 @@ var JPortal_default = /* @__PURE__ */ defineComponent({
1040
1311
  });
1041
1312
  //#endregion
1042
1313
  //#region src/components/command-palette/JCommandPalette.vue?vue&type=script&setup=true&lang.ts
1043
- var _hoisted_1$21 = {
1314
+ var _hoisted_1$31 = {
1044
1315
  key: 0,
1045
1316
  class: "j-command__overlay",
1046
1317
  "aria-hidden": "true"
1047
1318
  };
1048
- var _hoisted_2$15 = ["aria-label"];
1049
- var _hoisted_3$13 = { class: "j-command__search" };
1050
- var _hoisted_4$8 = [
1319
+ var _hoisted_2$22 = ["aria-label"];
1320
+ var _hoisted_3$18 = { class: "j-command__search" };
1321
+ var _hoisted_4$12 = [
1051
1322
  "aria-activedescendant",
1052
1323
  "aria-label",
1053
1324
  "placeholder"
1054
1325
  ];
1055
- var _hoisted_5$5 = {
1326
+ var _hoisted_5$8 = {
1056
1327
  key: 0,
1057
1328
  class: "j-command__progress",
1058
1329
  "aria-hidden": "true"
1059
1330
  };
1060
- var _hoisted_6$3 = ["aria-label"];
1061
- var _hoisted_7$1 = ["aria-labelledby"];
1331
+ var _hoisted_6$5 = ["aria-label"];
1332
+ var _hoisted_7$3 = ["aria-labelledby"];
1062
1333
  var _hoisted_8$1 = ["id"];
1063
1334
  var _hoisted_9$1 = [
1064
1335
  "id",
@@ -1293,7 +1564,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1293
1564
  return (_ctx, _cache) => {
1294
1565
  return openBlock(), createBlock(JPortal_default, null, {
1295
1566
  default: withCtx(() => [createVNode(Transition, { name: "j-command-overlay" }, {
1296
- default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$21)) : createCommentVNode("", true)]),
1567
+ default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$31)) : createCommentVNode("", true)]),
1297
1568
  _: 1
1298
1569
  }), createVNode(Transition, {
1299
1570
  name: "j-command",
@@ -1315,7 +1586,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1315
1586
  "aria-label": __props.label,
1316
1587
  class: "j-command"
1317
1588
  }, [
1318
- createElementVNode("div", _hoisted_3$13, [
1589
+ createElementVNode("div", _hoisted_3$18, [
1319
1590
  createVNode(unref(IconSearch), { class: "j-command__search-icon" }),
1320
1591
  withDirectives(createElementVNode("input", {
1321
1592
  ref_key: "input",
@@ -1336,7 +1607,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1336
1607
  spellcheck: "false",
1337
1608
  enterkeyhint: "go",
1338
1609
  onKeydown
1339
- }, null, 40, _hoisted_4$8), [[vModelText, search.value]]),
1610
+ }, null, 40, _hoisted_4$12), [[vModelText, search.value]]),
1340
1611
  createElementVNode("button", {
1341
1612
  type: "button",
1342
1613
  class: "j-command__esc j-kbd",
@@ -1344,7 +1615,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1344
1615
  "aria-label": "Close",
1345
1616
  onClick: close
1346
1617
  }, " Esc "),
1347
- __props.loading ? (openBlock(), createElementBlock("span", _hoisted_5$5)) : createCommentVNode("", true)
1618
+ __props.loading ? (openBlock(), createElementBlock("span", _hoisted_5$8)) : createCommentVNode("", true)
1348
1619
  ]),
1349
1620
  createElementVNode("div", {
1350
1621
  id: listboxId,
@@ -1390,8 +1661,8 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1390
1661
  }, toDisplayString(key), 1);
1391
1662
  }), 128))])) : createCommentVNode("", true)
1392
1663
  ])], 42, _hoisted_9$1);
1393
- }), 128))], 8, _hoisted_7$1);
1394
- }), 128)), !rows.value.length ? (openBlock(), createElementBlock("div", _hoisted_15, [__props.loading ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createVNode(unref(Spinner), { size: 16 }), _cache[2] || (_cache[2] = createElementVNode("span", null, "Searching…", -1))], 64)) : renderSlot(_ctx.$slots, "empty", { search: search.value }, () => [createElementVNode("span", _hoisted_16, toDisplayString(__props.emptyText), 1), search.value ? (openBlock(), createElementBlock("span", _hoisted_17, "Nothing matches “" + toDisplayString(search.value) + "”. Try fewer words.", 1)) : createCommentVNode("", true)], void 0, 1)])) : createCommentVNode("", true)], 40, _hoisted_6$3),
1664
+ }), 128))], 8, _hoisted_7$3);
1665
+ }), 128)), !rows.value.length ? (openBlock(), createElementBlock("div", _hoisted_15, [__props.loading ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createVNode(unref(Spinner), { size: 16 }), _cache[2] || (_cache[2] = createElementVNode("span", null, "Searching…", -1))], 64)) : renderSlot(_ctx.$slots, "empty", { search: search.value }, () => [createElementVNode("span", _hoisted_16, toDisplayString(__props.emptyText), 1), search.value ? (openBlock(), createElementBlock("span", _hoisted_17, "Nothing matches “" + toDisplayString(search.value) + "”. Try fewer words.", 1)) : createCommentVNode("", true)], void 0, 1)])) : createCommentVNode("", true)], 40, _hoisted_6$5),
1395
1666
  createElementVNode("div", _hoisted_18, [renderSlot(_ctx.$slots, "footer", {}, () => [
1396
1667
  _cache[3] || (_cache[3] = createElementVNode("span", { class: "j-command__hint" }, [
1397
1668
  createElementVNode("kbd", { class: "j-kbd" }, "↑"),
@@ -1402,7 +1673,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1402
1673
  _cache[5] || (_cache[5] = createElementVNode("span", { class: "j-command__hint" }, [createElementVNode("kbd", { class: "j-kbd" }, "Esc"), createTextVNode(" Close")], -1))
1403
1674
  ])]),
1404
1675
  createElementVNode("span", _hoisted_19, toDisplayString(announcement.value), 1)
1405
- ], 8, _hoisted_2$15)], 32)) : createCommentVNode("", true)]),
1676
+ ], 8, _hoisted_2$22)], 32)) : createCommentVNode("", true)]),
1406
1677
  _: 3
1407
1678
  })]),
1408
1679
  _: 3
@@ -1413,7 +1684,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1413
1684
  //#endregion
1414
1685
  //#region src/composables/useModal.ts
1415
1686
  /**
1416
- * Internal: everything a modal surface (Dialog, Sheet) shares — layering,
1687
+ * Internal: everything a modal surface (Dialog, Sheet) shares | layering,
1417
1688
  * focus trap and restoration, scroll lock, backdrop clicks and the "nudge"
1418
1689
  * when dismissal is refused.
1419
1690
  */
@@ -1452,25 +1723,25 @@ function useModal(panel, open, options) {
1452
1723
  var FIELD_SELECTOR = ":is(input:not([type=hidden]), textarea, select, [role=combobox]):not(:disabled)";
1453
1724
  //#endregion
1454
1725
  //#region src/components/dialog/JDialog.vue?vue&type=script&setup=true&lang.ts
1455
- var _hoisted_1$20 = {
1726
+ var _hoisted_1$30 = {
1456
1727
  key: 0,
1457
1728
  class: "j-dialog__overlay",
1458
1729
  "aria-hidden": "true"
1459
1730
  };
1460
- var _hoisted_2$14 = [
1731
+ var _hoisted_2$21 = [
1461
1732
  "aria-labelledby",
1462
1733
  "aria-label",
1463
1734
  "aria-describedby"
1464
1735
  ];
1465
- var _hoisted_3$12 = {
1736
+ var _hoisted_3$17 = {
1466
1737
  key: 0,
1467
1738
  class: "j-dialog__header"
1468
1739
  };
1469
- var _hoisted_4$7 = {
1740
+ var _hoisted_4$11 = {
1470
1741
  key: 1,
1471
1742
  class: "j-dialog__body"
1472
1743
  };
1473
- var _hoisted_5$4 = {
1744
+ var _hoisted_5$7 = {
1474
1745
  key: 2,
1475
1746
  class: "j-dialog__footer"
1476
1747
  };
@@ -1521,7 +1792,7 @@ var JDialog_default = /* @__PURE__ */ defineComponent({
1521
1792
  return (_ctx, _cache) => {
1522
1793
  return openBlock(), createBlock(JPortal_default, null, {
1523
1794
  default: withCtx(() => [createVNode(Transition, { name: "j-dialog-overlay" }, {
1524
- default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$20)) : createCommentVNode("", true)]),
1795
+ default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$30)) : createCommentVNode("", true)]),
1525
1796
  _: 1
1526
1797
  }), createVNode(Transition, {
1527
1798
  name: "j-dialog",
@@ -1548,7 +1819,7 @@ var JDialog_default = /* @__PURE__ */ defineComponent({
1548
1819
  "aria-describedby": __props.description ? descriptionId : void 0,
1549
1820
  onAnimationend: _cache[0] || (_cache[0] = ($event) => nudging.value = false)
1550
1821
  }, [
1551
- __props.title || __props.description || _ctx.$slots.header ? (openBlock(), createElementBlock("header", _hoisted_3$12, [renderSlot(_ctx.$slots, "header", {
1822
+ __props.title || __props.description || _ctx.$slots.header ? (openBlock(), createElementBlock("header", _hoisted_3$17, [renderSlot(_ctx.$slots, "header", {
1552
1823
  titleId,
1553
1824
  descriptionId
1554
1825
  }, () => [createElementVNode("h2", {
@@ -1559,8 +1830,8 @@ var JDialog_default = /* @__PURE__ */ defineComponent({
1559
1830
  id: descriptionId,
1560
1831
  class: "j-dialog__description"
1561
1832
  }, toDisplayString(__props.description), 1)) : createCommentVNode("", true)])])) : createCommentVNode("", true),
1562
- _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_4$7, [renderSlot(_ctx.$slots, "default", { close })])) : createCommentVNode("", true),
1563
- _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_5$4, [renderSlot(_ctx.$slots, "footer", { close })])) : createCommentVNode("", true),
1833
+ _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_4$11, [renderSlot(_ctx.$slots, "default", { close })])) : createCommentVNode("", true),
1834
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_5$7, [renderSlot(_ctx.$slots, "footer", { close })])) : createCommentVNode("", true),
1564
1835
  !__props.hideClose ? (openBlock(), createElementBlock("button", {
1565
1836
  key: 3,
1566
1837
  type: "button",
@@ -1568,7 +1839,7 @@ var JDialog_default = /* @__PURE__ */ defineComponent({
1568
1839
  "aria-label": "Close",
1569
1840
  onClick: close
1570
1841
  }, [createVNode(unref(IconX))])) : createCommentVNode("", true)
1571
- ], 42, _hoisted_2$14)], 32)) : createCommentVNode("", true)]),
1842
+ ], 42, _hoisted_2$21)], 32)) : createCommentVNode("", true)]),
1572
1843
  _: 3
1573
1844
  })]),
1574
1845
  _: 3
@@ -1596,7 +1867,7 @@ function firstElement(nodes) {
1596
1867
  }
1597
1868
  /**
1598
1869
  * Internal: renders its first child element and merges its own attributes
1599
- * (ARIA, listeners, ids) onto it — no wrapper element.
1870
+ * (ARIA, listeners, ids) onto it | no wrapper element.
1600
1871
  */
1601
1872
  var JSlot = defineComponent({
1602
1873
  name: "JSlot",
@@ -1730,7 +2001,7 @@ function useTypeahead(timeout = 500) {
1730
2001
  }
1731
2002
  //#endregion
1732
2003
  //#region src/components/dropdown-menu/JMenuContent.vue?vue&type=script&setup=true&lang.ts
1733
- var _hoisted_1$19 = ["id", "aria-labelledby"];
2004
+ var _hoisted_1$29 = ["id", "aria-labelledby"];
1734
2005
  //#endregion
1735
2006
  //#region src/components/dropdown-menu/JMenuContent.vue
1736
2007
  var JMenuContent_default = /* @__PURE__ */ defineComponent({
@@ -1874,7 +2145,7 @@ var JMenuContent_default = /* @__PURE__ */ defineComponent({
1874
2145
  "aria-orientation": "vertical",
1875
2146
  onKeydown,
1876
2147
  onPointerenter: _cache[0] || (_cache[0] = ($event) => emit("pointerenter"))
1877
- }, [renderSlot(_ctx.$slots, "default")], 46, _hoisted_1$19)) : createCommentVNode("", true)]),
2148
+ }, [renderSlot(_ctx.$slots, "default")], 46, _hoisted_1$29)) : createCommentVNode("", true)]),
1878
2149
  _: 3
1879
2150
  })]),
1880
2151
  _: 3
@@ -1974,12 +2245,12 @@ var JDropdownMenu_default = /* @__PURE__ */ defineComponent({
1974
2245
  });
1975
2246
  //#endregion
1976
2247
  //#region src/components/dropdown-menu/JDropdownMenuItem.vue?vue&type=script&setup=true&lang.ts
1977
- var _hoisted_1$18 = {
2248
+ var _hoisted_1$28 = {
1978
2249
  key: 0,
1979
2250
  class: "j-menu__icon"
1980
2251
  };
1981
- var _hoisted_2$13 = { class: "j-menu__text" };
1982
- var _hoisted_3$11 = {
2252
+ var _hoisted_2$20 = { class: "j-menu__text" };
2253
+ var _hoisted_3$16 = {
1983
2254
  key: 1,
1984
2255
  class: "j-menu__shortcut"
1985
2256
  };
@@ -2041,9 +2312,9 @@ var JDropdownMenuItem_default = /* @__PURE__ */ defineComponent({
2041
2312
  onPointerleave: onPointerLeave
2042
2313
  }, {
2043
2314
  default: withCtx(() => [
2044
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_1$18, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
2045
- createElementVNode("span", _hoisted_2$13, [renderSlot(_ctx.$slots, "default")]),
2046
- __props.shortcut ? (openBlock(), createElementBlock("span", _hoisted_3$11, toDisplayString(__props.shortcut), 1)) : createCommentVNode("", true),
2315
+ _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_1$28, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
2316
+ createElementVNode("span", _hoisted_2$20, [renderSlot(_ctx.$slots, "default")]),
2317
+ __props.shortcut ? (openBlock(), createElementBlock("span", _hoisted_3$16, toDisplayString(__props.shortcut), 1)) : createCommentVNode("", true),
2047
2318
  __props.checked !== void 0 ? (openBlock(), createBlock(unref(IconCheck), {
2048
2319
  key: 2,
2049
2320
  class: normalizeClass(["j-menu__check", { "is-checked": __props.checked }])
@@ -2061,7 +2332,7 @@ var JDropdownMenuItem_default = /* @__PURE__ */ defineComponent({
2061
2332
  });
2062
2333
  //#endregion
2063
2334
  //#region src/components/dropdown-menu/JDropdownMenuLabel.vue?vue&type=script&setup=true&lang.ts
2064
- var _hoisted_1$17 = {
2335
+ var _hoisted_1$27 = {
2065
2336
  class: "j-menu__label",
2066
2337
  role: "presentation"
2067
2338
  };
@@ -2071,7 +2342,7 @@ var JDropdownMenuLabel_default = /* @__PURE__ */ defineComponent({
2071
2342
  __name: "JDropdownMenuLabel",
2072
2343
  setup(__props) {
2073
2344
  return (_ctx, _cache) => {
2074
- return openBlock(), createElementBlock("div", _hoisted_1$17, [renderSlot(_ctx.$slots, "default")]);
2345
+ return openBlock(), createElementBlock("div", _hoisted_1$27, [renderSlot(_ctx.$slots, "default")]);
2075
2346
  };
2076
2347
  }
2077
2348
  });
@@ -2085,27 +2356,27 @@ var _plugin_vue_export_helper_default = (sfc, props) => {
2085
2356
  //#endregion
2086
2357
  //#region src/components/dropdown-menu/JDropdownMenuSeparator.vue
2087
2358
  var _sfc_main = {};
2088
- var _hoisted_1$16 = {
2359
+ var _hoisted_1$26 = {
2089
2360
  role: "separator",
2090
2361
  "aria-orientation": "horizontal",
2091
2362
  class: "j-menu__separator"
2092
2363
  };
2093
2364
  function _sfc_render(_ctx, _cache) {
2094
- return openBlock(), createElementBlock("div", _hoisted_1$16);
2365
+ return openBlock(), createElementBlock("div", _hoisted_1$26);
2095
2366
  }
2096
2367
  var JDropdownMenuSeparator_default = /*#__PURE__*/ _plugin_vue_export_helper_default(_sfc_main, [["render", _sfc_render]]);
2097
2368
  //#endregion
2098
2369
  //#region src/components/dropdown-menu/JDropdownMenuSub.vue?vue&type=script&setup=true&lang.ts
2099
- var _hoisted_1$15 = [
2370
+ var _hoisted_1$25 = [
2100
2371
  "aria-expanded",
2101
2372
  "aria-controls",
2102
2373
  "aria-disabled"
2103
2374
  ];
2104
- var _hoisted_2$12 = {
2375
+ var _hoisted_2$19 = {
2105
2376
  key: 0,
2106
2377
  class: "j-menu__icon"
2107
2378
  };
2108
- var _hoisted_3$10 = { class: "j-menu__text" };
2379
+ var _hoisted_3$15 = { class: "j-menu__text" };
2109
2380
  //#endregion
2110
2381
  //#region src/components/dropdown-menu/JDropdownMenuSub.vue
2111
2382
  var JDropdownMenuSub_default = /* @__PURE__ */ defineComponent({
@@ -2179,10 +2450,10 @@ var JDropdownMenuSub_default = /* @__PURE__ */ defineComponent({
2179
2450
  onKeydown,
2180
2451
  onClick
2181
2452
  }, [
2182
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$12, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
2183
- createElementVNode("span", _hoisted_3$10, toDisplayString(__props.label), 1),
2453
+ _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$19, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
2454
+ createElementVNode("span", _hoisted_3$15, toDisplayString(__props.label), 1),
2184
2455
  createVNode(unref(IconChevronRight), { class: "j-menu__chevron" })
2185
- ], 40, _hoisted_1$15), createVNode(JMenuContent_default, {
2456
+ ], 40, _hoisted_1$25), createVNode(JMenuContent_default, {
2186
2457
  id: menuId,
2187
2458
  ref_key: "sub",
2188
2459
  ref: sub,
@@ -2212,15 +2483,53 @@ var JDropdownMenuSub_default = /* @__PURE__ */ defineComponent({
2212
2483
  }
2213
2484
  });
2214
2485
  //#endregion
2486
+ //#region src/components/empty-state/JEmptyState.vue?vue&type=script&setup=true&lang.ts
2487
+ var _hoisted_1$24 = {
2488
+ key: 0,
2489
+ class: "j-empty-state__icon"
2490
+ };
2491
+ var _hoisted_2$18 = {
2492
+ key: 1,
2493
+ class: "j-empty-state__title"
2494
+ };
2495
+ var _hoisted_3$14 = {
2496
+ key: 2,
2497
+ class: "j-empty-state__description"
2498
+ };
2499
+ var _hoisted_4$10 = {
2500
+ key: 3,
2501
+ class: "j-empty-state__actions"
2502
+ };
2503
+ //#endregion
2504
+ //#region src/components/empty-state/JEmptyState.vue
2505
+ var JEmptyState_default = /* @__PURE__ */ defineComponent({
2506
+ __name: "JEmptyState",
2507
+ props: {
2508
+ title: {},
2509
+ description: {},
2510
+ size: { default: "md" }
2511
+ },
2512
+ setup(__props) {
2513
+ return (_ctx, _cache) => {
2514
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["j-empty-state", `j-empty-state--${__props.size}`]) }, [
2515
+ _ctx.$slots.icon ? (openBlock(), createElementBlock("div", _hoisted_1$24, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("", true),
2516
+ __props.title ? (openBlock(), createElementBlock("p", _hoisted_2$18, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
2517
+ __props.description || _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_3$14, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])])) : createCommentVNode("", true),
2518
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_4$10, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true)
2519
+ ], 2);
2520
+ };
2521
+ }
2522
+ });
2523
+ //#endregion
2215
2524
  //#region src/components/field/JFieldShell.vue?vue&type=script&setup=true&lang.ts
2216
- var _hoisted_1$14 = {
2525
+ var _hoisted_1$23 = {
2217
2526
  key: 0,
2218
2527
  class: "j-field__required",
2219
2528
  "aria-hidden": "true"
2220
2529
  };
2221
- var _hoisted_2$11 = { class: "j-field__messages" };
2222
- var _hoisted_3$9 = ["id"];
2223
- var _hoisted_4$6 = ["id"];
2530
+ var _hoisted_2$17 = { class: "j-field__messages" };
2531
+ var _hoisted_3$13 = ["id"];
2532
+ var _hoisted_4$9 = ["id"];
2224
2533
  //#endregion
2225
2534
  //#region src/components/field/JFieldShell.vue
2226
2535
  var JFieldShell_default = /* @__PURE__ */ defineComponent({
@@ -2241,7 +2550,7 @@ var JFieldShell_default = /* @__PURE__ */ defineComponent({
2241
2550
  setup(__props) {
2242
2551
  /**
2243
2552
  * Internal: lays out label, control, description and error for form fields.
2244
- * Not exported — every field component composes it.
2553
+ * Not exported | every field component composes it.
2245
2554
  */
2246
2555
  return (_ctx, _cache) => {
2247
2556
  return openBlock(), createElementBlock("div", { class: normalizeClass(["j-field", { "is-disabled": __props.disabled }]) }, [
@@ -2251,11 +2560,11 @@ var JFieldShell_default = /* @__PURE__ */ defineComponent({
2251
2560
  class: "j-field__label",
2252
2561
  for: __props.labelFor === null ? void 0 : __props.labelFor ?? __props.id
2253
2562
  }, {
2254
- default: withCtx(() => [renderSlot(_ctx.$slots, "label", {}, () => [createTextVNode(toDisplayString(__props.label), 1)]), __props.required ? (openBlock(), createElementBlock("span", _hoisted_1$14, "*")) : createCommentVNode("", true)]),
2563
+ default: withCtx(() => [renderSlot(_ctx.$slots, "label", {}, () => [createTextVNode(toDisplayString(__props.label), 1)]), __props.required ? (openBlock(), createElementBlock("span", _hoisted_1$23, "*")) : createCommentVNode("", true)]),
2255
2564
  _: 3
2256
2565
  }, 8, ["id", "for"])) : createCommentVNode("", true),
2257
2566
  renderSlot(_ctx.$slots, "default"),
2258
- createElementVNode("div", _hoisted_2$11, [createVNode(Transition, {
2567
+ createElementVNode("div", _hoisted_2$17, [createVNode(Transition, {
2259
2568
  name: "j-field-message",
2260
2569
  mode: "out-in"
2261
2570
  }, {
@@ -2263,11 +2572,11 @@ var JFieldShell_default = /* @__PURE__ */ defineComponent({
2263
2572
  id: __props.errorId,
2264
2573
  key: __props.errorMessage,
2265
2574
  class: "j-field__error"
2266
- }, toDisplayString(__props.errorMessage), 9, _hoisted_3$9)) : __props.showDescription ? (openBlock(), createElementBlock("p", {
2575
+ }, toDisplayString(__props.errorMessage), 9, _hoisted_3$13)) : __props.showDescription ? (openBlock(), createElementBlock("p", {
2267
2576
  key: 1,
2268
2577
  id: __props.descriptionId,
2269
2578
  class: "j-field__description"
2270
- }, toDisplayString(__props.description), 9, _hoisted_4$6)) : createCommentVNode("", true)]),
2579
+ }, toDisplayString(__props.description), 9, _hoisted_4$9)) : createCommentVNode("", true)]),
2271
2580
  _: 1
2272
2581
  })])
2273
2582
  ], 2);
@@ -2304,11 +2613,11 @@ function useField(props) {
2304
2613
  }
2305
2614
  //#endregion
2306
2615
  //#region src/components/input/JInput.vue?vue&type=script&setup=true&lang.ts
2307
- var _hoisted_1$13 = {
2616
+ var _hoisted_1$22 = {
2308
2617
  key: 0,
2309
2618
  class: "j-control__adornment j-control__adornment--leading"
2310
2619
  };
2311
- var _hoisted_2$10 = [
2620
+ var _hoisted_2$16 = [
2312
2621
  "id",
2313
2622
  "type",
2314
2623
  "name",
@@ -2320,7 +2629,7 @@ var _hoisted_2$10 = [
2320
2629
  "aria-invalid",
2321
2630
  "aria-describedby"
2322
2631
  ];
2323
- var _hoisted_3$8 = {
2632
+ var _hoisted_3$12 = {
2324
2633
  key: 1,
2325
2634
  class: "j-control__adornment j-control__adornment--trailing"
2326
2635
  };
@@ -2390,7 +2699,7 @@ var JInput_default = /* @__PURE__ */ defineComponent({
2390
2699
  }]]),
2391
2700
  onPointerdown: onFramePointerDown
2392
2701
  }, [
2393
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_1$13, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
2702
+ _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_1$22, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
2394
2703
  withDirectives(createElementVNode("input", mergeProps({
2395
2704
  id: unref(field).id.value,
2396
2705
  ref_key: "input",
@@ -2411,8 +2720,8 @@ var JInput_default = /* @__PURE__ */ defineComponent({
2411
2720
  autocomplete: __props.autocomplete,
2412
2721
  "aria-invalid": unref(field).invalid.value || void 0,
2413
2722
  "aria-describedby": unref(field).describedBy.value
2414
- }), null, 16, _hoisted_2$10), [[vModelDynamic, model.value]]),
2415
- _ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_3$8, [renderSlot(_ctx.$slots, "trailing")])) : createCommentVNode("", true)
2723
+ }), null, 16, _hoisted_2$16), [[vModelDynamic, model.value]]),
2724
+ _ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_3$12, [renderSlot(_ctx.$slots, "trailing")])) : createCommentVNode("", true)
2416
2725
  ], 34)]),
2417
2726
  _: 2
2418
2727
  }, [_ctx.$slots.label ? {
@@ -2470,8 +2779,116 @@ var JKbd_default = /* @__PURE__ */ defineComponent({
2470
2779
  }
2471
2780
  });
2472
2781
  //#endregion
2782
+ //#region src/components/pagination/JPagination.vue?vue&type=script&setup=true&lang.ts
2783
+ var _hoisted_1$21 = ["aria-label"];
2784
+ var _hoisted_2$15 = ["disabled"];
2785
+ var _hoisted_3$11 = {
2786
+ key: 0,
2787
+ class: "j-pagination__ellipsis",
2788
+ "aria-hidden": "true"
2789
+ };
2790
+ var _hoisted_4$8 = [
2791
+ "aria-current",
2792
+ "aria-label",
2793
+ "disabled",
2794
+ "onClick"
2795
+ ];
2796
+ var _hoisted_5$6 = ["disabled"];
2797
+ //#endregion
2798
+ //#region src/components/pagination/JPagination.vue
2799
+ var JPagination_default = /* @__PURE__ */ defineComponent({
2800
+ __name: "JPagination",
2801
+ props: /*@__PURE__*/ mergeModels({
2802
+ total: {},
2803
+ siblingCount: { default: 1 },
2804
+ label: {},
2805
+ size: { default: "md" },
2806
+ disabled: { type: Boolean }
2807
+ }, {
2808
+ "modelValue": { default: 1 },
2809
+ "modelModifiers": {}
2810
+ }),
2811
+ emits: ["update:modelValue"],
2812
+ setup(__props) {
2813
+ const props = __props;
2814
+ const model = useModel(__props, "modelValue");
2815
+ const list = ref(null);
2816
+ const totalPages = computed(() => Math.max(1, Math.floor(props.total)));
2817
+ const current = computed(() => Math.min(Math.max(1, model.value), totalPages.value));
2818
+ const pageItems = computed(() => {
2819
+ const total = totalPages.value;
2820
+ const siblings = Math.max(0, props.siblingCount);
2821
+ if (total <= siblings * 2 + 5) return Array.from({ length: total }, (_, i) => i + 1);
2822
+ const left = Math.max(current.value - siblings, 1);
2823
+ const right = Math.min(current.value + siblings, total);
2824
+ const showLeftEllipsis = left > 2;
2825
+ const showRightEllipsis = right < total - 1;
2826
+ const items = [1];
2827
+ if (showLeftEllipsis) items.push("ellipsis");
2828
+ else for (let p = 2; p < left; p++) items.push(p);
2829
+ for (let p = Math.max(left, 2); p <= Math.min(right, total - 1); p++) items.push(p);
2830
+ if (showRightEllipsis) items.push("ellipsis");
2831
+ else for (let p = right + 1; p < total; p++) items.push(p);
2832
+ if (total > 1) items.push(total);
2833
+ return items;
2834
+ });
2835
+ function goTo(page, focus = false) {
2836
+ if (props.disabled) return;
2837
+ model.value = Math.min(Math.max(1, page), totalPages.value);
2838
+ if (focus) nextTick(() => focusElement(list.value?.querySelector("[aria-current=\"page\"]")));
2839
+ }
2840
+ function onKeydown(event) {
2841
+ if (!event.target.classList.contains("j-pagination__page")) return;
2842
+ if (event.key === "Home") {
2843
+ event.preventDefault();
2844
+ goTo(1, true);
2845
+ } else if (event.key === "End") {
2846
+ event.preventDefault();
2847
+ goTo(totalPages.value, true);
2848
+ }
2849
+ }
2850
+ return (_ctx, _cache) => {
2851
+ return openBlock(), createElementBlock("nav", {
2852
+ class: normalizeClass(["j-pagination", `j-pagination--${__props.size}`]),
2853
+ "aria-label": __props.label || "Pagination"
2854
+ }, [
2855
+ createElementVNode("button", {
2856
+ type: "button",
2857
+ class: "j-pagination__nav j-focusable",
2858
+ "aria-label": "Previous page",
2859
+ disabled: __props.disabled || current.value === 1,
2860
+ onClick: _cache[0] || (_cache[0] = ($event) => goTo(current.value - 1, true))
2861
+ }, [createVNode(unref(IconChevronLeft))], 8, _hoisted_2$15),
2862
+ createElementVNode("ul", {
2863
+ ref_key: "list",
2864
+ ref: list,
2865
+ class: "j-pagination__list",
2866
+ onKeydown
2867
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(pageItems.value, (item, index) => {
2868
+ return openBlock(), createElementBlock("li", { key: index }, [item === "ellipsis" ? (openBlock(), createElementBlock("span", _hoisted_3$11, [createVNode(unref(IconMoreHorizontal))])) : (openBlock(), createElementBlock("button", {
2869
+ key: 1,
2870
+ type: "button",
2871
+ class: normalizeClass(["j-pagination__page j-focusable", { "is-current": item === current.value }]),
2872
+ "aria-current": item === current.value ? "page" : void 0,
2873
+ "aria-label": `Page ${item}`,
2874
+ disabled: __props.disabled,
2875
+ onClick: ($event) => goTo(item)
2876
+ }, toDisplayString(item), 11, _hoisted_4$8))]);
2877
+ }), 128))], 544),
2878
+ createElementVNode("button", {
2879
+ type: "button",
2880
+ class: "j-pagination__nav j-focusable",
2881
+ "aria-label": "Next page",
2882
+ disabled: __props.disabled || current.value === totalPages.value,
2883
+ onClick: _cache[1] || (_cache[1] = ($event) => goTo(current.value + 1, true))
2884
+ }, [createVNode(unref(IconChevronRight))], 8, _hoisted_5$6)
2885
+ ], 10, _hoisted_1$21);
2886
+ };
2887
+ }
2888
+ });
2889
+ //#endregion
2473
2890
  //#region src/components/popover/JPopover.vue?vue&type=script&setup=true&lang.ts
2474
- var _hoisted_1$12 = ["aria-label"];
2891
+ var _hoisted_1$20 = ["aria-label"];
2475
2892
  //#endregion
2476
2893
  //#region src/components/popover/JPopover.vue
2477
2894
  var JPopover_default = /* @__PURE__ */ defineComponent({
@@ -2561,7 +2978,7 @@ var JPopover_default = /* @__PURE__ */ defineComponent({
2561
2978
  style: normalizeStyle(unref(styles)),
2562
2979
  "aria-label": __props.ariaLabel,
2563
2980
  onFocusout: onFocusOut
2564
- }, [renderSlot(_ctx.$slots, "default", { close: () => close(true) })], 44, _hoisted_1$12)) : createCommentVNode("", true)]),
2981
+ }, [renderSlot(_ctx.$slots, "default", { close: () => close(true) })], 44, _hoisted_1$20)) : createCommentVNode("", true)]),
2565
2982
  _: 3
2566
2983
  })]),
2567
2984
  _: 3
@@ -2571,16 +2988,16 @@ var JPopover_default = /* @__PURE__ */ defineComponent({
2571
2988
  });
2572
2989
  //#endregion
2573
2990
  //#region src/components/progress/JProgress.vue?vue&type=script&setup=true&lang.ts
2574
- var _hoisted_1$11 = {
2991
+ var _hoisted_1$19 = {
2575
2992
  key: 0,
2576
2993
  class: "j-progress__header"
2577
2994
  };
2578
- var _hoisted_2$9 = ["id"];
2579
- var _hoisted_3$7 = {
2995
+ var _hoisted_2$14 = ["id"];
2996
+ var _hoisted_3$10 = {
2580
2997
  key: 1,
2581
2998
  class: "j-progress__value"
2582
2999
  };
2583
- var _hoisted_4$5 = [
3000
+ var _hoisted_4$7 = [
2584
3001
  "aria-labelledby",
2585
3002
  "aria-valuemax",
2586
3003
  "aria-valuenow",
@@ -2609,11 +3026,11 @@ var JProgress_default = /* @__PURE__ */ defineComponent({
2609
3026
  `j-progress--${__props.size}`,
2610
3027
  `j-progress--${__props.variant}`,
2611
3028
  { "is-indeterminate": indeterminate.value }
2612
- ]]) }, [__props.label || __props.showValue ? (openBlock(), createElementBlock("div", _hoisted_1$11, [__props.label ? (openBlock(), createElementBlock("span", {
3029
+ ]]) }, [__props.label || __props.showValue ? (openBlock(), createElementBlock("div", _hoisted_1$19, [__props.label ? (openBlock(), createElementBlock("span", {
2613
3030
  key: 0,
2614
3031
  id: `${id}-label`,
2615
3032
  class: "j-progress__label"
2616
- }, toDisplayString(__props.label), 9, _hoisted_2$9)) : createCommentVNode("", true), __props.showValue && !indeterminate.value ? (openBlock(), createElementBlock("span", _hoisted_3$7, toDisplayString(percent.value) + "%", 1)) : createCommentVNode("", true)])) : createCommentVNode("", true), createElementVNode("div", {
3033
+ }, toDisplayString(__props.label), 9, _hoisted_2$14)) : createCommentVNode("", true), __props.showValue && !indeterminate.value ? (openBlock(), createElementBlock("span", _hoisted_3$10, toDisplayString(percent.value) + "%", 1)) : createCommentVNode("", true)])) : createCommentVNode("", true), createElementVNode("div", {
2617
3034
  class: "j-progress__track",
2618
3035
  role: "progressbar",
2619
3036
  "aria-labelledby": __props.label ? `${id}-label` : void 0,
@@ -2624,7 +3041,7 @@ var JProgress_default = /* @__PURE__ */ defineComponent({
2624
3041
  }, [createElementVNode("span", {
2625
3042
  class: "j-progress__fill",
2626
3043
  style: normalizeStyle(indeterminate.value ? void 0 : { transform: `scaleX(${ratio.value})` })
2627
- }, null, 4)], 8, _hoisted_4$5)], 2);
3044
+ }, null, 4)], 8, _hoisted_4$7)], 2);
2628
3045
  };
2629
3046
  }
2630
3047
  });
@@ -2633,9 +3050,9 @@ var JProgress_default = /* @__PURE__ */ defineComponent({
2633
3050
  var RADIO_GROUP = Symbol("JRadioGroup");
2634
3051
  //#endregion
2635
3052
  //#region src/components/radio/JRadio.vue?vue&type=script&setup=true&lang.ts
2636
- var _hoisted_1$10 = ["data-state"];
2637
- var _hoisted_2$8 = { class: "j-radio__control" };
2638
- var _hoisted_3$6 = [
3053
+ var _hoisted_1$18 = ["data-state"];
3054
+ var _hoisted_2$13 = { class: "j-radio__control" };
3055
+ var _hoisted_3$9 = [
2639
3056
  "name",
2640
3057
  "value",
2641
3058
  "checked",
@@ -2643,7 +3060,7 @@ var _hoisted_3$6 = [
2643
3060
  "required",
2644
3061
  "aria-describedby"
2645
3062
  ];
2646
- var _hoisted_4$4 = {
3063
+ var _hoisted_4$6 = {
2647
3064
  key: 0,
2648
3065
  class: "j-radio__text"
2649
3066
  };
@@ -2670,7 +3087,7 @@ var JRadio_default = /* @__PURE__ */ defineComponent({
2670
3087
  class: normalizeClass(["j-radio", [_ctx.$attrs.class, { "is-disabled": isDisabled.value }]]),
2671
3088
  style: normalizeStyle(_ctx.$attrs.style),
2672
3089
  "data-state": checked.value ? "checked" : "unchecked"
2673
- }, [createElementVNode("span", _hoisted_2$8, [createElementVNode("input", mergeProps({ id }, {
3090
+ }, [createElementVNode("span", _hoisted_2$13, [createElementVNode("input", mergeProps({ id }, {
2674
3091
  ..._ctx.$attrs,
2675
3092
  class: void 0,
2676
3093
  style: void 0
@@ -2684,10 +3101,10 @@ var JRadio_default = /* @__PURE__ */ defineComponent({
2684
3101
  required: unref(group)?.required.value,
2685
3102
  "aria-describedby": __props.description || _ctx.$slots.description ? descriptionId : void 0,
2686
3103
  onChange: _cache[0] || (_cache[0] = ($event) => unref(group)?.select(__props.value))
2687
- }), null, 16, _hoisted_3$6), _cache[1] || (_cache[1] = createElementVNode("span", {
3104
+ }), null, 16, _hoisted_3$9), _cache[1] || (_cache[1] = createElementVNode("span", {
2688
3105
  class: "j-radio__circle",
2689
3106
  "aria-hidden": "true"
2690
- }, null, -1))]), __props.label || _ctx.$slots.default || __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_4$4, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("label", {
3107
+ }, null, -1))]), __props.label || _ctx.$slots.default || __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_4$6, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("label", {
2691
3108
  key: 0,
2692
3109
  for: id,
2693
3110
  class: "j-radio__label"
@@ -2695,23 +3112,23 @@ var JRadio_default = /* @__PURE__ */ defineComponent({
2695
3112
  key: 1,
2696
3113
  id: descriptionId,
2697
3114
  class: "j-radio__description"
2698
- }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])])) : createCommentVNode("", true)])) : createCommentVNode("", true)], 14, _hoisted_1$10);
3115
+ }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])])) : createCommentVNode("", true)])) : createCommentVNode("", true)], 14, _hoisted_1$18);
2699
3116
  };
2700
3117
  }
2701
3118
  });
2702
3119
  //#endregion
2703
3120
  //#region src/components/radio/JRadioGroup.vue?vue&type=script&setup=true&lang.ts
2704
- var _hoisted_1$9 = [
3121
+ var _hoisted_1$17 = [
2705
3122
  "disabled",
2706
3123
  "aria-describedby",
2707
3124
  "aria-invalid",
2708
3125
  "aria-required"
2709
3126
  ];
2710
- var _hoisted_2$7 = {
3127
+ var _hoisted_2$12 = {
2711
3128
  key: 0,
2712
3129
  class: "j-radio-group__legend"
2713
3130
  };
2714
- var _hoisted_3$5 = {
3131
+ var _hoisted_3$8 = {
2715
3132
  key: 0,
2716
3133
  class: "j-field__required",
2717
3134
  "aria-hidden": "true"
@@ -2765,7 +3182,7 @@ var JRadioGroup_default = /* @__PURE__ */ defineComponent({
2765
3182
  "aria-invalid": !!__props.error || void 0,
2766
3183
  "aria-required": __props.required || void 0
2767
3184
  }, [
2768
- __props.label || _ctx.$slots.label ? (openBlock(), createElementBlock("legend", _hoisted_2$7, [renderSlot(_ctx.$slots, "label", {}, () => [createTextVNode(toDisplayString(__props.label), 1)]), __props.required ? (openBlock(), createElementBlock("span", _hoisted_3$5, "*")) : createCommentVNode("", true)])) : createCommentVNode("", true),
3185
+ __props.label || _ctx.$slots.label ? (openBlock(), createElementBlock("legend", _hoisted_2$12, [renderSlot(_ctx.$slots, "label", {}, () => [createTextVNode(toDisplayString(__props.label), 1)]), __props.required ? (openBlock(), createElementBlock("span", _hoisted_3$8, "*")) : createCommentVNode("", true)])) : createCommentVNode("", true),
2769
3186
  __props.description && !errorMessage.value ? (openBlock(), createElementBlock("p", {
2770
3187
  key: 1,
2771
3188
  id: descriptionId,
@@ -2777,13 +3194,121 @@ var JRadioGroup_default = /* @__PURE__ */ defineComponent({
2777
3194
  id: errorId,
2778
3195
  class: "j-radio-group__error"
2779
3196
  }, toDisplayString(errorMessage.value), 1)) : createCommentVNode("", true)
2780
- ], 10, _hoisted_1$9);
3197
+ ], 10, _hoisted_1$17);
3198
+ };
3199
+ }
3200
+ });
3201
+ //#endregion
3202
+ //#region src/components/rating/JRating.vue?vue&type=script&setup=true&lang.ts
3203
+ var _hoisted_1$16 = [
3204
+ "role",
3205
+ "aria-label",
3206
+ "aria-disabled"
3207
+ ];
3208
+ var _hoisted_2$11 = [
3209
+ "aria-checked",
3210
+ "aria-label",
3211
+ "tabindex",
3212
+ "disabled",
3213
+ "onClick",
3214
+ "onMouseenter",
3215
+ "onFocus"
3216
+ ];
3217
+ //#endregion
3218
+ //#region src/components/rating/JRating.vue
3219
+ var JRating_default = /* @__PURE__ */ defineComponent({
3220
+ __name: "JRating",
3221
+ props: /*@__PURE__*/ mergeModels({
3222
+ max: { default: 5 },
3223
+ readonly: { type: Boolean },
3224
+ disabled: { type: Boolean },
3225
+ size: { default: "md" },
3226
+ label: {},
3227
+ allowHalf: { type: Boolean }
3228
+ }, {
3229
+ "modelValue": { default: 0 },
3230
+ "modelModifiers": {}
3231
+ }),
3232
+ emits: ["update:modelValue"],
3233
+ setup(__props) {
3234
+ const props = __props;
3235
+ const model = useModel(__props, "modelValue");
3236
+ const hovered = ref(null);
3237
+ const stars = computed(() => Array.from({ length: props.max }, (_, i) => i + 1));
3238
+ const display = computed(() => hovered.value ?? model.value);
3239
+ function fillFor(star) {
3240
+ const value = display.value;
3241
+ if (value >= star) return 1;
3242
+ if (props.readonly && props.allowHalf && value >= star - .5) return .5;
3243
+ return 0;
3244
+ }
3245
+ function select(star) {
3246
+ if (props.readonly || props.disabled) return;
3247
+ model.value = star;
3248
+ }
3249
+ function onKeydown(event) {
3250
+ if (props.readonly || props.disabled) return;
3251
+ let next;
3252
+ if (event.key === "ArrowRight" || event.key === "ArrowUp") next = Math.min(props.max, model.value + 1);
3253
+ else if (event.key === "ArrowLeft" || event.key === "ArrowDown") next = Math.max(0, model.value - 1);
3254
+ else if (event.key === "Home") next = 0;
3255
+ else if (event.key === "End") next = props.max;
3256
+ if (next === void 0) return;
3257
+ event.preventDefault();
3258
+ model.value = next;
3259
+ }
3260
+ const groupLabel = computed(() => props.label ?? (props.readonly ? `${model.value} out of ${props.max} stars` : "Rating"));
3261
+ return (_ctx, _cache) => {
3262
+ return openBlock(), createElementBlock("div", {
3263
+ class: normalizeClass(["j-rating", [`j-rating--${__props.size}`, {
3264
+ "is-readonly": __props.readonly,
3265
+ "is-disabled": __props.disabled
3266
+ }]]),
3267
+ role: __props.readonly ? "img" : "radiogroup",
3268
+ "aria-label": groupLabel.value,
3269
+ "aria-disabled": __props.disabled || void 0,
3270
+ onMouseleave: _cache[1] || (_cache[1] = ($event) => hovered.value = null)
3271
+ }, [__props.readonly ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(stars.value, (star) => {
3272
+ return openBlock(), createElementBlock("span", {
3273
+ key: star,
3274
+ class: "j-rating__star",
3275
+ "aria-hidden": "true"
3276
+ }, [_cache[3] || (_cache[3] = createElementVNode("svg", {
3277
+ viewBox: "0 0 16 16",
3278
+ class: "j-rating__star-bg"
3279
+ }, [createElementVNode("path", { d: "M8 1.5l1.98 4.01 4.42.64-3.2 3.12.76 4.4L8 11.6l-3.96 2.08.76-4.4-3.2-3.12 4.42-.64z" })], -1)), createElementVNode("span", {
3280
+ class: "j-rating__star-fill",
3281
+ style: normalizeStyle({ width: `${fillFor(star) * 100}%` })
3282
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("svg", { viewBox: "0 0 16 16" }, [createElementVNode("path", { d: "M8 1.5l1.98 4.01 4.42.64-3.2 3.12.76 4.4L8 11.6l-3.96 2.08.76-4.4-3.2-3.12 4.42-.64z" })], -1)])], 4)]);
3283
+ }), 128)) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(stars.value, (star) => {
3284
+ return openBlock(), createElementBlock("button", {
3285
+ key: star,
3286
+ type: "button",
3287
+ role: "radio",
3288
+ class: "j-rating__button j-focusable",
3289
+ "aria-checked": model.value === star,
3290
+ "aria-label": `${star} ${star === 1 ? "star" : "stars"}`,
3291
+ tabindex: __props.disabled ? -1 : model.value === star || model.value === 0 && star === 1 ? 0 : -1,
3292
+ disabled: __props.disabled,
3293
+ onClick: ($event) => select(star),
3294
+ onMouseenter: ($event) => hovered.value = star,
3295
+ onFocus: ($event) => hovered.value = star,
3296
+ onBlur: _cache[0] || (_cache[0] = ($event) => hovered.value = null),
3297
+ onKeydown
3298
+ }, [_cache[5] || (_cache[5] = createElementVNode("svg", {
3299
+ viewBox: "0 0 16 16",
3300
+ class: "j-rating__star-bg"
3301
+ }, [createElementVNode("path", { d: "M8 1.5l1.98 4.01 4.42.64-3.2 3.12.76 4.4L8 11.6l-3.96 2.08.76-4.4-3.2-3.12 4.42-.64z" })], -1)), createElementVNode("span", {
3302
+ class: "j-rating__star-fill",
3303
+ style: normalizeStyle({ width: `${fillFor(star) * 100}%` })
3304
+ }, [..._cache[4] || (_cache[4] = [createElementVNode("svg", { viewBox: "0 0 16 16" }, [createElementVNode("path", { d: "M8 1.5l1.98 4.01 4.42.64-3.2 3.12.76 4.4L8 11.6l-3.96 2.08.76-4.4-3.2-3.12 4.42-.64z" })], -1)])], 4)], 40, _hoisted_2$11);
3305
+ }), 128))], 42, _hoisted_1$16);
2781
3306
  };
2782
3307
  }
2783
3308
  });
2784
3309
  //#endregion
2785
3310
  //#region src/components/select/JSelect.vue?vue&type=script&setup=true&lang.ts
2786
- var _hoisted_1$8 = [
3311
+ var _hoisted_1$15 = [
2787
3312
  "id",
2788
3313
  "aria-expanded",
2789
3314
  "aria-controls",
@@ -2794,18 +3319,18 @@ var _hoisted_1$8 = [
2794
3319
  "aria-required",
2795
3320
  "disabled"
2796
3321
  ];
2797
- var _hoisted_2$6 = ["id"];
2798
- var _hoisted_3$4 = ["name", "value"];
2799
- var _hoisted_4$3 = ["id", "aria-labelledby"];
2800
- var _hoisted_5$3 = [
3322
+ var _hoisted_2$10 = ["id"];
3323
+ var _hoisted_3$7 = ["name", "value"];
3324
+ var _hoisted_4$5 = ["id", "aria-labelledby"];
3325
+ var _hoisted_5$5 = [
2801
3326
  "id",
2802
3327
  "aria-selected",
2803
3328
  "aria-disabled",
2804
3329
  "onPointermove",
2805
3330
  "onClick"
2806
3331
  ];
2807
- var _hoisted_6$2 = { class: "j-select__option-text" };
2808
- var _hoisted_7 = { class: "j-select__option-label" };
3332
+ var _hoisted_6$4 = { class: "j-select__option-text" };
3333
+ var _hoisted_7$2 = { class: "j-select__option-label" };
2809
3334
  var _hoisted_8 = {
2810
3335
  key: 0,
2811
3336
  class: "j-select__option-description"
@@ -3043,13 +3568,13 @@ var JSelect_default = /* @__PURE__ */ defineComponent({
3043
3568
  }), [createElementVNode("span", {
3044
3569
  id: valueId.value,
3045
3570
  class: normalizeClass(["j-select__value", { "is-placeholder": !selected.value }])
3046
- }, [selected.value ? renderSlot(_ctx.$slots, "value", { option: selected.value }, () => [createTextVNode(toDisplayString(selected.value.label), 1)], void 0, 0) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(__props.placeholder), 1)], 64))], 10, _hoisted_2$6), createVNode(unref(IconChevronUpDown), { class: "j-select__chevron" })], 16, _hoisted_1$8),
3571
+ }, [selected.value ? renderSlot(_ctx.$slots, "value", { option: selected.value }, () => [createTextVNode(toDisplayString(selected.value.label), 1)], void 0, 0) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(__props.placeholder), 1)], 64))], 10, _hoisted_2$10), createVNode(unref(IconChevronUpDown), { class: "j-select__chevron" })], 16, _hoisted_1$15),
3047
3572
  __props.name ? (openBlock(), createElementBlock("input", {
3048
3573
  key: 0,
3049
3574
  type: "hidden",
3050
3575
  name: __props.name,
3051
3576
  value: model.value ?? ""
3052
- }, null, 8, _hoisted_3$4)) : createCommentVNode("", true),
3577
+ }, null, 8, _hoisted_3$7)) : createCommentVNode("", true),
3053
3578
  createVNode(JPortal_default, null, {
3054
3579
  default: withCtx(() => [createVNode(Transition, { name: "j-pop" }, {
3055
3580
  default: withCtx(() => [open.value ? (openBlock(), createElementBlock("ul", {
@@ -3076,12 +3601,12 @@ var JSelect_default = /* @__PURE__ */ defineComponent({
3076
3601
  "aria-disabled": option.disabled || void 0,
3077
3602
  onPointermove: ($event) => onOptionPointerMove(index),
3078
3603
  onClick: ($event) => commit(index)
3079
- }, [createElementVNode("span", _hoisted_6$2, [renderSlot(_ctx.$slots, "option", {
3604
+ }, [createElementVNode("span", _hoisted_6$4, [renderSlot(_ctx.$slots, "option", {
3080
3605
  option,
3081
3606
  selected: option.value === model.value,
3082
3607
  active: index === activeIndex.value
3083
- }, () => [createElementVNode("span", _hoisted_7, toDisplayString(option.label), 1), option.description ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(option.description), 1)) : createCommentVNode("", true)])]), createVNode(unref(IconCheck), { class: "j-select__check" })], 42, _hoisted_5$3);
3084
- }), 128)), visibleOptions.value.length === 0 ? (openBlock(), createElementBlock("li", _hoisted_9, " No options ")) : createCommentVNode("", true)], 46, _hoisted_4$3)) : createCommentVNode("", true)]),
3608
+ }, () => [createElementVNode("span", _hoisted_7$2, toDisplayString(option.label), 1), option.description ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(option.description), 1)) : createCommentVNode("", true)])]), createVNode(unref(IconCheck), { class: "j-select__check" })], 42, _hoisted_5$5);
3609
+ }), 128)), visibleOptions.value.length === 0 ? (openBlock(), createElementBlock("li", _hoisted_9, " No options ")) : createCommentVNode("", true)], 46, _hoisted_4$5)) : createCommentVNode("", true)]),
3085
3610
  _: 3
3086
3611
  })]),
3087
3612
  _: 3
@@ -3111,8 +3636,8 @@ var JSelect_default = /* @__PURE__ */ defineComponent({
3111
3636
  });
3112
3637
  //#endregion
3113
3638
  //#region src/components/separator/JSeparator.vue?vue&type=script&setup=true&lang.ts
3114
- var _hoisted_1$7 = ["role", "aria-orientation"];
3115
- var _hoisted_2$5 = {
3639
+ var _hoisted_1$14 = ["role", "aria-orientation"];
3640
+ var _hoisted_2$9 = {
3116
3641
  key: 0,
3117
3642
  class: "j-separator__label"
3118
3643
  };
@@ -3134,28 +3659,28 @@ var JSeparator_default = /* @__PURE__ */ defineComponent({
3134
3659
  class: normalizeClass(["j-separator", [`j-separator--${__props.orientation}`, { "j-separator--labelled": __props.label || _ctx.$slots.default }]]),
3135
3660
  role: __props.decorative ? "none" : "separator",
3136
3661
  "aria-orientation": __props.decorative ? void 0 : __props.orientation
3137
- }, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("span", _hoisted_2$5, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])])) : createCommentVNode("", true)], 10, _hoisted_1$7);
3662
+ }, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("span", _hoisted_2$9, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])])) : createCommentVNode("", true)], 10, _hoisted_1$14);
3138
3663
  };
3139
3664
  }
3140
3665
  });
3141
3666
  //#endregion
3142
3667
  //#region src/components/sheet/JSheet.vue?vue&type=script&setup=true&lang.ts
3143
- var _hoisted_1$6 = {
3668
+ var _hoisted_1$13 = {
3144
3669
  key: 0,
3145
3670
  class: "j-sheet__overlay",
3146
3671
  "aria-hidden": "true"
3147
3672
  };
3148
- var _hoisted_2$4 = [
3673
+ var _hoisted_2$8 = [
3149
3674
  "aria-labelledby",
3150
3675
  "aria-label",
3151
3676
  "aria-describedby"
3152
3677
  ];
3153
- var _hoisted_3$3 = {
3678
+ var _hoisted_3$6 = {
3154
3679
  key: 0,
3155
3680
  class: "j-sheet__header"
3156
3681
  };
3157
- var _hoisted_4$2 = { class: "j-sheet__body" };
3158
- var _hoisted_5$2 = {
3682
+ var _hoisted_4$4 = { class: "j-sheet__body" };
3683
+ var _hoisted_5$4 = {
3159
3684
  key: 1,
3160
3685
  class: "j-sheet__footer"
3161
3686
  };
@@ -3207,7 +3732,7 @@ var JSheet_default = /* @__PURE__ */ defineComponent({
3207
3732
  return (_ctx, _cache) => {
3208
3733
  return openBlock(), createBlock(JPortal_default, null, {
3209
3734
  default: withCtx(() => [createVNode(Transition, { name: "j-sheet-overlay" }, {
3210
- default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$6)) : createCommentVNode("", true)]),
3735
+ default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$13)) : createCommentVNode("", true)]),
3211
3736
  _: 1
3212
3737
  }), createVNode(Transition, {
3213
3738
  name: "j-sheet",
@@ -3238,7 +3763,7 @@ var JSheet_default = /* @__PURE__ */ defineComponent({
3238
3763
  "aria-describedby": __props.description ? descriptionId : void 0,
3239
3764
  onAnimationend: _cache[0] || (_cache[0] = ($event) => nudging.value = false)
3240
3765
  }, [
3241
- __props.title || __props.description || _ctx.$slots.header ? (openBlock(), createElementBlock("header", _hoisted_3$3, [renderSlot(_ctx.$slots, "header", {
3766
+ __props.title || __props.description || _ctx.$slots.header ? (openBlock(), createElementBlock("header", _hoisted_3$6, [renderSlot(_ctx.$slots, "header", {
3242
3767
  titleId,
3243
3768
  descriptionId
3244
3769
  }, () => [createElementVNode("h2", {
@@ -3249,8 +3774,8 @@ var JSheet_default = /* @__PURE__ */ defineComponent({
3249
3774
  id: descriptionId,
3250
3775
  class: "j-sheet__description"
3251
3776
  }, toDisplayString(__props.description), 1)) : createCommentVNode("", true)])])) : createCommentVNode("", true),
3252
- createElementVNode("div", _hoisted_4$2, [renderSlot(_ctx.$slots, "default", { close })]),
3253
- _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_5$2, [renderSlot(_ctx.$slots, "footer", { close })])) : createCommentVNode("", true),
3777
+ createElementVNode("div", _hoisted_4$4, [renderSlot(_ctx.$slots, "default", { close })]),
3778
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_5$4, [renderSlot(_ctx.$slots, "footer", { close })])) : createCommentVNode("", true),
3254
3779
  !__props.hideClose ? (openBlock(), createElementBlock("button", {
3255
3780
  key: 2,
3256
3781
  type: "button",
@@ -3258,7 +3783,7 @@ var JSheet_default = /* @__PURE__ */ defineComponent({
3258
3783
  "aria-label": "Close",
3259
3784
  onClick: close
3260
3785
  }, [createVNode(unref(IconX))])) : createCommentVNode("", true)
3261
- ], 42, _hoisted_2$4)], 34)) : createCommentVNode("", true)]),
3786
+ ], 42, _hoisted_2$8)], 34)) : createCommentVNode("", true)]),
3262
3787
  _: 3
3263
3788
  })]),
3264
3789
  _: 3
@@ -3307,9 +3832,178 @@ var JSkeleton_default = /* @__PURE__ */ defineComponent({
3307
3832
  }
3308
3833
  });
3309
3834
  //#endregion
3835
+ //#region src/components/slider/JSlider.vue?vue&type=script&setup=true&lang.ts
3836
+ var _hoisted_1$12 = [
3837
+ "tabindex",
3838
+ "aria-label",
3839
+ "aria-valuemin",
3840
+ "aria-valuemax",
3841
+ "aria-valuenow",
3842
+ "aria-valuetext",
3843
+ "aria-disabled",
3844
+ "onPointerdown",
3845
+ "onKeydown"
3846
+ ];
3847
+ var _hoisted_2$7 = {
3848
+ key: 0,
3849
+ class: "j-slider__bubble"
3850
+ };
3851
+ //#endregion
3852
+ //#region src/components/slider/JSlider.vue
3853
+ var JSlider_default = /* @__PURE__ */ defineComponent({
3854
+ __name: "JSlider",
3855
+ props: /*@__PURE__*/ mergeModels({
3856
+ min: { default: 0 },
3857
+ max: { default: 100 },
3858
+ step: { default: 1 },
3859
+ disabled: { type: Boolean },
3860
+ label: {},
3861
+ size: { default: "md" },
3862
+ showValue: { type: Boolean },
3863
+ format: {}
3864
+ }, {
3865
+ "modelValue": { default: 0 },
3866
+ "modelModifiers": {}
3867
+ }),
3868
+ emits: ["update:modelValue"],
3869
+ setup(__props) {
3870
+ const props = __props;
3871
+ /** A single value, or a `[low, high]` tuple for a range slider. */
3872
+ const model = useModel(__props, "modelValue");
3873
+ const track = ref(null);
3874
+ const activeThumb = ref(null);
3875
+ const isRange = computed(() => Array.isArray(model.value));
3876
+ const values = computed(() => Array.isArray(model.value) ? model.value : [model.value]);
3877
+ function clamp(value) {
3878
+ const stepped = Math.round((value - props.min) / props.step) * props.step + props.min;
3879
+ const rounded = Number(stepped.toFixed(6));
3880
+ return Math.min(props.max, Math.max(props.min, rounded));
3881
+ }
3882
+ function setValue(index, raw) {
3883
+ if (props.disabled) return;
3884
+ const next = [...values.value];
3885
+ let value = clamp(raw);
3886
+ if (isRange.value) {
3887
+ const lower = index === 0 ? props.min : next[index - 1];
3888
+ const upper = index === next.length - 1 ? props.max : next[index + 1];
3889
+ value = Math.min(upper, Math.max(lower, value));
3890
+ }
3891
+ next[index] = value;
3892
+ model.value = isRange.value ? [next[0], next[1]] : next[0];
3893
+ }
3894
+ function percent(value) {
3895
+ if (props.max === props.min) return 0;
3896
+ return (value - props.min) / (props.max - props.min) * 100;
3897
+ }
3898
+ function valueFromClientX(clientX) {
3899
+ const rect = track.value.getBoundingClientRect();
3900
+ const ratio = Math.min(1, Math.max(0, (clientX - rect.left) / rect.width));
3901
+ return props.min + ratio * (props.max - props.min);
3902
+ }
3903
+ function nearestThumb(value) {
3904
+ let nearest = 0;
3905
+ let best = Infinity;
3906
+ values.value.forEach((v, i) => {
3907
+ const dist = Math.abs(v - value);
3908
+ if (dist < best) {
3909
+ best = dist;
3910
+ nearest = i;
3911
+ }
3912
+ });
3913
+ return nearest;
3914
+ }
3915
+ function onPointerMove(event) {
3916
+ if (activeThumb.value === null) return;
3917
+ setValue(activeThumb.value, valueFromClientX(event.clientX));
3918
+ }
3919
+ function onPointerUp() {
3920
+ activeThumb.value = null;
3921
+ window.removeEventListener("pointermove", onPointerMove);
3922
+ window.removeEventListener("pointerup", onPointerUp);
3923
+ }
3924
+ function startDrag(index) {
3925
+ activeThumb.value = index;
3926
+ window.addEventListener("pointermove", onPointerMove);
3927
+ window.addEventListener("pointerup", onPointerUp);
3928
+ }
3929
+ function onTrackPointerDown(event) {
3930
+ if (props.disabled) return;
3931
+ const value = valueFromClientX(event.clientX);
3932
+ const index = nearestThumb(value);
3933
+ setValue(index, value);
3934
+ startDrag(index);
3935
+ }
3936
+ function onThumbPointerDown(index, event) {
3937
+ if (props.disabled) return;
3938
+ event.stopPropagation();
3939
+ event.currentTarget.focus();
3940
+ startDrag(index);
3941
+ }
3942
+ function onKeydown(index, event) {
3943
+ if (props.disabled) return;
3944
+ const big = props.step * 10 || (props.max - props.min) / 10;
3945
+ const current = values.value[index];
3946
+ let next;
3947
+ if (event.key === "ArrowRight" || event.key === "ArrowUp") next = current + props.step;
3948
+ else if (event.key === "ArrowLeft" || event.key === "ArrowDown") next = current - props.step;
3949
+ else if (event.key === "PageUp") next = current + big;
3950
+ else if (event.key === "PageDown") next = current - big;
3951
+ else if (event.key === "Home") next = props.min;
3952
+ else if (event.key === "End") next = props.max;
3953
+ if (next === void 0) return;
3954
+ event.preventDefault();
3955
+ setValue(index, next);
3956
+ }
3957
+ function display(value) {
3958
+ return props.format ? props.format(value) : String(Math.round(value * 100) / 100);
3959
+ }
3960
+ const fillStyle = computed(() => {
3961
+ if (isRange.value) {
3962
+ const [a, b] = values.value;
3963
+ return {
3964
+ left: `${percent(a)}%`,
3965
+ width: `${Math.max(0, percent(b) - percent(a))}%`
3966
+ };
3967
+ }
3968
+ return {
3969
+ left: "0%",
3970
+ width: `${percent(values.value[0])}%`
3971
+ };
3972
+ });
3973
+ return (_ctx, _cache) => {
3974
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["j-slider", [`j-slider--${__props.size}`, { "is-disabled": __props.disabled }]]) }, [createElementVNode("div", {
3975
+ ref_key: "track",
3976
+ ref: track,
3977
+ class: "j-slider__track",
3978
+ onPointerdown: onTrackPointerDown
3979
+ }, [createElementVNode("span", {
3980
+ class: "j-slider__range",
3981
+ style: normalizeStyle(fillStyle.value)
3982
+ }, null, 4), (openBlock(true), createElementBlock(Fragment, null, renderList(values.value, (value, index) => {
3983
+ return openBlock(), createElementBlock("span", {
3984
+ key: index,
3985
+ class: normalizeClass(["j-slider__thumb j-focusable", { "is-dragging": activeThumb.value === index }]),
3986
+ role: "slider",
3987
+ tabindex: __props.disabled ? -1 : 0,
3988
+ "aria-label": __props.label,
3989
+ "aria-orientation": "horizontal",
3990
+ "aria-valuemin": __props.min,
3991
+ "aria-valuemax": __props.max,
3992
+ "aria-valuenow": value,
3993
+ "aria-valuetext": display(value),
3994
+ "aria-disabled": __props.disabled || void 0,
3995
+ style: normalizeStyle({ left: `${percent(value)}%` }),
3996
+ onPointerdown: ($event) => onThumbPointerDown(index, $event),
3997
+ onKeydown: ($event) => onKeydown(index, $event)
3998
+ }, [__props.showValue ? (openBlock(), createElementBlock("span", _hoisted_2$7, toDisplayString(display(value)), 1)) : createCommentVNode("", true)], 46, _hoisted_1$12);
3999
+ }), 128))], 544)], 2);
4000
+ };
4001
+ }
4002
+ });
4003
+ //#endregion
3310
4004
  //#region src/components/spinner/JSpinner.vue?vue&type=script&setup=true&lang.ts
3311
- var _hoisted_1$5 = ["role"];
3312
- var _hoisted_2$3 = {
4005
+ var _hoisted_1$11 = ["role"];
4006
+ var _hoisted_2$6 = {
3313
4007
  key: 0,
3314
4008
  class: "j-sr-only"
3315
4009
  };
@@ -3332,27 +4026,72 @@ var JSpinner_default = /* @__PURE__ */ defineComponent({
3332
4026
  return openBlock(), createElementBlock("span", {
3333
4027
  class: "j-spinner-wrap",
3334
4028
  role: __props.label ? "status" : void 0
3335
- }, [createVNode(unref(Spinner), { size: pixels.value }, null, 8, ["size"]), __props.label ? (openBlock(), createElementBlock("span", _hoisted_2$3, toDisplayString(__props.label), 1)) : createCommentVNode("", true)], 8, _hoisted_1$5);
4029
+ }, [createVNode(unref(Spinner), { size: pixels.value }, null, 8, ["size"]), __props.label ? (openBlock(), createElementBlock("span", _hoisted_2$6, toDisplayString(__props.label), 1)) : createCommentVNode("", true)], 8, _hoisted_1$11);
4030
+ };
4031
+ }
4032
+ });
4033
+ //#endregion
4034
+ //#region src/components/stat/JStat.vue?vue&type=script&setup=true&lang.ts
4035
+ var _hoisted_1$10 = { class: "j-stat" };
4036
+ var _hoisted_2$5 = { class: "j-stat__header" };
4037
+ var _hoisted_3$5 = {
4038
+ key: 0,
4039
+ class: "j-stat__icon",
4040
+ "aria-hidden": "true"
4041
+ };
4042
+ var _hoisted_4$3 = { class: "j-stat__label" };
4043
+ var _hoisted_5$3 = { class: "j-stat__row" };
4044
+ var _hoisted_6$3 = { class: "j-stat__value" };
4045
+ var _hoisted_7$1 = {
4046
+ key: 0,
4047
+ class: "j-stat__description"
4048
+ };
4049
+ //#endregion
4050
+ //#region src/components/stat/JStat.vue
4051
+ var JStat_default = /* @__PURE__ */ defineComponent({
4052
+ __name: "JStat",
4053
+ props: {
4054
+ label: {},
4055
+ value: {},
4056
+ delta: {},
4057
+ trend: {},
4058
+ description: {}
4059
+ },
4060
+ setup(__props) {
4061
+ const props = __props;
4062
+ const trendIcon = computed(() => props.trend === "up" ? IconArrowUpRight : props.trend === "down" ? IconArrowDownRight : null);
4063
+ return (_ctx, _cache) => {
4064
+ return openBlock(), createElementBlock("div", _hoisted_1$10, [
4065
+ createElementVNode("div", _hoisted_2$5, [_ctx.$slots.icon ? (openBlock(), createElementBlock("span", _hoisted_3$5, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("", true), createElementVNode("span", _hoisted_4$3, toDisplayString(__props.label), 1)]),
4066
+ createElementVNode("div", _hoisted_5$3, [createElementVNode("span", _hoisted_6$3, toDisplayString(__props.value), 1), __props.delta ? (openBlock(), createElementBlock("span", {
4067
+ key: 0,
4068
+ class: normalizeClass(["j-stat__delta", __props.trend ? `j-stat__delta--${__props.trend}` : void 0])
4069
+ }, [trendIcon.value ? (openBlock(), createBlock(resolveDynamicComponent(trendIcon.value), {
4070
+ key: 0,
4071
+ "aria-hidden": "true"
4072
+ })) : createCommentVNode("", true), createTextVNode(" " + toDisplayString(__props.delta), 1)], 2)) : createCommentVNode("", true)]),
4073
+ __props.description ? (openBlock(), createElementBlock("p", _hoisted_7$1, toDisplayString(__props.description), 1)) : createCommentVNode("", true)
4074
+ ]);
3336
4075
  };
3337
4076
  }
3338
4077
  });
3339
4078
  //#endregion
3340
4079
  //#region src/components/switch/JSwitch.vue?vue&type=script&setup=true&lang.ts
3341
- var _hoisted_1$4 = ["data-state"];
3342
- var _hoisted_2$2 = [
4080
+ var _hoisted_1$9 = ["data-state"];
4081
+ var _hoisted_2$4 = [
3343
4082
  "id",
3344
4083
  "aria-checked",
3345
4084
  "aria-labelledby",
3346
4085
  "aria-describedby",
3347
4086
  "disabled"
3348
4087
  ];
3349
- var _hoisted_3$2 = ["name", "value"];
3350
- var _hoisted_4$1 = {
4088
+ var _hoisted_3$4 = ["name", "value"];
4089
+ var _hoisted_4$2 = {
3351
4090
  key: 1,
3352
4091
  class: "j-switch__text"
3353
4092
  };
3354
- var _hoisted_5$1 = ["id", "for"];
3355
- var _hoisted_6$1 = ["id"];
4093
+ var _hoisted_5$2 = ["id", "for"];
4094
+ var _hoisted_6$2 = ["id"];
3356
4095
  //#endregion
3357
4096
  //#region src/components/switch/JSwitch.vue
3358
4097
  var JSwitch_default = /* @__PURE__ */ defineComponent({
@@ -3414,31 +4153,31 @@ var JSwitch_default = /* @__PURE__ */ defineComponent({
3414
4153
  "aria-describedby": __props.description || _ctx.$slots.description ? descriptionId.value : void 0,
3415
4154
  disabled: __props.disabled,
3416
4155
  onClick: toggle
3417
- }), [..._cache[0] || (_cache[0] = [createElementVNode("span", { class: "j-switch__thumb" }, null, -1)])], 16, _hoisted_2$2),
4156
+ }), [..._cache[0] || (_cache[0] = [createElementVNode("span", { class: "j-switch__thumb" }, null, -1)])], 16, _hoisted_2$4),
3418
4157
  __props.name && model.value ? (openBlock(), createElementBlock("input", {
3419
4158
  key: 0,
3420
4159
  type: "hidden",
3421
4160
  name: __props.name,
3422
4161
  value: __props.value
3423
- }, null, 8, _hoisted_3$2)) : createCommentVNode("", true),
3424
- __props.label || _ctx.$slots.default || __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_4$1, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("label", {
4162
+ }, null, 8, _hoisted_3$4)) : createCommentVNode("", true),
4163
+ __props.label || _ctx.$slots.default || __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_4$2, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("label", {
3425
4164
  key: 0,
3426
4165
  id: labelId.value,
3427
4166
  for: id.value,
3428
4167
  class: "j-switch__label"
3429
- }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])], 8, _hoisted_5$1)) : createCommentVNode("", true), __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", {
4168
+ }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])], 8, _hoisted_5$2)) : createCommentVNode("", true), __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", {
3430
4169
  key: 1,
3431
4170
  id: descriptionId.value,
3432
4171
  class: "j-switch__description"
3433
- }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])], 8, _hoisted_6$1)) : createCommentVNode("", true)])) : createCommentVNode("", true)
3434
- ], 14, _hoisted_1$4);
4172
+ }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])], 8, _hoisted_6$2)) : createCommentVNode("", true)])) : createCommentVNode("", true)
4173
+ ], 14, _hoisted_1$9);
3435
4174
  };
3436
4175
  }
3437
4176
  });
3438
4177
  //#endregion
3439
4178
  //#region src/components/tabs/JTabs.vue?vue&type=script&setup=true&lang.ts
3440
- var _hoisted_1$3 = ["aria-label"];
3441
- var _hoisted_2$1 = [
4179
+ var _hoisted_1$8 = ["aria-label"];
4180
+ var _hoisted_2$3 = [
3442
4181
  "id",
3443
4182
  "aria-selected",
3444
4183
  "aria-controls",
@@ -3446,7 +4185,7 @@ var _hoisted_2$1 = [
3446
4185
  "disabled",
3447
4186
  "onClick"
3448
4187
  ];
3449
- var _hoisted_3$1 = [
4188
+ var _hoisted_3$3 = [
3450
4189
  "id",
3451
4190
  "aria-labelledby",
3452
4191
  "hidden"
@@ -3567,8 +4306,8 @@ var JTabs_default = /* @__PURE__ */ defineComponent({
3567
4306
  }, [renderSlot(_ctx.$slots, "tab", {
3568
4307
  item,
3569
4308
  selected: item.value === selected.value
3570
- }, () => [createTextVNode(toDisplayString(item.label), 1)])], 8, _hoisted_2$1);
3571
- }), 128))], 40, _hoisted_1$3), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
4309
+ }, () => [createTextVNode(toDisplayString(item.label), 1)])], 8, _hoisted_2$3);
4310
+ }), 128))], 40, _hoisted_1$8), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
3572
4311
  return openBlock(), createElementBlock(Fragment, { key: item.value }, [_ctx.$slots[item.value] ? (openBlock(), createElementBlock("div", {
3573
4312
  key: 0,
3574
4313
  id: panelId(item.value),
@@ -3580,14 +4319,62 @@ var JTabs_default = /* @__PURE__ */ defineComponent({
3580
4319
  }, [renderSlot(_ctx.$slots, item.value, {
3581
4320
  item,
3582
4321
  selected: item.value === selected.value
3583
- })], 8, _hoisted_3$1)) : createCommentVNode("", true)], 64);
4322
+ })], 8, _hoisted_3$3)) : createCommentVNode("", true)], 64);
3584
4323
  }), 128))], 2);
3585
4324
  };
3586
4325
  }
3587
4326
  });
3588
4327
  //#endregion
4328
+ //#region src/components/tag/JTag.vue?vue&type=script&setup=true&lang.ts
4329
+ var _hoisted_1$7 = {
4330
+ key: 0,
4331
+ class: "j-tag__icon"
4332
+ };
4333
+ var _hoisted_2$2 = { class: "j-tag__label" };
4334
+ var _hoisted_3$2 = ["aria-label", "disabled"];
4335
+ //#endregion
4336
+ //#region src/components/tag/JTag.vue
4337
+ var JTag_default = /* @__PURE__ */ defineComponent({
4338
+ __name: "JTag",
4339
+ props: {
4340
+ variant: { default: "neutral" },
4341
+ size: { default: "md" },
4342
+ disabled: { type: Boolean },
4343
+ removeLabel: {}
4344
+ },
4345
+ emits: ["remove"],
4346
+ setup(__props, { emit: __emit }) {
4347
+ const props = __props;
4348
+ const emit = __emit;
4349
+ const slots = useSlots();
4350
+ const text = computed(() => slots.default?.().map((vnode) => typeof vnode.children === "string" ? vnode.children : "").join("").trim());
4351
+ const removeButtonLabel = computed(() => props.removeLabel || (text.value ? `Remove ${text.value}` : "Remove"));
4352
+ function onRemove() {
4353
+ if (props.disabled) return;
4354
+ emit("remove");
4355
+ }
4356
+ return (_ctx, _cache) => {
4357
+ return openBlock(), createElementBlock("span", { class: normalizeClass(["j-tag", [
4358
+ `j-tag--${__props.variant}`,
4359
+ `j-tag--${__props.size}`,
4360
+ { "is-disabled": __props.disabled }
4361
+ ]]) }, [
4362
+ _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_1$7, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
4363
+ createElementVNode("span", _hoisted_2$2, [renderSlot(_ctx.$slots, "default")]),
4364
+ createElementVNode("button", {
4365
+ type: "button",
4366
+ class: "j-tag__remove j-focusable",
4367
+ "aria-label": removeButtonLabel.value,
4368
+ disabled: __props.disabled,
4369
+ onClick: onRemove
4370
+ }, [createVNode(unref(IconX))], 8, _hoisted_3$2)
4371
+ ], 2);
4372
+ };
4373
+ }
4374
+ });
4375
+ //#endregion
3589
4376
  //#region src/components/textarea/JTextarea.vue?vue&type=script&setup=true&lang.ts
3590
- var _hoisted_1$2 = [
4377
+ var _hoisted_1$6 = [
3591
4378
  "id",
3592
4379
  "rows",
3593
4380
  "name",
@@ -3689,7 +4476,7 @@ var JTextarea_default = /* @__PURE__ */ defineComponent({
3689
4476
  required: __props.required,
3690
4477
  "aria-invalid": unref(field).invalid.value || void 0,
3691
4478
  "aria-describedby": unref(field).describedBy.value
3692
- }), null, 16, _hoisted_1$2), [[vModelText, model.value]])], 2)]),
4479
+ }), null, 16, _hoisted_1$6), [[vModelText, model.value]])], 2)]),
3693
4480
  _: 2
3694
4481
  }, [_ctx.$slots.label ? {
3695
4482
  name: "label",
@@ -3713,6 +4500,55 @@ var JTextarea_default = /* @__PURE__ */ defineComponent({
3713
4500
  }
3714
4501
  });
3715
4502
  //#endregion
4503
+ //#region src/components/timeline/JTimeline.vue?vue&type=script&setup=true&lang.ts
4504
+ var _hoisted_1$5 = { class: "j-timeline" };
4505
+ //#endregion
4506
+ //#region src/components/timeline/JTimeline.vue
4507
+ var JTimeline_default = /* @__PURE__ */ defineComponent({
4508
+ __name: "JTimeline",
4509
+ setup(__props) {
4510
+ return (_ctx, _cache) => {
4511
+ return openBlock(), createElementBlock("ol", _hoisted_1$5, [renderSlot(_ctx.$slots, "default")]);
4512
+ };
4513
+ }
4514
+ });
4515
+ //#endregion
4516
+ //#region src/components/timeline/JTimelineItem.vue?vue&type=script&setup=true&lang.ts
4517
+ var _hoisted_1$4 = {
4518
+ class: "j-timeline-item__rail",
4519
+ "aria-hidden": "true"
4520
+ };
4521
+ var _hoisted_2$1 = { class: "j-timeline-item__marker" };
4522
+ var _hoisted_3$1 = { class: "j-timeline-item__content" };
4523
+ var _hoisted_4$1 = { class: "j-timeline-item__header" };
4524
+ var _hoisted_5$1 = {
4525
+ key: 0,
4526
+ class: "j-timeline-item__title"
4527
+ };
4528
+ var _hoisted_6$1 = {
4529
+ key: 1,
4530
+ class: "j-timeline-item__time"
4531
+ };
4532
+ var _hoisted_7 = {
4533
+ key: 0,
4534
+ class: "j-timeline-item__body"
4535
+ };
4536
+ //#endregion
4537
+ //#region src/components/timeline/JTimelineItem.vue
4538
+ var JTimelineItem_default = /* @__PURE__ */ defineComponent({
4539
+ __name: "JTimelineItem",
4540
+ props: {
4541
+ title: {},
4542
+ time: {},
4543
+ status: { default: "complete" }
4544
+ },
4545
+ setup(__props) {
4546
+ return (_ctx, _cache) => {
4547
+ return openBlock(), createElementBlock("li", { class: normalizeClass(["j-timeline-item", `j-timeline-item--${__props.status}`]) }, [createElementVNode("span", _hoisted_1$4, [createElementVNode("span", _hoisted_2$1, [renderSlot(_ctx.$slots, "marker")])]), createElementVNode("div", _hoisted_3$1, [createElementVNode("div", _hoisted_4$1, [__props.title || _ctx.$slots.title ? (openBlock(), createElementBlock("p", _hoisted_5$1, [renderSlot(_ctx.$slots, "title", {}, () => [createTextVNode(toDisplayString(__props.title), 1)])])) : createCommentVNode("", true), __props.time ? (openBlock(), createElementBlock("time", _hoisted_6$1, toDisplayString(__props.time), 1)) : createCommentVNode("", true)]), _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_7, [renderSlot(_ctx.$slots, "default")])) : createCommentVNode("", true)])], 2);
4548
+ };
4549
+ }
4550
+ });
4551
+ //#endregion
3716
4552
  //#region src/composables/useToast.ts
3717
4553
  var DEFAULT_TOAST_DURATION = 5e3;
3718
4554
  var state = reactive({ toasts: [] });
@@ -3795,7 +4631,7 @@ var typed = (type) => (title, options) => create(title, {
3795
4631
  ...options,
3796
4632
  type
3797
4633
  });
3798
- /** Show a toast. Works anywhere — inside or outside components. */
4634
+ /** Show a toast. Works anywhere | inside or outside components. */
3799
4635
  var toast = Object.assign(create, {
3800
4636
  success: typed("success"),
3801
4637
  error: typed("error"),
@@ -3818,7 +4654,7 @@ function useToast() {
3818
4654
  var toastState = state;
3819
4655
  //#endregion
3820
4656
  //#region src/components/toast/JToastItem.vue?vue&type=script&setup=true&lang.ts
3821
- var _hoisted_1$1 = ["data-swipe-direction", "role"];
4657
+ var _hoisted_1$3 = ["data-swipe-direction", "role"];
3822
4658
  var _hoisted_2 = {
3823
4659
  key: 0,
3824
4660
  class: "j-toast__icon",
@@ -3980,13 +4816,13 @@ var JToastItem_default = /* @__PURE__ */ defineComponent({
3980
4816
  style: normalizeStyle({ animationDuration: `${__props.toast.duration}ms` }),
3981
4817
  "aria-hidden": "true"
3982
4818
  }, null, 6)) : createCommentVNode("", true)
3983
- ], 46, _hoisted_1$1);
4819
+ ], 46, _hoisted_1$3);
3984
4820
  };
3985
4821
  }
3986
4822
  });
3987
4823
  //#endregion
3988
4824
  //#region src/components/toast/JToaster.vue?vue&type=script&setup=true&lang.ts
3989
- var _hoisted_1 = ["aria-label"];
4825
+ var _hoisted_1$2 = ["aria-label"];
3990
4826
  //#endregion
3991
4827
  //#region src/components/toast/JToaster.vue
3992
4828
  var JToaster_default = /* @__PURE__ */ defineComponent({
@@ -4058,13 +4894,112 @@ var JToaster_default = /* @__PURE__ */ defineComponent({
4058
4894
  }, null, 8, ["toast", "paused"]);
4059
4895
  }), 128))]),
4060
4896
  _: 1
4061
- }, 512)], 10, _hoisted_1)]),
4897
+ }, 512)], 10, _hoisted_1$2)]),
4062
4898
  _: 1
4063
4899
  });
4064
4900
  };
4065
4901
  }
4066
4902
  });
4067
4903
  //#endregion
4904
+ //#region src/components/toggle-group/context.ts
4905
+ var TOGGLE_GROUP = Symbol("JToggleGroup");
4906
+ //#endregion
4907
+ //#region src/components/toggle-group/JToggleGroup.vue?vue&type=script&setup=true&lang.ts
4908
+ var _hoisted_1$1 = ["aria-label"];
4909
+ //#endregion
4910
+ //#region src/components/toggle-group/JToggleGroup.vue
4911
+ var JToggleGroup_default = /* @__PURE__ */ defineComponent({
4912
+ __name: "JToggleGroup",
4913
+ props: /*@__PURE__*/ mergeModels({
4914
+ type: { default: "single" },
4915
+ size: { default: "md" },
4916
+ disabled: { type: Boolean },
4917
+ label: {}
4918
+ }, {
4919
+ "modelValue": { default: null },
4920
+ "modelModifiers": {}
4921
+ }),
4922
+ emits: ["update:modelValue"],
4923
+ setup(__props) {
4924
+ const props = __props;
4925
+ /** The pressed value in `single` mode, or an array of values in `multiple` mode. */
4926
+ const model = useModel(__props, "modelValue");
4927
+ provide(TOGGLE_GROUP, {
4928
+ type: computed(() => props.type),
4929
+ disabled: computed(() => !!props.disabled),
4930
+ isSelected: (value) => {
4931
+ if (props.type === "multiple") return Array.isArray(model.value) && model.value.includes(value);
4932
+ return model.value === value;
4933
+ },
4934
+ toggle: (value) => {
4935
+ if (props.disabled) return;
4936
+ if (props.type === "multiple") {
4937
+ const current = Array.isArray(model.value) ? model.value : [];
4938
+ model.value = current.includes(value) ? current.filter((v) => v !== value) : [...current, value];
4939
+ return;
4940
+ }
4941
+ model.value = value;
4942
+ }
4943
+ });
4944
+ function onKeydown(event) {
4945
+ const target = event.target;
4946
+ if (!target.classList.contains("j-toggle-group__item")) return;
4947
+ const root = event.currentTarget;
4948
+ const items = Array.from(root.querySelectorAll(".j-toggle-group__item:not(:disabled)"));
4949
+ const index = items.indexOf(target);
4950
+ let next;
4951
+ if (event.key === "ArrowRight" || event.key === "ArrowDown") next = items[(index + 1) % items.length];
4952
+ else if (event.key === "ArrowLeft" || event.key === "ArrowUp") next = items[(index - 1 + items.length) % items.length];
4953
+ else if (event.key === "Home") next = items[0];
4954
+ else if (event.key === "End") next = items[items.length - 1];
4955
+ if (!next) return;
4956
+ event.preventDefault();
4957
+ focusElement(next);
4958
+ }
4959
+ return (_ctx, _cache) => {
4960
+ return openBlock(), createElementBlock("div", {
4961
+ class: normalizeClass(["j-toggle-group", [`j-toggle-group--${__props.size}`, { "is-disabled": __props.disabled }]]),
4962
+ role: "group",
4963
+ "aria-label": __props.label,
4964
+ onKeydown
4965
+ }, [renderSlot(_ctx.$slots, "default")], 42, _hoisted_1$1);
4966
+ };
4967
+ }
4968
+ });
4969
+ //#endregion
4970
+ //#region src/components/toggle-group/JToggleGroupItem.vue?vue&type=script&setup=true&lang.ts
4971
+ var _hoisted_1 = [
4972
+ "aria-pressed",
4973
+ "aria-label",
4974
+ "disabled"
4975
+ ];
4976
+ //#endregion
4977
+ //#region src/components/toggle-group/JToggleGroupItem.vue
4978
+ var JToggleGroupItem_default = /* @__PURE__ */ defineComponent({
4979
+ __name: "JToggleGroupItem",
4980
+ props: {
4981
+ value: {},
4982
+ disabled: { type: Boolean },
4983
+ label: {}
4984
+ },
4985
+ setup(__props) {
4986
+ const props = __props;
4987
+ const group = inject(TOGGLE_GROUP);
4988
+ const selected = computed(() => group.isSelected(props.value));
4989
+ const isDisabled = computed(() => props.disabled || group.disabled.value);
4990
+ return (_ctx, _cache) => {
4991
+ return openBlock(), createElementBlock("button", {
4992
+ type: "button",
4993
+ class: normalizeClass(["j-toggle-group__item j-focusable", { "is-selected": selected.value }]),
4994
+ "aria-pressed": selected.value,
4995
+ "aria-label": __props.label,
4996
+ disabled: isDisabled.value,
4997
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(group).toggle(__props.value))
4998
+ }, [renderSlot(_ctx.$slots, "default")], 10, _hoisted_1);
4999
+ };
5000
+ }
5001
+ });
5002
+ //#endregion
4068
5003
  //#region src/components/tooltip/JTooltip.vue?vue&type=script&setup=true&lang.ts
4069
5004
  var warmUntil = 0;
4070
5005
  var WARM_WINDOW = 400;
@@ -4173,16 +5108,35 @@ var JTooltip_default = /* @__PURE__ */ defineComponent({
4173
5108
  }
4174
5109
  });
4175
5110
  //#endregion
5111
+ //#region src/components/visually-hidden/JVisuallyHidden.vue
5112
+ var JVisuallyHidden_default = /* @__PURE__ */ defineComponent({
5113
+ __name: "JVisuallyHidden",
5114
+ props: { as: { default: "span" } },
5115
+ setup(__props) {
5116
+ return (_ctx, _cache) => {
5117
+ return openBlock(), createBlock(resolveDynamicComponent(__props.as), { class: "j-visually-hidden j-sr-only" }, {
5118
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
5119
+ _: 3
5120
+ });
5121
+ };
5122
+ }
5123
+ });
5124
+ //#endregion
4176
5125
  //#region src/components.ts
4177
5126
  var components_exports = /* @__PURE__ */ __exportAll({
4178
5127
  JAccordion: () => JAccordion_default,
4179
5128
  JAccordionItem: () => JAccordionItem_default,
4180
5129
  JAlert: () => JAlert_default,
5130
+ JAspectRatio: () => JAspectRatio_default,
4181
5131
  JAvatar: () => JAvatar_default,
5132
+ JAvatarGroup: () => JAvatarGroup_default,
4182
5133
  JBadge: () => JBadge_default,
5134
+ JBanner: () => JBanner_default,
5135
+ JBreadcrumb: () => JBreadcrumb_default,
4183
5136
  JButton: () => JButton_default,
4184
5137
  JCard: () => JCard_default,
4185
5138
  JCheckbox: () => JCheckbox_default,
5139
+ JCollapsible: () => JCollapsible_default,
4186
5140
  JCommandPalette: () => JCommandPalette_default,
4187
5141
  JDialog: () => JDialog_default,
4188
5142
  JDropdownMenu: () => JDropdownMenu_default,
@@ -4190,22 +5144,33 @@ var components_exports = /* @__PURE__ */ __exportAll({
4190
5144
  JDropdownMenuLabel: () => JDropdownMenuLabel_default,
4191
5145
  JDropdownMenuSeparator: () => JDropdownMenuSeparator_default,
4192
5146
  JDropdownMenuSub: () => JDropdownMenuSub_default,
5147
+ JEmptyState: () => JEmptyState_default,
4193
5148
  JInput: () => JInput_default,
4194
5149
  JKbd: () => JKbd_default,
5150
+ JPagination: () => JPagination_default,
4195
5151
  JPopover: () => JPopover_default,
4196
5152
  JProgress: () => JProgress_default,
4197
5153
  JRadio: () => JRadio_default,
4198
5154
  JRadioGroup: () => JRadioGroup_default,
5155
+ JRating: () => JRating_default,
4199
5156
  JSelect: () => JSelect_default,
4200
5157
  JSeparator: () => JSeparator_default,
4201
5158
  JSheet: () => JSheet_default,
4202
5159
  JSkeleton: () => JSkeleton_default,
5160
+ JSlider: () => JSlider_default,
4203
5161
  JSpinner: () => JSpinner_default,
5162
+ JStat: () => JStat_default,
4204
5163
  JSwitch: () => JSwitch_default,
4205
5164
  JTabs: () => JTabs_default,
5165
+ JTag: () => JTag_default,
4206
5166
  JTextarea: () => JTextarea_default,
5167
+ JTimeline: () => JTimeline_default,
5168
+ JTimelineItem: () => JTimelineItem_default,
4207
5169
  JToaster: () => JToaster_default,
4208
- JTooltip: () => JTooltip_default
5170
+ JToggleGroup: () => JToggleGroup_default,
5171
+ JToggleGroupItem: () => JToggleGroupItem_default,
5172
+ JTooltip: () => JTooltip_default,
5173
+ JVisuallyHidden: () => JVisuallyHidden_default
4209
5174
  });
4210
5175
  //#endregion
4211
5176
  //#region src/composables/useRecentCommands.ts
@@ -4265,6 +5230,6 @@ var JuxtUI = { install(app) {
4265
5230
  for (const [name, component] of Object.entries(components_exports)) app.component(name, component);
4266
5231
  } };
4267
5232
  //#endregion
4268
- export { JAccordion_default as JAccordion, JAccordionItem_default as JAccordionItem, JAlert_default as JAlert, JAvatar_default as JAvatar, JBadge_default as JBadge, JButton_default as JButton, JCard_default as JCard, JCheckbox_default as JCheckbox, JCommandPalette_default as JCommandPalette, JDialog_default as JDialog, JDropdownMenu_default as JDropdownMenu, JDropdownMenuItem_default as JDropdownMenuItem, JDropdownMenuLabel_default as JDropdownMenuLabel, JDropdownMenuSeparator_default as JDropdownMenuSeparator, JDropdownMenuSub_default as JDropdownMenuSub, JInput_default as JInput, JKbd_default as JKbd, JPopover_default as JPopover, JProgress_default as JProgress, JRadio_default as JRadio, JRadioGroup_default as JRadioGroup, JSelect_default as JSelect, JSeparator_default as JSeparator, JSheet_default as JSheet, JSkeleton_default as JSkeleton, JSpinner_default as JSpinner, JSwitch_default as JSwitch, JTabs_default as JTabs, JTextarea_default as JTextarea, JToaster_default as JToaster, JTooltip_default as JTooltip, JuxtUI, JuxtUI as default, formatHotkey, matchText, matchesHotkey, toast, useFocusTrap, useHotkey, useRecentCommands, useScrollLock, useToast };
5233
+ export { JAccordion_default as JAccordion, JAccordionItem_default as JAccordionItem, JAlert_default as JAlert, JAspectRatio_default as JAspectRatio, JAvatar_default as JAvatar, JAvatarGroup_default as JAvatarGroup, JBadge_default as JBadge, JBanner_default as JBanner, JBreadcrumb_default as JBreadcrumb, JButton_default as JButton, JCard_default as JCard, JCheckbox_default as JCheckbox, JCollapsible_default as JCollapsible, JCommandPalette_default as JCommandPalette, JDialog_default as JDialog, JDropdownMenu_default as JDropdownMenu, JDropdownMenuItem_default as JDropdownMenuItem, JDropdownMenuLabel_default as JDropdownMenuLabel, JDropdownMenuSeparator_default as JDropdownMenuSeparator, JDropdownMenuSub_default as JDropdownMenuSub, JEmptyState_default as JEmptyState, JInput_default as JInput, JKbd_default as JKbd, JPagination_default as JPagination, JPopover_default as JPopover, JProgress_default as JProgress, JRadio_default as JRadio, JRadioGroup_default as JRadioGroup, JRating_default as JRating, JSelect_default as JSelect, JSeparator_default as JSeparator, JSheet_default as JSheet, JSkeleton_default as JSkeleton, JSlider_default as JSlider, JSpinner_default as JSpinner, JStat_default as JStat, JSwitch_default as JSwitch, JTabs_default as JTabs, JTag_default as JTag, JTextarea_default as JTextarea, JTimeline_default as JTimeline, JTimelineItem_default as JTimelineItem, JToaster_default as JToaster, JToggleGroup_default as JToggleGroup, JToggleGroupItem_default as JToggleGroupItem, JTooltip_default as JTooltip, JVisuallyHidden_default as JVisuallyHidden, JuxtUI, JuxtUI as default, formatHotkey, matchText, matchesHotkey, toast, useFocusTrap, useHotkey, useRecentCommands, useScrollLock, useToast };
4269
5234
 
4270
5235
  //# sourceMappingURL=index.js.map