@yewdiel21/motion-kit 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.md +178 -155
  2. package/bin/motion-kit.mjs +3 -3
  3. package/dist/auto/index.d.ts +6 -3
  4. package/dist/auto/index.js +8 -2
  5. package/dist/auto/index.js.map +1 -1
  6. package/dist/{chunk-EY4BJKC4.js → chunk-NFZIX3IA.js} +2 -2
  7. package/dist/chunk-RBEKR5UZ.js +3660 -0
  8. package/dist/chunk-RBEKR5UZ.js.map +1 -0
  9. package/dist/{chunk-CU6SXW3E.js → chunk-SDQ776LG.js} +1596 -485
  10. package/dist/chunk-SDQ776LG.js.map +1 -0
  11. package/dist/css/components/add-to-cart.css +72 -0
  12. package/dist/css/components/bidirectional-slider.css +168 -0
  13. package/dist/css/components/chart.css +7 -0
  14. package/dist/css/components/data-table.css +121 -26
  15. package/dist/css/components/filter-builder.css +10 -15
  16. package/dist/css/components/heatmap-chart.css +398 -0
  17. package/dist/css/components/hover-card.css +8 -2
  18. package/dist/css/components/image-preview.css +90 -2
  19. package/dist/css/components/json-viewer.css +33 -1
  20. package/dist/css/components/nav.css +102 -102
  21. package/dist/css/components/orbit-menu.css +130 -0
  22. package/dist/css/components/pagination.css +10 -5
  23. package/dist/css/components/pie-chart.css +397 -0
  24. package/dist/css/components/pill-button.css +135 -0
  25. package/dist/css/components/radar-chart.css +377 -0
  26. package/dist/css/components/radial-chart.css +412 -0
  27. package/dist/css/components/sankey-chart.css +365 -0
  28. package/dist/css/components/scroll-island.css +114 -0
  29. package/dist/css/components/select.css +136 -0
  30. package/dist/css/components/toolbar.css +122 -0
  31. package/dist/css/components/tree-view.css +79 -0
  32. package/dist/css/components/voice-dots.css +70 -0
  33. package/dist/elements/index.d.ts +180 -7
  34. package/dist/elements/index.js +293 -7
  35. package/dist/elements/index.js.map +1 -1
  36. package/dist/{engine-Cn6IhE3z.d.ts → engine-5zRIssTO.d.ts} +11 -1
  37. package/dist/index.css +1849 -168
  38. package/dist/index.d.ts +4 -4
  39. package/dist/index.js +33 -3
  40. package/dist/index.js.map +1 -1
  41. package/dist/react/index.d.ts +117 -11
  42. package/dist/react/index.js +320 -13
  43. package/dist/react/index.js.map +1 -1
  44. package/dist/{reduced-BBUusld6.d.ts → reduced-DQwVXQYb.d.ts} +1 -1
  45. package/dist/{reveal-DEvp6U6T.d.ts → reveal-DRpNO4KP.d.ts} +109 -4
  46. package/dist/store-Da3zSh8Z.d.ts +457 -0
  47. package/package.json +9 -16
  48. package/registry.json +1096 -948
  49. package/src/auto/auto-init.ts +6 -0
  50. package/src/components/add-to-cart/README.md +49 -0
  51. package/src/components/add-to-cart/add-to-cart.css +71 -0
  52. package/src/components/add-to-cart/element.ts +20 -0
  53. package/src/components/add-to-cart/engine.ts +206 -0
  54. package/src/components/add-to-cart/react.tsx +33 -0
  55. package/src/components/bidirectional-slider/README.md +46 -0
  56. package/src/components/bidirectional-slider/bidirectional-slider.css +167 -0
  57. package/src/components/bidirectional-slider/element.ts +42 -0
  58. package/src/components/bidirectional-slider/engine.ts +289 -0
  59. package/src/components/bidirectional-slider/react.tsx +45 -0
  60. package/src/components/chart/README.md +49 -24
  61. package/src/components/chart/chart.css +7 -0
  62. package/src/components/chart/element.ts +4 -1
  63. package/src/components/chart/engine.ts +153 -34
  64. package/src/components/chart/parts.ts +237 -0
  65. package/src/components/chart/react.tsx +2 -2
  66. package/src/components/chart/use-chart.ts +55 -0
  67. package/src/components/data-table/README.md +3 -3
  68. package/src/components/data-table/data-table.css +121 -26
  69. package/src/components/data-table/engine.ts +81 -29
  70. package/src/components/editable-table/engine.ts +67 -11
  71. package/src/components/filter-builder/engine.ts +33 -2
  72. package/src/components/filter-builder/filter-builder.css +10 -15
  73. package/src/components/heatmap-chart/README.md +48 -0
  74. package/src/components/heatmap-chart/element.ts +21 -0
  75. package/src/components/heatmap-chart/engine.ts +281 -0
  76. package/src/components/heatmap-chart/heatmap-chart.css +93 -0
  77. package/src/components/heatmap-chart/react.tsx +14 -0
  78. package/src/components/hover-card/engine.ts +30 -1
  79. package/src/components/hover-card/hover-card.css +8 -2
  80. package/src/components/image-preview/element.ts +1 -1
  81. package/src/components/image-preview/engine.ts +95 -15
  82. package/src/components/image-preview/image-preview.css +90 -2
  83. package/src/components/image-preview/react.tsx +3 -3
  84. package/src/components/json-viewer/engine.ts +11 -2
  85. package/src/components/json-viewer/json-viewer.css +33 -1
  86. package/src/components/nav/README.md +12 -10
  87. package/src/components/nav/element.ts +5 -5
  88. package/src/components/nav/engine.ts +21 -14
  89. package/src/components/nav/nav.css +102 -102
  90. package/src/components/nav/react.tsx +4 -4
  91. package/src/components/orbit-menu/README.md +46 -0
  92. package/src/components/orbit-menu/element.ts +27 -0
  93. package/src/components/orbit-menu/engine.ts +179 -0
  94. package/src/components/orbit-menu/orbit-menu.css +129 -0
  95. package/src/components/orbit-menu/react.tsx +44 -0
  96. package/src/components/pagination/README.md +1 -1
  97. package/src/components/pagination/engine.ts +50 -4
  98. package/src/components/pagination/pagination.css +10 -5
  99. package/src/components/pie-chart/README.md +48 -0
  100. package/src/components/pie-chart/element.ts +30 -0
  101. package/src/components/pie-chart/engine.ts +283 -0
  102. package/src/components/pie-chart/pie-chart.css +92 -0
  103. package/src/components/pie-chart/react.tsx +14 -0
  104. package/src/components/pill-button/README.md +46 -0
  105. package/src/components/pill-button/element.ts +16 -0
  106. package/src/components/pill-button/engine.ts +77 -0
  107. package/src/components/pill-button/pill-button.css +134 -0
  108. package/src/components/pill-button/react.tsx +32 -0
  109. package/src/components/radar-chart/README.md +48 -0
  110. package/src/components/radar-chart/element.ts +30 -0
  111. package/src/components/radar-chart/engine.ts +327 -0
  112. package/src/components/radar-chart/radar-chart.css +72 -0
  113. package/src/components/radar-chart/react.tsx +14 -0
  114. package/src/components/radial-chart/README.md +58 -0
  115. package/src/components/radial-chart/element.ts +30 -0
  116. package/src/components/radial-chart/engine.ts +317 -0
  117. package/src/components/radial-chart/radial-chart.css +107 -0
  118. package/src/components/radial-chart/react.tsx +14 -0
  119. package/src/components/sankey-chart/README.md +48 -0
  120. package/src/components/sankey-chart/element.ts +31 -0
  121. package/src/components/sankey-chart/engine.ts +401 -0
  122. package/src/components/sankey-chart/react.tsx +14 -0
  123. package/src/components/sankey-chart/sankey-chart.css +60 -0
  124. package/src/components/scroll-island/README.md +44 -0
  125. package/src/components/scroll-island/element.ts +16 -0
  126. package/src/components/scroll-island/engine.ts +274 -0
  127. package/src/components/scroll-island/react.tsx +26 -0
  128. package/src/components/scroll-island/scroll-island.css +113 -0
  129. package/src/components/select/README.md +34 -0
  130. package/src/components/select/element.ts +26 -0
  131. package/src/components/select/engine.ts +267 -0
  132. package/src/components/select/react.tsx +33 -0
  133. package/src/components/select/select.css +135 -0
  134. package/src/components/toolbar/README.md +46 -0
  135. package/src/components/toolbar/element.ts +30 -0
  136. package/src/components/toolbar/engine.ts +230 -0
  137. package/src/components/toolbar/react.tsx +34 -0
  138. package/src/components/toolbar/toolbar.css +121 -0
  139. package/src/components/tree-view/element.ts +1 -1
  140. package/src/components/tree-view/engine.ts +174 -0
  141. package/src/components/tree-view/react.tsx +7 -3
  142. package/src/components/tree-view/tree-view.css +79 -0
  143. package/src/components/voice-dots/README.md +48 -0
  144. package/src/components/voice-dots/element.ts +45 -0
  145. package/src/components/voice-dots/engine.ts +243 -0
  146. package/src/components/voice-dots/react.tsx +52 -0
  147. package/src/components/voice-dots/voice-dots.css +69 -0
  148. package/src/elements/index.ts +39 -0
  149. package/src/index.ts +16 -0
  150. package/src/motion/liquid.ts +14 -4
  151. package/src/react/index.ts +14 -1
  152. package/dist/chunk-6P4P7NU6.js +0 -1401
  153. package/dist/chunk-6P4P7NU6.js.map +0 -1
  154. package/dist/chunk-CU6SXW3E.js.map +0 -1
  155. package/dist/store-DjkTBX7f.d.ts +0 -195
  156. /package/dist/{chunk-EY4BJKC4.js.map → chunk-NFZIX3IA.js.map} +0 -0
@@ -213,8 +213,8 @@ function channels(start, onChange) {
213
213
  gsap2.ticker.remove(tick);
214
214
  gsap2.ticker.add(tick);
215
215
  resolveDone?.();
216
- return new Promise((resolve) => {
217
- resolveDone = resolve;
216
+ return new Promise((resolve2) => {
217
+ resolveDone = resolve2;
218
218
  });
219
219
  },
220
220
  stop() {
@@ -293,7 +293,7 @@ function requestFrame(fn) {
293
293
  const id = setTimeout(() => fn(Date.now()), 16);
294
294
  return () => clearTimeout(id);
295
295
  }
296
- var nextFrame = () => new Promise((resolve) => requestFrame(() => resolve()));
296
+ var nextFrame = () => new Promise((resolve2) => requestFrame(() => resolve2()));
297
297
 
298
298
  // src/core/styles.ts
299
299
  function clearStyles(targets, properties) {
@@ -525,14 +525,14 @@ function revealFrom(target, options = {}) {
525
525
  paint();
526
526
  target.append(veil);
527
527
  let done = false;
528
- let resolve;
529
- const finished = new Promise((r) => resolve = r);
528
+ let resolve2;
529
+ const finished = new Promise((r) => resolve2 = r);
530
530
  const cleanup = () => {
531
531
  if (done) return;
532
532
  done = true;
533
533
  veil.remove();
534
534
  target.style.position = position2;
535
- resolve();
535
+ resolve2();
536
536
  };
537
537
  const [duration, fade] = TIMING.reveal[speed];
538
538
  const timeline = gsap.timeline({ delay, onComplete: cleanup, onInterrupt: cleanup }).to(progress, { value: 100, duration, ease: "power2.out", onUpdate: paint }, 0).to(veil, { opacity: 0, duration: fade, ease: "power1.out" }, Math.max(0, duration * Math.min(1, 1 / overshoot) - 0.1));
@@ -708,14 +708,14 @@ function confetti(origin, options = {}) {
708
708
  let frame = 0;
709
709
  let last = 0;
710
710
  let stopped = false;
711
- let resolve;
712
- const finished = new Promise((done) => resolve = done);
711
+ let resolve2;
712
+ const finished = new Promise((done) => resolve2 = done);
713
713
  const stop2 = () => {
714
714
  if (stopped) return;
715
715
  stopped = true;
716
716
  cancelAnimationFrame(frame);
717
717
  canvas.remove();
718
- resolve();
718
+ resolve2();
719
719
  };
720
720
  const draw = (now2) => {
721
721
  const f = last ? Math.min((now2 - last) / (1e3 / 60), 3) : 1;
@@ -1376,7 +1376,7 @@ function ensureGoo() {
1376
1376
  svg2.setAttribute("width", "0");
1377
1377
  svg2.setAttribute("height", "0");
1378
1378
  svg2.style.position = "absolute";
1379
- svg2.innerHTML = `<defs><filter id="${GOO}" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur in="SourceGraphic" stdDeviation="20"/><feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9"/></filter></defs>`;
1379
+ svg2.innerHTML = `<defs><filter id="${GOO}" x="-50%" y="-50%" width="200%" height="200%" color-interpolation-filters="sRGB"><feGaussianBlur in="SourceGraphic" stdDeviation="20"/><feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9"/></filter></defs>`;
1380
1380
  document.body.append(svg2);
1381
1381
  }
1382
1382
  function gooLayer(surface) {
@@ -1474,7 +1474,7 @@ function liquidOpen(surface, origin, parts) {
1474
1474
  }
1475
1475
  });
1476
1476
  const L = TIMING.liquid;
1477
- void motion.animate(
1477
+ const settled = motion.animate(
1478
1478
  { top: box.top, left: box.left, width: box.width, height: box.height, radius: endRadius, scale: 1, blur: 0 },
1479
1479
  {
1480
1480
  top: spring(144, 14, { velocity: 2400, direction: towardY }),
@@ -1489,16 +1489,22 @@ function liquidOpen(surface, origin, parts) {
1489
1489
  gsap.to(shape, { background: surfaceColor, duration: L.color, delay: L.colorDelay, ease: "power2.out" });
1490
1490
  if (parts.length) gsap.to(parts, { opacity: 1, duration: L.color, delay: L.colorDelay, ease: "power2.out" });
1491
1491
  gsap.to(originBlob, { opacity: 0, duration: L.ghost, delay: L.ghostDelay, ease: "power2.out" });
1492
+ const sharpen = setTimeout(() => {
1493
+ layer.style.filter = "none";
1494
+ originBlob.remove();
1495
+ }, (L.ghostDelay + L.ghost) * 1e3 + 30);
1492
1496
  let done = false;
1493
1497
  const finish = () => {
1494
1498
  if (done) return;
1495
1499
  done = true;
1496
1500
  motion.stop();
1497
1501
  clearTimeout(timer2);
1502
+ clearTimeout(sharpen);
1498
1503
  layer.remove();
1499
1504
  restore();
1500
1505
  if (parts.length) gsap.set(parts, { clearProps: "opacity,transform,transformOrigin,filter" });
1501
1506
  };
1507
+ void settled.then(finish);
1502
1508
  const timer2 = setTimeout(finish, L.safetyMs);
1503
1509
  return finish;
1504
1510
  }
@@ -1700,7 +1706,7 @@ function textBox(element) {
1700
1706
  }
1701
1707
  var textOf = (element) => element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement ? element.value || element.placeholder : element.firstChild?.textContent ?? element.textContent ?? "";
1702
1708
  function flyText(from, to, text, duration) {
1703
- return new Promise((resolve) => {
1709
+ return new Promise((resolve2) => {
1704
1710
  const start = textBox(from);
1705
1711
  const end = textBox(to);
1706
1712
  const fromSize = parseFloat(start.style.fontSize) || 16;
@@ -1742,7 +1748,7 @@ function flyText(from, to, text, duration) {
1742
1748
  ease: EASE.signature,
1743
1749
  onComplete: () => {
1744
1750
  ghost.remove();
1745
- resolve();
1751
+ resolve2();
1746
1752
  }
1747
1753
  });
1748
1754
  });
@@ -2761,6 +2767,194 @@ function createQuantity(root, options = {}) {
2761
2767
  }, destroy: () => scope.dispose() };
2762
2768
  }
2763
2769
 
2770
+ // src/motion/micro.ts
2771
+ var list2 = (targets) => !targets ? [] : targets instanceof Element ? [targets] : [...targets];
2772
+ var live = () => {
2773
+ registerMotion();
2774
+ return !reduced();
2775
+ };
2776
+ function press(el5) {
2777
+ if (!el5 || !live()) return null;
2778
+ gsap.killTweensOf(el5, "scaleX,scaleY");
2779
+ return gsap.timeline({
2780
+ onComplete: () => {
2781
+ gsap.set(el5, { clearProps: "scale,transform" });
2782
+ }
2783
+ }).to(el5, { scaleX: 0.95, scaleY: 0.9, duration: 0.1, ease: "power2.out" }).to(el5, { scaleX: 1, scaleY: 1, duration: 0.5, ease: EASE.click });
2784
+ }
2785
+ function blurIn(targets, { from = "rise", stagger = 0.05, delay = 0, duration } = {}) {
2786
+ const items = list2(targets);
2787
+ if (!items.length || !live()) return null;
2788
+ const start = from === "pop" ? { opacity: 0, scale: 0.7, filter: "blur(32px)" } : from === "soft" ? { opacity: 0, scale: 0.96, filter: "blur(16px)" } : { opacity: 0, y: -20, filter: "blur(16px)" };
2789
+ return gsap.fromTo(items, start, {
2790
+ opacity: 1,
2791
+ y: 0,
2792
+ scale: 1,
2793
+ filter: "blur(0px)",
2794
+ duration: duration ?? (from === "pop" ? 0.3 : 0.5),
2795
+ ease: from === "pop" ? EASE.pop : "power2.out",
2796
+ stagger,
2797
+ delay,
2798
+ clearProps: "opacity,transform,filter"
2799
+ });
2800
+ }
2801
+ function blurOut(targets, { to = "up", onComplete } = {}) {
2802
+ const items = list2(targets);
2803
+ if (!items.length) return null;
2804
+ if (!live()) {
2805
+ onComplete?.();
2806
+ return null;
2807
+ }
2808
+ const end = to === "left" ? { x: -64 } : to === "down" ? { y: 24 } : { y: -20 };
2809
+ return gsap.to(items, { ...end, opacity: 0, filter: "blur(16px)", duration: 0.5, ease: "power2.out", onComplete });
2810
+ }
2811
+ function collapse(el5, { onComplete } = {}) {
2812
+ if (!el5) return null;
2813
+ if (!live()) {
2814
+ onComplete?.();
2815
+ return null;
2816
+ }
2817
+ return gsap.to(el5, {
2818
+ height: 0,
2819
+ paddingTop: 0,
2820
+ paddingBottom: 0,
2821
+ marginTop: 0,
2822
+ marginBottom: 0,
2823
+ opacity: 0,
2824
+ filter: "blur(16px)",
2825
+ overflow: "hidden",
2826
+ duration: 0.25,
2827
+ ease: "power2.in",
2828
+ onComplete
2829
+ });
2830
+ }
2831
+ function shake(el5, distance = 4) {
2832
+ if (!el5 || !live()) return null;
2833
+ gsap.killTweensOf(el5, "x");
2834
+ return gsap.to(el5, {
2835
+ keyframes: { x: [0, -distance, distance, -distance, 0] },
2836
+ duration: 0.5,
2837
+ ease: EASE.shake,
2838
+ clearProps: "x,transform"
2839
+ });
2840
+ }
2841
+ function ringPulse(el5, color = "var(--mk-accent-soft)") {
2842
+ if (!el5 || !live()) return null;
2843
+ const before = { color: el5.style.outlineColor, style: el5.style.outlineStyle, offset: el5.style.outlineOffset };
2844
+ el5.style.outlineColor = color;
2845
+ el5.style.outlineStyle = "solid";
2846
+ el5.style.outlineOffset = "-4px";
2847
+ const restore = () => {
2848
+ el5.style.outlineColor = before.color;
2849
+ el5.style.outlineStyle = before.style;
2850
+ el5.style.outlineOffset = before.offset;
2851
+ el5.style.removeProperty("outline-width");
2852
+ if (el5.getAttribute("style") === "") el5.removeAttribute("style");
2853
+ };
2854
+ return gsap.fromTo(el5, { outlineWidth: 0 }, { keyframes: { outlineWidth: [0, 4, 0] }, duration: 1, ease: "power1.inOut", onComplete: restore, onInterrupt: restore });
2855
+ }
2856
+ function burst(origin, { count = 7, distance = 28, colors = ["var(--mk-accent)"], ring = true, size = 6 } = {}) {
2857
+ if (!origin || !live()) return null;
2858
+ const layer = document.createElement("span");
2859
+ layer.setAttribute("aria-hidden", "true");
2860
+ layer.dataset.mkBurst = "";
2861
+ Object.assign(layer.style, { position: "absolute", inset: "0", pointerEvents: "none", overflow: "visible", display: "grid", placeItems: "center" });
2862
+ const positioned = getComputedStyle(origin).position !== "static";
2863
+ const previousPosition = origin.style.position;
2864
+ if (!positioned) origin.style.position = "relative";
2865
+ origin.append(layer);
2866
+ const cleanup = () => {
2867
+ layer.remove();
2868
+ if (!positioned) origin.style.position = previousPosition;
2869
+ if (origin.getAttribute("style") === "") origin.removeAttribute("style");
2870
+ };
2871
+ const timeline = gsap.timeline({ onComplete: cleanup, onInterrupt: cleanup });
2872
+ if (ring) {
2873
+ const circle = document.createElement("span");
2874
+ Object.assign(circle.style, { position: "absolute", width: "100%", aspectRatio: "1", borderRadius: "50%", border: `2px solid ${colors[0]}` });
2875
+ layer.append(circle);
2876
+ timeline.fromTo(circle, { scale: 0.3, opacity: 0.9 }, { scale: 1.6, opacity: 0, duration: 0.5, ease: "power2.out" }, 0);
2877
+ }
2878
+ for (let i = 0; i < count; i++) {
2879
+ const angle2 = i / count * Math.PI * 2 - Math.PI / 2;
2880
+ for (const [k, scale] of [[0, 1], [1, 0.6]]) {
2881
+ const dot = document.createElement("span");
2882
+ Object.assign(dot.style, {
2883
+ position: "absolute",
2884
+ width: `${size * scale}px`,
2885
+ height: `${size * scale}px`,
2886
+ borderRadius: "50%",
2887
+ background: colors[(i + k) % colors.length]
2888
+ });
2889
+ layer.append(dot);
2890
+ const reach = distance * (k ? 0.72 : 1);
2891
+ const turn = k ? 0.32 : 0;
2892
+ timeline.fromTo(
2893
+ dot,
2894
+ { x: 0, y: 0, scale: 0, opacity: 1 },
2895
+ { x: Math.cos(angle2 + turn) * reach, y: Math.sin(angle2 + turn) * reach, scale: 1, duration: 0.45, ease: "power3.out" },
2896
+ 0.05
2897
+ );
2898
+ timeline.to(dot, { scale: 0, opacity: 0, duration: 0.3, ease: "power2.in" }, 0.38);
2899
+ }
2900
+ }
2901
+ return timeline;
2902
+ }
2903
+ var rolling = /* @__PURE__ */ new WeakMap();
2904
+ function rollDigits(el5, text, direction = 1, duration = 0.5) {
2905
+ if (!el5) return null;
2906
+ rolling.get(el5)?.progress(1).kill();
2907
+ rolling.delete(el5);
2908
+ const previous = el5.textContent ?? "";
2909
+ if (previous === text || !live()) {
2910
+ el5.textContent = text;
2911
+ return null;
2912
+ }
2913
+ const width = Math.max(previous.length, text.length);
2914
+ const oldChars = previous.padStart(width, " ");
2915
+ const newChars = text.padStart(width, " ");
2916
+ el5.textContent = "";
2917
+ const label = document.createElement("span");
2918
+ label.className = "mk-sr-only";
2919
+ label.textContent = text;
2920
+ const visual = document.createElement("span");
2921
+ visual.setAttribute("aria-hidden", "true");
2922
+ visual.style.display = "inline-flex";
2923
+ const moving = [];
2924
+ const padding = Math.min(width - previous.length, width - text.length);
2925
+ for (let i = padding; i < width; i++) {
2926
+ const before = oldChars[i];
2927
+ const after = newChars[i];
2928
+ const cell = document.createElement("span");
2929
+ Object.assign(cell.style, { position: "relative", display: "inline-block", overflow: "hidden", whiteSpace: "pre" });
2930
+ const next = document.createElement("span");
2931
+ next.style.display = "inline-block";
2932
+ next.textContent = after;
2933
+ cell.append(next);
2934
+ if (before !== after) {
2935
+ const old = document.createElement("span");
2936
+ Object.assign(old.style, { position: "absolute", left: "0", top: "0", display: "inline-block" });
2937
+ old.textContent = before;
2938
+ cell.append(old);
2939
+ moving.push([old, next]);
2940
+ }
2941
+ visual.append(cell);
2942
+ }
2943
+ el5.append(label, visual);
2944
+ const timeline = gsap.timeline({
2945
+ onComplete: () => {
2946
+ el5.textContent = text;
2947
+ rolling.delete(el5);
2948
+ }
2949
+ });
2950
+ moving.forEach(([old, next], i) => {
2951
+ timeline.to(old, { yPercent: -100 * direction, opacity: 0, filter: "blur(4px)", duration, ease: EASE.signature }, i * 0.03);
2952
+ timeline.fromTo(next, { yPercent: 100 * direction, opacity: 0, filter: "blur(4px)" }, { yPercent: 0, opacity: 1, filter: "blur(0px)", duration, ease: EASE.signature }, i * 0.03);
2953
+ });
2954
+ rolling.set(el5, timeline);
2955
+ return timeline;
2956
+ }
2957
+
2764
2958
  // src/components/pagination/engine.ts
2765
2959
  var positive = (n, fallback) => Number.isFinite(n) ? Math.max(1, Math.min(Number.MAX_SAFE_INTEGER - 32, Math.floor(n))) : fallback;
2766
2960
  function createPagination(root, options = {}) {
@@ -2768,16 +2962,33 @@ function createPagination(root, options = {}) {
2768
2962
  if (!root || !pages) return inert({ setPage() {
2769
2963
  }, setTotalPages() {
2770
2964
  }, page: 1, totalPages: 1 });
2965
+ registerMotion();
2771
2966
  const scope = createScope();
2772
2967
  const original = [...pages.childNodes];
2968
+ const indicator = document.createElement("span");
2969
+ indicator.dataset.mkPaginationIndicator = "";
2970
+ indicator.setAttribute("aria-hidden", "true");
2971
+ const effects = /* @__PURE__ */ new Set();
2972
+ const keep = (animation) => {
2973
+ if (!animation) return;
2974
+ effects.add(animation);
2975
+ for (const effect of effects) if (effect.totalProgress() === 1) effects.delete(effect);
2976
+ };
2977
+ scope.add(() => {
2978
+ for (const effect of effects) effect.kill();
2979
+ effects.clear();
2980
+ });
2981
+ let placed = false;
2773
2982
  const previous = root.querySelector("[data-mk-pagination-previous]");
2774
2983
  const next = root.querySelector("[data-mk-pagination-next]");
2775
2984
  let total = positive(options.totalPages, 10);
2776
2985
  let page = Math.min(total, positive(options.page, 1));
2777
2986
  const siblings = Math.min(10, Math.max(0, Number.isFinite(options.siblings) ? Math.floor(options.siblings) : 1));
2778
2987
  scope.attr(root, "data-mk-ready", "");
2779
- const render = () => {
2988
+ scope.attr(root, "data-mk-glide", "");
2989
+ const render = (animate = false) => {
2780
2990
  const hadFocus = pages.contains(document.activeElement);
2991
+ const before = new Map([...pages.querySelectorAll("[data-mk-page]")].map((button2) => [button2.dataset.mkPage, button2.offsetLeft]));
2781
2992
  const selected = /* @__PURE__ */ new Set([1, total]);
2782
2993
  for (let n = Math.max(1, page - siblings); n <= Math.min(total, page + siblings); n++) selected.add(n);
2783
2994
  const fragment = document.createDocumentFragment();
@@ -2799,8 +3010,23 @@ function createPagination(root, options = {}) {
2799
3010
  fragment.append(button2);
2800
3011
  last = n;
2801
3012
  }
2802
- pages.replaceChildren(fragment);
3013
+ pages.replaceChildren(indicator, fragment);
2803
3014
  if (hadFocus) pages.querySelector("[aria-current]")?.focus();
3015
+ const motion = animate && !reduced();
3016
+ if (motion) {
3017
+ for (const button2 of pages.querySelectorAll("[data-mk-page]")) {
3018
+ const from = before.get(button2.dataset.mkPage);
3019
+ if (from === void 0) keep(gsap.fromTo(button2, { opacity: 0, scale: 0.6, filter: "blur(4px)" }, { opacity: 1, scale: 1, filter: "blur(0px)", duration: 0.3, ease: EASE.pop, clearProps: "opacity,transform,filter" }));
3020
+ else if (from !== button2.offsetLeft) keep(gsap.fromTo(button2, { x: from - button2.offsetLeft }, { x: 0, duration: 0.35, ease: EASE.swatch, clearProps: "transform" }));
3021
+ }
3022
+ }
3023
+ const current3 = pages.querySelector("[aria-current]");
3024
+ if (current3) {
3025
+ const box = { x: current3.offsetLeft, width: current3.offsetWidth, height: current3.offsetHeight };
3026
+ if (motion && placed) keep(gsap.to(indicator, { ...box, duration: 0.4, ease: EASE.swatch }));
3027
+ else gsap.set(indicator, box);
3028
+ placed = true;
3029
+ }
2804
3030
  if (previous) scope.attr(previous, "disabled", page === 1 ? "" : null);
2805
3031
  if (next) scope.attr(next, "disabled", page === total ? "" : null);
2806
3032
  };
@@ -2810,7 +3036,7 @@ function createPagination(root, options = {}) {
2810
3036
  if (candidate === page) return;
2811
3037
  const focused = pages.contains(document.activeElement);
2812
3038
  page = candidate;
2813
- render();
3039
+ render(true);
2814
3040
  if (focused) pages.querySelector("[aria-current]")?.focus();
2815
3041
  if (notify) {
2816
3042
  options.onChange?.(page);
@@ -2820,6 +3046,8 @@ function createPagination(root, options = {}) {
2820
3046
  scope.on(root, "click", (event) => {
2821
3047
  const target = event.target.closest("button");
2822
3048
  if (!target || target.disabled) return;
3049
+ if (!reduced()) keep(press(target));
3050
+ if ((target === previous || target === next) && !reduced()) keep(gsap.fromTo(target, { x: target === next ? 4 : -4 }, { x: 0, duration: 0.45, ease: EASE.click, clearProps: "x" }));
2823
3051
  if (target === previous) setPage(page - 1);
2824
3052
  else if (target === next) setPage(page + 1);
2825
3053
  else if (target.dataset.mkPage) setPage(Number(target.dataset.mkPage));
@@ -2856,6 +3084,7 @@ function createPagination(root, options = {}) {
2856
3084
  var sequence = 0;
2857
3085
  var EDGE2 = 12;
2858
3086
  var GAP2 = 12;
3087
+ var FOLD_MS = 400;
2859
3088
  function createHoverCard(root, options = {}) {
2860
3089
  const trigger = root?.querySelector("[data-mk-hover-trigger]");
2861
3090
  const panel = root?.querySelector("[data-mk-hover-panel]");
@@ -2901,6 +3130,8 @@ function createHoverCard(root, options = {}) {
2901
3130
  if (left + box.width > view.width - EDGE2) shift = view.width - EDGE2 - box.width - left;
2902
3131
  if (left + shift < EDGE2) shift = EDGE2 - left;
2903
3132
  if (shift) root.style.setProperty("--mk-hover-shift", `${Math.round(shift)}px`);
3133
+ const target = trigger.getBoundingClientRect();
3134
+ root.style.setProperty("--mk-hover-origin-x", `${Math.round(target.left + target.width / 2 - (left + shift))}px`);
2904
3135
  };
2905
3136
  let pending = null;
2906
3137
  const schedulePlace = () => {
@@ -2915,13 +3146,33 @@ function createHoverCard(root, options = {}) {
2915
3146
  clearTimeout(timer2);
2916
3147
  timer2 = void 0;
2917
3148
  };
3149
+ let folding;
3150
+ const settleFold = () => {
3151
+ clearTimeout(folding);
3152
+ folding = void 0;
3153
+ panel.removeEventListener("animationend", settleFold);
3154
+ if (scope.disposed) return;
3155
+ scope.attr(root, "data-mk-closing", null);
3156
+ if (!opened) scope.attr(panel, "hidden", "");
3157
+ };
3158
+ scope.add(() => {
3159
+ clearTimeout(folding);
3160
+ panel.removeEventListener("animationend", settleFold);
3161
+ });
2918
3162
  const set = (value) => {
2919
3163
  cancel();
2920
3164
  if (scope.disposed) return;
2921
3165
  const changed = value !== opened;
2922
3166
  opened = value;
2923
3167
  scope.attr(trigger, "aria-expanded", String(value));
2924
- scope.attr(panel, "hidden", value ? null : "");
3168
+ if (value) {
3169
+ if (folding !== void 0) settleFold();
3170
+ scope.attr(panel, "hidden", null);
3171
+ } else if (changed && !reduced() && root.dataset.mkInput !== "keyboard" && !panel.hidden) {
3172
+ scope.attr(root, "data-mk-closing", "");
3173
+ panel.addEventListener("animationend", settleFold);
3174
+ folding = setTimeout(settleFold, FOLD_MS);
3175
+ } else if (folding === void 0) scope.attr(panel, "hidden", "");
2925
3176
  scope.attr(root, "data-mk-open", value ? "" : null);
2926
3177
  if (value && changed) {
2927
3178
  scope.attr(root, "data-mk-input", pointerInput ? "pointer" : "keyboard");
@@ -4174,7 +4425,7 @@ function createSlotPicker(root, options = {}) {
4174
4425
  ctx.add(() => flowIn(fresh, { target: ".mk-slot-picker__time", style: 2, startScale: 0.7, blur: 32, duration: 0.3, stagger: 0.02, ease: "mk-slot-in" }));
4175
4426
  }
4176
4427
  };
4177
- const resolve = (d) => {
4428
+ const resolve2 = (d) => {
4178
4429
  const source = slots;
4179
4430
  if (Array.isArray(source)) return source;
4180
4431
  if (typeof source === "function") return source(d);
@@ -4190,7 +4441,7 @@ function createSlotPicker(root, options = {}) {
4190
4441
  const mine = ++request;
4191
4442
  let result;
4192
4443
  try {
4193
- result = resolve(date);
4444
+ result = resolve2(date);
4194
4445
  } catch {
4195
4446
  result = [];
4196
4447
  }
@@ -4209,324 +4460,136 @@ function createSlotPicker(root, options = {}) {
4209
4460
  renderTimes("ready", 0);
4210
4461
  }
4211
4462
  }
4212
- );
4213
- } else {
4214
- times = clean(result);
4215
- if (time2 && !times.includes(time2)) time2 = null;
4216
- renderTimes("ready", direction);
4217
- }
4218
- };
4219
- const syncHeading = () => {
4220
- if (!heading) return;
4221
- if (date) {
4222
- heading.textContent = labels.heading(date);
4223
- if (!heading.hasAttribute("data-mk-shown")) scope.attr(heading, "data-mk-shown", "");
4224
- }
4225
- };
4226
- const emit = () => {
4227
- const key2 = date ? dayKey(date) : "";
4228
- const value = date && time2 ? `${key2}T${time2}` : null;
4229
- if (output) {
4230
- output.value = value ?? "";
4231
- output.dispatchEvent(new Event("input", { bubbles: true }));
4232
- output.dispatchEvent(new Event("change", { bubbles: true }));
4233
- }
4234
- if (date && time2 && value) {
4235
- const detail = { date, time: time2, key: key2, value };
4236
- options.onChange?.(detail);
4237
- root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail }));
4238
- }
4239
- };
4240
- const selectDate = (input, notify = true) => {
4241
- if (scope.disposed) return;
4242
- const d = toDate(input);
4243
- if (disabled(d)) return;
4244
- const direction = date ? Math.sign(d.getTime() - date.getTime()) : 0;
4245
- if (sameDay(d, date)) return;
4246
- date = d;
4247
- time2 = null;
4248
- focusDay = d;
4249
- if (!sameMonth(d, month)) {
4250
- const dir = d > month ? 1 : -1;
4251
- month = d;
4252
- renderDays(dir);
4253
- }
4254
- daysHost.querySelectorAll('[role="gridcell"]').forEach((cell) => {
4255
- const b = cell.querySelector("[data-mk-slot-day]");
4256
- if (b) {
4257
- cell.setAttribute("aria-selected", String(b.dataset.mkSlotDay === dayKey(d)));
4258
- b.tabIndex = b.dataset.mkSlotDay === dayKey(d) ? 0 : -1;
4259
- }
4260
- });
4261
- syncHeading();
4262
- load(direction);
4263
- if (notify) {
4264
- options.onDateChange?.(d);
4265
- emit();
4266
- }
4267
- };
4268
- const selectTime = (t, notify = true) => {
4269
- if (scope.disposed || !date) return;
4270
- if (t !== null && !times.includes(t)) return;
4271
- time2 = t;
4272
- timesHost.querySelectorAll("[data-mk-slot-time]").forEach((b) => {
4273
- b.setAttribute("aria-checked", String(b.dataset.mkSlotTime === t));
4274
- b.tabIndex = (t ? b.dataset.mkSlotTime === t : b === timesHost.querySelector("[data-mk-slot-time]")) ? 0 : -1;
4275
- });
4276
- if (notify) emit();
4277
- };
4278
- scope.on(root, "click", (e) => {
4279
- const target = e.target.closest("button");
4280
- if (!target || target.disabled || !root.contains(target)) return;
4281
- if (target === prev) moveFocus(addMonths(month, -1), false);
4282
- else if (target === next) moveFocus(addMonths(month, 1), false);
4283
- else if (target.dataset.mkSlotDay) selectDate(target.dataset.mkSlotDay);
4284
- else if (target.dataset.mkSlotTime) selectTime(target.dataset.mkSlotTime);
4285
- });
4286
- scope.on(daysHost, "keydown", (e) => {
4287
- const event = e;
4288
- const key2 = event.target.dataset?.mkSlotDay;
4289
- if (!key2) return;
4290
- const d = toDate(key2);
4291
- const to = {
4292
- ArrowLeft: () => addDays(d, -1),
4293
- ArrowRight: () => addDays(d, 1),
4294
- ArrowUp: () => addDays(d, -7),
4295
- ArrowDown: () => addDays(d, 7),
4296
- Home: () => startOfWeek(d, firstDay),
4297
- End: () => addDays(startOfWeek(d, firstDay), 6),
4298
- PageUp: () => addMonths(d, -1),
4299
- PageDown: () => addMonths(d, 1)
4300
- }[event.key]?.();
4301
- if (!to) return;
4302
- event.preventDefault();
4303
- moveFocus(to, true);
4304
- });
4305
- scope.on(timesHost, "keydown", (e) => {
4306
- const event = e;
4307
- const current3 = event.target.dataset?.mkSlotTime;
4308
- if (!current3) return;
4309
- const i = times.indexOf(current3);
4310
- const to = { ArrowRight: i + 1, ArrowDown: i + 1, ArrowLeft: i - 1, ArrowUp: i - 1, Home: 0, End: times.length - 1 }[event.key];
4311
- if (to === void 0) return;
4312
- event.preventDefault();
4313
- const t = times[(to + times.length) % times.length];
4314
- selectTime(t);
4315
- timesHost.querySelector(`[data-mk-slot-time="${t}"]`)?.focus();
4316
- });
4317
- renderDays(0);
4318
- if (date) {
4319
- syncHeading();
4320
- load(0);
4321
- if (time2 && !times.includes(time2)) time2 = null;
4322
- } else renderTimes("placeholder", 0);
4323
- return {
4324
- selectDate: (d) => selectDate(d),
4325
- selectTime: (t) => selectTime(t),
4326
- setSlots(source) {
4327
- if (scope.disposed) return;
4328
- slots = fromJson(source) ?? [];
4329
- load(0);
4330
- },
4331
- get date() {
4332
- return date;
4333
- },
4334
- get time() {
4335
- return time2;
4336
- },
4337
- get value() {
4338
- return date && time2 ? `${dayKey(date)}T${time2}` : null;
4339
- },
4340
- destroy: () => scope.dispose()
4341
- };
4342
- }
4343
-
4344
- // src/motion/micro.ts
4345
- var list2 = (targets) => !targets ? [] : targets instanceof Element ? [targets] : [...targets];
4346
- var live = () => {
4347
- registerMotion();
4348
- return !reduced();
4349
- };
4350
- function press(el5) {
4351
- if (!el5 || !live()) return null;
4352
- gsap.killTweensOf(el5, "scaleX,scaleY");
4353
- return gsap.timeline({
4354
- onComplete: () => {
4355
- gsap.set(el5, { clearProps: "scale,transform" });
4356
- }
4357
- }).to(el5, { scaleX: 0.95, scaleY: 0.9, duration: 0.1, ease: "power2.out" }).to(el5, { scaleX: 1, scaleY: 1, duration: 0.5, ease: EASE.click });
4358
- }
4359
- function blurIn(targets, { from = "rise", stagger = 0.05, delay = 0, duration } = {}) {
4360
- const items = list2(targets);
4361
- if (!items.length || !live()) return null;
4362
- const start = from === "pop" ? { opacity: 0, scale: 0.7, filter: "blur(32px)" } : from === "soft" ? { opacity: 0, scale: 0.96, filter: "blur(16px)" } : { opacity: 0, y: -20, filter: "blur(16px)" };
4363
- return gsap.fromTo(items, start, {
4364
- opacity: 1,
4365
- y: 0,
4366
- scale: 1,
4367
- filter: "blur(0px)",
4368
- duration: duration ?? (from === "pop" ? 0.3 : 0.5),
4369
- ease: from === "pop" ? EASE.pop : "power2.out",
4370
- stagger,
4371
- delay,
4372
- clearProps: "opacity,transform,filter"
4373
- });
4374
- }
4375
- function blurOut(targets, { to = "up", onComplete } = {}) {
4376
- const items = list2(targets);
4377
- if (!items.length) return null;
4378
- if (!live()) {
4379
- onComplete?.();
4380
- return null;
4381
- }
4382
- const end = to === "left" ? { x: -64 } : to === "down" ? { y: 24 } : { y: -20 };
4383
- return gsap.to(items, { ...end, opacity: 0, filter: "blur(16px)", duration: 0.5, ease: "power2.out", onComplete });
4384
- }
4385
- function collapse(el5, { onComplete } = {}) {
4386
- if (!el5) return null;
4387
- if (!live()) {
4388
- onComplete?.();
4389
- return null;
4390
- }
4391
- return gsap.to(el5, {
4392
- height: 0,
4393
- paddingTop: 0,
4394
- paddingBottom: 0,
4395
- marginTop: 0,
4396
- marginBottom: 0,
4397
- opacity: 0,
4398
- filter: "blur(16px)",
4399
- overflow: "hidden",
4400
- duration: 0.25,
4401
- ease: "power2.in",
4402
- onComplete
4403
- });
4404
- }
4405
- function shake(el5, distance = 4) {
4406
- if (!el5 || !live()) return null;
4407
- gsap.killTweensOf(el5, "x");
4408
- return gsap.to(el5, {
4409
- keyframes: { x: [0, -distance, distance, -distance, 0] },
4410
- duration: 0.5,
4411
- ease: EASE.shake,
4412
- clearProps: "x,transform"
4413
- });
4414
- }
4415
- function ringPulse(el5, color = "var(--mk-accent-soft)") {
4416
- if (!el5 || !live()) return null;
4417
- const before = { color: el5.style.outlineColor, style: el5.style.outlineStyle, offset: el5.style.outlineOffset };
4418
- el5.style.outlineColor = color;
4419
- el5.style.outlineStyle = "solid";
4420
- el5.style.outlineOffset = "-4px";
4421
- const restore = () => {
4422
- el5.style.outlineColor = before.color;
4423
- el5.style.outlineStyle = before.style;
4424
- el5.style.outlineOffset = before.offset;
4425
- el5.style.removeProperty("outline-width");
4426
- if (el5.getAttribute("style") === "") el5.removeAttribute("style");
4427
- };
4428
- return gsap.fromTo(el5, { outlineWidth: 0 }, { keyframes: { outlineWidth: [0, 4, 0] }, duration: 1, ease: "power1.inOut", onComplete: restore, onInterrupt: restore });
4429
- }
4430
- function burst(origin, { count = 7, distance = 28, colors = ["var(--mk-accent)"], ring = true, size = 6 } = {}) {
4431
- if (!origin || !live()) return null;
4432
- const layer = document.createElement("span");
4433
- layer.setAttribute("aria-hidden", "true");
4434
- layer.dataset.mkBurst = "";
4435
- Object.assign(layer.style, { position: "absolute", inset: "0", pointerEvents: "none", overflow: "visible", display: "grid", placeItems: "center" });
4436
- const positioned = getComputedStyle(origin).position !== "static";
4437
- const previousPosition = origin.style.position;
4438
- if (!positioned) origin.style.position = "relative";
4439
- origin.append(layer);
4440
- const cleanup = () => {
4441
- layer.remove();
4442
- if (!positioned) origin.style.position = previousPosition;
4443
- if (origin.getAttribute("style") === "") origin.removeAttribute("style");
4444
- };
4445
- const timeline = gsap.timeline({ onComplete: cleanup, onInterrupt: cleanup });
4446
- if (ring) {
4447
- const circle = document.createElement("span");
4448
- Object.assign(circle.style, { position: "absolute", width: "100%", aspectRatio: "1", borderRadius: "50%", border: `2px solid ${colors[0]}` });
4449
- layer.append(circle);
4450
- timeline.fromTo(circle, { scale: 0.3, opacity: 0.9 }, { scale: 1.6, opacity: 0, duration: 0.5, ease: "power2.out" }, 0);
4451
- }
4452
- for (let i = 0; i < count; i++) {
4453
- const angle2 = i / count * Math.PI * 2 - Math.PI / 2;
4454
- for (const [k, scale] of [[0, 1], [1, 0.6]]) {
4455
- const dot = document.createElement("span");
4456
- Object.assign(dot.style, {
4457
- position: "absolute",
4458
- width: `${size * scale}px`,
4459
- height: `${size * scale}px`,
4460
- borderRadius: "50%",
4461
- background: colors[(i + k) % colors.length]
4462
- });
4463
- layer.append(dot);
4464
- const reach = distance * (k ? 0.72 : 1);
4465
- const turn = k ? 0.32 : 0;
4466
- timeline.fromTo(
4467
- dot,
4468
- { x: 0, y: 0, scale: 0, opacity: 1 },
4469
- { x: Math.cos(angle2 + turn) * reach, y: Math.sin(angle2 + turn) * reach, scale: 1, duration: 0.45, ease: "power3.out" },
4470
- 0.05
4471
- );
4472
- timeline.to(dot, { scale: 0, opacity: 0, duration: 0.3, ease: "power2.in" }, 0.38);
4473
- }
4474
- }
4475
- return timeline;
4476
- }
4477
- var rolling = /* @__PURE__ */ new WeakMap();
4478
- function rollDigits(el5, text, direction = 1, duration = 0.5) {
4479
- if (!el5) return null;
4480
- rolling.get(el5)?.progress(1).kill();
4481
- rolling.delete(el5);
4482
- const previous = el5.textContent ?? "";
4483
- if (previous === text || !live()) {
4484
- el5.textContent = text;
4485
- return null;
4486
- }
4487
- const width = Math.max(previous.length, text.length);
4488
- const oldChars = previous.padStart(width, " ");
4489
- const newChars = text.padStart(width, " ");
4490
- el5.textContent = "";
4491
- const label = document.createElement("span");
4492
- label.className = "mk-sr-only";
4493
- label.textContent = text;
4494
- const visual = document.createElement("span");
4495
- visual.setAttribute("aria-hidden", "true");
4496
- visual.style.display = "inline-flex";
4497
- const moving = [];
4498
- const padding = Math.min(width - previous.length, width - text.length);
4499
- for (let i = padding; i < width; i++) {
4500
- const before = oldChars[i];
4501
- const after = newChars[i];
4502
- const cell = document.createElement("span");
4503
- Object.assign(cell.style, { position: "relative", display: "inline-block", overflow: "hidden", whiteSpace: "pre" });
4504
- const next = document.createElement("span");
4505
- next.style.display = "inline-block";
4506
- next.textContent = after;
4507
- cell.append(next);
4508
- if (before !== after) {
4509
- const old = document.createElement("span");
4510
- Object.assign(old.style, { position: "absolute", left: "0", top: "0", display: "inline-block" });
4511
- old.textContent = before;
4512
- cell.append(old);
4513
- moving.push([old, next]);
4463
+ );
4464
+ } else {
4465
+ times = clean(result);
4466
+ if (time2 && !times.includes(time2)) time2 = null;
4467
+ renderTimes("ready", direction);
4514
4468
  }
4515
- visual.append(cell);
4516
- }
4517
- el5.append(label, visual);
4518
- const timeline = gsap.timeline({
4519
- onComplete: () => {
4520
- el5.textContent = text;
4521
- rolling.delete(el5);
4469
+ };
4470
+ const syncHeading = () => {
4471
+ if (!heading) return;
4472
+ if (date) {
4473
+ heading.textContent = labels.heading(date);
4474
+ if (!heading.hasAttribute("data-mk-shown")) scope.attr(heading, "data-mk-shown", "");
4475
+ }
4476
+ };
4477
+ const emit = () => {
4478
+ const key2 = date ? dayKey(date) : "";
4479
+ const value = date && time2 ? `${key2}T${time2}` : null;
4480
+ if (output) {
4481
+ output.value = value ?? "";
4482
+ output.dispatchEvent(new Event("input", { bubbles: true }));
4483
+ output.dispatchEvent(new Event("change", { bubbles: true }));
4484
+ }
4485
+ if (date && time2 && value) {
4486
+ const detail = { date, time: time2, key: key2, value };
4487
+ options.onChange?.(detail);
4488
+ root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail }));
4522
4489
  }
4490
+ };
4491
+ const selectDate = (input, notify = true) => {
4492
+ if (scope.disposed) return;
4493
+ const d = toDate(input);
4494
+ if (disabled(d)) return;
4495
+ const direction = date ? Math.sign(d.getTime() - date.getTime()) : 0;
4496
+ if (sameDay(d, date)) return;
4497
+ date = d;
4498
+ time2 = null;
4499
+ focusDay = d;
4500
+ if (!sameMonth(d, month)) {
4501
+ const dir = d > month ? 1 : -1;
4502
+ month = d;
4503
+ renderDays(dir);
4504
+ }
4505
+ daysHost.querySelectorAll('[role="gridcell"]').forEach((cell) => {
4506
+ const b = cell.querySelector("[data-mk-slot-day]");
4507
+ if (b) {
4508
+ cell.setAttribute("aria-selected", String(b.dataset.mkSlotDay === dayKey(d)));
4509
+ b.tabIndex = b.dataset.mkSlotDay === dayKey(d) ? 0 : -1;
4510
+ }
4511
+ });
4512
+ syncHeading();
4513
+ load(direction);
4514
+ if (notify) {
4515
+ options.onDateChange?.(d);
4516
+ emit();
4517
+ }
4518
+ };
4519
+ const selectTime = (t, notify = true) => {
4520
+ if (scope.disposed || !date) return;
4521
+ if (t !== null && !times.includes(t)) return;
4522
+ time2 = t;
4523
+ timesHost.querySelectorAll("[data-mk-slot-time]").forEach((b) => {
4524
+ b.setAttribute("aria-checked", String(b.dataset.mkSlotTime === t));
4525
+ b.tabIndex = (t ? b.dataset.mkSlotTime === t : b === timesHost.querySelector("[data-mk-slot-time]")) ? 0 : -1;
4526
+ });
4527
+ if (notify) emit();
4528
+ };
4529
+ scope.on(root, "click", (e) => {
4530
+ const target = e.target.closest("button");
4531
+ if (!target || target.disabled || !root.contains(target)) return;
4532
+ if (target === prev) moveFocus(addMonths(month, -1), false);
4533
+ else if (target === next) moveFocus(addMonths(month, 1), false);
4534
+ else if (target.dataset.mkSlotDay) selectDate(target.dataset.mkSlotDay);
4535
+ else if (target.dataset.mkSlotTime) selectTime(target.dataset.mkSlotTime);
4523
4536
  });
4524
- moving.forEach(([old, next], i) => {
4525
- timeline.to(old, { yPercent: -100 * direction, opacity: 0, filter: "blur(4px)", duration, ease: EASE.signature }, i * 0.03);
4526
- timeline.fromTo(next, { yPercent: 100 * direction, opacity: 0, filter: "blur(4px)" }, { yPercent: 0, opacity: 1, filter: "blur(0px)", duration, ease: EASE.signature }, i * 0.03);
4537
+ scope.on(daysHost, "keydown", (e) => {
4538
+ const event = e;
4539
+ const key2 = event.target.dataset?.mkSlotDay;
4540
+ if (!key2) return;
4541
+ const d = toDate(key2);
4542
+ const to = {
4543
+ ArrowLeft: () => addDays(d, -1),
4544
+ ArrowRight: () => addDays(d, 1),
4545
+ ArrowUp: () => addDays(d, -7),
4546
+ ArrowDown: () => addDays(d, 7),
4547
+ Home: () => startOfWeek(d, firstDay),
4548
+ End: () => addDays(startOfWeek(d, firstDay), 6),
4549
+ PageUp: () => addMonths(d, -1),
4550
+ PageDown: () => addMonths(d, 1)
4551
+ }[event.key]?.();
4552
+ if (!to) return;
4553
+ event.preventDefault();
4554
+ moveFocus(to, true);
4527
4555
  });
4528
- rolling.set(el5, timeline);
4529
- return timeline;
4556
+ scope.on(timesHost, "keydown", (e) => {
4557
+ const event = e;
4558
+ const current3 = event.target.dataset?.mkSlotTime;
4559
+ if (!current3) return;
4560
+ const i = times.indexOf(current3);
4561
+ const to = { ArrowRight: i + 1, ArrowDown: i + 1, ArrowLeft: i - 1, ArrowUp: i - 1, Home: 0, End: times.length - 1 }[event.key];
4562
+ if (to === void 0) return;
4563
+ event.preventDefault();
4564
+ const t = times[(to + times.length) % times.length];
4565
+ selectTime(t);
4566
+ timesHost.querySelector(`[data-mk-slot-time="${t}"]`)?.focus();
4567
+ });
4568
+ renderDays(0);
4569
+ if (date) {
4570
+ syncHeading();
4571
+ load(0);
4572
+ if (time2 && !times.includes(time2)) time2 = null;
4573
+ } else renderTimes("placeholder", 0);
4574
+ return {
4575
+ selectDate: (d) => selectDate(d),
4576
+ selectTime: (t) => selectTime(t),
4577
+ setSlots(source) {
4578
+ if (scope.disposed) return;
4579
+ slots = fromJson(source) ?? [];
4580
+ load(0);
4581
+ },
4582
+ get date() {
4583
+ return date;
4584
+ },
4585
+ get time() {
4586
+ return time2;
4587
+ },
4588
+ get value() {
4589
+ return date && time2 ? `${dayKey(date)}T${time2}` : null;
4590
+ },
4591
+ destroy: () => scope.dispose()
4592
+ };
4530
4593
  }
4531
4594
 
4532
4595
  // src/components/attachment/engine.ts
@@ -6232,6 +6295,22 @@ function barPath(x, width, base, end, rounded) {
6232
6295
  if (!r) return `M${round(x)},${round(base)}V${round(end)}H${round(x + width)}V${round(base)}Z`;
6233
6296
  return `M${round(x)},${round(base)}V${round(end + dir * r)}Q${round(x)},${round(end)} ${round(x + r)},${round(end)}H${round(x + width - r)}Q${round(x + width)},${round(end)} ${round(x + width)},${round(end + dir * r)}V${round(base)}Z`;
6234
6297
  }
6298
+ function pillPath(x, width, a, b) {
6299
+ const top = Math.min(a, b), bottom = Math.max(a, b);
6300
+ const r = Math.min(width / 2, (bottom - top) / 2);
6301
+ return `M${round(x + r)},${round(top)}H${round(x + width - r)}Q${round(x + width)},${round(top)} ${round(x + width)},${round(top + r)}V${round(bottom - r)}Q${round(x + width)},${round(bottom)} ${round(x + width - r)},${round(bottom)}H${round(x + r)}Q${round(x)},${round(bottom)} ${round(x)},${round(bottom - r)}V${round(top + r)}Q${round(x)},${round(top)} ${round(x + r)},${round(top)}Z`;
6302
+ }
6303
+ function linePath(points, smooth) {
6304
+ if (!points.length) return "";
6305
+ let path = `M${round(points[0][0])},${round(points[0][1])}`;
6306
+ const slopes = points.slice(1).map((point, i) => (point[1] - points[i][1]) / (point[0] - points[i][0] || 1));
6307
+ const tangents = points.map((_, i) => i === 0 ? slopes[0] : i === points.length - 1 ? slopes[i - 1] : slopes[i - 1] * slopes[i] <= 0 ? 0 : 2 * slopes[i - 1] * slopes[i] / (slopes[i - 1] + slopes[i]));
6308
+ for (let i = 1; i < points.length; i++) {
6309
+ const [x0, y0] = points[i - 1], [x, y] = points[i], dx = (x - x0) / 3;
6310
+ path += smooth ? `C${round(x0 + dx)},${round(y0 + tangents[i - 1] * dx)} ${round(x - dx)},${round(y - tangents[i] * dx)} ${round(x)},${round(y)}` : `L${round(x)},${round(y)}`;
6311
+ }
6312
+ return path;
6313
+ }
6235
6314
  function modelOf(options) {
6236
6315
  const fromPoints = options.points?.length ? { labels: options.points.map((point) => String(point.label)), series: [{ name: options.label ?? "", values: options.points.map((point) => point.value) }] } : null;
6237
6316
  const labels = fromPoints?.labels ?? (options.labels ?? []).map(String);
@@ -6244,7 +6323,9 @@ function modelOf(options) {
6244
6323
  name: String(series2.name ?? ""),
6245
6324
  values: Array.from({ length: count }, (_, j) => finite3(series2.values[j]) ? series2.values[j] : null),
6246
6325
  color: series2.color ?? (mono ? "var(--mk-chart-mono)" : i < SLOTS ? `var(--mk-chart-${i + 1})` : "var(--mk-chart-other)"),
6247
- dash: series2.dash
6326
+ dash: series2.dash,
6327
+ type: series2.type,
6328
+ lowerValues: series2.lowerValues ? Array.from({ length: count }, (_, j) => finite3(series2.lowerValues[j]) ? series2.lowerValues[j] : null) : void 0
6248
6329
  }));
6249
6330
  return { labels: fullLabels, series };
6250
6331
  }
@@ -6312,7 +6393,9 @@ function createChart(root, initial = {}) {
6312
6393
  if (options.formatValue) return options.formatValue(value);
6313
6394
  return new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(value);
6314
6395
  };
6315
- const type = () => options.type === "bar" || options.type === "area" ? options.type : "line";
6396
+ const type = () => options.type === "bar" || options.type === "area" || options.type === "composed" ? options.type : "line";
6397
+ const seriesType = (index) => type() === "composed" ? model.series[index].type ?? "line" : type();
6398
+ const hasBars = () => model.series.some((_, index) => seriesType(index) === "bar");
6316
6399
  const stacked = () => type() === "bar" && Boolean(options.stacked) && model.series.length > 1;
6317
6400
  const hasData = () => model.labels.length > 0 && model.series.some((series) => series.values.some(finite3));
6318
6401
  const totalsOf = (values, index) => {
@@ -6327,6 +6410,13 @@ function createChart(root, initial = {}) {
6327
6410
  return { up, down };
6328
6411
  };
6329
6412
  const targetValues = () => model.series.map((series) => series.values);
6413
+ const lowerValues = () => model.series.map((series) => series.lowerValues ?? []);
6414
+ const rangeText = (series, index) => {
6415
+ const value = series.values[index];
6416
+ const lower = series.lowerValues?.[index];
6417
+ if (!finite3(value)) return "\u2014";
6418
+ return finite3(lower) ? `${format(lower)} \u2013 ${format(value)}` : format(value);
6419
+ };
6330
6420
  const totals = (index) => totalsOf(targetValues(), index);
6331
6421
  const domainOf = (values) => {
6332
6422
  let lo = 0;
@@ -6344,6 +6434,12 @@ function createChart(root, initial = {}) {
6344
6434
  lo = Math.min(lo, value);
6345
6435
  }
6346
6436
  }
6437
+ for (const list3 of lowerValues()) {
6438
+ if (finite3(list3[i])) {
6439
+ lo = Math.min(lo, list3[i]);
6440
+ hi = Math.max(hi, list3[i]);
6441
+ }
6442
+ }
6347
6443
  });
6348
6444
  if (hi === lo) hi = lo + 1;
6349
6445
  const step = niceStep((hi - lo) / 4);
@@ -6389,7 +6485,7 @@ function createChart(root, initial = {}) {
6389
6485
  for (const series of model.series) {
6390
6486
  const td = document.createElement("td");
6391
6487
  const value = series.values[i];
6392
- td.textContent = finite3(value) ? format(value) : "\u2014";
6488
+ td.textContent = rangeText(series, i);
6393
6489
  row.append(td);
6394
6490
  }
6395
6491
  if (stacked()) {
@@ -6407,11 +6503,11 @@ function createChart(root, initial = {}) {
6407
6503
  const show = options.legend ?? model.series.length > 1;
6408
6504
  legend.hidden = !show || !hasData();
6409
6505
  if (legend.hidden) return;
6410
- for (const series of model.series) {
6506
+ for (const [index, series] of model.series.entries()) {
6411
6507
  const item = document.createElement("li");
6412
6508
  const swatch = document.createElement("span");
6413
6509
  swatch.dataset.mkChartSwatch = "";
6414
- swatch.dataset.mkType = type();
6510
+ swatch.dataset.mkType = seriesType(index);
6415
6511
  swatch.style.background = series.color;
6416
6512
  swatch.style.color = series.color;
6417
6513
  if (series.dash) swatch.dataset.mkDash = "";
@@ -6427,19 +6523,19 @@ function createChart(root, initial = {}) {
6427
6523
  for (let i = list3.length - 1; i >= 0; i--) if (finite3(list3[i])) return i;
6428
6524
  return -1;
6429
6525
  };
6430
- const paint = (values, lo, hi, step) => {
6526
+ const paint = (values, lo, hi, step, lower = lowerValues()) => {
6431
6527
  canvas.replaceChildren();
6432
6528
  const width = Math.max(120, Math.round(plot.clientWidth || root.clientWidth || 600));
6433
6529
  const height = Math.max(80, Math.round(finite3(options.height) ? options.height : 240));
6434
6530
  canvas.setAttribute("viewBox", `0 0 ${width} ${height}`);
6435
6531
  canvas.setAttribute("width", String(width));
6436
6532
  canvas.setAttribute("height", String(height));
6437
- const bar = type() === "bar";
6533
+ const bar = hasBars();
6438
6534
  const axis = Boolean(options.axis);
6439
6535
  const ticks = [];
6440
6536
  for (let t = lo; t <= hi + step / 2; t += step) ticks.push(Number(t.toPrecision(12)));
6441
6537
  const tickText = ticks.map(format);
6442
- const withEnd = !bar && options.endLabel !== false && lastPoint(values[0]) >= 0;
6538
+ const withEnd = seriesType(0) !== "bar" && options.endLabel !== false && lastPoint(values[0]) >= 0;
6443
6539
  const left = axis ? Math.min(96, Math.max(28, Math.max(...tickText.map((text) => text.length)) * 7 + 12)) : 4;
6444
6540
  const top = 16;
6445
6541
  const right = withEnd ? Math.min(120, Math.max(48, format(values[0][lastPoint(values[0])]).length * 7.5 + 28)) : 8;
@@ -6452,6 +6548,7 @@ function createChart(root, initial = {}) {
6452
6548
  const slot = plotW / n;
6453
6549
  const xs = model.labels.map((_, i) => bar ? left + slot * (i + 0.5) : n === 1 ? left + plotW / 2 : left + plotW * i / (n - 1));
6454
6550
  geometry = { width, height, top, bottom: top + plotH, left, right: width - right, xs, y, base };
6551
+ shown4 = { values, lower, lo, hi, type: type(), stacked: stacked() };
6455
6552
  const grid = svg("g", { "data-mk-part": "grid" });
6456
6553
  if (!axis) {
6457
6554
  const zero = svg("line", { x1: left, x2: width - right, y1: round(base), y2: round(base) });
@@ -6488,11 +6585,55 @@ function createChart(root, initial = {}) {
6488
6585
  const marks = svg("g", { "data-mk-part": "series" });
6489
6586
  const defs = svg("defs");
6490
6587
  if (bar) {
6491
- const groups = stacked() ? 1 : model.series.length;
6492
- const barWidth = Math.max(2, Math.min(BAR_MAX, (slot * 0.62 - GAP3 * (groups - 1)) / groups));
6588
+ const barIndices = model.series.flatMap((_, index) => seriesType(index) === "bar" ? [index] : []);
6589
+ const groups = stacked() ? 1 : barIndices.length;
6590
+ const maxWidth = finite3(options.barWidth) ? Math.max(2, Math.min(96, options.barWidth)) : BAR_MAX;
6591
+ const barWidth = Math.max(2, Math.min(maxWidth, (slot * 0.62 - GAP3 * (groups - 1)) / groups));
6592
+ const pill2 = options.barStyle === "pill";
6593
+ const trackLayer = svg("g", { "data-mk-part": "bar-tracks" });
6594
+ canvas.append(trackLayer);
6595
+ if (options.barFill && options.barFill !== "solid") {
6596
+ model.series.forEach((series, k) => {
6597
+ const gradient = svg("linearGradient", { id: `${uid2}-bar-${k}`, x1: 0, y1: 0, x2: 0, y2: 1 });
6598
+ for (const [offset, opacity] of [["0", "1"], ["1", "0.4"]]) {
6599
+ const stop2 = svg("stop", { offset });
6600
+ stop2.style.stopColor = series.color;
6601
+ stop2.style.stopOpacity = opacity;
6602
+ gradient.append(stop2);
6603
+ }
6604
+ defs.append(gradient);
6605
+ });
6606
+ const hatch = svg("pattern", { id: `${uid2}-hatch`, patternUnits: "userSpaceOnUse", width: 6, height: 6, patternTransform: "rotate(35)" });
6607
+ const ground = svg("rect", { width: 6, height: 6 });
6608
+ ground.style.fill = "var(--mk-chart-track)";
6609
+ const stripe = svg("line", { x1: 0, x2: 0, y1: 0, y2: 6 });
6610
+ stripe.style.stroke = "var(--mk-chart-grid)";
6611
+ stripe.style.strokeWidth = "2";
6612
+ hatch.append(ground, stripe);
6613
+ defs.append(hatch);
6614
+ }
6615
+ const fillBar = (path, k, index) => {
6616
+ const fill = options.barFill && options.barFill !== "solid" ? `url(#${uid2}-bar-${k})` : model.series[k].color;
6617
+ path.style.setProperty("--mk-bar-fill", fill);
6618
+ path.style.fill = options.barFill === "spotlight" && index !== (selected ?? n - 1) ? `url(#${uid2}-hatch)` : fill;
6619
+ };
6620
+ const addTrack = (x) => {
6621
+ if (!options.barTrack) return;
6622
+ const path = svg("path", { d: pillPath(x, barWidth, top, base), "data-mk-part": "bar-track" });
6623
+ trackLayer.append(path);
6624
+ };
6493
6625
  const totalsLayer = svg("g", { "data-mk-part": "totals" });
6494
6626
  model.labels.forEach((_, i) => {
6495
6627
  if (stacked()) {
6628
+ const clipId = `${uid2}-stack-${i}`;
6629
+ if (pill2) {
6630
+ const sum = totalsOf(values, i);
6631
+ const clip = svg("clipPath", { id: clipId });
6632
+ if (sum.up) clip.append(svg("path", { d: pillPath(xs[i] - barWidth / 2, barWidth, base, y(sum.up)) }));
6633
+ if (sum.down) clip.append(svg("path", { d: pillPath(xs[i] - barWidth / 2, barWidth, base, y(sum.down)) }));
6634
+ defs.append(clip);
6635
+ }
6636
+ addTrack(xs[i] - barWidth / 2);
6496
6637
  let up = 0;
6497
6638
  let down = 0;
6498
6639
  const outer = { up: -1, down: -1 };
@@ -6511,8 +6652,9 @@ function createChart(root, initial = {}) {
6511
6652
  const start = y(from) + (from !== 0 ? value > 0 ? -GAP3 : GAP3 : 0);
6512
6653
  const end = y(to);
6513
6654
  if (value > 0 && end >= start || value < 0 && end <= start) return;
6514
- const path = svg("path", { d: barPath(xs[i] - barWidth / 2, barWidth, start, end, k === (value > 0 ? outer.up : outer.down)), "data-mk-index": i, "data-mk-series": k });
6515
- path.style.fill = model.series[k].color;
6655
+ const path = svg("path", { d: barPath(xs[i] - barWidth / 2, barWidth, start, end, !pill2 && k === (value > 0 ? outer.up : outer.down)), "data-mk-part": "bar", "data-mk-index": i, "data-mk-series": k });
6656
+ if (pill2) path.setAttribute("clip-path", `url(#${clipId})`);
6657
+ fillBar(path, k, i);
6516
6658
  marks.append(path);
6517
6659
  });
6518
6660
  if (slot >= 22 && up > 0) {
@@ -6524,30 +6666,35 @@ function createChart(root, initial = {}) {
6524
6666
  } else {
6525
6667
  const groupWidth = groups * barWidth + GAP3 * (groups - 1);
6526
6668
  values.forEach((list3, k) => {
6669
+ if (seriesType(k) !== "bar") return;
6527
6670
  const value = list3[i];
6671
+ const x = xs[i] - groupWidth / 2 + barIndices.indexOf(k) * (barWidth + GAP3);
6672
+ addTrack(x);
6528
6673
  if (!finite3(value) || value === 0) return;
6529
- const x = xs[i] - groupWidth / 2 + k * (barWidth + GAP3);
6530
- const path = svg("path", { d: barPath(x, barWidth, base, y(value), true), "data-mk-index": i, "data-mk-series": k });
6531
- path.style.fill = model.series[k].color;
6674
+ const path = svg("path", { d: pill2 ? pillPath(x, barWidth, base, y(value)) : barPath(x, barWidth, base, y(value), true), "data-mk-part": "bar", "data-mk-index": i, "data-mk-series": k });
6675
+ fillBar(path, k, i);
6532
6676
  marks.append(path);
6533
6677
  });
6534
6678
  }
6535
6679
  });
6536
6680
  if (totalsLayer.childNodes.length) canvas.append(totalsLayer);
6537
- } else {
6681
+ }
6682
+ if (model.series.some((_, index) => seriesType(index) !== "bar")) {
6538
6683
  values.forEach((list3, k) => {
6684
+ if (seriesType(k) === "bar") return;
6539
6685
  const series = model.series[k];
6540
6686
  const runs2 = [];
6541
6687
  let run = [];
6542
6688
  list3.forEach((value, i) => {
6543
- if (finite3(value)) run.push([xs[i], y(value)]);
6689
+ const bottomValue = lower[k]?.[i];
6690
+ if (finite3(value) && (!series.lowerValues || finite3(bottomValue))) run.push([xs[i], y(value), finite3(bottomValue) ? y(bottomValue) : base]);
6544
6691
  else if (run.length) {
6545
6692
  runs2.push(run);
6546
6693
  run = [];
6547
6694
  }
6548
6695
  });
6549
6696
  if (run.length) runs2.push(run);
6550
- if (type() === "area") {
6697
+ if (seriesType(k) === "area") {
6551
6698
  const gradient = svg("linearGradient", { id: `${uid2}-fill-${k}`, x1: 0, x2: 0, y1: 0, y2: 1 });
6552
6699
  const stop2 = (offset, opacity) => {
6553
6700
  const element = svg("stop", { offset });
@@ -6559,8 +6706,10 @@ function createChart(root, initial = {}) {
6559
6706
  defs.append(gradient);
6560
6707
  for (const points of runs2) {
6561
6708
  if (points.length < 2) continue;
6562
- const d = `M${points.map(([px, py]) => `${round(px)},${round(py)}`).join("L")}L${round(points[points.length - 1][0])},${round(base)}L${round(points[0][0])},${round(base)}Z`;
6563
- const area = svg("path", { d, "data-mk-part": "area" });
6709
+ const upper = linePath(points, options.curve === "smooth");
6710
+ const bottom2 = linePath([...points].reverse().map(([px, , py]) => [px, py]), options.curve === "smooth");
6711
+ const d = `${upper}${bottom2.replace(/^M/, "L")}Z`;
6712
+ const area = svg("path", { d, "data-mk-part": "area", "data-mk-series": k });
6564
6713
  area.style.fill = `url(#${uid2}-fill-${k})`;
6565
6714
  marks.append(area);
6566
6715
  }
@@ -6572,7 +6721,7 @@ function createChart(root, initial = {}) {
6572
6721
  marks.append(dot);
6573
6722
  continue;
6574
6723
  }
6575
- const line = svg("path", { d: `M${points.map(([px, py]) => `${round(px)},${round(py)}`).join("L")}`, "data-mk-part": "line" });
6724
+ const line = svg("path", { d: linePath(points, options.curve === "smooth"), "data-mk-part": "line" });
6576
6725
  line.style.stroke = series.color;
6577
6726
  const dotted = Boolean(series.dash) && Number(series.dash.trim().split(/[\s,]+/)[0]) <= 1;
6578
6727
  line.style.strokeWidth = dotted ? "2.5" : series.dash ? "1.5" : k === 0 ? "2.5" : "2";
@@ -6581,7 +6730,7 @@ function createChart(root, initial = {}) {
6581
6730
  }
6582
6731
  });
6583
6732
  const last2 = lastPoint(values[0]);
6584
- if (last2 >= 0 && !model.series[0].dash) {
6733
+ if (last2 >= 0 && seriesType(0) !== "bar" && !model.series[0].dash) {
6585
6734
  const point = svg("circle", { cx: round(xs[last2]), cy: round(y(values[0][last2])), r: 5, "data-mk-part": "end" });
6586
6735
  point.style.fill = model.series[0].color;
6587
6736
  marks.append(point);
@@ -6607,6 +6756,11 @@ function createChart(root, initial = {}) {
6607
6756
  cursor.replaceChildren();
6608
6757
  if (band) band.style.display = "none";
6609
6758
  for (const mark of canvas.querySelectorAll("[data-mk-index]")) mark.removeAttribute("data-mk-dim");
6759
+ for (const mark of canvas.querySelectorAll('[data-mk-part="bar"]')) {
6760
+ const index = Number(mark.dataset.mkIndex);
6761
+ mark.toggleAttribute("data-mk-active", index === selected);
6762
+ if (options.barFill === "spotlight") mark.style.fill = index === (selected ?? model.labels.length - 1) ? mark.style.getPropertyValue("--mk-bar-fill") : `url(#${uid2}-hatch)`;
6763
+ }
6610
6764
  if (selected === null || !hasData()) {
6611
6765
  if (!tooltip.hidden && !reduced()) {
6612
6766
  gsap.killTweensOf(tooltip, "opacity,scale");
@@ -6631,6 +6785,24 @@ function createChart(root, initial = {}) {
6631
6785
  for (const mark of canvas.querySelectorAll("[data-mk-index]")) if (mark.getAttribute("data-mk-index") !== String(i)) mark.setAttribute("data-mk-dim", "");
6632
6786
  const { up, down } = totals(i);
6633
6787
  anchorY = stacked() ? geometry.y(up || down) : Math.min(...model.series.map((series) => finite3(series.values[i]) ? geometry.y(series.values[i]) : geometry.bottom));
6788
+ if (options.barStyle === "pill") {
6789
+ const amount = stacked() ? up + down : model.series[0]?.values[i];
6790
+ if (finite3(amount)) {
6791
+ const label = format(amount), width = Math.max(40, label.length * 7 + 18);
6792
+ const bx = Math.max(0, Math.min(geometry.width - width, x - width / 2));
6793
+ const by = Math.max(0, anchorY - 32);
6794
+ const group = svg("g", { "data-mk-part": "bar-value" });
6795
+ group.append(svg("rect", { x: round(bx), y: round(by), width, height: 24, rx: 12 }));
6796
+ const text = svg("text", { x: round(bx + width / 2), y: round(by + 12), "text-anchor": "middle", "dominant-baseline": "middle" });
6797
+ text.textContent = label;
6798
+ group.append(text);
6799
+ cursor.append(group);
6800
+ const marker = svg("circle", { cx: round(x), cy: round(anchorY), r: 4, "data-mk-part": "marker" });
6801
+ marker.style.fill = model.series[0]?.color ?? "var(--mk-text)";
6802
+ cursor.append(marker);
6803
+ if (fresh && !reduced()) keep(gsap.fromTo(group, { opacity: 0, y: 6 }, { opacity: 1, y: 0, duration: 0.3, ease: EASE.pop }));
6804
+ }
6805
+ }
6634
6806
  } else {
6635
6807
  cursor.append(svg("line", { x1: round(x), x2: round(x), y1: geometry.top, y2: geometry.bottom, "data-mk-part": "guide" }));
6636
6808
  model.series.forEach((series) => {
@@ -6661,10 +6833,10 @@ function createChart(root, initial = {}) {
6661
6833
  const name = document.createElement("span");
6662
6834
  name.textContent = series.name;
6663
6835
  const amount = document.createElement("b");
6664
- amount.textContent = finite3(value) ? format(value) : "\u2014";
6836
+ amount.textContent = rangeText(series, i);
6665
6837
  row.append(swatch, name, amount);
6666
6838
  tooltip.append(row);
6667
- rows.push(`${series.name ? `${series.name}: ` : ""}${finite3(value) ? format(value) : "sin dato"}`);
6839
+ rows.push(`${series.name ? `${series.name}: ` : ""}${finite3(value) ? rangeText(series, i) : "sin dato"}`);
6668
6840
  }
6669
6841
  if (stacked()) {
6670
6842
  const { up, down } = totals(i);
@@ -6713,6 +6885,7 @@ function createChart(root, initial = {}) {
6713
6885
  glide?.kill();
6714
6886
  canvas.setAttribute("aria-label", describe());
6715
6887
  scope.attr(root, "data-mk-chart-type", type());
6888
+ scope.attr(root, "data-mk-bar-style", options.barStyle ?? "rounded");
6716
6889
  renderTable();
6717
6890
  renderLegend();
6718
6891
  const ok = hasData();
@@ -6732,7 +6905,7 @@ function createChart(root, initial = {}) {
6732
6905
  const target = targetValues();
6733
6906
  const domain = domainOf(target);
6734
6907
  const finish = () => {
6735
- shown4 = { values: target, lo: domain.lo, hi: domain.hi, type: type(), stacked: stacked() };
6908
+ shown4 = { values: target, lower: lowerValues(), lo: domain.lo, hi: domain.hi, type: type(), stacked: stacked() };
6736
6909
  paint(target, domain.lo, domain.hi, domain.step);
6737
6910
  paintSelection(false);
6738
6911
  };
@@ -6751,7 +6924,11 @@ function createChart(root, initial = {}) {
6751
6924
  const before = from.values[k][i];
6752
6925
  return finite3(value) && finite3(before) ? before + (value - before) * t : value;
6753
6926
  }));
6754
- paint(values, from.lo + (domain.lo - from.lo) * t, from.hi + (domain.hi - from.hi) * t, domain.step);
6927
+ const lower = lowerValues().map((list3, k) => list3.map((value, i) => {
6928
+ const before = from.lower[k]?.[i];
6929
+ return finite3(value) && finite3(before) ? before + (value - before) * t : value;
6930
+ }));
6931
+ paint(values, from.lo + (domain.lo - from.lo) * t, from.hi + (domain.hi - from.hi) * t, domain.step, lower);
6755
6932
  paintSelection(false);
6756
6933
  },
6757
6934
  onComplete: () => {
@@ -6763,12 +6940,14 @@ function createChart(root, initial = {}) {
6763
6940
  }
6764
6941
  finish();
6765
6942
  if (type() === "bar") {
6766
- const state = { t: 0 };
6943
+ const stagger = Math.min(0.045, 0.22 / Math.max(1, model.labels.length - 1));
6944
+ const length = 0.7 + stagger * (model.labels.length - 1);
6945
+ const state = { t: 0 }, ease = gsap.parseEase(EASE.swatch);
6767
6946
  glide = gsap.to(state, {
6768
- t: 1,
6769
- duration: 0.7,
6770
- ease: EASE.swatch,
6771
- onUpdate: () => paint(target.map((list3) => list3.map((value) => finite3(value) ? value * state.t : value)), domain.lo, domain.hi, domain.step),
6947
+ t: length,
6948
+ duration: length,
6949
+ ease: "none",
6950
+ onUpdate: () => paint(target.map((list3) => list3.map((value, i) => finite3(value) ? value * Math.max(0, ease(Math.min(1, Math.max(0, (state.t - i * stagger) / 0.7)))) : value)), domain.lo, domain.hi, domain.step),
6772
6951
  onComplete: () => {
6773
6952
  finish();
6774
6953
  settle();
@@ -7775,7 +7954,7 @@ function createImagePreview(root, options = {}) {
7775
7954
  registerMotion();
7776
7955
  const scope = createScope();
7777
7956
  const loop = options.loop ?? true;
7778
- const labels = { close: "Cerrar", prev: "Imagen anterior", next: "Imagen siguiente", dialog: "Vista de imagen", ...options.labels };
7957
+ const labels = { close: "Cerrar", prev: "Imagen anterior", next: "Imagen siguiente", dialog: "Vista de imagen", strip: "Miniaturas", picture: "Imagen", ...options.labels };
7779
7958
  const pictures = () => [...root.querySelectorAll("[data-mk-image]")].map((thumb) => {
7780
7959
  const img = thumb.matches("img") ? thumb : thumb.querySelector("img");
7781
7960
  return {
@@ -7804,7 +7983,15 @@ function createImagePreview(root, options = {}) {
7804
7983
  const counter = document.createElement("span");
7805
7984
  counter.dataset.mkLightbox = "count";
7806
7985
  counter.setAttribute("aria-live", "polite");
7807
- dialog.append(backdrop, stage, prev, next, close, counter);
7986
+ const strip = document.createElement("div");
7987
+ strip.dataset.mkLightbox = "strip";
7988
+ strip.setAttribute("role", "group");
7989
+ strip.setAttribute("aria-label", labels.strip);
7990
+ strip.hidden = true;
7991
+ const ring = document.createElement("span");
7992
+ ring.dataset.mkLightboxRing = "";
7993
+ ring.setAttribute("aria-hidden", "true");
7994
+ dialog.append(backdrop, stage, prev, next, close, counter, strip);
7808
7995
  root.append(dialog);
7809
7996
  scope.add(() => dialog.remove());
7810
7997
  scope.attr(root, "data-mk-ready", "");
@@ -7844,6 +8031,42 @@ function createImagePreview(root, options = {}) {
7844
8031
  next.disabled = !loop && i === list3.length - 1;
7845
8032
  prev.hidden = next.hidden = list3.length < 2;
7846
8033
  };
8034
+ let ringShown = false;
8035
+ const buildStrip = () => {
8036
+ const show = options.strip !== false && list3.length > 1;
8037
+ strip.hidden = !show;
8038
+ dialog.toggleAttribute("data-mk-strip", show);
8039
+ ringShown = false;
8040
+ if (!show) return strip.replaceChildren();
8041
+ strip.replaceChildren(
8042
+ ring,
8043
+ ...list3.map((picture, i) => {
8044
+ const thumb = document.createElement("button");
8045
+ thumb.type = "button";
8046
+ thumb.dataset.mkLightboxThumb = String(i);
8047
+ thumb.setAttribute("aria-label", `${labels.picture} ${i + 1} de ${list3.length}`);
8048
+ const small = thumbImg(picture);
8049
+ const img = document.createElement("img");
8050
+ img.src = (small instanceof HTMLImageElement ? small.getAttribute("src") || small.currentSrc : "") || picture.src;
8051
+ img.alt = "";
8052
+ img.draggable = false;
8053
+ thumb.append(img);
8054
+ return thumb;
8055
+ })
8056
+ );
8057
+ };
8058
+ const paintStrip = () => {
8059
+ if (strip.hidden) return;
8060
+ const thumbs = [...strip.querySelectorAll("[data-mk-lightbox-thumb]")];
8061
+ thumbs.forEach((thumb, i) => i === index ? thumb.setAttribute("aria-current", "true") : thumb.removeAttribute("aria-current"));
8062
+ const active = thumbs[index];
8063
+ if (!active) return;
8064
+ const box = { x: active.offsetLeft, y: active.offsetTop, width: active.offsetWidth, height: active.offsetHeight };
8065
+ if (!ringShown || reduced()) gsap.set(ring, box);
8066
+ else keep(gsap.to(ring, { ...box, duration: 0.35, ease: EASE.swatch }));
8067
+ ringShown = true;
8068
+ if (typeof strip.scrollTo === "function") strip.scrollTo({ left: active.offsetLeft + active.offsetWidth / 2 - strip.clientWidth / 2, behavior: reduced() ? "auto" : "smooth" });
8069
+ };
7847
8070
  const fromThumb = (picture) => {
7848
8071
  const small = thumbImg(picture).getBoundingClientRect();
7849
8072
  const big = image.getBoundingClientRect();
@@ -7871,16 +8094,18 @@ function createImagePreview(root, options = {}) {
7871
8094
  isOpen = true;
7872
8095
  index = target;
7873
8096
  counter.textContent = "";
8097
+ buildStrip();
7874
8098
  write(target);
7875
8099
  if (typeof dialog.showModal === "function") dialog.showModal();
7876
8100
  else dialog.setAttribute("open", "");
8101
+ paintStrip();
7877
8102
  close.focus({ preventScroll: true });
7878
8103
  const picture = list3[target];
7879
8104
  options.onOpenChange?.(true);
7880
8105
  root.dispatchEvent(new CustomEvent("mk:open", { bubbles: true, detail: { index } }));
7881
8106
  if (reduced()) return;
7882
8107
  keep(gsap.fromTo(backdrop, { opacity: 0 }, { opacity: 1, duration: 0.4, ease: "power2.out", clearProps: "opacity" }));
7883
- keep(gsap.fromTo([prev, next, close, counter, caption], { opacity: 0 }, { opacity: 1, duration: 0.3, delay: 0.3, clearProps: "opacity" }));
8108
+ keep(gsap.fromTo([prev, next, close, counter, caption, strip], { opacity: 0 }, { opacity: 1, duration: 0.3, delay: 0.3, clearProps: "opacity" }));
7884
8109
  const grow = () => {
7885
8110
  const start = fromThumb(picture);
7886
8111
  if (!start) return void keep(gsap.fromTo(image, { opacity: 0, scale: 0.92 }, { opacity: 1, scale: 1, duration: 0.35, ease: EASE.pop, clearProps: "opacity,scale,transform" }));
@@ -7912,11 +8137,11 @@ function createImagePreview(root, options = {}) {
7912
8137
  gsap.set(image, { scale: 1, x: 0, y: 0 });
7913
8138
  const end = fromThumb(picture);
7914
8139
  keep(gsap.to(backdrop, { opacity: 0, duration: 0.35, ease: "power2.in" }));
7915
- keep(gsap.to([prev, next, close, counter, caption], { opacity: 0, duration: 0.15 }));
8140
+ keep(gsap.to([prev, next, close, counter, caption, strip], { opacity: 0, duration: 0.15 }));
7916
8141
  if (!end) return void keep(gsap.to(image, { opacity: 0, scale: 0.92, duration: 0.25, ease: "power2.in", onComplete: finish }));
7917
8142
  thumbImg(picture).style.visibility = "hidden";
7918
8143
  keep(gsap.to(image, { ...end, duration: 0.5, ease: EASE.signature, onComplete: () => {
7919
- gsap.set([prev, next, close, counter, caption], { clearProps: "opacity" });
8144
+ gsap.set([prev, next, close, counter, caption, strip], { clearProps: "opacity" });
7920
8145
  finish();
7921
8146
  } }));
7922
8147
  };
@@ -7932,12 +8157,41 @@ function createImagePreview(root, options = {}) {
7932
8157
  index = target;
7933
8158
  options.onChange?.(index);
7934
8159
  root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { index, previous: before } }));
7935
- if (reduced()) return write(target);
8160
+ if (reduced()) {
8161
+ write(target);
8162
+ paintStrip();
8163
+ return;
8164
+ }
7936
8165
  gsap.killTweensOf(image);
7937
- keep(
7938
- gsap.timeline().to(image, { x: -60 * direction, opacity: 0, filter: "blur(12px)", duration: 0.18, ease: "power2.in" }).call(() => write(target)).fromTo(image, { x: 60 * direction, opacity: 0, filter: "blur(12px)" }, { x: 0, opacity: 1, filter: "blur(0px)", duration: 0.4, ease: EASE.signature, clearProps: "transform,opacity,filter" })
7939
- );
8166
+ ghost?.remove();
8167
+ const leaving = image.cloneNode();
8168
+ leaving.dataset.mkLightbox = "ghost";
8169
+ leaving.alt = "";
8170
+ leaving.setAttribute("aria-hidden", "true");
8171
+ Object.assign(leaving.style, { position: "absolute", left: `${image.offsetLeft}px`, top: `${image.offsetTop}px`, width: `${image.offsetWidth}px`, height: `${image.offsetHeight}px`, margin: "0" });
8172
+ stage.append(leaving);
8173
+ ghost = leaving;
8174
+ write(target);
8175
+ paintStrip();
8176
+ gsap.set(image, { opacity: 0, x: 0, y: 0 });
8177
+ keep(gsap.to(leaving, { xPercent: -28 * direction, scale: 0.86, opacity: 0, filter: "blur(10px)", duration: 0.45, ease: EASE.signature, onComplete: () => {
8178
+ leaving.remove();
8179
+ if (ghost === leaving) ghost = null;
8180
+ } }));
8181
+ const enter = () => {
8182
+ if (!isOpen || index !== target) return;
8183
+ keep(gsap.fromTo(image, { xPercent: 24 * direction, scale: 1.04, opacity: 0, filter: "blur(10px)" }, { xPercent: 0, scale: 1, opacity: 1, filter: "blur(0px)", duration: 0.5, ease: EASE.signature, clearProps: "transform,opacity,filter" }));
8184
+ };
8185
+ const decoded = typeof image.decode === "function" ? image.decode().catch(() => void 0) : Promise.resolve();
8186
+ if (image.complete && image.naturalWidth) enter();
8187
+ else void Promise.race([decoded, new Promise((done) => setTimeout(done, 250))]).then(enter);
7940
8188
  }
8189
+ let ghost = null;
8190
+ scope.add(() => ghost?.remove());
8191
+ scope.on(strip, "click", (event) => {
8192
+ const thumb = event.target?.closest("[data-mk-lightbox-thumb]");
8193
+ if (thumb) go(Number(thumb.dataset.mkLightboxThumb));
8194
+ });
7941
8195
  scope.on(root, "click", (event) => {
7942
8196
  const thumb = event.target?.closest("[data-mk-image]");
7943
8197
  if (!thumb || !root.contains(thumb) || dialog.contains(thumb)) return;
@@ -11710,7 +11964,7 @@ function createBreadcrumb(root, options = {}) {
11710
11964
  list3.replaceChildren(...nodes);
11711
11965
  nav.toggleAttribute("data-mk-expanded", expanded);
11712
11966
  };
11713
- const fold6 = (keepEnd) => {
11967
+ const fold7 = (keepEnd) => {
11714
11968
  const end = Math.max(1, items.length - keepEnd);
11715
11969
  return Array.from({ length: Math.max(0, end - 1) }, (_, i) => i + 1);
11716
11970
  };
@@ -11722,7 +11976,7 @@ function createBreadcrumb(root, options = {}) {
11722
11976
  return;
11723
11977
  }
11724
11978
  if (maxItems !== "auto") {
11725
- hidden = items.length > maxItems ? fold6(maxItems - 1) : [];
11979
+ hidden = items.length > maxItems ? fold7(maxItems - 1) : [];
11726
11980
  render();
11727
11981
  return;
11728
11982
  }
@@ -11730,7 +11984,7 @@ function createBreadcrumb(root, options = {}) {
11730
11984
  hidden = [];
11731
11985
  render();
11732
11986
  for (let keepEnd = items.length - 2; keepEnd >= 1 && !fits(); keepEnd--) {
11733
- hidden = fold6(keepEnd);
11987
+ hidden = fold7(keepEnd);
11734
11988
  render();
11735
11989
  }
11736
11990
  nav.removeAttribute("data-mk-measuring");
@@ -13797,46 +14051,250 @@ function matchesFilter(record, filter, fields) {
13797
14051
  results.push(matchesFilter(record, node, fields));
13798
14052
  continue;
13799
14053
  }
13800
- const field = fields.find((candidate) => candidate.key === node.field);
13801
- if (!field || !isComplete(node, fields)) continue;
13802
- results.push(testRule(record, node, field));
13803
- }
13804
- if (!results.length) return true;
13805
- return filter.combinator === "and" ? results.every(Boolean) : results.some(Boolean);
13806
- }
13807
- function hasConditions(filter, fields) {
13808
- return filter.rules.some((node) => isGroup(node) ? hasConditions(node, fields) : isComplete(node, fields));
13809
- }
13810
- var shown2 = (field, value) => {
13811
- if (blank(value)) return "\u2026";
13812
- if (typeOf(field) === "select") return field.options?.find((option) => option.value === String(value))?.label ?? String(value);
13813
- if (typeOf(field) === "date") {
13814
- const date = toDate(value, new Date(Number.NaN));
13815
- if (!Number.isNaN(date.getTime())) return new Intl.DateTimeFormat("es", { day: "numeric", month: "short", year: "numeric" }).format(date);
13816
- }
13817
- return String(value);
13818
- };
13819
- function describeFilter(filter, fields, nested = false) {
13820
- const joiner = filter.combinator === "and" ? " y " : " o ";
13821
- const parts = [];
13822
- for (const node of filter.rules) {
13823
- if (isGroup(node)) {
13824
- const inner = describeFilter(node, fields, true);
13825
- if (inner) parts.push(inner);
13826
- continue;
14054
+ const field = fields.find((candidate) => candidate.key === node.field);
14055
+ if (!field || !isComplete(node, fields)) continue;
14056
+ results.push(testRule(record, node, field));
14057
+ }
14058
+ if (!results.length) return true;
14059
+ return filter.combinator === "and" ? results.every(Boolean) : results.some(Boolean);
14060
+ }
14061
+ function hasConditions(filter, fields) {
14062
+ return filter.rules.some((node) => isGroup(node) ? hasConditions(node, fields) : isComplete(node, fields));
14063
+ }
14064
+ var shown2 = (field, value) => {
14065
+ if (blank(value)) return "\u2026";
14066
+ if (typeOf(field) === "select") return field.options?.find((option) => option.value === String(value))?.label ?? String(value);
14067
+ if (typeOf(field) === "date") {
14068
+ const date = toDate(value, new Date(Number.NaN));
14069
+ if (!Number.isNaN(date.getTime())) return new Intl.DateTimeFormat("es", { day: "numeric", month: "short", year: "numeric" }).format(date);
14070
+ }
14071
+ return String(value);
14072
+ };
14073
+ function describeFilter(filter, fields, nested = false) {
14074
+ const joiner = filter.combinator === "and" ? " y " : " o ";
14075
+ const parts = [];
14076
+ for (const node of filter.rules) {
14077
+ if (isGroup(node)) {
14078
+ const inner = describeFilter(node, fields, true);
14079
+ if (inner) parts.push(inner);
14080
+ continue;
14081
+ }
14082
+ const field = fields.find((candidate) => candidate.key === node.field);
14083
+ if (!field || !isComplete(node, fields)) continue;
14084
+ const operator = operatorOf(field, node.operator);
14085
+ const [a, b] = Array.isArray(node.value) ? node.value : [node.value, null];
14086
+ const values = operator.arity === 0 ? "" : operator.arity === 1 ? ` ${shown2(field, a)}` : ` ${shown2(field, a)} y ${shown2(field, b)}`;
14087
+ parts.push(`${field.label} ${operator.label}${values}`);
14088
+ }
14089
+ if (!parts.length) return "";
14090
+ const text = parts.join(joiner);
14091
+ return nested && parts.length > 1 ? `(${text})` : text;
14092
+ }
14093
+ var cloneFilter = (filter) => JSON.parse(JSON.stringify(filter));
14094
+
14095
+ // src/components/select/engine.ts
14096
+ var CHEVRON2 = '<svg aria-hidden="true" data-mk-select-chevron width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 10l5 5 5-5"/></svg>';
14097
+ var CHECK4 = '<svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>';
14098
+ var fold4 = (text) => text.normalize("NFD").replace(/[̀-ͯ]/g, "").toLocaleLowerCase();
14099
+ function fillSelect(select, list3) {
14100
+ const groups = /* @__PURE__ */ new Map();
14101
+ const nodes = [];
14102
+ for (const choice of list3) {
14103
+ const option = new Option(choice.label, choice.value);
14104
+ option.disabled = Boolean(choice.disabled);
14105
+ if (!choice.group) {
14106
+ nodes.push(option);
14107
+ continue;
14108
+ }
14109
+ let group = groups.get(choice.group);
14110
+ if (!group) {
14111
+ group = document.createElement("optgroup");
14112
+ group.label = choice.group;
14113
+ groups.set(choice.group, group);
14114
+ nodes.push(group);
14115
+ }
14116
+ group.append(option);
14117
+ }
14118
+ select.replaceChildren(...nodes);
14119
+ }
14120
+ function createSelect(root, options = {}) {
14121
+ if (!root) return inert({ setValue() {
14122
+ }, setOptions() {
14123
+ }, refresh() {
14124
+ }, open() {
14125
+ }, close() {
14126
+ }, value: "" });
14127
+ registerMotion();
14128
+ const scope = createScope();
14129
+ const made = [];
14130
+ scope.add(() => made.forEach((element) => element.remove()));
14131
+ let native = root.querySelector("select:not([multiple])");
14132
+ if (!native) {
14133
+ native = document.createElement("select");
14134
+ if (options.name) native.name = options.name;
14135
+ root.append(native);
14136
+ made.push(native);
14137
+ } else {
14138
+ const select2 = native;
14139
+ const children = [...select2.childNodes];
14140
+ const value = select2.value;
14141
+ scope.add(() => {
14142
+ if (select2.childNodes.length !== children.length || children.some((node, i) => select2.childNodes[i] !== node)) select2.replaceChildren(...children);
14143
+ select2.value = value;
14144
+ });
14145
+ }
14146
+ const select = native;
14147
+ if (options.options) fillSelect(select, options.options);
14148
+ if (options.value !== void 0) select.value = options.value;
14149
+ scope.attr(select, "hidden", "");
14150
+ scope.attr(select, "tabindex", "-1");
14151
+ scope.attr(select, "aria-hidden", "true");
14152
+ const trigger = document.createElement("button");
14153
+ trigger.type = "button";
14154
+ trigger.dataset.mkSelectTrigger = "";
14155
+ trigger.setAttribute("aria-haspopup", "menu");
14156
+ trigger.setAttribute("aria-expanded", "false");
14157
+ const valueText = document.createElement("span");
14158
+ valueText.dataset.mkSelectValue = "";
14159
+ trigger.append(valueText);
14160
+ trigger.insertAdjacentHTML("beforeend", CHEVRON2);
14161
+ select.after(trigger);
14162
+ made.push(trigger);
14163
+ const dialog = document.createElement("dialog");
14164
+ dialog.className = "mk-dialog mk-menu mk-select-menu";
14165
+ dialog.dataset.mkSelectMenu = "";
14166
+ dialog.setAttribute("aria-label", options.label ?? "Opciones");
14167
+ root.append(dialog);
14168
+ made.push(dialog);
14169
+ scope.attr(root, "data-mk-ready", "");
14170
+ const effects = /* @__PURE__ */ new Set();
14171
+ const keep = (animation) => {
14172
+ if (!animation) return;
14173
+ effects.add(animation);
14174
+ for (const effect of effects) if (effect.totalProgress() === 1) effects.delete(effect);
14175
+ };
14176
+ scope.add(() => {
14177
+ for (const effect of effects) effect.kill();
14178
+ effects.clear();
14179
+ });
14180
+ const choices = () => [...select.options];
14181
+ const buildItems = () => {
14182
+ const nodes = [];
14183
+ const item = (option) => {
14184
+ const button2 = document.createElement("button");
14185
+ button2.type = "button";
14186
+ button2.dataset.mkItem = "";
14187
+ button2.dataset.mkValue = option.value;
14188
+ const text = document.createElement("span");
14189
+ text.textContent = option.text;
14190
+ button2.append(text);
14191
+ button2.insertAdjacentHTML("beforeend", CHECK4);
14192
+ if (option.disabled) button2.setAttribute("aria-disabled", "true");
14193
+ return button2;
14194
+ };
14195
+ for (const child of select.children) {
14196
+ if (child instanceof HTMLOptGroupElement) {
14197
+ const heading = document.createElement("p");
14198
+ heading.dataset.mkSelectGroup = "";
14199
+ heading.setAttribute("aria-hidden", "true");
14200
+ heading.textContent = child.label;
14201
+ nodes.push(heading, ...[...child.children].filter((node) => node instanceof HTMLOptionElement).map(item));
14202
+ } else if (child instanceof HTMLOptionElement) nodes.push(item(child));
14203
+ }
14204
+ dialog.replaceChildren(...nodes);
14205
+ };
14206
+ const placeholderText = () => options.placeholder ?? choices().find((option) => option.value === "")?.text ?? "Elige\u2026";
14207
+ const markItems = () => {
14208
+ for (const item of dialog.querySelectorAll("[data-mk-item]")) {
14209
+ item.setAttribute("role", "menuitemradio");
14210
+ item.setAttribute("aria-checked", String(item.dataset.mkValue === select.value));
14211
+ }
14212
+ };
14213
+ const paint = () => {
14214
+ const chosen = select.selectedOptions[0];
14215
+ const empty = !chosen || chosen.value === "";
14216
+ valueText.textContent = empty ? placeholderText() : chosen.text;
14217
+ root.toggleAttribute("data-mk-placeholder", empty);
14218
+ if (options.label) trigger.setAttribute("aria-label", `${options.label}: ${valueText.textContent}`);
14219
+ trigger.disabled = Boolean(options.disabled) || select.disabled;
14220
+ markItems();
14221
+ };
14222
+ scope.add(() => root.removeAttribute("data-mk-placeholder"));
14223
+ const choose = (value, notify) => {
14224
+ if (value === select.value) return;
14225
+ const before = choices().findIndex((option) => option.value === select.value);
14226
+ select.value = value;
14227
+ if (select.value !== value) return;
14228
+ const after = choices().findIndex((option) => option.value === value);
14229
+ paint();
14230
+ if (!reduced()) {
14231
+ gsap.killTweensOf(valueText);
14232
+ keep(gsap.fromTo(valueText, { y: after >= before ? 6 : -6, opacity: 0, filter: "blur(4px)" }, { y: 0, opacity: 1, filter: "blur(0px)", duration: 0.28, ease: EASE.pop, clearProps: "transform,opacity,filter" }));
13827
14233
  }
13828
- const field = fields.find((candidate) => candidate.key === node.field);
13829
- if (!field || !isComplete(node, fields)) continue;
13830
- const operator = operatorOf(field, node.operator);
13831
- const [a, b] = Array.isArray(node.value) ? node.value : [node.value, null];
13832
- const values = operator.arity === 0 ? "" : operator.arity === 1 ? ` ${shown2(field, a)}` : ` ${shown2(field, a)} y ${shown2(field, b)}`;
13833
- parts.push(`${field.label} ${operator.label}${values}`);
13834
- }
13835
- if (!parts.length) return "";
13836
- const text = parts.join(joiner);
13837
- return nested && parts.length > 1 ? `(${text})` : text;
14234
+ if (!notify) return;
14235
+ select.dispatchEvent(new Event("input", { bubbles: true }));
14236
+ select.dispatchEvent(new Event("change", { bubbles: true }));
14237
+ options.onChange?.(value);
14238
+ root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { value } }));
14239
+ };
14240
+ const menu = createMenu(dialog, {
14241
+ triggers: false,
14242
+ onOpen: markItems,
14243
+ onClose: () => trigger.setAttribute("aria-expanded", "false"),
14244
+ onSelect: (value) => choose(value, true)
14245
+ });
14246
+ scope.add(() => menu.destroy());
14247
+ scope.on(dialog, "mk:select", (event) => event.stopPropagation());
14248
+ const open = () => {
14249
+ if (trigger.disabled || menu.isOpen) return;
14250
+ trigger.setAttribute("aria-expanded", "true");
14251
+ dialog.style.setProperty("--mk-select-width", `${trigger.offsetWidth}px`);
14252
+ menu.open(trigger);
14253
+ };
14254
+ scope.on(trigger, "click", () => {
14255
+ if (!reduced()) keep(press(trigger));
14256
+ open();
14257
+ });
14258
+ scope.on(trigger, "keydown", (event) => {
14259
+ const key2 = event;
14260
+ if (key2.ctrlKey || key2.metaKey || key2.altKey) return;
14261
+ if (["ArrowDown", "ArrowUp", "Enter", " "].includes(key2.key)) {
14262
+ key2.preventDefault();
14263
+ open();
14264
+ } else if (key2.key.length === 1 && key2.key.trim()) {
14265
+ const letter = fold4(key2.key);
14266
+ const list3 = choices();
14267
+ const from = list3.findIndex((option) => option.value === select.value);
14268
+ for (let step = 1; step <= list3.length; step++) {
14269
+ const option = list3[(from + step) % list3.length];
14270
+ if (!option.disabled && option.value !== "" && fold4(option.text).startsWith(letter)) {
14271
+ choose(option.value, true);
14272
+ break;
14273
+ }
14274
+ }
14275
+ }
14276
+ });
14277
+ const refresh = () => {
14278
+ buildItems();
14279
+ paint();
14280
+ };
14281
+ if (typeof MutationObserver === "function") scope.observe(new MutationObserver(() => !scope.disposed && refresh())).observe(select, { childList: true, subtree: true, attributes: true, attributeFilter: ["disabled", "label"] });
14282
+ refresh();
14283
+ return {
14284
+ setValue: (value, notify = true) => choose(value, notify),
14285
+ setOptions(next) {
14286
+ fillSelect(select, next);
14287
+ refresh();
14288
+ },
14289
+ refresh,
14290
+ open,
14291
+ close: () => menu.close(),
14292
+ get value() {
14293
+ return select.value;
14294
+ },
14295
+ destroy: () => scope.dispose()
14296
+ };
13838
14297
  }
13839
- var cloneFilter = (filter) => JSON.parse(JSON.stringify(filter));
13840
14298
 
13841
14299
  // src/components/filter-builder/engine.ts
13842
14300
  var CLOSE2 = '<svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M7 7l10 10M17 7L7 17"/></svg>';
@@ -13894,6 +14352,24 @@ function createFilterBuilder(root, options = {}) {
13894
14352
  options.onChange?.(cloneFilter(model));
13895
14353
  root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { value: cloneFilter(model), summary: describeFilter(model, fields) } }));
13896
14354
  };
14355
+ const selects = /* @__PURE__ */ new Map();
14356
+ const choice = (select, label) => {
14357
+ const box = el4("span", { class: "mk-select", "data-mk-fb-select": "" });
14358
+ box.append(select);
14359
+ selects.set(box, createSelect(box, { label }));
14360
+ return box;
14361
+ };
14362
+ const dropChoices = (container) => {
14363
+ for (const [box, select] of selects) {
14364
+ if (!container.contains(box)) continue;
14365
+ select.destroy();
14366
+ selects.delete(box);
14367
+ }
14368
+ };
14369
+ scope.add(() => {
14370
+ for (const select of selects.values()) select.destroy();
14371
+ selects.clear();
14372
+ });
13897
14373
  const valueControl = (rule, index) => {
13898
14374
  const field = fieldOf(rule.field);
13899
14375
  const type = typeOf(field);
@@ -13902,6 +14378,9 @@ function createFilterBuilder(root, options = {}) {
13902
14378
  if (type === "select") {
13903
14379
  control = el4("select");
13904
14380
  control.append(el4("option", { value: "" }, "Elige\u2026"), ...(field?.options ?? []).map((option) => el4("option", { value: option.value }, option.label)));
14381
+ control.dataset.mkFbValue = String(index);
14382
+ control.value = current3 === null || current3 === void 0 ? "" : String(current3);
14383
+ return choice(control, index === 1 ? "Hasta" : operatorOf(field, rule.operator).arity === 2 ? "Desde" : "Valor");
13905
14384
  } else {
13906
14385
  control = el4("input");
13907
14386
  control.type = type === "number" ? "text" : type === "date" ? "date" : "text";
@@ -13916,6 +14395,7 @@ function createFilterBuilder(root, options = {}) {
13916
14395
  const fillValues = (row, rule) => {
13917
14396
  const host = row.querySelector("[data-mk-fb-values]");
13918
14397
  const { arity } = operatorOf(fieldOf(rule.field), rule.operator);
14398
+ dropChoices(host);
13919
14399
  host.replaceChildren();
13920
14400
  if (arity === 0) return;
13921
14401
  host.append(valueControl(rule, 0));
@@ -13935,7 +14415,7 @@ function createFilterBuilder(root, options = {}) {
13935
14415
  const values = el4("span", { "data-mk-fb-values": "" });
13936
14416
  const remove = el4("button", { type: "button", "data-mk-fb-remove": "", "aria-label": "Quitar condici\xF3n" });
13937
14417
  remove.innerHTML = CLOSE2;
13938
- row.append(field, operator, values, remove);
14418
+ row.append(choice(field, "Campo"), choice(operator, "Operador"), values, remove);
13939
14419
  fillOperators(row, rule);
13940
14420
  fillValues(row, rule);
13941
14421
  return row;
@@ -13977,6 +14457,7 @@ function createFilterBuilder(root, options = {}) {
13977
14457
  }
13978
14458
  };
13979
14459
  const render = () => {
14460
+ dropChoices(tree);
13980
14461
  tree.replaceChildren(groupBox(model, 0));
13981
14462
  placeIndicators(true);
13982
14463
  describe();
@@ -14000,7 +14481,7 @@ function createFilterBuilder(root, options = {}) {
14000
14481
  parts.push(element);
14001
14482
  if (isGroup(node)) placeIndicators(true);
14002
14483
  keep(blurIn(parts, { from: "rise", stagger: 0.04 }));
14003
- element.querySelector("select, input")?.focus();
14484
+ element.querySelector("[data-mk-select-trigger], input")?.focus();
14004
14485
  emit();
14005
14486
  };
14006
14487
  const removeNode = (id) => {
@@ -14014,6 +14495,7 @@ function createFilterBuilder(root, options = {}) {
14014
14495
  const box = boxOf(parent.id);
14015
14496
  const focusAfter = box.querySelector(":scope > [data-mk-fb-actions] button");
14016
14497
  const gone = () => {
14498
+ dropChoices(element);
14017
14499
  element.remove();
14018
14500
  link?.remove();
14019
14501
  };
@@ -14067,6 +14549,7 @@ function createFilterBuilder(root, options = {}) {
14067
14549
  setCombinator(group, next);
14068
14550
  option.parentElement.querySelector(`[data-combinator="${next}"]`).focus();
14069
14551
  });
14552
+ scope.on(tree, "mk:change", (event) => event.stopPropagation());
14070
14553
  scope.on(tree, "change", (event) => {
14071
14554
  const target = event.target;
14072
14555
  const row = target.closest("[data-mk-fb-rule]");
@@ -14763,15 +15246,15 @@ function toggleCheck(nodes, checked, id, value) {
14763
15246
  });
14764
15247
  return next;
14765
15248
  }
14766
- var fold4 = foldText;
15249
+ var fold5 = foldText;
14767
15250
  function searchTree(nodes, query, text = (node) => node.label) {
14768
- const needle = fold4(query.trim());
15251
+ const needle = fold5(query.trim());
14769
15252
  const matches = /* @__PURE__ */ new Set();
14770
15253
  const visible = /* @__PURE__ */ new Set();
14771
15254
  const open = /* @__PURE__ */ new Set();
14772
15255
  if (!needle) return { matches, visible, open, active: false };
14773
15256
  const visit = (node, ancestors) => {
14774
- if (fold4(text(node)).includes(needle)) {
15257
+ if (fold5(text(node)).includes(needle)) {
14775
15258
  matches.add(node.id);
14776
15259
  visible.add(node.id);
14777
15260
  for (const ancestor of ancestors) {
@@ -14786,10 +15269,25 @@ function searchTree(nodes, query, text = (node) => node.label) {
14786
15269
  }
14787
15270
 
14788
15271
  // src/components/tree-view/engine.ts
14789
- var CHEVRON2 = '<svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6l6 6-6 6"/></svg>';
14790
- var CHECK4 = '<svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path data-mk-tree-tick d="M5 12.5l4.5 4.5L19 7.5" pathLength="1"/><path data-mk-tree-dash d="M6 12h12"/></svg>';
15272
+ var FOLDER = '<svg aria-hidden="true" viewBox="0 0 48 40"><path data-mk-tree-folder-back d="M2 6a4 4 0 0 1 4-4h11.6a4 4 0 0 1 2.9 1.2L23.4 6H42a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4z"/><path data-mk-tree-folder-front d="M2 14a4 4 0 0 1 4-4h36a4 4 0 0 1 4 4v20a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4z"/></svg>';
15273
+ var PAGE = '<svg aria-hidden="true" viewBox="0 0 40 48"><path data-mk-tree-sheet d="M7 2h18.5L37 13.5V42a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V6a4 4 0 0 1 4-4z"/><path data-mk-tree-fold d="M25.5 2v8.5a3 3 0 0 0 3 3H37z"/></svg>';
15274
+ function moveTreeNode(nodes, id, into) {
15275
+ let taken = null;
15276
+ const without = (list3) => list3.filter((node) => {
15277
+ if (node.id !== id) return true;
15278
+ taken = node;
15279
+ return false;
15280
+ }).map((node) => node.children ? { ...node, children: without(node.children) } : node);
15281
+ const rest = without(nodes);
15282
+ const moved = taken;
15283
+ if (!moved) return nodes;
15284
+ const put = (list3) => list3.map((node) => node.id === into ? { ...node, children: [...node.children ?? [], moved] } : node.children ? { ...node, children: put(node.children) } : node);
15285
+ return put(rest);
15286
+ }
15287
+ var CHEVRON3 = '<svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6l6 6-6 6"/></svg>';
15288
+ var CHECK5 = '<svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path data-mk-tree-tick d="M5 12.5l4.5 4.5L19 7.5" pathLength="1"/><path data-mk-tree-dash d="M6 12h12"/></svg>';
14791
15289
  var sequence18 = 0;
14792
- var fold5 = foldText;
15290
+ var fold6 = foldText;
14793
15291
  function createTreeView(root, options = {}) {
14794
15292
  if (!root) return inert({ expand() {
14795
15293
  }, collapse() {
@@ -14903,12 +15401,12 @@ function createTreeView(root, options = {}) {
14903
15401
  line.style.setProperty("--mk-tree-depth", String(depth));
14904
15402
  const chevron2 = document.createElement("span");
14905
15403
  chevron2.dataset.mkTreeChevron = "";
14906
- if (branch) chevron2.innerHTML = CHEVRON2;
15404
+ if (branch) chevron2.innerHTML = CHEVRON3;
14907
15405
  line.append(chevron2);
14908
15406
  if (options.checkable) {
14909
15407
  const check2 = document.createElement("span");
14910
15408
  check2.dataset.mkTreeCheck = "";
14911
- check2.innerHTML = CHECK4;
15409
+ check2.innerHTML = CHECK5;
14912
15410
  line.append(check2);
14913
15411
  }
14914
15412
  if (node.icon) {
@@ -14917,6 +15415,12 @@ function createTreeView(root, options = {}) {
14917
15415
  icon2.setAttribute("aria-hidden", "true");
14918
15416
  icon2.textContent = node.icon;
14919
15417
  line.append(icon2);
15418
+ } else if (options.icons) {
15419
+ const icon2 = document.createElement("span");
15420
+ if (branch) icon2.dataset.mkTreeFolder = "";
15421
+ else icon2.dataset.mkTreePage = "";
15422
+ icon2.innerHTML = branch ? FOLDER : PAGE;
15423
+ line.append(icon2);
14920
15424
  }
14921
15425
  const label = document.createElement("span");
14922
15426
  label.dataset.mkTreeLabel = "";
@@ -14956,12 +15460,29 @@ function createTreeView(root, options = {}) {
14956
15460
  const target = focused && items.find((item) => item.dataset.id === focused) || selected && items.find((item) => item.dataset.id === selected) || items[0];
14957
15461
  for (const item of tree.querySelectorAll('[role="treeitem"]')) item.tabIndex = item === target ? 0 : -1;
14958
15462
  };
15463
+ let known = null;
15464
+ const allIds = (list3, into = /* @__PURE__ */ new Set()) => {
15465
+ for (const node of list3) {
15466
+ into.add(node.id);
15467
+ if (node.children) allIds(node.children, into);
15468
+ }
15469
+ return into;
15470
+ };
15471
+ const welcome = () => {
15472
+ const now2 = allIds(nodes);
15473
+ const fresh = known ? [...now2].filter((id) => !known.has(id)) : [];
15474
+ known = now2;
15475
+ if (reduced() || !fresh.length) return;
15476
+ const rows = fresh.map((id) => itemOf(id)?.querySelector(":scope > [data-mk-tree-row]")).filter((line) => !!line && visibleItems().includes(line.parentElement));
15477
+ if (rows.length) keep(gsap.fromTo(rows, { opacity: 0, x: -8, filter: "blur(6px)" }, { opacity: 1, x: 0, filter: "blur(0px)", duration: 0.35, stagger: 0.03, ease: "power2.out", clearProps: "opacity,transform,filter" }));
15478
+ };
14959
15479
  const render = () => {
14960
15480
  tree.replaceChildren(...nodes.map((node, i) => row(node, 0, i, nodes.length)));
14961
15481
  paintChecks(false);
14962
15482
  applySearch(false);
14963
15483
  roving();
14964
15484
  placePill(false);
15485
+ welcome();
14965
15486
  };
14966
15487
  const animateGroup = (group, open) => {
14967
15488
  if (reduced()) {
@@ -15103,6 +15624,114 @@ function createTreeView(root, options = {}) {
15103
15624
  }
15104
15625
  });
15105
15626
  }
15627
+ if (options.draggable) {
15628
+ let drag = null;
15629
+ let opening;
15630
+ const clearOver = () => {
15631
+ clearTimeout(opening);
15632
+ drag?.over?.removeAttribute("data-mk-tree-over");
15633
+ if (drag) drag.over = null;
15634
+ };
15635
+ const branchAt = (x, y) => {
15636
+ const under = document.elementFromPoint(x, y)?.closest('[role="treeitem"]');
15637
+ if (!under || !tree.contains(under) || !drag) return null;
15638
+ const node = nodeOf(under.dataset.id);
15639
+ const candidate = node && isBranch(node) ? under : under.parentElement?.closest('[role="treeitem"]') ?? null;
15640
+ if (!candidate) return null;
15641
+ const path = findNode(nodes, candidate.dataset.id)?.path.map((each) => each.id) ?? [];
15642
+ const parent = findNode(nodes, drag.id)?.path.at(-2)?.id;
15643
+ if (path.includes(drag.id) || candidate.dataset.id === parent) return null;
15644
+ return candidate;
15645
+ };
15646
+ const lift = (id, x, y) => {
15647
+ const node = nodeOf(id);
15648
+ const card = document.createElement("div");
15649
+ card.dataset.mkTreeDrag = "";
15650
+ card.setAttribute("aria-hidden", "true");
15651
+ if (options.icons) {
15652
+ const icon2 = document.createElement("span");
15653
+ if (isBranch(node)) icon2.dataset.mkTreeFolder = "";
15654
+ else icon2.dataset.mkTreePage = "";
15655
+ icon2.innerHTML = isBranch(node) ? FOLDER : PAGE;
15656
+ card.append(icon2);
15657
+ }
15658
+ const text = document.createElement("span");
15659
+ text.textContent = node.label;
15660
+ card.append(text);
15661
+ Object.assign(card.style, { left: "0px", top: "0px" });
15662
+ root.append(card);
15663
+ gsap.set(card, { x: x + 14, y: y + 10 });
15664
+ if (!reduced()) keep(gsap.fromTo(card, { scale: 0.85, opacity: 0 }, { scale: 1.04, opacity: 1, duration: 0.3, ease: EASE.pop }));
15665
+ itemOf(id)?.setAttribute("data-mk-tree-dragging", "");
15666
+ return card;
15667
+ };
15668
+ const end = (drop) => {
15669
+ if (!drag) return;
15670
+ const { id, card, over } = drag;
15671
+ clearOver();
15672
+ drag = null;
15673
+ itemOf(id)?.removeAttribute("data-mk-tree-dragging");
15674
+ if (!card) return;
15675
+ const into = drop && over ? over.dataset.id : null;
15676
+ const fly = (to) => {
15677
+ const box2 = to?.querySelector(":scope > [data-mk-tree-row]")?.getBoundingClientRect();
15678
+ if (reduced() || !box2 || !box2.width) return card.remove();
15679
+ keep(gsap.to(card, { x: box2.left + 24, y: box2.top + box2.height / 2 - 14, scale: 0.4, opacity: 0, duration: 0.32, ease: "power2.in", onComplete: () => card.remove() }));
15680
+ };
15681
+ if (!into) return fly(itemOf(id));
15682
+ fly(over);
15683
+ const node = nodeOf(id);
15684
+ nodes = moveTreeNode(nodes, id, into);
15685
+ expanded.add(into);
15686
+ render();
15687
+ const target = nodeOf(into);
15688
+ options.onMove?.(nodeOf(id), target);
15689
+ root.dispatchEvent(new CustomEvent("mk:move", { bubbles: true, detail: { node, into: target } }));
15690
+ };
15691
+ scope.on(tree, "pointerdown", (event) => {
15692
+ const down = event;
15693
+ const target = down.target;
15694
+ const line = target.closest("[data-mk-tree-row]");
15695
+ const item = line?.parentElement;
15696
+ if (!line || !item || down.button !== 0 || target.closest("[data-mk-tree-chevron], [data-mk-tree-check]") || item.getAttribute("aria-disabled") === "true") return;
15697
+ drag = { id: item.dataset.id, x: down.clientX, y: down.clientY, pointer: down.pointerId, card: null, over: null, lastX: down.clientX, lastT: performance.now() };
15698
+ });
15699
+ scope.on(window, "pointermove", (event) => {
15700
+ const move = event;
15701
+ if (!drag || move.pointerId !== drag.pointer) return;
15702
+ if (!drag.card) {
15703
+ if (Math.hypot(move.clientX - drag.x, move.clientY - drag.y) < 6) return;
15704
+ drag.card = lift(drag.id, move.clientX, move.clientY);
15705
+ }
15706
+ const now2 = performance.now();
15707
+ const speed = (move.clientX - drag.lastX) / Math.max(1, now2 - drag.lastT);
15708
+ drag.lastX = move.clientX;
15709
+ drag.lastT = now2;
15710
+ gsap.set(drag.card, { x: move.clientX + 14, y: move.clientY + 10 });
15711
+ if (!reduced()) keep(gsap.to(drag.card, { rotation: Math.max(-10, Math.min(10, speed * 12)), duration: 0.25, ease: "power2.out" }));
15712
+ const over = branchAt(move.clientX, move.clientY);
15713
+ if (over === drag.over) return;
15714
+ clearOver();
15715
+ if (!over) return;
15716
+ drag.over = over;
15717
+ over.setAttribute("data-mk-tree-over", "");
15718
+ if (over.getAttribute("aria-expanded") === "false") opening = setTimeout(() => void setOpen(over.dataset.id, true), 600);
15719
+ });
15720
+ scope.on(window, "pointerup", (event) => {
15721
+ if (drag && event.pointerId === drag.pointer) end(true);
15722
+ });
15723
+ scope.on(window, "pointercancel", () => end(false));
15724
+ scope.on(document, "keydown", (event) => {
15725
+ if (event.key === "Escape" && drag?.card) end(false);
15726
+ });
15727
+ scope.on(tree, "click", (event) => {
15728
+ if (drag?.card) event.stopImmediatePropagation();
15729
+ }, true);
15730
+ scope.add(() => {
15731
+ clearTimeout(opening);
15732
+ drag?.card?.remove();
15733
+ });
15734
+ }
15106
15735
  scope.on(tree, "click", (event) => {
15107
15736
  const target = event.target;
15108
15737
  const item = target?.closest('[role="treeitem"]');
@@ -15184,9 +15813,9 @@ function createTreeView(root, options = {}) {
15184
15813
  const now2 = Date.now();
15185
15814
  typed = now2 - typedAt > 600 ? key2.key : typed + key2.key;
15186
15815
  typedAt = now2;
15187
- const needle = fold5(typed);
15816
+ const needle = fold6(typed);
15188
15817
  const order = [...items.slice(index + (typed.length === 1 ? 1 : 0)), ...items.slice(0, index + (typed.length === 1 ? 1 : 0))];
15189
- const match = order.find((candidate) => fold5(nodeOf(candidate.dataset.id)?.label ?? "").startsWith(needle));
15818
+ const match = order.find((candidate) => fold6(nodeOf(candidate.dataset.id)?.label ?? "").startsWith(needle));
15190
15819
  if (match) go(match);
15191
15820
  }
15192
15821
  });
@@ -15346,8 +15975,8 @@ var ICONS2 = {
15346
15975
  grid: SVG8('<rect x="4" y="4" width="6.5" height="6.5" rx="1.5"/><rect x="13.5" y="4" width="6.5" height="6.5" rx="1.5"/><rect x="4" y="13.5" width="6.5" height="6.5" rx="1.5"/><rect x="13.5" y="13.5" width="6.5" height="6.5" rx="1.5"/>')
15347
15976
  };
15348
15977
  var ARROW2 = '<svg aria-hidden="true" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5M6 11l6-6 6 6"/></svg>';
15349
- var FOLDER = '<svg aria-hidden="true" viewBox="0 0 48 40"><path data-mk-fx-folder-back d="M2 6a4 4 0 0 1 4-4h11.6a4 4 0 0 1 2.9 1.2L23.4 6H42a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4z"/><path data-mk-fx-folder-front d="M2 14a4 4 0 0 1 4-4h36a4 4 0 0 1 4 4v20a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4z"/></svg>';
15350
- var PAGE = '<svg aria-hidden="true" viewBox="0 0 40 48"><path data-mk-fx-page d="M7 2h18.5L37 13.5V42a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V6a4 4 0 0 1 4-4z"/><path data-mk-fx-fold d="M25.5 2v8.5a3 3 0 0 0 3 3H37z"/></svg>';
15978
+ var FOLDER2 = '<svg aria-hidden="true" viewBox="0 0 48 40"><path data-mk-fx-folder-back d="M2 6a4 4 0 0 1 4-4h11.6a4 4 0 0 1 2.9 1.2L23.4 6H42a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4z"/><path data-mk-fx-folder-front d="M2 14a4 4 0 0 1 4-4h36a4 4 0 0 1 4 4v20a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4z"/></svg>';
15979
+ var PAGE2 = '<svg aria-hidden="true" viewBox="0 0 40 48"><path data-mk-fx-page d="M7 2h18.5L37 13.5V42a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V6a4 4 0 0 1 4-4z"/><path data-mk-fx-fold d="M25.5 2v8.5a3 3 0 0 0 3 3H37z"/></svg>';
15351
15980
  var SORT_LABEL = { name: "Nombre", size: "Tama\xF1o", modified: "Modificado" };
15352
15981
  var plural = (n, one, many) => `${n} ${n === 1 ? one : many}`;
15353
15982
  var sequence19 = 0;
@@ -15355,7 +15984,7 @@ function iconOf(entry) {
15355
15984
  const icon2 = document.createElement("span");
15356
15985
  icon2.dataset.mkFxIcon = "";
15357
15986
  icon2.dataset.family = fileFamily(entry);
15358
- icon2.innerHTML = isFolder(entry) ? FOLDER : PAGE;
15987
+ icon2.innerHTML = isFolder(entry) ? FOLDER2 : PAGE2;
15359
15988
  const extension2 = isFolder(entry) ? "" : extensionOf(entry.name);
15360
15989
  if (extension2) {
15361
15990
  const tag = document.createElement("span");
@@ -16461,7 +17090,7 @@ function createFileExplorer(root, options = {}) {
16461
17090
 
16462
17091
  // src/components/json-viewer/engine.ts
16463
17092
  var COPY = '<svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg>';
16464
- var CHECK5 = '<svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>';
17093
+ var CHECK6 = '<svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>';
16465
17094
  var SVG9 = (paths) => `<svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${paths}</svg>`;
16466
17095
  var EXPAND = SVG9('<path d="M7 9l5-5 5 5M7 15l5 5 5-5"/>');
16467
17096
  var COLLAPSE = SVG9('<path d="M7 4l5 5 5-5M7 20l5-5 5 5"/>');
@@ -16629,7 +17258,7 @@ function createJsonViewer(root, options = {}) {
16629
17258
  scope.attr(root, "data-mk-ready", "");
16630
17259
  const copied = (button2) => {
16631
17260
  if (!button2) return;
16632
- button2.innerHTML = CHECK5;
17261
+ button2.innerHTML = CHECK6;
16633
17262
  button2.setAttribute("data-mk-copied", "");
16634
17263
  if (!reduced()) keep(gsap.fromTo(button2.firstElementChild, { scale: 0.3, rotation: -25 }, { scale: 1, rotation: 0, duration: 0.42, ease: EASE.pop, transformOrigin: "50% 50%", clearProps: "transform" }));
16635
17264
  scope.timeout(() => {
@@ -16713,8 +17342,14 @@ function createJsonViewer(root, options = {}) {
16713
17342
  },
16714
17343
  onSelect: (node) => {
16715
17344
  const meta = node.data;
17345
+ const appearing = foot.hidden;
17346
+ const moved = pathText.textContent !== meta.path;
16716
17347
  foot.hidden = false;
16717
17348
  pathText.textContent = meta.path;
17349
+ if (!reduced()) {
17350
+ if (appearing) keep(blurIn(foot, { from: "rise", duration: 0.32 }));
17351
+ else if (moved) keep(blurIn(pathText, { from: "soft", duration: 0.28 }));
17352
+ }
16718
17353
  options.onSelect?.(meta.path, meta.value);
16719
17354
  root.dispatchEvent(new CustomEvent("mk:select", { bubbles: true, detail: { path: meta.path, value: meta.value } }));
16720
17355
  }
@@ -17431,8 +18066,8 @@ function createVirtualList(root, options = {}) {
17431
18066
  }
17432
18067
 
17433
18068
  // src/components/resizable-panel/engine.ts
17434
- var CHEVRON3 = (path) => `<svg aria-hidden="true" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="${path}"/></svg>`;
17435
- var ARROWS = { left: CHEVRON3("M15 6l-6 6 6 6"), right: CHEVRON3("M9 6l6 6-6 6"), up: CHEVRON3("M6 15l6-6 6 6"), down: CHEVRON3("M6 9l6 6 6-6") };
18069
+ var CHEVRON4 = (path) => `<svg aria-hidden="true" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="${path}"/></svg>`;
18070
+ var ARROWS = { left: CHEVRON4("M15 6l-6 6 6 6"), right: CHEVRON4("M9 6l6 6-6 6"), up: CHEVRON4("M6 15l6-6 6 6"), down: CHEVRON4("M6 9l6 6 6-6") };
17436
18071
  var sequence21 = 0;
17437
18072
  var round3 = (n) => Math.round(n * 10) / 10;
17438
18073
  function normaliseSizes(sizes, count) {
@@ -17956,9 +18591,11 @@ var ICONS3 = {
17956
18591
  previous: SVG10('<path d="M15 6l-6 6 6 6"/>'),
17957
18592
  next: SVG10('<path d="M9 6l6 6-6 6"/>'),
17958
18593
  close: SVG10('<path d="M7 7l10 10M17 7L7 17"/>', 14),
17959
- arrow: SVG10('<path d="M12 19V5M6 11l6-6 6 6"/>', 12)
18594
+ arrow: SVG10('<path d="M12 19V5M6 11l6-6 6 6"/>', 12),
18595
+ chevron: SVG10('<path d="M7 10l5 5 5-5"/>', 14),
18596
+ check: SVG10('<path d="M5 12.5l4.5 4.5L19 7.5"/>', 16)
17960
18597
  };
17961
- var CHECK6 = '<svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path data-mk-dt-tick d="M5 12.5l4.5 4.5L19 7.5" pathLength="1"/><path data-mk-dt-dash d="M6 12h12"/></svg>';
18598
+ var CHECK7 = '<svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.2" stroke-linecap="round" stroke-linejoin="round"><path data-mk-dt-tick d="M5.5 12l4 4L18.5 7.5" pathLength="1"/><path data-mk-dt-dash d="M6.5 12h11"/></svg>';
17962
18599
  var plural3 = (n, one, many) => `${n} ${n === 1 ? one : many}`;
17963
18600
  var sequence22 = 0;
17964
18601
  function createDataTable(root, options = {}) {
@@ -18169,21 +18806,18 @@ function createDataTable(root, options = {}) {
18169
18806
  emptyHost.hidden = true;
18170
18807
  const foot = el5("div", "data-mk-dt-foot");
18171
18808
  const range = el5("span", "data-mk-dt-range");
18172
- const sizeField = el5("label", "data-mk-dt-size");
18809
+ const sizeField = el5("div", "data-mk-dt-size");
18173
18810
  sizeField.append(el5("span", void 0, "Filas"));
18174
- const sizeSelect = el5("select");
18175
- for (const size of pageSizes) {
18176
- const option = el5("option", void 0, String(size));
18177
- option.value = String(size);
18178
- sizeSelect.append(option);
18179
- }
18180
- if (!pageSizes.includes(pageSize) && pageSize) {
18181
- const option = el5("option", void 0, String(pageSize));
18182
- option.value = String(pageSize);
18183
- sizeSelect.prepend(option);
18184
- }
18185
- sizeSelect.value = String(pageSize);
18186
- sizeField.append(sizeSelect);
18811
+ const sizeButton = el5("button", "data-mk-dt-size-button");
18812
+ sizeButton.type = "button";
18813
+ sizeButton.setAttribute("aria-haspopup", "menu");
18814
+ sizeButton.setAttribute("aria-expanded", "false");
18815
+ const sizeValue = el5("span", "data-mk-dt-size-value", String(pageSize));
18816
+ sizeButton.append(sizeValue);
18817
+ sizeButton.insertAdjacentHTML("beforeend", ICONS3.chevron);
18818
+ sizeButton.setAttribute("aria-label", `Filas por p\xE1gina: ${pageSize}`);
18819
+ sizeField.append(sizeButton);
18820
+ const sizes = pageSize && !pageSizes.includes(pageSize) ? [pageSize, ...pageSizes] : [...pageSizes];
18187
18821
  const pager = el5("nav", "data-mk-dt-pager");
18188
18822
  pager.setAttribute("aria-label", "P\xE1ginas");
18189
18823
  const previous = el5("button", "data-mk-dt-previous");
@@ -18224,7 +18858,7 @@ function createDataTable(root, options = {}) {
18224
18858
  const status = el5("span");
18225
18859
  status.className = "mk-sr-only";
18226
18860
  status.setAttribute("role", "status");
18227
- root.append(bar, active, scroll, emptyHost, foot, bulk, status);
18861
+ root.append(bar, bulk, active, scroll, emptyHost, foot, status);
18228
18862
  scope.attr(root, "data-mk-ready", "");
18229
18863
  scope.add(() => {
18230
18864
  for (const effect of effects) effect.kill();
@@ -18237,7 +18871,7 @@ function createDataTable(root, options = {}) {
18237
18871
  input.type = "checkbox";
18238
18872
  input.setAttribute("aria-label", label);
18239
18873
  box.append(input);
18240
- box.insertAdjacentHTML("beforeend", CHECK6);
18874
+ box.insertAdjacentHTML("beforeend", CHECK7);
18241
18875
  return { box, input };
18242
18876
  };
18243
18877
  const paintCheck = (box, state, animate) => {
@@ -18423,14 +19057,16 @@ function createDataTable(root, options = {}) {
18423
19057
  gsap.killTweensOf(bulk);
18424
19058
  if (show) {
18425
19059
  bulk.hidden = false;
18426
- if (animate && !reduced()) keep(gsap.fromTo(bulk, { opacity: 0, y: 16, filter: "blur(8px)" }, { opacity: 1, y: 0, filter: "blur(0px)", duration: 0.35, ease: EASE.pop, clearProps: "opacity,transform,filter" }));
19060
+ if (animate && !reduced()) keep(gsap.fromTo(bulk, { opacity: 0, y: -8, filter: "blur(8px)" }, { opacity: 1, y: 0, filter: "blur(0px)", duration: 0.35, ease: EASE.pop, clearProps: "opacity,transform,filter" }));
18427
19061
  } else if (animate && !reduced()) {
18428
- keep(gsap.to(bulk, { opacity: 0, y: 16, filter: "blur(6px)", duration: 0.22, ease: "power2.in", onComplete: () => {
19062
+ keep(gsap.to(bulk, { opacity: 0, y: -8, filter: "blur(6px)", duration: 0.22, ease: "power2.in", onComplete: () => {
18429
19063
  bulk.hidden = true;
18430
19064
  gsap.set(bulk, { clearProps: "opacity,transform,filter" });
18431
19065
  } }));
18432
19066
  } else bulk.hidden = true;
18433
19067
  };
19068
+ let slides = 0;
19069
+ scope.add(() => scroll.style.removeProperty("overflow-x"));
18434
19070
  const render = (motion = "none") => {
18435
19071
  const all = loading ? [] : results();
18436
19072
  const pages = pageCount(all.length);
@@ -18456,7 +19092,25 @@ function createDataTable(root, options = {}) {
18456
19092
  })
18457
19093
  );
18458
19094
  } else if (motion === "forward" || motion === "back") {
18459
- keep(gsap.fromTo(fresh, { opacity: 0, x: motion === "forward" ? 24 : -24 }, { opacity: 1, x: 0, duration: 0.32, stagger: 0.015, ease: "power2.out", clearProps: "opacity,transform" }));
19095
+ const fits = scroll.scrollWidth <= scroll.clientWidth + 1;
19096
+ const token = ++slides;
19097
+ if (fits) scroll.style.overflowX = "hidden";
19098
+ const release = () => {
19099
+ if (token === slides) scroll.style.removeProperty("overflow-x");
19100
+ };
19101
+ keep(
19102
+ gsap.fromTo(fresh, fits ? { opacity: 0, x: motion === "forward" ? 24 : -24 } : { opacity: 0, y: 6 }, {
19103
+ opacity: 1,
19104
+ x: 0,
19105
+ y: 0,
19106
+ duration: 0.32,
19107
+ stagger: 0.015,
19108
+ ease: "power2.out",
19109
+ clearProps: "opacity,transform",
19110
+ onComplete: release,
19111
+ onInterrupt: release
19112
+ })
19113
+ );
18460
19114
  } else if (wasLoading) keep(gsap.fromTo(fresh, { opacity: 0, y: 6 }, { opacity: 1, y: 0, duration: 0.35, stagger: 0.025, ease: "power2.out", clearProps: "opacity,transform" }));
18461
19115
  }
18462
19116
  options.onRender?.(body);
@@ -18596,11 +19250,6 @@ function createDataTable(root, options = {}) {
18596
19250
  keep(press(next));
18597
19251
  setPage(page + 1);
18598
19252
  });
18599
- scope.on(sizeSelect, "change", () => {
18600
- pageSize = Number(sizeSelect.value) || 0;
18601
- page = 0;
18602
- render("reflow");
18603
- });
18604
19253
  scope.on(clearButton, "click", clearAll);
18605
19254
  scope.on(bulkClose, "click", () => setSelection([]));
18606
19255
  scope.on(bulkAll, "click", () => setSelection(results().map(idOf)));
@@ -18621,11 +19270,55 @@ function createDataTable(root, options = {}) {
18621
19270
  scope.add(() => dialog.remove());
18622
19271
  return dialog;
18623
19272
  };
19273
+ const sizeDialog = panelDialog("size", "Filas por p\xE1gina");
19274
+ sizeDialog.className = "mk-dialog mk-menu mk-dt-panel mk-dt-menu";
19275
+ const sizeItems = sizes.map((size) => {
19276
+ const item = el5("button", "data-mk-item");
19277
+ item.type = "button";
19278
+ item.dataset.mkValue = String(size);
19279
+ item.append(el5("span", void 0, String(size)));
19280
+ item.insertAdjacentHTML("beforeend", ICONS3.check);
19281
+ sizeDialog.append(item);
19282
+ return item;
19283
+ });
19284
+ const paintSize = () => {
19285
+ for (const item of sizeItems) {
19286
+ const on = Number(item.dataset.mkValue) === pageSize;
19287
+ item.setAttribute("role", "menuitemradio");
19288
+ item.setAttribute("aria-checked", String(on));
19289
+ }
19290
+ };
19291
+ const changePageSize = (size, animate) => {
19292
+ const next2 = Math.max(0, Math.floor(size));
19293
+ const text = String(next2);
19294
+ if (animate && next2 !== pageSize && !reduced()) keep(rollDigits(sizeValue, text, next2 > pageSize ? 1 : -1, 0.3));
19295
+ else sizeValue.textContent = text;
19296
+ sizeButton.setAttribute("aria-label", `Filas por p\xE1gina: ${next2}`);
19297
+ pageSize = next2;
19298
+ page = 0;
19299
+ paintSize();
19300
+ render("reflow");
19301
+ };
19302
+ const sizeMenu = createMenu(sizeDialog, {
19303
+ triggers: false,
19304
+ // The menu marks every item a plain menuitem when it opens: these are a choice.
19305
+ onOpen: paintSize,
19306
+ onClose: () => sizeButton.setAttribute("aria-expanded", "false"),
19307
+ onSelect: (value) => changePageSize(Number(value) || 0, true)
19308
+ });
19309
+ paintSize();
19310
+ scope.on(sizeDialog, "mk:select", (event) => event.stopPropagation());
19311
+ scope.add(() => sizeMenu.destroy());
19312
+ scope.on(sizeButton, "click", () => {
19313
+ keep(press(sizeButton));
19314
+ sizeButton.setAttribute("aria-expanded", "true");
19315
+ sizeMenu.open(sizeButton);
19316
+ });
18624
19317
  let rowMenu = null;
18625
19318
  let menuRow = null;
18626
19319
  if (options.actions?.length) {
18627
19320
  const dialog = panelDialog("menu", "Acciones de la fila");
18628
- dialog.className = "mk-dialog mk-menu mk-dt-menu";
19321
+ dialog.className = "mk-dialog mk-menu mk-dt-panel mk-dt-menu";
18629
19322
  for (const action of options.actions) {
18630
19323
  const item = el5("button", "data-mk-item", action.label);
18631
19324
  item.type = "button";
@@ -18794,10 +19487,7 @@ function createDataTable(root, options = {}) {
18794
19487
  sortBy,
18795
19488
  setPage,
18796
19489
  setPageSize(size) {
18797
- pageSize = Math.max(0, Math.floor(size));
18798
- sizeSelect.value = String(pageSize);
18799
- page = 0;
18800
- render("reflow");
19490
+ changePageSize(size, false);
18801
19491
  },
18802
19492
  setQuery(next2) {
18803
19493
  query = next2;
@@ -19153,18 +19843,12 @@ function createEditableTable(root, options = {}) {
19153
19843
  setValue(id, column.key, !value);
19154
19844
  return;
19155
19845
  }
19156
- let editor;
19157
19846
  if (kind === "select") {
19158
- const select = document.createElement("select");
19159
- for (const option of column.options ?? []) {
19160
- const element = document.createElement("option");
19161
- element.value = option.value;
19162
- element.textContent = option.label;
19163
- select.append(element);
19164
- }
19165
- select.value = String(value ?? "");
19166
- editor = select;
19167
- } else {
19847
+ openChoices(cell, id, column, String(value ?? ""));
19848
+ return;
19849
+ }
19850
+ let editor;
19851
+ {
19168
19852
  const input = document.createElement("input");
19169
19853
  input.type = kind === "number" ? "text" : kind === "date" ? "date" : "text";
19170
19854
  if (kind === "number") input.inputMode = "decimal";
@@ -19233,6 +19917,62 @@ function createEditableTable(root, options = {}) {
19233
19917
  });
19234
19918
  };
19235
19919
  const finishEdit = (save2) => editing?.done(save2);
19920
+ const CHECK8 = '<svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>';
19921
+ let choices = null;
19922
+ let choosing = null;
19923
+ const markChoices = (dialog) => {
19924
+ for (const item of dialog.querySelectorAll("[data-mk-item]")) {
19925
+ item.setAttribute("role", "menuitemradio");
19926
+ item.setAttribute("aria-checked", String(item.dataset.mkValue === choosing?.value));
19927
+ }
19928
+ };
19929
+ const choiceMenu = () => {
19930
+ if (choices) return choices;
19931
+ const dialog = document.createElement("dialog");
19932
+ dialog.className = "mk-dialog mk-menu mk-select-menu";
19933
+ dialog.dataset.mkEtChoices = "";
19934
+ root.append(dialog);
19935
+ scope.add(() => dialog.remove());
19936
+ const menu = createMenu(dialog, {
19937
+ triggers: false,
19938
+ onOpen: () => markChoices(dialog),
19939
+ onSelect: (value) => {
19940
+ const target = choosing;
19941
+ if (target && value !== target.value) setValue(target.id, target.key, value);
19942
+ },
19943
+ onClose: () => {
19944
+ const target = choosing;
19945
+ choosing = null;
19946
+ const fresh = target ? cellOf(target.id, target.key) : null;
19947
+ if (fresh) focusCell(fresh, false);
19948
+ }
19949
+ });
19950
+ scope.on(dialog, "mk:select", (event) => event.stopPropagation());
19951
+ scope.add(() => menu.destroy());
19952
+ choices = { menu, dialog };
19953
+ return choices;
19954
+ };
19955
+ const openChoices = (cell, id, column, value) => {
19956
+ const { menu, dialog } = choiceMenu();
19957
+ dialog.setAttribute("aria-label", column.label);
19958
+ dialog.replaceChildren(
19959
+ ...(column.options ?? []).map((option) => {
19960
+ const item = document.createElement("button");
19961
+ item.type = "button";
19962
+ item.dataset.mkItem = "";
19963
+ item.dataset.mkValue = option.value;
19964
+ const text = document.createElement("span");
19965
+ text.textContent = option.label;
19966
+ item.append(text);
19967
+ item.insertAdjacentHTML("beforeend", CHECK8);
19968
+ return item;
19969
+ })
19970
+ );
19971
+ choosing = { id, key: column.key, value };
19972
+ markChoices(dialog);
19973
+ dialog.style.setProperty("--mk-select-width", `${cell.offsetWidth}px`);
19974
+ menu.open(cell);
19975
+ };
19236
19976
  const moveFrom = (cell, move) => {
19237
19977
  const { row, column, rows, cells } = positionOf(cell);
19238
19978
  if (move === "right" || move === "left") {
@@ -20117,6 +20857,369 @@ function createRichTextEditor(root, options = {}) {
20117
20857
  };
20118
20858
  }
20119
20859
 
20860
+ // src/components/add-to-cart/engine.ts
20861
+ var BOX = 56;
20862
+ var FLIGHT = 0.62;
20863
+ var resolve = (option, fallback) => option instanceof HTMLElement ? option : typeof option === "string" ? document.querySelector(option) : fallback();
20864
+ function createAddToCart(root, options = {}) {
20865
+ const button2 = root ? root.matches("button") ? root : root.querySelector("button") : null;
20866
+ if (!root || !button2) return inert({ add() {
20867
+ }, setCount() {
20868
+ }, count: 0 });
20869
+ registerMotion();
20870
+ const scope = createScope();
20871
+ const quantity = Number.isFinite(options.quantity) && options.quantity > 0 ? Math.round(options.quantity) : 1;
20872
+ const target = () => resolve(options.target, () => {
20873
+ const all = [...document.querySelectorAll("[data-mk-cart-target]")];
20874
+ return all.find((element) => {
20875
+ const box = element.getBoundingClientRect();
20876
+ return box.width > 0 && box.bottom > 0 && box.top < innerHeight;
20877
+ }) ?? all[0] ?? null;
20878
+ });
20879
+ const image = () => resolve(options.image, () => button2.closest("[data-mk-cart-item]")?.querySelector("[data-mk-cart-image]") ?? null);
20880
+ const counter = () => target()?.querySelector("[data-mk-cart-count]") ?? null;
20881
+ const read = Number.parseInt(counter()?.textContent ?? "", 10);
20882
+ let count = Number.isFinite(options.count) ? Math.max(0, Math.round(options.count)) : Number.isFinite(read) ? read : 0;
20883
+ const status = document.createElement("span");
20884
+ status.className = "mk-sr-only";
20885
+ status.setAttribute("role", "status");
20886
+ root.append(status);
20887
+ scope.add(() => status.remove());
20888
+ scope.attr(root, "data-mk-ready", "");
20889
+ const boxes = /* @__PURE__ */ new Set();
20890
+ const effects = /* @__PURE__ */ new Set();
20891
+ const keep = (animation) => {
20892
+ if (!animation) return;
20893
+ effects.add(animation);
20894
+ for (const effect of effects) if (effect.totalProgress() === 1) effects.delete(effect);
20895
+ };
20896
+ scope.add(() => {
20897
+ for (const effect of effects) effect.kill();
20898
+ effects.clear();
20899
+ for (const box of boxes) box.remove();
20900
+ boxes.clear();
20901
+ });
20902
+ const land = (animate) => {
20903
+ const cart = target();
20904
+ const number2 = counter();
20905
+ const text = String(count);
20906
+ if (number2 && number2.textContent !== text) {
20907
+ if (animate) keep(rollDigits(number2, text, 1, 0.35));
20908
+ else number2.textContent = text;
20909
+ }
20910
+ if (cart && animate) {
20911
+ keep(gsap.fromTo(cart, { scale: 1 }, { scale: 1.1, duration: 0.14, ease: "power2.out", yoyo: true, repeat: 1, clearProps: "transform" }));
20912
+ keep(ringPulse(cart));
20913
+ }
20914
+ status.textContent = `${options.label ?? "A\xF1adido al carrito"}: ${count}`;
20915
+ options.onLand?.(count);
20916
+ root.dispatchEvent(new CustomEvent("mk:land", { bubbles: true, detail: { count } }));
20917
+ };
20918
+ const makeBox = (picture) => {
20919
+ const box = document.createElement("div");
20920
+ box.dataset.mkCartBox = "";
20921
+ box.setAttribute("aria-hidden", "true");
20922
+ let thumb = null;
20923
+ const src = picture instanceof HTMLImageElement ? picture.currentSrc || picture.getAttribute("src") : null;
20924
+ if (src) {
20925
+ thumb = document.createElement("img");
20926
+ thumb.src = src;
20927
+ thumb.alt = "";
20928
+ thumb.dataset.mkCartThumb = "";
20929
+ box.append(thumb);
20930
+ }
20931
+ const front = document.createElement("span");
20932
+ front.dataset.mkCartFront = "";
20933
+ const tape = document.createElement("span");
20934
+ tape.dataset.mkCartTape = "";
20935
+ front.append(tape);
20936
+ const left = document.createElement("span");
20937
+ left.dataset.mkCartFlap = "left";
20938
+ const right = document.createElement("span");
20939
+ right.dataset.mkCartFlap = "right";
20940
+ box.append(front, left, right);
20941
+ return { box, thumb, front, tape, left, right };
20942
+ };
20943
+ const add = () => {
20944
+ if (scope.disposed) return;
20945
+ count += quantity;
20946
+ options.onAdd?.(count);
20947
+ root.dispatchEvent(new CustomEvent("mk:add", { bubbles: true, detail: { count } }));
20948
+ if (reduced()) return land(false);
20949
+ keep(press(button2));
20950
+ const picture = image();
20951
+ const from = (picture ?? button2).getBoundingClientRect();
20952
+ const cart = target();
20953
+ const to = cart?.getBoundingClientRect() ?? null;
20954
+ const { box, thumb, front, tape, left, right } = makeBox(picture);
20955
+ const startX = from.left + from.width / 2 - BOX / 2;
20956
+ const startY = from.top + from.height / 2 - BOX / 2;
20957
+ Object.assign(box.style, { left: `${startX}px`, top: `${startY}px`, width: `${BOX}px`, height: `${BOX}px` });
20958
+ document.body.append(box);
20959
+ boxes.add(box);
20960
+ const gone = () => {
20961
+ box.remove();
20962
+ boxes.delete(box);
20963
+ };
20964
+ const timeline = gsap.timeline({
20965
+ onComplete: () => {
20966
+ gone();
20967
+ land(true);
20968
+ }
20969
+ });
20970
+ if (thumb) {
20971
+ const scale = Math.max(from.width, from.height) / 40 || 1;
20972
+ timeline.fromTo(thumb, { scale, y: 0, opacity: 1 }, { scale: 1, y: -14, duration: 0.32, ease: EASE.signature }, 0);
20973
+ timeline.to(thumb, { y: 4, duration: 0.16, ease: "power2.in" }, 0.3);
20974
+ }
20975
+ timeline.fromTo(front, { scaleY: 0 }, { scaleY: 1, duration: 0.26, ease: EASE.pop }, 0.08);
20976
+ timeline.fromTo([left, right], { opacity: 0 }, { opacity: 1, duration: 0.12 }, 0.12);
20977
+ timeline.fromTo(left, { rotation: -70 }, { rotation: 0, duration: 0.3, ease: EASE.click }, 0.38);
20978
+ timeline.fromTo(right, { rotation: 70 }, { rotation: 0, duration: 0.3, ease: EASE.click }, 0.43);
20979
+ timeline.fromTo(tape, { scaleY: 0 }, { scaleY: 1, duration: 0.16, ease: EASE.wipe }, 0.62);
20980
+ const start = 0.74;
20981
+ if (to) {
20982
+ const dx = to.left + to.width / 2 - (startX + BOX / 2);
20983
+ const dy = to.top + to.height / 2 - (startY + BOX / 2);
20984
+ const lift = Math.min(dy, 0) - 70;
20985
+ timeline.to(box, { x: dx, duration: FLIGHT, ease: EASE.signature }, start);
20986
+ timeline.to(box, { y: lift, duration: FLIGHT * 0.42, ease: "power2.out" }, start);
20987
+ timeline.to(box, { y: dy, duration: FLIGHT * 0.58, ease: "power2.in" }, start + FLIGHT * 0.42);
20988
+ timeline.fromTo(box, { rotation: 0 }, { rotation: 10, scale: 0.55, duration: FLIGHT, ease: "power1.inOut" }, start);
20989
+ timeline.to(box, { scale: 0.15, opacity: 0, duration: 0.14, ease: "power2.in" }, start + FLIGHT - 0.04);
20990
+ } else timeline.to(box, { y: -24, opacity: 0, scale: 0.8, filter: "blur(6px)", duration: 0.3, ease: "power2.in" }, start);
20991
+ keep(timeline);
20992
+ };
20993
+ scope.on(button2, "click", add);
20994
+ return {
20995
+ add,
20996
+ setCount(next) {
20997
+ if (!Number.isFinite(next)) return;
20998
+ count = Math.max(0, Math.round(next));
20999
+ const number2 = counter();
21000
+ if (number2) number2.textContent = String(count);
21001
+ },
21002
+ get count() {
21003
+ return count;
21004
+ },
21005
+ destroy: () => scope.dispose()
21006
+ };
21007
+ }
21008
+
21009
+ // src/components/scroll-island/engine.ts
21010
+ var INSET = 6;
21011
+ var BAR_WIDTH = 4;
21012
+ var ISLAND_HEIGHT = 36;
21013
+ var MIN_BAR = 28;
21014
+ function createScrollIsland(root, options = {}) {
21015
+ if (!root) return inert({ refresh() {
21016
+ } });
21017
+ registerMotion();
21018
+ const scope = createScope();
21019
+ const page = options.page ?? (root === document.documentElement || root === document.body);
21020
+ const scroller = page ? document.scrollingElement ?? document.documentElement : root;
21021
+ const reach = Number.isFinite(options.reach) ? Math.max(8, options.reach) : 56;
21022
+ const idle2 = Number.isFinite(options.idle) ? Math.max(0, options.idle) : 900;
21023
+ const marked3 = page ? document.documentElement : root;
21024
+ scope.attr(marked3, "data-mk-scroll-island-host", "");
21025
+ scope.attr(root, "data-mk-ready", "");
21026
+ const island = document.createElement("div");
21027
+ island.dataset.mkScrollIsland = "";
21028
+ island.dataset.mkState = "hidden";
21029
+ island.setAttribute("aria-hidden", "true");
21030
+ const rail = document.createElement("span");
21031
+ rail.dataset.mkIslandRail = "";
21032
+ const thumb = document.createElement("div");
21033
+ thumb.dataset.mkIslandThumb = "";
21034
+ const content = document.createElement("span");
21035
+ content.dataset.mkIslandContent = "";
21036
+ const percent = document.createElement("span");
21037
+ percent.dataset.mkIslandPercent = "";
21038
+ const sectionText = document.createElement("span");
21039
+ sectionText.dataset.mkIslandSection = "";
21040
+ content.append(percent, sectionText);
21041
+ thumb.append(content);
21042
+ island.append(rail, thumb);
21043
+ document.body.append(island);
21044
+ scope.add(() => island.remove());
21045
+ const effects = /* @__PURE__ */ new Set();
21046
+ const keep = (animation) => {
21047
+ if (!animation) return;
21048
+ effects.add(animation);
21049
+ for (const effect of effects) if (effect.totalProgress() === 1) effects.delete(effect);
21050
+ };
21051
+ scope.add(() => {
21052
+ for (const effect of effects) effect.kill();
21053
+ effects.clear();
21054
+ });
21055
+ const frame = () => page ? { top: 0, left: 0, right: innerWidth, bottom: innerHeight, height: innerHeight } : root.getBoundingClientRect();
21056
+ const track = () => {
21057
+ const box = frame();
21058
+ return { top: box.top + INSET, height: Math.max(0, box.height - INSET * 2), right: box.right, left: box.left, bottom: box.bottom };
21059
+ };
21060
+ const range = () => Math.max(0, scroller.scrollHeight - scroller.clientHeight);
21061
+ const scrollable = () => range() > 1;
21062
+ const progress = () => range() ? Math.min(1, Math.max(0, scroller.scrollTop / range())) : 0;
21063
+ let state = "hidden";
21064
+ let section;
21065
+ let hideTimer;
21066
+ let dragging = null;
21067
+ let scrollBehavior = null;
21068
+ const restoreBehavior = () => {
21069
+ if (!scrollBehavior) return;
21070
+ const previous = scrollBehavior;
21071
+ if (previous.value) scroller.style.setProperty("scroll-behavior", previous.value, previous.priority);
21072
+ else scroller.style.removeProperty("scroll-behavior");
21073
+ if (!previous.hadStyle && !scroller.getAttribute("style")) scroller.removeAttribute("style");
21074
+ scrollBehavior = null;
21075
+ };
21076
+ scope.add(restoreBehavior);
21077
+ scope.add(() => clearTimeout(hideTimer));
21078
+ const headings = () => options.sections === false ? [] : [...(page ? document.body : root).querySelectorAll(options.sections ?? "h2, h3")];
21079
+ const currentSection = () => {
21080
+ const box = frame();
21081
+ const line = box.top + scroller.clientHeight * 0.3;
21082
+ let found = null;
21083
+ for (const heading of headings()) if (heading.getBoundingClientRect().top <= line) found = heading;
21084
+ return found?.textContent?.trim() || null;
21085
+ };
21086
+ const geometry = (as) => {
21087
+ const { height } = track();
21088
+ const size = as === "island" ? ISLAND_HEIGHT : Math.max(MIN_BAR, Math.min(height, height * (scroller.clientHeight / Math.max(1, scroller.scrollHeight))));
21089
+ const top = (height - size) * progress();
21090
+ if (as !== "island") return { top, height: size, width: BAR_WIDTH, borderRadius: BAR_WIDTH / 2 };
21091
+ return { top, height: size, width: Math.min(Math.max(ISLAND_HEIGHT, track().right - track().left - INSET * 2), Math.max(ISLAND_HEIGHT, content.scrollWidth + 28)), borderRadius: size / 2 };
21092
+ };
21093
+ const place3 = () => {
21094
+ const box = track();
21095
+ Object.assign(island.style, { top: `${box.top}px`, height: `${box.height}px`, left: `${box.left}px`, width: `${Math.max(0, box.right - box.left - 4)}px` });
21096
+ };
21097
+ const paintText = () => {
21098
+ percent.textContent = `${Math.round(progress() * 100)} %`;
21099
+ const now2 = currentSection();
21100
+ if (now2 !== section) {
21101
+ const first = section === void 0;
21102
+ section = now2;
21103
+ sectionText.textContent = now2 ?? "";
21104
+ sectionText.hidden = !now2;
21105
+ if (!first && state === "island" && !reduced()) keep(blurIn(sectionText, { from: "soft", duration: 0.3 }));
21106
+ options.onSection?.(now2);
21107
+ root.dispatchEvent(new CustomEvent("mk:section", { bubbles: true, detail: { section: now2 } }));
21108
+ }
21109
+ };
21110
+ const go = (next, follow = false) => {
21111
+ if (!scrollable()) next = "hidden";
21112
+ const changed = next !== state;
21113
+ state = next;
21114
+ island.dataset.mkState = next;
21115
+ place3();
21116
+ const shape = geometry(next === "hidden" ? "bar" : next);
21117
+ if (follow || !changed || reduced()) {
21118
+ gsap.killTweensOf(thumb);
21119
+ gsap.set(thumb, shape);
21120
+ return;
21121
+ }
21122
+ gsap.killTweensOf(thumb);
21123
+ keep(gsap.to(thumb, { ...shape, duration: next === "island" ? 0.42 : 0.32, ease: next === "island" ? EASE.swatch : "power3.out" }));
21124
+ };
21125
+ const settleLater = () => {
21126
+ clearTimeout(hideTimer);
21127
+ hideTimer = setTimeout(() => {
21128
+ if (state === "bar" && !dragging && !options.persistent) go("hidden");
21129
+ }, idle2);
21130
+ };
21131
+ const onScroll = () => {
21132
+ paintText();
21133
+ if (state === "island" || dragging) go(state, true);
21134
+ else {
21135
+ go("bar", true);
21136
+ settleLater();
21137
+ }
21138
+ };
21139
+ scope.on(page ? window : root, "scroll", onScroll, { passive: true });
21140
+ if (!page) scope.on(window, "scroll", () => state !== "hidden" && place3(), { passive: true, capture: true });
21141
+ scope.on(window, "resize", () => go(state, true));
21142
+ const near = (x, y) => {
21143
+ const box = track();
21144
+ return y >= box.top - INSET && y <= box.top + box.height + INSET && x <= box.right && box.right - x <= reach;
21145
+ };
21146
+ scope.on(window, "pointermove", (event) => {
21147
+ const move = event;
21148
+ if (move.pointerType === "touch") return;
21149
+ if (dragging) {
21150
+ if (move.pointerId !== dragging.id) return;
21151
+ const box = track();
21152
+ const shape = geometry("island");
21153
+ const ratio = (move.clientY - box.top - dragging.offset) / Math.max(1, box.height - shape.height);
21154
+ scroller.scrollTop = Math.min(1, Math.max(0, ratio)) * range();
21155
+ onScroll();
21156
+ return;
21157
+ }
21158
+ if (near(move.clientX, move.clientY)) {
21159
+ if (state !== "island" && scrollable()) {
21160
+ clearTimeout(hideTimer);
21161
+ paintText();
21162
+ go("island");
21163
+ }
21164
+ } else if (state === "island") {
21165
+ const box = track();
21166
+ if (box.right - move.clientX > reach + 24 || move.clientY < box.top - 24 || move.clientY > box.top + box.height + 24) {
21167
+ go("bar");
21168
+ settleLater();
21169
+ }
21170
+ }
21171
+ });
21172
+ scope.on(thumb, "pointerdown", (event) => {
21173
+ const down = event;
21174
+ if (state !== "island" || down.button !== 0) return;
21175
+ down.preventDefault();
21176
+ down.stopPropagation();
21177
+ if (!scrollBehavior) scrollBehavior = { value: scroller.style.getPropertyValue("scroll-behavior"), priority: scroller.style.getPropertyPriority("scroll-behavior"), hadStyle: scroller.hasAttribute("style") };
21178
+ scroller.style.setProperty("scroll-behavior", "auto", "important");
21179
+ const box = thumb.getBoundingClientRect();
21180
+ dragging = { id: down.pointerId, offset: down.clientY - box.top || ISLAND_HEIGHT / 2 };
21181
+ island.setAttribute("data-mk-dragging", "");
21182
+ try {
21183
+ thumb.setPointerCapture(down.pointerId);
21184
+ } catch {
21185
+ }
21186
+ });
21187
+ const release = (event) => {
21188
+ if (!dragging || event.pointerId !== dragging.id) return;
21189
+ dragging = null;
21190
+ restoreBehavior();
21191
+ island.removeAttribute("data-mk-dragging");
21192
+ };
21193
+ scope.on(window, "pointerup", release);
21194
+ scope.on(window, "pointercancel", release);
21195
+ scope.on(rail, "pointerdown", (event) => {
21196
+ const down = event;
21197
+ if (state !== "island" || down.button !== 0) return;
21198
+ down.preventDefault();
21199
+ const box = track();
21200
+ const size = geometry("island").height;
21201
+ const ratio = (down.clientY - box.top - size / 2) / Math.max(1, box.height - size);
21202
+ scroller.scrollTo({ top: Math.round(Math.min(1, Math.max(0, ratio)) * range()), behavior: reduced() ? "auto" : "smooth" });
21203
+ });
21204
+ paintText();
21205
+ go(options.persistent ? "bar" : "hidden");
21206
+ if (typeof ResizeObserver === "function") {
21207
+ const observer = scope.observe(new ResizeObserver(() => {
21208
+ paintText();
21209
+ go(state, true);
21210
+ }));
21211
+ observer.observe(root);
21212
+ for (const child of root.children) observer.observe(child);
21213
+ }
21214
+ return {
21215
+ refresh: () => {
21216
+ paintText();
21217
+ go(state, true);
21218
+ },
21219
+ destroy: () => scope.dispose()
21220
+ };
21221
+ }
21222
+
20120
21223
  export {
20121
21224
  PATHS,
20122
21225
  springPath,
@@ -20202,23 +21305,28 @@ export {
20202
21305
  createChatBackground,
20203
21306
  createSteps,
20204
21307
  createQuantity,
21308
+ press,
21309
+ blurIn,
21310
+ blurOut,
21311
+ collapse,
21312
+ shake,
21313
+ ringPulse,
21314
+ burst,
21315
+ rollDigits,
20205
21316
  createPagination,
20206
21317
  createHoverCard,
20207
21318
  createInputOtp,
20208
21319
  createStudioDock,
20209
21320
  createTrailer,
20210
21321
  toDate,
21322
+ addDays,
21323
+ startOfWeek,
20211
21324
  dayKey,
21325
+ weekdayNames,
21326
+ safeFormat,
21327
+ capitalize,
20212
21328
  createCalendar,
20213
21329
  createSlotPicker,
20214
- press,
20215
- blurIn,
20216
- blurOut,
20217
- collapse,
20218
- shake,
20219
- ringPulse,
20220
- burst,
20221
- rollDigits,
20222
21330
  formatBytes,
20223
21331
  describeAccept,
20224
21332
  acceptsFile,
@@ -20305,6 +21413,7 @@ export {
20305
21413
  matchesFilter,
20306
21414
  hasConditions,
20307
21415
  describeFilter,
21416
+ createSelect,
20308
21417
  createFilterBuilder,
20309
21418
  relativeTime,
20310
21419
  dayLabel,
@@ -20329,6 +21438,8 @@ export {
20329
21438
  createDataTable,
20330
21439
  createEditableTable,
20331
21440
  sanitizeHtml,
20332
- createRichTextEditor
21441
+ createRichTextEditor,
21442
+ createAddToCart,
21443
+ createScrollIsland
20333
21444
  };
20334
- //# sourceMappingURL=chunk-CU6SXW3E.js.map
21445
+ //# sourceMappingURL=chunk-SDQ776LG.js.map