@codbex/harmonia 1.1.2 → 1.2.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
@@ -65,6 +65,8 @@
65
65
  var Clock = 7;
66
66
  var Search = 8;
67
67
  var Ellipsis = 9;
68
+ var Minus = 10;
69
+ var Plus = 11;
68
70
  function setCalendarContent(svg) {
69
71
  const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
70
72
  path.setAttributeNS(
@@ -177,6 +179,20 @@
177
179
  circle3.setAttributeNS(null, "r", "1.5");
178
180
  svg.appendChild(circle3);
179
181
  }
182
+ function setMinusContent(svg) {
183
+ const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
184
+ path.setAttributeNS(null, "d", "m2.75 7.25h10.5c0.4155 0 0.75 0.3345 0.75 0.75s-0.3345 0.75-0.75 0.75h-10.5c-0.4155 0-0.75-0.3345-0.75-0.75s0.3345-0.75 0.75-0.75z");
185
+ svg.appendChild(path);
186
+ }
187
+ function setPlusContent(svg) {
188
+ const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
189
+ path.setAttributeNS(
190
+ null,
191
+ "d",
192
+ "m8 2c-0.4155 0-0.75 0.3345-0.75 0.75v4.5h-4.5c-0.4155 0-0.75 0.3345-0.75 0.75s0.3345 0.75 0.75 0.75h4.5v4.5c0 0.4155 0.3345 0.75 0.75 0.75s0.75-0.3345 0.75-0.75v-4.5h4.5c0.4155 0 0.75-0.3345 0.75-0.75s-0.3345-0.75-0.75-0.75h-4.5v-4.5c0-0.4155-0.3345-0.75-0.75-0.75z"
193
+ );
194
+ svg.appendChild(path);
195
+ }
180
196
  function createSvg({ icon, classes = "size-4", attrs } = {}) {
181
197
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
182
198
  svg.setAttributeNS(null, "width", "16");
@@ -220,9 +236,64 @@
220
236
  case Ellipsis:
221
237
  setEllipsisContent(svg);
222
238
  break;
239
+ case Minus:
240
+ setMinusContent(svg);
241
+ break;
242
+ case Plus:
243
+ setPlusContent(svg);
244
+ break;
245
+ default:
246
+ break;
223
247
  }
224
248
  return svg;
225
249
  }
250
+ function setSvgContent(svg, icon) {
251
+ svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
252
+ svg.setAttribute("width", "16");
253
+ svg.setAttribute("height", "16");
254
+ svg.setAttribute("viewBox", "0 0 16 16");
255
+ svg.setAttribute("fill", "currentColor");
256
+ switch (icon) {
257
+ case "calendar":
258
+ setCalendarContent(svg);
259
+ break;
260
+ case "check":
261
+ setCheckContent(svg);
262
+ break;
263
+ case "chevron-down":
264
+ setChevronDownContent(svg);
265
+ break;
266
+ case "chevron-left":
267
+ setChevronLeftContent(svg);
268
+ break;
269
+ case "chevron-right":
270
+ setChevronRightContent(svg);
271
+ break;
272
+ case "chevrons-left":
273
+ setChevronsLeftContent(svg);
274
+ break;
275
+ case "chevrons-right":
276
+ setChevronsRightContent(svg);
277
+ break;
278
+ case "clock":
279
+ setClockContent(svg);
280
+ break;
281
+ case "search":
282
+ setSearchContent(svg);
283
+ break;
284
+ case "ellipsis":
285
+ setEllipsisContent(svg);
286
+ break;
287
+ case "minus":
288
+ setMinusContent(svg);
289
+ break;
290
+ case "plus":
291
+ setPlusContent(svg);
292
+ break;
293
+ default:
294
+ break;
295
+ }
296
+ }
226
297
 
227
298
  // src/components/accordion.js
228
299
  function accordion_default(Alpine) {
@@ -233,10 +304,10 @@
233
304
  }) : { single: false };
234
305
  el.setAttribute("data-slot", "accordion");
235
306
  });
236
- Alpine.directive("h-accordion-item", (el, { original, expression, modifiers }, { effect, Alpine: Alpine2 }) => {
307
+ Alpine.directive("h-accordion-item", (el, { original: original2, expression, modifiers }, { effect, Alpine: Alpine2 }) => {
237
308
  const accordion = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_accordion"));
238
309
  if (!accordion) {
239
- throw new Error(`${original} must be inside an accordion`);
310
+ throw new Error(`${original2} must be inside an accordion`);
240
311
  }
241
312
  el.classList.add("border-b", "last:border-b-0", "[[data-variant=header]_&]:data-[state=closed]:border-b-0");
242
313
  el.setAttribute("data-slot", "accordion-item");
@@ -264,14 +335,14 @@
264
335
  setAttributes();
265
336
  effect(setAttributes);
266
337
  });
267
- Alpine.directive("h-accordion-trigger", (el, { original, expression }, { effect, evaluateLater, Alpine: Alpine2, cleanup }) => {
338
+ Alpine.directive("h-accordion-trigger", (el, { original: original2, expression }, { effect, evaluateLater, Alpine: Alpine2, cleanup }) => {
268
339
  if (el.tagName.length !== 2 && !el.tagName.startsWith("H")) {
269
- throw new Error(`${original} must be a header element`);
340
+ throw new Error(`${original2} must be a header element`);
270
341
  }
271
342
  const accordion = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_accordion"));
272
343
  const accordionItem = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_accordionItem"));
273
344
  if (!accordionItem || !accordion) {
274
- throw new Error(`${original} must have an accordion and accordion item parent elements`);
345
+ throw new Error(`${original2} must have an accordion and accordion item parent elements`);
275
346
  }
276
347
  el.classList.add(
277
348
  "flex",
@@ -456,10 +527,10 @@
456
527
  el.classList.add("cursor-pointer", "hover:bg-secondary-hover", "active:bg-secondary-active");
457
528
  }
458
529
  });
459
- Alpine.directive("h-avatar-image", (el, { original }, { cleanup }) => {
530
+ Alpine.directive("h-avatar-image", (el, { original: original2 }, { cleanup }) => {
460
531
  const avatar = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_avatar"));
461
532
  if (!avatar) {
462
- throw new Error(`${original} must be inside an h-avatar element`);
533
+ throw new Error(`${original2} must be inside an avatar element`);
463
534
  }
464
535
  el.classList.add("aspect-square", "size-full");
465
536
  el.setAttribute("data-slot", "avatar-image");
@@ -490,10 +561,10 @@
490
561
  observer.disconnect();
491
562
  });
492
563
  });
493
- Alpine.directive("h-avatar-fallback", (el, { original }, { effect }) => {
564
+ Alpine.directive("h-avatar-fallback", (el, { original: original2 }, { effect }) => {
494
565
  const avatar = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_avatar"));
495
566
  if (!avatar) {
496
- throw new Error(`${original} must be inside an h-avatar element`);
567
+ throw new Error(`${original2} must be inside an avatar element`);
497
568
  }
498
569
  el.classList.add("hidden", "bg-muted", "flex", "size-full", "items-center", "justify-center");
499
570
  el.setAttribute("data-slot", "avatar-fallback");
@@ -702,7 +773,7 @@
702
773
  }
703
774
  };
704
775
  function button_default(Alpine) {
705
- Alpine.directive("h-button", (el, { original, modifiers }, { cleanup }) => {
776
+ Alpine.directive("h-button", (el, { original: original2, modifiers }, { cleanup }) => {
706
777
  setButtonClasses(el);
707
778
  if (!el.hasAttribute("data-slot")) {
708
779
  el.setAttribute("data-slot", "button");
@@ -719,7 +790,7 @@
719
790
  el.classList.remove(...getButtonSize(lastSize, isAddon));
720
791
  el.classList.add(...getButtonSize(size3, isAddon));
721
792
  if (size3.startsWith("icon") && !el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
722
- console.error(`${original}: Icon-only buttons must have an "aria-label" or "aria-labelledby" attribute`, el);
793
+ console.error(`${original2}: Icon-only buttons must have an "aria-label" or "aria-labelledby" attribute`, el);
723
794
  }
724
795
  lastSize = size3;
725
796
  }
@@ -970,6 +1041,62 @@
970
1041
  }
971
1042
  return coords;
972
1043
  }
1044
+ async function detectOverflow(state, options) {
1045
+ var _await$platform$isEle;
1046
+ if (options === void 0) {
1047
+ options = {};
1048
+ }
1049
+ const {
1050
+ x,
1051
+ y,
1052
+ platform: platform2,
1053
+ rects,
1054
+ elements,
1055
+ strategy
1056
+ } = state;
1057
+ const {
1058
+ boundary = "clippingAncestors",
1059
+ rootBoundary = "viewport",
1060
+ elementContext = "floating",
1061
+ altBoundary = false,
1062
+ padding = 0
1063
+ } = evaluate(options, state);
1064
+ const paddingObject = getPaddingObject(padding);
1065
+ const altContext = elementContext === "floating" ? "reference" : "floating";
1066
+ const element = elements[altBoundary ? altContext : elementContext];
1067
+ const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
1068
+ element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
1069
+ boundary,
1070
+ rootBoundary,
1071
+ strategy
1072
+ }));
1073
+ const rect = elementContext === "floating" ? {
1074
+ x,
1075
+ y,
1076
+ width: rects.floating.width,
1077
+ height: rects.floating.height
1078
+ } : rects.reference;
1079
+ const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
1080
+ const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
1081
+ x: 1,
1082
+ y: 1
1083
+ } : {
1084
+ x: 1,
1085
+ y: 1
1086
+ };
1087
+ const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
1088
+ elements,
1089
+ rect,
1090
+ offsetParent,
1091
+ strategy
1092
+ }) : rect);
1093
+ return {
1094
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
1095
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
1096
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
1097
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
1098
+ };
1099
+ }
973
1100
  var computePosition = async (reference, floating, config) => {
974
1101
  const {
975
1102
  placement = "bottom",
@@ -992,6 +1119,7 @@
992
1119
  let middlewareData = {};
993
1120
  let resetCount = 0;
994
1121
  for (let i = 0; i < validMiddleware.length; i++) {
1122
+ var _platform$detectOverf;
995
1123
  const {
996
1124
  name,
997
1125
  fn
@@ -1009,7 +1137,10 @@
1009
1137
  strategy,
1010
1138
  middlewareData,
1011
1139
  rects,
1012
- platform: platform2,
1140
+ platform: {
1141
+ ...platform2,
1142
+ detectOverflow: (_platform$detectOverf = platform2.detectOverflow) != null ? _platform$detectOverf : detectOverflow
1143
+ },
1013
1144
  elements: {
1014
1145
  reference,
1015
1146
  floating
@@ -1053,62 +1184,6 @@
1053
1184
  middlewareData
1054
1185
  };
1055
1186
  };
1056
- async function detectOverflow(state, options) {
1057
- var _await$platform$isEle;
1058
- if (options === void 0) {
1059
- options = {};
1060
- }
1061
- const {
1062
- x,
1063
- y,
1064
- platform: platform2,
1065
- rects,
1066
- elements,
1067
- strategy
1068
- } = state;
1069
- const {
1070
- boundary = "clippingAncestors",
1071
- rootBoundary = "viewport",
1072
- elementContext = "floating",
1073
- altBoundary = false,
1074
- padding = 0
1075
- } = evaluate(options, state);
1076
- const paddingObject = getPaddingObject(padding);
1077
- const altContext = elementContext === "floating" ? "reference" : "floating";
1078
- const element = elements[altBoundary ? altContext : elementContext];
1079
- const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
1080
- element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
1081
- boundary,
1082
- rootBoundary,
1083
- strategy
1084
- }));
1085
- const rect = elementContext === "floating" ? {
1086
- x,
1087
- y,
1088
- width: rects.floating.width,
1089
- height: rects.floating.height
1090
- } : rects.reference;
1091
- const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
1092
- const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
1093
- x: 1,
1094
- y: 1
1095
- } : {
1096
- x: 1,
1097
- y: 1
1098
- };
1099
- const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
1100
- elements,
1101
- rect,
1102
- offsetParent,
1103
- strategy
1104
- }) : rect);
1105
- return {
1106
- top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
1107
- bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
1108
- left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
1109
- right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
1110
- };
1111
- }
1112
1187
  var arrow = (options) => ({
1113
1188
  name: "arrow",
1114
1189
  options,
@@ -1210,7 +1285,7 @@
1210
1285
  fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
1211
1286
  }
1212
1287
  const placements2 = [initialPlacement, ...fallbackPlacements];
1213
- const overflow = await detectOverflow(state, detectOverflowOptions);
1288
+ const overflow = await platform2.detectOverflow(state, detectOverflowOptions);
1214
1289
  const overflows = [];
1215
1290
  let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
1216
1291
  if (checkMainAxis) {
@@ -1359,7 +1434,8 @@
1359
1434
  const {
1360
1435
  x,
1361
1436
  y,
1362
- placement
1437
+ placement,
1438
+ platform: platform2
1363
1439
  } = state;
1364
1440
  const {
1365
1441
  mainAxis: checkMainAxis = true,
@@ -1382,7 +1458,7 @@
1382
1458
  x,
1383
1459
  y
1384
1460
  };
1385
- const overflow = await detectOverflow(state, detectOverflowOptions);
1461
+ const overflow = await platform2.detectOverflow(state, detectOverflowOptions);
1386
1462
  const crossAxis = getSideAxis(getSide(placement));
1387
1463
  const mainAxis = getOppositeAxis(crossAxis);
1388
1464
  let mainAxisCoord = coords[mainAxis];
@@ -1440,7 +1516,7 @@
1440
1516
  },
1441
1517
  ...detectOverflowOptions
1442
1518
  } = evaluate(options, state);
1443
- const overflow = await detectOverflow(state, detectOverflowOptions);
1519
+ const overflow = await platform2.detectOverflow(state, detectOverflowOptions);
1444
1520
  const side = getSide(placement);
1445
1521
  const alignment = getAlignment(placement);
1446
1522
  const isYAxis = getSideAxis(placement) === "y";
@@ -2263,7 +2339,7 @@
2263
2339
 
2264
2340
  // src/components/calendar.js
2265
2341
  function calendar_default(Alpine) {
2266
- Alpine.directive("h-calendar", (el, { original, expression }, { effect, evaluateLater, cleanup, Alpine: Alpine2 }) => {
2342
+ Alpine.directive("h-calendar", (el, { original: original2, expression }, { effect, evaluateLater, cleanup, Alpine: Alpine2 }) => {
2267
2343
  const datepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_datepicker"));
2268
2344
  el.classList.add("border", "rounded-control", "gap-2", "p-2");
2269
2345
  el.setAttribute("tabindex", "-1");
@@ -2272,7 +2348,7 @@
2272
2348
  el.setAttribute("role", "dialog");
2273
2349
  el.setAttribute("aria-modal", "true");
2274
2350
  el.setAttribute("data-slot", "date-picker-calendar");
2275
- el.setAttribute("data-state", datepicker._h_datepicker.expanded ? "open" : "closed");
2351
+ el.setAttribute("data-state", datepicker._h_datepicker.state.expanded ? "open" : "closed");
2276
2352
  } else {
2277
2353
  el.classList.add("shadow-input", "data-[invalid=true]:border-negative", "data-[invalid=true]:ring-negative/20", "dark:data-[invalid=true]:ring-negative/40");
2278
2354
  }
@@ -2307,7 +2383,7 @@
2307
2383
  const onInputChange = () => {
2308
2384
  const newValue = new Date(datepicker._h_datepicker.input.value);
2309
2385
  if (isNaN(newValue)) {
2310
- console.error(`${original}: input value is not a valid date - ${datepicker._h_datepicker.input.value}`);
2386
+ console.error(`${original2}: input value is not a valid date - ${datepicker._h_datepicker.input.value}`);
2311
2387
  datepicker._h_datepicker.input.setCustomValidity("Input value is not a valid date.");
2312
2388
  return;
2313
2389
  } else if (selected.getTime() !== newValue.getTime()) {
@@ -2324,7 +2400,7 @@
2324
2400
  if (el.hasOwnProperty("_x_model") && el._x_model.get()) {
2325
2401
  selected = new Date(el._x_model.get());
2326
2402
  if (isNaN(selected)) {
2327
- console.error(`${original}: input value is not a valid date - ${el._x_model.get()}`);
2403
+ console.error(`${original2}: input value is not a valid date - ${el._x_model.get()}`);
2328
2404
  if (datepicker) datepicker._h_datepicker.input.setCustomValidity("Input value is not a valid date.");
2329
2405
  else el.setAttribute("data-invalid", "true");
2330
2406
  } else if (datepicker) {
@@ -2338,7 +2414,7 @@
2338
2414
  selected = new Date(focusedDay);
2339
2415
  modelChange(true);
2340
2416
  render();
2341
- if (datepicker) datepicker._h_datepicker.expanded = false;
2417
+ if (datepicker) datepicker._h_datepicker.state.expanded = false;
2342
2418
  }
2343
2419
  function isDisabled(d) {
2344
2420
  if (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) return true;
@@ -2648,7 +2724,7 @@
2648
2724
  break;
2649
2725
  case "Escape":
2650
2726
  event.preventDefault();
2651
- if (datepicker) datepicker._h_datepicker.expanded = false;
2727
+ if (datepicker) datepicker._h_datepicker.state.expanded = false;
2652
2728
  return;
2653
2729
  case "Enter":
2654
2730
  case " ":
@@ -2712,8 +2788,8 @@
2712
2788
  }
2713
2789
  if (datepicker) {
2714
2790
  effect(() => {
2715
- el.setAttribute("data-state", datepicker._h_datepicker.expanded ? "open" : "closed");
2716
- if (datepicker._h_datepicker.expanded) {
2791
+ el.setAttribute("data-state", datepicker._h_datepicker.state.expanded ? "open" : "closed");
2792
+ if (datepicker._h_datepicker.state.expanded) {
2717
2793
  autoUpdateCleanup = autoUpdate(datepicker, el, updatePosition);
2718
2794
  Alpine2.nextTick(() => {
2719
2795
  focusDay();
@@ -2833,10 +2909,10 @@
2833
2909
  });
2834
2910
  }
2835
2911
  });
2836
- Alpine.directive("h-collapsible-trigger", (el, { original, modifiers }, { effect, Alpine: Alpine2, cleanup }) => {
2912
+ Alpine.directive("h-collapsible-trigger", (el, { original: original2, modifiers }, { effect, Alpine: Alpine2, cleanup }) => {
2837
2913
  const collapsible = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_collapsible"));
2838
2914
  if (!collapsible) {
2839
- throw new Error(`${original} must be inside a collapsible element`);
2915
+ throw new Error(`${original2} must be inside a collapsible element`);
2840
2916
  }
2841
2917
  if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "collapsible-trigger");
2842
2918
  if (modifiers.includes("chevron")) {
@@ -2855,10 +2931,10 @@
2855
2931
  el.removeEventListener("click", handler);
2856
2932
  });
2857
2933
  });
2858
- Alpine.directive("h-collapsible-content", (el, { original }, { effect, Alpine: Alpine2 }) => {
2934
+ Alpine.directive("h-collapsible-content", (el, { original: original2 }, { effect, Alpine: Alpine2 }) => {
2859
2935
  const collapsible = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_collapsible"));
2860
2936
  if (!collapsible) {
2861
- throw new Error(`${original} must be inside an h-collapsible element`);
2937
+ throw new Error(`${original2} must be inside an h-collapsible element`);
2862
2938
  }
2863
2939
  if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "collapsible-content");
2864
2940
  el.classList.add("data-[state=closed]:!hidden");
@@ -2889,16 +2965,20 @@
2889
2965
 
2890
2966
  // src/components/datepicker.js
2891
2967
  function datepicker_default(Alpine) {
2892
- Alpine.directive("h-date-picker", (el, { original }, { Alpine: Alpine2, cleanup }) => {
2893
- el._h_datepicker = Alpine2.reactive({
2968
+ Alpine.directive("h-date-picker", (el, { original: original2, modifiers }, { Alpine: Alpine2, cleanup }) => {
2969
+ const state = Alpine2.reactive({
2970
+ expanded: false
2971
+ });
2972
+ el._h_datepicker = {
2894
2973
  id: void 0,
2895
2974
  controls: `hdpc${v4_default()}`,
2896
2975
  input: void 0,
2897
- expanded: false
2898
- });
2976
+ state,
2977
+ inTable: modifiers.includes("table")
2978
+ };
2899
2979
  el._h_datepicker.input = el.querySelector("input");
2900
2980
  if (!el._h_datepicker.input || el._h_datepicker.input.tagName !== "INPUT") {
2901
- throw new Error(`${original} must contain an input`);
2981
+ throw new Error(`${original2} must contain an input`);
2902
2982
  } else if (el._h_datepicker.input.hasAttribute("id")) {
2903
2983
  el._h_datepicker.id = el._h_datepicker.input.getAttribute("id");
2904
2984
  } else {
@@ -2907,30 +2987,50 @@
2907
2987
  el._h_datepicker.id = id;
2908
2988
  }
2909
2989
  el.classList.add(
2990
+ "overflow-hidden",
2910
2991
  "border-input",
2911
- "bg-input-inner",
2912
2992
  "flex",
2913
- "w-full",
2914
2993
  "items-center",
2915
- "rounded-control",
2916
- "border",
2917
- "shadow-input",
2918
2994
  "transition-[color,box-shadow]",
2919
2995
  "duration-200",
2920
2996
  "outline-none",
2921
2997
  "pl-3",
2922
2998
  "min-w-0",
2923
- "has-[input:focus-visible]:border-ring",
2924
- "has-[input:focus-visible]:ring-ring/50",
2925
- "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
2926
- "has-[input[aria-invalid=true]]:ring-negative/20",
2927
- "has-[input[aria-invalid=true]]:border-negative",
2928
- "dark:has-[input[aria-invalid=true]]:ring-negative/40",
2929
- "has-[input:invalid]:ring-negative/20",
2930
- "has-[input:invalid]:border-negative",
2931
- "dark:has-[input:invalid]:ring-negative/40"
2999
+ "has-[input:disabled]:pointer-events-none",
3000
+ "has-[input:disabled]:cursor-not-allowed",
3001
+ "has-[input:disabled]:opacity-50"
2932
3002
  );
2933
- el.setAttribute("data-slot", "date-picker");
3003
+ if (el._h_datepicker.inTable) {
3004
+ el.classList.add(
3005
+ "size-full",
3006
+ "h-10",
3007
+ "has-[input:focus-visible]:inset-ring-ring/50",
3008
+ "has-[input:focus-visible]:inset-ring-2",
3009
+ "has-[input[aria-invalid=true]]:inset-ring-negative/20",
3010
+ "dark:has-[input[aria-invalid=true]]:inset-ring-negative/40",
3011
+ "has-[input:invalid]:!inset-ring-negative/20",
3012
+ "dark:has-[input:invalid]:!inset-ring-negative/40"
3013
+ );
3014
+ el.setAttribute("data-slot", "cell-input-date");
3015
+ } else {
3016
+ el.classList.add(
3017
+ "w-full",
3018
+ "rounded-control",
3019
+ "border",
3020
+ "bg-input-inner",
3021
+ "shadow-input",
3022
+ "has-[input:focus-visible]:border-ring",
3023
+ "has-[input:focus-visible]:ring-ring/50",
3024
+ "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
3025
+ "has-[input[aria-invalid=true]]:ring-negative/20",
3026
+ "has-[input[aria-invalid=true]]:border-negative",
3027
+ "dark:has-[input[aria-invalid=true]]:ring-negative/40",
3028
+ "has-[input:invalid]:ring-negative/20",
3029
+ "has-[input:invalid]:border-negative",
3030
+ "dark:has-[input:invalid]:ring-negative/40"
3031
+ );
3032
+ el.setAttribute("data-slot", "date-picker");
3033
+ }
2934
3034
  el._h_datepicker.input.classList.add(
2935
3035
  "bg-transparent",
2936
3036
  "outline-none",
@@ -2955,39 +3055,40 @@
2955
3055
  observer.disconnect();
2956
3056
  });
2957
3057
  });
2958
- Alpine.directive("h-date-picker-trigger", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
3058
+ Alpine.directive("h-date-picker-trigger", (el, { original: original2 }, { effect, cleanup, Alpine: Alpine2 }) => {
2959
3059
  if (el.tagName !== "BUTTON") {
2960
- throw new Error(`${original} must be a button`);
3060
+ throw new Error(`${original2} must be a button`);
2961
3061
  }
2962
3062
  if (!el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
2963
- throw new Error(`${original}: must have an "aria-label" or "aria-labelledby" attribute`);
3063
+ throw new Error(`${original2}: must have an "aria-label" or "aria-labelledby" attribute`);
2964
3064
  }
2965
3065
  const datepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_datepicker"));
2966
3066
  if (!datepicker) {
2967
- throw new Error(`${original} must be inside an date-picker element`);
3067
+ throw new Error(`${original2} must be inside an date-picker element`);
3068
+ }
3069
+ el.classList.add("cursor-pointer", "inline-flex", "items-center", "justify-center", "h-full", "aspect-square", "bg-transparent", "hover:bg-secondary", "active:bg-secondary-active", "outline-none");
3070
+ if (datepicker._h_datepicker.inTable) {
3071
+ el.classList.add(
3072
+ "focus-visible:inset-ring-ring/50",
3073
+ "focus-visible:inset-ring-2",
3074
+ "[input[aria-invalid=true]~&]:inset-ring-negative/20",
3075
+ "dark:[input[aria-invalid=true]~&]:inset-ring-negative/40",
3076
+ "[input:invalid~&]:!inset-ring-negative/20",
3077
+ "dark:[input:invalid~&]:!inset-ring-negative/40"
3078
+ );
3079
+ } else {
3080
+ el.classList.add(
3081
+ "focus-visible:border-ring",
3082
+ "focus-visible:ring-ring/50",
3083
+ "focus-visible:ring-[calc(var(--spacing)*0.75)]",
3084
+ "[input[aria-invalid=true]~&]:ring-negative/20",
3085
+ "[input[aria-invalid=true]~&]:border-negative",
3086
+ "dark:[input[aria-invalid=true]~&]:ring-negative/40",
3087
+ "[input:invalid~&]:ring-negative/20",
3088
+ "[input:invalid~&]:border-negative",
3089
+ "dark:[input:invalid~&]:ring-negative/40"
3090
+ );
2968
3091
  }
2969
- el.classList.add(
2970
- "cursor-pointer",
2971
- "inline-flex",
2972
- "items-center",
2973
- "justify-center",
2974
- "rounded-r-control",
2975
- "h-full",
2976
- "aspect-square",
2977
- "bg-transparent",
2978
- "hover:bg-secondary",
2979
- "active:bg-secondary-active",
2980
- "outline-none",
2981
- "focus-visible:border-ring",
2982
- "focus-visible:ring-ring/50",
2983
- "focus-visible:ring-[calc(var(--spacing)*0.75)]",
2984
- "[input[aria-invalid=true]~&]:ring-negative/20",
2985
- "[input[aria-invalid=true]~&]:border-negative",
2986
- "dark:[input[aria-invalid=true]~&]:ring-negative/40",
2987
- "[input:invalid~&]:ring-negative/20",
2988
- "[input:invalid~&]:border-negative",
2989
- "dark:[input:invalid~&]:ring-negative/40"
2990
- );
2991
3092
  el.setAttribute("aria-controls", datepicker._h_datepicker.controls);
2992
3093
  el.setAttribute("aria-expanded", "false");
2993
3094
  el.setAttribute("aria-haspopup", "dialog");
@@ -3004,17 +3105,16 @@
3004
3105
  })
3005
3106
  );
3006
3107
  effect(() => {
3007
- el.setAttribute("data-state", datepicker._h_datepicker.expanded ? "open" : "closed");
3008
- el.setAttribute("aria-expanded", datepicker._h_datepicker.expanded);
3108
+ el.setAttribute("data-state", datepicker._h_datepicker.state.expanded ? "open" : "closed");
3109
+ el.setAttribute("aria-expanded", datepicker._h_datepicker.state.expanded);
3009
3110
  });
3010
3111
  const close = () => {
3011
- datepicker._h_datepicker.expanded = false;
3112
+ datepicker._h_datepicker.state.expanded = false;
3012
3113
  };
3013
3114
  const handler = () => {
3014
- datepicker._h_datepicker.expanded = !datepicker._h_datepicker.expanded;
3015
- el.setAttribute("aria-expanded", datepicker._h_datepicker.expanded);
3115
+ datepicker._h_datepicker.state.expanded = !datepicker._h_datepicker.state.expanded;
3016
3116
  Alpine2.nextTick(() => {
3017
- if (datepicker._h_datepicker.expanded) {
3117
+ if (datepicker._h_datepicker.state.expanded) {
3018
3118
  top.addEventListener("click", close, { once: true });
3019
3119
  } else {
3020
3120
  top.removeEventListener("click", close);
@@ -3101,7 +3201,7 @@
3101
3201
  el.setAttribute("data-slot", "dialog-header");
3102
3202
  });
3103
3203
  Alpine.directive("h-dialog-title", (el, _, { Alpine: Alpine2 }) => {
3104
- el.classList.add("text-lg", "leading-none", "font-semibold");
3204
+ el.classList.add("order-1", "text-lg", "leading-none", "font-semibold");
3105
3205
  el.setAttribute("data-slot", "dialog-title");
3106
3206
  const dialog = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "dialog");
3107
3207
  if (dialog && (!dialog.hasAttribute("aria-labelledby") || !dialog.hasAttribute("aria-label"))) {
@@ -3114,6 +3214,7 @@
3114
3214
  });
3115
3215
  Alpine.directive("h-dialog-close", (el) => {
3116
3216
  el.classList.add(
3217
+ "order-2",
3117
3218
  "ring-offset-background",
3118
3219
  "focus:ring-ring",
3119
3220
  "rounded-xs",
@@ -3129,9 +3230,10 @@
3129
3230
  "[&_svg:not([class*='size-'])]:size-4"
3130
3231
  );
3131
3232
  el.setAttribute("data-slot", "dialog-close");
3233
+ el.setAttribute("type", "button");
3132
3234
  });
3133
3235
  Alpine.directive("h-dialog-description", (el, _, { Alpine: Alpine2 }) => {
3134
- el.classList.add("col-span-full", "text-muted-foreground", "text-sm");
3236
+ el.classList.add("order-3", "col-span-full", "text-muted-foreground", "text-sm");
3135
3237
  el.setAttribute("data-slot", "dialog-description");
3136
3238
  const dialog = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "dialog");
3137
3239
  if (dialog && (!dialog.hasAttribute("aria-describedby") || !dialog.hasAttribute("aria-description"))) {
@@ -3242,13 +3344,13 @@
3242
3344
 
3243
3345
  // src/components/icon.js
3244
3346
  function icon_default(Alpine) {
3245
- Alpine.directive("h-icon", (el, { original }) => {
3347
+ Alpine.directive("h-icon", (el, { original: original2, modifiers }) => {
3246
3348
  if (el.tagName.toLowerCase() !== "svg") {
3247
- throw new Error(`${original} works only on svg elements`);
3349
+ throw new Error(`${original2} works only on svg elements`);
3248
3350
  } else if (!el.hasAttribute("role")) {
3249
- throw new Error(`${original} must have a role`);
3351
+ throw new Error(`${original2} must have a role`);
3250
3352
  } else if (el.getAttribute("role") === "img" && !el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
3251
- throw new Error(`${original}: svg images with the role of img must have an "aria-label" or "aria-labelledby" attribute`);
3353
+ throw new Error(`${original2}: svg images with the role of img must have an "aria-label" or "aria-labelledby" attribute`);
3252
3354
  }
3253
3355
  el.classList.add("fill-current");
3254
3356
  el.setAttribute("data-slot", "icon");
@@ -3266,6 +3368,8 @@
3266
3368
  }).catch((response) => {
3267
3369
  console.error(response);
3268
3370
  });
3371
+ } else if (modifiers[0]) {
3372
+ setSvgContent(el, modifiers[0]);
3269
3373
  }
3270
3374
  });
3271
3375
  }
@@ -3342,6 +3446,18 @@
3342
3446
  if (modifiers.includes("group")) {
3343
3447
  el.classList.add("h-full", "flex-1", "rounded-none", "border-0", "bg-transparent", "shadow-none", "focus-visible:ring-0");
3344
3448
  el.setAttribute("data-slot", "input-group-control");
3449
+ } else if (modifiers.includes("table")) {
3450
+ el.classList.add(
3451
+ "size-full",
3452
+ "h-10",
3453
+ "focus-visible:inset-ring-ring/50",
3454
+ "focus-visible:inset-ring-2",
3455
+ "aria-invalid:inset-ring-negative/20",
3456
+ "dark:aria-invalid:inset-ring-negative/40",
3457
+ "invalid:!inset-ring-negative/20",
3458
+ "dark:invalid:!inset-ring-negative/40"
3459
+ );
3460
+ el.setAttribute("data-slot", "cell-input");
3345
3461
  } else {
3346
3462
  el.classList.add("w-full", "rounded-control", "border", "bg-input-inner", "shadow-input", "focus-visible:ring-[calc(var(--spacing)*0.75)]");
3347
3463
  el.setAttribute("data-slot", "input");
@@ -3451,8 +3567,9 @@
3451
3567
  el.classList.add("text-muted-foreground", "flex", "items-center", "gap-2", "text-sm", "[&_svg]:pointer-events-none", "[&_svg:not([class*='size-'])]:size-4");
3452
3568
  el.setAttribute("data-slot", "label");
3453
3569
  });
3454
- Alpine.directive("h-input-number", (el, { original }, { cleanup }) => {
3570
+ Alpine.directive("h-input-number", (el, { original: original2 }, { cleanup }) => {
3455
3571
  el.classList.add(
3572
+ "overflow-hidden",
3456
3573
  "group/input-number",
3457
3574
  "border-input",
3458
3575
  "bg-input-inner",
@@ -3466,18 +3583,24 @@
3466
3583
  "transition-[color,box-shadow]",
3467
3584
  "outline-none",
3468
3585
  "min-w-0",
3469
- "has-[[data-slot=input-number-control]:focus-visible]:border-ring",
3470
- "has-[[data-slot=input-number-control]:focus-visible]:ring-ring/50",
3471
- "has-[[data-slot=input-number-control]:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
3472
- "has-[[data-slot][aria-invalid=true]]:ring-negative/20",
3473
- "has-[[data-slot][aria-invalid=true]]:border-negative",
3474
- "dark:has-[[data-slot][aria-invalid=true]]:ring-negative/40"
3586
+ "has-[input:focus-visible]:border-ring",
3587
+ "has-[input:focus-visible]:ring-ring/50",
3588
+ "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
3589
+ "has-[input[aria-invalid=true]]:ring-negative/20",
3590
+ "has-[input[aria-invalid=true]]:border-negative",
3591
+ "dark:has-[input[aria-invalid=true]]:ring-negative/40",
3592
+ "has-[input:invalid]:ring-negative/20",
3593
+ "has-[input:invalid]:border-negative",
3594
+ "dark:has-[input:invalid]:ring-negative/40",
3595
+ "has-[input:disabled]:pointer-events-none",
3596
+ "has-[input:disabled]:cursor-not-allowed",
3597
+ "has-[input:disabled]:opacity-50"
3475
3598
  );
3476
3599
  el.setAttribute("role", "group");
3477
3600
  el.setAttribute("data-slot", "input-number");
3478
3601
  const input = el.querySelector("input");
3479
3602
  if (!input || input.getAttribute("type") !== "number") {
3480
- throw new Error(`${original} must contain an input of type 'number'`);
3603
+ throw new Error(`${original2} must contain an input of type 'number'`);
3481
3604
  }
3482
3605
  if (!input.hasAttribute("type")) input.setAttribute("type", "number");
3483
3606
  if (!input.hasAttribute("inputmode")) input.setAttribute("inputmode", "numeric");
@@ -3492,14 +3615,27 @@
3492
3615
  input.setAttribute("autocorrect", "off");
3493
3616
  input.setAttribute("spellcheck", "off");
3494
3617
  input.setAttribute("data-slot", "input-number-control");
3495
- input.classList.add("rounded-l-control", "size-full", "px-3", "py-1", "outline-none");
3618
+ input.classList.add("size-full", "px-3", "py-1", "outline-none");
3496
3619
  const stepDown = document.createElement("button");
3497
3620
  stepDown.setAttribute("type", "button");
3498
3621
  stepDown.setAttribute("tabIndex", "-1");
3499
3622
  stepDown.setAttribute("aria-label", "Decrease");
3500
3623
  stepDown.setAttribute("aria-controls", input.getAttribute("id"));
3501
3624
  stepDown.setAttribute("data-slot", "step-up-trigger");
3625
+ stepDown.appendChild(
3626
+ createSvg({
3627
+ icon: Minus,
3628
+ classes: "opacity-70 fill-foreground size-4 shrink-0 pointer-events-none",
3629
+ attrs: {
3630
+ "aria-hidden": true,
3631
+ role: "presentation"
3632
+ }
3633
+ })
3634
+ );
3502
3635
  stepDown.classList.add(
3636
+ "inline-flex",
3637
+ "items-center",
3638
+ "justify-center",
3503
3639
  "cursor-pointer",
3504
3640
  "border-l",
3505
3641
  "border-input",
@@ -3512,15 +3648,7 @@
3512
3648
  "active:bg-secondary-active",
3513
3649
  "outline-none",
3514
3650
  "relative",
3515
- "before:block",
3516
- "before:opacity-70",
3517
- "before:rounded-full",
3518
- "before:h-0.5",
3519
- "before:min-h-px",
3520
- "before:w-3",
3521
- "before:mx-auto",
3522
- "before:bg-foreground",
3523
- "before:hover:bg-secondary-foreground"
3651
+ "[&:hover>svg]:text-secondary-foreground"
3524
3652
  );
3525
3653
  el.appendChild(stepDown);
3526
3654
  const onStepDown = () => {
@@ -3535,13 +3663,25 @@
3535
3663
  stepUp.setAttribute("aria-label", "Increase");
3536
3664
  stepUp.setAttribute("aria-controls", input.getAttribute("id"));
3537
3665
  stepUp.setAttribute("data-slot", "step-up-trigger");
3666
+ stepUp.appendChild(
3667
+ createSvg({
3668
+ icon: Plus,
3669
+ classes: "opacity-70 fill-foreground size-4 shrink-0 pointer-events-none",
3670
+ attrs: {
3671
+ "aria-hidden": true,
3672
+ role: "presentation"
3673
+ }
3674
+ })
3675
+ );
3538
3676
  stepUp.classList.add(
3677
+ "inline-flex",
3678
+ "items-center",
3679
+ "justify-center",
3539
3680
  "cursor-pointer",
3540
3681
  "border-l",
3541
3682
  "border-input",
3542
3683
  "[input[aria-invalid=true]~&]:border-negative",
3543
3684
  "[input:invalid~&]:border-negative",
3544
- "rounded-r-control",
3545
3685
  "h-full",
3546
3686
  "aspect-square",
3547
3687
  "bg-transparent",
@@ -3549,32 +3689,7 @@
3549
3689
  "active:bg-secondary-active",
3550
3690
  "outline-none",
3551
3691
  "relative",
3552
- "before:block",
3553
- "before:opacity-70",
3554
- "before:absolute",
3555
- "before:rounded-full",
3556
- "before:h-0.5",
3557
- "before:min-h-px",
3558
- "before:w-3",
3559
- "before:top-1/2",
3560
- "before:left-1/2",
3561
- "before:-translate-x-1/2",
3562
- "before:-translate-y-1/2",
3563
- "before:bg-foreground",
3564
- "before:hover:bg-secondary-foreground",
3565
- "after:block",
3566
- "after:opacity-70",
3567
- "after:absolute",
3568
- "after:rounded-full",
3569
- "after:h-3",
3570
- "after:min-w-px",
3571
- "after:w-0.5",
3572
- "after:top-1/2",
3573
- "after:left-1/2",
3574
- "after:-translate-x-1/2",
3575
- "after:-translate-y-1/2",
3576
- "after:bg-foreground",
3577
- "after:hover:bg-secondary-foreground"
3692
+ "[&:hover>svg]:text-secondary-foreground"
3578
3693
  );
3579
3694
  el.appendChild(stepUp);
3580
3695
  const onStepUp = () => {
@@ -3731,13 +3846,13 @@
3731
3846
  el.setAttribute("data-slot", "list");
3732
3847
  el.setAttribute("role", "group");
3733
3848
  });
3734
- Alpine.directive("h-list-header", (el, { original }, { Alpine: Alpine2 }) => {
3849
+ Alpine.directive("h-list-header", (el, { original: original2 }, { Alpine: Alpine2 }) => {
3735
3850
  el.classList.add("font-medium", "flex", "items-center", "p-2", "gap-2", "align-middle", "bg-table-header", "text-table-header-foreground");
3736
3851
  el.setAttribute("role", "presentation");
3737
3852
  el.setAttribute("data-slot", "list-header");
3738
3853
  const list = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "list");
3739
3854
  if (!list) {
3740
- throw new Error(`${original} must be placed inside a list element`);
3855
+ throw new Error(`${original2} must be placed inside a list element`);
3741
3856
  }
3742
3857
  if (!el.hasAttribute("id")) {
3743
3858
  const id = `lbh${v4_default()}`;
@@ -3782,17 +3897,24 @@
3782
3897
  function menu_default(Alpine) {
3783
3898
  Alpine.directive("h-menu-trigger", (el, { modifiers }) => {
3784
3899
  el._menu_trigger = {
3785
- isDropdown: modifiers.includes("dropdown")
3900
+ isDropdown: modifiers.includes("dropdown"),
3901
+ setOpen(open) {
3902
+ el.setAttribute("data-state", open ? "open" : "closed");
3903
+ }
3786
3904
  };
3905
+ el.setAttribute("data-state", "closed");
3787
3906
  });
3788
- Alpine.directive("h-menu", (el, { original, modifiers }, { cleanup, Alpine: Alpine2 }) => {
3907
+ Alpine.directive("h-menu", (el, { original: original2, modifiers }, { cleanup, Alpine: Alpine2 }) => {
3908
+ if (el.tagName !== "UL") {
3909
+ throw new Error(`${original2} must be an ul element`);
3910
+ }
3789
3911
  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");
3790
3912
  el.setAttribute("role", "menu");
3791
3913
  el.setAttribute("aria-orientation", "vertical");
3792
3914
  el.setAttribute("tabindex", "-1");
3793
3915
  el.setAttribute("data-slot", "menu");
3794
3916
  if (!el.hasAttribute("aria-labelledby") && !el.hasAttribute("aria-label")) {
3795
- throw new Error(`${original} must have an "aria-label" or "aria-labelledby" attribute`);
3917
+ throw new Error(`${original2} must have an "aria-label" or "aria-labelledby" attribute`);
3796
3918
  }
3797
3919
  const isSubmenu = modifiers.includes("sub");
3798
3920
  const menuTrigger = (() => {
@@ -3804,7 +3926,7 @@
3804
3926
  return sibling;
3805
3927
  })();
3806
3928
  if (!isSubmenu && !menuTrigger) {
3807
- throw new Error(`${original} menu must be placed after a menu trigger element`);
3929
+ throw new Error(`${original2} menu must be placed after a menu trigger element`);
3808
3930
  }
3809
3931
  let menuSubItem;
3810
3932
  if (isSubmenu) menuSubItem = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "menu-sub");
@@ -3834,6 +3956,9 @@
3834
3956
  } else {
3835
3957
  listenForTrigger(true);
3836
3958
  if (focusTrigger) menuTrigger.focus();
3959
+ if (menuTrigger._menu_trigger.isDropdown) {
3960
+ menuTrigger._menu_trigger.setOpen(false);
3961
+ }
3837
3962
  }
3838
3963
  }
3839
3964
  el._menu = { close };
@@ -3984,6 +4109,9 @@
3984
4109
  }
3985
4110
  }
3986
4111
  function openDropdown() {
4112
+ if (menuTrigger._menu_trigger.isDropdown) {
4113
+ menuTrigger._menu_trigger.setOpen(true);
4114
+ }
3987
4115
  open(menuTrigger);
3988
4116
  }
3989
4117
  function onContextmenu(event) {
@@ -4017,7 +4145,10 @@
4017
4145
  el.removeEventListener("keydown", onKeyDown);
4018
4146
  });
4019
4147
  });
4020
- Alpine.directive("h-menu-item", (el, _, { cleanup, Alpine: Alpine2 }) => {
4148
+ Alpine.directive("h-menu-item", (el, { original: original2 }, { cleanup, Alpine: Alpine2 }) => {
4149
+ if (el.tagName !== "LI") {
4150
+ throw new Error(`${original2} must be a li element`);
4151
+ }
4021
4152
  el.classList.add(
4022
4153
  "focus:bg-secondary-hover",
4023
4154
  "focus:text-secondary-foreground",
@@ -4070,7 +4201,7 @@
4070
4201
  el.removeEventListener("mouseleave", focusOut);
4071
4202
  });
4072
4203
  });
4073
- Alpine.directive("h-menu-sub", (el, { original }, { cleanup, Alpine: Alpine2 }) => {
4204
+ Alpine.directive("h-menu-sub", (el, { original: original2 }, { cleanup, Alpine: Alpine2 }) => {
4074
4205
  el.classList.add(
4075
4206
  "focus:bg-secondary-hover",
4076
4207
  "hover:bg-secondary-hover",
@@ -4102,7 +4233,7 @@
4102
4233
  const chevronRight = createSvg({ icon: ChevronRight, classes: "size-4 ml-auto", attrs: { "aria-hidden": true, role: "presentation" } });
4103
4234
  el.appendChild(chevronRight);
4104
4235
  const parentMenu = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("role") === "menu");
4105
- if (!parentMenu) throw new Error(`${original} must have a parent`);
4236
+ if (!parentMenu) throw new Error(`${original2} must have a parent`);
4106
4237
  el._menu_sub = {
4107
4238
  open: void 0,
4108
4239
  close: void 0,
@@ -4196,7 +4327,10 @@
4196
4327
  el.classList.add("text-foreground", "px-2", "py-1.5", "text-sm", "font-semibold", "text-left", "data-[inset=true]:pl-8");
4197
4328
  el.setAttribute("data-slot", "menu-label");
4198
4329
  });
4199
- Alpine.directive("h-menu-checkbox-item", (el, _, { cleanup, Alpine: Alpine2 }) => {
4330
+ Alpine.directive("h-menu-checkbox-item", (el, { original: original2 }, { cleanup, Alpine: Alpine2 }) => {
4331
+ if (el.tagName !== "LI" && el.tagName !== "DIV") {
4332
+ throw new Error(`${original2} must be a li or div element`);
4333
+ }
4200
4334
  el.classList.add(
4201
4335
  "focus:bg-secondary-hover",
4202
4336
  "hover:bg-secondary-hover",
@@ -4261,7 +4395,10 @@
4261
4395
  el.removeEventListener("mouseleave", focusOut);
4262
4396
  });
4263
4397
  });
4264
- Alpine.directive("h-menu-radio-item", (el, { expression }, { effect, evaluateLater, cleanup, Alpine: Alpine2 }) => {
4398
+ Alpine.directive("h-menu-radio-item", (el, { original: original2, expression }, { effect, evaluateLater, cleanup, Alpine: Alpine2 }) => {
4399
+ if (el.tagName !== "LI" && el.tagName !== "DIV") {
4400
+ throw new Error(`${original2} must be a li or div element`);
4401
+ }
4265
4402
  el.classList.add(
4266
4403
  "focus:bg-secondary-hover",
4267
4404
  "hover:bg-secondary-hover",
@@ -4488,7 +4625,7 @@
4488
4625
  });
4489
4626
  }
4490
4627
  });
4491
- Alpine.directive("h-popover", (el, { original, modifiers }, { effect }) => {
4628
+ Alpine.directive("h-popover", (el, { original: original2, modifiers }, { effect }) => {
4492
4629
  const popover = (() => {
4493
4630
  let sibling = el.previousElementSibling;
4494
4631
  while (sibling && !sibling.hasOwnProperty("_popover")) {
@@ -4497,7 +4634,7 @@
4497
4634
  return sibling;
4498
4635
  })();
4499
4636
  if (!popover) {
4500
- throw new Error(`${original} must be placed after a popover element`);
4637
+ throw new Error(`${original2} must be placed after a popover element`);
4501
4638
  }
4502
4639
  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");
4503
4640
  el.setAttribute("data-slot", "popover");
@@ -6509,7 +6646,7 @@
6509
6646
  none: 3
6510
6647
  });
6511
6648
  function select_default(Alpine) {
6512
- Alpine.directive("h-select", (el, _, { Alpine: Alpine2, cleanup }) => {
6649
+ Alpine.directive("h-select", (el, { modifiers }, { Alpine: Alpine2, cleanup }) => {
6513
6650
  el._h_select = Alpine2.reactive({
6514
6651
  id: void 0,
6515
6652
  controls: `hsc${v4_default()}`,
@@ -6526,46 +6663,45 @@
6526
6663
  set: void 0,
6527
6664
  get: void 0
6528
6665
  };
6529
- el.classList.add(
6530
- "cursor-pointer",
6531
- "border-input",
6532
- "has-focus-visible:border-ring",
6533
- "has-focus-visible:ring-[calc(var(--spacing)*0.75)]",
6534
- "has-focus-visible:ring-ring/50",
6535
- "dark:has-[aria-invalid=true]:ring-negative/40",
6536
- "dark:has-[input:invalid]:ring-negative/40",
6537
- "has-[aria-invalid=true]:border-negative",
6538
- "has-[aria-invalid=true]:ring-negative/20",
6539
- "has-[input:invalid]:border-negative",
6540
- "has-[input:invalid]:ring-negative/20",
6541
- "hover:bg-secondary-hover",
6542
- "active:bg-secondary-active",
6543
- "w-full",
6544
- "rounded-control",
6545
- "border",
6546
- "bg-input-inner",
6547
- "text-sm",
6548
- "whitespace-nowrap",
6549
- "shadow-input",
6550
- "transition-[color,box-shadow]",
6551
- "duration-200",
6552
- "outline-none",
6553
- "has-[input:disabled]:pointer-events-none",
6554
- "has-[input:disabled]:opacity-50"
6555
- );
6556
- el.setAttribute("data-slot", "select");
6557
- const observer = sizeObserver(el);
6558
- cleanup(() => {
6559
- observer.disconnect();
6560
- });
6666
+ el.classList.add("cursor-pointer", "outline-none", "transition-[color,box-shadow]", "duration-200", "w-full", "has-[input:disabled]:pointer-events-none", "has-[input:disabled]:opacity-50");
6667
+ if (modifiers.includes("table")) {
6668
+ el.classList.add("h-10", "flex", "focus-visible:inset-ring-ring/50", "focus-visible:inset-ring-2", "hover:bg-table-hover", "hover:text-table-hover-foreground", "active:!bg-table-active", "active:!text-table-active-foreground");
6669
+ el.setAttribute("data-slot", "cell-input-select");
6670
+ } else {
6671
+ el.classList.add(
6672
+ "border-input",
6673
+ "has-focus-visible:border-ring",
6674
+ "has-focus-visible:ring-[calc(var(--spacing)*0.75)]",
6675
+ "has-focus-visible:ring-ring/50",
6676
+ "dark:has-[aria-invalid=true]:ring-negative/40",
6677
+ "dark:has-[input:invalid]:ring-negative/40",
6678
+ "has-[aria-invalid=true]:border-negative",
6679
+ "has-[aria-invalid=true]:ring-negative/20",
6680
+ "has-[input:invalid]:border-negative",
6681
+ "has-[input:invalid]:ring-negative/20",
6682
+ "hover:bg-secondary-hover",
6683
+ "active:bg-secondary-active",
6684
+ "rounded-control",
6685
+ "border",
6686
+ "bg-input-inner",
6687
+ "text-sm",
6688
+ "whitespace-nowrap",
6689
+ "shadow-input"
6690
+ );
6691
+ el.setAttribute("data-slot", "select");
6692
+ const observer = sizeObserver(el);
6693
+ cleanup(() => {
6694
+ observer.disconnect();
6695
+ });
6696
+ }
6561
6697
  });
6562
- Alpine.directive("h-select-input", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
6698
+ Alpine.directive("h-select-input", (el, { original: original2 }, { effect, cleanup, Alpine: Alpine2 }) => {
6563
6699
  if (el.tagName !== "INPUT") {
6564
- throw new Error(`${original} must be a readonly input of type "text"`);
6700
+ throw new Error(`${original2} must be a readonly input of type "text"`);
6565
6701
  }
6566
6702
  const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6567
6703
  if (!select) {
6568
- throw new Error(`${original} must be inside a select element`);
6704
+ throw new Error(`${original2} must be inside a select element`);
6569
6705
  } else if (el.hasOwnProperty("_x_model")) {
6570
6706
  select._h_select.multiple = Array.isArray(el._x_model.get());
6571
6707
  select._h_model.set = (value) => {
@@ -6818,10 +6954,10 @@
6818
6954
  observer.disconnect();
6819
6955
  });
6820
6956
  });
6821
- Alpine.directive("h-select-content", (el, { original }, { effect, Alpine: Alpine2 }) => {
6957
+ Alpine.directive("h-select-content", (el, { original: original2 }, { effect, Alpine: Alpine2 }) => {
6822
6958
  const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6823
6959
  if (!select) {
6824
- throw new Error(`${original} must be inside a select element`);
6960
+ throw new Error(`${original2} must be inside a select element`);
6825
6961
  }
6826
6962
  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");
6827
6963
  el.setAttribute("data-slot", "select-content");
@@ -6832,7 +6968,7 @@
6832
6968
  el.setAttribute("data-state", select._h_select.expanded ? "open" : "closed");
6833
6969
  const control = select.querySelector(`#${select._h_select.id}`);
6834
6970
  if (!control) {
6835
- throw new Error(`${original}: trigger not found`);
6971
+ throw new Error(`${original2}: trigger not found`);
6836
6972
  }
6837
6973
  let autoUpdateCleanup;
6838
6974
  function updatePosition() {
@@ -6874,10 +7010,10 @@
6874
7010
  }
6875
7011
  });
6876
7012
  });
6877
- Alpine.directive("h-select-search", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
7013
+ Alpine.directive("h-select-search", (el, { original: original2 }, { effect, cleanup, Alpine: Alpine2 }) => {
6878
7014
  const select = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6879
7015
  if (!select) {
6880
- throw new Error(`${original} must be inside an h-select element`);
7016
+ throw new Error(`${original2} must be inside an h-select element`);
6881
7017
  } else {
6882
7018
  select._h_select.filterType = FilterType[el.getAttribute("data-filter")] ?? FilterType["starts-with"];
6883
7019
  }
@@ -6949,10 +7085,10 @@
6949
7085
  selectGroup._h_selectGroup.labelledby = id;
6950
7086
  }
6951
7087
  });
6952
- Alpine.directive("h-select-option", (el, { original, expression }, { effect, evaluateLater, cleanup }) => {
7088
+ Alpine.directive("h-select-option", (el, { original: original2, expression }, { effect, evaluateLater, cleanup }) => {
6953
7089
  const select = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_select"));
6954
7090
  if (!select) {
6955
- throw new Error(`${original} must be inside an h-select element`);
7091
+ throw new Error(`${original2} must be inside an h-select element`);
6956
7092
  }
6957
7093
  el.classList.add(
6958
7094
  "focus:bg-primary",
@@ -7237,6 +7373,11 @@
7237
7373
  "md:after:hidden",
7238
7374
  "group-data-[collapsed=true]/sidebar:hidden"
7239
7375
  );
7376
+ if (el.tagName !== "BUTTON") {
7377
+ el.setAttribute("role", "button");
7378
+ } else {
7379
+ el.setAttribute("type", "button");
7380
+ }
7240
7381
  el.setAttribute("data-slot", "sidebar-group-action");
7241
7382
  });
7242
7383
  Alpine.directive("h-sidebar-group-content", (el) => {
@@ -7247,11 +7388,18 @@
7247
7388
  el.classList.add("vbox", "w-full", "min-w-0", "gap-1");
7248
7389
  el.setAttribute("data-slot", "sidebar-menu");
7249
7390
  });
7250
- Alpine.directive("h-sidebar-menu-item", (el) => {
7391
+ Alpine.directive("h-sidebar-menu-item", (el, { original: original2 }) => {
7392
+ if (el.tagName !== "BUTTON") {
7393
+ throw new Error(`${original2} must be a button`);
7394
+ }
7251
7395
  el.classList.add("group/menu-item", "relative");
7396
+ el.setAttribute("type", "button");
7252
7397
  el.setAttribute("data-slot", "sidebar-menu-item");
7253
7398
  });
7254
7399
  Alpine.directive("h-sidebar-menu-button", (el) => {
7400
+ if (el.tagName !== "BUTTON") {
7401
+ throw new Error(`${original} must be a button`);
7402
+ }
7255
7403
  el.classList.add(
7256
7404
  "peer/menu-button",
7257
7405
  "flex",
@@ -7291,6 +7439,7 @@
7291
7439
  "[&>svg]:shrink-0",
7292
7440
  "[&>svg:not(:first-child):last-child]:ml-auto"
7293
7441
  );
7442
+ el.setAttribute("type", "button");
7294
7443
  if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "sidebar-menu-button");
7295
7444
  const sizes = {
7296
7445
  default: ["h-8", "text-sm"],
@@ -7338,6 +7487,11 @@
7338
7487
  if (modifiers.includes("autohide")) {
7339
7488
  el.classList.add("peer-data-[active=true]/menu-button:text-sidebar-secondary-foreground", "group-focus-within/menu-item:opacity-100", "group-hover/menu-item:opacity-100", "data-[state=open]:opacity-100", "md:opacity-0");
7340
7489
  }
7490
+ if (el.tagName !== "BUTTON") {
7491
+ el.setAttribute("role", "button");
7492
+ } else {
7493
+ el.setAttribute("type", "button");
7494
+ }
7341
7495
  el.setAttribute("data-slot", "sidebar-menu-action");
7342
7496
  });
7343
7497
  Alpine.directive("h-sidebar-menu-badge", (el) => {
@@ -7385,7 +7539,7 @@
7385
7539
  el.setAttribute("role", "none");
7386
7540
  });
7387
7541
  Alpine.directive("h-sidebar-menu-sub", (el, { modifiers }) => {
7388
- el.classList.add("vbox", "min-w-0", "translate-x-px", "gap-1", "py-0.5", "group-data-[collapsed=true]/sidebar:hidden");
7542
+ el.classList.add("vbox", "min-w-0", "translate-x-px", "gap-1", "py-0.5", "group-data-[collapsed=true]/sidebar:!hidden");
7389
7543
  if (!modifiers.includes("flat")) {
7390
7544
  el.classList.add("border-sidebar-border", "mx-3.5", "border-l", "px-2.5");
7391
7545
  }
@@ -7396,6 +7550,9 @@
7396
7550
  el.setAttribute("data-slot", "sidebar-menu-sub-item");
7397
7551
  });
7398
7552
  Alpine.directive("h-sidebar-menu-sub-button", (el) => {
7553
+ if (el.tagName !== "BUTTON") {
7554
+ throw new Error(`${original} must be a button`);
7555
+ }
7399
7556
  el.classList.add(
7400
7557
  "text-sidebar-foreground",
7401
7558
  "ring-sidebar-ring",
@@ -7430,6 +7587,7 @@
7430
7587
  "data-[active=true]:text-sidebar-primary-foreground",
7431
7588
  "group-data-[collapsed=true]/sidebar:hidden"
7432
7589
  );
7590
+ el.setAttribute("type", "button");
7433
7591
  el.setAttribute("data-slot", "sidebar-menu-sub-button");
7434
7592
  const sizes = {
7435
7593
  sm: ["text-xs"],
@@ -7501,18 +7659,212 @@
7501
7659
 
7502
7660
  // src/components/split.js
7503
7661
  function split_default(Alpine) {
7504
- Alpine.directive("h-split", (el) => {
7505
- el.classList.add("flex", "data-[orientation=horizontal]:flex-row", "data-[orientation=vertical]:flex-col");
7506
- el.setAttribute("tabindex", "-1");
7507
- el.setAttribute("data-slot", "split");
7662
+ Alpine.directive("h-split", (el, {}, { cleanup, Alpine: Alpine2 }) => {
7663
+ const panels = [];
7664
+ const state = Alpine2.reactive({
7665
+ isHorizontal: el.getAttribute("data-orientation") === "horizontal",
7666
+ isBorder: el.getAttribute("data-variant") === "border"
7667
+ });
7668
+ const storageKey = el.getAttribute("data-key");
7669
+ const loadSizes = () => {
7670
+ if (!storageKey) return null;
7671
+ try {
7672
+ const raw = localStorage.getItem(storageKey);
7673
+ if (!raw) return null;
7674
+ return JSON.parse(raw);
7675
+ } catch {
7676
+ return null;
7677
+ }
7678
+ };
7679
+ let saveTimer = null;
7680
+ const SAVE_DELAY = 200;
7681
+ const saveSizes = () => {
7682
+ if (!storageKey) return;
7683
+ if (saveTimer) clearTimeout(saveTimer);
7684
+ saveTimer = setTimeout(() => {
7685
+ const visible = panels.filter((p) => !p.hidden);
7686
+ const sizes = visible.map((p) => p.size / usableSize());
7687
+ localStorage.setItem(storageKey, JSON.stringify(sizes));
7688
+ saveTimer = null;
7689
+ }, SAVE_DELAY);
7690
+ };
7691
+ const sizeProp = () => state.isHorizontal ? "width" : "height";
7692
+ const containerSize = () => state.isHorizontal ? el.getBoundingClientRect().width : el.getBoundingClientRect().height;
7693
+ const gutterSize = () => {
7694
+ const panel = panels.find((p) => p.gutter.parentElement);
7695
+ if (panel) {
7696
+ return panel.gutter.getBoundingClientRect()[sizeProp()] ?? 0;
7697
+ }
7698
+ return 0;
7699
+ };
7700
+ const usableSize = () => {
7701
+ const visiblePanels = panels.filter((p) => !p.hidden);
7702
+ const gutters = Math.max(0, visiblePanels.length - 1);
7703
+ return containerSize() - gutters * gutterSize();
7704
+ };
7705
+ const normalize = (value) => {
7706
+ if (value == null) return null;
7707
+ if (typeof value === "number") return value;
7708
+ if (value.endsWith("%")) {
7709
+ return parseFloat(value) / 100 * usableSize();
7710
+ }
7711
+ return parseFloat(value);
7712
+ };
7713
+ let initialized = false;
7714
+ const DELTA_ABS = 0.01;
7715
+ const layout = () => {
7716
+ const visible = panels.filter((p) => !p.hidden);
7717
+ if (!visible.length) return;
7718
+ const total = usableSize();
7719
+ if (!initialized) {
7720
+ initialized = true;
7721
+ const visible2 = panels.filter((p) => !p.hidden);
7722
+ const stored = loadSizes();
7723
+ if (stored && stored.length === visible2.length) {
7724
+ visible2.forEach((p, i) => {
7725
+ p.size = stored[i] * usableSize();
7726
+ p.explicit = true;
7727
+ });
7728
+ } else {
7729
+ const explicitTotal = visible2.filter((p) => p.explicit).reduce((sum, p) => sum + p.declaredSize, 0);
7730
+ const autoPanels = visible2.filter((p) => !p.explicit);
7731
+ const remaining = total - explicitTotal;
7732
+ const share = autoPanels.length ? remaining / autoPanels.length : 0;
7733
+ visible2.forEach((p) => {
7734
+ if (p.explicit) {
7735
+ p.size = p.declaredSize;
7736
+ } else {
7737
+ p.size = share;
7738
+ }
7739
+ p.size = Math.min(Math.max(p.size ?? share, p.min), p.max);
7740
+ });
7741
+ }
7742
+ }
7743
+ visible.forEach((p) => {
7744
+ if (p.size == null) {
7745
+ p.size = p.min ?? 0;
7746
+ }
7747
+ p.size = Math.min(Math.max(p.size, p.min), p.max);
7748
+ });
7749
+ let currentTotal = visible.reduce((sum, p) => sum + p.size, 0);
7750
+ let delta = total - currentTotal;
7751
+ if (Math.abs(delta) < DELTA_ABS) {
7752
+ visible.forEach((p) => p.apply());
7753
+ return;
7754
+ }
7755
+ let flexible = visible.filter((p) => {
7756
+ if (p.collapsed) return false;
7757
+ if (delta > 0) {
7758
+ return p.size < p.max;
7759
+ } else {
7760
+ return p.size > p.min;
7761
+ }
7762
+ });
7763
+ while (flexible.length && Math.abs(delta) > DELTA_ABS) {
7764
+ const share = delta / flexible.length;
7765
+ let consumed = 0;
7766
+ const nextFlexible = [];
7767
+ flexible.forEach((p) => {
7768
+ const proposed = p.size + share;
7769
+ const clamped = Math.min(Math.max(proposed, p.min), p.max);
7770
+ const actualChange = clamped - p.size;
7771
+ if (Math.abs(actualChange) > DELTA_ABS) {
7772
+ p.size = clamped;
7773
+ consumed += actualChange;
7774
+ }
7775
+ if (delta > 0) {
7776
+ if (p.size < p.max) nextFlexible.push(p);
7777
+ } else {
7778
+ if (p.size > p.min) nextFlexible.push(p);
7779
+ }
7780
+ });
7781
+ delta -= consumed;
7782
+ flexible = nextFlexible;
7783
+ if (Math.abs(consumed) < DELTA_ABS) break;
7784
+ }
7785
+ visible.forEach((p) => p.apply());
7786
+ };
7787
+ let layoutFrame = null;
7788
+ const queueLayout = () => {
7789
+ if (layoutFrame) cancelAnimationFrame(layoutFrame);
7790
+ layoutFrame = requestAnimationFrame(() => {
7791
+ layout();
7792
+ saveSizes();
7793
+ layoutFrame = null;
7794
+ });
7795
+ };
7796
+ const refreshGutters = () => {
7797
+ panels.forEach((p, i) => p.setGutter(i === panels.length - 1));
7798
+ };
7799
+ el._h_split = {
7800
+ state,
7801
+ panels,
7802
+ addPanel(panel) {
7803
+ panels.push(panel);
7804
+ if (panel.size == null) {
7805
+ panel.size = null;
7806
+ }
7807
+ initialized = false;
7808
+ refreshGutters();
7809
+ queueLayout();
7810
+ },
7811
+ removePanel(panel) {
7812
+ const i = panels.indexOf(panel);
7813
+ if (i !== -1) panels.splice(i, 1);
7814
+ initialized = false;
7815
+ refreshGutters();
7816
+ queueLayout();
7817
+ },
7818
+ panelHidden() {
7819
+ initialized = false;
7820
+ refreshGutters();
7821
+ queueLayout();
7822
+ },
7823
+ panelChange() {
7824
+ queueLayout();
7825
+ },
7826
+ normalize,
7827
+ saveSizes
7828
+ };
7829
+ el.classList.add("flex", "flex-1", "min-w-0", "min-h-0", "data-[orientation=horizontal]:flex-row", "data-[orientation=vertical]:flex-col");
7830
+ const observer = new MutationObserver((mutations) => {
7831
+ mutations.forEach((mutation) => {
7832
+ if (mutation.attributeName === "data-orientation") {
7833
+ state.isHorizontal = el.getAttribute("data-orientation") === "horizontal";
7834
+ queueLayout();
7835
+ } else if (mutation.attributeName === "data-variant") {
7836
+ state.isBorder = el.getAttribute("data-variant") === "border";
7837
+ queueLayout();
7838
+ } else {
7839
+ panels.forEach((p) => p.setLocked(el.getAttribute("data-locked") === "true"));
7840
+ }
7841
+ });
7842
+ });
7843
+ observer.observe(el, { attributes: true, attributeFilter: ["data-orientation", "data-variant", "data-locked"] });
7844
+ const containerObserver = new ResizeObserver(queueLayout);
7845
+ containerObserver.observe(el);
7846
+ cleanup(() => {
7847
+ if (layoutFrame) cancelAnimationFrame(layoutFrame);
7848
+ if (saveTimer) clearTimeout(saveTimer);
7849
+ containerObserver.disconnect();
7850
+ observer.disconnect();
7851
+ });
7508
7852
  });
7509
- Alpine.directive("h-split-panel", (el) => {
7510
- el.classList.add('[&.hidden+[data-slot="split-gutter"]]:hidden');
7853
+ Alpine.directive("h-split-panel", (el, { original: original2 }, { effect, cleanup, Alpine: Alpine2 }) => {
7854
+ const split = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_split"));
7855
+ if (!split) {
7856
+ throw new Error(`${original2} must be inside an split element`);
7857
+ }
7858
+ el.classList.add("flex", "shrink", "grow-0", "box-border", "min-w-0", "min-h-0", "overflow-visible");
7511
7859
  el.setAttribute("tabindex", "-1");
7512
7860
  el.setAttribute("data-slot", "split-panel");
7513
- });
7514
- Alpine.directive("h-split-gutter", (el, _, { cleanup }) => {
7515
- el.classList.add(
7861
+ const gutter = document.createElement("span");
7862
+ gutter.setAttribute("data-slot", "split-gutter");
7863
+ gutter.setAttribute("aria-disabled", el.getAttribute("data-locked") === "true");
7864
+ gutter.setAttribute("tabindex", "-1");
7865
+ gutter.setAttribute("role", "separator");
7866
+ gutter.classList.add(
7867
+ "overflow-visible",
7516
7868
  "relative",
7517
7869
  "shrink-0",
7518
7870
  "touch-none",
@@ -7520,15 +7872,8 @@
7520
7872
  "outline-none",
7521
7873
  "hover:bg-primary-hover",
7522
7874
  "active:bg-primary-active",
7523
- "before:absolute",
7524
- "before:top-1/2",
7525
- "before:left-1/2",
7526
- "before:-translate-x-1/2",
7527
- "before:-translate-y-1/2",
7528
- "before:block",
7529
- "before:bg-transparent",
7530
7875
  "hover:before:bg-primary-hover",
7531
- "[[data-locked=true]>&]:pointer-events-none",
7876
+ "aria-disabled:pointer-events-none",
7532
7877
  "[[data-orientation=horizontal]>&]:cursor-col-resize",
7533
7878
  "[[data-orientation=vertical]>&]:cursor-row-resize"
7534
7879
  );
@@ -7538,19 +7883,23 @@
7538
7883
  "hover:bg-primary-hover",
7539
7884
  "active:bg-primary-active",
7540
7885
  "before:absolute",
7541
- "before:top-1/2",
7542
- "before:left-1/2",
7543
- "before:-translate-x-1/2",
7544
- "before:-translate-y-1/2",
7545
7886
  "before:block",
7546
7887
  "before:bg-transparent",
7547
7888
  "hover:before:bg-primary-hover",
7889
+ "[[data-orientation=horizontal]>&]:before:-translate-x-1/2",
7890
+ "[[data-orientation=horizontal]>&[data-edge=end]]:before:-translate-x-1",
7891
+ "[[data-orientation=horizontal]>&[data-edge=start]]:before:translate-x-0",
7892
+ "[[data-orientation=horizontal]>&]:before:left-1/2",
7548
7893
  "[[data-orientation=horizontal]>&]:!w-px",
7549
7894
  "[[data-orientation=horizontal]>&]:before:h-full",
7550
- "[[data-orientation=horizontal]>&]:before:w-[calc(var(--spacing)*1.25)]",
7895
+ "[[data-orientation=horizontal]>&]:before:w-[calc(var(--spacing)*1)]",
7896
+ "[[data-orientation=vertical]>&]:before:-translate-y-1/2",
7897
+ "[[data-orientation=vertical]>&[data-edge=end]]:before:-translate-y-1",
7898
+ "[[data-orientation=vertical]>&[data-edge=start]]:before:translate-y-0",
7899
+ "[[data-orientation=vertical]>&]:before:top-1/2",
7551
7900
  "[[data-orientation=vertical]>&]:!h-px",
7552
7901
  "[[data-orientation=vertical]>&]:before:w-full",
7553
- "[[data-orientation=vertical]>&]:before:h-[calc(var(--spacing)*1.25)]"
7902
+ "[[data-orientation=vertical]>&]:before:h-[calc(var(--spacing)*1)]"
7554
7903
  ];
7555
7904
  const handleClasses = [
7556
7905
  "bg-transparent",
@@ -7599,24 +7948,175 @@
7599
7948
  "[[data-orientation=vertical]>&]:after:w-5",
7600
7949
  "[[data-orientation=vertical]>&]:after:h-2.5"
7601
7950
  ];
7602
- el.setAttribute("data-slot", "split-gutter");
7603
- el.setAttribute("tabindex", "-1");
7604
- el.setAttribute("role", "separator");
7605
- function setVariant(variant = "handle") {
7606
- if (variant === "border") {
7607
- el.classList.remove(...handleClasses);
7608
- el.classList.add(...borderClasses);
7951
+ const setVariant = () => {
7952
+ if (split._h_split.state.isBorder) {
7953
+ gutter.classList.remove(...handleClasses);
7954
+ gutter.classList.add(...borderClasses);
7609
7955
  } else {
7610
- el.classList.remove(...borderClasses);
7611
- el.classList.add(...handleClasses);
7956
+ gutter.classList.remove(...borderClasses);
7957
+ gutter.classList.add(...handleClasses);
7612
7958
  }
7613
- }
7614
- const observer = new MutationObserver(() => {
7615
- setVariant(el.parentElement.getAttribute("data-variant"));
7959
+ };
7960
+ setVariant();
7961
+ effect(setVariant);
7962
+ const initialSize = split._h_split.normalize(el.getAttribute("data-size"));
7963
+ let handleSize = 0;
7964
+ const panel = {
7965
+ el,
7966
+ gutter,
7967
+ hidden: el.getAttribute("data-hidden") === "true",
7968
+ declaredSize: initialSize,
7969
+ size: initialSize,
7970
+ explicit: initialSize != null,
7971
+ min: split._h_split.normalize(el.getAttribute("data-min")) ?? 0,
7972
+ max: split._h_split.normalize(el.getAttribute("data-max")) ?? Infinity,
7973
+ collapsed: false,
7974
+ prevSize: null,
7975
+ apply() {
7976
+ el.style.flexBasis = `${this.size.toFixed(2)}px`;
7977
+ if (split._h_split.state.isBorder) {
7978
+ this.setHandleOffset();
7979
+ }
7980
+ },
7981
+ setGutter(last) {
7982
+ if (this.hidden || last) {
7983
+ gutter.remove();
7984
+ } else if (!gutter.parentElement) {
7985
+ el.after(gutter);
7986
+ handleSize = this.getHandleSize();
7987
+ }
7988
+ },
7989
+ setHandleOffset() {
7990
+ const panels = split._h_split.panels.filter((p) => !p.hidden);
7991
+ const index = panels.indexOf(panel);
7992
+ const next = panels[index + 1];
7993
+ if (!next) return;
7994
+ if (next.size < handleSize) {
7995
+ gutter.setAttribute("data-edge", "end");
7996
+ } else if (this.size < handleSize) {
7997
+ gutter.setAttribute("data-edge", "start");
7998
+ } else {
7999
+ gutter.removeAttribute("data-edge");
8000
+ }
8001
+ },
8002
+ getHandleSize() {
8003
+ if (split._h_split.state.isBorder) {
8004
+ const beforeStyle = window.getComputedStyle(gutter, "::before");
8005
+ return Number(beforeStyle[split._h_split.state.isHorizontal ? "width" : "height"].replace("px", "")) / 2;
8006
+ } else {
8007
+ return 0;
8008
+ }
8009
+ },
8010
+ setLocked(locked = false) {
8011
+ const panelLocked = el.getAttribute("data-locked") === "true";
8012
+ if (locked) {
8013
+ gutter.classList.add("pointer-events-none");
8014
+ } else if (panelLocked) {
8015
+ gutter.classList.add("pointer-events-none");
8016
+ } else {
8017
+ gutter.classList.remove("pointer-events-none");
8018
+ }
8019
+ }
8020
+ };
8021
+ split._h_split.addPanel(panel);
8022
+ const drag = (e) => {
8023
+ e.preventDefault();
8024
+ gutter.setPointerCapture(e.pointerId);
8025
+ const panels = split._h_split.panels.filter((p) => !p.hidden);
8026
+ const index = panels.indexOf(panel);
8027
+ const next = panels[index + 1];
8028
+ if (!next) return;
8029
+ const startPos = split._h_split.state.isHorizontal ? e.clientX : e.clientY;
8030
+ const startA = panel.size;
8031
+ const startB = next.size;
8032
+ const minDelta = Math.max(
8033
+ panel.min - startA,
8034
+ // how much panel A can shrink
8035
+ startB - next.max
8036
+ // how much panel B can grow
8037
+ );
8038
+ const maxDelta = Math.min(
8039
+ panel.max - startA,
8040
+ // how much panel A can grow
8041
+ startB - next.min
8042
+ // how much panel B can shrink
8043
+ );
8044
+ const move = (e2) => {
8045
+ const currentPos = split._h_split.state.isHorizontal ? e2.clientX : e2.clientY;
8046
+ const delta = currentPos - startPos;
8047
+ const clamped = Math.min(maxDelta, Math.max(minDelta, delta));
8048
+ panel.size = startA + clamped;
8049
+ next.size = startB - clamped;
8050
+ panel.explicit = false;
8051
+ if (panel.collapsed) {
8052
+ panel.collapsed = false;
8053
+ }
8054
+ if (next.collapsed) {
8055
+ next.collapsed = false;
8056
+ }
8057
+ split._h_split.panelChange();
8058
+ };
8059
+ const up = () => {
8060
+ gutter.releasePointerCapture(e.pointerId);
8061
+ gutter.removeEventListener("pointermove", move);
8062
+ gutter.removeEventListener("pointerup", up);
8063
+ };
8064
+ gutter.addEventListener("pointermove", move);
8065
+ gutter.addEventListener("pointerup", up);
8066
+ };
8067
+ gutter.addEventListener("pointerdown", drag);
8068
+ const collapse = () => {
8069
+ if (panel.collapsed) return;
8070
+ panel.prevSize = panel.size;
8071
+ panel.size = panel.min ?? 0;
8072
+ panel.collapsed = true;
8073
+ panel.explicit = true;
8074
+ split._h_split.panelChange();
8075
+ };
8076
+ const expand = () => {
8077
+ if (!panel.collapsed) return;
8078
+ const target = panel.prevSize ?? panel.min ?? 0;
8079
+ const delta = target - panel.size;
8080
+ const visible = split._h_split.panels.filter((p) => !p.hidden && p !== panel);
8081
+ let remaining = delta;
8082
+ for (const p of visible) {
8083
+ const available = p.size - p.min;
8084
+ const take = Math.min(available, remaining);
8085
+ p.size -= take;
8086
+ remaining -= take;
8087
+ if (remaining <= 0) break;
8088
+ }
8089
+ panel.size = target - remaining;
8090
+ panel.collapsed = false;
8091
+ panel.explicit = true;
8092
+ split._h_split.panelChange();
8093
+ };
8094
+ const observer = new MutationObserver((mutations) => {
8095
+ mutations.forEach((mutation) => {
8096
+ if (mutation.attributeName === "data-hidden") {
8097
+ panel.hidden = el.getAttribute("data-hidden") === "true";
8098
+ if (panel.hidden) {
8099
+ el.classList.add("hidden");
8100
+ } else {
8101
+ el.classList.remove("hidden");
8102
+ }
8103
+ split._h_split.panelHidden();
8104
+ } else if (mutation.attributeName === "data-locked") {
8105
+ panel.setLocked();
8106
+ } else {
8107
+ if (el.getAttribute("data-collapse") === "true") {
8108
+ collapse();
8109
+ } else {
8110
+ expand();
8111
+ }
8112
+ }
8113
+ });
7616
8114
  });
7617
- observer.observe(el.parentElement, { attributes: true, attributeFilter: ["data-variant"] });
7618
- setVariant(el.parentElement.getAttribute("data-variant"));
8115
+ observer.observe(el, { attributes: true, attributeFilter: ["data-hidden", "data-locked", "data-collapse"] });
7619
8116
  cleanup(() => {
8117
+ gutter.remove();
8118
+ gutter.removeEventListener("pointerdown", drag);
8119
+ split._h_split.removePanel(panel);
7620
8120
  observer.disconnect();
7621
8121
  });
7622
8122
  });
@@ -7678,7 +8178,18 @@
7678
8178
  function table_default(Alpine) {
7679
8179
  Alpine.directive("h-table-container", (el, { modifiers }) => {
7680
8180
  if (modifiers.includes("scroll")) {
7681
- el.classList.add("overflow-scroll", "[&_thead]:sticky", "[&_thead]:top-0", "[&_thead]:z-2", "[&_tfoot]:sticky", "[&_tfoot]:bottom-0", "[&_tfoot]:z-2", "[&_tbody_tr_th]:sticky", "[&_tbody_tr_th]:left-0", "[&_tbody_tr_th]:z-1");
8181
+ el.classList.add(
8182
+ "overflow-scroll",
8183
+ "[&_thead[data-slot|=table]]:sticky",
8184
+ "[&_thead[data-slot|=table]]:top-0",
8185
+ "[&_thead[data-slot|=table]]:z-2",
8186
+ "[&_tfoot[data-slot|=table]]:sticky",
8187
+ "[&_tfoot[data-slot|=table]]:bottom-0",
8188
+ "[&_tfoot[data-slot|=table]]:z-2",
8189
+ "[&_tbody_tr_th[data-slot|=table]]:sticky",
8190
+ "[&_tbody_tr_th[data-slot|=table]]:left-0",
8191
+ "[&_tbody_tr_th[data-slot|=table]]:z-1"
8192
+ );
7682
8193
  } else {
7683
8194
  el.classList.add("relative", "w-full", "overflow-x-auto");
7684
8195
  }
@@ -7693,13 +8204,19 @@
7693
8204
  el.setAttribute("data-slot", "table");
7694
8205
  switch (el.getAttribute("data-borders")) {
7695
8206
  case "rows":
7696
- el.classList.add("[&_tr_td]:border-b", "[&_tr_th]:border-b", "first:[&_tfoot_tr_td]:border-t", "first:[&_tfoot_tr_th]:border-t");
8207
+ el.classList.add("[&_tr_td[data-slot|=table]]:border-b", "[&_tr_th[data-slot|=table]]:border-b", "first:[&_tfoot_tr_td[data-slot|=table]]:border-t", "first:[&_tfoot_tr_th[data-slot|=table]]:border-t");
7697
8208
  break;
7698
8209
  case "columns":
7699
- el.classList.add("[&_tr]:divide-x");
8210
+ el.classList.add("[&_tr[data-slot|=table]]:divide-x");
7700
8211
  break;
7701
8212
  case "both":
7702
- el.classList.add("[&_tr_td]:border-b", "[&_tr_th]:border-b", "first:[&_tfoot_tr_td]:border-t", "first:[&_tfoot_tr_th]:border-t", "[&_tr]:divide-x");
8213
+ el.classList.add(
8214
+ "[&_tr_td[data-slot|=table]]:border-b",
8215
+ "[&_tr_th[data-slot|=table]]:border-b",
8216
+ "first:[&_tfoot_tr_td[data-slot|=table]]:border-t",
8217
+ "first:[&_tfoot_tr_th[data-slot|=table]]:border-t",
8218
+ "[&_tr[data-slot|=table]]:divide-x"
8219
+ );
7703
8220
  break;
7704
8221
  }
7705
8222
  });
@@ -7729,6 +8246,7 @@
7729
8246
  Alpine.directive("h-table-cell", (el) => {
7730
8247
  el.classList.add(
7731
8248
  "p-2",
8249
+ "[&:has([data-slot|=cell-input])]:p-0",
7732
8250
  "align-middle",
7733
8251
  "whitespace-nowrap",
7734
8252
  "[&:has([role=checkbox])]:pr-0",
@@ -7741,15 +8259,47 @@
7741
8259
  );
7742
8260
  el.setAttribute("data-slot", "table-cell");
7743
8261
  });
8262
+ Alpine.directive("h-table-cell-button", (el) => {
8263
+ el.classList.add(
8264
+ "px-2",
8265
+ "size-full",
8266
+ "h-10",
8267
+ "cursor-pointer",
8268
+ "inline-flex",
8269
+ "items-center",
8270
+ "justify-between",
8271
+ "outline-none",
8272
+ "gap-2",
8273
+ "transition-[color,box-shadow]",
8274
+ "[&_svg]:pointer-events-none",
8275
+ "[&_svg]:opacity-70",
8276
+ "[&_svg]:text-foreground",
8277
+ "[&_svg]:transition-transform",
8278
+ "[&_svg]:duration-200",
8279
+ "[&_svg:not([class*='size-'])]:size-4",
8280
+ "shrink-0",
8281
+ "[&_svg]:shrink-0",
8282
+ "focus-visible:inset-ring-ring/50",
8283
+ "focus-visible:inset-ring-2",
8284
+ "hover:bg-table-hover",
8285
+ "hover:text-table-hover-foreground",
8286
+ "active:!bg-table-active",
8287
+ "active:!text-table-active-foreground",
8288
+ "[&[data-state=open]>svg:not(:first-child):last-child]:rotate-180",
8289
+ "[&[data-state=open]>svg:only-child]:rotate-180"
8290
+ );
8291
+ el.setAttribute("type", "button");
8292
+ el.setAttribute("data-slot", "cell-input-button");
8293
+ });
7744
8294
  Alpine.directive("h-table-body", (el) => {
7745
8295
  el.classList.add(
7746
- "[&_tr:last-child_td]:border-b-0",
7747
- "[&_tr:last-child_th]:border-b-0",
7748
- "[&_tr_th]:bg-table-header",
7749
- "[&_tr[data-hoverable=true]:hover_th]:bg-table-hover",
7750
- "[&_tr[data-hoverable=true]:hover_th]:text-table-hover-foreground",
7751
- "[&_tr[data-activable=true]:active_th]:!bg-table-active",
7752
- "[&_tr[data-activable=true]:active_th]:!text-table-active-foreground"
8296
+ "[&_tr:last-child_td[data-slot|=table]]:border-b-0",
8297
+ "[&_tr:last-child_th[data-slot|=table]]:border-b-0",
8298
+ "[&_tr_th[data-slot|=table]]:bg-table-header",
8299
+ "[&_tr[data-hoverable=true]:hover_th[data-slot|=table]]:bg-table-hover",
8300
+ "[&_tr[data-hoverable=true]:hover_th[data-slot|=table]]:text-table-hover-foreground",
8301
+ "[&_tr[data-activable=true]:active_th[data-slot|=table]]:!bg-table-active",
8302
+ "[&_tr[data-activable=true]:active_th[data-slot|=table]]:!text-table-active-foreground"
7753
8303
  );
7754
8304
  el.setAttribute("data-slot", "table-body");
7755
8305
  });
@@ -7769,7 +8319,7 @@
7769
8319
  el.setAttribute("data-slot", "table-caption");
7770
8320
  });
7771
8321
  Alpine.directive("h-table-footer", (el) => {
7772
- el.classList.add("bg-table-header", "font-medium", "last:[&>tr_td]:border-b-0", "last:[&>tr_th]:border-b-0");
8322
+ el.classList.add("bg-table-header", "font-medium", "last:[&>tr_td[data-slot|=table]]:border-b-0", "last:[&>tr_th[data-slot|=table]]:border-b-0");
7773
8323
  el.setAttribute("data-slot", "table-footer");
7774
8324
  });
7775
8325
  }
@@ -7823,7 +8373,7 @@
7823
8373
  el.setAttribute("role", "tablist");
7824
8374
  el.setAttribute("data-slot", "tab-list");
7825
8375
  });
7826
- Alpine.directive("h-tab", (el, { original }) => {
8376
+ Alpine.directive("h-tab", (el, { original: original2 }) => {
7827
8377
  el.classList.add(
7828
8378
  "cursor-pointer",
7829
8379
  "focus-visible:border-ring",
@@ -7870,8 +8420,8 @@
7870
8420
  );
7871
8421
  el.setAttribute("role", "tab");
7872
8422
  el.setAttribute("data-slot", "tab");
7873
- if (!el.hasAttribute("id")) throw new Error(`${original}: Tabs must have an id`);
7874
- if (!el.hasAttribute("aria-controls")) throw new Error(`${original}: aria-controls must be set to the tab-content id.`);
8423
+ if (!el.hasAttribute("id")) throw new Error(`${original2}: Tabs must have an id`);
8424
+ if (!el.hasAttribute("aria-controls")) throw new Error(`${original2}: aria-controls must be set to the tab-content id.`);
7875
8425
  });
7876
8426
  Alpine.directive("h-tab-action", (el) => {
7877
8427
  el.classList.add("cursor-pointer", "ml-auto", "rounded-md", "text-foreground", "hover:bg-secondary", "hover:text-secondary-foreground", "active:bg-secondary-active");
@@ -7905,13 +8455,13 @@
7905
8455
  el.setAttribute("role", "button");
7906
8456
  el.setAttribute("data-slot", "tab-list-action");
7907
8457
  });
7908
- Alpine.directive("h-tabs-content", (el, { original }) => {
8458
+ Alpine.directive("h-tabs-content", (el, { original: original2 }) => {
7909
8459
  el.classList.add("flex-1", "outline-none");
7910
8460
  el.setAttribute("role", "tabpanel");
7911
8461
  el.setAttribute("tabindex", "0");
7912
8462
  el.setAttribute("data-slot", "tabs-content");
7913
- if (!el.hasAttribute("id")) throw new Error(`${original}: Tab content must have an id`);
7914
- if (!el.hasAttribute("aria-labelledby")) throw new Error(`${original}: aria-labelledby must be set to the tab id.`);
8463
+ if (!el.hasAttribute("id")) throw new Error(`${original2}: Tab content must have an id`);
8464
+ if (!el.hasAttribute("aria-labelledby")) throw new Error(`${original2}: aria-labelledby must be set to the tab id.`);
7915
8465
  });
7916
8466
  }
7917
8467
 
@@ -8174,7 +8724,7 @@
8174
8724
  });
8175
8725
  }
8176
8726
  function timepicker_default(Alpine) {
8177
- Alpine.directive("h-time-picker", (el, { expression }, { evaluateLater, cleanup, effect, Alpine: Alpine2 }) => {
8727
+ Alpine.directive("h-time-picker", (el, { expression, modifiers }, { evaluateLater, cleanup, effect, Alpine: Alpine2 }) => {
8178
8728
  el._h_timepicker = Alpine2.reactive({
8179
8729
  id: void 0,
8180
8730
  controls: `htpc${v4_default()}`,
@@ -8204,39 +8754,55 @@
8204
8754
  el.classList.add(
8205
8755
  "cursor-pointer",
8206
8756
  "border-input",
8207
- "[&>input]:appearance-none",
8208
- "has-[input:focus-visible]:border-ring",
8209
- "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
8210
- "has-[input:focus-visible]:ring-ring/50",
8211
- "has-[input[aria-invalid=true]]:ring-negative/20",
8212
- "has-[input[aria-invalid=true]]:border-negative",
8213
- "dark:has-[input[aria-invalid=true]]:ring-negative/40",
8214
- "has-[input:invalid]:ring-negative/20",
8215
- "has-[input:invalid]:border-negative",
8216
- "dark:has-[input:invalid]:ring-negative/40",
8217
8757
  "hover:bg-secondary-hover",
8218
8758
  "active:bg-secondary-active",
8219
8759
  "flex",
8220
- "w-full",
8221
8760
  "items-center",
8222
8761
  "justify-between",
8223
8762
  "gap-2",
8224
- "rounded-control",
8225
- "border",
8226
- "bg-input-inner",
8227
8763
  "pl-3",
8228
8764
  "pr-2",
8229
8765
  "data-[size=sm]:pr-1",
8230
8766
  "text-sm",
8231
8767
  "whitespace-nowrap",
8232
- "shadow-input",
8233
8768
  "transition-[color,box-shadow]",
8234
8769
  "duration-200",
8235
8770
  "outline-none",
8236
8771
  "has-[input:disabled]:pointer-events-none",
8772
+ "has-[input:disabled]:cursor-not-allowed",
8237
8773
  "has-[input:disabled]:opacity-50"
8238
8774
  );
8239
- el.setAttribute("data-slot", "time-picker");
8775
+ if (modifiers.includes("table")) {
8776
+ el.classList.add(
8777
+ "size-full",
8778
+ "h-10",
8779
+ "has-[input:focus-visible]:inset-ring-ring/50",
8780
+ "has-[input:focus-visible]:inset-ring-2",
8781
+ "has-[input[aria-invalid=true]]:inset-ring-negative/20",
8782
+ "dark:has-[input[aria-invalid=true]]:inset-ring-negative/40",
8783
+ "has-[input:invalid]:!inset-ring-negative/20",
8784
+ "dark:has-[input:invalid]:!inset-ring-negative/40"
8785
+ );
8786
+ el.setAttribute("data-slot", "cell-input-time");
8787
+ } else {
8788
+ el.classList.add(
8789
+ "w-full",
8790
+ "rounded-control",
8791
+ "border",
8792
+ "bg-input-inner",
8793
+ "shadow-input",
8794
+ "has-[input:focus-visible]:border-ring",
8795
+ "has-[input:focus-visible]:ring-[calc(var(--spacing)*0.75)]",
8796
+ "has-[input:focus-visible]:ring-ring/50",
8797
+ "has-[input[aria-invalid=true]]:ring-negative/20",
8798
+ "has-[input[aria-invalid=true]]:border-negative",
8799
+ "dark:has-[input[aria-invalid=true]]:ring-negative/40",
8800
+ "has-[input:invalid]:ring-negative/20",
8801
+ "has-[input:invalid]:border-negative",
8802
+ "dark:has-[input:invalid]:ring-negative/40"
8803
+ );
8804
+ el.setAttribute("data-slot", "time-picker");
8805
+ }
8240
8806
  el.setAttribute("tabindex", "-1");
8241
8807
  el.appendChild(
8242
8808
  createSvg({
@@ -8288,13 +8854,13 @@
8288
8854
  top.removeEventListener("click", el._h_timepicker.close);
8289
8855
  });
8290
8856
  });
8291
- Alpine.directive("h-time-picker-input", (el, { original }, { effect, cleanup, Alpine: Alpine2 }) => {
8857
+ Alpine.directive("h-time-picker-input", (el, { original: original2 }, { effect, cleanup, Alpine: Alpine2 }) => {
8292
8858
  if (el.tagName !== "INPUT") {
8293
- throw new Error(`${original} must be a readonly input of type "text"`);
8859
+ throw new Error(`${original2} must be a readonly input of type "text"`);
8294
8860
  }
8295
8861
  const timepicker = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_timepicker"));
8296
8862
  if (!timepicker) {
8297
- throw new Error(`${original} must be inside a time-picker element`);
8863
+ throw new Error(`${original2} must be inside a time-picker element`);
8298
8864
  }
8299
8865
  timepicker._h_timepicker.focusInput = () => {
8300
8866
  el.focus();
@@ -8322,7 +8888,20 @@
8322
8888
  timepicker._h_timepicker.id = `htp${v4_default()}`;
8323
8889
  el.setAttribute("id", timepicker._h_timepicker.id);
8324
8890
  }
8325
- el.classList.add("cursor-pointer", "bg-transparent", "text-transparent", "text-shadow-[0_0_0_var(--foreground)]", "placeholder:text-muted-foreground", "outline-none", "size-full", "border-0", "md:text-sm", "text-base", "truncate");
8891
+ el.classList.add(
8892
+ "appearance-none",
8893
+ "cursor-pointer",
8894
+ "bg-transparent",
8895
+ "text-transparent",
8896
+ "text-shadow-[0_0_0_var(--foreground)]",
8897
+ "placeholder:text-muted-foreground",
8898
+ "outline-none",
8899
+ "size-full",
8900
+ "border-0",
8901
+ "md:text-sm",
8902
+ "text-base",
8903
+ "truncate"
8904
+ );
8326
8905
  el.setAttribute("aria-autocomplete", "none");
8327
8906
  el.setAttribute("aria-controls", timepicker._h_timepicker.controls);
8328
8907
  el.setAttribute("aria-expanded", "false");
@@ -8870,8 +9449,8 @@
8870
9449
  "shrink-0",
8871
9450
  "items-center",
8872
9451
  "px-1",
8873
- 'has-[>[data-slot="avatar"]:last-child]:pr-2',
8874
- 'has-[>[data-slot="toolbar-image"]:first-child]:pl-2',
9452
+ 'has-[>[data-slot="avatar"]:last-of-type]:pr-2',
9453
+ 'has-[>[data-slot="toolbar-image"]:first-of-type]:pl-2',
8875
9454
  "gap-1",
8876
9455
  modifiers.includes("footer") ? "border-t" : "border-b",
8877
9456
  "w-full",
@@ -8930,7 +9509,7 @@
8930
9509
  el.removeEventListener("pointerleave", handler);
8931
9510
  });
8932
9511
  });
8933
- Alpine.directive("h-tooltip", (el, { original }, { effect }) => {
9512
+ Alpine.directive("h-tooltip", (el, { original: original2 }, { effect }) => {
8934
9513
  const tooltip = (() => {
8935
9514
  let sibling = el.previousElementSibling;
8936
9515
  while (sibling && !sibling.hasOwnProperty("_tooltip")) {
@@ -8939,7 +9518,7 @@
8939
9518
  return sibling;
8940
9519
  })();
8941
9520
  if (!tooltip) {
8942
- throw new Error(`${original} must be placed after a tooltip trigger element`);
9521
+ throw new Error(`${original2} must be placed after a tooltip trigger element`);
8943
9522
  }
8944
9523
  el.classList.add("absolute", "bg-foreground", "text-background", "z-50", "w-fit", "rounded-md", "px-3", "py-1.5", "text-xs", "text-balance");
8945
9524
  el.setAttribute("data-slot", "tooltip");
@@ -9145,9 +9724,9 @@
9145
9724
  });
9146
9725
  }
9147
9726
  });
9148
- Alpine.directive("h-tree-button", (el, { original }, { effect }) => {
9727
+ Alpine.directive("h-tree-button", (el, { original: original2 }, { effect }) => {
9149
9728
  const treeItem = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_tree_item"));
9150
- if (!treeItem) throw new Error(`${original} must be inside a tree item`);
9729
+ if (!treeItem) throw new Error(`${original2} must be inside a tree item`);
9151
9730
  el.classList.add(
9152
9731
  "flex",
9153
9732
  "w-full",
@@ -9302,7 +9881,7 @@
9302
9881
 
9303
9882
  // src/utils/template.js
9304
9883
  function template_default(Alpine) {
9305
- Alpine.directive("h-template", (el, { original, expression }, { evaluate: evaluate2, Alpine: Alpine2, cleanup }) => {
9884
+ Alpine.directive("h-template", (el, { original: original2, expression }, { evaluate: evaluate2, Alpine: Alpine2, cleanup }) => {
9306
9885
  if (el.hasAttribute(Alpine2.prefixed("data"))) {
9307
9886
  const template = evaluate2(expression);
9308
9887
  const clone = template.content.cloneNode(true).firstElementChild;
@@ -9312,10 +9891,11 @@
9312
9891
  Alpine2.initTree(clone);
9313
9892
  });
9314
9893
  cleanup(() => {
9894
+ Alpine2.destroyTree(clone);
9315
9895
  clone.remove();
9316
9896
  });
9317
9897
  } else {
9318
- console.error(`${original}: ${Alpine2.prefixed("data")} directive is missing`);
9898
+ console.error(`${original2}: ${Alpine2.prefixed("data")} directive is missing`);
9319
9899
  }
9320
9900
  });
9321
9901
  }
@@ -9333,7 +9913,7 @@
9333
9913
  }
9334
9914
 
9335
9915
  // package.json
9336
- var version = "1.1.2";
9916
+ var version = "1.2.1";
9337
9917
 
9338
9918
  // src/index.js
9339
9919
  window.Harmonia = { getBreakpointListener, addColorSchemeListener, getColorScheme, removeColorSchemeListener, setColorScheme, version };