@codbex/harmonia 0.8.0 → 0.9.1

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",
@@ -2172,7 +2181,7 @@
2172
2181
  el.classList.add("border", "rounded-control", "gap-2", "p-2");
2173
2182
  el.setAttribute("tabindex", "-1");
2174
2183
  if (datepicker) {
2175
- el.classList.add("fixed", "bg-popover", "text-popover-foreground", "data-[state=open]:flex", "data-[state=open]:flex-col", "data-[state=closed]:hidden", "z-50", "shadow-md");
2184
+ el.classList.add("absolute", "bg-popover", "text-popover-foreground", "data-[state=open]:flex", "data-[state=open]:flex-col", "data-[state=closed]:hidden", "z-50", "shadow-md");
2176
2185
  el.setAttribute("role", "dialog");
2177
2186
  el.setAttribute("aria-modal", "true");
2178
2187
  el.setAttribute("data-slot", "date-picker-calendar");
@@ -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();
@@ -2588,7 +2611,6 @@
2588
2611
  function updatePosition() {
2589
2612
  computePosition2(datepicker, el, {
2590
2613
  placement: el.getAttribute("data-align") || "bottom-start",
2591
- strategy: "fixed",
2592
2614
  middleware: [offset2(4), flip2(), shift2({ padding: 4 })]
2593
2615
  }).then(({ x, y }) => {
2594
2616
  Object.assign(el.style, {
@@ -2668,11 +2690,11 @@
2668
2690
  "[&>input]:border-0",
2669
2691
  "[&>input]:cursor-pointer",
2670
2692
  "[&>input]:focus-visible:border-ring",
2671
- "[&>input]:focus-visible:ring-[3px]",
2693
+ "[&>input]:focus-visible:ring-[calc(var(--spacing)*0.75)]",
2672
2694
  "[&>input]:focus-visible:ring-ring/50",
2673
2695
  "[&>input]:left-0",
2674
2696
  "[&>input]:outline-none",
2675
- "[&>input]:rounded-[0.25rem]",
2697
+ "[&>input]:rounded-[0.438rem]",
2676
2698
  "[&>input]:size-full",
2677
2699
  "[&>input]:top-0",
2678
2700
  "aspect-square",
@@ -2704,7 +2726,7 @@
2704
2726
  "has-[input:invalid]:border-negative",
2705
2727
  "has-[input:invalid]:ring-negative/20",
2706
2728
  "relative",
2707
- "rounded-[0.25rem]",
2729
+ "rounded-[0.438rem]",
2708
2730
  "shadow-input",
2709
2731
  "shrink-0",
2710
2732
  "size-5",
@@ -2731,10 +2753,10 @@
2731
2753
  });
2732
2754
  }
2733
2755
  });
2734
- Alpine.directive("h-collapsible-trigger", (el, { modifiers }, { effect, Alpine: Alpine2, cleanup }) => {
2756
+ Alpine.directive("h-collapsible-trigger", (el, { original, modifiers }, { effect, Alpine: Alpine2, cleanup }) => {
2735
2757
  const collapsible = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_collapsible"));
2736
2758
  if (!collapsible) {
2737
- throw new Error("h-collapsible-trigger must be inside an h-collapsible element");
2759
+ throw new Error(`${original} must be inside a collapsible element`);
2738
2760
  }
2739
2761
  if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "collapsible-trigger");
2740
2762
  if (modifiers.includes("chevron")) {
@@ -2742,21 +2764,21 @@
2742
2764
  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
2765
  else el.classList.add("[&[data-state=open]>svg:not(:first-child):last-child]:rotate-180", "[&[data-state=open]>svg:only-child]:rotate-180");
2744
2766
  }
2745
- const handler2 = () => {
2767
+ const handler = () => {
2746
2768
  collapsible._h_collapsible.expanded = !collapsible._h_collapsible.expanded;
2747
2769
  };
2748
2770
  effect(() => {
2749
2771
  el.setAttribute("data-state", collapsible._h_collapsible.expanded ? "open" : "closed");
2750
2772
  });
2751
- el.addEventListener("click", handler2);
2773
+ el.addEventListener("click", handler);
2752
2774
  cleanup(() => {
2753
- el.removeEventListener("click", handler2);
2775
+ el.removeEventListener("click", handler);
2754
2776
  });
2755
2777
  });
2756
- Alpine.directive("h-collapsible-content", (el, {}, { effect, Alpine: Alpine2 }) => {
2778
+ Alpine.directive("h-collapsible-content", (el, { original }, { effect, Alpine: Alpine2 }) => {
2757
2779
  const collapsible = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_collapsible"));
2758
2780
  if (!collapsible) {
2759
- throw new Error("h-collapsible-content must be inside an h-collapsible element");
2781
+ throw new Error(`${original} must be inside an h-collapsible element`);
2760
2782
  }
2761
2783
  if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "collapsible-content");
2762
2784
  el.classList.add("data-[state=closed]:!hidden");
@@ -2768,7 +2790,7 @@
2768
2790
 
2769
2791
  // src/components/datepicker.js
2770
2792
  function datepicker_default(Alpine) {
2771
- Alpine.directive("h-date-picker", (el, {}, { Alpine: Alpine2 }) => {
2793
+ Alpine.directive("h-date-picker", (el, { original }, { Alpine: Alpine2 }) => {
2772
2794
  el._h_datepicker = Alpine2.reactive({
2773
2795
  id: void 0,
2774
2796
  controls: `hdpc${v4_default()}`,
@@ -2777,7 +2799,7 @@
2777
2799
  });
2778
2800
  el._h_datepicker.input = el.querySelector("input");
2779
2801
  if (!el._h_datepicker.input || el._h_datepicker.input.tagName !== "INPUT") {
2780
- throw new Error("h-date-picker must have an input inside it");
2802
+ throw new Error(`${original} must contain an input`);
2781
2803
  } else if (el._h_datepicker.input.hasAttribute("id")) {
2782
2804
  el._h_datepicker.id = el._h_datepicker.input.getAttribute("id");
2783
2805
  } else {
@@ -2804,7 +2826,7 @@
2804
2826
  "min-w-0",
2805
2827
  "has-[input:focus-visible]:border-ring",
2806
2828
  "has-[input:focus-visible]:ring-ring/50",
2807
- "has-[input:focus-visible]:ring-[3px]",
2829
+ "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
2808
2830
  "has-[input[aria-invalid=true]]:ring-negative/20",
2809
2831
  "has-[input[aria-invalid=true]]:border-negative",
2810
2832
  "dark:has-[input[aria-invalid=true]]:ring-negative/40",
@@ -2813,20 +2835,32 @@
2813
2835
  "dark:has-[input:invalid]:ring-negative/40"
2814
2836
  );
2815
2837
  el.setAttribute("data-slot", "date-picker");
2816
- el._h_datepicker.input.classList.add("bg-transparent", "outline-none", "flex-1", "border-0", "focus-visible:ring-0", "disabled:pointer-events-none", "disabled:cursor-not-allowed", "disabled:opacity-50", "md:text-sm", "text-base");
2838
+ el._h_datepicker.input.classList.add(
2839
+ "bg-transparent",
2840
+ "outline-none",
2841
+ "flex-1",
2842
+ "h-full",
2843
+ "border-0",
2844
+ "focus-visible:ring-0",
2845
+ "disabled:pointer-events-none",
2846
+ "disabled:cursor-not-allowed",
2847
+ "disabled:opacity-50",
2848
+ "md:text-sm",
2849
+ "text-base"
2850
+ );
2817
2851
  el._h_datepicker.input.setAttribute("aria-autocomplete", "none");
2818
2852
  el._h_datepicker.input.setAttribute("type", "text");
2819
2853
  });
2820
- Alpine.directive("h-date-picker-trigger", (el, {}, { effect, cleanup, Alpine: Alpine2 }) => {
2854
+ Alpine.directive("h-date-picker-trigger", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
2821
2855
  if (el.tagName !== "BUTTON") {
2822
- throw new Error("h-date-picker-trigger must be a button");
2856
+ throw new Error(`${original} must be a button`);
2823
2857
  }
2824
2858
  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');
2859
+ throw new Error(`${original}: must have an "aria-label" or "aria-labelledby" attribute`);
2826
2860
  }
2827
2861
  const datepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_datepicker"));
2828
2862
  if (!datepicker) {
2829
- throw new Error("h-date-picker-trigger must be inside an h-date-picker element");
2863
+ throw new Error(`${original} must be inside an date-picker element`);
2830
2864
  }
2831
2865
  el.setAttribute("aria-controls", datepicker._h_datepicker.controls);
2832
2866
  el.setAttribute("aria-expanded", "false");
@@ -2849,7 +2883,7 @@
2849
2883
  const close = () => {
2850
2884
  datepicker._h_datepicker.expanded = false;
2851
2885
  };
2852
- const handler2 = () => {
2886
+ const handler = () => {
2853
2887
  datepicker._h_datepicker.expanded = !datepicker._h_datepicker.expanded;
2854
2888
  el.setAttribute("aria-expanded", datepicker._h_datepicker.expanded);
2855
2889
  Alpine2.nextTick(() => {
@@ -2860,9 +2894,9 @@
2860
2894
  }
2861
2895
  });
2862
2896
  };
2863
- el.addEventListener("click", handler2);
2897
+ el.addEventListener("click", handler);
2864
2898
  cleanup(() => {
2865
- el.removeEventListener("click", handler2);
2899
+ el.removeEventListener("click", handler);
2866
2900
  top.removeEventListener("click", close);
2867
2901
  });
2868
2902
  }).before("h-button");
@@ -2870,42 +2904,40 @@
2870
2904
 
2871
2905
  // src/components/dialog.js
2872
2906
  function dialog_default(Alpine) {
2873
- Alpine.directive("h-dialog-overlay", (el, {}, { cleanup }) => {
2907
+ Alpine.directive("h-dialog-overlay", (el, _, { cleanup }) => {
2874
2908
  el.classList.add("hidden", "data-[open=true]:block", "fixed", "inset-0", "z-50", "bg-black/60");
2875
2909
  el.setAttribute("tabindex", "-1");
2876
2910
  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();
2911
+ const observer = new MutationObserver(() => {
2912
+ if (el.getAttribute("data-open") === "true") {
2913
+ const inputs = el.getElementsByTagName("INPUT");
2914
+ if (inputs.length) {
2915
+ for (let i = 0; i < inputs.length; i++) {
2916
+ if (inputs[i].autofocus) {
2917
+ inputs[i].focus();
2918
+ return;
2919
+ }
2920
+ }
2921
+ inputs[0].focus();
2922
+ return;
2923
+ } else {
2924
+ const textareas = el.getElementsByTagName("TEXTAREA");
2925
+ if (textareas.length) {
2926
+ for (let i = 0; i < textareas.length; i++) {
2927
+ if (textareas[i].autofocus) {
2928
+ textareas[i].focus();
2885
2929
  return;
2886
2930
  }
2887
2931
  }
2888
- inputs[0].focus();
2932
+ textareas[0].focus();
2889
2933
  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
2934
  }
2907
2935
  }
2908
- });
2936
+ const buttons = el.getElementsByTagName("BUTTON");
2937
+ if (buttons.length) {
2938
+ buttons[0].focus();
2939
+ }
2940
+ }
2909
2941
  });
2910
2942
  observer.observe(el, { attributes: true, attributeFilter: ["data-open"] });
2911
2943
  cleanup(() => {
@@ -2941,7 +2973,7 @@
2941
2973
  el.classList.add("grid", "grid-cols-[1fr_auto]", "place-items-start", "gap-2", "text-center", "sm:text-left");
2942
2974
  el.setAttribute("data-slot", "dialog-header");
2943
2975
  });
2944
- Alpine.directive("h-dialog-title", (el, {}, { Alpine: Alpine2 }) => {
2976
+ Alpine.directive("h-dialog-title", (el, _, { Alpine: Alpine2 }) => {
2945
2977
  el.classList.add("text-lg", "leading-none", "font-semibold");
2946
2978
  el.setAttribute("data-slot", "dialog-title");
2947
2979
  const dialog = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "dialog");
@@ -2971,7 +3003,7 @@
2971
3003
  );
2972
3004
  el.setAttribute("data-slot", "dialog-close");
2973
3005
  });
2974
- Alpine.directive("h-dialog-description", (el, {}, { Alpine: Alpine2 }) => {
3006
+ Alpine.directive("h-dialog-description", (el, _, { Alpine: Alpine2 }) => {
2975
3007
  el.classList.add("col-span-full", "text-muted-foreground", "text-sm");
2976
3008
  el.setAttribute("data-slot", "dialog-description");
2977
3009
  const dialog = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "dialog");
@@ -3060,13 +3092,13 @@
3060
3092
 
3061
3093
  // src/components/icon.js
3062
3094
  function icon_default(Alpine) {
3063
- Alpine.directive("h-icon", (el) => {
3095
+ Alpine.directive("h-icon", (el, { original }) => {
3064
3096
  if (el.tagName.toLowerCase() !== "svg") {
3065
- throw new Error("h-icon works only on svg elements");
3097
+ throw new Error(`${original} works only on svg elements`);
3066
3098
  } else if (!el.hasAttribute("role")) {
3067
- throw new Error("h-icon must have a role");
3099
+ throw new Error(`${original} must have a role`);
3068
3100
  } 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');
3101
+ throw new Error(`${original}: svg images with the role of img must have an "aria-label" or "aria-labelledby" attribute`);
3070
3102
  }
3071
3103
  el.classList.add("fill-current");
3072
3104
  el.setAttribute("data-slot", "icon");
@@ -3155,7 +3187,7 @@
3155
3187
  "md:text-sm",
3156
3188
  "focus-visible:border-ring",
3157
3189
  "focus-visible:ring-ring/50",
3158
- "focus-visible:ring-[3px]",
3190
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
3159
3191
  "aria-invalid:ring-negative/20",
3160
3192
  "dark:aria-invalid:ring-negative/40",
3161
3193
  "aria-invalid:border-negative",
@@ -3164,7 +3196,7 @@
3164
3196
  "invalid:!border-negative"
3165
3197
  );
3166
3198
  if (modifiers.includes("group")) {
3167
- el.classList.remove("rounded-control", "border", "bg-input-inner", "shadow-input", "focus-visible:ring-[3px]");
3199
+ el.classList.remove("rounded-control", "border", "bg-input-inner", "shadow-input", "focus-visible:ring-[calc(var(--spacing)*0.75)]");
3168
3200
  el.classList.add("flex-1", "rounded-none", "border-0", "bg-transparent", "shadow-none", "focus-visible:ring-0");
3169
3201
  el.setAttribute("data-slot", "input-group-control");
3170
3202
  } else el.setAttribute("data-slot", "input");
@@ -3199,7 +3231,7 @@
3199
3231
  "has-[>[data-align=block-end]]:[&>input]:pt-3",
3200
3232
  "has-[[data-slot=input-group-control]:focus-visible]:border-ring",
3201
3233
  "has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50",
3202
- "has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]",
3234
+ "has-[[data-slot=input-group-control]:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
3203
3235
  "has-[[data-slot][aria-invalid=true]]:ring-negative/20",
3204
3236
  "has-[[data-slot][aria-invalid=true]]:border-negative",
3205
3237
  "dark:has-[[data-slot][aria-invalid=true]]:ring-negative/40"
@@ -3207,7 +3239,7 @@
3207
3239
  el.setAttribute("role", "group");
3208
3240
  el.setAttribute("data-slot", "input-group");
3209
3241
  });
3210
- Alpine.directive("h-input-group-addon", (el, {}, { cleanup }) => {
3242
+ Alpine.directive("h-input-group-addon", (el, _, { cleanup }) => {
3211
3243
  el.classList.add(
3212
3244
  "text-muted-foreground",
3213
3245
  "flex",
@@ -3237,7 +3269,7 @@
3237
3269
  if (variants.hasOwnProperty(variant)) el.classList.add(...variants[variant]);
3238
3270
  }
3239
3271
  setVariant(el.getAttribute("data-align") ?? "inline-start");
3240
- const handler2 = (event) => {
3272
+ const handler = (event) => {
3241
3273
  if (event.target.closest("button")) {
3242
3274
  return;
3243
3275
  }
@@ -3245,9 +3277,9 @@
3245
3277
  if (!input) input = event.currentTarget.parentElement?.querySelector("textarea");
3246
3278
  input?.focus();
3247
3279
  };
3248
- el.addEventListener("click", handler2);
3280
+ el.addEventListener("click", handler);
3249
3281
  cleanup(() => {
3250
- el.removeEventListener("click", handler2);
3282
+ el.removeEventListener("click", handler);
3251
3283
  });
3252
3284
  });
3253
3285
  Alpine.directive("h-input-group-text", (el) => {
@@ -3294,7 +3326,7 @@
3294
3326
 
3295
3327
  // src/components/list.js
3296
3328
  function list_default(Alpine) {
3297
- Alpine.directive("h-listbox", (el, {}, { cleanup }) => {
3329
+ Alpine.directive("h-listbox", (el, _, { cleanup }) => {
3298
3330
  el.classList.add(
3299
3331
  "divide-solid",
3300
3332
  "divide-y",
@@ -3309,7 +3341,7 @@
3309
3341
  "disabled:opacity-50",
3310
3342
  "focus-visible:border-ring",
3311
3343
  "focus-visible:ring-ring/50",
3312
- "focus-visible:ring-[3px]",
3344
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
3313
3345
  "aria-invalid:ring-negative/20",
3314
3346
  "dark:aria-invalid:ring-negative/40",
3315
3347
  "aria-invalid:border-negative",
@@ -3348,6 +3380,7 @@
3348
3380
  case "End":
3349
3381
  focusLastOption(el);
3350
3382
  break;
3383
+ case "Up":
3351
3384
  case "ArrowUp":
3352
3385
  let prevElem = event.target.previousElementSibling;
3353
3386
  if (prevElem && prevElem.getAttribute("data-slot") !== "list-header") {
@@ -3359,6 +3392,7 @@
3359
3392
  }
3360
3393
  }
3361
3394
  break;
3395
+ case "Down":
3362
3396
  case "ArrowDown":
3363
3397
  let nextElem = event.target.nextElementSibling;
3364
3398
  if (nextElem) {
@@ -3378,14 +3412,14 @@
3378
3412
  break;
3379
3413
  }
3380
3414
  }
3381
- function onClick(event) {
3415
+ function onClick2(event) {
3382
3416
  if (event.target.getAttribute("data-slot") === "list-item") selectOption(event.target);
3383
3417
  }
3384
- el.addEventListener("click", onClick);
3418
+ el.addEventListener("click", onClick2);
3385
3419
  el.addEventListener("keydown", onKeyDown);
3386
3420
  cleanup(() => {
3387
3421
  el.removeEventListener("keydown", onKeyDown);
3388
- el.removeEventListener("click", onClick);
3422
+ el.removeEventListener("click", onClick2);
3389
3423
  });
3390
3424
  });
3391
3425
  Alpine.directive("h-list", (el) => {
@@ -3393,13 +3427,13 @@
3393
3427
  el.setAttribute("data-slot", "list");
3394
3428
  el.setAttribute("role", "group");
3395
3429
  });
3396
- Alpine.directive("h-list-header", (el, {}, { Alpine: Alpine2 }) => {
3430
+ Alpine.directive("h-list-header", (el, { original }, { Alpine: Alpine2 }) => {
3397
3431
  el.classList.add("font-medium", "flex", "items-center", "p-2", "gap-2", "align-middle", "bg-table-header", "text-table-header-foreground");
3398
3432
  el.setAttribute("role", "presentation");
3399
3433
  el.setAttribute("data-slot", "list-header");
3400
3434
  const list = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "list");
3401
3435
  if (!list) {
3402
- throw new Error("h-list-header: must be placed inside an h-list element");
3436
+ throw new Error(`${original} must be placed inside a list element`);
3403
3437
  }
3404
3438
  if (!el.hasAttribute("id")) {
3405
3439
  const id = `lbh${v4_default()}`;
@@ -3447,14 +3481,14 @@
3447
3481
  isDropdown: modifiers.includes("dropdown")
3448
3482
  };
3449
3483
  });
3450
- Alpine.directive("h-menu", (el, { modifiers }, { cleanup, Alpine: Alpine2 }) => {
3484
+ Alpine.directive("h-menu", (el, { original, modifiers }, { cleanup, Alpine: Alpine2 }) => {
3451
3485
  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
3486
  el.setAttribute("role", "menu");
3453
3487
  el.setAttribute("aria-orientation", "vertical");
3454
3488
  el.setAttribute("tabindex", "-1");
3455
3489
  el.setAttribute("data-slot", "menu");
3456
3490
  if (!el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
3457
- throw new Error('h-menu: must have an "aria-label" or "aria-labelledby" attribute');
3491
+ throw new Error(`${original} must have an "aria-label" or "aria-labelledby" attribute`);
3458
3492
  }
3459
3493
  const isSubmenu = modifiers.includes("sub");
3460
3494
  const menuTrigger = (() => {
@@ -3466,7 +3500,7 @@
3466
3500
  return sibling;
3467
3501
  })();
3468
3502
  if (!isSubmenu && !menuTrigger) {
3469
- throw new Error("h-menu: menu must be placed after an h-menu-trigger element");
3503
+ throw new Error(`${original} menu must be placed after a menu trigger element`);
3470
3504
  }
3471
3505
  let menuSubItem;
3472
3506
  if (isSubmenu) menuSubItem = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "menu-sub");
@@ -3479,22 +3513,23 @@
3479
3513
  else menuTrigger.removeEventListener("contextmenu", onContextmenu);
3480
3514
  }
3481
3515
  }
3482
- function close(parent = false) {
3516
+ function close(closeParent = false, focusTrigger = false) {
3483
3517
  el.pauseKeyEvents = false;
3484
3518
  el.classList.add("hidden");
3485
3519
  Object.assign(el.style, {
3486
3520
  left: "0px",
3487
3521
  top: "0px"
3488
3522
  });
3489
- top.removeEventListener("contextmenu", onClick);
3490
- top.removeEventListener("click", onClick);
3491
- el.removeEventListener("keydown", onKeydown);
3523
+ top.removeEventListener("contextmenu", onClick2);
3524
+ top.removeEventListener("click", onClick2);
3525
+ el.removeEventListener("keydown", onKeyDown);
3492
3526
  if (isSubmenu) {
3493
- if (parent) {
3527
+ if (closeParent) {
3494
3528
  menuSubItem._menu_sub.closeTree();
3495
3529
  }
3496
3530
  } else {
3497
3531
  listenForTrigger(true);
3532
+ if (focusTrigger) menuTrigger.focus();
3498
3533
  }
3499
3534
  }
3500
3535
  el._menu = { close };
@@ -3515,12 +3550,12 @@
3515
3550
  }
3516
3551
  return false;
3517
3552
  }
3518
- function onClick(event) {
3553
+ function onClick2(event) {
3519
3554
  if (event.type === "contextmenu") event.preventDefault();
3520
3555
  close(isSubmenu);
3521
3556
  }
3522
3557
  el.pauseKeyEvents = false;
3523
- function onKeydown(event) {
3558
+ function onKeyDown(event) {
3524
3559
  if (!el.pauseKeyEvents) {
3525
3560
  let menuitem;
3526
3561
  switch (event.key) {
@@ -3536,7 +3571,7 @@
3536
3571
  if (isSubmenu) {
3537
3572
  Alpine2.nextTick(() => menuSubItem.focus());
3538
3573
  }
3539
- close();
3574
+ close(void 0, true);
3540
3575
  break;
3541
3576
  case "Tab":
3542
3577
  case " ":
@@ -3633,9 +3668,9 @@
3633
3668
  listenForTrigger(false);
3634
3669
  }
3635
3670
  Alpine2.nextTick(() => {
3636
- top.addEventListener("contextmenu", onClick);
3637
- top.addEventListener("click", onClick);
3638
- el.addEventListener("keydown", onKeydown);
3671
+ top.addEventListener("contextmenu", onClick2);
3672
+ top.addEventListener("click", onClick2);
3673
+ el.addEventListener("keydown", onKeyDown);
3639
3674
  });
3640
3675
  Object.assign(el.style, {
3641
3676
  left: `${x}px`,
@@ -3673,12 +3708,12 @@
3673
3708
  }
3674
3709
  cleanup(() => {
3675
3710
  listenForTrigger(false);
3676
- top.removeEventListener("click", onClick);
3677
- top.removeEventListener("contextmenu", onClick);
3678
- el.removeEventListener("keydown", onKeydown);
3711
+ top.removeEventListener("click", onClick2);
3712
+ top.removeEventListener("contextmenu", onClick2);
3713
+ el.removeEventListener("keydown", onKeyDown);
3679
3714
  });
3680
3715
  });
3681
- Alpine.directive("h-menu-item", (el, {}, { cleanup, Alpine: Alpine2 }) => {
3716
+ Alpine.directive("h-menu-item", (el, _, { cleanup, Alpine: Alpine2 }) => {
3682
3717
  el.classList.add(
3683
3718
  "focus:bg-secondary-hover",
3684
3719
  "focus:text-secondary-foreground",
@@ -3731,7 +3766,7 @@
3731
3766
  el.removeEventListener("mouseleave", focusOut);
3732
3767
  });
3733
3768
  });
3734
- Alpine.directive("h-menu-sub", (el, {}, { cleanup, Alpine: Alpine2 }) => {
3769
+ Alpine.directive("h-menu-sub", (el, { original }, { cleanup, Alpine: Alpine2 }) => {
3735
3770
  el.classList.add(
3736
3771
  "focus:bg-secondary-hover",
3737
3772
  "hover:bg-secondary-hover",
@@ -3756,12 +3791,13 @@
3756
3791
  "[&_svg:not([class*='size-'])]:size-4",
3757
3792
  "after:block",
3758
3793
  "after:bg-transparent",
3759
- "after:border-t-[0.063rem]",
3760
- "after:border-r-[0.063rem]",
3794
+ "after:border-t-[calc(var(--spacing)*0.25)]",
3795
+ "after:border-r-[calc(var(--spacing)*0.25)]",
3761
3796
  "after:border-muted-foreground",
3762
3797
  "after:pointer-events-none",
3763
- "after:size-[0.438rem]",
3764
- "after:rounded-[0.063rem]",
3798
+ "after:min-w-1.75",
3799
+ "after:size-1.75",
3800
+ "after:rounded-[calc(var(--spacing)*0.25)]",
3765
3801
  "after:rotate-45",
3766
3802
  "after:ml-auto",
3767
3803
  "after:-translate-x-0.75"
@@ -3772,7 +3808,7 @@
3772
3808
  el.setAttribute("tabindex", "-1");
3773
3809
  el.setAttribute("data-slot", "menu-sub");
3774
3810
  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");
3811
+ if (!parentMenu) throw new Error(`${original} must have a parent`);
3776
3812
  el._menu_sub = {
3777
3813
  open: void 0,
3778
3814
  close: void 0,
@@ -3780,17 +3816,17 @@
3780
3816
  closeTree() {
3781
3817
  el.setAttribute("aria-expanded", "false");
3782
3818
  this.expanded = false;
3783
- el.removeEventListener("keydown", onKeydown);
3819
+ el.removeEventListener("keydown", onKeyDown);
3784
3820
  parentMenu.pauseKeyEvents = false;
3785
3821
  parentMenu._menu.close(true);
3786
3822
  }
3787
3823
  };
3788
3824
  const keyEvents = ["Right", "ArrowRight", "Enter", " "];
3789
- function onKeydown(event) {
3825
+ function onKeyDown(event) {
3790
3826
  if (keyEvents.includes(event.key)) {
3791
3827
  event.stopPropagation();
3792
3828
  event.preventDefault();
3793
- el.removeEventListener("keydown", onKeydown);
3829
+ el.removeEventListener("keydown", onKeyDown);
3794
3830
  const submenuitem = el.querySelector('[role^=menuitem][tabIndex="-1"]:first-of-type');
3795
3831
  if (submenuitem) {
3796
3832
  el.setAttribute("aria-expanded", "true");
@@ -3817,7 +3853,7 @@
3817
3853
  el._menu_sub.expanded = false;
3818
3854
  el.setAttribute("aria-expanded", false);
3819
3855
  parentMenu.pauseKeyEvents = false;
3820
- el.removeEventListener("keydown", onKeydown);
3856
+ el.removeEventListener("keydown", onKeyDown);
3821
3857
  }
3822
3858
  }
3823
3859
  function focusIn(event) {
@@ -3838,7 +3874,7 @@
3838
3874
  el.setAttribute("aria-expanded", false);
3839
3875
  parentMenu.pauseKeyEvents = false;
3840
3876
  }
3841
- el.addEventListener("keydown", onKeydown);
3877
+ el.addEventListener("keydown", onKeyDown);
3842
3878
  el.addEventListener("blur", focusOut);
3843
3879
  }
3844
3880
  }
@@ -3866,7 +3902,7 @@
3866
3902
  el.classList.add("text-foreground", "px-2", "py-1.5", "text-sm", "font-semibold", "text-left", "data-[inset=true]:pl-8");
3867
3903
  el.setAttribute("data-slot", "menu-label");
3868
3904
  });
3869
- Alpine.directive("h-menu-checkbox-item", (el, {}, { cleanup, Alpine: Alpine2 }) => {
3905
+ Alpine.directive("h-menu-checkbox-item", (el, _, { cleanup, Alpine: Alpine2 }) => {
3870
3906
  el.classList.add(
3871
3907
  "focus:bg-secondary-hover",
3872
3908
  "hover:bg-secondary-hover",
@@ -3895,7 +3931,6 @@
3895
3931
  "before:pointer-events-none",
3896
3932
  "before:w-2.5",
3897
3933
  "before:h-1.5",
3898
- "before:rounded-[0.125rem]",
3899
3934
  "before:-rotate-45",
3900
3935
  "before:-translate-x-0.75",
3901
3936
  "aria-[checked=true]:before:visible"
@@ -3910,13 +3945,13 @@
3910
3945
  });
3911
3946
  el.setAttribute("aria-checked", checked);
3912
3947
  }
3948
+ function onActivate() {
3949
+ el._x_model.set(!el._x_model.get());
3950
+ setState(el._x_model.get());
3951
+ }
3913
3952
  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
3953
  setState(el._x_model.get(), false);
3919
- el.addEventListener("click", handler2);
3954
+ el.addEventListener("click", onActivate);
3920
3955
  }
3921
3956
  const menu = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "menu");
3922
3957
  function focusOut(event) {
@@ -3932,8 +3967,8 @@
3932
3967
  el.addEventListener("focus", focusIn);
3933
3968
  cleanup(() => {
3934
3969
  if (el.hasOwnProperty("_x_model")) {
3935
- el.removeEventListener("click", handler);
3936
- el.removeEventListener("keydown", handler);
3970
+ el.removeEventListener("click", onActivate);
3971
+ el.removeEventListener("keydown", onActivate);
3937
3972
  }
3938
3973
  el.removeEventListener("mouseenter", focusIn);
3939
3974
  el.removeEventListener("focus", focusIn);
@@ -3983,24 +4018,24 @@
3983
4018
  el.setAttribute("aria-checked", checked);
3984
4019
  if (dispatch) el.dispatchEvent(new Event("change", { bubbles: true }));
3985
4020
  }
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);
4021
+ function onActivate(event) {
4022
+ if (event.type === "keydown") {
4023
+ if (event.key !== " " && event.key !== "Enter") {
4024
+ return;
4025
+ } else if (event.key === " ") {
4026
+ event.preventDefault();
3997
4027
  }
3998
- };
4028
+ }
4029
+ if (el._x_model.get() !== value) {
4030
+ el._x_model.set(value);
4031
+ }
4032
+ }
4033
+ if (el.hasOwnProperty("_x_model")) {
3999
4034
  effect(() => {
4000
4035
  setState(el._x_model.get() === value);
4001
4036
  });
4002
- el.addEventListener("click", handler2);
4003
- el.addEventListener("keydown", handler2);
4037
+ el.addEventListener("click", onActivate);
4038
+ el.addEventListener("keydown", onActivate);
4004
4039
  }
4005
4040
  const menu = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "menu");
4006
4041
  function focusOut(event) {
@@ -4016,8 +4051,8 @@
4016
4051
  el.addEventListener("focus", focusIn);
4017
4052
  cleanup(() => {
4018
4053
  if (el.hasOwnProperty("_x_model")) {
4019
- el.removeEventListener("click", handler);
4020
- el.removeEventListener("keydown", handler);
4054
+ el.removeEventListener("click", onActivate);
4055
+ el.removeEventListener("keydown", onActivate);
4021
4056
  }
4022
4057
  el.removeEventListener("mouseenter", focusIn);
4023
4058
  el.removeEventListener("focus", focusIn);
@@ -4061,7 +4096,7 @@
4061
4096
  "outline-none",
4062
4097
  "focus-visible:border-ring",
4063
4098
  "focus-visible:ring-ring/50",
4064
- "focus-visible:ring-[3px]",
4099
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
4065
4100
  "h-9",
4066
4101
  "min-w-9",
4067
4102
  "text-foreground",
@@ -4156,23 +4191,23 @@
4156
4191
  };
4157
4192
  const close = () => {
4158
4193
  el._popover.expanded = false;
4159
- el.addEventListener("click", handler2);
4194
+ el.addEventListener("click", handler);
4160
4195
  };
4161
- const handler2 = () => {
4196
+ const handler = () => {
4162
4197
  el._popover.expanded = !el._popover.expanded;
4163
4198
  setAttributes();
4164
4199
  Alpine2.nextTick(() => {
4165
4200
  if (el._popover.auto && el._popover.expanded) {
4166
4201
  top.addEventListener("click", close, { once: true });
4167
- el.removeEventListener("click", handler2);
4202
+ el.removeEventListener("click", handler);
4168
4203
  }
4169
4204
  });
4170
4205
  };
4171
4206
  setAttributes();
4172
4207
  if (el._popover.auto) {
4173
- el.addEventListener("click", handler2);
4208
+ el.addEventListener("click", handler);
4174
4209
  cleanup(() => {
4175
- el.removeEventListener("click", handler2);
4210
+ el.removeEventListener("click", handler);
4176
4211
  top.removeEventListener("click", close);
4177
4212
  });
4178
4213
  } else {
@@ -4181,7 +4216,7 @@
4181
4216
  });
4182
4217
  }
4183
4218
  });
4184
- Alpine.directive("h-popover", (el, { modifiers }, { effect }) => {
4219
+ Alpine.directive("h-popover", (el, { original, modifiers }, { effect }) => {
4185
4220
  const popover = (() => {
4186
4221
  let sibling = el.previousElementSibling;
4187
4222
  while (sibling && !sibling.hasOwnProperty("_popover")) {
@@ -4190,7 +4225,7 @@
4190
4225
  return sibling;
4191
4226
  })();
4192
4227
  if (!popover) {
4193
- throw new Error("h-popover-content must be placed after an h-popover element");
4228
+ throw new Error(`${original} must be placed after a popover element`);
4194
4229
  }
4195
4230
  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
4231
  el.setAttribute("data-slot", "popover");
@@ -4276,7 +4311,7 @@
4276
4311
  "[&>input]:border-0",
4277
4312
  "[&>input]:cursor-pointer",
4278
4313
  "[&>input]:focus-visible:border-ring",
4279
- "[&>input]:focus-visible:ring-[3px]",
4314
+ "[&>input]:focus-visible:ring-[calc(var(--spacing)*0.75)]",
4280
4315
  "[&>input]:focus-visible:ring-ring/50",
4281
4316
  "[&>input]:left-0",
4282
4317
  "[&>input]:outline-none",
@@ -6202,103 +6237,175 @@
6202
6237
  none: 3
6203
6238
  });
6204
6239
  function select_default(Alpine) {
6205
- Alpine.directive("h-select", (el, {}, { Alpine: Alpine2 }) => {
6240
+ Alpine.directive("h-select", (el, _, { Alpine: Alpine2, cleanup }) => {
6206
6241
  el._h_select = Alpine2.reactive({
6207
6242
  id: void 0,
6208
6243
  controls: `hsc${v4_default()}`,
6209
6244
  expanded: false,
6210
- model: void 0,
6211
6245
  multiple: false,
6212
6246
  label: [],
6247
+ refreshLabel: void 0,
6248
+ listeners: [],
6213
6249
  search: "",
6214
6250
  focusSearch: void 0,
6215
6251
  filterType: FilterType["starts-with"]
6216
6252
  });
6253
+ el._h_model = {
6254
+ set: void 0,
6255
+ get: void 0
6256
+ };
6257
+ el.classList.add(
6258
+ "cursor-pointer",
6259
+ "border-input",
6260
+ "has-focus-visible:border-ring",
6261
+ "has-focus-visible:ring-[calc(var(--spacing)*0.75)]",
6262
+ "has-focus-visible:ring-ring/50",
6263
+ "dark:has-[aria-invalid=true]:ring-negative/40",
6264
+ "dark:has-[input:invalid]:ring-negative/40",
6265
+ "has-[aria-invalid=true]:border-negative",
6266
+ "has-[aria-invalid=true]:ring-negative/20",
6267
+ "has-[input:invalid]:border-negative",
6268
+ "has-[input:invalid]:ring-negative/20",
6269
+ "hover:bg-secondary-hover",
6270
+ "active:bg-secondary-active",
6271
+ "w-full",
6272
+ "rounded-control",
6273
+ "border",
6274
+ "bg-input-inner",
6275
+ "text-sm",
6276
+ "whitespace-nowrap",
6277
+ "shadow-input",
6278
+ "transition-[color,box-shadow]",
6279
+ "duration-200",
6280
+ "outline-none",
6281
+ "has-[input:disabled]:pointer-events-none",
6282
+ "has-[input:disabled]:opacity-50",
6283
+ "[&_svg]:pointer-events-none",
6284
+ "[&_svg]:shrink-0",
6285
+ "[&_svg]:size-4",
6286
+ "[&_svg]:opacity-50"
6287
+ );
6217
6288
  el.setAttribute("data-slot", "select");
6289
+ const setSize = (size3) => {
6290
+ if (size3 === "sm") {
6291
+ el.classList.add("h-8");
6292
+ el.classList.remove("h-9", "h-6.5");
6293
+ } else if (size3 === "xs") {
6294
+ el.classList.add("h-6.5");
6295
+ el.classList.remove("h-9", "h-8");
6296
+ } else {
6297
+ el.classList.add("h-9");
6298
+ el.classList.remove("h-8", "h-6.5");
6299
+ }
6300
+ };
6301
+ setSize(el.getAttribute("data-size"));
6302
+ const observer = new MutationObserver(() => {
6303
+ setSize(el.getAttribute("data-size"));
6304
+ });
6305
+ observer.observe(el, { attributes: true, attributeFilter: ["data-size"] });
6306
+ cleanup(() => {
6307
+ observer.disconnect();
6308
+ });
6218
6309
  });
6219
- Alpine.directive("h-select-trigger", (el, {}, { effect, cleanup, Alpine: Alpine2 }) => {
6310
+ Alpine.directive("h-select-input", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
6311
+ if (el.tagName !== "INPUT") {
6312
+ throw new Error(`${original} must be a readonly input of type "text"`);
6313
+ }
6220
6314
  const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6221
6315
  if (!select) {
6222
- throw new Error("h-select-trigger must be inside an h-select element");
6316
+ throw new Error(`${original} must be inside a select element`);
6223
6317
  } else if (el.hasOwnProperty("_x_model")) {
6224
6318
  select._h_select.multiple = Array.isArray(el._x_model.get());
6225
- select._h_select.model = el._x_model.get();
6319
+ select._h_model.set = (value) => {
6320
+ if (select._h_select.multiple) {
6321
+ const vIndex = el._x_model.get().indexOf(value);
6322
+ if (vIndex > -1) {
6323
+ const newArr = el._x_model.get();
6324
+ newArr.splice(vIndex, 1);
6325
+ el._x_model.set(newArr);
6326
+ } else {
6327
+ const arr = el._x_model.get();
6328
+ arr.push(value);
6329
+ el._x_model.set(arr);
6330
+ }
6331
+ } else if (el._x_model.get() !== value) {
6332
+ el._x_model.set(value);
6333
+ } else {
6334
+ el._x_model.set("");
6335
+ }
6336
+ };
6337
+ select._h_model.get = el._x_model.get;
6338
+ } else {
6339
+ select._h_model.set = (value) => {
6340
+ el.value = value;
6341
+ el.dispatchEvent(new Event("change", { bubbles: true }));
6342
+ };
6343
+ select._h_model.get = () => el.value;
6226
6344
  }
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");
6345
+ el.classList.add("hidden");
6346
+ el.setAttribute("type", "text");
6347
+ const fakeTrigger = document.createElement("span");
6348
+ const displayValue = document.createElement("span");
6349
+ displayValue.classList.add("text-left", "truncate", "w-full");
6350
+ fakeTrigger.appendChild(displayValue);
6351
+ fakeTrigger.setAttribute("data-slot", "select-value");
6352
+ fakeTrigger.setAttribute("tabindex", "0");
6353
+ 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
6354
  function getPlaceholder() {
6250
6355
  if (!el.value) {
6251
6356
  const value = el.getAttribute("placeholder");
6252
6357
  if (value) {
6253
- selectValue.innerText = value;
6254
- selectValue.classList.add("text-muted-foreground");
6358
+ displayValue.innerText = value;
6359
+ displayValue.classList.add("text-muted-foreground");
6255
6360
  } else {
6256
- selectValue.classList.remove("text-muted-foreground");
6361
+ displayValue.classList.remove("text-muted-foreground");
6257
6362
  }
6258
6363
  }
6259
6364
  }
6260
6365
  getPlaceholder();
6261
6366
  const observer = new MutationObserver((mutations) => {
6262
6367
  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");
6368
+ if (mutation.attributeName === "data-id") {
6369
+ select._h_select.id = el.getAttribute("data-id");
6370
+ fakeTrigger.setAttribute("id", select._h_select.id);
6266
6371
  } else if (mutation.attributeName === "placeholder" && !select._h_select.label.length) {
6267
6372
  getPlaceholder();
6268
6373
  }
6269
6374
  });
6270
6375
  });
6271
- observer.observe(el, { attributes: true, attributeFilter: ["value", "placeholder"] });
6376
+ observer.observe(el, { attributes: true, attributeFilter: ["data-id", "placeholder"] });
6272
6377
  effect(() => {
6273
6378
  if (select._h_select.label.length === 1) {
6274
- selectValue.innerText = select._h_select.label[0];
6379
+ displayValue.innerText = select._h_select.label[0];
6380
+ displayValue.classList.remove("text-muted-foreground");
6275
6381
  } else if (select._h_select.label.length > 1) {
6276
- selectValue.innerText = select._h_select.label.join(", ");
6382
+ displayValue.innerText = select._h_select.label.join(", ");
6383
+ displayValue.classList.remove("text-muted-foreground");
6277
6384
  } else {
6278
6385
  getPlaceholder();
6279
6386
  }
6280
6387
  });
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");
6388
+ fakeTrigger.setAttribute("data-slot", "select-input");
6389
+ select._h_select.id = el.hasAttribute("data-id") ? el.getAttribute("data-id") : `hs${v4_default()}`;
6390
+ fakeTrigger.setAttribute("id", select._h_select.id);
6391
+ fakeTrigger.setAttribute("aria-controls", select._h_select.controls);
6392
+ fakeTrigger.setAttribute("aria-haspopup", "listbox");
6393
+ fakeTrigger.setAttribute("aria-autocomplete", "none");
6394
+ fakeTrigger.setAttribute("role", "combobox");
6292
6395
  effect(() => {
6293
- el.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6294
- el.setAttribute("aria-expanded", select._h_select.expanded);
6396
+ fakeTrigger.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6397
+ fakeTrigger.setAttribute("aria-expanded", select._h_select.expanded);
6295
6398
  });
6296
- const close = () => {
6399
+ const close = (focusSelect = false) => {
6297
6400
  select._h_select.expanded = false;
6401
+ top.removeEventListener("click", close);
6402
+ el.parentElement.removeEventListener("keydown", onKeyDown);
6403
+ options = null;
6404
+ if (focusSelect) fakeTrigger.focus();
6298
6405
  };
6299
6406
  let content;
6300
6407
  let options;
6301
- const shiftFocus = (event) => {
6408
+ const onKeyDown = (event) => {
6302
6409
  switch (event.key) {
6303
6410
  case "Down":
6304
6411
  case "ArrowDown":
@@ -6370,13 +6477,19 @@
6370
6477
  options[options.length - 1].setAttribute("tabindex", "0");
6371
6478
  options[options.length - 1].focus();
6372
6479
  break;
6480
+ case " ":
6373
6481
  case "Enter":
6482
+ event.preventDefault();
6483
+ if (!select._h_select.multiple) {
6484
+ close(true);
6485
+ }
6486
+ break;
6374
6487
  case "Escape":
6375
- handler2();
6376
- el.focus();
6488
+ event.preventDefault();
6489
+ close(true);
6377
6490
  break;
6378
6491
  case "Tab":
6379
- handler2();
6492
+ close();
6380
6493
  break;
6381
6494
  case "Control":
6382
6495
  case "Shift":
@@ -6394,7 +6507,7 @@
6394
6507
  }
6395
6508
  }
6396
6509
  };
6397
- const handler2 = () => {
6510
+ const onClick2 = () => {
6398
6511
  select._h_select.expanded = !select._h_select.expanded;
6399
6512
  if (select._h_select.expanded) {
6400
6513
  if (!content) content = select.querySelector(`#${select._h_select.controls}`);
@@ -6403,15 +6516,26 @@
6403
6516
  Alpine2.nextTick(() => {
6404
6517
  if (select._h_select.expanded) {
6405
6518
  top.addEventListener("click", close, { once: true });
6406
- el.parentElement.addEventListener("keydown", shiftFocus);
6519
+ el.parentElement.addEventListener("keydown", onKeyDown);
6407
6520
  } else {
6408
6521
  top.removeEventListener("click", close);
6409
- el.parentElement.removeEventListener("keydown", shiftFocus);
6522
+ el.parentElement.removeEventListener("keydown", onKeyDown);
6410
6523
  options = null;
6411
6524
  }
6412
6525
  });
6413
6526
  };
6414
- el.addEventListener("click", handler2);
6527
+ const onPress = (event) => {
6528
+ if (event.key === "Escape" && select._h_select.expanded) close(true);
6529
+ else if (event.key === "Enter") {
6530
+ event.preventDefault();
6531
+ onClick2();
6532
+ } else if (event.key === " ") {
6533
+ event.preventDefault();
6534
+ setTimeout(() => onClick2(), 0);
6535
+ }
6536
+ };
6537
+ fakeTrigger.addEventListener("keydown", onPress);
6538
+ fakeTrigger.addEventListener("click", onClick2);
6415
6539
  const chevronDown = createElement(ChevronDown, {
6416
6540
  class: ["opacity-50 size-4 transition-transform duration-200"],
6417
6541
  width: "16",
@@ -6419,19 +6543,32 @@
6419
6543
  "aria-hidden": true,
6420
6544
  role: "presentation"
6421
6545
  });
6422
- el.appendChild(selectValue);
6423
- el.appendChild(chevronDown);
6546
+ el.parentElement.appendChild(fakeTrigger);
6547
+ fakeTrigger.appendChild(chevronDown);
6548
+ const onInputChange = () => {
6549
+ select._h_select.label.length = 0;
6550
+ for (let i = 0; i < select._h_select.listeners.length; i++) {
6551
+ const label = select._h_select.listeners[i](select._h_model.get());
6552
+ if (label) {
6553
+ select._h_select.label.push(label);
6554
+ }
6555
+ }
6556
+ };
6557
+ select._h_select.refreshLabel = onInputChange;
6558
+ el.addEventListener("change", onInputChange);
6424
6559
  cleanup(() => {
6425
- el.removeEventListener("click", handler2);
6426
- el.parentElement.removeEventListener("keydown", shiftFocus);
6560
+ fakeTrigger.removeEventListener("click", onClick2);
6561
+ fakeTrigger.removeEventListener("keydown", onPress);
6562
+ el.parentElement.removeEventListener("keydown", onKeyDown);
6427
6563
  top.removeEventListener("click", close);
6564
+ el.removeEventListener("change", onInputChange);
6428
6565
  observer.disconnect();
6429
6566
  });
6430
6567
  });
6431
- Alpine.directive("h-select-content", (el, {}, { effect, Alpine: Alpine2 }) => {
6568
+ Alpine.directive("h-select-content", (el, { original }, { effect, Alpine: Alpine2 }) => {
6432
6569
  const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6433
6570
  if (!select) {
6434
- throw new Error("h-select-content must be inside an h-select element");
6571
+ throw new Error(`${original} must be inside a select element`);
6435
6572
  }
6436
6573
  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
6574
  el.setAttribute("data-slot", "select-content");
@@ -6439,11 +6576,10 @@
6439
6576
  el.setAttribute("role", "presentation");
6440
6577
  el.setAttribute("id", select._h_select.controls);
6441
6578
  el.setAttribute("tabindex", "-1");
6442
- el.setAttribute("aria-labelledby", select._h_select.id);
6443
6579
  el.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6444
6580
  const control = select.querySelector(`#${select._h_select.id}`);
6445
6581
  if (!control) {
6446
- throw new Error("h-select-content: trigger not found");
6582
+ throw new Error(`${original}: trigger not found`);
6447
6583
  }
6448
6584
  let autoUpdateCleanup;
6449
6585
  function updatePosition() {
@@ -6469,6 +6605,9 @@
6469
6605
  });
6470
6606
  });
6471
6607
  }
6608
+ effect(() => {
6609
+ el.setAttribute("aria-labelledby", select._h_select.id);
6610
+ });
6472
6611
  effect(() => {
6473
6612
  el.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6474
6613
  if (select._h_select.expanded) {
@@ -6482,12 +6621,12 @@
6482
6621
  }
6483
6622
  });
6484
6623
  });
6485
- Alpine.directive("h-select-search", (el, { modifiers }, { effect, cleanup }) => {
6486
- const select = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6624
+ Alpine.directive("h-select-search", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
6625
+ const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6487
6626
  if (!select) {
6488
- throw new Error("h-select-search must be inside an h-select element");
6627
+ throw new Error(`${original} must be inside an h-select element`);
6489
6628
  } else {
6490
- select._h_select.filterType = FilterType[modifiers[0]] ?? FilterType["starts-with"];
6629
+ select._h_select.filterType = FilterType[el.getAttribute("data-filter")] ?? FilterType["starts-with"];
6491
6630
  }
6492
6631
  el.classList.add("flex", "h-8", "items-center", "gap-2", "border-b", "px-2");
6493
6632
  el.setAttribute("data-slot", "select-search");
@@ -6508,12 +6647,12 @@
6508
6647
  select._h_select.focusSearch = () => {
6509
6648
  searchInput.focus();
6510
6649
  };
6511
- function handler2(event) {
6650
+ function onActivate(event) {
6512
6651
  if (event.type === "keydown" && (event.key === "Escape" || event.key === "ArrowDown" || event.key === "Down")) return;
6513
6652
  event.stopPropagation();
6514
6653
  }
6515
- el.addEventListener("click", handler2);
6516
- el.addEventListener("keydown", handler2);
6654
+ el.addEventListener("click", onActivate);
6655
+ el.addEventListener("keydown", onActivate);
6517
6656
  if (select._h_select.filterType !== FilterType.none) {
6518
6657
  let onInput2 = function() {
6519
6658
  select._h_select.search = searchInput.value.toLowerCase();
@@ -6524,13 +6663,19 @@
6524
6663
  if (select._h_select.expanded) searchInput.focus({ preventScroll: true });
6525
6664
  el.setAttribute("aria-expanded", select._h_select.expanded);
6526
6665
  });
6666
+ const observer = new MutationObserver(() => {
6667
+ select._h_select.filterType = FilterType[el.getAttribute("data-filter")] ?? FilterType["starts-with"];
6668
+ el.setAttribute("aria-autocomplete", select._h_select.filterType === FilterType.none ? "both" : "list");
6669
+ });
6670
+ observer.observe(el, { attributes: true, attributeFilter: ["data-filter"] });
6527
6671
  cleanup(() => {
6528
- el.removeEventListener("click", handler2);
6529
- el.removeEventListener("keydown", handler2);
6672
+ el.removeEventListener("click", onActivate);
6673
+ el.removeEventListener("keydown", onActivate);
6530
6674
  if (select._h_select.filterType !== FilterType.none) searchInput.removeEventListener("keyup", onInput);
6675
+ observer.disconnect();
6531
6676
  });
6532
6677
  });
6533
- Alpine.directive("h-select-group", (el, {}, { effect }) => {
6678
+ Alpine.directive("h-select-group", (el, _, { effect }) => {
6534
6679
  el.setAttribute("data-slot", "select-group");
6535
6680
  el._h_selectGroup = Alpine.reactive({
6536
6681
  labelledby: void 0
@@ -6551,10 +6696,10 @@
6551
6696
  selectGroup._h_selectGroup.labelledby = id;
6552
6697
  }
6553
6698
  });
6554
- Alpine.directive("h-select-option", (el, { expression }, { effect, evaluateLater, cleanup }) => {
6699
+ Alpine.directive("h-select-option", (el, { original, expression }, { effect, evaluateLater, cleanup }) => {
6555
6700
  const select = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6556
6701
  if (!select) {
6557
- throw new Error("h-select-option must be inside an h-select element");
6702
+ throw new Error(`${original} must be inside an h-select element`);
6558
6703
  }
6559
6704
  el.classList.add(
6560
6705
  "focus:bg-primary",
@@ -6601,18 +6746,13 @@
6601
6746
  el.appendChild(indicatorEl);
6602
6747
  el.appendChild(labelEl);
6603
6748
  function getValue() {
6604
- if (el.hasOwnProperty("_x_bindings") && el._x_bindings.hasOwnProperty("value")) return el._x_bindings.value;
6605
- else return el.getAttribute("value");
6749
+ return el.getAttribute("data-value");
6606
6750
  }
6607
6751
  const getLabel = evaluateLater(expression);
6608
6752
  effect(() => {
6609
6753
  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
6754
  labelEl.innerText = label;
6755
+ select._h_select.refreshLabel();
6616
6756
  });
6617
6757
  });
6618
6758
  effect(() => {
@@ -6639,51 +6779,40 @@
6639
6779
  if (selected) {
6640
6780
  indicatorEl.classList.remove("invisible");
6641
6781
  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");
6782
+ return labelEl.innerText;
6651
6783
  }
6784
+ indicatorEl.classList.add("invisible");
6785
+ el.setAttribute("aria-selected", "false");
6786
+ return "";
6652
6787
  }
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") {
6788
+ const onModelChange = (value) => {
6789
+ return setSelectedState(select._h_select.multiple ? value.includes(getValue()) : value === getValue());
6790
+ };
6791
+ select._h_select.listeners.push(onModelChange);
6792
+ const onActivate = (event) => {
6793
+ if (event.type === "keydown" && (event.key === "Enter" || event.key === " ") || event.type === "click") {
6666
6794
  if (select._h_select.multiple) {
6667
- const vIndex = select._h_select.model.indexOf(getValue());
6795
+ const vIndex = select._h_model.get().indexOf(getValue());
6668
6796
  if (vIndex > -1) {
6669
- select._h_select.model.splice(vIndex, 1);
6670
- removeLabel();
6797
+ const val = select._h_model.get().splice(vIndex, 1);
6798
+ select._h_model.set(val);
6671
6799
  } else {
6672
- select._h_select.model.push(getValue());
6800
+ select._h_model.get().push(getValue());
6673
6801
  }
6674
- } else if (select._h_select.model !== getValue()) {
6675
- select._h_select.model = getValue();
6802
+ } else if (select._h_model.get() !== getValue()) {
6803
+ select._h_model.set(getValue());
6676
6804
  } else {
6677
- select._h_select.model = "";
6678
- removeLabel();
6805
+ select._h_model.set("");
6679
6806
  }
6680
6807
  }
6681
6808
  };
6682
- el.addEventListener("click", handler2);
6683
- el.addEventListener("keydown", handler2);
6809
+ el.addEventListener("click", onActivate);
6810
+ el.addEventListener("keydown", onActivate);
6684
6811
  cleanup(() => {
6685
- el.removeEventListener("click", handler2);
6686
- el.removeEventListener("keydown", handler2);
6812
+ el.removeEventListener("click", onActivate);
6813
+ el.removeEventListener("keydown", onActivate);
6814
+ const lIndex = select._h_select.listeners.indexOf(onModelChange);
6815
+ select._h_select.listeners.splice(lIndex, 1);
6687
6816
  });
6688
6817
  });
6689
6818
  Alpine.directive("h-select-separator", (el) => {
@@ -6727,17 +6856,17 @@
6727
6856
  el.setAttribute("data-open", isOpen);
6728
6857
  });
6729
6858
  });
6730
- const onClick = (event) => {
6859
+ const onClick2 = (event) => {
6731
6860
  if (event.target.getAttribute("data-slot") === "sheet-overlay") {
6732
6861
  evaluate2(`${expression} = false`);
6733
6862
  }
6734
6863
  };
6735
- el.addEventListener("click", onClick);
6864
+ el.addEventListener("click", onClick2);
6736
6865
  cleanup(() => {
6737
- el.removeEventListener("click", onClick);
6866
+ el.removeEventListener("click", onClick2);
6738
6867
  });
6739
6868
  });
6740
- Alpine.directive("h-sheet", (el, {}, { cleanup }) => {
6869
+ Alpine.directive("h-sheet", (el, _, { cleanup }) => {
6741
6870
  el.classList.add("bg-background", "fixed", "shadow-lg");
6742
6871
  el.setAttribute("data-slot", "sheet");
6743
6872
  let lastSide;
@@ -6784,10 +6913,8 @@
6784
6913
  }
6785
6914
  };
6786
6915
  setFloating();
6787
- const observer = new MutationObserver((mutations) => {
6788
- mutations.forEach(() => {
6789
- setFloating();
6790
- });
6916
+ const observer = new MutationObserver(() => {
6917
+ setFloating();
6791
6918
  });
6792
6919
  observer.observe(el, { attributes: true, attributeFilter: ["data-floating"] });
6793
6920
  cleanup(() => {
@@ -7117,7 +7244,7 @@
7117
7244
  el.setAttribute("tabindex", "-1");
7118
7245
  el.setAttribute("data-slot", "split-panel");
7119
7246
  });
7120
- Alpine.directive("h-split-gutter", (el, {}, { cleanup }) => {
7247
+ Alpine.directive("h-split-gutter", (el, _, { cleanup }) => {
7121
7248
  el.classList.add(
7122
7249
  "relative",
7123
7250
  "shrink-0",
@@ -7153,10 +7280,10 @@
7153
7280
  "hover:before:bg-primary-hover",
7154
7281
  "group-data-[orientation=horizontal]/split:!w-px",
7155
7282
  "group-data-[orientation=horizontal]/split:before:h-full",
7156
- "group-data-[orientation=horizontal]/split:before:w-[0.313rem]",
7283
+ "group-data-[orientation=horizontal]/split:before:w-[calc(var(--spacing)*1.25)]",
7157
7284
  "group-data-[orientation=vertical]/split:!h-px",
7158
7285
  "group-data-[orientation=vertical]/split:before:w-full",
7159
- "group-data-[orientation=vertical]/split:before:h-[0.313rem]"
7286
+ "group-data-[orientation=vertical]/split:before:h-[calc(var(--spacing)*1.25)]"
7160
7287
  ];
7161
7288
  const handleClasses = [
7162
7289
  "bg-transparent",
@@ -7238,7 +7365,7 @@
7238
7365
  "[&>input]:border-0",
7239
7366
  "[&>input]:cursor-pointer",
7240
7367
  "[&>input]:focus-visible:border-ring",
7241
- "[&>input]:focus-visible:ring-[3px]",
7368
+ "[&>input]:focus-visible:ring-[calc(var(--spacing)*0.75)]",
7242
7369
  "[&>input]:focus-visible:ring-ring/50",
7243
7370
  "[&>input]:left-0",
7244
7371
  "[&>input]:outline-none",
@@ -7247,27 +7374,27 @@
7247
7374
  "[&>input]:top-0",
7248
7375
  "before:bg-background",
7249
7376
  "before:duration-200",
7250
- "before:inline-block",
7251
- "before:m-[1px]",
7377
+ "before:block",
7252
7378
  "before:pointer-events-none",
7253
7379
  "before:ring-0",
7254
7380
  "before:rounded-full",
7255
7381
  "before:shadow-input",
7256
- "before:size-5",
7382
+ "before:h-full",
7383
+ "before:aspect-square",
7257
7384
  "before:transition-transform",
7258
7385
  "bg-muted",
7259
7386
  "border",
7260
- "data-[size=sm]:before:size-4",
7261
7387
  "data-[size=sm]:h-5",
7262
7388
  "data-[size=sm]:max-w-8",
7263
7389
  "data-[size=sm]:min-w-8",
7264
7390
  "duration-200",
7265
7391
  "h-6",
7266
- "has-[input:checked]:before:translate-x-[calc(100%-var(--spacing)*1)]",
7392
+ "has-[input:checked]:before:translate-x-[calc(100%-var(--spacing))]",
7267
7393
  "has-[input:checked]:bg-primary",
7268
7394
  "has-[input:checked]:border-primary-active",
7269
7395
  "has-[input:disabled]:cursor-not-allowed",
7270
7396
  "has-[input:disabled]:opacity-50",
7397
+ "p-0.25",
7271
7398
  "max-w-10",
7272
7399
  "min-w-10",
7273
7400
  "relative",
@@ -7407,7 +7534,7 @@
7407
7534
  "data-[floating=true]:shadow-xs",
7408
7535
  "data-[floating=true]:z-1",
7409
7536
  "data-[floating=true]:rounded-lg",
7410
- "data-[floating=true]:p-[0.188rem]"
7537
+ "data-[floating=true]:p-[calc(var(--spacing)*0.75)]"
7411
7538
  );
7412
7539
  el.setAttribute("data-slot", "tab-bar");
7413
7540
  });
@@ -7417,6 +7544,9 @@
7417
7544
  "flex",
7418
7545
  "items-start",
7419
7546
  "justify-start",
7547
+ "scrollbar-none",
7548
+ "group-data-[orientation=horizontal]/tabs:overflow-x-scroll",
7549
+ "group-data-[orientation=vertical]/tabs:overflow-y-scroll",
7420
7550
  "group-data-[orientation=horizontal]/tabs:flex-row",
7421
7551
  "group-data-[orientation=vertical]/tabs:flex-col",
7422
7552
  "group-data-[orientation=vertical]/tabs:h-fit",
@@ -7426,7 +7556,7 @@
7426
7556
  el.setAttribute("role", "tablist");
7427
7557
  el.setAttribute("data-slot", "tab-list");
7428
7558
  });
7429
- Alpine.directive("h-tab", (el) => {
7559
+ Alpine.directive("h-tab", (el, { original }) => {
7430
7560
  el.classList.add(
7431
7561
  "cursor-pointer",
7432
7562
  "focus-visible:border-ring",
@@ -7473,8 +7603,8 @@
7473
7603
  );
7474
7604
  el.setAttribute("role", "tab");
7475
7605
  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.");
7606
+ if (!el.hasAttribute("id")) throw new Error(`${original}: Tabs must have an id`);
7607
+ if (!el.hasAttribute("aria-controls")) throw new Error(`${original}: aria-controls must be set to the tab-content id.`);
7478
7608
  });
7479
7609
  Alpine.directive("h-tab-action", (el) => {
7480
7610
  el.classList.add("cursor-pointer", "ml-auto", "rounded-md", "text-foreground", "hover:bg-secondary", "hover:text-secondary-foreground", "active:bg-secondary-active");
@@ -7508,13 +7638,13 @@
7508
7638
  el.setAttribute("role", "button");
7509
7639
  el.setAttribute("data-slot", "tab-list-action");
7510
7640
  });
7511
- Alpine.directive("h-tabs-content", (el) => {
7641
+ Alpine.directive("h-tabs-content", (el, { original }) => {
7512
7642
  el.classList.add("flex-1", "outline-none");
7513
7643
  el.setAttribute("role", "tabpanel");
7514
7644
  el.setAttribute("tabindex", "0");
7515
7645
  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.");
7646
+ if (!el.hasAttribute("id")) throw new Error(`${original}: Tab content must have an id`);
7647
+ if (!el.hasAttribute("aria-labelledby")) throw new Error(`${original}: aria-labelledby must be set to the tab id.`);
7518
7648
  });
7519
7649
  }
7520
7650
 
@@ -7577,7 +7707,7 @@
7577
7707
  el.classList.add("mt-6", "border-l-2", "pl-6", "italic");
7578
7708
  break;
7579
7709
  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");
7710
+ 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
7711
  break;
7582
7712
  case "code":
7583
7713
  el.classList.add("bg-muted", "relative", "rounded", "p-3", "font-mono", "text-sm", "font-semibold", "whitespace-pre");
@@ -7630,13 +7760,13 @@
7630
7760
  "shadow-input",
7631
7761
  "transition-[color,box-shadow]",
7632
7762
  "outline-none",
7633
- "focus-visible:ring-[3px]",
7763
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
7634
7764
  "disabled:cursor-not-allowed",
7635
7765
  "disabled:opacity-50",
7636
7766
  "md:text-sm"
7637
7767
  );
7638
7768
  if (modifiers.includes("group")) {
7639
- el.classList.remove("rounded-control", "border", "bg-input-inner", "py-2", "shadow-input", "focus-visible:ring-[3px]");
7769
+ el.classList.remove("rounded-control", "border", "bg-input-inner", "py-2", "shadow-input", "focus-visible:ring-[calc(var(--spacing)*0.75)]");
7640
7770
  el.classList.add("flex-1", "resize-none", "rounded-none", "border-0", "bg-transparent", "py-3", "shadow-none", "focus-visible:ring-0");
7641
7771
  el.setAttribute("data-slot", "input-group-control");
7642
7772
  } else el.setAttribute("data-slot", "textarea");
@@ -7666,7 +7796,7 @@
7666
7796
  "outline-none",
7667
7797
  "focus-visible:border-ring",
7668
7798
  "focus-visible:ring-ring/50",
7669
- "focus-visible:ring-[3px]"
7799
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]"
7670
7800
  );
7671
7801
  el.setAttribute("data-slot", "tile");
7672
7802
  const sizes = {
@@ -7774,6 +7904,15 @@
7774
7904
  }
7775
7905
  return { hour, minute, second, period };
7776
7906
  };
7907
+ function scrollIntoCenter(container, element, behavior = "instant") {
7908
+ const containerRect = container.getBoundingClientRect();
7909
+ const elementRect = element.getBoundingClientRect();
7910
+ const offset4 = elementRect.top - containerRect.top - container.clientHeight / 2 + element.clientHeight / 2;
7911
+ container.scrollBy({
7912
+ top: offset4,
7913
+ behavior
7914
+ });
7915
+ }
7777
7916
  function timepicker_default(Alpine) {
7778
7917
  Alpine.directive("h-time-picker", (el, { expression }, { evaluateLater, cleanup, effect, Alpine: Alpine2 }) => {
7779
7918
  el._h_timepicker = Alpine2.reactive({
@@ -7784,12 +7923,16 @@
7784
7923
  is12Hour: false,
7785
7924
  locale: void 0,
7786
7925
  seconds: void 0,
7787
- close() {
7926
+ focusInput: void 0,
7927
+ close(focus = false) {
7788
7928
  el._h_timepicker.expanded = false;
7789
7929
  top.removeEventListener("click", el._h_timepicker.close);
7930
+ if (focus && this.focusInput) {
7931
+ this.focusInput();
7932
+ }
7790
7933
  }
7791
7934
  });
7792
- el._time = {
7935
+ el._h_time = {
7793
7936
  changed: void 0,
7794
7937
  parts: {
7795
7938
  hour: null,
@@ -7803,7 +7946,7 @@
7803
7946
  "border-input",
7804
7947
  "[&>input]:appearance-none",
7805
7948
  "has-[input:focus-visible]:border-ring",
7806
- "has-[input:focus-visible]:ring-[3px]",
7949
+ "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
7807
7950
  "has-[input:focus-visible]:ring-ring/50",
7808
7951
  "dark:has-[aria-invalid=true]:ring-negative/40",
7809
7952
  "dark:has-[input:invalid]:ring-negative/40",
@@ -7866,7 +8009,7 @@
7866
8009
  } else {
7867
8010
  el._h_timepicker.is12Hour = new Intl.DateTimeFormat(el._h_timepicker.locale, { hour: "numeric" }).resolvedOptions().hour12;
7868
8011
  }
7869
- const handler2 = (event) => {
8012
+ const handler = (event) => {
7870
8013
  if (event.type === "keydown" && event.key !== "Enter") return;
7871
8014
  el._h_timepicker.expanded = !el._h_timepicker.expanded;
7872
8015
  el.setAttribute("aria-expanded", el._h_timepicker.expanded);
@@ -7878,23 +8021,26 @@
7878
8021
  }
7879
8022
  });
7880
8023
  };
7881
- el.addEventListener("click", handler2);
7882
- el.addEventListener("keydown", handler2);
8024
+ el.addEventListener("click", handler);
8025
+ el.addEventListener("keydown", handler);
7883
8026
  cleanup(() => {
7884
- el.removeEventListener("click", handler2);
7885
- el.removeEventListener("keydown", handler2);
8027
+ el.removeEventListener("click", handler);
8028
+ el.removeEventListener("keydown", handler);
7886
8029
  top.removeEventListener("click", el._h_timepicker.close);
7887
8030
  });
7888
8031
  });
7889
- Alpine.directive("h-time-picker-input", (el, {}, { effect, Alpine: Alpine2 }) => {
8032
+ Alpine.directive("h-time-picker-input", (el, { original }, { effect, Alpine: Alpine2 }) => {
7890
8033
  if (el.tagName !== "INPUT") {
7891
- throw new Error("h-time-picker-input must be a readonly input of type text");
8034
+ throw new Error(`${original} must be a readonly input of type "text"`);
7892
8035
  }
7893
8036
  const timepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_timepicker"));
7894
8037
  if (!timepicker) {
7895
- throw new Error("h-time-picker-input must be inside an h-time-picker element");
8038
+ throw new Error(`${original} must be inside a time-picker element`);
7896
8039
  }
7897
- timepicker._time.changed = () => {
8040
+ timepicker._h_timepicker.focusInput = () => {
8041
+ el.focus();
8042
+ };
8043
+ timepicker._h_time.changed = () => {
7898
8044
  Alpine2.nextTick(() => {
7899
8045
  el.dispatchEvent(new Event("change"));
7900
8046
  });
@@ -7917,7 +8063,7 @@
7917
8063
  timepicker._h_timepicker.id = `htp${v4_default()}`;
7918
8064
  el.setAttribute("id", timepicker._h_timepicker.id);
7919
8065
  }
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");
8066
+ 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
8067
  el.readOnly = true;
7922
8068
  el.setAttribute("aria-autocomplete", "none");
7923
8069
  el.setAttribute("aria-controls", timepicker._h_timepicker.controls);
@@ -7936,22 +8082,22 @@
7936
8082
  if (timepicker._h_timepicker.is12Hour) {
7937
8083
  if (timepicker._h_timepicker.seconds) {
7938
8084
  timepicker._h_timepicker.model.set(`${hour}:${minute}:${second ?? "00"} ${period}`);
7939
- timepicker._time.parts.second = second ?? "00";
8085
+ timepicker._h_time.parts.second = second ?? "00";
7940
8086
  } else {
7941
8087
  timepicker._h_timepicker.model.set(`${hour}:${minute} ${period}`);
7942
8088
  }
7943
- timepicker._time.parts.hour = hour;
7944
- timepicker._time.parts.minute = minute;
7945
- timepicker._time.parts.period = period;
8089
+ timepicker._h_time.parts.hour = hour;
8090
+ timepicker._h_time.parts.minute = minute;
8091
+ timepicker._h_time.parts.period = period;
7946
8092
  } else {
7947
8093
  if (timepicker._h_timepicker.seconds) {
7948
8094
  timepicker._h_timepicker.model.set(`${hour}:${minute}:${second ?? "00"}`);
7949
- timepicker._time.parts.second = second ?? "00";
8095
+ timepicker._h_time.parts.second = second ?? "00";
7950
8096
  } else {
7951
8097
  timepicker._h_timepicker.model.set(`${hour}:${minute}`);
7952
8098
  }
7953
- timepicker._time.parts.hour = hour;
7954
- timepicker._time.parts.minute = minute;
8099
+ timepicker._h_time.parts.hour = hour;
8100
+ timepicker._h_time.parts.minute = minute;
7955
8101
  }
7956
8102
  }
7957
8103
  let placeholder;
@@ -7966,14 +8112,14 @@
7966
8112
  el.setAttribute("aria-expanded", timepicker._h_timepicker.expanded);
7967
8113
  });
7968
8114
  }).before("h-button");
7969
- Alpine.directive("h-time-picker-popup", (el, {}, { effect, cleanup, Alpine: Alpine2 }) => {
8115
+ Alpine.directive("h-time-picker-popup", (el, _, { effect, cleanup, Alpine: Alpine2 }) => {
7970
8116
  const timepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_timepicker"));
7971
8117
  el.classList.add(
7972
8118
  "overflow-hidden",
7973
8119
  "outline-none",
7974
8120
  "border",
7975
8121
  "rounded-control",
7976
- "fixed",
8122
+ "absolute",
7977
8123
  "bg-popover",
7978
8124
  "text-popover-foreground",
7979
8125
  "data-[state=open]:flex",
@@ -8008,45 +8154,45 @@
8008
8154
  ];
8009
8155
  const updateModel = () => {
8010
8156
  let newValue;
8011
- if (timepicker._time.parts.hour !== null && timepicker._time.parts.minute !== null) {
8157
+ if (timepicker._h_time.parts.hour !== null && timepicker._h_time.parts.minute !== null) {
8012
8158
  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}`;
8159
+ if (timepicker._h_time.parts.seconds !== null) {
8160
+ newValue = `${timepicker._h_time.parts.hour}:${timepicker._h_time.parts.minute}:${timepicker._h_time.parts.second}`;
8015
8161
  } else return;
8016
8162
  } else {
8017
- newValue = `${timepicker._time.parts.hour}:${timepicker._time.parts.minute}`;
8163
+ newValue = `${timepicker._h_time.parts.hour}:${timepicker._h_time.parts.minute}`;
8018
8164
  }
8019
8165
  } else return;
8020
8166
  if (timepicker._h_timepicker.is12Hour) {
8021
- if (timepicker._time.parts.period !== null) {
8022
- newValue += ` ${timepicker._time.parts.period}`;
8167
+ if (timepicker._h_time.parts.period !== null) {
8168
+ newValue += ` ${timepicker._h_time.parts.period}`;
8023
8169
  } else return;
8024
8170
  }
8025
8171
  if (newValue) {
8026
8172
  timepicker._h_timepicker.model.set(newValue);
8027
- timepicker._time.changed();
8173
+ timepicker._h_time.changed();
8028
8174
  }
8029
8175
  };
8030
8176
  const getCurrentTime = () => {
8031
8177
  let date = /* @__PURE__ */ new Date();
8032
8178
  let hour = date.getHours();
8033
- timepicker._time.parts.period = hour >= 12 ? dayPeriodLabels.pm : dayPeriodLabels.am;
8179
+ timepicker._h_time.parts.period = hour >= 12 ? dayPeriodLabels.pm : dayPeriodLabels.am;
8034
8180
  if (timepicker._h_timepicker.is12Hour) {
8035
8181
  hour = date.getHours() % 12 || 12;
8036
8182
  }
8037
8183
  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();
8184
+ timepicker._h_time.parts.hour = hour < 10 ? `0${hour}` : hour.toString();
8185
+ timepicker._h_time.parts.minute = minute < 10 ? `0${minute}` : minute.toString();
8040
8186
  if (timepicker._h_timepicker.seconds) {
8041
8187
  let second = date.getSeconds();
8042
- timepicker._time.parts.second = second < 10 ? `0${second}` : second.toString();
8188
+ timepicker._h_time.parts.second = second < 10 ? `0${second}` : second.toString();
8043
8189
  }
8044
8190
  updateModel();
8045
8191
  timepicker._h_timepicker.close();
8046
8192
  };
8047
8193
  function onKeyDown(event) {
8048
8194
  if (event.key === "Escape") {
8049
- timepicker._h_timepicker.close();
8195
+ timepicker._h_timepicker.close(true);
8050
8196
  } else if (event.target.tagName === "LI") {
8051
8197
  let list;
8052
8198
  let inHoursList = event.target.parentElement.dataset.type === "hours";
@@ -8060,6 +8206,7 @@
8060
8206
  list = periodList;
8061
8207
  }
8062
8208
  switch (event.key) {
8209
+ case "Up":
8063
8210
  case "ArrowUp":
8064
8211
  event.target.setAttribute("tabindex", "-1");
8065
8212
  let prevElem = event.target.previousElementSibling;
@@ -8073,6 +8220,7 @@
8073
8220
  prevElem.setAttribute("tabindex", "0");
8074
8221
  prevElem.focus();
8075
8222
  break;
8223
+ case "Down":
8076
8224
  case "ArrowDown":
8077
8225
  event.target.setAttribute("tabindex", "-1");
8078
8226
  let nextElem = event.target.nextElementSibling;
@@ -8086,6 +8234,58 @@
8086
8234
  nextElem.setAttribute("tabindex", "0");
8087
8235
  nextElem.focus();
8088
8236
  break;
8237
+ case "Home":
8238
+ case "PageUp":
8239
+ let firstChild;
8240
+ if (list.firstChild === event.target) {
8241
+ break;
8242
+ } else if (inHoursList && timepicker._h_timepicker.is12Hour) {
8243
+ if (list.children[1] === event.target) {
8244
+ break;
8245
+ } else {
8246
+ firstChild = list.children[1];
8247
+ }
8248
+ } else {
8249
+ firstChild = list.firstChild;
8250
+ }
8251
+ event.target.setAttribute("tabindex", "-1");
8252
+ firstChild.setAttribute("tabindex", "0");
8253
+ firstChild.focus();
8254
+ break;
8255
+ case "End":
8256
+ case "PageDown":
8257
+ let lastElem;
8258
+ if (list.lastChild === event.target) {
8259
+ break;
8260
+ } else if (inHoursList && timepicker._h_timepicker.is12Hour) {
8261
+ if (list.children[12] !== event.target) {
8262
+ lastElem = list.children[12];
8263
+ } else {
8264
+ break;
8265
+ }
8266
+ } else {
8267
+ lastElem = list.lastChild;
8268
+ }
8269
+ event.target.setAttribute("tabindex", "-1");
8270
+ lastElem.setAttribute("tabindex", "0");
8271
+ lastElem.focus();
8272
+ break;
8273
+ case "Right":
8274
+ case "ArrowRight":
8275
+ let nextColumn = event.target.parentElement.nextElementSibling;
8276
+ if (nextColumn) {
8277
+ const child = nextColumn.querySelector('li[tabindex="0"]');
8278
+ child.focus();
8279
+ }
8280
+ break;
8281
+ case "Left":
8282
+ case "ArrowLeft":
8283
+ let prevColumn = event.target.parentElement.previousElementSibling;
8284
+ if (prevColumn) {
8285
+ const child = prevColumn.querySelector('li[tabindex="0"]');
8286
+ child.focus();
8287
+ }
8288
+ break;
8089
8289
  case "Enter":
8090
8290
  case " ":
8091
8291
  event.target.click();
@@ -8111,13 +8311,13 @@
8111
8311
  function setTime(event) {
8112
8312
  if (event.target.tagName === "LI") {
8113
8313
  if (event.target.parentElement.dataset.type === "hours") {
8114
- timepicker._time.parts.hour = event.target.innerText;
8314
+ timepicker._h_time.parts.hour = event.target.innerText;
8115
8315
  } else if (event.target.parentElement.dataset.type === "minutes") {
8116
- timepicker._time.parts.minute = event.target.innerText;
8316
+ timepicker._h_time.parts.minute = event.target.innerText;
8117
8317
  } else if (event.target.parentElement.dataset.type === "seconds") {
8118
- timepicker._time.parts.second = event.target.innerText;
8318
+ timepicker._h_time.parts.second = event.target.innerText;
8119
8319
  } else if (event.target.parentElement.dataset.type === "period") {
8120
- timepicker._time.parts.period = event.target.innerText;
8320
+ timepicker._h_time.parts.period = event.target.innerText;
8121
8321
  }
8122
8322
  render();
8123
8323
  updateModel();
@@ -8236,7 +8436,7 @@
8236
8436
  if (timepicker._h_timepicker.is12Hour) {
8237
8437
  hoursList.firstChild.classList.add("hidden");
8238
8438
  for (let h = 1; h < 13; h++) {
8239
- if (hoursList.children[h].innerText === timepicker._time.parts.hour) {
8439
+ if (hoursList.children[h].innerText === timepicker._h_time.parts.hour) {
8240
8440
  hoursList.children[h].setAttribute("tabindex", "0");
8241
8441
  hoursList.children[h].setAttribute("aria-selected", true);
8242
8442
  selectedHour = hoursList.children[h];
@@ -8253,7 +8453,7 @@
8253
8453
  } else {
8254
8454
  for (let h = 0; h < hoursList.children.length; h++) {
8255
8455
  hoursList.children[h].classList.remove("hidden");
8256
- if (hoursList.children[h].innerText === timepicker._time.parts.hour) {
8456
+ if (hoursList.children[h].innerText === timepicker._h_time.parts.hour) {
8257
8457
  hoursList.children[h].setAttribute("tabindex", "0");
8258
8458
  hoursList.children[h].setAttribute("aria-selected", true);
8259
8459
  selectedHour = hoursList.children[h];
@@ -8267,7 +8467,7 @@
8267
8467
  hoursList.children[timepicker._h_timepicker.is12Hour ? 1 : 0].setAttribute("tabindex", "0");
8268
8468
  }
8269
8469
  for (let m = 0; m < minutesList.children.length; m++) {
8270
- if (minutesList.children[m].innerText === timepicker._time.parts.minute) {
8470
+ if (minutesList.children[m].innerText === timepicker._h_time.parts.minute) {
8271
8471
  minutesList.children[m].setAttribute("tabindex", "0");
8272
8472
  minutesList.children[m].setAttribute("aria-selected", true);
8273
8473
  selectedMinute = minutesList.children[m];
@@ -8282,7 +8482,7 @@
8282
8482
  if (timepicker._h_timepicker.seconds) {
8283
8483
  secondsList.classList.remove("hidden");
8284
8484
  for (let s = 0; s < secondsList.children.length; s++) {
8285
- if (secondsList.children[s].innerText === timepicker._time.parts.second) {
8485
+ if (secondsList.children[s].innerText === timepicker._h_time.parts.second) {
8286
8486
  secondsList.children[s].setAttribute("tabindex", "0");
8287
8487
  secondsList.children[s].setAttribute("aria-selected", true);
8288
8488
  selectedSecond = secondsList.children[s];
@@ -8295,22 +8495,22 @@
8295
8495
  secondsList.firstChild.setAttribute("tabindex", "0");
8296
8496
  }
8297
8497
  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;
8498
+ 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
8499
  } else {
8300
- okButton.disabled = timepicker._time.parts.hour && timepicker._time.parts.minute && timepicker._time.parts.second ? false : true;
8500
+ okButton.disabled = timepicker._h_time.parts.hour && timepicker._h_time.parts.minute && timepicker._h_time.parts.second ? false : true;
8301
8501
  }
8302
8502
  } else {
8303
8503
  secondsList.classList.add("hidden");
8304
8504
  if (timepicker._h_timepicker.is12Hour) {
8305
- okButton.disabled = timepicker._time.parts.hour && timepicker._time.parts.minute && timepicker._time.parts.period ? false : true;
8505
+ okButton.disabled = timepicker._h_time.parts.hour && timepicker._h_time.parts.minute && timepicker._h_time.parts.period ? false : true;
8306
8506
  } else {
8307
- okButton.disabled = timepicker._time.parts.hour && timepicker._time.parts.minute ? false : true;
8507
+ okButton.disabled = timepicker._h_time.parts.hour && timepicker._h_time.parts.minute ? false : true;
8308
8508
  }
8309
8509
  }
8310
8510
  if (timepicker._h_timepicker.is12Hour) {
8311
8511
  periodList.classList.remove("hidden");
8312
8512
  for (let p = 0; p < periodList.children.length; p++) {
8313
- if (periodList.children[p].innerText === timepicker._time.parts.period) {
8513
+ if (periodList.children[p].innerText === timepicker._h_time.parts.period) {
8314
8514
  periodList.children[p].setAttribute("tabindex", "0");
8315
8515
  periodList.children[p].setAttribute("aria-selected", true);
8316
8516
  selectedPeriod = periodList.children[p];
@@ -8326,26 +8526,31 @@
8326
8526
  periodList.classList.add("hidden");
8327
8527
  }
8328
8528
  }
8329
- const onClick = (event) => {
8529
+ const onClick2 = (event) => {
8330
8530
  event.stopPropagation();
8331
8531
  };
8332
- el.addEventListener("click", onClick);
8532
+ el.addEventListener("click", onClick2);
8333
8533
  let autoUpdateCleanup;
8534
+ let focusFirstItem = true;
8334
8535
  function updatePosition() {
8335
8536
  computePosition2(timepicker, el, {
8336
8537
  placement: el.getAttribute("data-align") || "bottom-start",
8337
- strategy: "fixed",
8338
8538
  middleware: [offset2(4), flip2(), shift2({ padding: 4 })]
8339
8539
  }).then(({ x, y }) => {
8340
- if (selectedHour) {
8341
- selectedHour.focus();
8342
- } else {
8343
- hoursList.children[timepicker._h_timepicker.is12Hour ? 1 : 0].focus();
8344
- }
8345
8540
  Object.assign(el.style, {
8346
8541
  left: `${x}px`,
8347
8542
  top: `${y}px`
8348
8543
  });
8544
+ if (focusFirstItem) {
8545
+ focusFirstItem = false;
8546
+ Alpine2.nextTick(() => {
8547
+ if (selectedHour) {
8548
+ selectedHour.focus();
8549
+ } else {
8550
+ hoursList.children[timepicker._h_timepicker.is12Hour ? 1 : 0].focus();
8551
+ }
8552
+ });
8553
+ }
8349
8554
  });
8350
8555
  }
8351
8556
  effect(() => {
@@ -8353,11 +8558,12 @@
8353
8558
  if (timepicker._h_timepicker.expanded) {
8354
8559
  render();
8355
8560
  autoUpdateCleanup = autoUpdate(timepicker, el, updatePosition);
8356
- if (selectedHour) selectedHour.scrollIntoView({ block: "center" });
8357
- if (selectedMinute) selectedMinute.scrollIntoView({ block: "center" });
8358
- if (selectedSecond && timepicker._h_timepicker.seconds) selectedSecond.scrollIntoView({ block: "center" });
8561
+ if (selectedHour) scrollIntoCenter(selectedHour.parentElement, selectedHour);
8562
+ if (selectedMinute) scrollIntoCenter(selectedMinute.parentElement, selectedMinute);
8563
+ if (selectedSecond && timepicker._h_timepicker.seconds) scrollIntoCenter(selectedSecond.parentElement, selectedSecond);
8359
8564
  } else {
8360
8565
  if (autoUpdateCleanup) autoUpdateCleanup();
8566
+ focusFirstItem = true;
8361
8567
  Object.assign(el.style, {
8362
8568
  left: "0px",
8363
8569
  top: "0px"
@@ -8366,7 +8572,7 @@
8366
8572
  });
8367
8573
  cleanup(() => {
8368
8574
  el.removeEventListener("keydown", onKeyDown);
8369
- el.removeEventListener("click", onClick);
8575
+ el.removeEventListener("click", onClick2);
8370
8576
  okButton.removeEventListener("click", timepicker._h_timepicker.close);
8371
8577
  for (let h = 0; h < hoursList.children.length; h++) {
8372
8578
  hoursList.children[h].removeEventListener("click", setHour);
@@ -8431,7 +8637,7 @@
8431
8637
 
8432
8638
  // src/components/tooltip.js
8433
8639
  function tooltip_default(Alpine) {
8434
- Alpine.directive("h-tooltip-trigger", (el, {}, { Alpine: Alpine2, cleanup }) => {
8640
+ Alpine.directive("h-tooltip-trigger", (el, _, { Alpine: Alpine2, cleanup }) => {
8435
8641
  el._tooltip = Alpine2.reactive({
8436
8642
  id: void 0,
8437
8643
  controls: `hpc${v4_default()}`,
@@ -8444,17 +8650,17 @@
8444
8650
  el.setAttribute("id", el._tooltip.id);
8445
8651
  }
8446
8652
  el.setAttribute("aria-describedby", el._tooltip.controls);
8447
- const handler2 = (event) => {
8653
+ const handler = (event) => {
8448
8654
  el._tooltip.shown = event.type === "pointerenter";
8449
8655
  };
8450
- el.addEventListener("pointerenter", handler2);
8451
- el.addEventListener("pointerleave", handler2);
8656
+ el.addEventListener("pointerenter", handler);
8657
+ el.addEventListener("pointerleave", handler);
8452
8658
  cleanup(() => {
8453
- el.removeEventListener("pointerenter", handler2);
8454
- el.removeEventListener("pointerleave", handler2);
8659
+ el.removeEventListener("pointerenter", handler);
8660
+ el.removeEventListener("pointerleave", handler);
8455
8661
  });
8456
8662
  });
8457
- Alpine.directive("h-tooltip", (el, {}, { effect }) => {
8663
+ Alpine.directive("h-tooltip", (el, { original }, { effect }) => {
8458
8664
  const tooltip = (() => {
8459
8665
  let sibling = el.previousElementSibling;
8460
8666
  while (sibling && !sibling.hasOwnProperty("_tooltip")) {
@@ -8463,13 +8669,13 @@
8463
8669
  return sibling;
8464
8670
  })();
8465
8671
  if (!tooltip) {
8466
- throw new Error("h-tooltip must be placed after an h-tooltip-trigger element");
8672
+ throw new Error(`${original} must be placed after a tooltip trigger element`);
8467
8673
  }
8468
8674
  el.classList.add("absolute", "bg-foreground", "text-background", "z-50", "w-fit", "rounded-md", "px-3", "py-1.5", "text-xs", "text-balance");
8469
8675
  el.setAttribute("data-slot", "tooltip");
8470
8676
  el.setAttribute("id", tooltip._tooltip.controls);
8471
8677
  const arrowEl = document.createElement("span");
8472
- arrowEl.classList.add("absolute", "bg-foreground", "fill-foreground", "z-50", "size-2.5", "rotate-45", "rounded-[2px]");
8678
+ arrowEl.classList.add("absolute", "bg-foreground", "size-2.5", "rotate-45");
8473
8679
  el.appendChild(arrowEl);
8474
8680
  function updatePosition() {
8475
8681
  computePosition2(tooltip, el, {
@@ -8480,11 +8686,12 @@
8480
8686
  left: `${x}px`,
8481
8687
  top: `${y}px`
8482
8688
  });
8483
- if (middlewareData.arrow)
8689
+ if (middlewareData.arrow) {
8484
8690
  Object.assign(arrowEl.style, {
8485
8691
  left: middlewareData.arrow.x != null ? `${middlewareData.arrow.x}px` : "",
8486
- top: placement === "top" ? `${el.offsetHeight - 5}px` : `-5px`
8692
+ top: placement === "top" ? `${el.offsetHeight - arrowEl.clientHeight / 2}px` : `-${arrowEl.clientHeight / 2}px`
8487
8693
  });
8694
+ }
8488
8695
  });
8489
8696
  }
8490
8697
  effect(() => {
@@ -8506,6 +8713,246 @@
8506
8713
  });
8507
8714
  }
8508
8715
 
8716
+ // src/components/tree.js
8717
+ function tree_default(Alpine) {
8718
+ Alpine.directive("h-tree", (el, { modifiers }, { effect, cleanup }) => {
8719
+ el.classList.add("vbox", "w-full", "min-w-0", "gap-1");
8720
+ el.setAttribute("tabindex", "-1");
8721
+ if (modifiers.includes("sub")) {
8722
+ el.classList.add(
8723
+ "relative",
8724
+ "translate-x-px",
8725
+ "py-0.5",
8726
+ "pl-4",
8727
+ "data-[border=true]:before:absolute",
8728
+ "data-[border=true]:before:left-[calc(var(--spacing)*2.5)]",
8729
+ "data-[border=true]:before:block",
8730
+ "data-[border=true]:before:top-0.5",
8731
+ "data-[border=true]:before:bottom-0.5",
8732
+ "data-[border=true]:before:min-w-px",
8733
+ "data-[border=true]:before:w-[calc(var(--spacing)*0.25)]",
8734
+ "data-[border=true]:before:bg-border"
8735
+ );
8736
+ el.setAttribute("data-slot", "subtree");
8737
+ el.setAttribute("role", "group");
8738
+ const treeItem = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_tree_item"));
8739
+ effect(() => {
8740
+ if (treeItem._h_tree_item.expanded) {
8741
+ el.classList.remove("!hidden");
8742
+ } else {
8743
+ el.classList.add("!hidden");
8744
+ }
8745
+ });
8746
+ } else {
8747
+ let getVisibleItems = function(tree) {
8748
+ return [...tree.querySelectorAll('[role="treeitem"]')].filter((item) => {
8749
+ let parent = item.parentElement.closest('[role="group"]');
8750
+ while (parent) {
8751
+ const parentItem = parent.closest('[role="treeitem"]');
8752
+ if (parentItem && parentItem.getAttribute("aria-expanded") === "false") {
8753
+ return false;
8754
+ }
8755
+ parent = parentItem?.parentElement.closest('[role="group"]');
8756
+ }
8757
+ return true;
8758
+ });
8759
+ }, focusItem = function(item) {
8760
+ [...el.querySelectorAll('[role="treeitem"]')].forEach((i) => i.setAttribute("tabindex", "-1"));
8761
+ item.setAttribute("tabindex", "0");
8762
+ item.focus();
8763
+ }, onKeyDown = function(event) {
8764
+ const items = getVisibleItems(el);
8765
+ const current = el.querySelector('li[tabindex="0"]');
8766
+ const index = items.indexOf(current);
8767
+ if (index === -1) return;
8768
+ switch (event.key) {
8769
+ case "Down":
8770
+ case "ArrowDown":
8771
+ event.preventDefault();
8772
+ if (items[index + 1]) focusItem(items[index + 1]);
8773
+ break;
8774
+ case "Up":
8775
+ case "ArrowUp":
8776
+ event.preventDefault();
8777
+ if (items[index - 1]) focusItem(items[index - 1]);
8778
+ break;
8779
+ case "Right":
8780
+ case "ArrowRight":
8781
+ if (current.getAttribute("aria-expanded") === "false") {
8782
+ current.click();
8783
+ } else {
8784
+ const firstChild = current.querySelector('[role="group"] [role="treeitem"]');
8785
+ if (firstChild) focusItem(firstChild);
8786
+ }
8787
+ break;
8788
+ case "Left":
8789
+ case "ArrowLeft":
8790
+ if (current.getAttribute("aria-expanded") === "true") {
8791
+ current.click();
8792
+ } else {
8793
+ const parentItem = current.parentElement.closest('[role="treeitem"]');
8794
+ if (parentItem) focusItem(parentItem);
8795
+ }
8796
+ break;
8797
+ case "Home":
8798
+ event.preventDefault();
8799
+ focusItem(items[0]);
8800
+ break;
8801
+ case "End":
8802
+ event.preventDefault();
8803
+ focusItem(items[items.length - 1]);
8804
+ break;
8805
+ case "Enter":
8806
+ case " ":
8807
+ event.preventDefault();
8808
+ current.click();
8809
+ break;
8810
+ }
8811
+ };
8812
+ el.setAttribute("data-slot", "tree");
8813
+ el.setAttribute("role", "tree");
8814
+ el.addEventListener("keydown", onKeyDown);
8815
+ cleanup(() => {
8816
+ el.removeEventListener("keydown", onClick);
8817
+ });
8818
+ }
8819
+ });
8820
+ Alpine.directive("h-tree-item", (el, { modifiers, expression }, { evaluate: evaluate2, evaluateLater, effect, cleanup }) => {
8821
+ el._h_tree_item = Alpine.reactive({
8822
+ hasSubtree: modifiers.includes("expanded"),
8823
+ expanded: true
8824
+ });
8825
+ el.classList.add(
8826
+ "group/tree-item",
8827
+ "relative",
8828
+ "outline-none",
8829
+ 'focus:[&>[data-slot="tree-button"]]:bg-secondary',
8830
+ 'focus:[&>[data-slot="tree-button"]]:text-secondary-foreground',
8831
+ 'aria-selected:[&>[data-slot="tree-button"]]:bg-primary',
8832
+ 'aria-selected:[&>[data-slot="tree-button"]]:font-medium',
8833
+ 'aria-selected:[&>[data-slot="tree-button"]]:text-primary-foreground'
8834
+ );
8835
+ el.setAttribute("data-slot", "tree-item");
8836
+ el.setAttribute("role", "treeitem");
8837
+ const treeRoot = Alpine.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "tree");
8838
+ if (treeRoot && treeRoot.querySelector("[data-slot=tree-item]") === el) {
8839
+ el.setAttribute("tabindex", "0");
8840
+ } else {
8841
+ el.setAttribute("tabindex", "-1");
8842
+ }
8843
+ effect(() => {
8844
+ if (!el.closest('[role="tree"]')) return;
8845
+ });
8846
+ const onClick2 = (event) => {
8847
+ if (event.target === el || event.target.parentElement === el) {
8848
+ if (el._h_tree_item.hasSubtree) {
8849
+ if (expression === "false" || expression === "true") {
8850
+ el._h_tree_item.expanded = el.getAttribute("aria-expanded") === "true" ? false : true;
8851
+ el.setAttribute("aria-expanded", el._h_tree_item.expanded);
8852
+ } else {
8853
+ el._h_tree_item.expanded = !evaluate2(expression);
8854
+ evaluate2(`${expression} = !${expression}`);
8855
+ }
8856
+ }
8857
+ [...treeRoot.querySelectorAll('[role="treeitem"]')].forEach((i) => i.setAttribute("tabindex", "-1"));
8858
+ el.setAttribute("tabindex", "0");
8859
+ }
8860
+ };
8861
+ el.addEventListener("click", onClick2);
8862
+ cleanup(() => {
8863
+ el.removeEventListener("click", onClick2);
8864
+ });
8865
+ if (el._h_tree_item.hasSubtree) {
8866
+ const setExpanded = (expanded) => {
8867
+ el._h_tree_item.expanded = expanded;
8868
+ el.setAttribute("aria-expanded", expanded);
8869
+ };
8870
+ const getExpanded = evaluateLater(expression);
8871
+ effect(() => {
8872
+ getExpanded((expanded) => {
8873
+ setExpanded(expanded);
8874
+ });
8875
+ });
8876
+ }
8877
+ });
8878
+ Alpine.directive("h-tree-button", (el, { original }, { effect }) => {
8879
+ const treeItem = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_tree_item"));
8880
+ if (!treeItem) throw new Error(`${original} must be inside a tree item`);
8881
+ el.classList.add(
8882
+ "flex",
8883
+ "w-full",
8884
+ "items-center",
8885
+ "gap-2",
8886
+ "overflow-hidden",
8887
+ "rounded-md",
8888
+ "p-1.5",
8889
+ "text-left",
8890
+ "text-sm",
8891
+ "align-middle",
8892
+ "outline-hidden",
8893
+ "ring-ring",
8894
+ "transition-[width,height,padding]",
8895
+ "hover:bg-secondary",
8896
+ "hover:text-secondary-foreground",
8897
+ "focus-visible:ring-2",
8898
+ "active:bg-primary",
8899
+ "active:text-primary-foreground",
8900
+ "disabled:pointer-events-none",
8901
+ "disabled:opacity-50",
8902
+ "aria-disabled:pointer-events-none",
8903
+ "aria-disabled:opacity-50",
8904
+ "[&>span]:w-full",
8905
+ "[&>span]:truncate",
8906
+ "[&>span]:align-middle",
8907
+ "[&>span]:pointer-events-none",
8908
+ "[&>svg]:size-4",
8909
+ "[&>svg]:shrink-0",
8910
+ "[&>svg]:pointer-events-none",
8911
+ "data-[indicator]:after:block",
8912
+ "data-[indicator]:after:ml-auto",
8913
+ "data-[indicator]:after:rounded-full",
8914
+ "data-[indicator]:after:size-2",
8915
+ "data-[indicator=positive]:after:bg-positive",
8916
+ "data-[indicator=negative]:after:bg-negative",
8917
+ "data-[indicator=warning]:after:bg-warning",
8918
+ "data-[indicator=information]:after:bg-information",
8919
+ "before:mr-1",
8920
+ "before:bg-transparent",
8921
+ "before:min-w-1.5",
8922
+ "before:size-1.5",
8923
+ "before:pointer-events-none"
8924
+ );
8925
+ el.setAttribute("data-slot", "tree-button");
8926
+ el.setAttribute("tabindex", "-1");
8927
+ el.setAttribute("role", "presentation");
8928
+ if (treeItem._h_tree_item.hasSubtree) {
8929
+ el.classList.add(
8930
+ "before:block",
8931
+ "before:mr-1",
8932
+ "before:bg-transparent",
8933
+ "before:border-t-[calc(var(--spacing)*0.25)]",
8934
+ "before:border-r-[calc(var(--spacing)*0.25)]",
8935
+ "before:border-foreground",
8936
+ "active:before:border-primary-foreground",
8937
+ "before:pointer-events-none",
8938
+ "before:min-w-1.5",
8939
+ "before:size-1.5",
8940
+ "before:rounded-[calc(var(--spacing)*0.25)]",
8941
+ "before:rotate-135",
8942
+ "before:translate-x-1/2",
8943
+ "before:-translate-y-0.25",
8944
+ "data-[expanded=false]:before:rotate-45",
8945
+ "data-[expanded=false]:before:translate-x-1/2",
8946
+ "data-[expanded=false]:before:-translate-y-0",
8947
+ "aria-selected:before:border-primary-foreground"
8948
+ );
8949
+ }
8950
+ effect(() => {
8951
+ el.setAttribute("data-expanded", treeItem._h_tree_item.expanded);
8952
+ });
8953
+ });
8954
+ }
8955
+
8509
8956
  // src/utils/theme.js
8510
8957
  var colorSchemeKey = "codbex.harmonia.colorMode";
8511
8958
  var savedScheme = localStorage.getItem(colorSchemeKey);
@@ -8581,13 +9028,13 @@
8581
9028
  initColorScheme();
8582
9029
 
8583
9030
  // src/utils/breakpoint-listener.js
8584
- function getBreakpointListener(handler2, breakpoint = 768) {
9031
+ function getBreakpointListener(handler, breakpoint = 768) {
8585
9032
  const mql = top.matchMedia(`(width <= ${breakpoint}px)`);
8586
9033
  const onWidthChange = (event) => {
8587
- handler2(event.matches);
9034
+ handler(event.matches);
8588
9035
  };
8589
9036
  mql.addEventListener("change", onWidthChange);
8590
- handler2(mql.matches);
9037
+ handler(mql.matches);
8591
9038
  return {
8592
9039
  _mql: mql,
8593
9040
  _onWidthChange: onWidthChange,
@@ -8630,7 +9077,7 @@
8630
9077
  }
8631
9078
 
8632
9079
  // package.json
8633
- var version = "0.8.0";
9080
+ var version = "0.9.1";
8634
9081
 
8635
9082
  // src/index.js
8636
9083
  window.Harmonia = { getBreakpointListener, addColorSchemeListener, getColorScheme, removeColorSchemeListener, setColorScheme, version };
@@ -8675,6 +9122,7 @@
8675
9122
  window.Alpine.plugin(timepicker_default);
8676
9123
  window.Alpine.plugin(toolbar_default);
8677
9124
  window.Alpine.plugin(tooltip_default);
9125
+ window.Alpine.plugin(tree_default);
8678
9126
  window.Alpine.plugin(focus_default);
8679
9127
  window.Alpine.plugin(template_default);
8680
9128
  });
@@ -8694,7 +9142,7 @@ lucide/dist/esm/icons/clock.js:
8694
9142
  lucide/dist/esm/icons/search.js:
8695
9143
  lucide/dist/esm/lucide.js:
8696
9144
  (**
8697
- * @license lucide v0.544.0 - ISC
9145
+ * @license lucide v0.562.0 - ISC
8698
9146
  *
8699
9147
  * This source code is licensed under the ISC license.
8700
9148
  * See the LICENSE file in the root directory of this source tree.