@codbex/harmonia 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/harmonia.js CHANGED
@@ -143,10 +143,10 @@
143
143
  }) : { single: false };
144
144
  el.setAttribute("data-slot", "accordion");
145
145
  });
146
- Alpine.directive("h-accordion-item", (el, { expression, modifiers }, { effect, Alpine: Alpine2 }) => {
146
+ Alpine.directive("h-accordion-item", (el, { original, expression, modifiers }, { effect, Alpine: Alpine2 }) => {
147
147
  const accordion = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_accordion"));
148
148
  if (!accordion) {
149
- throw new Error("h-accordion-item must be inside an h-accordion");
149
+ throw new Error(`${original} must be inside an accordion`);
150
150
  }
151
151
  el.classList.add("border-b", "last:border-b-0", "[[data-variant=header]_&]:data-[state=closed]:border-b-0");
152
152
  el.setAttribute("data-slot", "accordion-item");
@@ -174,14 +174,14 @@
174
174
  setAttributes();
175
175
  effect(setAttributes);
176
176
  });
177
- Alpine.directive("h-accordion-trigger", (el, { expression }, { effect, evaluateLater, Alpine: Alpine2, cleanup }) => {
177
+ Alpine.directive("h-accordion-trigger", (el, { original, expression }, { effect, evaluateLater, Alpine: Alpine2, cleanup }) => {
178
178
  if (el.tagName.length !== 2 && !el.tagName.startsWith("H")) {
179
- throw new Error("h-accordion-trigger must be a header element");
179
+ throw new Error(`${original} must be a header element`);
180
180
  }
181
181
  const accordion = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_accordion"));
182
182
  const accordionItem = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_accordionItem"));
183
183
  if (!accordionItem || !accordion) {
184
- throw new Error("h-accordion-trigger must be inside an h-accordion-item, which must be inside an h-accordion");
184
+ throw new Error(`${original} must have an accordion and accordion item parent elements`);
185
185
  }
186
186
  el.classList.add(
187
187
  "flex",
@@ -222,7 +222,7 @@
222
222
  "transition-all",
223
223
  "outline-none",
224
224
  "hover:underline",
225
- "focus-visible:ring-[3px]",
225
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
226
226
  "disabled:pointer-events-none",
227
227
  "disabled:opacity-50",
228
228
  "[&[data-state=open]>svg]:rotate-180"
@@ -240,7 +240,7 @@
240
240
  button.setAttribute("data-state", accordionItem._h_accordionItem.expanded ? "open" : "closed");
241
241
  button.setAttribute("aria-expanded", accordionItem._h_accordionItem.expanded);
242
242
  };
243
- const handler2 = () => {
243
+ const handler = () => {
244
244
  accordionItem._h_accordionItem.expanded = !accordionItem._h_accordionItem.expanded;
245
245
  setAttributes();
246
246
  if (accordion._h_accordion.single) {
@@ -248,9 +248,9 @@
248
248
  }
249
249
  };
250
250
  setAttributes();
251
- el.addEventListener("click", handler2);
251
+ el.addEventListener("click", handler);
252
252
  cleanup(() => {
253
- el.removeEventListener("click", handler2);
253
+ el.removeEventListener("click", handler);
254
254
  });
255
255
  if (accordion._h_accordion.single) {
256
256
  effect(() => {
@@ -261,7 +261,7 @@
261
261
  });
262
262
  }
263
263
  });
264
- Alpine.directive("h-accordion-content", (el, {}, { effect, Alpine: Alpine2 }) => {
264
+ Alpine.directive("h-accordion-content", (el, _, { effect, Alpine: Alpine2 }) => {
265
265
  el.classList.add("pt-0", "pb-4", "overflow-hidden", "text-sm", "data-[state=closed]:hidden");
266
266
  el.setAttribute("data-slot", "accordion-content");
267
267
  const parent = Alpine2.findClosest(el.parentElement, (parent2) => parent2.hasOwnProperty("_h_accordionItem"));
@@ -314,10 +314,8 @@
314
314
  if (variants.hasOwnProperty(variant)) el.classList.add(...variants[variant]);
315
315
  }
316
316
  setVariant(el.getAttribute("data-variant") ?? "default");
317
- const observer = new MutationObserver((mutations) => {
318
- mutations.forEach(() => {
319
- setVariant(el.getAttribute("data-variant") ?? "default");
320
- });
317
+ const observer = new MutationObserver(() => {
318
+ setVariant(el.getAttribute("data-variant") ?? "default");
321
319
  });
322
320
  observer.observe(el, { attributes: true, attributeFilter: ["data-variant"] });
323
321
  cleanup(() => {
@@ -340,7 +338,7 @@
340
338
 
341
339
  // src/components/avatar.js
342
340
  function avatar_default(Alpine) {
343
- Alpine.directive("h-avatar", (el, {}, { Alpine: Alpine2 }) => {
341
+ Alpine.directive("h-avatar", (el, _, { Alpine: Alpine2 }) => {
344
342
  el.classList.add(
345
343
  "relative",
346
344
  "bg-secondary",
@@ -367,10 +365,10 @@
367
365
  el.classList.add("cursor-pointer", "hover:bg-secondary-hover", "active:bg-secondary-active");
368
366
  }
369
367
  });
370
- Alpine.directive("h-avatar-image", (el, {}, { cleanup }) => {
368
+ Alpine.directive("h-avatar-image", (el, { original }, { cleanup }) => {
371
369
  const avatar = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_avatar"));
372
370
  if (!avatar) {
373
- throw new Error("h-avatar-image must be inside an h-avatar element");
371
+ throw new Error(`${original} must be inside an h-avatar element`);
374
372
  }
375
373
  el.classList.add("aspect-square", "size-full");
376
374
  el.setAttribute("data-slot", "avatar-image");
@@ -392,10 +390,8 @@
392
390
  } else {
393
391
  interval = setInterval(completeCheck, 10);
394
392
  }
395
- const observer = new MutationObserver((mutations) => {
396
- mutations.forEach(() => {
397
- interval = setInterval(completeCheck, 10);
398
- });
393
+ const observer = new MutationObserver(() => {
394
+ interval = setInterval(completeCheck, 10);
399
395
  });
400
396
  observer.observe(el, { attributes: true, attributeFilter: ["src"] });
401
397
  cleanup(() => {
@@ -403,10 +399,10 @@
403
399
  observer.disconnect();
404
400
  });
405
401
  });
406
- Alpine.directive("h-avatar-fallback", (el, {}, { effect }) => {
402
+ Alpine.directive("h-avatar-fallback", (el, { original }, { effect }) => {
407
403
  const avatar = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_avatar"));
408
404
  if (!avatar) {
409
- throw new Error("h-avatar-fallback must be inside an h-avatar element");
405
+ throw new Error(`${original} must be inside an h-avatar element`);
410
406
  }
411
407
  el.classList.add("hidden", "bg-muted", "flex", "size-full", "items-center", "justify-center");
412
408
  el.setAttribute("data-slot", "avatar-fallback");
@@ -419,7 +415,7 @@
419
415
 
420
416
  // src/components/badge.js
421
417
  function badge_default(Alpine) {
422
- Alpine.directive("h-badge", (el, {}, { cleanup }) => {
418
+ Alpine.directive("h-badge", (el, _, { cleanup }) => {
423
419
  el.classList.add(
424
420
  "[a&]:cursor-pointer",
425
421
  "inline-flex",
@@ -439,7 +435,7 @@
439
435
  "[&>svg]:pointer-events-none",
440
436
  "focus-visible:border-ring",
441
437
  "focus-visible:ring-ring/50",
442
- "focus-visible:ring-[3px]",
438
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
443
439
  "transition-[color,box-shadow]",
444
440
  "overflow-hidden"
445
441
  );
@@ -454,16 +450,14 @@
454
450
  outline: ["bg-transparent", "text-foreground", "[a&]:hover:bg-secondary", "[a&]:hover:text-secondary-foreground", "[a&]:active:bg-secondary-active"]
455
451
  };
456
452
  function setVariant(variant) {
457
- for (const [_, value] of Object.entries(variants)) {
453
+ for (const [_2, value] of Object.entries(variants)) {
458
454
  el.classList.remove(...value);
459
455
  }
460
456
  if (variants.hasOwnProperty(variant)) el.classList.add(...variants[variant]);
461
457
  }
462
458
  setVariant(el.getAttribute("data-variant") ?? "default");
463
- const observer = new MutationObserver((mutations) => {
464
- mutations.forEach(() => {
465
- setVariant(el.getAttribute("data-variant") ?? "default");
466
- });
459
+ const observer = new MutationObserver(() => {
460
+ setVariant(el.getAttribute("data-variant") ?? "default");
467
461
  });
468
462
  observer.observe(el, { attributes: true, attributeFilter: ["data-variant"] });
469
463
  cleanup(() => {
@@ -489,6 +483,7 @@
489
483
  "bg-primary",
490
484
  "text-primary-foreground",
491
485
  "shadow-button",
486
+ "focus-visible:outline-primary/50",
492
487
  "hover:bg-primary-hover",
493
488
  "active:bg-primary-active",
494
489
  "aria-pressed:bg-primary-active",
@@ -500,6 +495,7 @@
500
495
  "bg-positive",
501
496
  "text-positive-foreground",
502
497
  "shadow-button",
498
+ "focus-visible:outline-positive/50",
503
499
  "hover:bg-positive-hover",
504
500
  "active:bg-positive-active",
505
501
  "aria-pressed:bg-positive-active",
@@ -511,6 +507,7 @@
511
507
  "bg-negative",
512
508
  "text-negative-foreground",
513
509
  "shadow-button",
510
+ "focus-visible:outline-negative/50",
514
511
  "hover:bg-negative-hover",
515
512
  "active:bg-negative-active",
516
513
  "aria-pressed:bg-negative-active",
@@ -522,6 +519,7 @@
522
519
  "bg-warning",
523
520
  "text-warning-foreground",
524
521
  "shadow-button",
522
+ "focus-visible:outline-warning/50",
525
523
  "hover:bg-warning-hover",
526
524
  "active:bg-warning-active",
527
525
  "aria-pressed:bg-warning-active",
@@ -529,6 +527,18 @@
529
527
  "hover:data-[toggled=true]:bg-warning-hover",
530
528
  "data-[toggled=true]:bg-warning-active"
531
529
  ],
530
+ information: [
531
+ "bg-information",
532
+ "text-information-foreground",
533
+ "shadow-button",
534
+ "focus-visible:outline-information/50",
535
+ "hover:bg-information-hover",
536
+ "active:bg-information-active",
537
+ "aria-pressed:bg-information-active",
538
+ "active:data-[toggled=true]:bg-information-active",
539
+ "hover:data-[toggled=true]:bg-information-hover",
540
+ "data-[toggled=true]:bg-information-active"
541
+ ],
532
542
  outline: [
533
543
  "border",
534
544
  "bg-background",
@@ -573,10 +583,9 @@
573
583
  "[&_svg:not([class*='size-'])]:size-4",
574
584
  "shrink-0",
575
585
  "[&_svg]:shrink-0",
576
- "outline-none",
577
- "focus-visible:border-ring",
578
- "focus-visible:ring-ring/50",
579
- "focus-visible:ring-[3px]",
586
+ "outline-ring/50",
587
+ "focus-visible:outline-[calc(var(--spacing)*0.75)]",
588
+ "focus-visible:outline",
580
589
  "aria-invalid:ring-negative/20",
581
590
  "dark:aria-invalid:ring-negative/40",
582
591
  "aria-invalid:border-negative",
@@ -606,7 +615,7 @@
606
615
  }
607
616
  };
608
617
  function button_default(Alpine) {
609
- Alpine.directive("h-button", (el, { modifiers }, { cleanup }) => {
618
+ Alpine.directive("h-button", (el, { original, modifiers }, { cleanup }) => {
610
619
  setButtonClasses(el);
611
620
  if (!el.hasAttribute("data-slot")) {
612
621
  el.setAttribute("data-slot", "button");
@@ -623,7 +632,7 @@
623
632
  el.classList.remove(...getButtonSize(lastSize, inGroup));
624
633
  el.classList.add(...getButtonSize(size3, inGroup));
625
634
  if (size3.startsWith("icon") && !el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
626
- console.error('h-button: Icon-only buttons must have an "aria-label" or "aria-labelledby" attribute', el);
635
+ console.error(`${original}: Icon-only buttons must have an "aria-label" or "aria-labelledby" attribute`, el);
627
636
  }
628
637
  lastSize = size3;
629
638
  }
@@ -2167,7 +2176,7 @@
2167
2176
 
2168
2177
  // src/components/calendar.js
2169
2178
  function calendar_default(Alpine) {
2170
- Alpine.directive("h-calendar", (el, { expression }, { effect, evaluateLater, cleanup, Alpine: Alpine2 }) => {
2179
+ Alpine.directive("h-calendar", (el, { original, expression }, { effect, evaluateLater, cleanup, Alpine: Alpine2 }) => {
2171
2180
  const datepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_datepicker"));
2172
2181
  el.classList.add("border", "rounded-control", "gap-2", "p-2");
2173
2182
  el.setAttribute("tabindex", "-1");
@@ -2211,7 +2220,7 @@
2211
2220
  const onInputChange = () => {
2212
2221
  const newValue = new Date(datepicker._h_datepicker.input.value);
2213
2222
  if (isNaN(newValue)) {
2214
- console.error(`h-calendar: input value is not a valid date - ${datepicker._h_datepicker.input.value}`);
2223
+ console.error(`${original}: input value is not a valid date - ${datepicker._h_datepicker.input.value}`);
2215
2224
  datepicker._h_datepicker.input.setCustomValidity("Input value is not a valid date.");
2216
2225
  return;
2217
2226
  } else if (selected.getTime() !== newValue.getTime()) {
@@ -2228,7 +2237,7 @@
2228
2237
  if (el.hasOwnProperty("_x_model") && el._x_model.get()) {
2229
2238
  selected = new Date(el._x_model.get());
2230
2239
  if (isNaN(selected)) {
2231
- console.error(`h-calendar: input value is not a valid date - ${el._x_model.get()}`);
2240
+ console.error(`${original}: input value is not a valid date - ${el._x_model.get()}`);
2232
2241
  if (datepicker) datepicker._h_datepicker.input.setCustomValidity("Input value is not a valid date.");
2233
2242
  else el.setAttribute("data-invalid", "true");
2234
2243
  } else if (datepicker) {
@@ -2283,7 +2292,7 @@
2283
2292
  "outline-none",
2284
2293
  "focus-visible:border-ring",
2285
2294
  "focus-visible:ring-ring/50",
2286
- "focus-visible:ring-[3px]",
2295
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
2287
2296
  "bg-transparent",
2288
2297
  "text-foreground",
2289
2298
  "hover:bg-secondary",
@@ -2510,35 +2519,49 @@
2510
2519
  if (!focusedDay) focusedDay = selected || new Date(date.getFullYear(), date.getMonth(), 1);
2511
2520
  let newDay = new Date(focusedDay);
2512
2521
  switch (event.key) {
2522
+ case "Left":
2513
2523
  case "ArrowLeft":
2524
+ event.preventDefault();
2514
2525
  newDay.setDate(newDay.getDate() - 1);
2515
2526
  break;
2527
+ case "Right":
2516
2528
  case "ArrowRight":
2529
+ event.preventDefault();
2517
2530
  newDay.setDate(newDay.getDate() + 1);
2518
2531
  break;
2532
+ case "Up":
2519
2533
  case "ArrowUp":
2534
+ event.preventDefault();
2520
2535
  newDay.setDate(newDay.getDate() - 7);
2521
2536
  break;
2537
+ case "Down":
2522
2538
  case "ArrowDown":
2539
+ event.preventDefault();
2523
2540
  newDay.setDate(newDay.getDate() + 7);
2524
2541
  break;
2525
2542
  case "Home":
2543
+ event.preventDefault();
2526
2544
  newDay.setDate(1);
2527
2545
  break;
2528
2546
  case "End":
2547
+ event.preventDefault();
2529
2548
  newDay.setDate(end.getDate());
2530
2549
  break;
2531
2550
  case "PageUp":
2551
+ event.preventDefault();
2532
2552
  newDay.setMonth(newDay.getMonth() - 1);
2533
2553
  break;
2534
2554
  case "PageDown":
2555
+ event.preventDefault();
2535
2556
  newDay.setMonth(newDay.getMonth() + 1);
2536
2557
  break;
2537
2558
  case "Escape":
2559
+ event.preventDefault();
2538
2560
  if (datepicker) datepicker._h_datepicker.expanded = false;
2539
2561
  return;
2540
2562
  case "Enter":
2541
2563
  case " ":
2564
+ event.preventDefault();
2542
2565
  if (!isDisabled(focusedDay)) {
2543
2566
  selected = new Date(focusedDay);
2544
2567
  modelChange();
@@ -2668,11 +2691,11 @@
2668
2691
  "[&>input]:border-0",
2669
2692
  "[&>input]:cursor-pointer",
2670
2693
  "[&>input]:focus-visible:border-ring",
2671
- "[&>input]:focus-visible:ring-[3px]",
2694
+ "[&>input]:focus-visible:ring-[calc(var(--spacing)*0.75)]",
2672
2695
  "[&>input]:focus-visible:ring-ring/50",
2673
2696
  "[&>input]:left-0",
2674
2697
  "[&>input]:outline-none",
2675
- "[&>input]:rounded-[0.25rem]",
2698
+ "[&>input]:rounded-[0.438rem]",
2676
2699
  "[&>input]:size-full",
2677
2700
  "[&>input]:top-0",
2678
2701
  "aspect-square",
@@ -2704,7 +2727,7 @@
2704
2727
  "has-[input:invalid]:border-negative",
2705
2728
  "has-[input:invalid]:ring-negative/20",
2706
2729
  "relative",
2707
- "rounded-[0.25rem]",
2730
+ "rounded-[0.438rem]",
2708
2731
  "shadow-input",
2709
2732
  "shrink-0",
2710
2733
  "size-5",
@@ -2731,10 +2754,10 @@
2731
2754
  });
2732
2755
  }
2733
2756
  });
2734
- Alpine.directive("h-collapsible-trigger", (el, { modifiers }, { effect, Alpine: Alpine2, cleanup }) => {
2757
+ Alpine.directive("h-collapsible-trigger", (el, { original, modifiers }, { effect, Alpine: Alpine2, cleanup }) => {
2735
2758
  const collapsible = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_collapsible"));
2736
2759
  if (!collapsible) {
2737
- throw new Error("h-collapsible-trigger must be inside an h-collapsible element");
2760
+ throw new Error(`${original} must be inside a collapsible element`);
2738
2761
  }
2739
2762
  if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "collapsible-trigger");
2740
2763
  if (modifiers.includes("chevron")) {
@@ -2742,21 +2765,21 @@
2742
2765
  if (modifiers.includes("90")) el.classList.add("[&[data-state=open]>svg:not(:first-child):last-child]:rotate-90", "[&[data-state=open]>svg:only-child]:rotate-90");
2743
2766
  else el.classList.add("[&[data-state=open]>svg:not(:first-child):last-child]:rotate-180", "[&[data-state=open]>svg:only-child]:rotate-180");
2744
2767
  }
2745
- const handler2 = () => {
2768
+ const handler = () => {
2746
2769
  collapsible._h_collapsible.expanded = !collapsible._h_collapsible.expanded;
2747
2770
  };
2748
2771
  effect(() => {
2749
2772
  el.setAttribute("data-state", collapsible._h_collapsible.expanded ? "open" : "closed");
2750
2773
  });
2751
- el.addEventListener("click", handler2);
2774
+ el.addEventListener("click", handler);
2752
2775
  cleanup(() => {
2753
- el.removeEventListener("click", handler2);
2776
+ el.removeEventListener("click", handler);
2754
2777
  });
2755
2778
  });
2756
- Alpine.directive("h-collapsible-content", (el, {}, { effect, Alpine: Alpine2 }) => {
2779
+ Alpine.directive("h-collapsible-content", (el, { original }, { effect, Alpine: Alpine2 }) => {
2757
2780
  const collapsible = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_collapsible"));
2758
2781
  if (!collapsible) {
2759
- throw new Error("h-collapsible-content must be inside an h-collapsible element");
2782
+ throw new Error(`${original} must be inside an h-collapsible element`);
2760
2783
  }
2761
2784
  if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "collapsible-content");
2762
2785
  el.classList.add("data-[state=closed]:!hidden");
@@ -2768,7 +2791,7 @@
2768
2791
 
2769
2792
  // src/components/datepicker.js
2770
2793
  function datepicker_default(Alpine) {
2771
- Alpine.directive("h-date-picker", (el, {}, { Alpine: Alpine2 }) => {
2794
+ Alpine.directive("h-date-picker", (el, { original }, { Alpine: Alpine2 }) => {
2772
2795
  el._h_datepicker = Alpine2.reactive({
2773
2796
  id: void 0,
2774
2797
  controls: `hdpc${v4_default()}`,
@@ -2777,7 +2800,7 @@
2777
2800
  });
2778
2801
  el._h_datepicker.input = el.querySelector("input");
2779
2802
  if (!el._h_datepicker.input || el._h_datepicker.input.tagName !== "INPUT") {
2780
- throw new Error("h-date-picker must have an input inside it");
2803
+ throw new Error(`${original} must contain an input`);
2781
2804
  } else if (el._h_datepicker.input.hasAttribute("id")) {
2782
2805
  el._h_datepicker.id = el._h_datepicker.input.getAttribute("id");
2783
2806
  } else {
@@ -2804,7 +2827,7 @@
2804
2827
  "min-w-0",
2805
2828
  "has-[input:focus-visible]:border-ring",
2806
2829
  "has-[input:focus-visible]:ring-ring/50",
2807
- "has-[input:focus-visible]:ring-[3px]",
2830
+ "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
2808
2831
  "has-[input[aria-invalid=true]]:ring-negative/20",
2809
2832
  "has-[input[aria-invalid=true]]:border-negative",
2810
2833
  "dark:has-[input[aria-invalid=true]]:ring-negative/40",
@@ -2817,16 +2840,16 @@
2817
2840
  el._h_datepicker.input.setAttribute("aria-autocomplete", "none");
2818
2841
  el._h_datepicker.input.setAttribute("type", "text");
2819
2842
  });
2820
- Alpine.directive("h-date-picker-trigger", (el, {}, { effect, cleanup, Alpine: Alpine2 }) => {
2843
+ Alpine.directive("h-date-picker-trigger", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
2821
2844
  if (el.tagName !== "BUTTON") {
2822
- throw new Error("h-date-picker-trigger must be a button");
2845
+ throw new Error(`${original} must be a button`);
2823
2846
  }
2824
2847
  if (!el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
2825
- throw new Error('h-date-picker-trigger: must have an "aria-label" or "aria-labelledby" attribute');
2848
+ throw new Error(`${original}: must have an "aria-label" or "aria-labelledby" attribute`);
2826
2849
  }
2827
2850
  const datepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_datepicker"));
2828
2851
  if (!datepicker) {
2829
- throw new Error("h-date-picker-trigger must be inside an h-date-picker element");
2852
+ throw new Error(`${original} must be inside an date-picker element`);
2830
2853
  }
2831
2854
  el.setAttribute("aria-controls", datepicker._h_datepicker.controls);
2832
2855
  el.setAttribute("aria-expanded", "false");
@@ -2849,7 +2872,7 @@
2849
2872
  const close = () => {
2850
2873
  datepicker._h_datepicker.expanded = false;
2851
2874
  };
2852
- const handler2 = () => {
2875
+ const handler = () => {
2853
2876
  datepicker._h_datepicker.expanded = !datepicker._h_datepicker.expanded;
2854
2877
  el.setAttribute("aria-expanded", datepicker._h_datepicker.expanded);
2855
2878
  Alpine2.nextTick(() => {
@@ -2860,9 +2883,9 @@
2860
2883
  }
2861
2884
  });
2862
2885
  };
2863
- el.addEventListener("click", handler2);
2886
+ el.addEventListener("click", handler);
2864
2887
  cleanup(() => {
2865
- el.removeEventListener("click", handler2);
2888
+ el.removeEventListener("click", handler);
2866
2889
  top.removeEventListener("click", close);
2867
2890
  });
2868
2891
  }).before("h-button");
@@ -2870,42 +2893,40 @@
2870
2893
 
2871
2894
  // src/components/dialog.js
2872
2895
  function dialog_default(Alpine) {
2873
- Alpine.directive("h-dialog-overlay", (el, {}, { cleanup }) => {
2896
+ Alpine.directive("h-dialog-overlay", (el, _, { cleanup }) => {
2874
2897
  el.classList.add("hidden", "data-[open=true]:block", "fixed", "inset-0", "z-50", "bg-black/60");
2875
2898
  el.setAttribute("tabindex", "-1");
2876
2899
  el.setAttribute("data-slot", "dialog-overlay");
2877
- const observer = new MutationObserver((mutations) => {
2878
- mutations.forEach(() => {
2879
- if (el.getAttribute("data-open") === "true") {
2880
- const inputs = el.getElementsByTagName("INPUT");
2881
- if (inputs.length) {
2882
- for (let i = 0; i < inputs.length; i++) {
2883
- if (inputs[i].autofocus) {
2884
- inputs[i].focus();
2900
+ const observer = new MutationObserver(() => {
2901
+ if (el.getAttribute("data-open") === "true") {
2902
+ const inputs = el.getElementsByTagName("INPUT");
2903
+ if (inputs.length) {
2904
+ for (let i = 0; i < inputs.length; i++) {
2905
+ if (inputs[i].autofocus) {
2906
+ inputs[i].focus();
2907
+ return;
2908
+ }
2909
+ }
2910
+ inputs[0].focus();
2911
+ return;
2912
+ } else {
2913
+ const textareas = el.getElementsByTagName("TEXTAREA");
2914
+ if (textareas.length) {
2915
+ for (let i = 0; i < textareas.length; i++) {
2916
+ if (textareas[i].autofocus) {
2917
+ textareas[i].focus();
2885
2918
  return;
2886
2919
  }
2887
2920
  }
2888
- inputs[0].focus();
2921
+ textareas[0].focus();
2889
2922
  return;
2890
- } else {
2891
- const textareas = el.getElementsByTagName("TEXTAREA");
2892
- if (textareas.length) {
2893
- for (let i = 0; i < textareas.length; i++) {
2894
- if (textareas[i].autofocus) {
2895
- textareas[i].focus();
2896
- return;
2897
- }
2898
- }
2899
- textareas[0].focus();
2900
- return;
2901
- }
2902
- }
2903
- const buttons = el.getElementsByTagName("BUTTON");
2904
- if (buttons.length) {
2905
- buttons[0].focus();
2906
2923
  }
2907
2924
  }
2908
- });
2925
+ const buttons = el.getElementsByTagName("BUTTON");
2926
+ if (buttons.length) {
2927
+ buttons[0].focus();
2928
+ }
2929
+ }
2909
2930
  });
2910
2931
  observer.observe(el, { attributes: true, attributeFilter: ["data-open"] });
2911
2932
  cleanup(() => {
@@ -2941,7 +2962,7 @@
2941
2962
  el.classList.add("grid", "grid-cols-[1fr_auto]", "place-items-start", "gap-2", "text-center", "sm:text-left");
2942
2963
  el.setAttribute("data-slot", "dialog-header");
2943
2964
  });
2944
- Alpine.directive("h-dialog-title", (el, {}, { Alpine: Alpine2 }) => {
2965
+ Alpine.directive("h-dialog-title", (el, _, { Alpine: Alpine2 }) => {
2945
2966
  el.classList.add("text-lg", "leading-none", "font-semibold");
2946
2967
  el.setAttribute("data-slot", "dialog-title");
2947
2968
  const dialog = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "dialog");
@@ -2971,7 +2992,7 @@
2971
2992
  );
2972
2993
  el.setAttribute("data-slot", "dialog-close");
2973
2994
  });
2974
- Alpine.directive("h-dialog-description", (el, {}, { Alpine: Alpine2 }) => {
2995
+ Alpine.directive("h-dialog-description", (el, _, { Alpine: Alpine2 }) => {
2975
2996
  el.classList.add("col-span-full", "text-muted-foreground", "text-sm");
2976
2997
  el.setAttribute("data-slot", "dialog-description");
2977
2998
  const dialog = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "dialog");
@@ -3060,13 +3081,13 @@
3060
3081
 
3061
3082
  // src/components/icon.js
3062
3083
  function icon_default(Alpine) {
3063
- Alpine.directive("h-icon", (el) => {
3084
+ Alpine.directive("h-icon", (el, { original }) => {
3064
3085
  if (el.tagName.toLowerCase() !== "svg") {
3065
- throw new Error("h-icon works only on svg elements");
3086
+ throw new Error(`${original} works only on svg elements`);
3066
3087
  } else if (!el.hasAttribute("role")) {
3067
- throw new Error("h-icon must have a role");
3088
+ throw new Error(`${original} must have a role`);
3068
3089
  } else if (el.getAttribute("role") === "img" && !el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
3069
- throw new Error('h-icon: svg images with the role of img must have an "aria-label" or "aria-labelledby" attribute');
3090
+ throw new Error(`${original}: svg images with the role of img must have an "aria-label" or "aria-labelledby" attribute`);
3070
3091
  }
3071
3092
  el.classList.add("fill-current");
3072
3093
  el.setAttribute("data-slot", "icon");
@@ -3155,7 +3176,7 @@
3155
3176
  "md:text-sm",
3156
3177
  "focus-visible:border-ring",
3157
3178
  "focus-visible:ring-ring/50",
3158
- "focus-visible:ring-[3px]",
3179
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
3159
3180
  "aria-invalid:ring-negative/20",
3160
3181
  "dark:aria-invalid:ring-negative/40",
3161
3182
  "aria-invalid:border-negative",
@@ -3164,7 +3185,7 @@
3164
3185
  "invalid:!border-negative"
3165
3186
  );
3166
3187
  if (modifiers.includes("group")) {
3167
- el.classList.remove("rounded-control", "border", "bg-input-inner", "shadow-input", "focus-visible:ring-[3px]");
3188
+ el.classList.remove("rounded-control", "border", "bg-input-inner", "shadow-input", "focus-visible:ring-[calc(var(--spacing)*0.75)]");
3168
3189
  el.classList.add("flex-1", "rounded-none", "border-0", "bg-transparent", "shadow-none", "focus-visible:ring-0");
3169
3190
  el.setAttribute("data-slot", "input-group-control");
3170
3191
  } else el.setAttribute("data-slot", "input");
@@ -3199,7 +3220,7 @@
3199
3220
  "has-[>[data-align=block-end]]:[&>input]:pt-3",
3200
3221
  "has-[[data-slot=input-group-control]:focus-visible]:border-ring",
3201
3222
  "has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50",
3202
- "has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]",
3223
+ "has-[[data-slot=input-group-control]:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
3203
3224
  "has-[[data-slot][aria-invalid=true]]:ring-negative/20",
3204
3225
  "has-[[data-slot][aria-invalid=true]]:border-negative",
3205
3226
  "dark:has-[[data-slot][aria-invalid=true]]:ring-negative/40"
@@ -3207,7 +3228,7 @@
3207
3228
  el.setAttribute("role", "group");
3208
3229
  el.setAttribute("data-slot", "input-group");
3209
3230
  });
3210
- Alpine.directive("h-input-group-addon", (el, {}, { cleanup }) => {
3231
+ Alpine.directive("h-input-group-addon", (el, _, { cleanup }) => {
3211
3232
  el.classList.add(
3212
3233
  "text-muted-foreground",
3213
3234
  "flex",
@@ -3237,7 +3258,7 @@
3237
3258
  if (variants.hasOwnProperty(variant)) el.classList.add(...variants[variant]);
3238
3259
  }
3239
3260
  setVariant(el.getAttribute("data-align") ?? "inline-start");
3240
- const handler2 = (event) => {
3261
+ const handler = (event) => {
3241
3262
  if (event.target.closest("button")) {
3242
3263
  return;
3243
3264
  }
@@ -3245,9 +3266,9 @@
3245
3266
  if (!input) input = event.currentTarget.parentElement?.querySelector("textarea");
3246
3267
  input?.focus();
3247
3268
  };
3248
- el.addEventListener("click", handler2);
3269
+ el.addEventListener("click", handler);
3249
3270
  cleanup(() => {
3250
- el.removeEventListener("click", handler2);
3271
+ el.removeEventListener("click", handler);
3251
3272
  });
3252
3273
  });
3253
3274
  Alpine.directive("h-input-group-text", (el) => {
@@ -3294,7 +3315,7 @@
3294
3315
 
3295
3316
  // src/components/list.js
3296
3317
  function list_default(Alpine) {
3297
- Alpine.directive("h-listbox", (el, {}, { cleanup }) => {
3318
+ Alpine.directive("h-listbox", (el, _, { cleanup }) => {
3298
3319
  el.classList.add(
3299
3320
  "divide-solid",
3300
3321
  "divide-y",
@@ -3309,7 +3330,7 @@
3309
3330
  "disabled:opacity-50",
3310
3331
  "focus-visible:border-ring",
3311
3332
  "focus-visible:ring-ring/50",
3312
- "focus-visible:ring-[3px]",
3333
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
3313
3334
  "aria-invalid:ring-negative/20",
3314
3335
  "dark:aria-invalid:ring-negative/40",
3315
3336
  "aria-invalid:border-negative",
@@ -3348,6 +3369,7 @@
3348
3369
  case "End":
3349
3370
  focusLastOption(el);
3350
3371
  break;
3372
+ case "Up":
3351
3373
  case "ArrowUp":
3352
3374
  let prevElem = event.target.previousElementSibling;
3353
3375
  if (prevElem && prevElem.getAttribute("data-slot") !== "list-header") {
@@ -3359,6 +3381,7 @@
3359
3381
  }
3360
3382
  }
3361
3383
  break;
3384
+ case "Down":
3362
3385
  case "ArrowDown":
3363
3386
  let nextElem = event.target.nextElementSibling;
3364
3387
  if (nextElem) {
@@ -3378,14 +3401,14 @@
3378
3401
  break;
3379
3402
  }
3380
3403
  }
3381
- function onClick(event) {
3404
+ function onClick2(event) {
3382
3405
  if (event.target.getAttribute("data-slot") === "list-item") selectOption(event.target);
3383
3406
  }
3384
- el.addEventListener("click", onClick);
3407
+ el.addEventListener("click", onClick2);
3385
3408
  el.addEventListener("keydown", onKeyDown);
3386
3409
  cleanup(() => {
3387
3410
  el.removeEventListener("keydown", onKeyDown);
3388
- el.removeEventListener("click", onClick);
3411
+ el.removeEventListener("click", onClick2);
3389
3412
  });
3390
3413
  });
3391
3414
  Alpine.directive("h-list", (el) => {
@@ -3393,13 +3416,13 @@
3393
3416
  el.setAttribute("data-slot", "list");
3394
3417
  el.setAttribute("role", "group");
3395
3418
  });
3396
- Alpine.directive("h-list-header", (el, {}, { Alpine: Alpine2 }) => {
3419
+ Alpine.directive("h-list-header", (el, { original }, { Alpine: Alpine2 }) => {
3397
3420
  el.classList.add("font-medium", "flex", "items-center", "p-2", "gap-2", "align-middle", "bg-table-header", "text-table-header-foreground");
3398
3421
  el.setAttribute("role", "presentation");
3399
3422
  el.setAttribute("data-slot", "list-header");
3400
3423
  const list = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "list");
3401
3424
  if (!list) {
3402
- throw new Error("h-list-header: must be placed inside an h-list element");
3425
+ throw new Error(`${original} must be placed inside a list element`);
3403
3426
  }
3404
3427
  if (!el.hasAttribute("id")) {
3405
3428
  const id = `lbh${v4_default()}`;
@@ -3447,14 +3470,14 @@
3447
3470
  isDropdown: modifiers.includes("dropdown")
3448
3471
  };
3449
3472
  });
3450
- Alpine.directive("h-menu", (el, { modifiers }, { cleanup, Alpine: Alpine2 }) => {
3473
+ Alpine.directive("h-menu", (el, { original, modifiers }, { cleanup, Alpine: Alpine2 }) => {
3451
3474
  el.classList.add("hidden", "fixed", "bg-popover", "text-popover-foreground", "font-normal", "z-50", "min-w-[8rem]", "overflow-x-hidden", "overflow-y-auto", "rounded-md", "p-1", "shadow-md", "border", "outline-none");
3452
3475
  el.setAttribute("role", "menu");
3453
3476
  el.setAttribute("aria-orientation", "vertical");
3454
3477
  el.setAttribute("tabindex", "-1");
3455
3478
  el.setAttribute("data-slot", "menu");
3456
3479
  if (!el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
3457
- throw new Error('h-menu: must have an "aria-label" or "aria-labelledby" attribute');
3480
+ throw new Error(`${original} must have an "aria-label" or "aria-labelledby" attribute`);
3458
3481
  }
3459
3482
  const isSubmenu = modifiers.includes("sub");
3460
3483
  const menuTrigger = (() => {
@@ -3466,7 +3489,7 @@
3466
3489
  return sibling;
3467
3490
  })();
3468
3491
  if (!isSubmenu && !menuTrigger) {
3469
- throw new Error("h-menu: menu must be placed after an h-menu-trigger element");
3492
+ throw new Error(`${original} menu must be placed after a menu trigger element`);
3470
3493
  }
3471
3494
  let menuSubItem;
3472
3495
  if (isSubmenu) menuSubItem = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "menu-sub");
@@ -3479,22 +3502,23 @@
3479
3502
  else menuTrigger.removeEventListener("contextmenu", onContextmenu);
3480
3503
  }
3481
3504
  }
3482
- function close(parent = false) {
3505
+ function close(closeParent = false, focusTrigger = false) {
3483
3506
  el.pauseKeyEvents = false;
3484
3507
  el.classList.add("hidden");
3485
3508
  Object.assign(el.style, {
3486
3509
  left: "0px",
3487
3510
  top: "0px"
3488
3511
  });
3489
- top.removeEventListener("contextmenu", onClick);
3490
- top.removeEventListener("click", onClick);
3491
- el.removeEventListener("keydown", onKeydown);
3512
+ top.removeEventListener("contextmenu", onClick2);
3513
+ top.removeEventListener("click", onClick2);
3514
+ el.removeEventListener("keydown", onKeyDown);
3492
3515
  if (isSubmenu) {
3493
- if (parent) {
3516
+ if (closeParent) {
3494
3517
  menuSubItem._menu_sub.closeTree();
3495
3518
  }
3496
3519
  } else {
3497
3520
  listenForTrigger(true);
3521
+ if (focusTrigger) menuTrigger.focus();
3498
3522
  }
3499
3523
  }
3500
3524
  el._menu = { close };
@@ -3515,12 +3539,12 @@
3515
3539
  }
3516
3540
  return false;
3517
3541
  }
3518
- function onClick(event) {
3542
+ function onClick2(event) {
3519
3543
  if (event.type === "contextmenu") event.preventDefault();
3520
3544
  close(isSubmenu);
3521
3545
  }
3522
3546
  el.pauseKeyEvents = false;
3523
- function onKeydown(event) {
3547
+ function onKeyDown(event) {
3524
3548
  if (!el.pauseKeyEvents) {
3525
3549
  let menuitem;
3526
3550
  switch (event.key) {
@@ -3536,7 +3560,7 @@
3536
3560
  if (isSubmenu) {
3537
3561
  Alpine2.nextTick(() => menuSubItem.focus());
3538
3562
  }
3539
- close();
3563
+ close(void 0, true);
3540
3564
  break;
3541
3565
  case "Tab":
3542
3566
  case " ":
@@ -3633,9 +3657,9 @@
3633
3657
  listenForTrigger(false);
3634
3658
  }
3635
3659
  Alpine2.nextTick(() => {
3636
- top.addEventListener("contextmenu", onClick);
3637
- top.addEventListener("click", onClick);
3638
- el.addEventListener("keydown", onKeydown);
3660
+ top.addEventListener("contextmenu", onClick2);
3661
+ top.addEventListener("click", onClick2);
3662
+ el.addEventListener("keydown", onKeyDown);
3639
3663
  });
3640
3664
  Object.assign(el.style, {
3641
3665
  left: `${x}px`,
@@ -3673,12 +3697,12 @@
3673
3697
  }
3674
3698
  cleanup(() => {
3675
3699
  listenForTrigger(false);
3676
- top.removeEventListener("click", onClick);
3677
- top.removeEventListener("contextmenu", onClick);
3678
- el.removeEventListener("keydown", onKeydown);
3700
+ top.removeEventListener("click", onClick2);
3701
+ top.removeEventListener("contextmenu", onClick2);
3702
+ el.removeEventListener("keydown", onKeyDown);
3679
3703
  });
3680
3704
  });
3681
- Alpine.directive("h-menu-item", (el, {}, { cleanup, Alpine: Alpine2 }) => {
3705
+ Alpine.directive("h-menu-item", (el, _, { cleanup, Alpine: Alpine2 }) => {
3682
3706
  el.classList.add(
3683
3707
  "focus:bg-secondary-hover",
3684
3708
  "focus:text-secondary-foreground",
@@ -3731,7 +3755,7 @@
3731
3755
  el.removeEventListener("mouseleave", focusOut);
3732
3756
  });
3733
3757
  });
3734
- Alpine.directive("h-menu-sub", (el, {}, { cleanup, Alpine: Alpine2 }) => {
3758
+ Alpine.directive("h-menu-sub", (el, { original }, { cleanup, Alpine: Alpine2 }) => {
3735
3759
  el.classList.add(
3736
3760
  "focus:bg-secondary-hover",
3737
3761
  "hover:bg-secondary-hover",
@@ -3756,12 +3780,13 @@
3756
3780
  "[&_svg:not([class*='size-'])]:size-4",
3757
3781
  "after:block",
3758
3782
  "after:bg-transparent",
3759
- "after:border-t-[0.063rem]",
3760
- "after:border-r-[0.063rem]",
3783
+ "after:border-t-[calc(var(--spacing)*0.25)]",
3784
+ "after:border-r-[calc(var(--spacing)*0.25)]",
3761
3785
  "after:border-muted-foreground",
3762
3786
  "after:pointer-events-none",
3763
- "after:size-[0.438rem]",
3764
- "after:rounded-[0.063rem]",
3787
+ "after:min-w-1.75",
3788
+ "after:size-1.75",
3789
+ "after:rounded-[calc(var(--spacing)*0.25)]",
3765
3790
  "after:rotate-45",
3766
3791
  "after:ml-auto",
3767
3792
  "after:-translate-x-0.75"
@@ -3772,7 +3797,7 @@
3772
3797
  el.setAttribute("tabindex", "-1");
3773
3798
  el.setAttribute("data-slot", "menu-sub");
3774
3799
  const parentMenu = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "menu");
3775
- if (!parentMenu) throw new Error("h-menu-sub: Menu sub item must have a parent");
3800
+ if (!parentMenu) throw new Error(`${original} must have a parent`);
3776
3801
  el._menu_sub = {
3777
3802
  open: void 0,
3778
3803
  close: void 0,
@@ -3780,17 +3805,17 @@
3780
3805
  closeTree() {
3781
3806
  el.setAttribute("aria-expanded", "false");
3782
3807
  this.expanded = false;
3783
- el.removeEventListener("keydown", onKeydown);
3808
+ el.removeEventListener("keydown", onKeyDown);
3784
3809
  parentMenu.pauseKeyEvents = false;
3785
3810
  parentMenu._menu.close(true);
3786
3811
  }
3787
3812
  };
3788
3813
  const keyEvents = ["Right", "ArrowRight", "Enter", " "];
3789
- function onKeydown(event) {
3814
+ function onKeyDown(event) {
3790
3815
  if (keyEvents.includes(event.key)) {
3791
3816
  event.stopPropagation();
3792
3817
  event.preventDefault();
3793
- el.removeEventListener("keydown", onKeydown);
3818
+ el.removeEventListener("keydown", onKeyDown);
3794
3819
  const submenuitem = el.querySelector('[role^=menuitem][tabIndex="-1"]:first-of-type');
3795
3820
  if (submenuitem) {
3796
3821
  el.setAttribute("aria-expanded", "true");
@@ -3817,7 +3842,7 @@
3817
3842
  el._menu_sub.expanded = false;
3818
3843
  el.setAttribute("aria-expanded", false);
3819
3844
  parentMenu.pauseKeyEvents = false;
3820
- el.removeEventListener("keydown", onKeydown);
3845
+ el.removeEventListener("keydown", onKeyDown);
3821
3846
  }
3822
3847
  }
3823
3848
  function focusIn(event) {
@@ -3838,7 +3863,7 @@
3838
3863
  el.setAttribute("aria-expanded", false);
3839
3864
  parentMenu.pauseKeyEvents = false;
3840
3865
  }
3841
- el.addEventListener("keydown", onKeydown);
3866
+ el.addEventListener("keydown", onKeyDown);
3842
3867
  el.addEventListener("blur", focusOut);
3843
3868
  }
3844
3869
  }
@@ -3866,7 +3891,7 @@
3866
3891
  el.classList.add("text-foreground", "px-2", "py-1.5", "text-sm", "font-semibold", "text-left", "data-[inset=true]:pl-8");
3867
3892
  el.setAttribute("data-slot", "menu-label");
3868
3893
  });
3869
- Alpine.directive("h-menu-checkbox-item", (el, {}, { cleanup, Alpine: Alpine2 }) => {
3894
+ Alpine.directive("h-menu-checkbox-item", (el, _, { cleanup, Alpine: Alpine2 }) => {
3870
3895
  el.classList.add(
3871
3896
  "focus:bg-secondary-hover",
3872
3897
  "hover:bg-secondary-hover",
@@ -3895,7 +3920,6 @@
3895
3920
  "before:pointer-events-none",
3896
3921
  "before:w-2.5",
3897
3922
  "before:h-1.5",
3898
- "before:rounded-[0.125rem]",
3899
3923
  "before:-rotate-45",
3900
3924
  "before:-translate-x-0.75",
3901
3925
  "aria-[checked=true]:before:visible"
@@ -3910,13 +3934,13 @@
3910
3934
  });
3911
3935
  el.setAttribute("aria-checked", checked);
3912
3936
  }
3937
+ function onActivate() {
3938
+ el._x_model.set(!el._x_model.get());
3939
+ setState(el._x_model.get());
3940
+ }
3913
3941
  if (el.hasOwnProperty("_x_model")) {
3914
- let handler2 = function() {
3915
- el._x_model.set(!el._x_model.get());
3916
- setState(el._x_model.get());
3917
- };
3918
3942
  setState(el._x_model.get(), false);
3919
- el.addEventListener("click", handler2);
3943
+ el.addEventListener("click", onActivate);
3920
3944
  }
3921
3945
  const menu = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "menu");
3922
3946
  function focusOut(event) {
@@ -3932,8 +3956,8 @@
3932
3956
  el.addEventListener("focus", focusIn);
3933
3957
  cleanup(() => {
3934
3958
  if (el.hasOwnProperty("_x_model")) {
3935
- el.removeEventListener("click", handler);
3936
- el.removeEventListener("keydown", handler);
3959
+ el.removeEventListener("click", onActivate);
3960
+ el.removeEventListener("keydown", onActivate);
3937
3961
  }
3938
3962
  el.removeEventListener("mouseenter", focusIn);
3939
3963
  el.removeEventListener("focus", focusIn);
@@ -3983,24 +4007,24 @@
3983
4007
  el.setAttribute("aria-checked", checked);
3984
4008
  if (dispatch) el.dispatchEvent(new Event("change", { bubbles: true }));
3985
4009
  }
3986
- if (el.hasOwnProperty("_x_model")) {
3987
- let handler2 = function(event) {
3988
- if (event.type === "keydown") {
3989
- if (event.key !== " " && event.key !== "Enter") {
3990
- return;
3991
- } else if (event.key === " ") {
3992
- event.preventDefault();
3993
- }
3994
- }
3995
- if (el._x_model.get() !== value) {
3996
- el._x_model.set(value);
4010
+ function onActivate(event) {
4011
+ if (event.type === "keydown") {
4012
+ if (event.key !== " " && event.key !== "Enter") {
4013
+ return;
4014
+ } else if (event.key === " ") {
4015
+ event.preventDefault();
3997
4016
  }
3998
- };
4017
+ }
4018
+ if (el._x_model.get() !== value) {
4019
+ el._x_model.set(value);
4020
+ }
4021
+ }
4022
+ if (el.hasOwnProperty("_x_model")) {
3999
4023
  effect(() => {
4000
4024
  setState(el._x_model.get() === value);
4001
4025
  });
4002
- el.addEventListener("click", handler2);
4003
- el.addEventListener("keydown", handler2);
4026
+ el.addEventListener("click", onActivate);
4027
+ el.addEventListener("keydown", onActivate);
4004
4028
  }
4005
4029
  const menu = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "menu");
4006
4030
  function focusOut(event) {
@@ -4016,8 +4040,8 @@
4016
4040
  el.addEventListener("focus", focusIn);
4017
4041
  cleanup(() => {
4018
4042
  if (el.hasOwnProperty("_x_model")) {
4019
- el.removeEventListener("click", handler);
4020
- el.removeEventListener("keydown", handler);
4043
+ el.removeEventListener("click", onActivate);
4044
+ el.removeEventListener("keydown", onActivate);
4021
4045
  }
4022
4046
  el.removeEventListener("mouseenter", focusIn);
4023
4047
  el.removeEventListener("focus", focusIn);
@@ -4061,7 +4085,7 @@
4061
4085
  "outline-none",
4062
4086
  "focus-visible:border-ring",
4063
4087
  "focus-visible:ring-ring/50",
4064
- "focus-visible:ring-[3px]",
4088
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
4065
4089
  "h-9",
4066
4090
  "min-w-9",
4067
4091
  "text-foreground",
@@ -4156,23 +4180,23 @@
4156
4180
  };
4157
4181
  const close = () => {
4158
4182
  el._popover.expanded = false;
4159
- el.addEventListener("click", handler2);
4183
+ el.addEventListener("click", handler);
4160
4184
  };
4161
- const handler2 = () => {
4185
+ const handler = () => {
4162
4186
  el._popover.expanded = !el._popover.expanded;
4163
4187
  setAttributes();
4164
4188
  Alpine2.nextTick(() => {
4165
4189
  if (el._popover.auto && el._popover.expanded) {
4166
4190
  top.addEventListener("click", close, { once: true });
4167
- el.removeEventListener("click", handler2);
4191
+ el.removeEventListener("click", handler);
4168
4192
  }
4169
4193
  });
4170
4194
  };
4171
4195
  setAttributes();
4172
4196
  if (el._popover.auto) {
4173
- el.addEventListener("click", handler2);
4197
+ el.addEventListener("click", handler);
4174
4198
  cleanup(() => {
4175
- el.removeEventListener("click", handler2);
4199
+ el.removeEventListener("click", handler);
4176
4200
  top.removeEventListener("click", close);
4177
4201
  });
4178
4202
  } else {
@@ -4181,7 +4205,7 @@
4181
4205
  });
4182
4206
  }
4183
4207
  });
4184
- Alpine.directive("h-popover", (el, { modifiers }, { effect }) => {
4208
+ Alpine.directive("h-popover", (el, { original, modifiers }, { effect }) => {
4185
4209
  const popover = (() => {
4186
4210
  let sibling = el.previousElementSibling;
4187
4211
  while (sibling && !sibling.hasOwnProperty("_popover")) {
@@ -4190,7 +4214,7 @@
4190
4214
  return sibling;
4191
4215
  })();
4192
4216
  if (!popover) {
4193
- throw new Error("h-popover-content must be placed after an h-popover element");
4217
+ throw new Error(`${original} must be placed after a popover element`);
4194
4218
  }
4195
4219
  el.classList.add("absolute", "bg-popover", "text-popover-foreground", "data-[state=closed]:hidden", "top-0", "left-0", "z-50", "min-w-[1rem]", "rounded-md", "border", "shadow-md", "outline-hidden", "overflow-scroll");
4196
4220
  el.setAttribute("data-slot", "popover");
@@ -4276,7 +4300,7 @@
4276
4300
  "[&>input]:border-0",
4277
4301
  "[&>input]:cursor-pointer",
4278
4302
  "[&>input]:focus-visible:border-ring",
4279
- "[&>input]:focus-visible:ring-[3px]",
4303
+ "[&>input]:focus-visible:ring-[calc(var(--spacing)*0.75)]",
4280
4304
  "[&>input]:focus-visible:ring-ring/50",
4281
4305
  "[&>input]:left-0",
4282
4306
  "[&>input]:outline-none",
@@ -6202,103 +6226,175 @@
6202
6226
  none: 3
6203
6227
  });
6204
6228
  function select_default(Alpine) {
6205
- Alpine.directive("h-select", (el, {}, { Alpine: Alpine2 }) => {
6229
+ Alpine.directive("h-select", (el, _, { Alpine: Alpine2, cleanup }) => {
6206
6230
  el._h_select = Alpine2.reactive({
6207
6231
  id: void 0,
6208
6232
  controls: `hsc${v4_default()}`,
6209
6233
  expanded: false,
6210
- model: void 0,
6211
6234
  multiple: false,
6212
6235
  label: [],
6236
+ refreshLabel: void 0,
6237
+ listeners: [],
6213
6238
  search: "",
6214
6239
  focusSearch: void 0,
6215
6240
  filterType: FilterType["starts-with"]
6216
6241
  });
6242
+ el._h_model = {
6243
+ set: void 0,
6244
+ get: void 0
6245
+ };
6246
+ el.classList.add(
6247
+ "cursor-pointer",
6248
+ "border-input",
6249
+ "has-focus-visible:border-ring",
6250
+ "has-focus-visible:ring-[calc(var(--spacing)*0.75)]",
6251
+ "has-focus-visible:ring-ring/50",
6252
+ "dark:has-[aria-invalid=true]:ring-negative/40",
6253
+ "dark:has-[input:invalid]:ring-negative/40",
6254
+ "has-[aria-invalid=true]:border-negative",
6255
+ "has-[aria-invalid=true]:ring-negative/20",
6256
+ "has-[input:invalid]:border-negative",
6257
+ "has-[input:invalid]:ring-negative/20",
6258
+ "hover:bg-secondary-hover",
6259
+ "active:bg-secondary-active",
6260
+ "w-full",
6261
+ "rounded-control",
6262
+ "border",
6263
+ "bg-input-inner",
6264
+ "text-sm",
6265
+ "whitespace-nowrap",
6266
+ "shadow-input",
6267
+ "transition-[color,box-shadow]",
6268
+ "duration-200",
6269
+ "outline-none",
6270
+ "has-[input:disabled]:pointer-events-none",
6271
+ "has-[input:disabled]:opacity-50",
6272
+ "[&_svg]:pointer-events-none",
6273
+ "[&_svg]:shrink-0",
6274
+ "[&_svg]:size-4",
6275
+ "[&_svg]:opacity-50"
6276
+ );
6217
6277
  el.setAttribute("data-slot", "select");
6278
+ const setSize = (size3) => {
6279
+ if (size3 === "sm") {
6280
+ el.classList.add("h-8");
6281
+ el.classList.remove("h-9", "h-6.5");
6282
+ } else if (size3 === "xs") {
6283
+ el.classList.add("h-6.5");
6284
+ el.classList.remove("h-9", "h-8");
6285
+ } else {
6286
+ el.classList.add("h-9");
6287
+ el.classList.remove("h-8", "h-6.5");
6288
+ }
6289
+ };
6290
+ setSize(el.getAttribute("data-size"));
6291
+ const observer = new MutationObserver(() => {
6292
+ setSize(el.getAttribute("data-size"));
6293
+ });
6294
+ observer.observe(el, { attributes: true, attributeFilter: ["data-size"] });
6295
+ cleanup(() => {
6296
+ observer.disconnect();
6297
+ });
6218
6298
  });
6219
- Alpine.directive("h-select-trigger", (el, {}, { effect, cleanup, Alpine: Alpine2 }) => {
6299
+ Alpine.directive("h-select-input", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
6300
+ if (el.tagName !== "INPUT") {
6301
+ throw new Error(`${original} must be a readonly input of type "text"`);
6302
+ }
6220
6303
  const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6221
6304
  if (!select) {
6222
- throw new Error("h-select-trigger must be inside an h-select element");
6305
+ throw new Error(`${original} must be inside a select element`);
6223
6306
  } else if (el.hasOwnProperty("_x_model")) {
6224
6307
  select._h_select.multiple = Array.isArray(el._x_model.get());
6225
- select._h_select.model = el._x_model.get();
6308
+ select._h_model.set = (value) => {
6309
+ if (select._h_select.multiple) {
6310
+ const vIndex = el._x_model.get().indexOf(value);
6311
+ if (vIndex > -1) {
6312
+ const newArr = el._x_model.get();
6313
+ newArr.splice(vIndex, 1);
6314
+ el._x_model.set(newArr);
6315
+ } else {
6316
+ const arr = el._x_model.get();
6317
+ arr.push(value);
6318
+ el._x_model.set(arr);
6319
+ }
6320
+ } else if (el._x_model.get() !== value) {
6321
+ el._x_model.set(value);
6322
+ } else {
6323
+ el._x_model.set("");
6324
+ }
6325
+ };
6326
+ select._h_model.get = el._x_model.get;
6327
+ } else {
6328
+ select._h_model.set = (value) => {
6329
+ el.value = value;
6330
+ el.dispatchEvent(new Event("change", { bubbles: true }));
6331
+ };
6332
+ select._h_model.get = () => el.value;
6226
6333
  }
6227
- setButtonClasses(el);
6228
- const setVariant = (variant) => {
6229
- if (variant === "secondary") {
6230
- el.classList.add(...buttonVariants["default"]);
6231
- return;
6232
- } else if (variant === "transparent") {
6233
- el.classList.add(...buttonVariants["transparent"]);
6234
- } else el.classList.add("shadow-input", ...buttonVariants["outline"]);
6235
- };
6236
- const setSize = (size3) => {
6237
- const sizes = ["sm", "xs", "lg"];
6238
- if (sizes.includes(size3)) {
6239
- el.classList.add(...getButtonSize(size3));
6240
- } else el.classList.add(...getButtonSize());
6241
- };
6242
- setVariant(el.getAttribute("data-variant"));
6243
- setSize(el.getAttribute("data-size"));
6244
- el.classList.add("w-full", "[&_svg]:opacity-50", "[&[data-state=open]>svg]:rotate-180");
6245
- el.setAttribute("type", "button");
6246
- const selectValue = document.createElement("span");
6247
- selectValue.setAttribute("data-slot", "select-value");
6248
- selectValue.classList.add("text-left", "truncate", "pointer-events-none", "w-full");
6334
+ el.classList.add("hidden");
6335
+ el.setAttribute("type", "text");
6336
+ const fakeTrigger = document.createElement("span");
6337
+ const displayValue = document.createElement("span");
6338
+ displayValue.classList.add("text-left", "truncate", "w-full");
6339
+ fakeTrigger.appendChild(displayValue);
6340
+ fakeTrigger.setAttribute("data-slot", "select-value");
6341
+ fakeTrigger.setAttribute("tabindex", "0");
6342
+ fakeTrigger.classList.add("flex", "items-center", "justify-between", "gap-2", "outline-none", "pl-3", "pr-2", "size-full", "[&[data-state=open]>svg]:rotate-180");
6249
6343
  function getPlaceholder() {
6250
6344
  if (!el.value) {
6251
6345
  const value = el.getAttribute("placeholder");
6252
6346
  if (value) {
6253
- selectValue.innerText = value;
6254
- selectValue.classList.add("text-muted-foreground");
6347
+ displayValue.innerText = value;
6348
+ displayValue.classList.add("text-muted-foreground");
6255
6349
  } else {
6256
- selectValue.classList.remove("text-muted-foreground");
6350
+ displayValue.classList.remove("text-muted-foreground");
6257
6351
  }
6258
6352
  }
6259
6353
  }
6260
6354
  getPlaceholder();
6261
6355
  const observer = new MutationObserver((mutations) => {
6262
6356
  mutations.forEach((mutation) => {
6263
- if (mutation.attributeName === "value") {
6264
- el.dispatchEvent(new Event("change", { bubbles: true }));
6265
- if (el.value) selectValue.classList.remove("text-muted-foreground");
6357
+ if (mutation.attributeName === "data-id") {
6358
+ select._h_select.id = el.getAttribute("data-id");
6359
+ fakeTrigger.setAttribute("id", select._h_select.id);
6266
6360
  } else if (mutation.attributeName === "placeholder" && !select._h_select.label.length) {
6267
6361
  getPlaceholder();
6268
6362
  }
6269
6363
  });
6270
6364
  });
6271
- observer.observe(el, { attributes: true, attributeFilter: ["value", "placeholder"] });
6365
+ observer.observe(el, { attributes: true, attributeFilter: ["data-id", "placeholder"] });
6272
6366
  effect(() => {
6273
6367
  if (select._h_select.label.length === 1) {
6274
- selectValue.innerText = select._h_select.label[0];
6368
+ displayValue.innerText = select._h_select.label[0];
6369
+ displayValue.classList.remove("text-muted-foreground");
6275
6370
  } else if (select._h_select.label.length > 1) {
6276
- selectValue.innerText = select._h_select.label.join(", ");
6371
+ displayValue.innerText = select._h_select.label.join(", ");
6372
+ displayValue.classList.remove("text-muted-foreground");
6277
6373
  } else {
6278
6374
  getPlaceholder();
6279
6375
  }
6280
6376
  });
6281
- el.setAttribute("data-slot", "select-trigger");
6282
- if (el.hasAttribute("id")) {
6283
- select._h_select.id = el.getAttribute("id");
6284
- } else {
6285
- select._h_select.id = `hs${v4_default()}`;
6286
- el.setAttribute("id", select._h_select.id);
6287
- }
6288
- el.setAttribute("aria-controls", select._h_select.controls);
6289
- el.setAttribute("aria-haspopup", "listbox");
6290
- el.setAttribute("aria-autocomplete", "none");
6291
- el.setAttribute("role", "combobox");
6377
+ fakeTrigger.setAttribute("data-slot", "select-input");
6378
+ select._h_select.id = el.hasAttribute("data-id") ? el.getAttribute("data-id") : `hs${v4_default()}`;
6379
+ fakeTrigger.setAttribute("id", select._h_select.id);
6380
+ fakeTrigger.setAttribute("aria-controls", select._h_select.controls);
6381
+ fakeTrigger.setAttribute("aria-haspopup", "listbox");
6382
+ fakeTrigger.setAttribute("aria-autocomplete", "none");
6383
+ fakeTrigger.setAttribute("role", "combobox");
6292
6384
  effect(() => {
6293
- el.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6294
- el.setAttribute("aria-expanded", select._h_select.expanded);
6385
+ fakeTrigger.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6386
+ fakeTrigger.setAttribute("aria-expanded", select._h_select.expanded);
6295
6387
  });
6296
- const close = () => {
6388
+ const close = (focusSelect = false) => {
6297
6389
  select._h_select.expanded = false;
6390
+ top.removeEventListener("click", close);
6391
+ el.parentElement.removeEventListener("keydown", onKeyDown);
6392
+ options = null;
6393
+ if (focusSelect) fakeTrigger.focus();
6298
6394
  };
6299
6395
  let content;
6300
6396
  let options;
6301
- const shiftFocus = (event) => {
6397
+ const onKeyDown = (event) => {
6302
6398
  switch (event.key) {
6303
6399
  case "Down":
6304
6400
  case "ArrowDown":
@@ -6370,13 +6466,19 @@
6370
6466
  options[options.length - 1].setAttribute("tabindex", "0");
6371
6467
  options[options.length - 1].focus();
6372
6468
  break;
6469
+ case " ":
6373
6470
  case "Enter":
6471
+ event.preventDefault();
6472
+ if (!select._h_select.multiple) {
6473
+ close(true);
6474
+ }
6475
+ break;
6374
6476
  case "Escape":
6375
- handler2();
6376
- el.focus();
6477
+ event.preventDefault();
6478
+ close(true);
6377
6479
  break;
6378
6480
  case "Tab":
6379
- handler2();
6481
+ close();
6380
6482
  break;
6381
6483
  case "Control":
6382
6484
  case "Shift":
@@ -6394,7 +6496,7 @@
6394
6496
  }
6395
6497
  }
6396
6498
  };
6397
- const handler2 = () => {
6499
+ const onClick2 = () => {
6398
6500
  select._h_select.expanded = !select._h_select.expanded;
6399
6501
  if (select._h_select.expanded) {
6400
6502
  if (!content) content = select.querySelector(`#${select._h_select.controls}`);
@@ -6403,15 +6505,26 @@
6403
6505
  Alpine2.nextTick(() => {
6404
6506
  if (select._h_select.expanded) {
6405
6507
  top.addEventListener("click", close, { once: true });
6406
- el.parentElement.addEventListener("keydown", shiftFocus);
6508
+ el.parentElement.addEventListener("keydown", onKeyDown);
6407
6509
  } else {
6408
6510
  top.removeEventListener("click", close);
6409
- el.parentElement.removeEventListener("keydown", shiftFocus);
6511
+ el.parentElement.removeEventListener("keydown", onKeyDown);
6410
6512
  options = null;
6411
6513
  }
6412
6514
  });
6413
6515
  };
6414
- el.addEventListener("click", handler2);
6516
+ const onPress = (event) => {
6517
+ if (event.key === "Escape" && select._h_select.expanded) close(true);
6518
+ else if (event.key === "Enter") {
6519
+ event.preventDefault();
6520
+ onClick2();
6521
+ } else if (event.key === " ") {
6522
+ event.preventDefault();
6523
+ setTimeout(() => onClick2(), 0);
6524
+ }
6525
+ };
6526
+ fakeTrigger.addEventListener("keydown", onPress);
6527
+ fakeTrigger.addEventListener("click", onClick2);
6415
6528
  const chevronDown = createElement(ChevronDown, {
6416
6529
  class: ["opacity-50 size-4 transition-transform duration-200"],
6417
6530
  width: "16",
@@ -6419,19 +6532,32 @@
6419
6532
  "aria-hidden": true,
6420
6533
  role: "presentation"
6421
6534
  });
6422
- el.appendChild(selectValue);
6423
- el.appendChild(chevronDown);
6535
+ el.parentElement.appendChild(fakeTrigger);
6536
+ fakeTrigger.appendChild(chevronDown);
6537
+ const onInputChange = () => {
6538
+ select._h_select.label.length = 0;
6539
+ for (let i = 0; i < select._h_select.listeners.length; i++) {
6540
+ const label = select._h_select.listeners[i](select._h_model.get());
6541
+ if (label) {
6542
+ select._h_select.label.push(label);
6543
+ }
6544
+ }
6545
+ };
6546
+ select._h_select.refreshLabel = onInputChange;
6547
+ el.addEventListener("change", onInputChange);
6424
6548
  cleanup(() => {
6425
- el.removeEventListener("click", handler2);
6426
- el.parentElement.removeEventListener("keydown", shiftFocus);
6549
+ fakeTrigger.removeEventListener("click", onClick2);
6550
+ fakeTrigger.removeEventListener("keydown", onPress);
6551
+ el.parentElement.removeEventListener("keydown", onKeyDown);
6427
6552
  top.removeEventListener("click", close);
6553
+ el.removeEventListener("change", onInputChange);
6428
6554
  observer.disconnect();
6429
6555
  });
6430
6556
  });
6431
- Alpine.directive("h-select-content", (el, {}, { effect, Alpine: Alpine2 }) => {
6557
+ Alpine.directive("h-select-content", (el, { original }, { effect, Alpine: Alpine2 }) => {
6432
6558
  const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6433
6559
  if (!select) {
6434
- throw new Error("h-select-content must be inside an h-select element");
6560
+ throw new Error(`${original} must be inside a select element`);
6435
6561
  }
6436
6562
  el.classList.add("absolute", "bg-popover", "text-popover-foreground", "data-[state=closed]:hidden", "p-1", "top-0", "left-0", "z-50", "min-w-[1rem]", "overflow-x-hidden", "overflow-y-auto", "rounded-md", "border", "shadow-md");
6437
6563
  el.setAttribute("data-slot", "select-content");
@@ -6439,11 +6565,10 @@
6439
6565
  el.setAttribute("role", "presentation");
6440
6566
  el.setAttribute("id", select._h_select.controls);
6441
6567
  el.setAttribute("tabindex", "-1");
6442
- el.setAttribute("aria-labelledby", select._h_select.id);
6443
6568
  el.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6444
6569
  const control = select.querySelector(`#${select._h_select.id}`);
6445
6570
  if (!control) {
6446
- throw new Error("h-select-content: trigger not found");
6571
+ throw new Error(`${original}: trigger not found`);
6447
6572
  }
6448
6573
  let autoUpdateCleanup;
6449
6574
  function updatePosition() {
@@ -6469,6 +6594,9 @@
6469
6594
  });
6470
6595
  });
6471
6596
  }
6597
+ effect(() => {
6598
+ el.setAttribute("aria-labelledby", select._h_select.id);
6599
+ });
6472
6600
  effect(() => {
6473
6601
  el.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6474
6602
  if (select._h_select.expanded) {
@@ -6482,12 +6610,12 @@
6482
6610
  }
6483
6611
  });
6484
6612
  });
6485
- Alpine.directive("h-select-search", (el, { modifiers }, { effect, cleanup }) => {
6486
- const select = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6613
+ Alpine.directive("h-select-search", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
6614
+ const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6487
6615
  if (!select) {
6488
- throw new Error("h-select-search must be inside an h-select element");
6616
+ throw new Error(`${original} must be inside an h-select element`);
6489
6617
  } else {
6490
- select._h_select.filterType = FilterType[modifiers[0]] ?? FilterType["starts-with"];
6618
+ select._h_select.filterType = FilterType[el.getAttribute("data-filter")] ?? FilterType["starts-with"];
6491
6619
  }
6492
6620
  el.classList.add("flex", "h-8", "items-center", "gap-2", "border-b", "px-2");
6493
6621
  el.setAttribute("data-slot", "select-search");
@@ -6508,12 +6636,12 @@
6508
6636
  select._h_select.focusSearch = () => {
6509
6637
  searchInput.focus();
6510
6638
  };
6511
- function handler2(event) {
6639
+ function onActivate(event) {
6512
6640
  if (event.type === "keydown" && (event.key === "Escape" || event.key === "ArrowDown" || event.key === "Down")) return;
6513
6641
  event.stopPropagation();
6514
6642
  }
6515
- el.addEventListener("click", handler2);
6516
- el.addEventListener("keydown", handler2);
6643
+ el.addEventListener("click", onActivate);
6644
+ el.addEventListener("keydown", onActivate);
6517
6645
  if (select._h_select.filterType !== FilterType.none) {
6518
6646
  let onInput2 = function() {
6519
6647
  select._h_select.search = searchInput.value.toLowerCase();
@@ -6524,13 +6652,19 @@
6524
6652
  if (select._h_select.expanded) searchInput.focus({ preventScroll: true });
6525
6653
  el.setAttribute("aria-expanded", select._h_select.expanded);
6526
6654
  });
6655
+ const observer = new MutationObserver(() => {
6656
+ select._h_select.filterType = FilterType[el.getAttribute("data-filter")] ?? FilterType["starts-with"];
6657
+ el.setAttribute("aria-autocomplete", select._h_select.filterType === FilterType.none ? "both" : "list");
6658
+ });
6659
+ observer.observe(el, { attributes: true, attributeFilter: ["data-filter"] });
6527
6660
  cleanup(() => {
6528
- el.removeEventListener("click", handler2);
6529
- el.removeEventListener("keydown", handler2);
6661
+ el.removeEventListener("click", onActivate);
6662
+ el.removeEventListener("keydown", onActivate);
6530
6663
  if (select._h_select.filterType !== FilterType.none) searchInput.removeEventListener("keyup", onInput);
6664
+ observer.disconnect();
6531
6665
  });
6532
6666
  });
6533
- Alpine.directive("h-select-group", (el, {}, { effect }) => {
6667
+ Alpine.directive("h-select-group", (el, _, { effect }) => {
6534
6668
  el.setAttribute("data-slot", "select-group");
6535
6669
  el._h_selectGroup = Alpine.reactive({
6536
6670
  labelledby: void 0
@@ -6551,10 +6685,10 @@
6551
6685
  selectGroup._h_selectGroup.labelledby = id;
6552
6686
  }
6553
6687
  });
6554
- Alpine.directive("h-select-option", (el, { expression }, { effect, evaluateLater, cleanup }) => {
6688
+ Alpine.directive("h-select-option", (el, { original, expression }, { effect, evaluateLater, cleanup }) => {
6555
6689
  const select = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6556
6690
  if (!select) {
6557
- throw new Error("h-select-option must be inside an h-select element");
6691
+ throw new Error(`${original} must be inside an h-select element`);
6558
6692
  }
6559
6693
  el.classList.add(
6560
6694
  "focus:bg-primary",
@@ -6601,18 +6735,13 @@
6601
6735
  el.appendChild(indicatorEl);
6602
6736
  el.appendChild(labelEl);
6603
6737
  function getValue() {
6604
- if (el.hasOwnProperty("_x_bindings") && el._x_bindings.hasOwnProperty("value")) return el._x_bindings.value;
6605
- else return el.getAttribute("value");
6738
+ return el.getAttribute("data-value");
6606
6739
  }
6607
6740
  const getLabel = evaluateLater(expression);
6608
6741
  effect(() => {
6609
6742
  getLabel((label) => {
6610
- if (select._h_select.multiple && select._h_select.model.includes(getValue())) {
6611
- select._h_select.label[select._h_select.label.indexOf(labelEl.innerText)] = label;
6612
- } else if (select._h_select.model === getValue()) {
6613
- select._h_select.label[0] = label;
6614
- }
6615
6743
  labelEl.innerText = label;
6744
+ select._h_select.refreshLabel();
6616
6745
  });
6617
6746
  });
6618
6747
  effect(() => {
@@ -6639,51 +6768,40 @@
6639
6768
  if (selected) {
6640
6769
  indicatorEl.classList.remove("invisible");
6641
6770
  el.setAttribute("aria-selected", "true");
6642
- if (!select._h_select.label.length) {
6643
- select._h_select.label.push(labelEl.innerText);
6644
- } else if (!select._h_select.label.includes(labelEl.innerText)) {
6645
- if (select._h_select.multiple) select._h_select.label.push(labelEl.innerText);
6646
- else select._h_select.label[0] = labelEl.innerText;
6647
- }
6648
- } else {
6649
- indicatorEl.classList.add("invisible");
6650
- el.setAttribute("aria-selected", "false");
6771
+ return labelEl.innerText;
6651
6772
  }
6773
+ indicatorEl.classList.add("invisible");
6774
+ el.setAttribute("aria-selected", "false");
6775
+ return "";
6652
6776
  }
6653
- function removeLabel() {
6654
- const lIndex = select._h_select.label.indexOf(labelEl.innerText);
6655
- if (lIndex > -1) select._h_select.label.splice(lIndex, 1);
6656
- }
6657
- effect(() => {
6658
- if (select._h_select.multiple) {
6659
- setSelectedState(select._h_select.model.includes(getValue()));
6660
- } else {
6661
- setSelectedState(select._h_select.model === getValue());
6662
- }
6663
- });
6664
- const handler2 = (event) => {
6665
- if (event.type === "keydown" && event.key === "Enter" || event.type === "click") {
6777
+ const onModelChange = (value) => {
6778
+ return setSelectedState(select._h_select.multiple ? value.includes(getValue()) : value === getValue());
6779
+ };
6780
+ select._h_select.listeners.push(onModelChange);
6781
+ const onActivate = (event) => {
6782
+ if (event.type === "keydown" && (event.key === "Enter" || event.key === " ") || event.type === "click") {
6666
6783
  if (select._h_select.multiple) {
6667
- const vIndex = select._h_select.model.indexOf(getValue());
6784
+ const vIndex = select._h_model.get().indexOf(getValue());
6668
6785
  if (vIndex > -1) {
6669
- select._h_select.model.splice(vIndex, 1);
6670
- removeLabel();
6786
+ const val = select._h_model.get().splice(vIndex, 1);
6787
+ select._h_model.set(val);
6671
6788
  } else {
6672
- select._h_select.model.push(getValue());
6789
+ select._h_model.get().push(getValue());
6673
6790
  }
6674
- } else if (select._h_select.model !== getValue()) {
6675
- select._h_select.model = getValue();
6791
+ } else if (select._h_model.get() !== getValue()) {
6792
+ select._h_model.set(getValue());
6676
6793
  } else {
6677
- select._h_select.model = "";
6678
- removeLabel();
6794
+ select._h_model.set("");
6679
6795
  }
6680
6796
  }
6681
6797
  };
6682
- el.addEventListener("click", handler2);
6683
- el.addEventListener("keydown", handler2);
6798
+ el.addEventListener("click", onActivate);
6799
+ el.addEventListener("keydown", onActivate);
6684
6800
  cleanup(() => {
6685
- el.removeEventListener("click", handler2);
6686
- el.removeEventListener("keydown", handler2);
6801
+ el.removeEventListener("click", onActivate);
6802
+ el.removeEventListener("keydown", onActivate);
6803
+ const lIndex = select._h_select.listeners.indexOf(onModelChange);
6804
+ select._h_select.listeners.splice(lIndex, 1);
6687
6805
  });
6688
6806
  });
6689
6807
  Alpine.directive("h-select-separator", (el) => {
@@ -6727,17 +6845,17 @@
6727
6845
  el.setAttribute("data-open", isOpen);
6728
6846
  });
6729
6847
  });
6730
- const onClick = (event) => {
6848
+ const onClick2 = (event) => {
6731
6849
  if (event.target.getAttribute("data-slot") === "sheet-overlay") {
6732
6850
  evaluate2(`${expression} = false`);
6733
6851
  }
6734
6852
  };
6735
- el.addEventListener("click", onClick);
6853
+ el.addEventListener("click", onClick2);
6736
6854
  cleanup(() => {
6737
- el.removeEventListener("click", onClick);
6855
+ el.removeEventListener("click", onClick2);
6738
6856
  });
6739
6857
  });
6740
- Alpine.directive("h-sheet", (el, {}, { cleanup }) => {
6858
+ Alpine.directive("h-sheet", (el, _, { cleanup }) => {
6741
6859
  el.classList.add("bg-background", "fixed", "shadow-lg");
6742
6860
  el.setAttribute("data-slot", "sheet");
6743
6861
  let lastSide;
@@ -6784,10 +6902,8 @@
6784
6902
  }
6785
6903
  };
6786
6904
  setFloating();
6787
- const observer = new MutationObserver((mutations) => {
6788
- mutations.forEach(() => {
6789
- setFloating();
6790
- });
6905
+ const observer = new MutationObserver(() => {
6906
+ setFloating();
6791
6907
  });
6792
6908
  observer.observe(el, { attributes: true, attributeFilter: ["data-floating"] });
6793
6909
  cleanup(() => {
@@ -7117,7 +7233,7 @@
7117
7233
  el.setAttribute("tabindex", "-1");
7118
7234
  el.setAttribute("data-slot", "split-panel");
7119
7235
  });
7120
- Alpine.directive("h-split-gutter", (el, {}, { cleanup }) => {
7236
+ Alpine.directive("h-split-gutter", (el, _, { cleanup }) => {
7121
7237
  el.classList.add(
7122
7238
  "relative",
7123
7239
  "shrink-0",
@@ -7153,10 +7269,10 @@
7153
7269
  "hover:before:bg-primary-hover",
7154
7270
  "group-data-[orientation=horizontal]/split:!w-px",
7155
7271
  "group-data-[orientation=horizontal]/split:before:h-full",
7156
- "group-data-[orientation=horizontal]/split:before:w-[0.313rem]",
7272
+ "group-data-[orientation=horizontal]/split:before:w-[calc(var(--spacing)*1.25)]",
7157
7273
  "group-data-[orientation=vertical]/split:!h-px",
7158
7274
  "group-data-[orientation=vertical]/split:before:w-full",
7159
- "group-data-[orientation=vertical]/split:before:h-[0.313rem]"
7275
+ "group-data-[orientation=vertical]/split:before:h-[calc(var(--spacing)*1.25)]"
7160
7276
  ];
7161
7277
  const handleClasses = [
7162
7278
  "bg-transparent",
@@ -7238,7 +7354,7 @@
7238
7354
  "[&>input]:border-0",
7239
7355
  "[&>input]:cursor-pointer",
7240
7356
  "[&>input]:focus-visible:border-ring",
7241
- "[&>input]:focus-visible:ring-[3px]",
7357
+ "[&>input]:focus-visible:ring-[calc(var(--spacing)*0.75)]",
7242
7358
  "[&>input]:focus-visible:ring-ring/50",
7243
7359
  "[&>input]:left-0",
7244
7360
  "[&>input]:outline-none",
@@ -7247,27 +7363,27 @@
7247
7363
  "[&>input]:top-0",
7248
7364
  "before:bg-background",
7249
7365
  "before:duration-200",
7250
- "before:inline-block",
7251
- "before:m-[1px]",
7366
+ "before:block",
7252
7367
  "before:pointer-events-none",
7253
7368
  "before:ring-0",
7254
7369
  "before:rounded-full",
7255
7370
  "before:shadow-input",
7256
- "before:size-5",
7371
+ "before:h-full",
7372
+ "before:aspect-square",
7257
7373
  "before:transition-transform",
7258
7374
  "bg-muted",
7259
7375
  "border",
7260
- "data-[size=sm]:before:size-4",
7261
7376
  "data-[size=sm]:h-5",
7262
7377
  "data-[size=sm]:max-w-8",
7263
7378
  "data-[size=sm]:min-w-8",
7264
7379
  "duration-200",
7265
7380
  "h-6",
7266
- "has-[input:checked]:before:translate-x-[calc(100%-var(--spacing)*1)]",
7381
+ "has-[input:checked]:before:translate-x-[calc(100%-var(--spacing))]",
7267
7382
  "has-[input:checked]:bg-primary",
7268
7383
  "has-[input:checked]:border-primary-active",
7269
7384
  "has-[input:disabled]:cursor-not-allowed",
7270
7385
  "has-[input:disabled]:opacity-50",
7386
+ "p-0.25",
7271
7387
  "max-w-10",
7272
7388
  "min-w-10",
7273
7389
  "relative",
@@ -7407,7 +7523,7 @@
7407
7523
  "data-[floating=true]:shadow-xs",
7408
7524
  "data-[floating=true]:z-1",
7409
7525
  "data-[floating=true]:rounded-lg",
7410
- "data-[floating=true]:p-[0.188rem]"
7526
+ "data-[floating=true]:p-[calc(var(--spacing)*0.75)]"
7411
7527
  );
7412
7528
  el.setAttribute("data-slot", "tab-bar");
7413
7529
  });
@@ -7417,6 +7533,9 @@
7417
7533
  "flex",
7418
7534
  "items-start",
7419
7535
  "justify-start",
7536
+ "scrollbar-none",
7537
+ "group-data-[orientation=horizontal]/tabs:overflow-x-scroll",
7538
+ "group-data-[orientation=vertical]/tabs:overflow-y-scroll",
7420
7539
  "group-data-[orientation=horizontal]/tabs:flex-row",
7421
7540
  "group-data-[orientation=vertical]/tabs:flex-col",
7422
7541
  "group-data-[orientation=vertical]/tabs:h-fit",
@@ -7426,7 +7545,7 @@
7426
7545
  el.setAttribute("role", "tablist");
7427
7546
  el.setAttribute("data-slot", "tab-list");
7428
7547
  });
7429
- Alpine.directive("h-tab", (el) => {
7548
+ Alpine.directive("h-tab", (el, { original }) => {
7430
7549
  el.classList.add(
7431
7550
  "cursor-pointer",
7432
7551
  "focus-visible:border-ring",
@@ -7473,8 +7592,8 @@
7473
7592
  );
7474
7593
  el.setAttribute("role", "tab");
7475
7594
  el.setAttribute("data-slot", "tab");
7476
- if (!el.hasAttribute("id")) throw new Error("h-tab: Tabs must have an id");
7477
- if (!el.hasAttribute("aria-controls")) throw new Error("h-tab: aria-controls must be set to the tab-content id.");
7595
+ if (!el.hasAttribute("id")) throw new Error(`${original}: Tabs must have an id`);
7596
+ if (!el.hasAttribute("aria-controls")) throw new Error(`${original}: aria-controls must be set to the tab-content id.`);
7478
7597
  });
7479
7598
  Alpine.directive("h-tab-action", (el) => {
7480
7599
  el.classList.add("cursor-pointer", "ml-auto", "rounded-md", "text-foreground", "hover:bg-secondary", "hover:text-secondary-foreground", "active:bg-secondary-active");
@@ -7508,13 +7627,13 @@
7508
7627
  el.setAttribute("role", "button");
7509
7628
  el.setAttribute("data-slot", "tab-list-action");
7510
7629
  });
7511
- Alpine.directive("h-tabs-content", (el) => {
7630
+ Alpine.directive("h-tabs-content", (el, { original }) => {
7512
7631
  el.classList.add("flex-1", "outline-none");
7513
7632
  el.setAttribute("role", "tabpanel");
7514
7633
  el.setAttribute("tabindex", "0");
7515
7634
  el.setAttribute("data-slot", "tabs-content");
7516
- if (!el.hasAttribute("id")) throw new Error("h-tabs-content: Tab content must have an id");
7517
- if (!el.hasAttribute("aria-labelledby")) throw new Error("h-tabs-content: aria-labelledby must be set to the tab id.");
7635
+ if (!el.hasAttribute("id")) throw new Error(`${original}: Tab content must have an id`);
7636
+ if (!el.hasAttribute("aria-labelledby")) throw new Error(`${original}: aria-labelledby must be set to the tab id.`);
7518
7637
  });
7519
7638
  }
7520
7639
 
@@ -7577,7 +7696,7 @@
7577
7696
  el.classList.add("mt-6", "border-l-2", "pl-6", "italic");
7578
7697
  break;
7579
7698
  case "code-inline":
7580
- el.classList.add("bg-muted", "relative", "rounded", "px-[0.3rem]", "py-[0.2rem]", "font-mono", "text-sm", "font-semibold", "whitespace-pre");
7699
+ el.classList.add("bg-muted", "relative", "rounded", "px-[calc(var(--spacing)*1.2)]", "py-[calc(var(--spacing)*0.8)]", "font-mono", "text-sm", "font-semibold", "whitespace-pre");
7581
7700
  break;
7582
7701
  case "code":
7583
7702
  el.classList.add("bg-muted", "relative", "rounded", "p-3", "font-mono", "text-sm", "font-semibold", "whitespace-pre");
@@ -7630,13 +7749,13 @@
7630
7749
  "shadow-input",
7631
7750
  "transition-[color,box-shadow]",
7632
7751
  "outline-none",
7633
- "focus-visible:ring-[3px]",
7752
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
7634
7753
  "disabled:cursor-not-allowed",
7635
7754
  "disabled:opacity-50",
7636
7755
  "md:text-sm"
7637
7756
  );
7638
7757
  if (modifiers.includes("group")) {
7639
- el.classList.remove("rounded-control", "border", "bg-input-inner", "py-2", "shadow-input", "focus-visible:ring-[3px]");
7758
+ el.classList.remove("rounded-control", "border", "bg-input-inner", "py-2", "shadow-input", "focus-visible:ring-[calc(var(--spacing)*0.75)]");
7640
7759
  el.classList.add("flex-1", "resize-none", "rounded-none", "border-0", "bg-transparent", "py-3", "shadow-none", "focus-visible:ring-0");
7641
7760
  el.setAttribute("data-slot", "input-group-control");
7642
7761
  } else el.setAttribute("data-slot", "textarea");
@@ -7666,7 +7785,7 @@
7666
7785
  "outline-none",
7667
7786
  "focus-visible:border-ring",
7668
7787
  "focus-visible:ring-ring/50",
7669
- "focus-visible:ring-[3px]"
7788
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]"
7670
7789
  );
7671
7790
  el.setAttribute("data-slot", "tile");
7672
7791
  const sizes = {
@@ -7784,12 +7903,16 @@
7784
7903
  is12Hour: false,
7785
7904
  locale: void 0,
7786
7905
  seconds: void 0,
7787
- close() {
7906
+ focusInput: void 0,
7907
+ close(focus = false) {
7788
7908
  el._h_timepicker.expanded = false;
7789
7909
  top.removeEventListener("click", el._h_timepicker.close);
7910
+ if (focus && this.focusInput) {
7911
+ this.focusInput();
7912
+ }
7790
7913
  }
7791
7914
  });
7792
- el._time = {
7915
+ el._h_time = {
7793
7916
  changed: void 0,
7794
7917
  parts: {
7795
7918
  hour: null,
@@ -7803,7 +7926,7 @@
7803
7926
  "border-input",
7804
7927
  "[&>input]:appearance-none",
7805
7928
  "has-[input:focus-visible]:border-ring",
7806
- "has-[input:focus-visible]:ring-[3px]",
7929
+ "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
7807
7930
  "has-[input:focus-visible]:ring-ring/50",
7808
7931
  "dark:has-[aria-invalid=true]:ring-negative/40",
7809
7932
  "dark:has-[input:invalid]:ring-negative/40",
@@ -7866,7 +7989,7 @@
7866
7989
  } else {
7867
7990
  el._h_timepicker.is12Hour = new Intl.DateTimeFormat(el._h_timepicker.locale, { hour: "numeric" }).resolvedOptions().hour12;
7868
7991
  }
7869
- const handler2 = (event) => {
7992
+ const handler = (event) => {
7870
7993
  if (event.type === "keydown" && event.key !== "Enter") return;
7871
7994
  el._h_timepicker.expanded = !el._h_timepicker.expanded;
7872
7995
  el.setAttribute("aria-expanded", el._h_timepicker.expanded);
@@ -7878,23 +8001,26 @@
7878
8001
  }
7879
8002
  });
7880
8003
  };
7881
- el.addEventListener("click", handler2);
7882
- el.addEventListener("keydown", handler2);
8004
+ el.addEventListener("click", handler);
8005
+ el.addEventListener("keydown", handler);
7883
8006
  cleanup(() => {
7884
- el.removeEventListener("click", handler2);
7885
- el.removeEventListener("keydown", handler2);
8007
+ el.removeEventListener("click", handler);
8008
+ el.removeEventListener("keydown", handler);
7886
8009
  top.removeEventListener("click", el._h_timepicker.close);
7887
8010
  });
7888
8011
  });
7889
- Alpine.directive("h-time-picker-input", (el, {}, { effect, Alpine: Alpine2 }) => {
8012
+ Alpine.directive("h-time-picker-input", (el, { original }, { effect, Alpine: Alpine2 }) => {
7890
8013
  if (el.tagName !== "INPUT") {
7891
- throw new Error("h-time-picker-input must be a readonly input of type text");
8014
+ throw new Error(`${original} must be a readonly input of type "text"`);
7892
8015
  }
7893
8016
  const timepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_timepicker"));
7894
8017
  if (!timepicker) {
7895
- throw new Error("h-time-picker-input must be inside an h-time-picker element");
8018
+ throw new Error(`${original} must be inside a time-picker element`);
7896
8019
  }
7897
- timepicker._time.changed = () => {
8020
+ timepicker._h_timepicker.focusInput = () => {
8021
+ el.focus();
8022
+ };
8023
+ timepicker._h_time.changed = () => {
7898
8024
  Alpine2.nextTick(() => {
7899
8025
  el.dispatchEvent(new Event("change"));
7900
8026
  });
@@ -7917,7 +8043,7 @@
7917
8043
  timepicker._h_timepicker.id = `htp${v4_default()}`;
7918
8044
  el.setAttribute("id", timepicker._h_timepicker.id);
7919
8045
  }
7920
- el.classList.add("cursor-pointer", "bg-transparent", "outline-none", "flex-1", "h-full", "border-0", "focus-visible:ring-0", "md:text-sm", "text-base", "after:block", "after:w-1");
8046
+ el.classList.add("cursor-pointer", "bg-transparent", "text-transparent", "text-shadow-[0_0_0_var(--foreground)]", "outline-none", "flex-1", "h-full", "border-0", "md:text-sm", "text-base");
7921
8047
  el.readOnly = true;
7922
8048
  el.setAttribute("aria-autocomplete", "none");
7923
8049
  el.setAttribute("aria-controls", timepicker._h_timepicker.controls);
@@ -7936,22 +8062,22 @@
7936
8062
  if (timepicker._h_timepicker.is12Hour) {
7937
8063
  if (timepicker._h_timepicker.seconds) {
7938
8064
  timepicker._h_timepicker.model.set(`${hour}:${minute}:${second ?? "00"} ${period}`);
7939
- timepicker._time.parts.second = second ?? "00";
8065
+ timepicker._h_time.parts.second = second ?? "00";
7940
8066
  } else {
7941
8067
  timepicker._h_timepicker.model.set(`${hour}:${minute} ${period}`);
7942
8068
  }
7943
- timepicker._time.parts.hour = hour;
7944
- timepicker._time.parts.minute = minute;
7945
- timepicker._time.parts.period = period;
8069
+ timepicker._h_time.parts.hour = hour;
8070
+ timepicker._h_time.parts.minute = minute;
8071
+ timepicker._h_time.parts.period = period;
7946
8072
  } else {
7947
8073
  if (timepicker._h_timepicker.seconds) {
7948
8074
  timepicker._h_timepicker.model.set(`${hour}:${minute}:${second ?? "00"}`);
7949
- timepicker._time.parts.second = second ?? "00";
8075
+ timepicker._h_time.parts.second = second ?? "00";
7950
8076
  } else {
7951
8077
  timepicker._h_timepicker.model.set(`${hour}:${minute}`);
7952
8078
  }
7953
- timepicker._time.parts.hour = hour;
7954
- timepicker._time.parts.minute = minute;
8079
+ timepicker._h_time.parts.hour = hour;
8080
+ timepicker._h_time.parts.minute = minute;
7955
8081
  }
7956
8082
  }
7957
8083
  let placeholder;
@@ -7966,7 +8092,7 @@
7966
8092
  el.setAttribute("aria-expanded", timepicker._h_timepicker.expanded);
7967
8093
  });
7968
8094
  }).before("h-button");
7969
- Alpine.directive("h-time-picker-popup", (el, {}, { effect, cleanup, Alpine: Alpine2 }) => {
8095
+ Alpine.directive("h-time-picker-popup", (el, _, { effect, cleanup, Alpine: Alpine2 }) => {
7970
8096
  const timepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_timepicker"));
7971
8097
  el.classList.add(
7972
8098
  "overflow-hidden",
@@ -8008,45 +8134,45 @@
8008
8134
  ];
8009
8135
  const updateModel = () => {
8010
8136
  let newValue;
8011
- if (timepicker._time.parts.hour !== null && timepicker._time.parts.minute !== null) {
8137
+ if (timepicker._h_time.parts.hour !== null && timepicker._h_time.parts.minute !== null) {
8012
8138
  if (timepicker._h_timepicker.seconds) {
8013
- if (timepicker._time.parts.seconds !== null) {
8014
- newValue = `${timepicker._time.parts.hour}:${timepicker._time.parts.minute}:${timepicker._time.parts.second}`;
8139
+ if (timepicker._h_time.parts.seconds !== null) {
8140
+ newValue = `${timepicker._h_time.parts.hour}:${timepicker._h_time.parts.minute}:${timepicker._h_time.parts.second}`;
8015
8141
  } else return;
8016
8142
  } else {
8017
- newValue = `${timepicker._time.parts.hour}:${timepicker._time.parts.minute}`;
8143
+ newValue = `${timepicker._h_time.parts.hour}:${timepicker._h_time.parts.minute}`;
8018
8144
  }
8019
8145
  } else return;
8020
8146
  if (timepicker._h_timepicker.is12Hour) {
8021
- if (timepicker._time.parts.period !== null) {
8022
- newValue += ` ${timepicker._time.parts.period}`;
8147
+ if (timepicker._h_time.parts.period !== null) {
8148
+ newValue += ` ${timepicker._h_time.parts.period}`;
8023
8149
  } else return;
8024
8150
  }
8025
8151
  if (newValue) {
8026
8152
  timepicker._h_timepicker.model.set(newValue);
8027
- timepicker._time.changed();
8153
+ timepicker._h_time.changed();
8028
8154
  }
8029
8155
  };
8030
8156
  const getCurrentTime = () => {
8031
8157
  let date = /* @__PURE__ */ new Date();
8032
8158
  let hour = date.getHours();
8033
- timepicker._time.parts.period = hour >= 12 ? dayPeriodLabels.pm : dayPeriodLabels.am;
8159
+ timepicker._h_time.parts.period = hour >= 12 ? dayPeriodLabels.pm : dayPeriodLabels.am;
8034
8160
  if (timepicker._h_timepicker.is12Hour) {
8035
8161
  hour = date.getHours() % 12 || 12;
8036
8162
  }
8037
8163
  let minute = date.getMinutes();
8038
- timepicker._time.parts.hour = hour < 10 ? `0${hour}` : hour.toString();
8039
- timepicker._time.parts.minute = minute < 10 ? `0${minute}` : minute.toString();
8164
+ timepicker._h_time.parts.hour = hour < 10 ? `0${hour}` : hour.toString();
8165
+ timepicker._h_time.parts.minute = minute < 10 ? `0${minute}` : minute.toString();
8040
8166
  if (timepicker._h_timepicker.seconds) {
8041
8167
  let second = date.getSeconds();
8042
- timepicker._time.parts.second = second < 10 ? `0${second}` : second.toString();
8168
+ timepicker._h_time.parts.second = second < 10 ? `0${second}` : second.toString();
8043
8169
  }
8044
8170
  updateModel();
8045
8171
  timepicker._h_timepicker.close();
8046
8172
  };
8047
8173
  function onKeyDown(event) {
8048
8174
  if (event.key === "Escape") {
8049
- timepicker._h_timepicker.close();
8175
+ timepicker._h_timepicker.close(true);
8050
8176
  } else if (event.target.tagName === "LI") {
8051
8177
  let list;
8052
8178
  let inHoursList = event.target.parentElement.dataset.type === "hours";
@@ -8060,6 +8186,7 @@
8060
8186
  list = periodList;
8061
8187
  }
8062
8188
  switch (event.key) {
8189
+ case "Up":
8063
8190
  case "ArrowUp":
8064
8191
  event.target.setAttribute("tabindex", "-1");
8065
8192
  let prevElem = event.target.previousElementSibling;
@@ -8073,6 +8200,7 @@
8073
8200
  prevElem.setAttribute("tabindex", "0");
8074
8201
  prevElem.focus();
8075
8202
  break;
8203
+ case "Down":
8076
8204
  case "ArrowDown":
8077
8205
  event.target.setAttribute("tabindex", "-1");
8078
8206
  let nextElem = event.target.nextElementSibling;
@@ -8086,6 +8214,58 @@
8086
8214
  nextElem.setAttribute("tabindex", "0");
8087
8215
  nextElem.focus();
8088
8216
  break;
8217
+ case "Home":
8218
+ case "PageUp":
8219
+ let firstChild;
8220
+ if (list.firstChild === event.target) {
8221
+ break;
8222
+ } else if (inHoursList && timepicker._h_timepicker.is12Hour) {
8223
+ if (list.children[1] === event.target) {
8224
+ break;
8225
+ } else {
8226
+ firstChild = list.children[1];
8227
+ }
8228
+ } else {
8229
+ firstChild = list.firstChild;
8230
+ }
8231
+ event.target.setAttribute("tabindex", "-1");
8232
+ firstChild.setAttribute("tabindex", "0");
8233
+ firstChild.focus();
8234
+ break;
8235
+ case "End":
8236
+ case "PageDown":
8237
+ let lastElem;
8238
+ if (list.lastChild === event.target) {
8239
+ break;
8240
+ } else if (inHoursList && timepicker._h_timepicker.is12Hour) {
8241
+ if (list.children[12] !== event.target) {
8242
+ lastElem = list.children[12];
8243
+ } else {
8244
+ break;
8245
+ }
8246
+ } else {
8247
+ lastElem = list.lastChild;
8248
+ }
8249
+ event.target.setAttribute("tabindex", "-1");
8250
+ lastElem.setAttribute("tabindex", "0");
8251
+ lastElem.focus();
8252
+ break;
8253
+ case "Right":
8254
+ case "ArrowRight":
8255
+ let nextColumn = event.target.parentElement.nextElementSibling;
8256
+ if (nextColumn) {
8257
+ const child = nextColumn.querySelector('li[tabindex="0"]');
8258
+ child.focus();
8259
+ }
8260
+ break;
8261
+ case "Left":
8262
+ case "ArrowLeft":
8263
+ let prevColumn = event.target.parentElement.previousElementSibling;
8264
+ if (prevColumn) {
8265
+ const child = prevColumn.querySelector('li[tabindex="0"]');
8266
+ child.focus();
8267
+ }
8268
+ break;
8089
8269
  case "Enter":
8090
8270
  case " ":
8091
8271
  event.target.click();
@@ -8111,13 +8291,13 @@
8111
8291
  function setTime(event) {
8112
8292
  if (event.target.tagName === "LI") {
8113
8293
  if (event.target.parentElement.dataset.type === "hours") {
8114
- timepicker._time.parts.hour = event.target.innerText;
8294
+ timepicker._h_time.parts.hour = event.target.innerText;
8115
8295
  } else if (event.target.parentElement.dataset.type === "minutes") {
8116
- timepicker._time.parts.minute = event.target.innerText;
8296
+ timepicker._h_time.parts.minute = event.target.innerText;
8117
8297
  } else if (event.target.parentElement.dataset.type === "seconds") {
8118
- timepicker._time.parts.second = event.target.innerText;
8298
+ timepicker._h_time.parts.second = event.target.innerText;
8119
8299
  } else if (event.target.parentElement.dataset.type === "period") {
8120
- timepicker._time.parts.period = event.target.innerText;
8300
+ timepicker._h_time.parts.period = event.target.innerText;
8121
8301
  }
8122
8302
  render();
8123
8303
  updateModel();
@@ -8236,7 +8416,7 @@
8236
8416
  if (timepicker._h_timepicker.is12Hour) {
8237
8417
  hoursList.firstChild.classList.add("hidden");
8238
8418
  for (let h = 1; h < 13; h++) {
8239
- if (hoursList.children[h].innerText === timepicker._time.parts.hour) {
8419
+ if (hoursList.children[h].innerText === timepicker._h_time.parts.hour) {
8240
8420
  hoursList.children[h].setAttribute("tabindex", "0");
8241
8421
  hoursList.children[h].setAttribute("aria-selected", true);
8242
8422
  selectedHour = hoursList.children[h];
@@ -8253,7 +8433,7 @@
8253
8433
  } else {
8254
8434
  for (let h = 0; h < hoursList.children.length; h++) {
8255
8435
  hoursList.children[h].classList.remove("hidden");
8256
- if (hoursList.children[h].innerText === timepicker._time.parts.hour) {
8436
+ if (hoursList.children[h].innerText === timepicker._h_time.parts.hour) {
8257
8437
  hoursList.children[h].setAttribute("tabindex", "0");
8258
8438
  hoursList.children[h].setAttribute("aria-selected", true);
8259
8439
  selectedHour = hoursList.children[h];
@@ -8267,7 +8447,7 @@
8267
8447
  hoursList.children[timepicker._h_timepicker.is12Hour ? 1 : 0].setAttribute("tabindex", "0");
8268
8448
  }
8269
8449
  for (let m = 0; m < minutesList.children.length; m++) {
8270
- if (minutesList.children[m].innerText === timepicker._time.parts.minute) {
8450
+ if (minutesList.children[m].innerText === timepicker._h_time.parts.minute) {
8271
8451
  minutesList.children[m].setAttribute("tabindex", "0");
8272
8452
  minutesList.children[m].setAttribute("aria-selected", true);
8273
8453
  selectedMinute = minutesList.children[m];
@@ -8282,7 +8462,7 @@
8282
8462
  if (timepicker._h_timepicker.seconds) {
8283
8463
  secondsList.classList.remove("hidden");
8284
8464
  for (let s = 0; s < secondsList.children.length; s++) {
8285
- if (secondsList.children[s].innerText === timepicker._time.parts.second) {
8465
+ if (secondsList.children[s].innerText === timepicker._h_time.parts.second) {
8286
8466
  secondsList.children[s].setAttribute("tabindex", "0");
8287
8467
  secondsList.children[s].setAttribute("aria-selected", true);
8288
8468
  selectedSecond = secondsList.children[s];
@@ -8295,22 +8475,22 @@
8295
8475
  secondsList.firstChild.setAttribute("tabindex", "0");
8296
8476
  }
8297
8477
  if (timepicker._h_timepicker.is12Hour) {
8298
- okButton.disabled = timepicker._time.parts.hour && timepicker._time.parts.minute && timepicker._time.parts.second && timepicker._time.parts.period ? false : true;
8478
+ okButton.disabled = timepicker._h_time.parts.hour && timepicker._h_time.parts.minute && timepicker._h_time.parts.second && timepicker._h_time.parts.period ? false : true;
8299
8479
  } else {
8300
- okButton.disabled = timepicker._time.parts.hour && timepicker._time.parts.minute && timepicker._time.parts.second ? false : true;
8480
+ okButton.disabled = timepicker._h_time.parts.hour && timepicker._h_time.parts.minute && timepicker._h_time.parts.second ? false : true;
8301
8481
  }
8302
8482
  } else {
8303
8483
  secondsList.classList.add("hidden");
8304
8484
  if (timepicker._h_timepicker.is12Hour) {
8305
- okButton.disabled = timepicker._time.parts.hour && timepicker._time.parts.minute && timepicker._time.parts.period ? false : true;
8485
+ okButton.disabled = timepicker._h_time.parts.hour && timepicker._h_time.parts.minute && timepicker._h_time.parts.period ? false : true;
8306
8486
  } else {
8307
- okButton.disabled = timepicker._time.parts.hour && timepicker._time.parts.minute ? false : true;
8487
+ okButton.disabled = timepicker._h_time.parts.hour && timepicker._h_time.parts.minute ? false : true;
8308
8488
  }
8309
8489
  }
8310
8490
  if (timepicker._h_timepicker.is12Hour) {
8311
8491
  periodList.classList.remove("hidden");
8312
8492
  for (let p = 0; p < periodList.children.length; p++) {
8313
- if (periodList.children[p].innerText === timepicker._time.parts.period) {
8493
+ if (periodList.children[p].innerText === timepicker._h_time.parts.period) {
8314
8494
  periodList.children[p].setAttribute("tabindex", "0");
8315
8495
  periodList.children[p].setAttribute("aria-selected", true);
8316
8496
  selectedPeriod = periodList.children[p];
@@ -8326,10 +8506,10 @@
8326
8506
  periodList.classList.add("hidden");
8327
8507
  }
8328
8508
  }
8329
- const onClick = (event) => {
8509
+ const onClick2 = (event) => {
8330
8510
  event.stopPropagation();
8331
8511
  };
8332
- el.addEventListener("click", onClick);
8512
+ el.addEventListener("click", onClick2);
8333
8513
  let autoUpdateCleanup;
8334
8514
  function updatePosition() {
8335
8515
  computePosition2(timepicker, el, {
@@ -8366,7 +8546,7 @@
8366
8546
  });
8367
8547
  cleanup(() => {
8368
8548
  el.removeEventListener("keydown", onKeyDown);
8369
- el.removeEventListener("click", onClick);
8549
+ el.removeEventListener("click", onClick2);
8370
8550
  okButton.removeEventListener("click", timepicker._h_timepicker.close);
8371
8551
  for (let h = 0; h < hoursList.children.length; h++) {
8372
8552
  hoursList.children[h].removeEventListener("click", setHour);
@@ -8431,7 +8611,7 @@
8431
8611
 
8432
8612
  // src/components/tooltip.js
8433
8613
  function tooltip_default(Alpine) {
8434
- Alpine.directive("h-tooltip-trigger", (el, {}, { Alpine: Alpine2, cleanup }) => {
8614
+ Alpine.directive("h-tooltip-trigger", (el, _, { Alpine: Alpine2, cleanup }) => {
8435
8615
  el._tooltip = Alpine2.reactive({
8436
8616
  id: void 0,
8437
8617
  controls: `hpc${v4_default()}`,
@@ -8444,17 +8624,17 @@
8444
8624
  el.setAttribute("id", el._tooltip.id);
8445
8625
  }
8446
8626
  el.setAttribute("aria-describedby", el._tooltip.controls);
8447
- const handler2 = (event) => {
8627
+ const handler = (event) => {
8448
8628
  el._tooltip.shown = event.type === "pointerenter";
8449
8629
  };
8450
- el.addEventListener("pointerenter", handler2);
8451
- el.addEventListener("pointerleave", handler2);
8630
+ el.addEventListener("pointerenter", handler);
8631
+ el.addEventListener("pointerleave", handler);
8452
8632
  cleanup(() => {
8453
- el.removeEventListener("pointerenter", handler2);
8454
- el.removeEventListener("pointerleave", handler2);
8633
+ el.removeEventListener("pointerenter", handler);
8634
+ el.removeEventListener("pointerleave", handler);
8455
8635
  });
8456
8636
  });
8457
- Alpine.directive("h-tooltip", (el, {}, { effect }) => {
8637
+ Alpine.directive("h-tooltip", (el, { original }, { effect }) => {
8458
8638
  const tooltip = (() => {
8459
8639
  let sibling = el.previousElementSibling;
8460
8640
  while (sibling && !sibling.hasOwnProperty("_tooltip")) {
@@ -8463,13 +8643,13 @@
8463
8643
  return sibling;
8464
8644
  })();
8465
8645
  if (!tooltip) {
8466
- throw new Error("h-tooltip must be placed after an h-tooltip-trigger element");
8646
+ throw new Error(`${original} must be placed after a tooltip trigger element`);
8467
8647
  }
8468
8648
  el.classList.add("absolute", "bg-foreground", "text-background", "z-50", "w-fit", "rounded-md", "px-3", "py-1.5", "text-xs", "text-balance");
8469
8649
  el.setAttribute("data-slot", "tooltip");
8470
8650
  el.setAttribute("id", tooltip._tooltip.controls);
8471
8651
  const arrowEl = document.createElement("span");
8472
- arrowEl.classList.add("absolute", "bg-foreground", "fill-foreground", "z-50", "size-2.5", "rotate-45", "rounded-[2px]");
8652
+ arrowEl.classList.add("absolute", "bg-foreground", "size-2.5", "rotate-45");
8473
8653
  el.appendChild(arrowEl);
8474
8654
  function updatePosition() {
8475
8655
  computePosition2(tooltip, el, {
@@ -8480,11 +8660,12 @@
8480
8660
  left: `${x}px`,
8481
8661
  top: `${y}px`
8482
8662
  });
8483
- if (middlewareData.arrow)
8663
+ if (middlewareData.arrow) {
8484
8664
  Object.assign(arrowEl.style, {
8485
8665
  left: middlewareData.arrow.x != null ? `${middlewareData.arrow.x}px` : "",
8486
- top: placement === "top" ? `${el.offsetHeight - 5}px` : `-5px`
8666
+ top: placement === "top" ? `${el.offsetHeight - arrowEl.clientHeight / 2}px` : `-${arrowEl.clientHeight / 2}px`
8487
8667
  });
8668
+ }
8488
8669
  });
8489
8670
  }
8490
8671
  effect(() => {
@@ -8506,14 +8687,262 @@
8506
8687
  });
8507
8688
  }
8508
8689
 
8690
+ // src/components/tree.js
8691
+ function tree_default(Alpine) {
8692
+ Alpine.directive("h-tree", (el, { modifiers }, { effect, cleanup }) => {
8693
+ el.classList.add("vbox", "w-full", "min-w-0", "gap-1");
8694
+ el.setAttribute("tabindex", "-1");
8695
+ if (modifiers.includes("sub")) {
8696
+ el.classList.add(
8697
+ "relative",
8698
+ "translate-x-px",
8699
+ "py-0.5",
8700
+ "pl-4",
8701
+ "data-[border=true]:before:absolute",
8702
+ "data-[border=true]:before:left-[calc(var(--spacing)*2.5)]",
8703
+ "data-[border=true]:before:block",
8704
+ "data-[border=true]:before:top-0.5",
8705
+ "data-[border=true]:before:bottom-0.5",
8706
+ "data-[border=true]:before:min-w-px",
8707
+ "data-[border=true]:before:w-[calc(var(--spacing)*0.25)]",
8708
+ "data-[border=true]:before:bg-border"
8709
+ );
8710
+ el.setAttribute("data-slot", "subtree");
8711
+ el.setAttribute("role", "group");
8712
+ const treeItem = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_tree_item"));
8713
+ effect(() => {
8714
+ if (treeItem._h_tree_item.expanded) {
8715
+ el.classList.remove("!hidden");
8716
+ } else {
8717
+ el.classList.add("!hidden");
8718
+ }
8719
+ });
8720
+ } else {
8721
+ let getVisibleItems = function(tree) {
8722
+ return [...tree.querySelectorAll('[role="treeitem"]')].filter((item) => {
8723
+ let parent = item.parentElement.closest('[role="group"]');
8724
+ while (parent) {
8725
+ const parentItem = parent.closest('[role="treeitem"]');
8726
+ if (parentItem && parentItem.getAttribute("aria-expanded") === "false") {
8727
+ return false;
8728
+ }
8729
+ parent = parentItem?.parentElement.closest('[role="group"]');
8730
+ }
8731
+ return true;
8732
+ });
8733
+ }, focusItem = function(item) {
8734
+ [...el.querySelectorAll('[role="treeitem"]')].forEach((i) => i.setAttribute("tabindex", "-1"));
8735
+ item.setAttribute("tabindex", "0");
8736
+ item.focus();
8737
+ }, onKeyDown = function(event) {
8738
+ const items = getVisibleItems(el);
8739
+ const current = el.querySelector('li[tabindex="0"]');
8740
+ const index = items.indexOf(current);
8741
+ if (index === -1) return;
8742
+ switch (event.key) {
8743
+ case "Down":
8744
+ case "ArrowDown":
8745
+ event.preventDefault();
8746
+ if (items[index + 1]) focusItem(items[index + 1]);
8747
+ break;
8748
+ case "Up":
8749
+ case "ArrowUp":
8750
+ event.preventDefault();
8751
+ if (items[index - 1]) focusItem(items[index - 1]);
8752
+ break;
8753
+ case "Right":
8754
+ case "ArrowRight":
8755
+ if (current.getAttribute("aria-expanded") === "false") {
8756
+ current.click();
8757
+ } else {
8758
+ const firstChild = current.querySelector('[role="group"] [role="treeitem"]');
8759
+ if (firstChild) focusItem(firstChild);
8760
+ }
8761
+ break;
8762
+ case "Left":
8763
+ case "ArrowLeft":
8764
+ if (current.getAttribute("aria-expanded") === "true") {
8765
+ current.click();
8766
+ } else {
8767
+ const parentItem = current.parentElement.closest('[role="treeitem"]');
8768
+ if (parentItem) focusItem(parentItem);
8769
+ }
8770
+ break;
8771
+ case "Home":
8772
+ event.preventDefault();
8773
+ focusItem(items[0]);
8774
+ break;
8775
+ case "End":
8776
+ event.preventDefault();
8777
+ focusItem(items[items.length - 1]);
8778
+ break;
8779
+ case "Enter":
8780
+ case " ":
8781
+ event.preventDefault();
8782
+ current.click();
8783
+ break;
8784
+ }
8785
+ };
8786
+ el.setAttribute("data-slot", "tree");
8787
+ el.setAttribute("role", "tree");
8788
+ el.addEventListener("keydown", onKeyDown);
8789
+ cleanup(() => {
8790
+ el.removeEventListener("keydown", onClick);
8791
+ });
8792
+ }
8793
+ });
8794
+ Alpine.directive("h-tree-item", (el, { modifiers, expression }, { evaluate: evaluate2, evaluateLater, effect, cleanup }) => {
8795
+ el._h_tree_item = Alpine.reactive({
8796
+ hasSubtree: modifiers.includes("expanded"),
8797
+ expanded: true
8798
+ });
8799
+ el.classList.add(
8800
+ "group/tree-item",
8801
+ "relative",
8802
+ "outline-none",
8803
+ 'focus:[&>[data-slot="tree-button"]]:bg-secondary',
8804
+ 'focus:[&>[data-slot="tree-button"]]:text-secondary-foreground',
8805
+ 'aria-selected:[&>[data-slot="tree-button"]]:bg-primary',
8806
+ 'aria-selected:[&>[data-slot="tree-button"]]:font-medium',
8807
+ 'aria-selected:[&>[data-slot="tree-button"]]:text-primary-foreground'
8808
+ );
8809
+ el.setAttribute("data-slot", "tree-item");
8810
+ el.setAttribute("role", "treeitem");
8811
+ const treeRoot = Alpine.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "tree");
8812
+ if (treeRoot && treeRoot.querySelector("[data-slot=tree-item]") === el) {
8813
+ el.setAttribute("tabindex", "0");
8814
+ } else {
8815
+ el.setAttribute("tabindex", "-1");
8816
+ }
8817
+ effect(() => {
8818
+ if (!el.closest('[role="tree"]')) return;
8819
+ });
8820
+ const onClick2 = (event) => {
8821
+ if (event.target === el || event.target.parentElement === el) {
8822
+ if (el._h_tree_item.hasSubtree) {
8823
+ if (expression === "false" || expression === "true") {
8824
+ el._h_tree_item.expanded = el.getAttribute("aria-expanded") === "true" ? false : true;
8825
+ el.setAttribute("aria-expanded", el._h_tree_item.expanded);
8826
+ } else {
8827
+ el._h_tree_item.expanded = !evaluate2(expression);
8828
+ evaluate2(`${expression} = !${expression}`);
8829
+ }
8830
+ }
8831
+ [...treeRoot.querySelectorAll('[role="treeitem"]')].forEach((i) => i.setAttribute("tabindex", "-1"));
8832
+ el.setAttribute("tabindex", "0");
8833
+ }
8834
+ };
8835
+ el.addEventListener("click", onClick2);
8836
+ cleanup(() => {
8837
+ el.removeEventListener("click", onClick2);
8838
+ });
8839
+ if (el._h_tree_item.hasSubtree) {
8840
+ const setExpanded = (expanded) => {
8841
+ el._h_tree_item.expanded = expanded;
8842
+ el.setAttribute("aria-expanded", expanded);
8843
+ };
8844
+ const getExpanded = evaluateLater(expression);
8845
+ effect(() => {
8846
+ getExpanded((expanded) => {
8847
+ setExpanded(expanded);
8848
+ });
8849
+ });
8850
+ }
8851
+ });
8852
+ Alpine.directive("h-tree-button", (el, { original }, { effect }) => {
8853
+ const treeItem = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_tree_item"));
8854
+ if (!treeItem) throw new Error(`${original} must be inside a tree item`);
8855
+ el.classList.add(
8856
+ "flex",
8857
+ "w-full",
8858
+ "items-center",
8859
+ "gap-2",
8860
+ "overflow-hidden",
8861
+ "rounded-md",
8862
+ "p-1.5",
8863
+ "text-left",
8864
+ "text-sm",
8865
+ "align-middle",
8866
+ "outline-hidden",
8867
+ "ring-ring",
8868
+ "transition-[width,height,padding]",
8869
+ "hover:bg-secondary",
8870
+ "hover:text-secondary-foreground",
8871
+ "focus-visible:ring-2",
8872
+ "active:bg-primary",
8873
+ "active:text-primary-foreground",
8874
+ "disabled:pointer-events-none",
8875
+ "disabled:opacity-50",
8876
+ "aria-disabled:pointer-events-none",
8877
+ "aria-disabled:opacity-50",
8878
+ "[&>span]:w-full",
8879
+ "[&>span]:truncate",
8880
+ "[&>span]:align-middle",
8881
+ "[&>span]:pointer-events-none",
8882
+ "[&>svg]:size-4",
8883
+ "[&>svg]:shrink-0",
8884
+ "[&>svg]:pointer-events-none",
8885
+ "data-[indicator]:after:block",
8886
+ "data-[indicator]:after:ml-auto",
8887
+ "data-[indicator]:after:rounded-full",
8888
+ "data-[indicator]:after:size-2",
8889
+ "data-[indicator=positive]:after:bg-positive",
8890
+ "data-[indicator=negative]:after:bg-negative",
8891
+ "data-[indicator=warning]:after:bg-warning",
8892
+ "data-[indicator=information]:after:bg-information",
8893
+ "before:mr-1",
8894
+ "before:bg-transparent",
8895
+ "before:min-w-1.5",
8896
+ "before:size-1.5",
8897
+ "before:pointer-events-none"
8898
+ );
8899
+ el.setAttribute("data-slot", "tree-button");
8900
+ el.setAttribute("tabindex", "-1");
8901
+ el.setAttribute("role", "presentation");
8902
+ if (treeItem._h_tree_item.hasSubtree) {
8903
+ el.classList.add(
8904
+ "before:block",
8905
+ "before:mr-1",
8906
+ "before:bg-transparent",
8907
+ "before:border-t-[calc(var(--spacing)*0.25)]",
8908
+ "before:border-r-[calc(var(--spacing)*0.25)]",
8909
+ "before:border-foreground",
8910
+ "active:before:border-primary-foreground",
8911
+ "before:pointer-events-none",
8912
+ "before:min-w-1.5",
8913
+ "before:size-1.5",
8914
+ "before:rounded-[calc(var(--spacing)*0.25)]",
8915
+ "before:rotate-135",
8916
+ "before:translate-x-1/2",
8917
+ "before:-translate-y-0.25",
8918
+ "data-[expanded=false]:before:rotate-45",
8919
+ "data-[expanded=false]:before:translate-x-1/2",
8920
+ "data-[expanded=false]:before:-translate-y-0",
8921
+ "aria-selected:before:border-primary-foreground"
8922
+ );
8923
+ }
8924
+ effect(() => {
8925
+ el.setAttribute("data-expanded", treeItem._h_tree_item.expanded);
8926
+ });
8927
+ });
8928
+ }
8929
+
8509
8930
  // src/utils/theme.js
8510
8931
  var colorSchemeKey = "codbex.harmonia.colorMode";
8511
8932
  var savedScheme = localStorage.getItem(colorSchemeKey);
8933
+ var callbacks = [];
8934
+ var onColorSchemeChange = (scheme) => {
8935
+ for (let i = 0; i < callbacks.length; i++) {
8936
+ callbacks[i](scheme);
8937
+ }
8938
+ };
8512
8939
  var colorSchemeChange = (event) => {
8513
8940
  if (event.matches) {
8514
8941
  document.documentElement.classList.add("dark");
8942
+ onColorSchemeChange("dark");
8515
8943
  } else {
8516
8944
  document.documentElement.classList.remove("dark");
8945
+ onColorSchemeChange("light");
8517
8946
  }
8518
8947
  };
8519
8948
  var initColorScheme = () => {
@@ -8533,15 +8962,19 @@
8533
8962
  document.documentElement.classList.add("dark");
8534
8963
  localStorage.setItem(colorSchemeKey, "dark");
8535
8964
  window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", colorSchemeChange);
8965
+ onColorSchemeChange("dark");
8536
8966
  } else if (mode === "light") {
8537
8967
  document.documentElement.classList.remove("dark");
8538
8968
  localStorage.setItem(colorSchemeKey, "light");
8539
8969
  window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", colorSchemeChange);
8970
+ onColorSchemeChange("light");
8540
8971
  } else {
8541
8972
  if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
8542
8973
  document.documentElement.classList.add("dark");
8974
+ onColorSchemeChange("dark");
8543
8975
  } else {
8544
8976
  document.documentElement.classList.remove("dark");
8977
+ onColorSchemeChange("light");
8545
8978
  }
8546
8979
  localStorage.setItem(colorSchemeKey, "auto");
8547
8980
  window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", colorSchemeChange);
@@ -8555,16 +8988,27 @@
8555
8988
  }
8556
8989
  return "light";
8557
8990
  };
8991
+ var addColorSchemeListener = (callback) => {
8992
+ callbacks.push(callback);
8993
+ };
8994
+ var removeColorSchemeListener = (callback) => {
8995
+ for (let i = 0; i < callbacks.length; i++) {
8996
+ if (callbacks[i] === callback) {
8997
+ callbacks.splice(i, 1);
8998
+ return;
8999
+ }
9000
+ }
9001
+ };
8558
9002
  initColorScheme();
8559
9003
 
8560
9004
  // src/utils/breakpoint-listener.js
8561
- function getBreakpointListener(handler2, breakpoint = 768) {
9005
+ function getBreakpointListener(handler, breakpoint = 768) {
8562
9006
  const mql = top.matchMedia(`(width <= ${breakpoint}px)`);
8563
9007
  const onWidthChange = (event) => {
8564
- handler2(event.matches);
9008
+ handler(event.matches);
8565
9009
  };
8566
9010
  mql.addEventListener("change", onWidthChange);
8567
- handler2(mql.matches);
9011
+ handler(mql.matches);
8568
9012
  return {
8569
9013
  _mql: mql,
8570
9014
  _onWidthChange: onWidthChange,
@@ -8574,6 +9018,26 @@
8574
9018
  };
8575
9019
  }
8576
9020
 
9021
+ // src/utils/template.js
9022
+ function template_default(Alpine) {
9023
+ Alpine.directive("h-template", (el, { original, expression }, { evaluate: evaluate2, Alpine: Alpine2, cleanup }) => {
9024
+ if (el.hasAttribute(Alpine2.prefixed("data"))) {
9025
+ const template = evaluate2(expression);
9026
+ const clone = template.content.cloneNode(true).firstElementChild;
9027
+ Alpine2.addScopeToNode(clone, Alpine2.closestDataStack(el)[0], el.parentElement);
9028
+ Alpine2.mutateDom(() => {
9029
+ el.before(clone);
9030
+ Alpine2.initTree(clone);
9031
+ });
9032
+ cleanup(() => {
9033
+ clone.remove();
9034
+ });
9035
+ } else {
9036
+ console.error(`${original}: ${Alpine2.prefixed("data")} directive is missing`);
9037
+ }
9038
+ });
9039
+ }
9040
+
8577
9041
  // src/utils/focus.js
8578
9042
  function focus_default(Alpine) {
8579
9043
  Alpine.directive("h-focus", (el, { expression }, { effect, evaluateLater }) => {
@@ -8587,10 +9051,10 @@
8587
9051
  }
8588
9052
 
8589
9053
  // package.json
8590
- var version = "0.7.0";
9054
+ var version = "0.9.0";
8591
9055
 
8592
9056
  // src/index.js
8593
- window.Harmonia = { getBreakpointListener, getColorScheme, setColorScheme, version };
9057
+ window.Harmonia = { getBreakpointListener, addColorSchemeListener, getColorScheme, removeColorSchemeListener, setColorScheme, version };
8594
9058
  document.addEventListener("alpine:init", () => {
8595
9059
  window.Alpine.plugin(accordion_default);
8596
9060
  window.Alpine.plugin(alert_default);
@@ -8632,7 +9096,9 @@
8632
9096
  window.Alpine.plugin(timepicker_default);
8633
9097
  window.Alpine.plugin(toolbar_default);
8634
9098
  window.Alpine.plugin(tooltip_default);
9099
+ window.Alpine.plugin(tree_default);
8635
9100
  window.Alpine.plugin(focus_default);
9101
+ window.Alpine.plugin(template_default);
8636
9102
  });
8637
9103
  })();
8638
9104
  /*! Bundled license information:
@@ -8650,7 +9116,7 @@ lucide/dist/esm/icons/clock.js:
8650
9116
  lucide/dist/esm/icons/search.js:
8651
9117
  lucide/dist/esm/lucide.js:
8652
9118
  (**
8653
- * @license lucide v0.544.0 - ISC
9119
+ * @license lucide v0.562.0 - ISC
8654
9120
  *
8655
9121
  * This source code is licensed under the ISC license.
8656
9122
  * See the LICENSE file in the root directory of this source tree.