@juxtui/ui 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -12,119 +12,122 @@ var __exportAll = (all, no_symbols) => {
12
12
  return target;
13
13
  };
14
14
  //#endregion
15
- //#region src/components/avatar/JAvatar.vue?vue&type=script&setup=true&lang.ts
16
- var _hoisted_1$19 = [
17
- "role",
18
- "aria-label",
19
- "data-state"
20
- ];
21
- var _hoisted_2$14 = { class: "j-avatar__frame" };
22
- var _hoisted_3$13 = ["src"];
23
- var _hoisted_4$9 = {
24
- key: 1,
25
- class: "j-avatar__fallback",
26
- "aria-hidden": "true"
27
- };
28
- var _hoisted_5$7 = {
29
- key: 1,
30
- viewBox: "0 0 16 16",
31
- fill: "currentColor",
32
- class: "j-avatar__glyph"
33
- };
34
- //#endregion
35
- //#region src/components/avatar/JAvatar.vue
36
- var JAvatar_default = /* @__PURE__ */ defineComponent({
37
- __name: "JAvatar",
38
- props: {
39
- src: {},
40
- alt: {},
41
- name: {},
42
- size: { default: "md" },
43
- shape: { default: "circle" },
44
- status: {}
45
- },
46
- setup(__props) {
47
- const props = __props;
48
- const state = ref(props.src ? "loading" : "error");
49
- const img = ref(null);
50
- watch(() => props.src, (src) => {
51
- state.value = src ? "loading" : "error";
52
- });
53
- onMounted(() => {
54
- if (img.value?.complete && img.value.naturalWidth > 0) state.value = "loaded";
55
- });
56
- const initials = computed(() => {
57
- const parts = (props.name ?? "").trim().split(/\s+/).filter(Boolean);
58
- if (parts.length === 0) return "";
59
- const first = parts[0];
60
- const last = parts.length > 1 ? parts[parts.length - 1] : "";
61
- return (first[0] + (last[0] ?? "")).toUpperCase();
62
- });
63
- const statusLabel = {
64
- online: "Online",
65
- away: "Away",
66
- busy: "Busy",
67
- offline: "Offline"
68
- };
69
- const label = computed(() => {
70
- const who = props.alt ?? props.name;
71
- if (!who) return void 0;
72
- return props.status ? `${who} (${statusLabel[props.status]})` : who;
73
- });
74
- return (_ctx, _cache) => {
75
- return openBlock(), createElementBlock("span", {
76
- class: normalizeClass(["j-avatar", [`j-avatar--${__props.size}`, `j-avatar--${__props.shape}`]]),
77
- role: label.value ? "img" : void 0,
78
- "aria-label": label.value,
79
- "data-state": state.value
80
- }, [createElementVNode("span", _hoisted_2$14, [__props.src && state.value !== "error" ? (openBlock(), createElementBlock("img", {
81
- key: 0,
82
- ref_key: "img",
83
- ref: img,
84
- class: "j-avatar__image",
85
- src: __props.src,
86
- alt: "",
87
- onLoad: _cache[0] || (_cache[0] = ($event) => state.value = "loaded"),
88
- onError: _cache[1] || (_cache[1] = ($event) => state.value = "error")
89
- }, null, 40, _hoisted_3$13)) : createCommentVNode("", true), state.value !== "loaded" ? (openBlock(), createElementBlock("span", _hoisted_4$9, [renderSlot(_ctx.$slots, "fallback", {}, () => [initials.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(initials.value), 1)], 64)) : (openBlock(), createElementBlock("svg", _hoisted_5$7, [..._cache[2] || (_cache[2] = [createElementVNode("circle", {
90
- cx: "8",
91
- cy: "6",
92
- r: "2.75"
93
- }, null, -1), createElementVNode("path", { d: "M2.75 14c.6-2.6 2.7-4.25 5.25-4.25S12.65 11.4 13.25 14z" }, null, -1)])]))])])) : createCommentVNode("", true)]), __props.status ? (openBlock(), createElementBlock("span", {
94
- key: 0,
95
- class: normalizeClass(["j-avatar__status", `j-avatar__status--${__props.status}`]),
96
- "aria-hidden": "true"
97
- }, null, 2)) : createCommentVNode("", true)], 10, _hoisted_1$19);
98
- };
15
+ //#region src/utils/dom.ts
16
+ var isClient = typeof window !== "undefined" && typeof document !== "undefined";
17
+ /** Resolve a template ref that may point at an element or a component instance. */
18
+ function unrefElement(target) {
19
+ const value = unref(target);
20
+ if (!value) return null;
21
+ if (value instanceof Element) return value;
22
+ const el = value.$el;
23
+ if (el && el.nodeType !== Node.ELEMENT_NODE) {
24
+ const next = el.nextSibling;
25
+ return next instanceof HTMLElement ? next : null;
99
26
  }
100
- });
27
+ return el ?? null;
28
+ }
29
+ var FOCUSABLE = [
30
+ "a[href]",
31
+ "area[href]",
32
+ "button:not([disabled])",
33
+ "input:not([disabled]):not([type=\"hidden\"])",
34
+ "select:not([disabled])",
35
+ "textarea:not([disabled])",
36
+ "iframe",
37
+ "audio[controls]",
38
+ "video[controls]",
39
+ "[contenteditable]:not([contenteditable=\"false\"])",
40
+ "[tabindex]"
41
+ ].join(",");
42
+ function isVisible(el) {
43
+ if (el.hidden) return false;
44
+ if (typeof el.checkVisibility === "function") return el.checkVisibility({ visibilityProperty: true });
45
+ for (let node = el; node; node = node.parentElement) {
46
+ const style = getComputedStyle(node);
47
+ if (style.display === "none" || style.visibility === "hidden") return false;
48
+ }
49
+ return true;
50
+ }
51
+ /** Elements that can receive keyboard focus, in DOM order. */
52
+ function getFocusableElements(container) {
53
+ return Array.from(container.querySelectorAll(FOCUSABLE)).filter((el) => el.tabIndex >= 0 && !el.closest("[inert]") && isVisible(el));
54
+ }
55
+ function focusElement(el, options) {
56
+ if (!el) return;
57
+ el.focus({
58
+ preventScroll: true,
59
+ ...options
60
+ });
61
+ }
62
+ var isMac = () => isClient && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);
63
+ function prefersReducedMotion() {
64
+ return isClient && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
65
+ }
101
66
  //#endregion
102
- //#region src/components/badge/JBadge.vue?vue&type=script&setup=true&lang.ts
103
- var _hoisted_1$18 = {
104
- key: 0,
105
- class: "j-badge__marker",
106
- "aria-hidden": "true"
107
- };
108
- var _hoisted_2$13 = {
109
- key: 1,
110
- class: "j-badge__icon"
111
- };
67
+ //#region src/components/accordion/context.ts
68
+ var ACCORDION = Symbol("JAccordion");
112
69
  //#endregion
113
- //#region src/components/badge/JBadge.vue
114
- var JBadge_default = /* @__PURE__ */ defineComponent({
115
- __name: "JBadge",
116
- props: {
117
- variant: { default: "neutral" },
118
- size: { default: "md" },
119
- dot: { type: Boolean }
120
- },
70
+ //#region src/components/accordion/JAccordion.vue
71
+ var JAccordion_default = /* @__PURE__ */ defineComponent({
72
+ __name: "JAccordion",
73
+ props: /*@__PURE__*/ mergeModels({
74
+ type: { default: "single" },
75
+ collapsible: {
76
+ type: Boolean,
77
+ default: true
78
+ },
79
+ headingLevel: { default: 3 }
80
+ }, {
81
+ "modelValue": { default: null },
82
+ "modelModifiers": {}
83
+ }),
84
+ emits: ["update:modelValue"],
121
85
  setup(__props) {
86
+ const props = __props;
87
+ /** Open item(s): a value in `single` mode, an array in `multiple` mode. */
88
+ const model = useModel(__props, "modelValue");
89
+ function openValues() {
90
+ const value = model.value;
91
+ if (Array.isArray(value)) return value;
92
+ return value ? [value] : [];
93
+ }
94
+ provide(ACCORDION, {
95
+ isOpen: (value) => openValues().includes(value),
96
+ toggle: (value) => {
97
+ const current = openValues();
98
+ const isOpen = current.includes(value);
99
+ if (props.type === "multiple") {
100
+ model.value = isOpen ? current.filter((v) => v !== value) : [...current, value];
101
+ return;
102
+ }
103
+ if (isOpen) {
104
+ if (props.collapsible) model.value = null;
105
+ return;
106
+ }
107
+ model.value = value;
108
+ },
109
+ headingLevel: () => props.headingLevel
110
+ });
111
+ function onKeydown(event) {
112
+ const target = event.target;
113
+ if (!target.classList.contains("j-accordion__trigger")) return;
114
+ const root = event.currentTarget;
115
+ const triggers = Array.from(root.querySelectorAll(".j-accordion__trigger:not(:disabled)")).filter((el) => el.closest(".j-accordion") === root);
116
+ const index = triggers.indexOf(target);
117
+ let next;
118
+ if (event.key === "ArrowDown") next = triggers[(index + 1) % triggers.length];
119
+ else if (event.key === "ArrowUp") next = triggers[(index - 1 + triggers.length) % triggers.length];
120
+ else if (event.key === "Home") next = triggers[0];
121
+ else if (event.key === "End") next = triggers[triggers.length - 1];
122
+ if (!next) return;
123
+ event.preventDefault();
124
+ focusElement(next);
125
+ }
122
126
  return (_ctx, _cache) => {
123
- return openBlock(), createElementBlock("span", { class: normalizeClass(["j-badge", [
124
- `j-badge--${__props.variant}`,
125
- `j-badge--${__props.size}`,
126
- { "j-badge--status": __props.dot }
127
- ]]) }, [__props.dot ? (openBlock(), createElementBlock("span", _hoisted_1$18)) : _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$13, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true), renderSlot(_ctx.$slots, "default")], 2);
127
+ return openBlock(), createElementBlock("div", {
128
+ class: "j-accordion",
129
+ onKeydown
130
+ }, [renderSlot(_ctx.$slots, "default")], 32);
128
131
  };
129
132
  }
130
133
  });
@@ -149,7 +152,7 @@ function icon(name, children, viewBox = "0 0 16 16") {
149
152
  return component;
150
153
  }
151
154
  var IconCheck = icon("IconCheck", () => [h("path", { d: "M3.5 8.5l3 3 6-7" })]);
152
- icon("IconChevronDown", () => [h("path", { d: "M4.5 6.25L8 9.75l3.5-3.5" })]);
155
+ var IconChevronDown = icon("IconChevronDown", () => [h("path", { d: "M4.5 6.25L8 9.75l3.5-3.5" })]);
153
156
  var IconChevronUpDown = icon("IconChevronUpDown", () => [h("path", { d: "M5.25 6L8 3.25 10.75 6M5.25 10L8 12.75 10.75 10" })]);
154
157
  var IconChevronRight = icon("IconChevronRight", () => [h("path", { d: "M6.25 4.5L9.75 8l-3.5 3.5" })]);
155
158
  var IconX = icon("IconX", () => [h("path", { d: "M4.5 4.5l7 7M11.5 4.5l-7 7" })]);
@@ -216,105 +219,332 @@ var Spinner = (props) => {
216
219
  };
217
220
  Spinner.displayName = "JSpinner";
218
221
  //#endregion
219
- //#region src/components/button/JButton.vue?vue&type=script&setup=true&lang.ts
220
- var _hoisted_1$17 = { class: "j-button__content" };
221
- var _hoisted_2$12 = {
222
- key: 0,
223
- class: "j-button__icon"
224
- };
225
- var _hoisted_3$12 = {
226
- key: 1,
227
- class: "j-button__icon"
228
- };
229
- var _hoisted_4$8 = {
230
- key: 0,
231
- class: "j-button__spinner"
232
- };
222
+ //#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" };
233
229
  //#endregion
234
- //#region src/components/button/JButton.vue
235
- var JButton_default = /* @__PURE__ */ defineComponent({
236
- __name: "JButton",
230
+ //#region src/components/accordion/JAccordionItem.vue
231
+ var JAccordionItem_default = /* @__PURE__ */ defineComponent({
232
+ __name: "JAccordionItem",
237
233
  props: {
238
- variant: { default: "primary" },
239
- size: { default: "md" },
240
- loading: { type: Boolean },
241
- disabled: { type: Boolean },
242
- icon: { type: Boolean },
243
- block: { type: Boolean },
244
- as: { default: "button" },
245
- type: { default: "button" }
234
+ value: {},
235
+ title: {},
236
+ disabled: { type: Boolean }
246
237
  },
247
238
  setup(__props) {
248
239
  const props = __props;
249
- const isNativeButton = computed(() => props.as === "button");
250
- const inert = computed(() => props.disabled || props.loading);
251
- const attrs = computed(() => {
252
- if (isNativeButton.value) return {
253
- type: props.type,
254
- "disabled": props.disabled || void 0,
255
- "aria-disabled": props.loading || void 0
256
- };
257
- return {
258
- "aria-disabled": inert.value || void 0,
259
- "tabindex": props.disabled ? -1 : void 0
260
- };
261
- });
262
- function onClick(event) {
263
- if (inert.value) {
264
- event.preventDefault();
265
- event.stopImmediatePropagation();
266
- }
267
- }
240
+ const accordion = inject(ACCORDION);
241
+ const id = `j-${useId()}`;
242
+ const triggerId = `${id}-trigger`;
243
+ const panelId = `${id}-panel`;
244
+ const open = computed(() => accordion.isOpen(props.value));
245
+ const heading = computed(() => `h${accordion.headingLevel()}`);
268
246
  return (_ctx, _cache) => {
269
- return openBlock(), createBlock(resolveDynamicComponent(__props.as), mergeProps(attrs.value, {
270
- class: ["j-button j-focusable", [
271
- `j-button--${__props.variant}`,
272
- `j-button--${__props.size}`,
273
- {
274
- "j-button--icon": __props.icon,
275
- "j-button--block": __props.block,
276
- "is-loading": __props.loading
277
- }
278
- ]],
279
- "aria-busy": __props.loading || void 0,
280
- "data-disabled": __props.disabled || void 0,
281
- onClickCapture: onClick
282
- }), {
283
- default: withCtx(() => [createElementVNode("span", _hoisted_1$17, [
284
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$12, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
285
- renderSlot(_ctx.$slots, "default"),
286
- _ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_3$12, [renderSlot(_ctx.$slots, "trailing")])) : createCommentVNode("", true)
287
- ]), createVNode(Transition, { name: "j-button-spinner" }, {
288
- default: withCtx(() => [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_4$8, [createVNode(unref(Spinner), { size: __props.size === "xs" ? 12 : __props.size === "lg" ? 16 : 14 }, null, 8, ["size"])])) : createCommentVNode("", true)]),
289
- _: 1
290
- })]),
247
+ return openBlock(), createElementBlock("div", {
248
+ class: normalizeClass(["j-accordion__item", { "is-disabled": __props.disabled }]),
249
+ "data-state": open.value ? "open" : "closed"
250
+ }, [(openBlock(), createBlock(resolveDynamicComponent(heading.value), { class: "j-accordion__heading" }, {
251
+ default: withCtx(() => [createElementVNode("button", {
252
+ id: triggerId,
253
+ type: "button",
254
+ class: "j-accordion__trigger",
255
+ "aria-expanded": open.value,
256
+ "aria-controls": panelId,
257
+ disabled: __props.disabled,
258
+ 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)]),
291
260
  _: 3
292
- }, 16, [
293
- "class",
294
- "aria-busy",
295
- "data-disabled"
296
- ]);
261
+ })), createElementVNode("div", {
262
+ id: panelId,
263
+ role: "region",
264
+ class: "j-accordion__panel",
265
+ "aria-labelledby": triggerId,
266
+ 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);
297
268
  };
298
269
  }
299
270
  });
300
271
  //#endregion
301
- //#region src/components/card/JCard.vue?vue&type=script&setup=true&lang.ts
302
- var _hoisted_1$16 = {
272
+ //#region src/components/alert/JAlert.vue?vue&type=script&setup=true&lang.ts
273
+ var _hoisted_1$27 = {
303
274
  key: 0,
304
- class: "j-card__header"
275
+ class: "j-alert__icon",
276
+ "aria-hidden": "true"
305
277
  };
306
- var _hoisted_2$11 = { class: "j-card__heading" };
307
- var _hoisted_3$11 = {
278
+ var _hoisted_2$21 = { class: "j-alert__body" };
279
+ var _hoisted_3$18 = {
308
280
  key: 0,
309
- class: "j-card__title"
281
+ class: "j-alert__title"
310
282
  };
311
- var _hoisted_4$7 = {
283
+ var _hoisted_4$13 = {
312
284
  key: 1,
313
- class: "j-card__description"
285
+ class: "j-alert__description"
314
286
  };
315
- var _hoisted_5$6 = {
316
- key: 0,
317
- class: "j-card__actions"
287
+ var _hoisted_5$9 = {
288
+ key: 2,
289
+ class: "j-alert__actions"
290
+ };
291
+ //#endregion
292
+ //#region src/components/alert/JAlert.vue
293
+ var JAlert_default = /* @__PURE__ */ defineComponent({
294
+ __name: "JAlert",
295
+ props: {
296
+ variant: { default: "neutral" },
297
+ title: {},
298
+ description: {},
299
+ dismissible: { type: Boolean },
300
+ hideIcon: { type: Boolean }
301
+ },
302
+ emits: ["dismiss"],
303
+ setup(__props, { emit: __emit }) {
304
+ const emit = __emit;
305
+ const icons = {
306
+ neutral: IconInfo,
307
+ info: IconInfo,
308
+ success: IconCircleCheck,
309
+ warning: IconAlert,
310
+ destructive: IconCircleX
311
+ };
312
+ return (_ctx, _cache) => {
313
+ 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)
319
+ ]),
320
+ __props.dismissible ? (openBlock(), createElementBlock("button", {
321
+ key: 1,
322
+ type: "button",
323
+ class: "j-alert__close j-focusable",
324
+ "aria-label": "Dismiss",
325
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("dismiss"))
326
+ }, [createVNode(unref(IconX))])) : createCommentVNode("", true)
327
+ ], 2);
328
+ };
329
+ }
330
+ });
331
+ //#endregion
332
+ //#region src/components/avatar/JAvatar.vue?vue&type=script&setup=true&lang.ts
333
+ var _hoisted_1$26 = [
334
+ "role",
335
+ "aria-label",
336
+ "data-state"
337
+ ];
338
+ var _hoisted_2$20 = { class: "j-avatar__frame" };
339
+ var _hoisted_3$17 = ["src"];
340
+ var _hoisted_4$12 = {
341
+ key: 1,
342
+ class: "j-avatar__fallback",
343
+ "aria-hidden": "true"
344
+ };
345
+ var _hoisted_5$8 = {
346
+ key: 1,
347
+ viewBox: "0 0 16 16",
348
+ fill: "currentColor",
349
+ class: "j-avatar__glyph"
350
+ };
351
+ //#endregion
352
+ //#region src/components/avatar/JAvatar.vue
353
+ var JAvatar_default = /* @__PURE__ */ defineComponent({
354
+ __name: "JAvatar",
355
+ props: {
356
+ src: {},
357
+ alt: {},
358
+ name: {},
359
+ size: { default: "md" },
360
+ shape: { default: "circle" },
361
+ status: {}
362
+ },
363
+ setup(__props) {
364
+ const props = __props;
365
+ const state = ref(props.src ? "loading" : "error");
366
+ const img = ref(null);
367
+ watch(() => props.src, (src) => {
368
+ state.value = src ? "loading" : "error";
369
+ });
370
+ onMounted(() => {
371
+ if (img.value?.complete && img.value.naturalWidth > 0) state.value = "loaded";
372
+ });
373
+ const initials = computed(() => {
374
+ const parts = (props.name ?? "").trim().split(/\s+/).filter(Boolean);
375
+ if (parts.length === 0) return "";
376
+ const first = parts[0];
377
+ const last = parts.length > 1 ? parts[parts.length - 1] : "";
378
+ return (first[0] + (last[0] ?? "")).toUpperCase();
379
+ });
380
+ const statusLabel = {
381
+ online: "Online",
382
+ away: "Away",
383
+ busy: "Busy",
384
+ offline: "Offline"
385
+ };
386
+ const label = computed(() => {
387
+ const who = props.alt ?? props.name;
388
+ if (!who) return void 0;
389
+ return props.status ? `${who} (${statusLabel[props.status]})` : who;
390
+ });
391
+ return (_ctx, _cache) => {
392
+ return openBlock(), createElementBlock("span", {
393
+ class: normalizeClass(["j-avatar", [`j-avatar--${__props.size}`, `j-avatar--${__props.shape}`]]),
394
+ role: label.value ? "img" : void 0,
395
+ "aria-label": label.value,
396
+ "data-state": state.value
397
+ }, [createElementVNode("span", _hoisted_2$20, [__props.src && state.value !== "error" ? (openBlock(), createElementBlock("img", {
398
+ key: 0,
399
+ ref_key: "img",
400
+ ref: img,
401
+ class: "j-avatar__image",
402
+ src: __props.src,
403
+ alt: "",
404
+ onLoad: _cache[0] || (_cache[0] = ($event) => state.value = "loaded"),
405
+ 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", {
407
+ cx: "8",
408
+ cy: "6",
409
+ r: "2.75"
410
+ }, null, -1), createElementVNode("path", { d: "M2.75 14c.6-2.6 2.7-4.25 5.25-4.25S12.65 11.4 13.25 14z" }, null, -1)])]))])])) : createCommentVNode("", true)]), __props.status ? (openBlock(), createElementBlock("span", {
411
+ key: 0,
412
+ class: normalizeClass(["j-avatar__status", `j-avatar__status--${__props.status}`]),
413
+ "aria-hidden": "true"
414
+ }, null, 2)) : createCommentVNode("", true)], 10, _hoisted_1$26);
415
+ };
416
+ }
417
+ });
418
+ //#endregion
419
+ //#region src/components/badge/JBadge.vue?vue&type=script&setup=true&lang.ts
420
+ var _hoisted_1$25 = {
421
+ key: 0,
422
+ class: "j-badge__marker",
423
+ "aria-hidden": "true"
424
+ };
425
+ var _hoisted_2$19 = {
426
+ key: 1,
427
+ class: "j-badge__icon"
428
+ };
429
+ //#endregion
430
+ //#region src/components/badge/JBadge.vue
431
+ var JBadge_default = /* @__PURE__ */ defineComponent({
432
+ __name: "JBadge",
433
+ props: {
434
+ variant: { default: "neutral" },
435
+ size: { default: "md" },
436
+ dot: { type: Boolean }
437
+ },
438
+ setup(__props) {
439
+ return (_ctx, _cache) => {
440
+ return openBlock(), createElementBlock("span", { class: normalizeClass(["j-badge", [
441
+ `j-badge--${__props.variant}`,
442
+ `j-badge--${__props.size}`,
443
+ { "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);
445
+ };
446
+ }
447
+ });
448
+ //#endregion
449
+ //#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 = {
452
+ key: 0,
453
+ class: "j-button__icon"
454
+ };
455
+ var _hoisted_3$16 = {
456
+ key: 1,
457
+ class: "j-button__icon"
458
+ };
459
+ var _hoisted_4$11 = {
460
+ key: 0,
461
+ class: "j-button__spinner"
462
+ };
463
+ //#endregion
464
+ //#region src/components/button/JButton.vue
465
+ var JButton_default = /* @__PURE__ */ defineComponent({
466
+ __name: "JButton",
467
+ props: {
468
+ variant: { default: "primary" },
469
+ size: { default: "md" },
470
+ loading: { type: Boolean },
471
+ disabled: { type: Boolean },
472
+ icon: { type: Boolean },
473
+ block: { type: Boolean },
474
+ as: { default: "button" },
475
+ type: { default: "button" }
476
+ },
477
+ setup(__props) {
478
+ const props = __props;
479
+ const isNativeButton = computed(() => props.as === "button");
480
+ const inert = computed(() => props.disabled || props.loading);
481
+ const attrs = computed(() => {
482
+ if (isNativeButton.value) return {
483
+ type: props.type,
484
+ "disabled": props.disabled || void 0,
485
+ "aria-disabled": props.loading || void 0
486
+ };
487
+ return {
488
+ "aria-disabled": inert.value || void 0,
489
+ "tabindex": props.disabled ? -1 : void 0
490
+ };
491
+ });
492
+ function onClick(event) {
493
+ if (inert.value) {
494
+ event.preventDefault();
495
+ event.stopImmediatePropagation();
496
+ }
497
+ }
498
+ return (_ctx, _cache) => {
499
+ return openBlock(), createBlock(resolveDynamicComponent(__props.as), mergeProps(attrs.value, {
500
+ class: ["j-button j-focusable", [
501
+ `j-button--${__props.variant}`,
502
+ `j-button--${__props.size}`,
503
+ {
504
+ "j-button--icon": __props.icon,
505
+ "j-button--block": __props.block,
506
+ "is-loading": __props.loading
507
+ }
508
+ ]],
509
+ "aria-busy": __props.loading || void 0,
510
+ "data-disabled": __props.disabled || void 0,
511
+ onClickCapture: onClick
512
+ }), {
513
+ default: withCtx(() => [createElementVNode("span", _hoisted_1$24, [
514
+ _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$18, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
515
+ renderSlot(_ctx.$slots, "default"),
516
+ _ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_3$16, [renderSlot(_ctx.$slots, "trailing")])) : createCommentVNode("", true)
517
+ ]), 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)]),
519
+ _: 1
520
+ })]),
521
+ _: 3
522
+ }, 16, [
523
+ "class",
524
+ "aria-busy",
525
+ "data-disabled"
526
+ ]);
527
+ };
528
+ }
529
+ });
530
+ //#endregion
531
+ //#region src/components/card/JCard.vue?vue&type=script&setup=true&lang.ts
532
+ var _hoisted_1$23 = {
533
+ key: 0,
534
+ class: "j-card__header"
535
+ };
536
+ var _hoisted_2$17 = { class: "j-card__heading" };
537
+ var _hoisted_3$15 = {
538
+ key: 0,
539
+ class: "j-card__title"
540
+ };
541
+ var _hoisted_4$10 = {
542
+ key: 1,
543
+ class: "j-card__description"
544
+ };
545
+ var _hoisted_5$7 = {
546
+ key: 0,
547
+ class: "j-card__actions"
318
548
  };
319
549
  var _hoisted_6$5 = {
320
550
  key: 1,
@@ -339,7 +569,7 @@ var JCard_default = /* @__PURE__ */ defineComponent({
339
569
  return (_ctx, _cache) => {
340
570
  return openBlock(), createBlock(resolveDynamicComponent(__props.as), { class: normalizeClass(["j-card", [`j-card--${__props.variant}`, `j-card--p-${__props.padding}`]]) }, {
341
571
  default: withCtx(() => [
342
- __props.title || __props.description || _ctx.$slots.header || _ctx.$slots.actions ? (openBlock(), createElementBlock("header", _hoisted_1$16, [renderSlot(_ctx.$slots, "header", {}, () => [createElementVNode("div", _hoisted_2$11, [__props.title ? (openBlock(), createElementBlock("h3", _hoisted_3$11, toDisplayString(__props.title), 1)) : createCommentVNode("", true), __props.description ? (openBlock(), createElementBlock("p", _hoisted_4$7, toDisplayString(__props.description), 1)) : createCommentVNode("", true)])]), _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_5$6, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true)])) : createCommentVNode("", true),
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),
343
573
  _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_6$5, [renderSlot(_ctx.$slots, "default")])) : createCommentVNode("", true),
344
574
  _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_7$2, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)
345
575
  ]),
@@ -350,9 +580,9 @@ var JCard_default = /* @__PURE__ */ defineComponent({
350
580
  });
351
581
  //#endregion
352
582
  //#region src/components/checkbox/JCheckbox.vue?vue&type=script&setup=true&lang.ts
353
- var _hoisted_1$15 = ["data-state"];
354
- var _hoisted_2$10 = { class: "j-checkbox__control" };
355
- var _hoisted_3$10 = [
583
+ var _hoisted_1$22 = ["data-state"];
584
+ var _hoisted_2$16 = { class: "j-checkbox__control" };
585
+ var _hoisted_3$14 = [
356
586
  "id",
357
587
  "checked",
358
588
  "disabled",
@@ -361,11 +591,11 @@ var _hoisted_3$10 = [
361
591
  "value",
362
592
  "aria-describedby"
363
593
  ];
364
- var _hoisted_4$6 = {
594
+ var _hoisted_4$9 = {
365
595
  key: 0,
366
596
  class: "j-checkbox__text"
367
597
  };
368
- var _hoisted_5$5 = ["for"];
598
+ var _hoisted_5$6 = ["for"];
369
599
  var _hoisted_6$4 = ["id"];
370
600
  //#endregion
371
601
  //#region src/components/checkbox/JCheckbox.vue
@@ -412,7 +642,7 @@ var JCheckbox_default = /* @__PURE__ */ defineComponent({
412
642
  class: normalizeClass(["j-checkbox", [_ctx.$attrs.class, { "is-disabled": __props.disabled }]]),
413
643
  style: normalizeStyle(_ctx.$attrs.style),
414
644
  "data-state": state.value
415
- }, [createElementVNode("span", _hoisted_2$10, [createElementVNode("input", mergeProps({
645
+ }, [createElementVNode("span", _hoisted_2$16, [createElementVNode("input", mergeProps({
416
646
  id: id.value,
417
647
  ref_key: "input",
418
648
  ref: input
@@ -430,97 +660,45 @@ var JCheckbox_default = /* @__PURE__ */ defineComponent({
430
660
  value: __props.value,
431
661
  "aria-describedby": __props.description || _ctx.$slots.description ? descriptionId.value : void 0,
432
662
  onChange
433
- }), null, 16, _hoisted_3$10), _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$6, [__props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("label", {
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", {
434
664
  key: 0,
435
665
  for: id.value,
436
666
  class: "j-checkbox__label"
437
- }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])], 8, _hoisted_5$5)) : createCommentVNode("", true), __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", {
667
+ }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])], 8, _hoisted_5$6)) : createCommentVNode("", true), __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", {
438
668
  key: 1,
439
669
  id: descriptionId.value,
440
670
  class: "j-checkbox__description"
441
- }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])], 8, _hoisted_6$4)) : createCommentVNode("", true)])) : createCommentVNode("", true)], 14, _hoisted_1$15);
671
+ }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])], 8, _hoisted_6$4)) : createCommentVNode("", true)])) : createCommentVNode("", true)], 14, _hoisted_1$22);
442
672
  };
443
673
  }
444
674
  });
445
675
  //#endregion
446
- //#region src/utils/dom.ts
447
- var isClient = typeof window !== "undefined" && typeof document !== "undefined";
448
- /** Resolve a template ref that may point at an element or a component instance. */
449
- function unrefElement(target) {
450
- const value = unref(target);
451
- if (!value) return null;
452
- if (value instanceof Element) return value;
453
- const el = value.$el;
454
- if (el && el.nodeType !== Node.ELEMENT_NODE) {
455
- const next = el.nextSibling;
456
- return next instanceof HTMLElement ? next : null;
457
- }
458
- return el ?? null;
459
- }
460
- var FOCUSABLE = [
461
- "a[href]",
462
- "area[href]",
463
- "button:not([disabled])",
464
- "input:not([disabled]):not([type=\"hidden\"])",
465
- "select:not([disabled])",
466
- "textarea:not([disabled])",
467
- "iframe",
468
- "audio[controls]",
469
- "video[controls]",
470
- "[contenteditable]:not([contenteditable=\"false\"])",
471
- "[tabindex]"
472
- ].join(",");
473
- function isVisible(el) {
474
- if (el.hidden) return false;
475
- if (typeof el.checkVisibility === "function") return el.checkVisibility({ visibilityProperty: true });
476
- for (let node = el; node; node = node.parentElement) {
477
- const style = getComputedStyle(node);
478
- if (style.display === "none" || style.visibility === "hidden") return false;
479
- }
480
- return true;
481
- }
482
- /** Elements that can receive keyboard focus, in DOM order. */
483
- function getFocusableElements(container) {
484
- return Array.from(container.querySelectorAll(FOCUSABLE)).filter((el) => el.tabIndex >= 0 && !el.closest("[inert]") && isVisible(el));
485
- }
486
- function focusElement(el, options) {
487
- if (!el) return;
488
- el.focus({
489
- preventScroll: true,
490
- ...options
491
- });
492
- }
493
- var isMac = () => isClient && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);
494
- function prefersReducedMotion() {
495
- return isClient && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
496
- }
497
- //#endregion
498
- //#region src/composables/useFocusTrap.ts
499
- var stack = [];
500
- function isTop(trap) {
501
- return stack[stack.length - 1] === trap;
502
- }
503
- var listening$1 = false;
504
- function onKeydown$1(event) {
505
- if (event.key !== "Tab" || event.defaultPrevented) return;
506
- const container = stack[stack.length - 1]?.container.value;
507
- if (!container) return;
508
- const focusable = getFocusableElements(container);
509
- if (focusable.length === 0) {
510
- event.preventDefault();
511
- focusElement(container);
512
- return;
513
- }
514
- const first = focusable[0];
515
- const last = focusable[focusable.length - 1];
516
- const active = document.activeElement;
517
- const inside = active ? container.contains(active) : false;
518
- if (event.shiftKey && (active === first || active === container || !inside)) {
519
- event.preventDefault();
520
- focusElement(last);
521
- } else if (!event.shiftKey && (active === last || !inside)) {
522
- event.preventDefault();
523
- focusElement(first);
676
+ //#region src/composables/useFocusTrap.ts
677
+ var stack = [];
678
+ function isTop(trap) {
679
+ return stack[stack.length - 1] === trap;
680
+ }
681
+ var listening$1 = false;
682
+ function onKeydown$1(event) {
683
+ if (event.key !== "Tab" || event.defaultPrevented) return;
684
+ const container = stack[stack.length - 1]?.container.value;
685
+ if (!container) return;
686
+ const focusable = getFocusableElements(container);
687
+ if (focusable.length === 0) {
688
+ event.preventDefault();
689
+ focusElement(container);
690
+ return;
691
+ }
692
+ const first = focusable[0];
693
+ const last = focusable[focusable.length - 1];
694
+ const active = document.activeElement;
695
+ const inside = active ? container.contains(active) : false;
696
+ if (event.shiftKey && (active === first || active === container || !inside)) {
697
+ event.preventDefault();
698
+ focusElement(last);
699
+ } else if (!event.shiftKey && (active === last || !inside)) {
700
+ event.preventDefault();
701
+ focusElement(first);
524
702
  }
525
703
  }
526
704
  function onFocusIn(event) {
@@ -862,19 +1040,19 @@ var JPortal_default = /* @__PURE__ */ defineComponent({
862
1040
  });
863
1041
  //#endregion
864
1042
  //#region src/components/command-palette/JCommandPalette.vue?vue&type=script&setup=true&lang.ts
865
- var _hoisted_1$14 = {
1043
+ var _hoisted_1$21 = {
866
1044
  key: 0,
867
1045
  class: "j-command__overlay",
868
1046
  "aria-hidden": "true"
869
1047
  };
870
- var _hoisted_2$9 = ["aria-label"];
871
- var _hoisted_3$9 = { class: "j-command__search" };
872
- var _hoisted_4$5 = [
1048
+ var _hoisted_2$15 = ["aria-label"];
1049
+ var _hoisted_3$13 = { class: "j-command__search" };
1050
+ var _hoisted_4$8 = [
873
1051
  "aria-activedescendant",
874
1052
  "aria-label",
875
1053
  "placeholder"
876
1054
  ];
877
- var _hoisted_5$4 = {
1055
+ var _hoisted_5$5 = {
878
1056
  key: 0,
879
1057
  class: "j-command__progress",
880
1058
  "aria-hidden": "true"
@@ -1115,7 +1293,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1115
1293
  return (_ctx, _cache) => {
1116
1294
  return openBlock(), createBlock(JPortal_default, null, {
1117
1295
  default: withCtx(() => [createVNode(Transition, { name: "j-command-overlay" }, {
1118
- default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$14)) : createCommentVNode("", true)]),
1296
+ default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$21)) : createCommentVNode("", true)]),
1119
1297
  _: 1
1120
1298
  }), createVNode(Transition, {
1121
1299
  name: "j-command",
@@ -1137,7 +1315,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1137
1315
  "aria-label": __props.label,
1138
1316
  class: "j-command"
1139
1317
  }, [
1140
- createElementVNode("div", _hoisted_3$9, [
1318
+ createElementVNode("div", _hoisted_3$13, [
1141
1319
  createVNode(unref(IconSearch), { class: "j-command__search-icon" }),
1142
1320
  withDirectives(createElementVNode("input", {
1143
1321
  ref_key: "input",
@@ -1158,7 +1336,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1158
1336
  spellcheck: "false",
1159
1337
  enterkeyhint: "go",
1160
1338
  onKeydown
1161
- }, null, 40, _hoisted_4$5), [[vModelText, search.value]]),
1339
+ }, null, 40, _hoisted_4$8), [[vModelText, search.value]]),
1162
1340
  createElementVNode("button", {
1163
1341
  type: "button",
1164
1342
  class: "j-command__esc j-kbd",
@@ -1166,7 +1344,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1166
1344
  "aria-label": "Close",
1167
1345
  onClick: close
1168
1346
  }, " Esc "),
1169
- __props.loading ? (openBlock(), createElementBlock("span", _hoisted_5$4)) : createCommentVNode("", true)
1347
+ __props.loading ? (openBlock(), createElementBlock("span", _hoisted_5$5)) : createCommentVNode("", true)
1170
1348
  ]),
1171
1349
  createElementVNode("div", {
1172
1350
  id: listboxId,
@@ -1224,7 +1402,7 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1224
1402
  _cache[5] || (_cache[5] = createElementVNode("span", { class: "j-command__hint" }, [createElementVNode("kbd", { class: "j-kbd" }, "Esc"), createTextVNode(" Close")], -1))
1225
1403
  ])]),
1226
1404
  createElementVNode("span", _hoisted_19, toDisplayString(announcement.value), 1)
1227
- ], 8, _hoisted_2$9)], 32)) : createCommentVNode("", true)]),
1405
+ ], 8, _hoisted_2$15)], 32)) : createCommentVNode("", true)]),
1228
1406
  _: 3
1229
1407
  })]),
1230
1408
  _: 3
@@ -1233,26 +1411,66 @@ var JCommandPalette_default = /* @__PURE__ */ defineComponent({
1233
1411
  }
1234
1412
  });
1235
1413
  //#endregion
1414
+ //#region src/composables/useModal.ts
1415
+ /**
1416
+ * Internal: everything a modal surface (Dialog, Sheet) shares — layering,
1417
+ * focus trap and restoration, scroll lock, backdrop clicks and the "nudge"
1418
+ * when dismissal is refused.
1419
+ */
1420
+ function useModal(panel, open, options) {
1421
+ const nudging = ref(false);
1422
+ function nudge() {
1423
+ if (prefersReducedMotion()) return;
1424
+ nudging.value = false;
1425
+ requestAnimationFrame(() => nudging.value = true);
1426
+ }
1427
+ const { isTopLayer } = useLayer({
1428
+ active: open,
1429
+ elements: () => [panel.value],
1430
+ onEscape: () => options.closeOnEscape() ? options.close() : nudge()
1431
+ });
1432
+ useFocusTrap(panel, open, { initialFocus: () => panel.value?.querySelector("[autofocus], [data-autofocus]") ?? (options.focusSelector ? panel.value?.querySelector(options.focusSelector) : null) ?? panel.value });
1433
+ useScrollLock(open);
1434
+ let pressedOutside = false;
1435
+ function onBackdropPointerDown(event) {
1436
+ pressedOutside = event.target === event.currentTarget && isTopLayer();
1437
+ }
1438
+ function onBackdropClick(event) {
1439
+ const outside = pressedOutside && event.target === event.currentTarget;
1440
+ pressedOutside = false;
1441
+ if (!outside) return;
1442
+ if (options.closeOnOverlay()) options.close();
1443
+ else nudge();
1444
+ }
1445
+ return {
1446
+ nudging,
1447
+ onBackdropPointerDown,
1448
+ onBackdropClick
1449
+ };
1450
+ }
1451
+ /** Form fields worth focusing first in a modal body. */
1452
+ var FIELD_SELECTOR = ":is(input:not([type=hidden]), textarea, select, [role=combobox]):not(:disabled)";
1453
+ //#endregion
1236
1454
  //#region src/components/dialog/JDialog.vue?vue&type=script&setup=true&lang.ts
1237
- var _hoisted_1$13 = {
1455
+ var _hoisted_1$20 = {
1238
1456
  key: 0,
1239
1457
  class: "j-dialog__overlay",
1240
1458
  "aria-hidden": "true"
1241
1459
  };
1242
- var _hoisted_2$8 = [
1460
+ var _hoisted_2$14 = [
1243
1461
  "aria-labelledby",
1244
1462
  "aria-label",
1245
1463
  "aria-describedby"
1246
1464
  ];
1247
- var _hoisted_3$8 = {
1465
+ var _hoisted_3$12 = {
1248
1466
  key: 0,
1249
1467
  class: "j-dialog__header"
1250
1468
  };
1251
- var _hoisted_4$4 = {
1469
+ var _hoisted_4$7 = {
1252
1470
  key: 1,
1253
1471
  class: "j-dialog__body"
1254
1472
  };
1255
- var _hoisted_5$3 = {
1473
+ var _hoisted_5$4 = {
1256
1474
  key: 2,
1257
1475
  class: "j-dialog__footer"
1258
1476
  };
@@ -1290,38 +1508,20 @@ var JDialog_default = /* @__PURE__ */ defineComponent({
1290
1508
  const titleId = `j-${id}-title`;
1291
1509
  const descriptionId = `j-${id}-description`;
1292
1510
  const panel = ref(null);
1293
- const nudging = ref(false);
1294
1511
  function close() {
1295
1512
  open.value = false;
1296
1513
  }
1297
- function nudge() {
1298
- if (prefersReducedMotion()) return;
1299
- nudging.value = false;
1300
- requestAnimationFrame(() => nudging.value = true);
1301
- }
1302
- const { isTopLayer } = useLayer({
1303
- active: open,
1304
- elements: () => [panel.value],
1305
- onEscape: () => props.closeOnEscape ? close() : nudge()
1514
+ const { nudging, onBackdropPointerDown, onBackdropClick } = useModal(panel, open, {
1515
+ closeOnEscape: () => props.closeOnEscape,
1516
+ closeOnOverlay: () => props.closeOnOverlay,
1517
+ close,
1518
+ focusSelector: `.j-dialog__body ${FIELD_SELECTOR}`
1306
1519
  });
1307
- useFocusTrap(panel, open, { initialFocus: () => panel.value?.querySelector("[autofocus], [data-autofocus]") ?? panel.value?.querySelector(".j-dialog__body :is(input:not([type=hidden]), textarea, select, [role=combobox]):not(:disabled)") ?? panel.value });
1308
- useScrollLock(open);
1309
- let pressedOutside = false;
1310
- function onPointerDown(event) {
1311
- pressedOutside = event.target === event.currentTarget && isTopLayer();
1312
- }
1313
- function onClick(event) {
1314
- const outside = pressedOutside && event.target === event.currentTarget;
1315
- pressedOutside = false;
1316
- if (!outside) return;
1317
- if (props.closeOnOverlay) close();
1318
- else nudge();
1319
- }
1320
1520
  __expose({ close });
1321
1521
  return (_ctx, _cache) => {
1322
1522
  return openBlock(), createBlock(JPortal_default, null, {
1323
1523
  default: withCtx(() => [createVNode(Transition, { name: "j-dialog-overlay" }, {
1324
- default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$13)) : createCommentVNode("", true)]),
1524
+ default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$20)) : createCommentVNode("", true)]),
1325
1525
  _: 1
1326
1526
  }), createVNode(Transition, {
1327
1527
  name: "j-dialog",
@@ -1329,26 +1529,26 @@ var JDialog_default = /* @__PURE__ */ defineComponent({
1329
1529
  enter: 240,
1330
1530
  leave: 150
1331
1531
  },
1332
- onAfterLeave: _cache[1] || (_cache[1] = ($event) => emit("afterClose"))
1532
+ onAfterLeave: _cache[3] || (_cache[3] = ($event) => emit("afterClose"))
1333
1533
  }, {
1334
1534
  default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", {
1335
1535
  key: 0,
1336
1536
  class: "j-dialog__positioner",
1337
- onPointerdown: onPointerDown,
1338
- onClick
1537
+ onPointerdown: _cache[1] || (_cache[1] = (...args) => unref(onBackdropPointerDown) && unref(onBackdropPointerDown)(...args)),
1538
+ onClick: _cache[2] || (_cache[2] = (...args) => unref(onBackdropClick) && unref(onBackdropClick)(...args))
1339
1539
  }, [createElementVNode("div", {
1340
1540
  ref_key: "panel",
1341
1541
  ref: panel,
1342
1542
  role: "dialog",
1343
1543
  "aria-modal": "true",
1344
1544
  tabindex: "-1",
1345
- class: normalizeClass(["j-dialog__panel", [`j-dialog__panel--${__props.size}`, { "is-nudging": nudging.value }]]),
1545
+ class: normalizeClass(["j-dialog__panel", [`j-dialog__panel--${__props.size}`, { "is-nudging": unref(nudging) }]]),
1346
1546
  "aria-labelledby": __props.title || _ctx.$slots.header ? titleId : void 0,
1347
1547
  "aria-label": __props.ariaLabel,
1348
1548
  "aria-describedby": __props.description ? descriptionId : void 0,
1349
1549
  onAnimationend: _cache[0] || (_cache[0] = ($event) => nudging.value = false)
1350
1550
  }, [
1351
- __props.title || __props.description || _ctx.$slots.header ? (openBlock(), createElementBlock("header", _hoisted_3$8, [renderSlot(_ctx.$slots, "header", {
1551
+ __props.title || __props.description || _ctx.$slots.header ? (openBlock(), createElementBlock("header", _hoisted_3$12, [renderSlot(_ctx.$slots, "header", {
1352
1552
  titleId,
1353
1553
  descriptionId
1354
1554
  }, () => [createElementVNode("h2", {
@@ -1359,8 +1559,8 @@ var JDialog_default = /* @__PURE__ */ defineComponent({
1359
1559
  id: descriptionId,
1360
1560
  class: "j-dialog__description"
1361
1561
  }, toDisplayString(__props.description), 1)) : createCommentVNode("", true)])])) : createCommentVNode("", true),
1362
- _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_4$4, [renderSlot(_ctx.$slots, "default", { close })])) : createCommentVNode("", true),
1363
- _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_5$3, [renderSlot(_ctx.$slots, "footer", { close })])) : 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),
1364
1564
  !__props.hideClose ? (openBlock(), createElementBlock("button", {
1365
1565
  key: 3,
1366
1566
  type: "button",
@@ -1368,7 +1568,7 @@ var JDialog_default = /* @__PURE__ */ defineComponent({
1368
1568
  "aria-label": "Close",
1369
1569
  onClick: close
1370
1570
  }, [createVNode(unref(IconX))])) : createCommentVNode("", true)
1371
- ], 42, _hoisted_2$8)], 32)) : createCommentVNode("", true)]),
1571
+ ], 42, _hoisted_2$14)], 32)) : createCommentVNode("", true)]),
1372
1572
  _: 3
1373
1573
  })]),
1374
1574
  _: 3
@@ -1530,7 +1730,7 @@ function useTypeahead(timeout = 500) {
1530
1730
  }
1531
1731
  //#endregion
1532
1732
  //#region src/components/dropdown-menu/JMenuContent.vue?vue&type=script&setup=true&lang.ts
1533
- var _hoisted_1$12 = ["id", "aria-labelledby"];
1733
+ var _hoisted_1$19 = ["id", "aria-labelledby"];
1534
1734
  //#endregion
1535
1735
  //#region src/components/dropdown-menu/JMenuContent.vue
1536
1736
  var JMenuContent_default = /* @__PURE__ */ defineComponent({
@@ -1674,7 +1874,7 @@ var JMenuContent_default = /* @__PURE__ */ defineComponent({
1674
1874
  "aria-orientation": "vertical",
1675
1875
  onKeydown,
1676
1876
  onPointerenter: _cache[0] || (_cache[0] = ($event) => emit("pointerenter"))
1677
- }, [renderSlot(_ctx.$slots, "default")], 46, _hoisted_1$12)) : createCommentVNode("", true)]),
1877
+ }, [renderSlot(_ctx.$slots, "default")], 46, _hoisted_1$19)) : createCommentVNode("", true)]),
1678
1878
  _: 3
1679
1879
  })]),
1680
1880
  _: 3
@@ -1774,12 +1974,12 @@ var JDropdownMenu_default = /* @__PURE__ */ defineComponent({
1774
1974
  });
1775
1975
  //#endregion
1776
1976
  //#region src/components/dropdown-menu/JDropdownMenuItem.vue?vue&type=script&setup=true&lang.ts
1777
- var _hoisted_1$11 = {
1977
+ var _hoisted_1$18 = {
1778
1978
  key: 0,
1779
1979
  class: "j-menu__icon"
1780
1980
  };
1781
- var _hoisted_2$7 = { class: "j-menu__text" };
1782
- var _hoisted_3$7 = {
1981
+ var _hoisted_2$13 = { class: "j-menu__text" };
1982
+ var _hoisted_3$11 = {
1783
1983
  key: 1,
1784
1984
  class: "j-menu__shortcut"
1785
1985
  };
@@ -1841,9 +2041,9 @@ var JDropdownMenuItem_default = /* @__PURE__ */ defineComponent({
1841
2041
  onPointerleave: onPointerLeave
1842
2042
  }, {
1843
2043
  default: withCtx(() => [
1844
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_1$11, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
1845
- createElementVNode("span", _hoisted_2$7, [renderSlot(_ctx.$slots, "default")]),
1846
- __props.shortcut ? (openBlock(), createElementBlock("span", _hoisted_3$7, toDisplayString(__props.shortcut), 1)) : createCommentVNode("", true),
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),
1847
2047
  __props.checked !== void 0 ? (openBlock(), createBlock(unref(IconCheck), {
1848
2048
  key: 2,
1849
2049
  class: normalizeClass(["j-menu__check", { "is-checked": __props.checked }])
@@ -1861,7 +2061,7 @@ var JDropdownMenuItem_default = /* @__PURE__ */ defineComponent({
1861
2061
  });
1862
2062
  //#endregion
1863
2063
  //#region src/components/dropdown-menu/JDropdownMenuLabel.vue?vue&type=script&setup=true&lang.ts
1864
- var _hoisted_1$10 = {
2064
+ var _hoisted_1$17 = {
1865
2065
  class: "j-menu__label",
1866
2066
  role: "presentation"
1867
2067
  };
@@ -1871,7 +2071,7 @@ var JDropdownMenuLabel_default = /* @__PURE__ */ defineComponent({
1871
2071
  __name: "JDropdownMenuLabel",
1872
2072
  setup(__props) {
1873
2073
  return (_ctx, _cache) => {
1874
- return openBlock(), createElementBlock("div", _hoisted_1$10, [renderSlot(_ctx.$slots, "default")]);
2074
+ return openBlock(), createElementBlock("div", _hoisted_1$17, [renderSlot(_ctx.$slots, "default")]);
1875
2075
  };
1876
2076
  }
1877
2077
  });
@@ -1885,27 +2085,27 @@ var _plugin_vue_export_helper_default = (sfc, props) => {
1885
2085
  //#endregion
1886
2086
  //#region src/components/dropdown-menu/JDropdownMenuSeparator.vue
1887
2087
  var _sfc_main = {};
1888
- var _hoisted_1$9 = {
2088
+ var _hoisted_1$16 = {
1889
2089
  role: "separator",
1890
2090
  "aria-orientation": "horizontal",
1891
2091
  class: "j-menu__separator"
1892
2092
  };
1893
2093
  function _sfc_render(_ctx, _cache) {
1894
- return openBlock(), createElementBlock("div", _hoisted_1$9);
2094
+ return openBlock(), createElementBlock("div", _hoisted_1$16);
1895
2095
  }
1896
2096
  var JDropdownMenuSeparator_default = /*#__PURE__*/ _plugin_vue_export_helper_default(_sfc_main, [["render", _sfc_render]]);
1897
2097
  //#endregion
1898
2098
  //#region src/components/dropdown-menu/JDropdownMenuSub.vue?vue&type=script&setup=true&lang.ts
1899
- var _hoisted_1$8 = [
2099
+ var _hoisted_1$15 = [
1900
2100
  "aria-expanded",
1901
2101
  "aria-controls",
1902
2102
  "aria-disabled"
1903
2103
  ];
1904
- var _hoisted_2$6 = {
2104
+ var _hoisted_2$12 = {
1905
2105
  key: 0,
1906
2106
  class: "j-menu__icon"
1907
2107
  };
1908
- var _hoisted_3$6 = { class: "j-menu__text" };
2108
+ var _hoisted_3$10 = { class: "j-menu__text" };
1909
2109
  //#endregion
1910
2110
  //#region src/components/dropdown-menu/JDropdownMenuSub.vue
1911
2111
  var JDropdownMenuSub_default = /* @__PURE__ */ defineComponent({
@@ -1979,10 +2179,10 @@ var JDropdownMenuSub_default = /* @__PURE__ */ defineComponent({
1979
2179
  onKeydown,
1980
2180
  onClick
1981
2181
  }, [
1982
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_2$6, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
1983
- createElementVNode("span", _hoisted_3$6, toDisplayString(__props.label), 1),
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),
1984
2184
  createVNode(unref(IconChevronRight), { class: "j-menu__chevron" })
1985
- ], 40, _hoisted_1$8), createVNode(JMenuContent_default, {
2185
+ ], 40, _hoisted_1$15), createVNode(JMenuContent_default, {
1986
2186
  id: menuId,
1987
2187
  ref_key: "sub",
1988
2188
  ref: sub,
@@ -2013,14 +2213,14 @@ var JDropdownMenuSub_default = /* @__PURE__ */ defineComponent({
2013
2213
  });
2014
2214
  //#endregion
2015
2215
  //#region src/components/field/JFieldShell.vue?vue&type=script&setup=true&lang.ts
2016
- var _hoisted_1$7 = {
2216
+ var _hoisted_1$14 = {
2017
2217
  key: 0,
2018
2218
  class: "j-field__required",
2019
2219
  "aria-hidden": "true"
2020
2220
  };
2021
- var _hoisted_2$5 = { class: "j-field__messages" };
2022
- var _hoisted_3$5 = ["id"];
2023
- var _hoisted_4$3 = ["id"];
2221
+ var _hoisted_2$11 = { class: "j-field__messages" };
2222
+ var _hoisted_3$9 = ["id"];
2223
+ var _hoisted_4$6 = ["id"];
2024
2224
  //#endregion
2025
2225
  //#region src/components/field/JFieldShell.vue
2026
2226
  var JFieldShell_default = /* @__PURE__ */ defineComponent({
@@ -2051,11 +2251,11 @@ var JFieldShell_default = /* @__PURE__ */ defineComponent({
2051
2251
  class: "j-field__label",
2052
2252
  for: __props.labelFor === null ? void 0 : __props.labelFor ?? __props.id
2053
2253
  }, {
2054
- default: withCtx(() => [renderSlot(_ctx.$slots, "label", {}, () => [createTextVNode(toDisplayString(__props.label), 1)]), __props.required ? (openBlock(), createElementBlock("span", _hoisted_1$7, "*")) : createCommentVNode("", true)]),
2254
+ default: withCtx(() => [renderSlot(_ctx.$slots, "label", {}, () => [createTextVNode(toDisplayString(__props.label), 1)]), __props.required ? (openBlock(), createElementBlock("span", _hoisted_1$14, "*")) : createCommentVNode("", true)]),
2055
2255
  _: 3
2056
2256
  }, 8, ["id", "for"])) : createCommentVNode("", true),
2057
2257
  renderSlot(_ctx.$slots, "default"),
2058
- createElementVNode("div", _hoisted_2$5, [createVNode(Transition, {
2258
+ createElementVNode("div", _hoisted_2$11, [createVNode(Transition, {
2059
2259
  name: "j-field-message",
2060
2260
  mode: "out-in"
2061
2261
  }, {
@@ -2063,11 +2263,11 @@ var JFieldShell_default = /* @__PURE__ */ defineComponent({
2063
2263
  id: __props.errorId,
2064
2264
  key: __props.errorMessage,
2065
2265
  class: "j-field__error"
2066
- }, toDisplayString(__props.errorMessage), 9, _hoisted_3$5)) : __props.showDescription ? (openBlock(), createElementBlock("p", {
2266
+ }, toDisplayString(__props.errorMessage), 9, _hoisted_3$9)) : __props.showDescription ? (openBlock(), createElementBlock("p", {
2067
2267
  key: 1,
2068
2268
  id: __props.descriptionId,
2069
2269
  class: "j-field__description"
2070
- }, toDisplayString(__props.description), 9, _hoisted_4$3)) : createCommentVNode("", true)]),
2270
+ }, toDisplayString(__props.description), 9, _hoisted_4$6)) : createCommentVNode("", true)]),
2071
2271
  _: 1
2072
2272
  })])
2073
2273
  ], 2);
@@ -2104,141 +2304,486 @@ function useField(props) {
2104
2304
  }
2105
2305
  //#endregion
2106
2306
  //#region src/components/input/JInput.vue?vue&type=script&setup=true&lang.ts
2107
- var _hoisted_1$6 = {
2307
+ var _hoisted_1$13 = {
2108
2308
  key: 0,
2109
2309
  class: "j-control__adornment j-control__adornment--leading"
2110
2310
  };
2111
- var _hoisted_2$4 = [
2311
+ var _hoisted_2$10 = [
2112
2312
  "id",
2113
2313
  "type",
2114
2314
  "name",
2115
2315
  "placeholder",
2116
2316
  "disabled",
2117
- "readonly",
2118
- "required",
2119
- "autocomplete",
2317
+ "readonly",
2318
+ "required",
2319
+ "autocomplete",
2320
+ "aria-invalid",
2321
+ "aria-describedby"
2322
+ ];
2323
+ var _hoisted_3$8 = {
2324
+ key: 1,
2325
+ class: "j-control__adornment j-control__adornment--trailing"
2326
+ };
2327
+ //#endregion
2328
+ //#region src/components/input/JInput.vue
2329
+ var JInput_default = /* @__PURE__ */ defineComponent({
2330
+ inheritAttrs: false,
2331
+ __name: "JInput",
2332
+ props: /*@__PURE__*/ mergeModels({
2333
+ type: { default: "text" },
2334
+ placeholder: {},
2335
+ size: { default: "md" },
2336
+ readonly: { type: Boolean },
2337
+ name: {},
2338
+ autocomplete: {},
2339
+ label: {},
2340
+ description: {},
2341
+ error: {
2342
+ type: [String, Boolean],
2343
+ default: void 0
2344
+ },
2345
+ required: { type: Boolean },
2346
+ disabled: { type: Boolean },
2347
+ id: {}
2348
+ }, {
2349
+ "modelValue": { default: "" },
2350
+ "modelModifiers": {}
2351
+ }),
2352
+ emits: ["update:modelValue"],
2353
+ setup(__props, { expose: __expose }) {
2354
+ const props = __props;
2355
+ const model = useModel(__props, "modelValue");
2356
+ const field = useField(props);
2357
+ const input = ref(null);
2358
+ function onFramePointerDown(event) {
2359
+ if (event.target === input.value || props.disabled) return;
2360
+ if (event.target.closest("button, a, input, select, textarea, [tabindex]")) return;
2361
+ event.preventDefault();
2362
+ input.value?.focus();
2363
+ }
2364
+ __expose({
2365
+ /** The underlying `<input>` element. */
2366
+ input,
2367
+ focus: () => input.value?.focus(),
2368
+ select: () => input.value?.select()
2369
+ });
2370
+ return (_ctx, _cache) => {
2371
+ return openBlock(), createBlock(JFieldShell_default, {
2372
+ id: unref(field).id.value,
2373
+ class: normalizeClass(_ctx.$attrs.class),
2374
+ style: normalizeStyle(_ctx.$attrs.style),
2375
+ "label-id": unref(field).labelId.value,
2376
+ "description-id": unref(field).descriptionId.value,
2377
+ "error-id": unref(field).errorId.value,
2378
+ label: __props.label,
2379
+ description: __props.description,
2380
+ "error-message": unref(field).errorMessage.value,
2381
+ "show-description": unref(field).showDescription.value,
2382
+ required: __props.required,
2383
+ disabled: __props.disabled
2384
+ }, createSlots({
2385
+ default: withCtx(() => [createElementVNode("div", {
2386
+ class: normalizeClass(["j-control j-input", [`j-control--${__props.size}`, {
2387
+ "is-invalid": unref(field).invalid.value,
2388
+ "is-disabled": __props.disabled,
2389
+ "is-readonly": __props.readonly
2390
+ }]]),
2391
+ onPointerdown: onFramePointerDown
2392
+ }, [
2393
+ _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_1$13, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
2394
+ withDirectives(createElementVNode("input", mergeProps({
2395
+ id: unref(field).id.value,
2396
+ ref_key: "input",
2397
+ ref: input,
2398
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event)
2399
+ }, {
2400
+ ..._ctx.$attrs,
2401
+ class: void 0,
2402
+ style: void 0
2403
+ }, {
2404
+ class: "j-input__native",
2405
+ type: __props.type,
2406
+ name: __props.name,
2407
+ placeholder: __props.placeholder,
2408
+ disabled: __props.disabled,
2409
+ readonly: __props.readonly,
2410
+ required: __props.required,
2411
+ autocomplete: __props.autocomplete,
2412
+ "aria-invalid": unref(field).invalid.value || void 0,
2413
+ "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)
2416
+ ], 34)]),
2417
+ _: 2
2418
+ }, [_ctx.$slots.label ? {
2419
+ name: "label",
2420
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "label")]),
2421
+ key: "0"
2422
+ } : void 0]), 1032, [
2423
+ "id",
2424
+ "class",
2425
+ "style",
2426
+ "label-id",
2427
+ "description-id",
2428
+ "error-id",
2429
+ "label",
2430
+ "description",
2431
+ "error-message",
2432
+ "show-description",
2433
+ "required",
2434
+ "disabled"
2435
+ ]);
2436
+ };
2437
+ }
2438
+ });
2439
+ //#endregion
2440
+ //#region src/components/kbd/JKbd.vue
2441
+ var JKbd_default = /* @__PURE__ */ defineComponent({
2442
+ __name: "JKbd",
2443
+ props: {
2444
+ keys: {},
2445
+ size: { default: "md" }
2446
+ },
2447
+ setup(__props) {
2448
+ const props = __props;
2449
+ const mounted = ref(false);
2450
+ onMounted(() => mounted.value = true);
2451
+ const parts = computed(() => {
2452
+ if (!props.keys) return [];
2453
+ if (!mounted.value) return props.keys.split("+").map((part) => part === "mod" ? "Ctrl" : part.length === 1 ? part.toUpperCase() : part);
2454
+ return formatHotkey(props.keys);
2455
+ });
2456
+ return (_ctx, _cache) => {
2457
+ return __props.keys ? (openBlock(), createElementBlock("span", {
2458
+ key: 0,
2459
+ class: normalizeClass(["j-kbd-group", `j-kbd-group--${__props.size}`])
2460
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(parts.value, (part, i) => {
2461
+ return openBlock(), createElementBlock("kbd", {
2462
+ key: i,
2463
+ class: "j-kbd"
2464
+ }, toDisplayString(part), 1);
2465
+ }), 128))], 2)) : (openBlock(), createElementBlock("kbd", {
2466
+ key: 1,
2467
+ class: normalizeClass(["j-kbd", { "j-kbd--sm": __props.size === "sm" }])
2468
+ }, [renderSlot(_ctx.$slots, "default")], 2));
2469
+ };
2470
+ }
2471
+ });
2472
+ //#endregion
2473
+ //#region src/components/popover/JPopover.vue?vue&type=script&setup=true&lang.ts
2474
+ var _hoisted_1$12 = ["aria-label"];
2475
+ //#endregion
2476
+ //#region src/components/popover/JPopover.vue
2477
+ var JPopover_default = /* @__PURE__ */ defineComponent({
2478
+ __name: "JPopover",
2479
+ props: /*@__PURE__*/ mergeModels({
2480
+ placement: { default: "bottom" },
2481
+ offset: { default: 8 },
2482
+ ariaLabel: {},
2483
+ closeOnOutside: {
2484
+ type: Boolean,
2485
+ default: true
2486
+ },
2487
+ disabled: { type: Boolean }
2488
+ }, {
2489
+ "open": {
2490
+ type: Boolean,
2491
+ default: false
2492
+ },
2493
+ "openModifiers": {}
2494
+ }),
2495
+ emits: ["update:open"],
2496
+ setup(__props, { expose: __expose }) {
2497
+ const props = __props;
2498
+ const open = useModel(__props, "open");
2499
+ const id = `j-${useId()}-popover`;
2500
+ const triggerRef = ref();
2501
+ const triggerEl = computed(() => unrefElement(triggerRef.value));
2502
+ const content = ref(null);
2503
+ const { styles } = useFloating(triggerEl, content, () => ({
2504
+ placement: props.placement,
2505
+ offset: props.offset
2506
+ }));
2507
+ function close(restoreFocus = false) {
2508
+ if (!open.value) return;
2509
+ open.value = false;
2510
+ if (restoreFocus) nextTick(() => focusElement(triggerEl.value));
2511
+ }
2512
+ useLayer({
2513
+ active: open,
2514
+ elements: () => [triggerEl.value, content.value],
2515
+ onEscape: () => close(true),
2516
+ onPointerDownOutside: () => props.closeOnOutside && close(false)
2517
+ });
2518
+ watch(open, async (value) => {
2519
+ if (!value) return;
2520
+ await nextTick();
2521
+ const el = content.value;
2522
+ if (!el) return;
2523
+ focusElement(el.querySelector("[autofocus], [data-autofocus]") ?? getFocusableElements(el)[0] ?? el);
2524
+ }, { flush: "post" });
2525
+ function onFocusOut(event) {
2526
+ if (!props.closeOnOutside) return;
2527
+ const next = event.relatedTarget;
2528
+ if (!next) return;
2529
+ if (content.value?.contains(next) || triggerEl.value?.contains(next)) return;
2530
+ close(false);
2531
+ }
2532
+ function toggle() {
2533
+ if (props.disabled) return;
2534
+ open.value = !open.value;
2535
+ }
2536
+ const triggerProps = computed(() => ({
2537
+ "aria-haspopup": "dialog",
2538
+ "aria-expanded": open.value,
2539
+ "aria-controls": open.value ? id : void 0,
2540
+ "data-state": open.value ? "open" : "closed",
2541
+ "onClick": toggle
2542
+ }));
2543
+ __expose({ close: () => close(true) });
2544
+ return (_ctx, _cache) => {
2545
+ return openBlock(), createElementBlock(Fragment, null, [createVNode(unref(JSlot), mergeProps({
2546
+ ref_key: "triggerRef",
2547
+ ref: triggerRef
2548
+ }, triggerProps.value), {
2549
+ default: withCtx(() => [renderSlot(_ctx.$slots, "trigger", { open: open.value })]),
2550
+ _: 3
2551
+ }, 16), createVNode(JPortal_default, null, {
2552
+ default: withCtx(() => [createVNode(Transition, { name: "j-pop" }, {
2553
+ default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", {
2554
+ key: 0,
2555
+ id,
2556
+ ref_key: "content",
2557
+ ref: content,
2558
+ role: "dialog",
2559
+ tabindex: "-1",
2560
+ class: "j-popover j-popover-surface",
2561
+ style: normalizeStyle(unref(styles)),
2562
+ "aria-label": __props.ariaLabel,
2563
+ onFocusout: onFocusOut
2564
+ }, [renderSlot(_ctx.$slots, "default", { close: () => close(true) })], 44, _hoisted_1$12)) : createCommentVNode("", true)]),
2565
+ _: 3
2566
+ })]),
2567
+ _: 3
2568
+ })], 64);
2569
+ };
2570
+ }
2571
+ });
2572
+ //#endregion
2573
+ //#region src/components/progress/JProgress.vue?vue&type=script&setup=true&lang.ts
2574
+ var _hoisted_1$11 = {
2575
+ key: 0,
2576
+ class: "j-progress__header"
2577
+ };
2578
+ var _hoisted_2$9 = ["id"];
2579
+ var _hoisted_3$7 = {
2580
+ key: 1,
2581
+ class: "j-progress__value"
2582
+ };
2583
+ var _hoisted_4$5 = [
2584
+ "aria-labelledby",
2585
+ "aria-valuemax",
2586
+ "aria-valuenow",
2587
+ "aria-valuetext"
2588
+ ];
2589
+ //#endregion
2590
+ //#region src/components/progress/JProgress.vue
2591
+ var JProgress_default = /* @__PURE__ */ defineComponent({
2592
+ __name: "JProgress",
2593
+ props: {
2594
+ value: { default: null },
2595
+ max: { default: 100 },
2596
+ size: { default: "md" },
2597
+ label: {},
2598
+ showValue: { type: Boolean },
2599
+ variant: { default: "accent" }
2600
+ },
2601
+ setup(__props) {
2602
+ const props = __props;
2603
+ const id = `j-${useId()}`;
2604
+ const indeterminate = computed(() => props.value === null || props.value === void 0);
2605
+ const ratio = computed(() => indeterminate.value ? 0 : Math.min(1, Math.max(0, Number(props.value) / props.max)));
2606
+ const percent = computed(() => Math.round(ratio.value * 100));
2607
+ return (_ctx, _cache) => {
2608
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["j-progress", [
2609
+ `j-progress--${__props.size}`,
2610
+ `j-progress--${__props.variant}`,
2611
+ { "is-indeterminate": indeterminate.value }
2612
+ ]]) }, [__props.label || __props.showValue ? (openBlock(), createElementBlock("div", _hoisted_1$11, [__props.label ? (openBlock(), createElementBlock("span", {
2613
+ key: 0,
2614
+ id: `${id}-label`,
2615
+ 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", {
2617
+ class: "j-progress__track",
2618
+ role: "progressbar",
2619
+ "aria-labelledby": __props.label ? `${id}-label` : void 0,
2620
+ "aria-valuemin": "0",
2621
+ "aria-valuemax": __props.max,
2622
+ "aria-valuenow": indeterminate.value ? void 0 : __props.value,
2623
+ "aria-valuetext": indeterminate.value ? "Loading" : `${percent.value}%`
2624
+ }, [createElementVNode("span", {
2625
+ class: "j-progress__fill",
2626
+ style: normalizeStyle(indeterminate.value ? void 0 : { transform: `scaleX(${ratio.value})` })
2627
+ }, null, 4)], 8, _hoisted_4$5)], 2);
2628
+ };
2629
+ }
2630
+ });
2631
+ //#endregion
2632
+ //#region src/components/radio/context.ts
2633
+ var RADIO_GROUP = Symbol("JRadioGroup");
2634
+ //#endregion
2635
+ //#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 = [
2639
+ "name",
2640
+ "value",
2641
+ "checked",
2642
+ "disabled",
2643
+ "required",
2644
+ "aria-describedby"
2645
+ ];
2646
+ var _hoisted_4$4 = {
2647
+ key: 0,
2648
+ class: "j-radio__text"
2649
+ };
2650
+ //#endregion
2651
+ //#region src/components/radio/JRadio.vue
2652
+ var JRadio_default = /* @__PURE__ */ defineComponent({
2653
+ inheritAttrs: false,
2654
+ __name: "JRadio",
2655
+ props: {
2656
+ value: {},
2657
+ label: {},
2658
+ description: {},
2659
+ disabled: { type: Boolean }
2660
+ },
2661
+ setup(__props) {
2662
+ const props = __props;
2663
+ const group = inject(RADIO_GROUP, null);
2664
+ const id = `j-${useId()}`;
2665
+ const descriptionId = `${id}-description`;
2666
+ const checked = computed(() => group?.value.value === props.value);
2667
+ const isDisabled = computed(() => props.disabled || !!group?.disabled.value);
2668
+ return (_ctx, _cache) => {
2669
+ return openBlock(), createElementBlock("div", {
2670
+ class: normalizeClass(["j-radio", [_ctx.$attrs.class, { "is-disabled": isDisabled.value }]]),
2671
+ style: normalizeStyle(_ctx.$attrs.style),
2672
+ "data-state": checked.value ? "checked" : "unchecked"
2673
+ }, [createElementVNode("span", _hoisted_2$8, [createElementVNode("input", mergeProps({ id }, {
2674
+ ..._ctx.$attrs,
2675
+ class: void 0,
2676
+ style: void 0
2677
+ }, {
2678
+ type: "radio",
2679
+ class: "j-radio__input",
2680
+ name: unref(group)?.name.value,
2681
+ value: __props.value,
2682
+ checked: checked.value,
2683
+ disabled: isDisabled.value,
2684
+ required: unref(group)?.required.value,
2685
+ "aria-describedby": __props.description || _ctx.$slots.description ? descriptionId : void 0,
2686
+ onChange: _cache[0] || (_cache[0] = ($event) => unref(group)?.select(__props.value))
2687
+ }), null, 16, _hoisted_3$6), _cache[1] || (_cache[1] = createElementVNode("span", {
2688
+ class: "j-radio__circle",
2689
+ "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", {
2691
+ key: 0,
2692
+ for: id,
2693
+ class: "j-radio__label"
2694
+ }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.label), 1)])])) : createCommentVNode("", true), __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", {
2695
+ key: 1,
2696
+ id: descriptionId,
2697
+ class: "j-radio__description"
2698
+ }, [renderSlot(_ctx.$slots, "description", {}, () => [createTextVNode(toDisplayString(__props.description), 1)])])) : createCommentVNode("", true)])) : createCommentVNode("", true)], 14, _hoisted_1$10);
2699
+ };
2700
+ }
2701
+ });
2702
+ //#endregion
2703
+ //#region src/components/radio/JRadioGroup.vue?vue&type=script&setup=true&lang.ts
2704
+ var _hoisted_1$9 = [
2705
+ "disabled",
2706
+ "aria-describedby",
2120
2707
  "aria-invalid",
2121
- "aria-describedby"
2708
+ "aria-required"
2122
2709
  ];
2123
- var _hoisted_3$4 = {
2124
- key: 1,
2125
- class: "j-control__adornment j-control__adornment--trailing"
2710
+ var _hoisted_2$7 = {
2711
+ key: 0,
2712
+ class: "j-radio-group__legend"
2713
+ };
2714
+ var _hoisted_3$5 = {
2715
+ key: 0,
2716
+ class: "j-field__required",
2717
+ "aria-hidden": "true"
2126
2718
  };
2127
2719
  //#endregion
2128
- //#region src/components/input/JInput.vue
2129
- var JInput_default = /* @__PURE__ */ defineComponent({
2130
- inheritAttrs: false,
2131
- __name: "JInput",
2720
+ //#region src/components/radio/JRadioGroup.vue
2721
+ var JRadioGroup_default = /* @__PURE__ */ defineComponent({
2722
+ __name: "JRadioGroup",
2132
2723
  props: /*@__PURE__*/ mergeModels({
2133
- type: { default: "text" },
2134
- placeholder: {},
2135
- size: { default: "md" },
2136
- readonly: { type: Boolean },
2137
- name: {},
2138
- autocomplete: {},
2139
2724
  label: {},
2140
2725
  description: {},
2141
2726
  error: {
2142
2727
  type: [String, Boolean],
2143
2728
  default: void 0
2144
2729
  },
2145
- required: { type: Boolean },
2730
+ orientation: { default: "vertical" },
2146
2731
  disabled: { type: Boolean },
2147
- id: {}
2732
+ required: { type: Boolean },
2733
+ name: {}
2148
2734
  }, {
2149
- "modelValue": { default: "" },
2735
+ "modelValue": { default: null },
2150
2736
  "modelModifiers": {}
2151
2737
  }),
2152
2738
  emits: ["update:modelValue"],
2153
- setup(__props, { expose: __expose }) {
2739
+ setup(__props) {
2154
2740
  const props = __props;
2155
2741
  const model = useModel(__props, "modelValue");
2156
- const field = useField(props);
2157
- const input = ref(null);
2158
- function onFramePointerDown(event) {
2159
- if (event.target === input.value || props.disabled) return;
2160
- if (event.target.closest("button, a, input, select, textarea, [tabindex]")) return;
2161
- event.preventDefault();
2162
- input.value?.focus();
2163
- }
2164
- __expose({
2165
- /** The underlying `<input>` element. */
2166
- input,
2167
- focus: () => input.value?.focus(),
2168
- select: () => input.value?.select()
2742
+ const id = `j-${useId()}`;
2743
+ const descriptionId = `${id}-description`;
2744
+ const errorId = `${id}-error`;
2745
+ const errorMessage = computed(() => typeof props.error === "string" ? props.error : "");
2746
+ provide(RADIO_GROUP, {
2747
+ name: computed(() => props.name ?? id),
2748
+ value: computed(() => model.value),
2749
+ disabled: computed(() => props.disabled),
2750
+ required: computed(() => props.required),
2751
+ invalid: computed(() => !!props.error),
2752
+ select: (value) => {
2753
+ if (!props.disabled) model.value = value;
2754
+ }
2169
2755
  });
2756
+ const describedBy = computed(() => errorMessage.value ? errorId : props.description ? descriptionId : void 0);
2170
2757
  return (_ctx, _cache) => {
2171
- return openBlock(), createBlock(JFieldShell_default, {
2172
- id: unref(field).id.value,
2173
- class: normalizeClass(_ctx.$attrs.class),
2174
- style: normalizeStyle(_ctx.$attrs.style),
2175
- "label-id": unref(field).labelId.value,
2176
- "description-id": unref(field).descriptionId.value,
2177
- "error-id": unref(field).errorId.value,
2178
- label: __props.label,
2179
- description: __props.description,
2180
- "error-message": unref(field).errorMessage.value,
2181
- "show-description": unref(field).showDescription.value,
2182
- required: __props.required,
2183
- disabled: __props.disabled
2184
- }, createSlots({
2185
- default: withCtx(() => [createElementVNode("div", {
2186
- class: normalizeClass(["j-control j-input", [`j-control--${__props.size}`, {
2187
- "is-invalid": unref(field).invalid.value,
2188
- "is-disabled": __props.disabled,
2189
- "is-readonly": __props.readonly
2190
- }]]),
2191
- onPointerdown: onFramePointerDown
2192
- }, [
2193
- _ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_1$6, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
2194
- withDirectives(createElementVNode("input", mergeProps({
2195
- id: unref(field).id.value,
2196
- ref_key: "input",
2197
- ref: input,
2198
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event)
2199
- }, {
2200
- ..._ctx.$attrs,
2201
- class: void 0,
2202
- style: void 0
2203
- }, {
2204
- class: "j-input__native",
2205
- type: __props.type,
2206
- name: __props.name,
2207
- placeholder: __props.placeholder,
2208
- disabled: __props.disabled,
2209
- readonly: __props.readonly,
2210
- required: __props.required,
2211
- autocomplete: __props.autocomplete,
2212
- "aria-invalid": unref(field).invalid.value || void 0,
2213
- "aria-describedby": unref(field).describedBy.value
2214
- }), null, 16, _hoisted_2$4), [[vModelDynamic, model.value]]),
2215
- _ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_3$4, [renderSlot(_ctx.$slots, "trailing")])) : createCommentVNode("", true)
2216
- ], 34)]),
2217
- _: 2
2218
- }, [_ctx.$slots.label ? {
2219
- name: "label",
2220
- fn: withCtx(() => [renderSlot(_ctx.$slots, "label")]),
2221
- key: "0"
2222
- } : void 0]), 1032, [
2223
- "id",
2224
- "class",
2225
- "style",
2226
- "label-id",
2227
- "description-id",
2228
- "error-id",
2229
- "label",
2230
- "description",
2231
- "error-message",
2232
- "show-description",
2233
- "required",
2234
- "disabled"
2235
- ]);
2758
+ return openBlock(), createElementBlock("fieldset", {
2759
+ class: normalizeClass(["j-radio-group", {
2760
+ "is-disabled": __props.disabled,
2761
+ "is-invalid": !!__props.error
2762
+ }]),
2763
+ disabled: __props.disabled,
2764
+ "aria-describedby": describedBy.value,
2765
+ "aria-invalid": !!__props.error || void 0,
2766
+ "aria-required": __props.required || void 0
2767
+ }, [
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),
2769
+ __props.description && !errorMessage.value ? (openBlock(), createElementBlock("p", {
2770
+ key: 1,
2771
+ id: descriptionId,
2772
+ class: "j-radio-group__description"
2773
+ }, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
2774
+ createElementVNode("div", { class: normalizeClass(["j-radio-group__items", `j-radio-group__items--${__props.orientation}`]) }, [renderSlot(_ctx.$slots, "default")], 2),
2775
+ errorMessage.value ? (openBlock(), createElementBlock("p", {
2776
+ key: 2,
2777
+ id: errorId,
2778
+ class: "j-radio-group__error"
2779
+ }, toDisplayString(errorMessage.value), 1)) : createCommentVNode("", true)
2780
+ ], 10, _hoisted_1$9);
2236
2781
  };
2237
2782
  }
2238
2783
  });
2239
2784
  //#endregion
2240
2785
  //#region src/components/select/JSelect.vue?vue&type=script&setup=true&lang.ts
2241
- var _hoisted_1$5 = [
2786
+ var _hoisted_1$8 = [
2242
2787
  "id",
2243
2788
  "aria-expanded",
2244
2789
  "aria-controls",
@@ -2249,10 +2794,10 @@ var _hoisted_1$5 = [
2249
2794
  "aria-required",
2250
2795
  "disabled"
2251
2796
  ];
2252
- var _hoisted_2$3 = ["id"];
2253
- var _hoisted_3$3 = ["name", "value"];
2254
- var _hoisted_4$2 = ["id", "aria-labelledby"];
2255
- var _hoisted_5$2 = [
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 = [
2256
2801
  "id",
2257
2802
  "aria-selected",
2258
2803
  "aria-disabled",
@@ -2498,13 +3043,13 @@ var JSelect_default = /* @__PURE__ */ defineComponent({
2498
3043
  }), [createElementVNode("span", {
2499
3044
  id: valueId.value,
2500
3045
  class: normalizeClass(["j-select__value", { "is-placeholder": !selected.value }])
2501
- }, [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$3), createVNode(unref(IconChevronUpDown), { class: "j-select__chevron" })], 16, _hoisted_1$5),
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),
2502
3047
  __props.name ? (openBlock(), createElementBlock("input", {
2503
3048
  key: 0,
2504
3049
  type: "hidden",
2505
3050
  name: __props.name,
2506
3051
  value: model.value ?? ""
2507
- }, null, 8, _hoisted_3$3)) : createCommentVNode("", true),
3052
+ }, null, 8, _hoisted_3$4)) : createCommentVNode("", true),
2508
3053
  createVNode(JPortal_default, null, {
2509
3054
  default: withCtx(() => [createVNode(Transition, { name: "j-pop" }, {
2510
3055
  default: withCtx(() => [open.value ? (openBlock(), createElementBlock("ul", {
@@ -2535,8 +3080,8 @@ var JSelect_default = /* @__PURE__ */ defineComponent({
2535
3080
  option,
2536
3081
  selected: option.value === model.value,
2537
3082
  active: index === activeIndex.value
2538
- }, () => [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$2);
2539
- }), 128)), visibleOptions.value.length === 0 ? (openBlock(), createElementBlock("li", _hoisted_9, " No options ")) : createCommentVNode("", true)], 46, _hoisted_4$2)) : createCommentVNode("", true)]),
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)]),
2540
3085
  _: 3
2541
3086
  })]),
2542
3087
  _: 3
@@ -2565,6 +3110,233 @@ var JSelect_default = /* @__PURE__ */ defineComponent({
2565
3110
  }
2566
3111
  });
2567
3112
  //#endregion
3113
+ //#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 = {
3116
+ key: 0,
3117
+ class: "j-separator__label"
3118
+ };
3119
+ //#endregion
3120
+ //#region src/components/separator/JSeparator.vue
3121
+ var JSeparator_default = /* @__PURE__ */ defineComponent({
3122
+ __name: "JSeparator",
3123
+ props: {
3124
+ orientation: { default: "horizontal" },
3125
+ label: {},
3126
+ decorative: {
3127
+ type: Boolean,
3128
+ default: true
3129
+ }
3130
+ },
3131
+ setup(__props) {
3132
+ return (_ctx, _cache) => {
3133
+ return openBlock(), createElementBlock("div", {
3134
+ class: normalizeClass(["j-separator", [`j-separator--${__props.orientation}`, { "j-separator--labelled": __props.label || _ctx.$slots.default }]]),
3135
+ role: __props.decorative ? "none" : "separator",
3136
+ "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);
3138
+ };
3139
+ }
3140
+ });
3141
+ //#endregion
3142
+ //#region src/components/sheet/JSheet.vue?vue&type=script&setup=true&lang.ts
3143
+ var _hoisted_1$6 = {
3144
+ key: 0,
3145
+ class: "j-sheet__overlay",
3146
+ "aria-hidden": "true"
3147
+ };
3148
+ var _hoisted_2$4 = [
3149
+ "aria-labelledby",
3150
+ "aria-label",
3151
+ "aria-describedby"
3152
+ ];
3153
+ var _hoisted_3$3 = {
3154
+ key: 0,
3155
+ class: "j-sheet__header"
3156
+ };
3157
+ var _hoisted_4$2 = { class: "j-sheet__body" };
3158
+ var _hoisted_5$2 = {
3159
+ key: 1,
3160
+ class: "j-sheet__footer"
3161
+ };
3162
+ //#endregion
3163
+ //#region src/components/sheet/JSheet.vue
3164
+ var JSheet_default = /* @__PURE__ */ defineComponent({
3165
+ __name: "JSheet",
3166
+ props: /*@__PURE__*/ mergeModels({
3167
+ title: {},
3168
+ description: {},
3169
+ side: { default: "right" },
3170
+ size: { default: "md" },
3171
+ closeOnOverlay: {
3172
+ type: Boolean,
3173
+ default: true
3174
+ },
3175
+ closeOnEscape: {
3176
+ type: Boolean,
3177
+ default: true
3178
+ },
3179
+ hideClose: { type: Boolean },
3180
+ ariaLabel: {}
3181
+ }, {
3182
+ "open": {
3183
+ type: Boolean,
3184
+ default: false
3185
+ },
3186
+ "openModifiers": {}
3187
+ }),
3188
+ emits: /*@__PURE__*/ mergeModels(["afterClose"], ["update:open"]),
3189
+ setup(__props, { expose: __expose, emit: __emit }) {
3190
+ const props = __props;
3191
+ const open = useModel(__props, "open");
3192
+ const emit = __emit;
3193
+ const id = useId();
3194
+ const titleId = `j-${id}-title`;
3195
+ const descriptionId = `j-${id}-description`;
3196
+ const panel = ref(null);
3197
+ function close() {
3198
+ open.value = false;
3199
+ }
3200
+ const { nudging, onBackdropPointerDown, onBackdropClick } = useModal(panel, open, {
3201
+ closeOnEscape: () => props.closeOnEscape,
3202
+ closeOnOverlay: () => props.closeOnOverlay,
3203
+ close,
3204
+ focusSelector: `.j-sheet__body ${FIELD_SELECTOR}`
3205
+ });
3206
+ __expose({ close });
3207
+ return (_ctx, _cache) => {
3208
+ return openBlock(), createBlock(JPortal_default, null, {
3209
+ default: withCtx(() => [createVNode(Transition, { name: "j-sheet-overlay" }, {
3210
+ default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$6)) : createCommentVNode("", true)]),
3211
+ _: 1
3212
+ }), createVNode(Transition, {
3213
+ name: "j-sheet",
3214
+ duration: {
3215
+ enter: 280,
3216
+ leave: 180
3217
+ },
3218
+ onAfterLeave: _cache[3] || (_cache[3] = ($event) => emit("afterClose"))
3219
+ }, {
3220
+ default: withCtx(() => [open.value ? (openBlock(), createElementBlock("div", {
3221
+ key: 0,
3222
+ class: normalizeClass(["j-sheet__positioner", `j-sheet__positioner--${__props.side}`]),
3223
+ onPointerdown: _cache[1] || (_cache[1] = (...args) => unref(onBackdropPointerDown) && unref(onBackdropPointerDown)(...args)),
3224
+ onClick: _cache[2] || (_cache[2] = (...args) => unref(onBackdropClick) && unref(onBackdropClick)(...args))
3225
+ }, [createElementVNode("div", {
3226
+ ref_key: "panel",
3227
+ ref: panel,
3228
+ role: "dialog",
3229
+ "aria-modal": "true",
3230
+ tabindex: "-1",
3231
+ class: normalizeClass(["j-sheet", [
3232
+ `j-sheet--${__props.side}`,
3233
+ `j-sheet--${__props.size}`,
3234
+ { "is-nudging": unref(nudging) }
3235
+ ]]),
3236
+ "aria-labelledby": __props.title || _ctx.$slots.header ? titleId : void 0,
3237
+ "aria-label": __props.ariaLabel,
3238
+ "aria-describedby": __props.description ? descriptionId : void 0,
3239
+ onAnimationend: _cache[0] || (_cache[0] = ($event) => nudging.value = false)
3240
+ }, [
3241
+ __props.title || __props.description || _ctx.$slots.header ? (openBlock(), createElementBlock("header", _hoisted_3$3, [renderSlot(_ctx.$slots, "header", {
3242
+ titleId,
3243
+ descriptionId
3244
+ }, () => [createElementVNode("h2", {
3245
+ id: titleId,
3246
+ class: "j-sheet__title"
3247
+ }, toDisplayString(__props.title), 1), __props.description ? (openBlock(), createElementBlock("p", {
3248
+ key: 0,
3249
+ id: descriptionId,
3250
+ class: "j-sheet__description"
3251
+ }, 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),
3254
+ !__props.hideClose ? (openBlock(), createElementBlock("button", {
3255
+ key: 2,
3256
+ type: "button",
3257
+ class: "j-sheet__close j-focusable",
3258
+ "aria-label": "Close",
3259
+ onClick: close
3260
+ }, [createVNode(unref(IconX))])) : createCommentVNode("", true)
3261
+ ], 42, _hoisted_2$4)], 34)) : createCommentVNode("", true)]),
3262
+ _: 3
3263
+ })]),
3264
+ _: 3
3265
+ });
3266
+ };
3267
+ }
3268
+ });
3269
+ //#endregion
3270
+ //#region src/components/skeleton/JSkeleton.vue
3271
+ var JSkeleton_default = /* @__PURE__ */ defineComponent({
3272
+ __name: "JSkeleton",
3273
+ props: {
3274
+ shape: { default: "rect" },
3275
+ lines: { default: 1 },
3276
+ width: {},
3277
+ height: {}
3278
+ },
3279
+ setup(__props) {
3280
+ const props = __props;
3281
+ const style = computed(() => ({
3282
+ width: props.width,
3283
+ height: props.height
3284
+ }));
3285
+ return (_ctx, _cache) => {
3286
+ return __props.shape === "text" ? (openBlock(), createElementBlock("span", {
3287
+ key: 0,
3288
+ class: "j-skeleton-lines",
3289
+ style: normalizeStyle({ width: __props.width }),
3290
+ "aria-hidden": "true"
3291
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.lines, (i) => {
3292
+ return openBlock(), createElementBlock("span", {
3293
+ key: i,
3294
+ class: "j-skeleton j-skeleton--text",
3295
+ style: normalizeStyle({
3296
+ width: i === __props.lines && __props.lines > 1 ? "62%" : void 0,
3297
+ height: __props.height
3298
+ })
3299
+ }, null, 4);
3300
+ }), 128))], 4)) : (openBlock(), createElementBlock("span", {
3301
+ key: 1,
3302
+ class: normalizeClass(["j-skeleton", `j-skeleton--${__props.shape}`]),
3303
+ style: normalizeStyle(style.value),
3304
+ "aria-hidden": "true"
3305
+ }, null, 6));
3306
+ };
3307
+ }
3308
+ });
3309
+ //#endregion
3310
+ //#region src/components/spinner/JSpinner.vue?vue&type=script&setup=true&lang.ts
3311
+ var _hoisted_1$5 = ["role"];
3312
+ var _hoisted_2$3 = {
3313
+ key: 0,
3314
+ class: "j-sr-only"
3315
+ };
3316
+ //#endregion
3317
+ //#region src/components/spinner/JSpinner.vue
3318
+ var JSpinner_default = /* @__PURE__ */ defineComponent({
3319
+ __name: "JSpinner",
3320
+ props: {
3321
+ size: { default: "md" },
3322
+ label: { default: "Loading" }
3323
+ },
3324
+ setup(__props) {
3325
+ const props = __props;
3326
+ const pixels = computed(() => ({
3327
+ sm: 14,
3328
+ md: 16,
3329
+ lg: 20
3330
+ })[props.size]);
3331
+ return (_ctx, _cache) => {
3332
+ return openBlock(), createElementBlock("span", {
3333
+ class: "j-spinner-wrap",
3334
+ 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);
3336
+ };
3337
+ }
3338
+ });
3339
+ //#endregion
2568
3340
  //#region src/components/switch/JSwitch.vue?vue&type=script&setup=true&lang.ts
2569
3341
  var _hoisted_1$4 = ["data-state"];
2570
3342
  var _hoisted_2$2 = [
@@ -3403,6 +4175,9 @@ var JTooltip_default = /* @__PURE__ */ defineComponent({
3403
4175
  //#endregion
3404
4176
  //#region src/components.ts
3405
4177
  var components_exports = /* @__PURE__ */ __exportAll({
4178
+ JAccordion: () => JAccordion_default,
4179
+ JAccordionItem: () => JAccordionItem_default,
4180
+ JAlert: () => JAlert_default,
3406
4181
  JAvatar: () => JAvatar_default,
3407
4182
  JBadge: () => JBadge_default,
3408
4183
  JButton: () => JButton_default,
@@ -3416,7 +4191,16 @@ var components_exports = /* @__PURE__ */ __exportAll({
3416
4191
  JDropdownMenuSeparator: () => JDropdownMenuSeparator_default,
3417
4192
  JDropdownMenuSub: () => JDropdownMenuSub_default,
3418
4193
  JInput: () => JInput_default,
4194
+ JKbd: () => JKbd_default,
4195
+ JPopover: () => JPopover_default,
4196
+ JProgress: () => JProgress_default,
4197
+ JRadio: () => JRadio_default,
4198
+ JRadioGroup: () => JRadioGroup_default,
3419
4199
  JSelect: () => JSelect_default,
4200
+ JSeparator: () => JSeparator_default,
4201
+ JSheet: () => JSheet_default,
4202
+ JSkeleton: () => JSkeleton_default,
4203
+ JSpinner: () => JSpinner_default,
3420
4204
  JSwitch: () => JSwitch_default,
3421
4205
  JTabs: () => JTabs_default,
3422
4206
  JTextarea: () => JTextarea_default,
@@ -3481,6 +4265,6 @@ var JuxtUI = { install(app) {
3481
4265
  for (const [name, component] of Object.entries(components_exports)) app.component(name, component);
3482
4266
  } };
3483
4267
  //#endregion
3484
- export { 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, JSelect_default as JSelect, 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 };
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 };
3485
4269
 
3486
4270
  //# sourceMappingURL=index.js.map