@yewdiel21/motion-kit 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/auto/index.d.ts +18 -3
- package/dist/auto/index.js +32 -2
- package/dist/auto/index.js.map +1 -1
- package/dist/{chunk-VJFPTLAK.js → chunk-AWDEKDEJ.js} +2 -2
- package/dist/{chunk-BZLMCHUD.js → chunk-EDMXWUW3.js} +2 -2
- package/dist/{chunk-7IQTMF7Y.js → chunk-Q7IW4FV3.js} +2580 -58
- package/dist/chunk-Q7IW4FV3.js.map +1 -0
- package/dist/css/components/badge-button.css +16 -0
- package/dist/css/components/bento-grid.css +13 -0
- package/dist/css/components/drilldown-menu.css +11 -7
- package/dist/css/components/equalizer-slider.css +26 -0
- package/dist/css/components/handwriting-text.css +15 -0
- package/dist/css/components/magnetize-button.css +18 -0
- package/dist/css/components/morphing-page-dots.css +13 -0
- package/dist/css/components/not-found.css +22 -0
- package/dist/css/components/notification-stack.css +42 -0
- package/dist/css/components/particle-button.css +14 -0
- package/dist/css/components/radio-group.css +29 -0
- package/dist/css/components/rating-scale.css +23 -0
- package/dist/css/components/scroll-preview-dock.css +18 -0
- package/dist/css/components/select.css +16 -0
- package/dist/css/components/signature-pad.css +130 -103
- package/dist/css/components/stepper.css +36 -0
- package/dist/css/components/sticky-header.css +10 -0
- package/dist/css/components/temperature-slider.css +29 -0
- package/dist/css/components/voice-message-bubble.css +62 -45
- package/dist/css/components/waveform-player.css +49 -34
- package/dist/css/components/wheel-picker.css +16 -15
- package/dist/css/tokens.css +4 -0
- package/dist/elements/index.d.ts +206 -4
- package/dist/elements/index.js +581 -6
- package/dist/elements/index.js.map +1 -1
- package/dist/{engine-Bn6hC87X.d.ts → engine-t8d7brjn.d.ts} +341 -1
- package/dist/index.css +578 -170
- package/dist/index.d.ts +23 -23
- package/dist/index.js +33 -3
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +113 -7
- package/dist/react/index.js +669 -3
- package/dist/react/index.js.map +1 -1
- package/dist/{reduced-YS6TZjpa.d.ts → reduced-dPsZYqtI.d.ts} +1 -1
- package/dist/{store-CZ6vdtIE.d.ts → store-6hZNKiee.d.ts} +1 -1
- package/package.json +1 -1
- package/registry.json +180 -0
- package/src/auto/auto-init.ts +31 -0
- package/src/components/badge-button/README.md +28 -0
- package/src/components/badge-button/badge-button.css +15 -0
- package/src/components/badge-button/element.ts +16 -0
- package/src/components/badge-button/engine.ts +85 -0
- package/src/components/badge-button/react.tsx +31 -0
- package/src/components/bento-grid/README.md +26 -0
- package/src/components/bento-grid/bento-grid.css +12 -0
- package/src/components/bento-grid/element.ts +22 -0
- package/src/components/bento-grid/engine.ts +153 -0
- package/src/components/bento-grid/react.tsx +25 -0
- package/src/components/drilldown-menu/drilldown-menu.css +11 -7
- package/src/components/drilldown-menu/engine.ts +44 -4
- package/src/components/equalizer-slider/README.md +43 -0
- package/src/components/equalizer-slider/element.ts +41 -0
- package/src/components/equalizer-slider/engine.ts +32 -0
- package/src/components/equalizer-slider/equalizer-slider.css +26 -0
- package/src/components/equalizer-slider/react.tsx +60 -0
- package/src/components/equalizer-slider/shared.ts +161 -0
- package/src/components/handwriting-text/README.md +29 -0
- package/src/components/handwriting-text/element.ts +14 -0
- package/src/components/handwriting-text/engine.ts +108 -0
- package/src/components/handwriting-text/glyphs.ts +71 -0
- package/src/components/handwriting-text/handwriting-text.css +14 -0
- package/src/components/handwriting-text/react.tsx +23 -0
- package/src/components/magnetize-button/README.md +26 -0
- package/src/components/magnetize-button/element.ts +13 -0
- package/src/components/magnetize-button/engine.ts +84 -0
- package/src/components/magnetize-button/magnetize-button.css +17 -0
- package/src/components/magnetize-button/react.tsx +22 -0
- package/src/components/morphing-page-dots/README.md +28 -0
- package/src/components/morphing-page-dots/element.ts +16 -0
- package/src/components/morphing-page-dots/engine.ts +89 -0
- package/src/components/morphing-page-dots/morphing-page-dots.css +12 -0
- package/src/components/morphing-page-dots/react.tsx +32 -0
- package/src/components/not-found/README.md +26 -0
- package/src/components/not-found/element.ts +15 -0
- package/src/components/not-found/engine.ts +57 -0
- package/src/components/not-found/not-found.css +21 -0
- package/src/components/not-found/react.tsx +23 -0
- package/src/components/notification-stack/README.md +24 -0
- package/src/components/notification-stack/element.ts +26 -0
- package/src/components/notification-stack/engine.ts +329 -0
- package/src/components/notification-stack/notification-stack.css +41 -0
- package/src/components/notification-stack/react.tsx +28 -0
- package/src/components/particle-button/README.md +26 -0
- package/src/components/particle-button/element.ts +13 -0
- package/src/components/particle-button/engine.ts +52 -0
- package/src/components/particle-button/particle-button.css +13 -0
- package/src/components/particle-button/react.tsx +22 -0
- package/src/components/radio-group/README.md +43 -0
- package/src/components/radio-group/element.ts +41 -0
- package/src/components/radio-group/engine.ts +11 -0
- package/src/components/radio-group/radio-group.css +28 -0
- package/src/components/radio-group/react.tsx +60 -0
- package/src/components/radio-group/shared.ts +118 -0
- package/src/components/rating-scale/README.md +43 -0
- package/src/components/rating-scale/element.ts +41 -0
- package/src/components/rating-scale/engine.ts +63 -0
- package/src/components/rating-scale/rating-scale.css +22 -0
- package/src/components/rating-scale/react.tsx +60 -0
- package/src/components/scroll-preview-dock/README.md +24 -0
- package/src/components/scroll-preview-dock/element.ts +20 -0
- package/src/components/scroll-preview-dock/engine.ts +228 -0
- package/src/components/scroll-preview-dock/react.tsx +26 -0
- package/src/components/scroll-preview-dock/scroll-preview-dock.css +17 -0
- package/src/components/select/README.md +23 -9
- package/src/components/select/select.css +16 -0
- package/src/components/signature-pad/engine.ts +550 -437
- package/src/components/signature-pad/signature-pad.css +130 -103
- package/src/components/stepper/README.md +46 -0
- package/src/components/stepper/element.ts +42 -0
- package/src/components/stepper/engine.ts +103 -0
- package/src/components/stepper/react.tsx +60 -0
- package/src/components/stepper/stepper.css +35 -0
- package/src/components/sticky-header/README.md +30 -0
- package/src/components/sticky-header/element.ts +19 -0
- package/src/components/sticky-header/engine.ts +95 -0
- package/src/components/sticky-header/react.tsx +25 -0
- package/src/components/sticky-header/sticky-header.css +9 -0
- package/src/components/temperature-slider/README.md +42 -0
- package/src/components/temperature-slider/element.ts +53 -0
- package/src/components/temperature-slider/engine.ts +44 -0
- package/src/components/temperature-slider/react.tsx +66 -0
- package/src/components/temperature-slider/temperature-slider.css +29 -0
- package/src/components/voice-message-bubble/engine.ts +11 -0
- package/src/components/voice-message-bubble/voice-message-bubble.css +14 -12
- package/src/components/waveform-player/README.md +1 -1
- package/src/components/waveform-player/engine.ts +344 -261
- package/src/components/waveform-player/waveform-player.css +50 -35
- package/src/components/wheel-picker/README.md +3 -1
- package/src/components/wheel-picker/element.ts +12 -5
- package/src/components/wheel-picker/engine.ts +37 -8
- package/src/components/wheel-picker/wheel-picker.css +17 -16
- package/src/css/tokens.css +4 -0
- package/src/elements/index.ts +45 -0
- package/src/index.ts +311 -295
- package/src/react/index.ts +16 -0
- package/dist/chunk-7IQTMF7Y.js.map +0 -1
- /package/dist/{chunk-VJFPTLAK.js.map → chunk-AWDEKDEJ.js.map} +0 -0
- /package/dist/{chunk-BZLMCHUD.js.map → chunk-EDMXWUW3.js.map} +0 -0
|
@@ -2700,7 +2700,7 @@ function createQuantity(root, options = {}) {
|
|
|
2700
2700
|
const step = Number.isFinite(options.step) && options.step > 0 ? options.step : 1;
|
|
2701
2701
|
const steps = Math.floor((max - min) / step + 1e-9);
|
|
2702
2702
|
const upper = Math.min(max, Number((min + steps * step).toFixed(10)));
|
|
2703
|
-
const
|
|
2703
|
+
const normalize3 = (n) => Math.max(min, Math.min(upper, Number((min + Math.round((n - min) / step) * step).toFixed(10))));
|
|
2704
2704
|
const original = input.value;
|
|
2705
2705
|
const disabled = options.disabled ?? input.disabled;
|
|
2706
2706
|
const decrease = root.querySelector("[data-mk-quantity-decrease]");
|
|
@@ -2711,13 +2711,13 @@ function createQuantity(root, options = {}) {
|
|
|
2711
2711
|
scope.attr(input, "disabled", disabled ? "" : null);
|
|
2712
2712
|
scope.attr(root, "data-mk-ready", "");
|
|
2713
2713
|
const initial = input.value.trim() ? Number(input.value) : NaN;
|
|
2714
|
-
let value =
|
|
2714
|
+
let value = normalize3(Number.isFinite(options.value) ? options.value : Number.isFinite(initial) ? initial : min);
|
|
2715
2715
|
let pendingReset = null;
|
|
2716
2716
|
const typed = () => input.value.trim() && Number.isFinite(input.valueAsNumber) ? input.valueAsNumber : NaN;
|
|
2717
2717
|
const render = (syncInput = true) => {
|
|
2718
2718
|
if (pendingReset) {
|
|
2719
2719
|
if (pendingReset.eventPhase !== 0) return;
|
|
2720
|
-
if (!pendingReset.defaultPrevented) value =
|
|
2720
|
+
if (!pendingReset.defaultPrevented) value = normalize3(Number.isFinite(typed()) ? typed() : min);
|
|
2721
2721
|
pendingReset = null;
|
|
2722
2722
|
}
|
|
2723
2723
|
if (syncInput) input.value = String(value);
|
|
@@ -2728,7 +2728,7 @@ function createQuantity(root, options = {}) {
|
|
|
2728
2728
|
if (scope.disposed || !Number.isFinite(next)) return;
|
|
2729
2729
|
if (pendingReset?.eventPhase === 0) pendingReset = null;
|
|
2730
2730
|
const previous = value;
|
|
2731
|
-
value =
|
|
2731
|
+
value = normalize3(next);
|
|
2732
2732
|
render(syncInput);
|
|
2733
2733
|
if (notify && value !== previous) {
|
|
2734
2734
|
options.onChange?.(value);
|
|
@@ -2744,7 +2744,7 @@ function createQuantity(root, options = {}) {
|
|
|
2744
2744
|
});
|
|
2745
2745
|
scope.on(input, "input", () => {
|
|
2746
2746
|
const n = typed();
|
|
2747
|
-
if (Number.isFinite(n) &&
|
|
2747
|
+
if (Number.isFinite(n) && normalize3(n) === n) commit(n, true, false);
|
|
2748
2748
|
});
|
|
2749
2749
|
scope.on(input, "change", () => {
|
|
2750
2750
|
if (Number.isFinite(typed())) setValue(typed());
|
|
@@ -6055,13 +6055,13 @@ function createRangeSlider(root, options = {}) {
|
|
|
6055
6055
|
const places = Math.min(10, Math.max(decimals(step), decimals(min)));
|
|
6056
6056
|
const fix = (n) => Number(n.toFixed(places));
|
|
6057
6057
|
const upper = Math.min(max, fix(min + Math.floor((max - min) / step + 1e-9) * step));
|
|
6058
|
-
const
|
|
6058
|
+
const normalize3 = (n) => Math.max(min, Math.min(upper, fix(min + Math.round((n - min) / step) * step)));
|
|
6059
6059
|
const disabled = options.disabled ?? inputs.some((input) => input.disabled);
|
|
6060
6060
|
const output = root.querySelector("[data-mk-range-output]");
|
|
6061
6061
|
const format = (n) => options.formatValue ? options.formatValue(n) : String(n);
|
|
6062
6062
|
const originals = inputs.map((input) => input.value);
|
|
6063
6063
|
const ordered = (list3) => pair ? [...list3].sort((a, b) => a - b) : list3;
|
|
6064
|
-
const read = () => inputs.map((input) => input.value.trim() !== "" && Number.isFinite(Number(input.value)) ?
|
|
6064
|
+
const read = () => inputs.map((input) => input.value.trim() !== "" && Number.isFinite(Number(input.value)) ? normalize3(Number(input.value)) : NaN);
|
|
6065
6065
|
const authored = () => {
|
|
6066
6066
|
const current4 = read();
|
|
6067
6067
|
return inputs.map((input, i) => {
|
|
@@ -6069,7 +6069,7 @@ function createRangeSlider(root, options = {}) {
|
|
|
6069
6069
|
if (written === void 0) return current4[i];
|
|
6070
6070
|
const low = attrNumber(input, "min") ?? 0;
|
|
6071
6071
|
const high = Math.max(low, attrNumber(input, "max") ?? 100);
|
|
6072
|
-
return Number(input.value) === Math.min(high, Math.max(low, written)) ?
|
|
6072
|
+
return Number(input.value) === Math.min(high, Math.max(low, written)) ? normalize3(written) : current4[i];
|
|
6073
6073
|
});
|
|
6074
6074
|
};
|
|
6075
6075
|
const initial = (() => {
|
|
@@ -6078,7 +6078,7 @@ function createRangeSlider(root, options = {}) {
|
|
|
6078
6078
|
const fromInputs = authored();
|
|
6079
6079
|
return inputs.map((_, i) => {
|
|
6080
6080
|
const candidate = fromOption?.[i];
|
|
6081
|
-
if (finite2(candidate)) return
|
|
6081
|
+
if (finite2(candidate)) return normalize3(candidate);
|
|
6082
6082
|
return Number.isFinite(fromInputs[i]) ? fromInputs[i] : i === 0 ? min : upper;
|
|
6083
6083
|
});
|
|
6084
6084
|
})();
|
|
@@ -6188,7 +6188,7 @@ function createRangeSlider(root, options = {}) {
|
|
|
6188
6188
|
};
|
|
6189
6189
|
const take = (i) => {
|
|
6190
6190
|
const raw = inputs[i].value;
|
|
6191
|
-
const n = raw.trim() !== "" && Number.isFinite(Number(raw)) ?
|
|
6191
|
+
const n = raw.trim() !== "" && Number.isFinite(Number(raw)) ? normalize3(Number(raw)) : NaN;
|
|
6192
6192
|
if (!Number.isFinite(n)) return false;
|
|
6193
6193
|
let next = n;
|
|
6194
6194
|
if (pair) next = i === 0 ? Math.min(next, values[1]) : Math.max(next, values[0]);
|
|
@@ -6257,7 +6257,7 @@ function createRangeSlider(root, options = {}) {
|
|
|
6257
6257
|
setValue(next, notify = true) {
|
|
6258
6258
|
if (scope.disposed) return;
|
|
6259
6259
|
const list3 = Array.isArray(next) ? next : [next, next];
|
|
6260
|
-
const candidate = inputs.map((_, i) => finite2(list3[i]) ?
|
|
6260
|
+
const candidate = inputs.map((_, i) => finite2(list3[i]) ? normalize3(list3[i]) : values[i]);
|
|
6261
6261
|
values = ordered(candidate);
|
|
6262
6262
|
render(dragging >= 0 ? "drag" : "glide");
|
|
6263
6263
|
if (notify) commit(true);
|
|
@@ -8684,13 +8684,13 @@ function createPasswordStrength(root, options = {}) {
|
|
|
8684
8684
|
let lit = 0;
|
|
8685
8685
|
const paint = (animate) => {
|
|
8686
8686
|
const previous = lit;
|
|
8687
|
-
const
|
|
8688
|
-
lit =
|
|
8687
|
+
const level2 = input.value ? Math.max(1, result.score) : 0;
|
|
8688
|
+
lit = level2;
|
|
8689
8689
|
scope.attr(root, "data-mk-score", input.value ? String(result.score) : null);
|
|
8690
8690
|
const bars = segments.map((segment) => segment.firstElementChild);
|
|
8691
|
-
if (!animate || reduced()) gsap.set(bars, { scaleX: (i) => i <
|
|
8692
|
-
else if (
|
|
8693
|
-
else if (
|
|
8691
|
+
if (!animate || reduced()) gsap.set(bars, { scaleX: (i) => i < level2 ? 1 : 0 });
|
|
8692
|
+
else if (level2 > previous) keep(gsap.fromTo(bars.slice(previous, level2), { scaleX: 0 }, { scaleX: 1, duration: 0.35, ease: EASE.swatch, stagger: 0.07 }));
|
|
8693
|
+
else if (level2 < previous) keep(gsap.to(bars.slice(level2, previous).reverse(), { scaleX: 0, duration: 0.2, ease: "power2.in", stagger: 0.04 }));
|
|
8694
8694
|
if (label.textContent !== result.label) {
|
|
8695
8695
|
if (!animate || reduced()) label.textContent = result.label;
|
|
8696
8696
|
else {
|
|
@@ -21335,7 +21335,14 @@ function createSignaturePad(root, options = {}) {
|
|
|
21335
21335
|
placeholder2.dataset.mkSignaturePlaceholder = "";
|
|
21336
21336
|
placeholder2.setAttribute("aria-hidden", "true");
|
|
21337
21337
|
placeholder2.textContent = options.placeholder ?? "Firma aqu\xED";
|
|
21338
|
-
|
|
21338
|
+
const pen = document.createElement("span");
|
|
21339
|
+
pen.dataset.mkSignatureCursor = "";
|
|
21340
|
+
pen.setAttribute("aria-hidden", "true");
|
|
21341
|
+
const ghost = document.createElementNS(SVG_NS, "svg");
|
|
21342
|
+
ghost.setAttribute("data-mk-signature-ghost", "");
|
|
21343
|
+
ghost.setAttribute("aria-hidden", "true");
|
|
21344
|
+
ghost.setAttribute("preserveAspectRatio", "none");
|
|
21345
|
+
surface.append(svg2, ghost, placeholder2, pen);
|
|
21339
21346
|
const footer = document.createElement("div");
|
|
21340
21347
|
footer.dataset.mkSignatureFooter = "";
|
|
21341
21348
|
const toolbar = document.createElement("div");
|
|
@@ -21346,7 +21353,11 @@ function createSignaturePad(root, options = {}) {
|
|
|
21346
21353
|
const button2 = document.createElement("button");
|
|
21347
21354
|
button2.type = "button";
|
|
21348
21355
|
button2.dataset.mkSignatureAction = action;
|
|
21349
|
-
|
|
21356
|
+
const paths = { undo: "M9 5 4 10l5 5M4 10h9a6 6 0 0 1 6 6", redo: "m15 5 5 5-5 5m5-5h-9a6 6 0 0 0-6 6", clear: "m9 5 1-2h4l1 2M4 6h16M7 6l1 15h8l1-15M10 10v7m4-7v7" };
|
|
21357
|
+
button2.innerHTML = `<svg viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="${paths[action]}"/></svg>`;
|
|
21358
|
+
const caption = document.createElement("span");
|
|
21359
|
+
caption.textContent = text;
|
|
21360
|
+
button2.append(caption);
|
|
21350
21361
|
toolbar.append(button2);
|
|
21351
21362
|
return button2;
|
|
21352
21363
|
};
|
|
@@ -21358,13 +21369,17 @@ function createSignaturePad(root, options = {}) {
|
|
|
21358
21369
|
status.dataset.mkSignatureStatus = "";
|
|
21359
21370
|
status.setAttribute("role", "status");
|
|
21360
21371
|
status.setAttribute("aria-live", "polite");
|
|
21361
|
-
|
|
21372
|
+
const heading = document.createElement("div");
|
|
21373
|
+
heading.dataset.mkSignatureHeader = "";
|
|
21374
|
+
const title = document.createElement("span");
|
|
21375
|
+
title.textContent = options.label ?? "Tu firma";
|
|
21376
|
+
heading.append(title, status);
|
|
21362
21377
|
const hint = document.createElement("p");
|
|
21363
21378
|
hint.dataset.mkSignatureHint = "";
|
|
21364
21379
|
hint.id = `mk-signature-hint-${++nextId2}`;
|
|
21365
21380
|
hint.textContent = options.hint ?? "Dibuja con el rat\xF3n, el dedo o un l\xE1piz. Puedes deshacer cada trazo.";
|
|
21366
21381
|
svg2.setAttribute("aria-describedby", hint.id);
|
|
21367
|
-
wrapper.append(surface, footer, hint);
|
|
21382
|
+
wrapper.append(heading, surface, footer, hint);
|
|
21368
21383
|
let hidden = null;
|
|
21369
21384
|
if (options.name) {
|
|
21370
21385
|
hidden = document.createElement("input");
|
|
@@ -21374,11 +21389,37 @@ function createSignaturePad(root, options = {}) {
|
|
|
21374
21389
|
}
|
|
21375
21390
|
root.append(wrapper);
|
|
21376
21391
|
scope.add(() => wrapper.remove());
|
|
21377
|
-
for (const name of ["data-mk-disabled", "data-mk-readonly", "data-mk-drawing", "data-mk-empty"]) scope.attr(root, name, null);
|
|
21392
|
+
for (const name of ["data-mk-disabled", "data-mk-readonly", "data-mk-drawing", "data-mk-empty", "data-mk-pen-visible"]) scope.attr(root, name, null);
|
|
21378
21393
|
scope.attr(root, "data-mk-ready", "");
|
|
21379
21394
|
let dimensions = { width: 640, height: 240 };
|
|
21380
21395
|
let active = null;
|
|
21381
|
-
|
|
21396
|
+
const effects = /* @__PURE__ */ new Set();
|
|
21397
|
+
const statusCount = document.createElement("span");
|
|
21398
|
+
const statusLabel = document.createElement("span");
|
|
21399
|
+
let shown4 = null;
|
|
21400
|
+
const paintStatus = () => {
|
|
21401
|
+
const count = strokes.length;
|
|
21402
|
+
if (shown4 && shown4.count === count && shown4.readOnly === readOnly) return;
|
|
21403
|
+
const before = shown4;
|
|
21404
|
+
shown4 = { count, readOnly };
|
|
21405
|
+
const animate = before !== null && !reduced();
|
|
21406
|
+
if (!count) {
|
|
21407
|
+
status.textContent = "Sin firma";
|
|
21408
|
+
if (animate && before.count) keep(blurIn(status, { from: "soft", duration: 0.25 }));
|
|
21409
|
+
return;
|
|
21410
|
+
}
|
|
21411
|
+
statusLabel.replaceChildren(statusCount, ` ${count === 1 ? "trazo" : "trazos"} \xB7 ${readOnly ? "Solo lectura" : "Firma capturada"}`);
|
|
21412
|
+
status.replaceChildren(statusLabel);
|
|
21413
|
+
if (animate && before.count) keep(rollDigits(statusCount, String(count), count > before.count ? 1 : -1, 0.3));
|
|
21414
|
+
else {
|
|
21415
|
+
statusCount.textContent = String(count);
|
|
21416
|
+
if (animate) keep(blurIn(status, { from: "soft", duration: 0.25 }));
|
|
21417
|
+
}
|
|
21418
|
+
};
|
|
21419
|
+
const keep = (effect) => {
|
|
21420
|
+
for (const animation of effects) if (animation.totalProgress() === 1) effects.delete(animation);
|
|
21421
|
+
if (effect) effects.add(effect);
|
|
21422
|
+
};
|
|
21382
21423
|
const locked = () => disabled || readOnly;
|
|
21383
21424
|
const update = () => {
|
|
21384
21425
|
root.toggleAttribute("data-mk-empty", !strokes.length && !active);
|
|
@@ -21389,7 +21430,7 @@ function createSignaturePad(root, options = {}) {
|
|
|
21389
21430
|
undoButton.disabled = locked() || !undoStack.length;
|
|
21390
21431
|
redoButton.disabled = locked() || !redoStack.length;
|
|
21391
21432
|
clearButton.disabled = locked() || !strokes.length;
|
|
21392
|
-
|
|
21433
|
+
paintStatus();
|
|
21393
21434
|
if (hidden) {
|
|
21394
21435
|
hidden.disabled = disabled;
|
|
21395
21436
|
hidden.value = JSON.stringify(exportData());
|
|
@@ -21432,39 +21473,103 @@ function createSignaturePad(root, options = {}) {
|
|
|
21432
21473
|
redoStack = [];
|
|
21433
21474
|
};
|
|
21434
21475
|
const pulse = (button2) => {
|
|
21435
|
-
|
|
21476
|
+
keep(press(button2));
|
|
21477
|
+
const icon2 = button2.querySelector("svg");
|
|
21478
|
+
const turn = button2 === undoButton ? -50 : button2 === redoButton ? 50 : -14;
|
|
21479
|
+
if (icon2 && !reduced()) keep(gsap.fromTo(icon2, { rotate: turn }, { rotate: 0, duration: 0.5, ease: EASE.click, overwrite: "auto", clearProps: "transform" }));
|
|
21480
|
+
};
|
|
21481
|
+
const wipeId = `mk-signature-wipe-${++nextId2}`;
|
|
21482
|
+
let wipes = 0;
|
|
21483
|
+
const animateInk = (before, reason) => {
|
|
21436
21484
|
if (reduced()) return;
|
|
21437
|
-
|
|
21485
|
+
const { width, height } = dimensions;
|
|
21486
|
+
const byX = (a, b) => (a.points[0]?.x ?? 0) - (b.points[0]?.x ?? 0);
|
|
21487
|
+
const removed = before.filter((stroke) => !strokes.includes(stroke)).sort(byX);
|
|
21488
|
+
const added = strokes.filter((stroke) => !before.includes(stroke)).sort(byX);
|
|
21489
|
+
ghost.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
21490
|
+
if (removed.length && reason === "clear") {
|
|
21491
|
+
const svgNode = (tag, attributes) => {
|
|
21492
|
+
const node = document.createElementNS(SVG_NS, tag);
|
|
21493
|
+
for (const [name, value] of Object.entries(attributes)) node.setAttribute(name, String(value));
|
|
21494
|
+
return node;
|
|
21495
|
+
};
|
|
21496
|
+
const points = removed.flatMap((stroke) => stroke.points);
|
|
21497
|
+
const pad3 = inkWidth * 2 + 8;
|
|
21498
|
+
const left = Math.min(...points.map((point) => point.x)) * width - pad3;
|
|
21499
|
+
const right = Math.max(...points.map((point) => point.x)) * width + pad3;
|
|
21500
|
+
const top = Math.max(0, Math.min(...points.map((point) => point.y)) * height - pad3);
|
|
21501
|
+
const bottom = Math.min(height, Math.max(...points.map((point) => point.y)) * height + pad3);
|
|
21502
|
+
const id = `${wipeId}-${++wipes}`;
|
|
21503
|
+
const clip = svgNode("clipPath", { id });
|
|
21504
|
+
const reveal = svgNode("rect", { x: left, y: 0, width: width * 2, height });
|
|
21505
|
+
clip.append(reveal);
|
|
21506
|
+
const ink = svgNode("g", { "clip-path": `url(#${id})` });
|
|
21507
|
+
ink.append(...removed.map((stroke) => makePath(stroke, width, height)));
|
|
21508
|
+
const edge = svgNode("rect", { x: left, y: top, width: 2, height: Math.max(24, bottom - top), rx: 1, fill: "currentColor", opacity: 0 });
|
|
21509
|
+
ghost.append(clip, ink, edge);
|
|
21510
|
+
const done = () => {
|
|
21511
|
+
clip.remove();
|
|
21512
|
+
ink.remove();
|
|
21513
|
+
edge.remove();
|
|
21514
|
+
};
|
|
21515
|
+
const sweep = Math.min(0.6, Math.max(0.36, (right - left) / 900));
|
|
21516
|
+
keep(gsap.timeline({ onComplete: done, onInterrupt: done }).to([reveal, edge], { attr: { x: right }, duration: sweep, ease: "power2.inOut" }, 0).to(edge, { opacity: 0.3, duration: 0.08 }, 0).to(edge, { opacity: 0, duration: 0.14 }, sweep - 0.12));
|
|
21517
|
+
} else removed.forEach((stroke) => {
|
|
21518
|
+
const path = makePath(stroke, width, height);
|
|
21519
|
+
ghost.append(path);
|
|
21520
|
+
const length = path.getTotalLength?.() ?? 0;
|
|
21521
|
+
const done = () => path.remove();
|
|
21522
|
+
if (!length) {
|
|
21523
|
+
keep(gsap.to(path, { opacity: 0, duration: 0.25, onComplete: done }));
|
|
21524
|
+
return;
|
|
21525
|
+
}
|
|
21526
|
+
path.style.strokeDasharray = `${length} ${length}`;
|
|
21527
|
+
keep(gsap.timeline({ onComplete: done, onInterrupt: done }).fromTo(path, { strokeDashoffset: 0 }, { strokeDashoffset: length, duration: 0.5, ease: "power2.inOut" }, 0).to(path, { opacity: 0, duration: 0.16 }, 0.36));
|
|
21528
|
+
});
|
|
21529
|
+
const rendered = [...svg2.children];
|
|
21530
|
+
added.forEach((stroke, index) => {
|
|
21531
|
+
const path = rendered[strokes.indexOf(stroke)];
|
|
21532
|
+
const length = path?.getTotalLength?.() ?? 0;
|
|
21533
|
+
if (!path || !length) return;
|
|
21534
|
+
path.style.strokeDasharray = `${length} ${length}`;
|
|
21535
|
+
keep(gsap.fromTo(path, { strokeDashoffset: length }, { strokeDashoffset: 0, duration: 0.6, delay: Math.min(index * 0.08, 0.48), ease: EASE.wipe, clearProps: "strokeDasharray,strokeDashoffset" }));
|
|
21536
|
+
});
|
|
21438
21537
|
};
|
|
21439
21538
|
const undo = () => {
|
|
21440
21539
|
if (scope.disposed) return;
|
|
21441
21540
|
cancel();
|
|
21442
21541
|
if (!undoStack.length) return;
|
|
21542
|
+
const before = strokes;
|
|
21443
21543
|
redoStack.push(strokes);
|
|
21444
21544
|
strokes = undoStack.pop();
|
|
21445
21545
|
render();
|
|
21446
21546
|
update();
|
|
21447
21547
|
emit("undo");
|
|
21548
|
+
animateInk(before, "undo");
|
|
21448
21549
|
};
|
|
21449
21550
|
const redo = () => {
|
|
21450
21551
|
if (scope.disposed) return;
|
|
21451
21552
|
cancel();
|
|
21452
21553
|
if (!redoStack.length) return;
|
|
21554
|
+
const before = strokes;
|
|
21453
21555
|
undoStack.push(strokes);
|
|
21454
21556
|
strokes = redoStack.pop();
|
|
21455
21557
|
render();
|
|
21456
21558
|
update();
|
|
21457
21559
|
emit("redo");
|
|
21560
|
+
animateInk(before, "redo");
|
|
21458
21561
|
};
|
|
21459
21562
|
const clear = () => {
|
|
21460
21563
|
if (scope.disposed) return;
|
|
21461
21564
|
cancel();
|
|
21462
21565
|
if (!strokes.length) return;
|
|
21566
|
+
const before = strokes;
|
|
21463
21567
|
remember();
|
|
21464
21568
|
strokes = [];
|
|
21465
21569
|
render();
|
|
21466
21570
|
update();
|
|
21467
21571
|
emit("clear");
|
|
21572
|
+
animateInk(before, "clear");
|
|
21468
21573
|
};
|
|
21469
21574
|
const form = hidden?.form;
|
|
21470
21575
|
if (form) scope.on(form, "reset", (event) => {
|
|
@@ -21537,6 +21642,16 @@ function createSignaturePad(root, options = {}) {
|
|
|
21537
21642
|
if (active?.pointerId === event.pointerId) cancel();
|
|
21538
21643
|
});
|
|
21539
21644
|
scope.on(window, "blur", cancel);
|
|
21645
|
+
const movePen = (event) => {
|
|
21646
|
+
const pointer2 = event;
|
|
21647
|
+
const rect = surface.getBoundingClientRect();
|
|
21648
|
+
root.toggleAttribute("data-mk-pen-visible", pointer2.pointerType !== "touch" && !locked());
|
|
21649
|
+
pen.style.left = `${pointer2.clientX - rect.left}px`;
|
|
21650
|
+
pen.style.top = `${pointer2.clientY - rect.top}px`;
|
|
21651
|
+
};
|
|
21652
|
+
scope.on(surface, "pointerenter", movePen);
|
|
21653
|
+
scope.on(surface, "pointermove", movePen);
|
|
21654
|
+
scope.on(surface, "pointerleave", () => root.removeAttribute("data-mk-pen-visible"));
|
|
21540
21655
|
scope.on(document, "visibilitychange", () => {
|
|
21541
21656
|
if (document.hidden) cancel();
|
|
21542
21657
|
});
|
|
@@ -21549,7 +21664,7 @@ function createSignaturePad(root, options = {}) {
|
|
|
21549
21664
|
scope.on(window, "resize", render);
|
|
21550
21665
|
scope.add(() => {
|
|
21551
21666
|
cancel();
|
|
21552
|
-
|
|
21667
|
+
for (const effect of effects) effect.kill();
|
|
21553
21668
|
});
|
|
21554
21669
|
render();
|
|
21555
21670
|
update();
|
|
@@ -21674,6 +21789,12 @@ var finite6 = (n) => Number.isFinite(n) && n >= 0;
|
|
|
21674
21789
|
var clock = (n) => `${Math.floor(n / 60)}:${String(Math.floor(n % 60)).padStart(2, "0")}`;
|
|
21675
21790
|
var playIcon = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m9 6 9 6-9 6Z"/></svg>';
|
|
21676
21791
|
var pauseIcon = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 6v12M16 6v12"/></svg>';
|
|
21792
|
+
var level = (n) => typeof n === "number" && Number.isFinite(n) ? Math.max(0, Math.min(1, n)) : 0;
|
|
21793
|
+
var resample = (values, count) => count === values.length ? [...values] : Array.from({ length: count }, (_, k) => {
|
|
21794
|
+
const from = Math.floor(k * values.length / count);
|
|
21795
|
+
const slice = values.slice(from, Math.max(from + 1, Math.floor((k + 1) * values.length / count)));
|
|
21796
|
+
return slice.reduce((sum, n) => sum + n, 0) / slice.length;
|
|
21797
|
+
});
|
|
21677
21798
|
function createWaveformPlayer(root, options = {}) {
|
|
21678
21799
|
if (!root) return inert({ play: async () => false, pause() {
|
|
21679
21800
|
}, seek() {
|
|
@@ -21700,10 +21821,16 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21700
21821
|
audio.hidden = true;
|
|
21701
21822
|
const toggle = make("button", "toggle", container);
|
|
21702
21823
|
toggle.type = "button";
|
|
21824
|
+
const icon2 = make("span", "icon", toggle);
|
|
21703
21825
|
const body = make("div", "body", container);
|
|
21704
21826
|
const track = make("div", "track", body);
|
|
21705
21827
|
const bars = make("div", "bars", track);
|
|
21706
21828
|
bars.setAttribute("aria-hidden", "true");
|
|
21829
|
+
const head = make("span", "head", track);
|
|
21830
|
+
head.setAttribute("aria-hidden", "true");
|
|
21831
|
+
const preview = make("span", "preview", track);
|
|
21832
|
+
preview.setAttribute("aria-hidden", "true");
|
|
21833
|
+
preview.hidden = true;
|
|
21707
21834
|
const range = make("input", "seek", track);
|
|
21708
21835
|
range.type = "range";
|
|
21709
21836
|
range.min = "0";
|
|
@@ -21718,8 +21845,36 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21718
21845
|
message.setAttribute("aria-live", "polite");
|
|
21719
21846
|
scope.attr(root, "data-mk-ready", "");
|
|
21720
21847
|
scope.attr(root, "data-mk-wave-state", "idle");
|
|
21848
|
+
scope.attr(root, "data-mk-wave-scrubbing", null);
|
|
21721
21849
|
let barNodes = [];
|
|
21722
|
-
|
|
21850
|
+
const effects = /* @__PURE__ */ new Set();
|
|
21851
|
+
const keep = (effect) => {
|
|
21852
|
+
for (const animation of effects) if (animation.totalProgress() === 1) effects.delete(animation);
|
|
21853
|
+
if (effect) effects.add(effect);
|
|
21854
|
+
};
|
|
21855
|
+
let iconMotion = null;
|
|
21856
|
+
let lastPlaying;
|
|
21857
|
+
let lastRate = "";
|
|
21858
|
+
let following = false;
|
|
21859
|
+
const scrubbing = () => root.hasAttribute("data-mk-wave-scrubbing");
|
|
21860
|
+
const paintProgress = (seconds, animate = true) => {
|
|
21861
|
+
const progress = state.duration ? Math.max(0, Math.min(1, seconds / state.duration)) : 0;
|
|
21862
|
+
track.style.setProperty("--mk-wave-progress", String(progress));
|
|
21863
|
+
barNodes.forEach((bar, i) => {
|
|
21864
|
+
const played = (i + 0.5) / barNodes.length <= progress;
|
|
21865
|
+
if (bar.hasAttribute("data-mk-played") === played) return;
|
|
21866
|
+
bar.toggleAttribute("data-mk-played", played);
|
|
21867
|
+
if (animate && !scrubbing() && !reduced()) keep(gsap.fromTo(bar, { scaleY: 0.72 }, { scaleY: 1, duration: 0.35, ease: EASE.swatch, overwrite: "auto", clearProps: "transform" }));
|
|
21868
|
+
});
|
|
21869
|
+
};
|
|
21870
|
+
const followPlayback = () => {
|
|
21871
|
+
if (!scope.disposed && state.status === "playing") paintProgress(audio.currentTime);
|
|
21872
|
+
};
|
|
21873
|
+
const showPreview = (seconds, ratio) => {
|
|
21874
|
+
preview.textContent = clock(seconds);
|
|
21875
|
+
preview.style.setProperty("--mk-wave-at", String(Math.max(0.04, Math.min(0.96, ratio))));
|
|
21876
|
+
preview.hidden = false;
|
|
21877
|
+
};
|
|
21723
21878
|
const snapshot = () => ({ ...state });
|
|
21724
21879
|
const rates = () => {
|
|
21725
21880
|
const values = opts.playbackRates === false ? [] : opts.playbackRates ?? [1, 1.5, 2];
|
|
@@ -21727,7 +21882,13 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21727
21882
|
};
|
|
21728
21883
|
const paint = () => {
|
|
21729
21884
|
const playing = state.status === "playing";
|
|
21730
|
-
|
|
21885
|
+
const nextPlaying = playing || requested;
|
|
21886
|
+
if (lastPlaying !== nextPlaying) {
|
|
21887
|
+
icon2.innerHTML = nextPlaying ? pauseIcon : playIcon;
|
|
21888
|
+
iconMotion?.kill();
|
|
21889
|
+
if (lastPlaying !== void 0 && !reduced()) iconMotion = gsap.fromTo(icon2, { scale: 0.55, opacity: 0.3, filter: "blur(5px)" }, { scale: 1, opacity: 1, filter: "blur(0px)", duration: 0.3, ease: EASE.pop, clearProps: "transform,opacity,filter" });
|
|
21890
|
+
lastPlaying = nextPlaying;
|
|
21891
|
+
}
|
|
21731
21892
|
toggle.setAttribute("aria-label", `${playing || requested ? "Pausar" : "Reproducir"} ${opts.label ?? "audio"}`);
|
|
21732
21893
|
toggle.disabled = !!opts.disabled || !source;
|
|
21733
21894
|
range.disabled = !!opts.disabled || !state.duration;
|
|
@@ -21738,10 +21899,22 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21738
21899
|
time2.textContent = `${clock(state.currentTime)} / ${clock(state.duration)}`;
|
|
21739
21900
|
rate.hidden = rates().length < 2;
|
|
21740
21901
|
rate.disabled = !!opts.disabled;
|
|
21741
|
-
|
|
21902
|
+
const rateLabel = `${state.playbackRate}\xD7`;
|
|
21903
|
+
if (lastRate !== rateLabel) {
|
|
21904
|
+
if (lastRate) keep(rollDigits(rate, rateLabel, 1, 0.28));
|
|
21905
|
+
else rate.textContent = rateLabel;
|
|
21906
|
+
lastRate = rateLabel;
|
|
21907
|
+
}
|
|
21742
21908
|
rate.setAttribute("aria-label", `Velocidad ${state.playbackRate}\xD7. Cambiar velocidad`);
|
|
21743
|
-
|
|
21744
|
-
|
|
21909
|
+
paintProgress(state.currentTime);
|
|
21910
|
+
if (document.activeElement === range) showPreview(state.currentTime, state.duration ? state.currentTime / state.duration : 0);
|
|
21911
|
+
if (playing && !following) {
|
|
21912
|
+
following = true;
|
|
21913
|
+
gsap.ticker.add(followPlayback);
|
|
21914
|
+
} else if (!playing && following) {
|
|
21915
|
+
following = false;
|
|
21916
|
+
gsap.ticker.remove(followPlayback);
|
|
21917
|
+
}
|
|
21745
21918
|
root.setAttribute("data-mk-wave-state", state.status);
|
|
21746
21919
|
message.textContent = state.error ?? (state.status === "loading" ? "Cargando audio\u2026" : state.status === "ended" ? "Audio finalizado" : "");
|
|
21747
21920
|
};
|
|
@@ -21761,10 +21934,7 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21761
21934
|
if (event) root.dispatchEvent(new CustomEvent(`mk:audio-${event}`, { bubbles: true, detail: snapshot() }));
|
|
21762
21935
|
};
|
|
21763
21936
|
const bounce = (target) => {
|
|
21764
|
-
|
|
21765
|
-
effect?.progress(1);
|
|
21766
|
-
effect?.kill();
|
|
21767
|
-
effect = gsap.fromTo(target, { scale: 0.88 }, { scale: 1, duration: 0.4, ease: EASE.swatch, clearProps: "transform" });
|
|
21937
|
+
keep(press(target));
|
|
21768
21938
|
};
|
|
21769
21939
|
const fail = (message2) => {
|
|
21770
21940
|
requested = false;
|
|
@@ -21825,17 +21995,27 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21825
21995
|
pending = result;
|
|
21826
21996
|
return result;
|
|
21827
21997
|
};
|
|
21828
|
-
const
|
|
21998
|
+
const peakValues = () => {
|
|
21829
21999
|
const supplied = Array.isArray(opts.peaks) ? opts.peaks : [];
|
|
21830
|
-
|
|
22000
|
+
return supplied.length ? supplied.slice(0, 256).map(level) : Array(48).fill(0.24);
|
|
22001
|
+
};
|
|
22002
|
+
const barCount = (values) => {
|
|
22003
|
+
const width = bars.clientWidth;
|
|
22004
|
+
return width > 0 ? Math.max(12, Math.min(72, Math.floor((width + 3) / 8))) : values.length;
|
|
22005
|
+
};
|
|
22006
|
+
const renderPeaks = () => {
|
|
22007
|
+
const values = peakValues();
|
|
21831
22008
|
bars.replaceChildren();
|
|
21832
|
-
barNodes = values
|
|
22009
|
+
barNodes = resample(values, barCount(values)).map((peak) => {
|
|
21833
22010
|
const bar = make("i", "bar", bars);
|
|
21834
|
-
const peak = typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.min(1, value)) : 0;
|
|
21835
22011
|
bar.style.height = `${8 + peak * 92}%`;
|
|
21836
22012
|
return bar;
|
|
21837
22013
|
});
|
|
22014
|
+
paintProgress(state.currentTime, false);
|
|
21838
22015
|
};
|
|
22016
|
+
if (typeof ResizeObserver === "function") scope.observe(new ResizeObserver(() => {
|
|
22017
|
+
if (!scope.disposed && barCount(peakValues()) !== barNodes.length) renderPeaks();
|
|
22018
|
+
})).observe(bars);
|
|
21839
22019
|
const update = (next) => {
|
|
21840
22020
|
if (scope.disposed) return;
|
|
21841
22021
|
const previousPeaks = opts.peaks;
|
|
@@ -21863,6 +22043,35 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21863
22043
|
else void play();
|
|
21864
22044
|
});
|
|
21865
22045
|
scope.on(range, "input", () => seek(Number(range.value)));
|
|
22046
|
+
scope.on(range, "pointermove", (event) => {
|
|
22047
|
+
if (!state.duration || opts.disabled) return;
|
|
22048
|
+
const rect = range.getBoundingClientRect();
|
|
22049
|
+
if (!rect.width) return;
|
|
22050
|
+
const inset = parseFloat(getComputedStyle(track).getPropertyValue("--mk-wave-inset")) || 0;
|
|
22051
|
+
const ratio = Math.max(0, Math.min(1, (event.clientX - rect.left - inset) / Math.max(1, rect.width - inset * 2)));
|
|
22052
|
+
showPreview(state.duration * ratio, ratio);
|
|
22053
|
+
});
|
|
22054
|
+
scope.on(range, "pointerleave", () => {
|
|
22055
|
+
if (document.activeElement !== range) preview.hidden = true;
|
|
22056
|
+
});
|
|
22057
|
+
scope.on(range, "focus", () => {
|
|
22058
|
+
if (state.duration) showPreview(state.currentTime, state.currentTime / state.duration);
|
|
22059
|
+
});
|
|
22060
|
+
scope.on(range, "blur", () => {
|
|
22061
|
+
preview.hidden = true;
|
|
22062
|
+
});
|
|
22063
|
+
scope.on(range, "pointerdown", () => {
|
|
22064
|
+
if (range.disabled) return;
|
|
22065
|
+
root.setAttribute("data-mk-wave-scrubbing", "");
|
|
22066
|
+
keep(press(head));
|
|
22067
|
+
});
|
|
22068
|
+
const release = () => {
|
|
22069
|
+
if (!scrubbing()) return;
|
|
22070
|
+
root.removeAttribute("data-mk-wave-scrubbing");
|
|
22071
|
+
if (!reduced()) keep(gsap.fromTo(head, { scale: 1.12 }, { scale: 1, duration: 0.4, ease: EASE.swatch, overwrite: "auto", clearProps: "transform" }));
|
|
22072
|
+
};
|
|
22073
|
+
scope.on(window, "pointerup", release);
|
|
22074
|
+
scope.on(window, "pointercancel", release);
|
|
21866
22075
|
scope.on(rate, "click", () => {
|
|
21867
22076
|
const available = rates();
|
|
21868
22077
|
const index = available.indexOf(state.playbackRate);
|
|
@@ -21921,7 +22130,9 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21921
22130
|
request++;
|
|
21922
22131
|
requested = false;
|
|
21923
22132
|
pending = null;
|
|
21924
|
-
|
|
22133
|
+
iconMotion?.kill();
|
|
22134
|
+
for (const effect of effects) effect.kill();
|
|
22135
|
+
gsap.ticker.remove(followPlayback);
|
|
21925
22136
|
audio.pause();
|
|
21926
22137
|
audio.removeAttribute("src");
|
|
21927
22138
|
audio.load();
|
|
@@ -21938,6 +22149,7 @@ function createWaveformPlayer(root, options = {}) {
|
|
|
21938
22149
|
var statusLabels = { sending: "Enviando", sent: "Enviado", delivered: "Entregado", read: "Le\xEDdo", failed: "No enviado" };
|
|
21939
22150
|
function createVoiceMessageBubble(root, options = {}) {
|
|
21940
22151
|
if (!root) return createWaveformPlayer(null, options);
|
|
22152
|
+
registerMotion();
|
|
21941
22153
|
const scope = createScope();
|
|
21942
22154
|
let opts = { ...options };
|
|
21943
22155
|
const content = document.createElement("div");
|
|
@@ -21981,6 +22193,12 @@ function createVoiceMessageBubble(root, options = {}) {
|
|
|
21981
22193
|
player.update({ ...audio, label: opts.label ?? (opts.author ? `mensaje de voz de ${opts.author}` : "mensaje de voz") });
|
|
21982
22194
|
};
|
|
21983
22195
|
update(options);
|
|
22196
|
+
let entrance = null;
|
|
22197
|
+
if (!reduced()) {
|
|
22198
|
+
content.style.transformOrigin = opts.direction === "outgoing" ? "right bottom" : "left bottom";
|
|
22199
|
+
entrance = gsap.fromTo(content, { scale: 0.88, opacity: 0, filter: "blur(12px)", y: 10 }, { scale: 1, opacity: 1, filter: "blur(0px)", y: 0, duration: 0.65, ease: EASE.signature, clearProps: "transform,opacity,filter" });
|
|
22200
|
+
}
|
|
22201
|
+
scope.add(() => entrance?.kill());
|
|
21984
22202
|
return {
|
|
21985
22203
|
play: () => player.play(),
|
|
21986
22204
|
pause: () => player.pause(),
|
|
@@ -22022,6 +22240,12 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22022
22240
|
let focused = null;
|
|
22023
22241
|
const remembered = /* @__PURE__ */ new Map();
|
|
22024
22242
|
let animation = null;
|
|
22243
|
+
let hoverMotion = null;
|
|
22244
|
+
const effects = /* @__PURE__ */ new Set();
|
|
22245
|
+
const keep = (effect) => {
|
|
22246
|
+
for (const animation2 of effects) if (animation2.totalProgress() === 1) effects.delete(animation2);
|
|
22247
|
+
if (effect) effects.add(effect);
|
|
22248
|
+
};
|
|
22025
22249
|
const header = document.createElement("div");
|
|
22026
22250
|
header.dataset.mkDrilldownHeader = "";
|
|
22027
22251
|
const backButton = document.createElement("button");
|
|
@@ -22046,7 +22270,10 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22046
22270
|
const empty = document.createElement("p");
|
|
22047
22271
|
empty.dataset.mkDrilldownEmpty = "";
|
|
22048
22272
|
empty.setAttribute("role", "status");
|
|
22049
|
-
|
|
22273
|
+
const highlight = document.createElement("span");
|
|
22274
|
+
highlight.dataset.mkDrilldownHighlight = "";
|
|
22275
|
+
highlight.setAttribute("aria-hidden", "true");
|
|
22276
|
+
viewport.append(highlight, menu, empty);
|
|
22050
22277
|
backButton.setAttribute("aria-controls", menu.id);
|
|
22051
22278
|
root.append(header, breadcrumb, viewport);
|
|
22052
22279
|
scope.attr(root, "data-mk-ready", "");
|
|
@@ -22063,13 +22290,25 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22063
22290
|
}
|
|
22064
22291
|
return { valid: valid2, ancestors, items };
|
|
22065
22292
|
};
|
|
22066
|
-
const
|
|
22293
|
+
const level2 = () => levelAt(path);
|
|
22067
22294
|
const enabled = () => [...menu.querySelectorAll("[data-mk-drilldown-item]")].filter((item) => !item.disabled);
|
|
22068
22295
|
const buttonOf = (id) => enabled().find((item) => item.dataset.mkDrilldownItem === id);
|
|
22296
|
+
const highlightItem = (button2) => {
|
|
22297
|
+
hoverMotion?.kill();
|
|
22298
|
+
for (const item of enabled()) item.toggleAttribute("data-mk-highlighted", item === button2);
|
|
22299
|
+
if (!button2) {
|
|
22300
|
+
highlight.style.opacity = "0";
|
|
22301
|
+
return;
|
|
22302
|
+
}
|
|
22303
|
+
const geometry = { x: button2.offsetLeft + menu.offsetLeft, y: button2.offsetTop + menu.offsetTop, width: button2.offsetWidth, height: button2.offsetHeight, opacity: 1 };
|
|
22304
|
+
if (reduced()) gsap.set(highlight, geometry);
|
|
22305
|
+
else hoverMotion = gsap.to(highlight, { ...geometry, duration: 0.35, ease: EASE.swatch });
|
|
22306
|
+
};
|
|
22069
22307
|
const cancelMotion = () => {
|
|
22070
22308
|
animation?.kill();
|
|
22309
|
+
hoverMotion?.kill();
|
|
22071
22310
|
animation = null;
|
|
22072
|
-
gsap.set(menu, { clearProps: "transform,opacity,filter" });
|
|
22311
|
+
gsap.set([menu, heading, breadcrumb, ...menu.children], { clearProps: "transform,opacity,filter" });
|
|
22073
22312
|
gsap.set(viewport, { clearProps: "height" });
|
|
22074
22313
|
};
|
|
22075
22314
|
const roving = (id, focus = false) => {
|
|
@@ -22080,6 +22319,7 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22080
22319
|
menu.tabIndex = target ? -1 : 0;
|
|
22081
22320
|
if (focused) remembered.set(JSON.stringify(path), focused);
|
|
22082
22321
|
if (focus) (target ?? menu).focus({ preventScroll: true });
|
|
22322
|
+
if (focus) highlightItem(target);
|
|
22083
22323
|
};
|
|
22084
22324
|
const notifyPath = () => {
|
|
22085
22325
|
const next = [...path];
|
|
@@ -22089,13 +22329,15 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22089
22329
|
const render = (direction, focus, preferred) => {
|
|
22090
22330
|
const oldHeight = viewport.getBoundingClientRect().height;
|
|
22091
22331
|
cancelMotion();
|
|
22092
|
-
|
|
22332
|
+
highlightItem(null);
|
|
22333
|
+
const current3 = level2();
|
|
22093
22334
|
const label = config.label ?? "Actions";
|
|
22094
22335
|
const title = current3.ancestors.at(-1)?.label ?? label;
|
|
22095
22336
|
heading.textContent = title;
|
|
22096
22337
|
backButton.hidden = path.length === 0;
|
|
22097
22338
|
backButton.setAttribute("aria-label", config.backLabel ?? "Back");
|
|
22098
22339
|
breadcrumb.setAttribute("aria-label", `${label} path`);
|
|
22340
|
+
breadcrumb.hidden = path.length === 0;
|
|
22099
22341
|
const labels = [label, ...current3.ancestors.map((item) => item.label)];
|
|
22100
22342
|
crumbs.replaceChildren(...labels.map((text, index) => {
|
|
22101
22343
|
const li = document.createElement("li");
|
|
@@ -22154,6 +22396,7 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22154
22396
|
animation = gsap.timeline({ onComplete: () => {
|
|
22155
22397
|
animation = null;
|
|
22156
22398
|
} }).fromTo(menu, { x: 28 * direction, opacity: 0, filter: "blur(6px)" }, { x: 0, opacity: 1, filter: "blur(0px)", duration: 0.36, ease: EASE.signature, clearProps: "transform,opacity,filter" });
|
|
22399
|
+
animation.fromTo([heading, breadcrumb], { y: -6, opacity: 0.3, filter: "blur(6px)" }, { y: 0, opacity: 1, filter: "blur(0px)", duration: 0.3, ease: EASE.pop, clearProps: "transform,opacity,filter" }, 0).fromTo([...menu.children], { x: 12 * direction, opacity: 0 }, { x: 0, opacity: 1, duration: 0.3, stagger: 0.035, ease: EASE.swatchLight, clearProps: "transform,opacity" }, 0.04);
|
|
22157
22400
|
const nextHeight = viewport.getBoundingClientRect().height;
|
|
22158
22401
|
if (oldHeight > 0 && nextHeight > 0 && oldHeight !== nextHeight) {
|
|
22159
22402
|
animation.fromTo(viewport, { height: oldHeight }, { height: nextHeight, duration: 0.36, ease: EASE.signature, clearProps: "height" }, 0);
|
|
@@ -22175,16 +22418,22 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22175
22418
|
};
|
|
22176
22419
|
const open = (id) => {
|
|
22177
22420
|
if (scope.disposed) return false;
|
|
22178
|
-
const item =
|
|
22421
|
+
const item = level2().items.find((entry) => entry.id === id);
|
|
22179
22422
|
if (!item || item.disabled || !branch(item)) return false;
|
|
22180
22423
|
return navigate([...path, id], true, true);
|
|
22181
22424
|
};
|
|
22182
22425
|
const back = () => path.length ? navigate(path.slice(0, -1), true, true, path.at(-1)) : false;
|
|
22183
22426
|
const reset = () => navigate([], true, root.contains(document.activeElement), path[0]);
|
|
22184
22427
|
const activate = (id) => {
|
|
22185
|
-
const item =
|
|
22428
|
+
const item = level2().items.find((entry) => entry.id === id);
|
|
22186
22429
|
if (!item || item.disabled) return;
|
|
22187
22430
|
if (branch(item)) return void open(id);
|
|
22431
|
+
const button2 = buttonOf(id);
|
|
22432
|
+
if (button2) {
|
|
22433
|
+
for (const row of enabled()) row.toggleAttribute("data-mk-chosen", row === button2);
|
|
22434
|
+
keep(press(button2));
|
|
22435
|
+
keep(ringPulse(button2));
|
|
22436
|
+
}
|
|
22188
22437
|
const selected = copyItems([item])[0];
|
|
22189
22438
|
const selectedPath = [...path, item.id];
|
|
22190
22439
|
root.dispatchEvent(new CustomEvent("mk:select", { bubbles: true, detail: { item: selected, path: [...selectedPath] } }));
|
|
@@ -22198,8 +22447,20 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22198
22447
|
});
|
|
22199
22448
|
scope.on(menu, "focusin", (event) => {
|
|
22200
22449
|
const button2 = event.target?.closest("[data-mk-drilldown-item]");
|
|
22201
|
-
if (button2 && !button2.disabled)
|
|
22450
|
+
if (button2 && !button2.disabled) {
|
|
22451
|
+
roving(button2.dataset.mkDrilldownItem, false);
|
|
22452
|
+
highlightItem(button2);
|
|
22453
|
+
}
|
|
22454
|
+
});
|
|
22455
|
+
scope.on(menu, "pointerover", (event) => {
|
|
22456
|
+
const button2 = event.target?.closest("[data-mk-drilldown-item]");
|
|
22457
|
+
if (button2 && !button2.disabled) highlightItem(button2);
|
|
22202
22458
|
});
|
|
22459
|
+
scope.on(menu, "pointerleave", () => highlightItem(menu.contains(document.activeElement) ? buttonOf(focused ?? "") : null));
|
|
22460
|
+
if (typeof ResizeObserver === "function") scope.observe(new ResizeObserver(() => {
|
|
22461
|
+
const current3 = menu.querySelector("[data-mk-highlighted]");
|
|
22462
|
+
if (current3) highlightItem(current3);
|
|
22463
|
+
})).observe(menu);
|
|
22203
22464
|
scope.on(root, "keydown", (event) => {
|
|
22204
22465
|
const key2 = event.key;
|
|
22205
22466
|
if ((key2 === "ArrowLeft" || key2 === "Escape") && path.length) {
|
|
@@ -22220,13 +22481,16 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22220
22481
|
const button2 = event.target?.closest("[data-mk-drilldown-item]");
|
|
22221
22482
|
if (!button2 || button2.disabled || !menu.contains(button2)) return;
|
|
22222
22483
|
if (key2 === "Enter" || key2 === " " || key2 === "ArrowRight") {
|
|
22223
|
-
const item =
|
|
22484
|
+
const item = level2().items.find((entry) => entry.id === button2.dataset.mkDrilldownItem);
|
|
22224
22485
|
if (key2 === "ArrowRight" && (!item || !branch(item))) return;
|
|
22225
22486
|
event.preventDefault();
|
|
22226
22487
|
activate(button2.dataset.mkDrilldownItem);
|
|
22227
22488
|
}
|
|
22228
22489
|
});
|
|
22229
|
-
scope.on(backButton, "click", () =>
|
|
22490
|
+
scope.on(backButton, "click", () => {
|
|
22491
|
+
keep(press(backButton));
|
|
22492
|
+
back();
|
|
22493
|
+
});
|
|
22230
22494
|
scope.on(breadcrumb, "click", (event) => {
|
|
22231
22495
|
const button2 = event.target?.closest("[data-mk-drilldown-crumb]");
|
|
22232
22496
|
if (!button2 || !breadcrumb.contains(button2)) return;
|
|
@@ -22235,6 +22499,8 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22235
22499
|
});
|
|
22236
22500
|
scope.add(() => {
|
|
22237
22501
|
cancelMotion();
|
|
22502
|
+
for (const effect of effects) effect.kill();
|
|
22503
|
+
gsap.killTweensOf([heading, breadcrumb, highlight]);
|
|
22238
22504
|
remembered.clear();
|
|
22239
22505
|
header.remove();
|
|
22240
22506
|
breadcrumb.remove();
|
|
@@ -22282,7 +22548,7 @@ function createDrilldownMenu(root, options = {}) {
|
|
|
22282
22548
|
return [...path];
|
|
22283
22549
|
},
|
|
22284
22550
|
get items() {
|
|
22285
|
-
return copyItems(
|
|
22551
|
+
return copyItems(level2().items);
|
|
22286
22552
|
},
|
|
22287
22553
|
element: root,
|
|
22288
22554
|
destroy: () => scope.dispose()
|
|
@@ -22306,6 +22572,7 @@ function createWheelPicker(root, options = {}) {
|
|
|
22306
22572
|
if (!root) return inert({ setValue() {
|
|
22307
22573
|
}, setItems() {
|
|
22308
22574
|
}, value: "" });
|
|
22575
|
+
registerMotion();
|
|
22309
22576
|
const scope = createScope(), uid2 = `mk-wheel-${++sequence25}`;
|
|
22310
22577
|
let items = normalize(Array.isArray(options.items) ? options.items : []);
|
|
22311
22578
|
const rawRows = Number.isFinite(options.visibleItems) ? Math.round(options.visibleItems) : 5;
|
|
@@ -22366,17 +22633,29 @@ function createWheelPicker(root, options = {}) {
|
|
|
22366
22633
|
let typing;
|
|
22367
22634
|
let prefix = "";
|
|
22368
22635
|
let programmatic = null;
|
|
22636
|
+
let glide = null;
|
|
22637
|
+
let feedback = null;
|
|
22369
22638
|
let dragging = null;
|
|
22370
22639
|
let suppressClick = false;
|
|
22371
22640
|
scope.add(() => {
|
|
22372
22641
|
clearTimeout(timer2);
|
|
22373
22642
|
clearTimeout(typing);
|
|
22643
|
+
glide?.kill();
|
|
22644
|
+
feedback?.kill();
|
|
22374
22645
|
});
|
|
22646
|
+
const radius = height * rows / 2, step = height / radius, camera = radius * 3;
|
|
22375
22647
|
const paint = () => {
|
|
22376
|
-
const offset = viewport.scrollTop / height;
|
|
22648
|
+
const offset = viewport.scrollTop / height, flat = reduced();
|
|
22377
22649
|
nodes.forEach((node, index) => {
|
|
22378
|
-
const distance =
|
|
22379
|
-
|
|
22650
|
+
const distance = index - offset;
|
|
22651
|
+
const angle2 = distance * step, hidden = Math.abs(angle2) >= Math.PI / 2;
|
|
22652
|
+
const depth = radius * (Math.cos(angle2) - 1);
|
|
22653
|
+
const cameraScale = camera / (camera - depth);
|
|
22654
|
+
const shiftY = (radius * Math.sin(angle2) - distance * height) / cameraScale;
|
|
22655
|
+
node.style.transform = flat || hidden ? "" : `perspective(${camera.toFixed(0)}px) translate3d(0, ${shiftY.toFixed(3)}px, ${depth.toFixed(3)}px) rotateX(${(-angle2 * 180 / Math.PI).toFixed(3)}deg)`;
|
|
22656
|
+
node.style.opacity = String((items[index].disabled ? 0.32 : 1) * (flat ? 1 : hidden ? 0 : Math.pow(Math.cos(angle2), 1.6)));
|
|
22657
|
+
node.style.visibility = !flat && hidden ? "hidden" : "";
|
|
22658
|
+
node.style.pointerEvents = !flat && Math.abs(angle2) > 1.2 ? "none" : "";
|
|
22380
22659
|
node.setAttribute("aria-selected", String(index === current3));
|
|
22381
22660
|
});
|
|
22382
22661
|
input.value = items[current3]?.value ?? "";
|
|
@@ -22389,15 +22668,34 @@ function createWheelPicker(root, options = {}) {
|
|
|
22389
22668
|
else {
|
|
22390
22669
|
options.onChange?.(value);
|
|
22391
22670
|
status.textContent = items[current3]?.label ?? "";
|
|
22671
|
+
feedback?.kill();
|
|
22672
|
+
if (!reduced()) feedback = gsap.fromTo(highlight, { scaleX: 0.94, scaleY: 0.82 }, { scaleX: 1, scaleY: 1, duration: 0.5, ease: EASE.click, clearProps: "transform" });
|
|
22392
22673
|
}
|
|
22393
22674
|
input.dispatchEvent(new Event(kind, { bubbles: true }));
|
|
22394
22675
|
root.dispatchEvent(new CustomEvent(`mk:${kind}`, { bubbles: true, detail: { value, item: current3 >= 0 ? { ...items[current3] } : null } }));
|
|
22395
22676
|
};
|
|
22396
22677
|
const align = (animate) => {
|
|
22678
|
+
glide?.kill();
|
|
22679
|
+
glide = null;
|
|
22397
22680
|
const top = Math.max(0, current3) * height;
|
|
22398
|
-
if (animate && !reduced()
|
|
22681
|
+
if (animate && !reduced()) {
|
|
22399
22682
|
programmatic = top;
|
|
22400
|
-
|
|
22683
|
+
const proxy = { top: viewport.scrollTop };
|
|
22684
|
+
glide = gsap.to(proxy, {
|
|
22685
|
+
top,
|
|
22686
|
+
duration: 0.55,
|
|
22687
|
+
ease: EASE.swatch,
|
|
22688
|
+
onUpdate: () => {
|
|
22689
|
+
viewport.scrollTop = proxy.top;
|
|
22690
|
+
paint();
|
|
22691
|
+
},
|
|
22692
|
+
onComplete: () => {
|
|
22693
|
+
glide = null;
|
|
22694
|
+
programmatic = null;
|
|
22695
|
+
viewport.scrollTop = top;
|
|
22696
|
+
paint();
|
|
22697
|
+
}
|
|
22698
|
+
});
|
|
22401
22699
|
} else {
|
|
22402
22700
|
programmatic = null;
|
|
22403
22701
|
viewport.scrollTop = top;
|
|
@@ -22423,6 +22721,7 @@ function createWheelPicker(root, options = {}) {
|
|
|
22423
22721
|
};
|
|
22424
22722
|
const settle = () => {
|
|
22425
22723
|
if (scope.disposed || dragging) return;
|
|
22724
|
+
if (glide?.isActive()) return;
|
|
22426
22725
|
clearTimeout(timer2);
|
|
22427
22726
|
if (programmatic !== null) {
|
|
22428
22727
|
programmatic = null;
|
|
@@ -22463,7 +22762,8 @@ function createWheelPicker(root, options = {}) {
|
|
|
22463
22762
|
paint();
|
|
22464
22763
|
};
|
|
22465
22764
|
const interrupt = () => {
|
|
22466
|
-
|
|
22765
|
+
glide?.kill();
|
|
22766
|
+
glide = null;
|
|
22467
22767
|
programmatic = null;
|
|
22468
22768
|
};
|
|
22469
22769
|
scope.on(viewport, "pointerdown", (event) => {
|
|
@@ -22591,6 +22891,2213 @@ function createWheelPicker(root, options = {}) {
|
|
|
22591
22891
|
};
|
|
22592
22892
|
}
|
|
22593
22893
|
|
|
22894
|
+
// src/components/stepper/engine.ts
|
|
22895
|
+
function createStepper(root, options = {}) {
|
|
22896
|
+
if (!root) return inert({ value: 0, setValue() {
|
|
22897
|
+
}, next() {
|
|
22898
|
+
}, previous() {
|
|
22899
|
+
}, reset() {
|
|
22900
|
+
} });
|
|
22901
|
+
registerMotion();
|
|
22902
|
+
const scope = createScope();
|
|
22903
|
+
const effects = /* @__PURE__ */ new Set();
|
|
22904
|
+
const keep = (effect) => {
|
|
22905
|
+
for (const prior of effects) if (prior.totalProgress() === 1) effects.delete(prior);
|
|
22906
|
+
if (effect) effects.add(effect);
|
|
22907
|
+
};
|
|
22908
|
+
scope.add(() => {
|
|
22909
|
+
effects.forEach((effect) => effect.kill());
|
|
22910
|
+
effects.clear();
|
|
22911
|
+
});
|
|
22912
|
+
const items = (Array.isArray(options.items) ? options.items : []).filter((item) => item && typeof item.label === "string");
|
|
22913
|
+
const clamp5 = (n) => Math.max(0, Math.min(Math.max(0, items.length - 1), Number.isFinite(n) ? Math.round(n) : 0));
|
|
22914
|
+
const initial = clamp5(options.defaultValue ?? options.value ?? 0);
|
|
22915
|
+
let value = clamp5(options.value ?? initial);
|
|
22916
|
+
let furthest = value;
|
|
22917
|
+
let pending = null;
|
|
22918
|
+
const nav = document.createElement("nav");
|
|
22919
|
+
nav.dataset.mkStepperBody = "";
|
|
22920
|
+
nav.setAttribute("aria-label", options.label ?? "Progreso");
|
|
22921
|
+
const list3 = document.createElement("ol");
|
|
22922
|
+
list3.dataset.mkStepperList = "";
|
|
22923
|
+
nav.append(list3);
|
|
22924
|
+
const caption = document.createElement("span");
|
|
22925
|
+
caption.dataset.mkStepperCaption = "";
|
|
22926
|
+
caption.setAttribute("aria-live", "polite");
|
|
22927
|
+
nav.append(caption);
|
|
22928
|
+
root.append(nav);
|
|
22929
|
+
scope.add(() => nav.remove());
|
|
22930
|
+
const buttons = [];
|
|
22931
|
+
const rows = [];
|
|
22932
|
+
const marks = [];
|
|
22933
|
+
items.forEach((item, index) => {
|
|
22934
|
+
const row = document.createElement("li");
|
|
22935
|
+
row.dataset.mkStepperItem = "";
|
|
22936
|
+
const button2 = document.createElement("button");
|
|
22937
|
+
button2.type = "button";
|
|
22938
|
+
button2.dataset.mkStepperStep = String(index);
|
|
22939
|
+
const marker = document.createElement("span");
|
|
22940
|
+
marker.dataset.mkStepperMarker = "";
|
|
22941
|
+
marker.setAttribute("aria-hidden", "true");
|
|
22942
|
+
const copy = document.createElement("span");
|
|
22943
|
+
copy.dataset.mkStepperCopy = "";
|
|
22944
|
+
const title = document.createElement("span");
|
|
22945
|
+
title.dataset.mkStepperLabel = "";
|
|
22946
|
+
title.textContent = item.label;
|
|
22947
|
+
copy.append(title);
|
|
22948
|
+
if (item.description) {
|
|
22949
|
+
const description = document.createElement("span");
|
|
22950
|
+
description.dataset.mkStepperDescription = "";
|
|
22951
|
+
description.textContent = item.description;
|
|
22952
|
+
copy.append(description);
|
|
22953
|
+
}
|
|
22954
|
+
button2.append(marker, copy);
|
|
22955
|
+
row.append(button2);
|
|
22956
|
+
list3.append(row);
|
|
22957
|
+
buttons.push(button2);
|
|
22958
|
+
rows.push(row);
|
|
22959
|
+
marks.push(marker);
|
|
22960
|
+
scope.on(button2, "click", () => {
|
|
22961
|
+
if (!button2.disabled && !button2.matches(":disabled")) choose(index, true);
|
|
22962
|
+
});
|
|
22963
|
+
});
|
|
22964
|
+
const hidden = options.name ? document.createElement("input") : null;
|
|
22965
|
+
if (hidden) {
|
|
22966
|
+
hidden.type = "hidden";
|
|
22967
|
+
hidden.name = options.name;
|
|
22968
|
+
hidden.disabled = Boolean(options.disabled);
|
|
22969
|
+
nav.append(hidden);
|
|
22970
|
+
}
|
|
22971
|
+
scope.attr(root, "data-mk-ready", "");
|
|
22972
|
+
scope.attr(root, "data-mk-variant", options.variant ?? "horizontal");
|
|
22973
|
+
scope.attr(root, "data-mk-disabled", options.disabled ? "" : null);
|
|
22974
|
+
const paint = (animate, before) => {
|
|
22975
|
+
const nextEnabled = items.findIndex((item, index) => index > furthest && !item.disabled);
|
|
22976
|
+
const availableThrough = Math.max(furthest, nextEnabled);
|
|
22977
|
+
items.forEach((item, index) => {
|
|
22978
|
+
const selected = index === value;
|
|
22979
|
+
const complete = item.completed || index < value;
|
|
22980
|
+
rows[index].toggleAttribute("data-mk-current", selected);
|
|
22981
|
+
rows[index].toggleAttribute("data-mk-complete", Boolean(complete));
|
|
22982
|
+
rows[index].toggleAttribute("data-mk-error", Boolean(item.error));
|
|
22983
|
+
const button2 = buttons[index];
|
|
22984
|
+
button2.disabled = Boolean(options.disabled || item.disabled || options.linear && index > availableThrough);
|
|
22985
|
+
if (selected) button2.setAttribute("aria-current", "step");
|
|
22986
|
+
else button2.removeAttribute("aria-current");
|
|
22987
|
+
button2.setAttribute("aria-label", `${index + 1}. ${item.label}${item.error ? ", requiere atenci\xF3n" : complete ? ", completado" : ""}`);
|
|
22988
|
+
marks[index].textContent = item.error ? "!" : complete ? "\u2713" : String(index + 1);
|
|
22989
|
+
});
|
|
22990
|
+
if (hidden) hidden.value = String(value);
|
|
22991
|
+
const text = items.length ? `${value + 1} / ${items.length} \xB7 ${items[value]?.label ?? ""}` : "No hay pasos";
|
|
22992
|
+
if (animate && !reduced()) keep(rollDigits(caption, text, value >= before ? 1 : -1, 0.3));
|
|
22993
|
+
else caption.textContent = text;
|
|
22994
|
+
};
|
|
22995
|
+
const choose = (next, notify = false) => {
|
|
22996
|
+
if (scope.disposed) return;
|
|
22997
|
+
if (notify) pending = { value, furthest };
|
|
22998
|
+
const before = value;
|
|
22999
|
+
value = clamp5(next);
|
|
23000
|
+
furthest = Math.max(furthest, value);
|
|
23001
|
+
paint(before !== value, before);
|
|
23002
|
+
if (before === value) return;
|
|
23003
|
+
if (!reduced() && buttons[value]) {
|
|
23004
|
+
keep(press(buttons[value]));
|
|
23005
|
+
keep(gsap.fromTo(marks[value], { scale: 0.7, filter: "blur(4px)" }, { scale: 1, filter: "blur(0px)", duration: 0.4, ease: EASE.pop, overwrite: "auto", clearProps: "transform,filter" }));
|
|
23006
|
+
}
|
|
23007
|
+
if (notify) {
|
|
23008
|
+
const emitted = value;
|
|
23009
|
+
options.onChange?.(emitted);
|
|
23010
|
+
if (!scope.disposed) root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { value: emitted } }));
|
|
23011
|
+
}
|
|
23012
|
+
};
|
|
23013
|
+
const move = (direction, notify = true) => {
|
|
23014
|
+
if (options.disabled) return;
|
|
23015
|
+
for (let i = value + direction; i >= 0 && i < items.length; i += direction) if (!items[i]?.disabled) {
|
|
23016
|
+
choose(i, notify);
|
|
23017
|
+
break;
|
|
23018
|
+
}
|
|
23019
|
+
};
|
|
23020
|
+
const form = root.closest("form");
|
|
23021
|
+
if (form) scope.on(form, "reset", (event) => scope.timeout(() => {
|
|
23022
|
+
if (!scope.disposed && !event.defaultPrevented) {
|
|
23023
|
+
furthest = initial;
|
|
23024
|
+
choose(initial);
|
|
23025
|
+
}
|
|
23026
|
+
}, 0));
|
|
23027
|
+
paint(false, value);
|
|
23028
|
+
keep(blurIn(rows, { from: "soft", stagger: 0.04, duration: 0.35 }));
|
|
23029
|
+
return {
|
|
23030
|
+
get value() {
|
|
23031
|
+
return value;
|
|
23032
|
+
},
|
|
23033
|
+
setValue(next, notify = false) {
|
|
23034
|
+
const target = clamp5(next);
|
|
23035
|
+
if (!notify && pending && target === pending.value) furthest = pending.furthest;
|
|
23036
|
+
pending = null;
|
|
23037
|
+
choose(target, notify);
|
|
23038
|
+
},
|
|
23039
|
+
next: (notify = true) => move(1, notify),
|
|
23040
|
+
previous: (notify = true) => move(-1, notify),
|
|
23041
|
+
reset: (notify = false) => {
|
|
23042
|
+
pending = null;
|
|
23043
|
+
furthest = initial;
|
|
23044
|
+
choose(initial, notify);
|
|
23045
|
+
},
|
|
23046
|
+
destroy: () => scope.dispose()
|
|
23047
|
+
};
|
|
23048
|
+
}
|
|
23049
|
+
|
|
23050
|
+
// src/components/radio-group/shared.ts
|
|
23051
|
+
var sequence26 = 0;
|
|
23052
|
+
function createChoices(root, prefix, options) {
|
|
23053
|
+
if (!root) return inert({ value: null, setValue() {
|
|
23054
|
+
}, reset() {
|
|
23055
|
+
} });
|
|
23056
|
+
registerMotion();
|
|
23057
|
+
const scope = createScope();
|
|
23058
|
+
const effects = /* @__PURE__ */ new Set();
|
|
23059
|
+
const keep = (effect) => {
|
|
23060
|
+
for (const prior of effects) if (prior.totalProgress() === 1) effects.delete(prior);
|
|
23061
|
+
if (effect) effects.add(effect);
|
|
23062
|
+
};
|
|
23063
|
+
scope.add(() => {
|
|
23064
|
+
effects.forEach((effect) => effect.kill());
|
|
23065
|
+
effects.clear();
|
|
23066
|
+
});
|
|
23067
|
+
const part3 = (tag, parent, name2) => {
|
|
23068
|
+
const el5 = document.createElement(tag);
|
|
23069
|
+
el5.setAttribute(`data-mk-${prefix}-${name2}`, "");
|
|
23070
|
+
parent.append(el5);
|
|
23071
|
+
return el5;
|
|
23072
|
+
};
|
|
23073
|
+
const shell = part3("div", root, "body");
|
|
23074
|
+
scope.add(() => shell.remove());
|
|
23075
|
+
const group = part3("div", shell, "options");
|
|
23076
|
+
group.setAttribute("role", "radiogroup");
|
|
23077
|
+
group.setAttribute("aria-label", options.label ?? "Elige una opci\xF3n");
|
|
23078
|
+
group.setAttribute("aria-required", String(Boolean(options.required)));
|
|
23079
|
+
if (options.disabled) group.setAttribute("aria-disabled", "true");
|
|
23080
|
+
const message = part3("span", shell, "message");
|
|
23081
|
+
message.id = `mk-${prefix}-message-${++sequence26}`;
|
|
23082
|
+
message.setAttribute("aria-live", "polite");
|
|
23083
|
+
group.setAttribute("aria-describedby", message.id);
|
|
23084
|
+
if (options.error) group.setAttribute("aria-invalid", "true");
|
|
23085
|
+
const seen = /* @__PURE__ */ new Set();
|
|
23086
|
+
const items = (Array.isArray(options.items) ? options.items : []).filter((item) => {
|
|
23087
|
+
if (!item || typeof item.value !== "string" || seen.has(item.value)) return false;
|
|
23088
|
+
seen.add(item.value);
|
|
23089
|
+
return true;
|
|
23090
|
+
});
|
|
23091
|
+
const name = options.name ?? `mk-${prefix}-${sequence26}`;
|
|
23092
|
+
const valid2 = (candidate) => candidate != null && items.some((item) => item.value === candidate) ? candidate : null;
|
|
23093
|
+
const initial = valid2(options.defaultValue !== void 0 ? options.defaultValue : options.value);
|
|
23094
|
+
let value = valid2(options.value !== void 0 ? options.value : initial);
|
|
23095
|
+
const labels = [];
|
|
23096
|
+
const inputs = [];
|
|
23097
|
+
for (const item of items) {
|
|
23098
|
+
const label = part3("label", group, "option");
|
|
23099
|
+
const input = part3("input", label, "input");
|
|
23100
|
+
input.type = "radio";
|
|
23101
|
+
input.name = name;
|
|
23102
|
+
input.value = item.value;
|
|
23103
|
+
input.required = Boolean(options.required);
|
|
23104
|
+
input.disabled = Boolean(options.disabled || item.disabled);
|
|
23105
|
+
input.defaultChecked = item.value === initial;
|
|
23106
|
+
const mark = part3("span", label, "mark");
|
|
23107
|
+
mark.setAttribute("aria-hidden", "true");
|
|
23108
|
+
mark.textContent = item.symbol ?? "";
|
|
23109
|
+
const copy = part3("span", label, "copy");
|
|
23110
|
+
part3("span", copy, "label").textContent = item.label;
|
|
23111
|
+
if (item.description) part3("span", copy, "description").textContent = item.description;
|
|
23112
|
+
if (options.error) {
|
|
23113
|
+
input.setAttribute("aria-invalid", "true");
|
|
23114
|
+
input.setAttribute("aria-describedby", message.id);
|
|
23115
|
+
}
|
|
23116
|
+
labels.push(label);
|
|
23117
|
+
inputs.push(input);
|
|
23118
|
+
}
|
|
23119
|
+
scope.attr(root, "data-mk-ready", "");
|
|
23120
|
+
scope.attr(root, "data-mk-variant", options.variant ?? "pill");
|
|
23121
|
+
scope.attr(root, "data-mk-disabled", options.disabled ? "" : null);
|
|
23122
|
+
scope.attr(root, "data-mk-error", options.error ? "" : null);
|
|
23123
|
+
const paint = (animate, before) => {
|
|
23124
|
+
inputs.forEach((input, index) => {
|
|
23125
|
+
input.checked = input.value === value;
|
|
23126
|
+
labels[index].toggleAttribute("data-mk-selected", input.checked);
|
|
23127
|
+
});
|
|
23128
|
+
const caption = options.error ?? (items.length ? options.caption?.(value) ?? "" : "No hay opciones");
|
|
23129
|
+
if (animate && !reduced()) keep(rollDigits(message, caption, Number(value) >= Number(before) ? 1 : -1, 0.28));
|
|
23130
|
+
else message.textContent = caption;
|
|
23131
|
+
const at = (candidate) => items.findIndex((item) => item.value === candidate);
|
|
23132
|
+
options.decorate?.(labels, at(value), at(before), animate && before !== value && !reduced(), keep);
|
|
23133
|
+
};
|
|
23134
|
+
const choose = (next, notify = false, animate = true) => {
|
|
23135
|
+
if (scope.disposed) return;
|
|
23136
|
+
const target = valid2(next);
|
|
23137
|
+
const before = value;
|
|
23138
|
+
value = target;
|
|
23139
|
+
paint(animate, before);
|
|
23140
|
+
if (before === value) return;
|
|
23141
|
+
const index = items.findIndex((item) => item.value === value);
|
|
23142
|
+
if (animate && index >= 0 && !reduced()) {
|
|
23143
|
+
keep(press(labels[index]));
|
|
23144
|
+
keep(gsap.fromTo(labels[index].querySelector(`[data-mk-${prefix}-mark]`), { scale: 0.65, filter: "blur(4px)" }, { scale: 1, filter: "blur(0px)", duration: 0.4, ease: EASE.swatch, overwrite: "auto", clearProps: "transform,filter" }));
|
|
23145
|
+
}
|
|
23146
|
+
if (notify) {
|
|
23147
|
+
const emitted = value;
|
|
23148
|
+
options.onChange?.(emitted);
|
|
23149
|
+
if (!scope.disposed) root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { value: options.eventValue ? options.eventValue(emitted) : emitted } }));
|
|
23150
|
+
}
|
|
23151
|
+
};
|
|
23152
|
+
inputs.forEach((input) => scope.on(input, "change", () => {
|
|
23153
|
+
if (!input.disabled && !input.matches(":disabled") && input.checked) choose(input.value, true);
|
|
23154
|
+
else paint(false, value);
|
|
23155
|
+
}));
|
|
23156
|
+
const form = inputs[0]?.form;
|
|
23157
|
+
if (form) scope.on(form, "reset", (event) => {
|
|
23158
|
+
scope.timeout(() => {
|
|
23159
|
+
if (!scope.disposed && !event.defaultPrevented) choose(initial, false);
|
|
23160
|
+
}, 0);
|
|
23161
|
+
});
|
|
23162
|
+
paint(false, value);
|
|
23163
|
+
keep(blurIn(labels, { from: "soft", stagger: 0.035, duration: 0.35 }));
|
|
23164
|
+
return { get value() {
|
|
23165
|
+
return value;
|
|
23166
|
+
}, setValue: choose, reset: (notify = false) => choose(initial, notify), destroy: () => scope.dispose() };
|
|
23167
|
+
}
|
|
23168
|
+
|
|
23169
|
+
// src/components/radio-group/engine.ts
|
|
23170
|
+
function createRadioGroup(root, options = {}) {
|
|
23171
|
+
return createChoices(root, "radio", options);
|
|
23172
|
+
}
|
|
23173
|
+
|
|
23174
|
+
// src/components/equalizer-slider/shared.ts
|
|
23175
|
+
var finite7 = (n) => typeof n === "number" && Number.isFinite(n);
|
|
23176
|
+
var sequence27 = 0;
|
|
23177
|
+
function createNumericRange(root, options, design) {
|
|
23178
|
+
if (!root) return inert({ value: design.value, setValue() {
|
|
23179
|
+
}, reset() {
|
|
23180
|
+
}, configure() {
|
|
23181
|
+
} });
|
|
23182
|
+
registerMotion();
|
|
23183
|
+
const scope = createScope();
|
|
23184
|
+
const effects = /* @__PURE__ */ new Set();
|
|
23185
|
+
const keep = (effect) => {
|
|
23186
|
+
for (const prior of effects) if (prior.totalProgress() === 1) effects.delete(prior);
|
|
23187
|
+
if (effect) effects.add(effect);
|
|
23188
|
+
};
|
|
23189
|
+
scope.add(() => {
|
|
23190
|
+
effects.forEach((effect) => effect.kill());
|
|
23191
|
+
effects.clear();
|
|
23192
|
+
});
|
|
23193
|
+
let min = finite7(options.min) ? options.min : design.min;
|
|
23194
|
+
let max = finite7(options.max) && options.max > min ? options.max : Math.max(min + 1, design.max);
|
|
23195
|
+
let step = finite7(options.step) && options.step > 0 ? options.step : 1;
|
|
23196
|
+
let lastStep = Math.max(0, Math.floor((max - min) / step + 1e-8));
|
|
23197
|
+
let format = options.formatValue ?? design.format;
|
|
23198
|
+
const snap = (n) => Number((min + Math.max(0, Math.min(lastStep, Math.round((n - min) / step))) * step).toFixed(8));
|
|
23199
|
+
const initial = snap(finite7(options.defaultValue) ? options.defaultValue : finite7(options.value) ? options.value : design.value);
|
|
23200
|
+
let value = snap(finite7(options.value) ? options.value : initial);
|
|
23201
|
+
let committed = value;
|
|
23202
|
+
let held = false;
|
|
23203
|
+
const prefix = design.prefix;
|
|
23204
|
+
const part3 = (tag, parent, name) => {
|
|
23205
|
+
const el5 = document.createElement(tag);
|
|
23206
|
+
el5.setAttribute(`data-mk-${prefix}-${name}`, "");
|
|
23207
|
+
parent.append(el5);
|
|
23208
|
+
return el5;
|
|
23209
|
+
};
|
|
23210
|
+
const shell = part3("div", root, "body");
|
|
23211
|
+
scope.add(() => shell.remove());
|
|
23212
|
+
const header = part3("div", shell, "header");
|
|
23213
|
+
const label = part3("label", header, "label");
|
|
23214
|
+
label.textContent = options.label ?? design.label;
|
|
23215
|
+
const output = part3("output", header, "output");
|
|
23216
|
+
output.setAttribute("aria-hidden", "true");
|
|
23217
|
+
const track = part3("div", shell, "track");
|
|
23218
|
+
const thumb = part3("span", track, "thumb");
|
|
23219
|
+
thumb.setAttribute("aria-hidden", "true");
|
|
23220
|
+
const input = part3("input", track, "input");
|
|
23221
|
+
input.type = "range";
|
|
23222
|
+
input.min = String(min);
|
|
23223
|
+
input.max = String(max);
|
|
23224
|
+
input.step = String(step);
|
|
23225
|
+
input.defaultValue = String(initial);
|
|
23226
|
+
input.value = String(value);
|
|
23227
|
+
input.id = `mk-${prefix}-${++sequence27}`;
|
|
23228
|
+
label.htmlFor = input.id;
|
|
23229
|
+
input.disabled = Boolean(options.disabled);
|
|
23230
|
+
if (options.name) input.name = options.name;
|
|
23231
|
+
const message = part3("span", shell, "message");
|
|
23232
|
+
message.textContent = options.error ?? "";
|
|
23233
|
+
if (options.error) {
|
|
23234
|
+
message.id = `${input.id}-error`;
|
|
23235
|
+
input.setAttribute("aria-invalid", "true");
|
|
23236
|
+
input.setAttribute("aria-describedby", message.id);
|
|
23237
|
+
}
|
|
23238
|
+
const ends = part3("div", shell, "ends");
|
|
23239
|
+
ends.setAttribute("aria-hidden", "true");
|
|
23240
|
+
const minEnd = part3("span", ends, "min");
|
|
23241
|
+
minEnd.textContent = format(min);
|
|
23242
|
+
const maxEnd = part3("span", ends, "max");
|
|
23243
|
+
maxEnd.textContent = format(max);
|
|
23244
|
+
scope.attr(root, "data-mk-ready", "");
|
|
23245
|
+
scope.attr(root, "data-mk-disabled", options.disabled ? "" : null);
|
|
23246
|
+
scope.attr(root, "data-mk-error", options.error ? "" : null);
|
|
23247
|
+
scope.attr(root, "data-mk-held", null);
|
|
23248
|
+
scope.attr(root, "style", root.getAttribute("style"));
|
|
23249
|
+
const decorate = design.decorate?.({ root, track, thumb, scope, keep });
|
|
23250
|
+
let shown4 = null;
|
|
23251
|
+
let glide = null;
|
|
23252
|
+
scope.add(() => glide?.kill());
|
|
23253
|
+
const show = (ratio, animate) => {
|
|
23254
|
+
shown4 = ratio;
|
|
23255
|
+
root.style.setProperty(`--mk-${prefix}-ratio`, String(ratio));
|
|
23256
|
+
decorate?.(ratio, value, animate);
|
|
23257
|
+
};
|
|
23258
|
+
const paint = (animate, before) => {
|
|
23259
|
+
const ratio = (value - min) / (max - min);
|
|
23260
|
+
const text = format(value);
|
|
23261
|
+
input.value = String(value);
|
|
23262
|
+
input.setAttribute("aria-valuetext", text);
|
|
23263
|
+
if (animate && !held && !reduced()) keep(rollDigits(output, text, value >= before ? 1 : -1, 0.3));
|
|
23264
|
+
else {
|
|
23265
|
+
const roll = rollDigits(output, text, value >= before ? 1 : -1, 0);
|
|
23266
|
+
roll?.progress(1).kill();
|
|
23267
|
+
output.textContent = text;
|
|
23268
|
+
}
|
|
23269
|
+
glide?.kill();
|
|
23270
|
+
glide = null;
|
|
23271
|
+
if (animate && !held && !reduced() && shown4 !== null && Math.abs(ratio - shown4) > 1e-4) {
|
|
23272
|
+
const proxy = { ratio: shown4 };
|
|
23273
|
+
glide = gsap.to(proxy, { ratio, duration: 0.5, ease: EASE.swatch, onUpdate: () => show(Math.max(0, Math.min(1, proxy.ratio)), true) });
|
|
23274
|
+
} else show(ratio, animate && !held);
|
|
23275
|
+
};
|
|
23276
|
+
const emit = (type) => {
|
|
23277
|
+
if (scope.disposed) return;
|
|
23278
|
+
const emitted = value;
|
|
23279
|
+
(type === "input" ? options.onInput : options.onChange)?.(emitted);
|
|
23280
|
+
if (!scope.disposed) root.dispatchEvent(new CustomEvent(`mk:${type}`, { bubbles: true, detail: { value: emitted } }));
|
|
23281
|
+
};
|
|
23282
|
+
const set = (next, notify = false, animate = true) => {
|
|
23283
|
+
if (scope.disposed || !finite7(next)) return;
|
|
23284
|
+
const before = value;
|
|
23285
|
+
value = snap(next);
|
|
23286
|
+
paint(animate, before);
|
|
23287
|
+
if (notify && value !== before) {
|
|
23288
|
+
emit("input");
|
|
23289
|
+
committed = value;
|
|
23290
|
+
emit("change");
|
|
23291
|
+
} else if (!notify && value !== before) committed = value;
|
|
23292
|
+
};
|
|
23293
|
+
scope.on(input, "input", () => {
|
|
23294
|
+
if (input.disabled || input.matches(":disabled")) {
|
|
23295
|
+
input.value = String(value);
|
|
23296
|
+
return;
|
|
23297
|
+
}
|
|
23298
|
+
const before = value;
|
|
23299
|
+
value = snap(Number(input.value));
|
|
23300
|
+
paint(true, before);
|
|
23301
|
+
if (value !== before) emit("input");
|
|
23302
|
+
});
|
|
23303
|
+
scope.on(input, "change", () => {
|
|
23304
|
+
if (input.disabled || input.matches(":disabled")) return;
|
|
23305
|
+
const before = value;
|
|
23306
|
+
value = snap(Number(input.value));
|
|
23307
|
+
if (value !== before) paint(true, before);
|
|
23308
|
+
if (value !== committed) {
|
|
23309
|
+
committed = value;
|
|
23310
|
+
emit("change");
|
|
23311
|
+
}
|
|
23312
|
+
});
|
|
23313
|
+
scope.on(input, "pointerdown", () => {
|
|
23314
|
+
if (input.disabled || input.matches(":disabled")) return;
|
|
23315
|
+
held = true;
|
|
23316
|
+
root.setAttribute("data-mk-held", "");
|
|
23317
|
+
keep(press(thumb));
|
|
23318
|
+
});
|
|
23319
|
+
const release = () => {
|
|
23320
|
+
if (!held) return;
|
|
23321
|
+
held = false;
|
|
23322
|
+
root.removeAttribute("data-mk-held");
|
|
23323
|
+
if (!reduced()) keep(gsap.fromTo(thumb, { scale: 1.12 }, { scale: 1, duration: 0.4, ease: EASE.swatch, overwrite: "auto", clearProps: "transform" }));
|
|
23324
|
+
};
|
|
23325
|
+
scope.on(window, "pointerup", release);
|
|
23326
|
+
scope.on(window, "pointercancel", release);
|
|
23327
|
+
scope.on(input, "blur", release);
|
|
23328
|
+
if (input.form) scope.on(input.form, "reset", (event) => scope.timeout(() => {
|
|
23329
|
+
if (!scope.disposed && !event.defaultPrevented) set(initial);
|
|
23330
|
+
}, 0));
|
|
23331
|
+
const configure = (next, notify = false) => {
|
|
23332
|
+
if (scope.disposed) return;
|
|
23333
|
+
const before = value;
|
|
23334
|
+
if (finite7(next.min)) min = next.min;
|
|
23335
|
+
if (finite7(next.max)) max = next.max > min ? next.max : min + 1;
|
|
23336
|
+
if (finite7(next.step) && next.step > 0) step = next.step;
|
|
23337
|
+
if (next.format) format = next.format;
|
|
23338
|
+
lastStep = Math.max(0, Math.floor((max - min) / step + 1e-8));
|
|
23339
|
+
input.min = String(min);
|
|
23340
|
+
input.max = String(max);
|
|
23341
|
+
input.step = String(step);
|
|
23342
|
+
const ends2 = [[minEnd, format(min)], [maxEnd, format(max)]];
|
|
23343
|
+
for (const [end, text] of ends2) {
|
|
23344
|
+
if (reduced()) end.textContent = text;
|
|
23345
|
+
else keep(rollDigits(end, text, 1, 0.3));
|
|
23346
|
+
}
|
|
23347
|
+
value = snap(finite7(next.value) ? next.value : value);
|
|
23348
|
+
paint(true, before);
|
|
23349
|
+
if (value !== before) {
|
|
23350
|
+
committed = value;
|
|
23351
|
+
if (notify) {
|
|
23352
|
+
emit("input");
|
|
23353
|
+
emit("change");
|
|
23354
|
+
}
|
|
23355
|
+
}
|
|
23356
|
+
};
|
|
23357
|
+
paint(false, value);
|
|
23358
|
+
return { get value() {
|
|
23359
|
+
return value;
|
|
23360
|
+
}, setValue: set, reset: (notify = false) => set(initial, notify), configure, destroy: () => scope.dispose() };
|
|
23361
|
+
}
|
|
23362
|
+
|
|
23363
|
+
// src/components/equalizer-slider/engine.ts
|
|
23364
|
+
function createEqualizerSlider(root, options = {}) {
|
|
23365
|
+
return createNumericRange(root, options, {
|
|
23366
|
+
prefix: "equalizer",
|
|
23367
|
+
label: "Volumen",
|
|
23368
|
+
min: 0,
|
|
23369
|
+
max: 100,
|
|
23370
|
+
value: 60,
|
|
23371
|
+
format: (n) => `${n} %`,
|
|
23372
|
+
decorate({ track, keep }) {
|
|
23373
|
+
const wave = document.createElement("span");
|
|
23374
|
+
wave.dataset.mkEqualizerWave = "";
|
|
23375
|
+
wave.setAttribute("aria-hidden", "true");
|
|
23376
|
+
track.prepend(wave);
|
|
23377
|
+
const count = Math.max(12, Math.min(72, Math.round(Number.isFinite(options.bars) ? options.bars : 40)));
|
|
23378
|
+
const bars = Array.from({ length: count }, (_, i) => {
|
|
23379
|
+
const bar = document.createElement("span");
|
|
23380
|
+
const supplied = options.waveform?.[i % options.waveform.length];
|
|
23381
|
+
const height = Number.isFinite(supplied) ? Math.max(0.1, Math.min(1, supplied)) : 0.25 + 0.75 * Math.abs(Math.sin(i * 1.73) * Math.cos(i * 0.41));
|
|
23382
|
+
bar.style.height = `${height * 100}%`;
|
|
23383
|
+
wave.append(bar);
|
|
23384
|
+
return bar;
|
|
23385
|
+
});
|
|
23386
|
+
return (ratio, _value, animate) => bars.forEach((bar, i) => {
|
|
23387
|
+
const on = i / Math.max(1, count - 1) <= ratio;
|
|
23388
|
+
const changed = bar.hasAttribute("data-mk-on") !== on;
|
|
23389
|
+
bar.toggleAttribute("data-mk-on", on);
|
|
23390
|
+
if (animate && changed && !reduced()) keep(gsap.fromTo(bar, { scaleY: 0.72 }, { scaleY: 1, duration: 0.35, ease: EASE.swatch, overwrite: "auto", clearProps: "transform" }));
|
|
23391
|
+
});
|
|
23392
|
+
}
|
|
23393
|
+
});
|
|
23394
|
+
}
|
|
23395
|
+
|
|
23396
|
+
// src/components/temperature-slider/engine.ts
|
|
23397
|
+
var RANGE = { C: { min: 16, max: 30, value: 22 }, F: { min: 60, max: 86, value: 72 } };
|
|
23398
|
+
var convert = (value, from, to) => from === to ? value : to === "F" ? value * 9 / 5 + 32 : (value - 32) * 5 / 9;
|
|
23399
|
+
function createTemperatureSlider(root, options = {}) {
|
|
23400
|
+
let unit = options.unit === "F" ? "F" : "C";
|
|
23401
|
+
const formatFor = (next) => (n) => `${n}\xB0${next}`;
|
|
23402
|
+
const range = createNumericRange(root, options, {
|
|
23403
|
+
prefix: "temperature",
|
|
23404
|
+
label: "Temperatura",
|
|
23405
|
+
...RANGE[unit],
|
|
23406
|
+
format: formatFor(unit),
|
|
23407
|
+
decorate({ track, thumb }) {
|
|
23408
|
+
const rail = document.createElement("span");
|
|
23409
|
+
rail.dataset.mkTemperatureRail = "";
|
|
23410
|
+
rail.setAttribute("aria-hidden", "true");
|
|
23411
|
+
track.prepend(rail);
|
|
23412
|
+
const fill = document.createElement("span");
|
|
23413
|
+
fill.dataset.mkTemperatureFill = "";
|
|
23414
|
+
rail.append(fill);
|
|
23415
|
+
const ticks = document.createElement("span");
|
|
23416
|
+
ticks.dataset.mkTemperatureTicks = "";
|
|
23417
|
+
ticks.setAttribute("aria-hidden", "true");
|
|
23418
|
+
for (let i = 0; i <= 14; i++) ticks.append(document.createElement("i"));
|
|
23419
|
+
track.prepend(ticks);
|
|
23420
|
+
thumb.textContent = "\xB7\xB7";
|
|
23421
|
+
return (ratio) => {
|
|
23422
|
+
root?.style.setProperty("--mk-temperature-warm", `${Math.round(ratio * 100)}%`);
|
|
23423
|
+
fill.style.width = `${ratio * 100}%`;
|
|
23424
|
+
};
|
|
23425
|
+
}
|
|
23426
|
+
});
|
|
23427
|
+
return {
|
|
23428
|
+
get value() {
|
|
23429
|
+
return range.value;
|
|
23430
|
+
},
|
|
23431
|
+
get unit() {
|
|
23432
|
+
return unit;
|
|
23433
|
+
},
|
|
23434
|
+
setValue: range.setValue,
|
|
23435
|
+
reset: range.reset,
|
|
23436
|
+
setUnit(next, limits = {}, notify = false) {
|
|
23437
|
+
const target = next === "F" ? "F" : "C";
|
|
23438
|
+
const value = Math.round(convert(range.value, unit, target));
|
|
23439
|
+
unit = target;
|
|
23440
|
+
range.configure({ min: limits.min ?? RANGE[target].min, max: limits.max ?? RANGE[target].max, step: limits.step, format: options.formatValue ?? formatFor(target), value }, notify);
|
|
23441
|
+
},
|
|
23442
|
+
destroy: range.destroy
|
|
23443
|
+
};
|
|
23444
|
+
}
|
|
23445
|
+
|
|
23446
|
+
// src/components/rating-scale/engine.ts
|
|
23447
|
+
var SENTIMENTS = ["Muy mal", "Mal", "Regular", "Bien", "Muy bien"];
|
|
23448
|
+
var SYMBOLS = ["\u2322", "\u2322", "\u2212", "\u2323", "\u2323"];
|
|
23449
|
+
function createRatingScale(root, options = {}) {
|
|
23450
|
+
if (!root) return inert({ value: null, setValue() {
|
|
23451
|
+
}, reset() {
|
|
23452
|
+
} });
|
|
23453
|
+
const sentiment = options.variant === "sentiment";
|
|
23454
|
+
const min = Number.isFinite(options.min) ? Math.round(options.min) : sentiment ? 1 : 0;
|
|
23455
|
+
const max = Number.isFinite(options.max) ? Math.max(min, Math.min(min + 20, Math.round(options.max))) : sentiment ? min + 4 : min + 10;
|
|
23456
|
+
const labels = options.labels ?? (sentiment ? SENTIMENTS : []);
|
|
23457
|
+
const items = Array.from({ length: max - min + 1 }, (_, i) => ({
|
|
23458
|
+
value: String(min + i),
|
|
23459
|
+
label: labels[i] ?? String(min + i),
|
|
23460
|
+
symbol: sentiment ? SYMBOLS[Math.min(4, Math.round(i / Math.max(1, max - min) * 4))] : String(min + i)
|
|
23461
|
+
}));
|
|
23462
|
+
const normalize3 = (value) => value != null && Number.isFinite(value) ? String(Math.max(min, Math.min(max, Math.round(value)))) : null;
|
|
23463
|
+
const instance = createChoices(root, "rating-scale", {
|
|
23464
|
+
...options,
|
|
23465
|
+
variant: sentiment ? "sentiment" : "numbered",
|
|
23466
|
+
items,
|
|
23467
|
+
value: normalize3(options.value !== void 0 ? options.value : options.defaultValue),
|
|
23468
|
+
defaultValue: normalize3(options.defaultValue !== void 0 ? options.defaultValue : options.value),
|
|
23469
|
+
caption: (value) => value === null ? "Sin responder" : labels[Number(value) - min] ?? `${value} de ${max}`,
|
|
23470
|
+
eventValue: (value) => value === null ? null : Number(value),
|
|
23471
|
+
onChange: (value) => options.onChange?.(value === null ? null : Number(value)),
|
|
23472
|
+
decorate(labels2, index, previous, animate, keep) {
|
|
23473
|
+
labels2.forEach((label, i) => label.toggleAttribute("data-mk-in-range", !sentiment && index >= 0 && i < index));
|
|
23474
|
+
if (!animate || index < 0) return;
|
|
23475
|
+
if (sentiment) {
|
|
23476
|
+
const mood = index / Math.max(1, labels2.length - 1) * 2 - 1;
|
|
23477
|
+
const mark = labels2[index].querySelector("[data-mk-rating-scale-mark]");
|
|
23478
|
+
keep(gsap.timeline().to(mark, { y: mood > 0 ? -8 * mood : 4 * -mood, rotate: mood === 0 ? 8 : 12 * mood, duration: 0.14, ease: "power2.out" }).to(mark, { y: 0, rotate: 0, duration: 0.55, ease: EASE.click, clearProps: "y,rotate" }));
|
|
23479
|
+
return;
|
|
23480
|
+
}
|
|
23481
|
+
const from = previous >= 0 ? previous : 0, step = index >= from ? 1 : -1;
|
|
23482
|
+
for (let i = from, k = 0; i !== index; i += step, k++) {
|
|
23483
|
+
keep(gsap.timeline({ delay: Math.min(k * 0.03, 0.3) }).to(labels2[i], { y: -5, duration: 0.12, ease: "power2.out" }).to(labels2[i], { y: 0, duration: 0.4, ease: EASE.click, clearProps: "y" }));
|
|
23484
|
+
}
|
|
23485
|
+
}
|
|
23486
|
+
});
|
|
23487
|
+
return {
|
|
23488
|
+
get value() {
|
|
23489
|
+
return instance.value === null ? null : Number(instance.value);
|
|
23490
|
+
},
|
|
23491
|
+
setValue: (value, notify = false) => instance.setValue(normalize3(value), notify),
|
|
23492
|
+
reset: (notify = false) => instance.reset(notify),
|
|
23493
|
+
destroy: () => instance.destroy()
|
|
23494
|
+
};
|
|
23495
|
+
}
|
|
23496
|
+
|
|
23497
|
+
// src/components/notification-stack/engine.ts
|
|
23498
|
+
var sequence28 = 0;
|
|
23499
|
+
function createNotificationStack(root, options = {}) {
|
|
23500
|
+
if (!root) return inert({ push() {
|
|
23501
|
+
}, dismiss() {
|
|
23502
|
+
}, clear() {
|
|
23503
|
+
}, expand() {
|
|
23504
|
+
}, collapse() {
|
|
23505
|
+
}, toggle() {
|
|
23506
|
+
}, setOptions() {
|
|
23507
|
+
}, items: [], expanded: false });
|
|
23508
|
+
registerMotion();
|
|
23509
|
+
const scope = createScope();
|
|
23510
|
+
let opts = { ...options };
|
|
23511
|
+
let expanded = options.expanded ?? false;
|
|
23512
|
+
let hovered = false;
|
|
23513
|
+
let focused = false;
|
|
23514
|
+
let inviting = false;
|
|
23515
|
+
let resize = null;
|
|
23516
|
+
const heights = /* @__PURE__ */ new WeakMap();
|
|
23517
|
+
const original = [...root.childNodes];
|
|
23518
|
+
const entries = /* @__PURE__ */ new Map();
|
|
23519
|
+
const animations = /* @__PURE__ */ new Set();
|
|
23520
|
+
const track = (animation) => {
|
|
23521
|
+
for (const prior of animations) if (prior.totalProgress() === 1 || !prior.parent) animations.delete(prior);
|
|
23522
|
+
if (animation) animations.add(animation);
|
|
23523
|
+
};
|
|
23524
|
+
const deck = document.createElement("div");
|
|
23525
|
+
deck.className = "mk-notification-stack__deck";
|
|
23526
|
+
deck.id = `mk-notifications-${++sequence28}`;
|
|
23527
|
+
const empty = document.createElement("p");
|
|
23528
|
+
empty.className = "mk-notification-stack__empty";
|
|
23529
|
+
const toggle = document.createElement("button");
|
|
23530
|
+
toggle.type = "button";
|
|
23531
|
+
toggle.className = "mk-notification-stack__toggle";
|
|
23532
|
+
toggle.setAttribute("aria-controls", deck.id);
|
|
23533
|
+
const count = document.createElement("span");
|
|
23534
|
+
const toggleText = document.createElement("span");
|
|
23535
|
+
const chevron2 = document.createElement("span");
|
|
23536
|
+
chevron2.className = "mk-notification-stack__chevron";
|
|
23537
|
+
chevron2.setAttribute("aria-hidden", "true");
|
|
23538
|
+
chevron2.innerHTML = '<svg viewBox="0 0 16 16"><path d="m4 6 4 4 4-4"/></svg>';
|
|
23539
|
+
toggle.append(count, toggleText, chevron2);
|
|
23540
|
+
const live2 = document.createElement("span");
|
|
23541
|
+
live2.className = "mk-sr-only";
|
|
23542
|
+
live2.setAttribute("role", "status");
|
|
23543
|
+
live2.setAttribute("aria-live", "polite");
|
|
23544
|
+
root.replaceChildren(deck, empty, toggle, live2);
|
|
23545
|
+
scope.attr(root, "class", `${root.className} mk-notification-stack`.trim());
|
|
23546
|
+
scope.attr(root, "data-mk-ready", "");
|
|
23547
|
+
scope.attr(root, "role", "region");
|
|
23548
|
+
const pause = (entry) => {
|
|
23549
|
+
if (entry.timer !== void 0) {
|
|
23550
|
+
clearTimeout(entry.timer);
|
|
23551
|
+
entry.timer = void 0;
|
|
23552
|
+
entry.remaining = Math.max(0, entry.remaining - (Date.now() - entry.started));
|
|
23553
|
+
}
|
|
23554
|
+
};
|
|
23555
|
+
const paused = () => hovered || focused || opts.disabled || document.hidden;
|
|
23556
|
+
const start = (entry) => {
|
|
23557
|
+
if (paused() || entry.remaining === Infinity || entry.timer !== void 0) return;
|
|
23558
|
+
entry.started = Date.now();
|
|
23559
|
+
entry.timer = setTimeout(() => dismiss(entry.item.id), entry.remaining);
|
|
23560
|
+
};
|
|
23561
|
+
const syncTimers = () => entries.forEach((entry) => paused() ? pause(entry) : start(entry));
|
|
23562
|
+
const duration = (item) => {
|
|
23563
|
+
const ms = item.duration ?? opts.duration ?? 6e3;
|
|
23564
|
+
return Number.isFinite(ms) && ms > 0 ? ms : Infinity;
|
|
23565
|
+
};
|
|
23566
|
+
const layout = (motion) => {
|
|
23567
|
+
if (scope.disposed) return;
|
|
23568
|
+
const cards = [...entries.values()].reverse();
|
|
23569
|
+
const direction = opts.direction === "up" || opts.direction === "side" ? opts.direction : "down";
|
|
23570
|
+
scope.attr(root, "data-mk-direction", direction);
|
|
23571
|
+
scope.attr(root, "data-mk-expandable", !expanded && cards.length > 1 && !opts.disabled ? "" : null);
|
|
23572
|
+
const peek = inviting && !expanded && !reduced() ? 18 : 12;
|
|
23573
|
+
cards.forEach((entry, index) => {
|
|
23574
|
+
const visible = expanded || index === 0;
|
|
23575
|
+
entry.card.inert = !visible || !!opts.disabled;
|
|
23576
|
+
entry.card.setAttribute("aria-hidden", String(!visible));
|
|
23577
|
+
entry.card.toggleAttribute("data-mk-peek", !visible);
|
|
23578
|
+
});
|
|
23579
|
+
if (cards[0]) deck.style.setProperty("--mk-stack-front", `${cards[0].card.offsetHeight}px`);
|
|
23580
|
+
let offset = 0;
|
|
23581
|
+
let tallest = 0;
|
|
23582
|
+
cards.forEach((entry, index) => {
|
|
23583
|
+
entry.card.style.zIndex = String(cards.length - index);
|
|
23584
|
+
const layer = Math.min(index, 3);
|
|
23585
|
+
let x = 0, y = 0;
|
|
23586
|
+
if (expanded) {
|
|
23587
|
+
if (direction === "side") x = offset;
|
|
23588
|
+
else y = direction === "up" ? -offset : offset;
|
|
23589
|
+
offset += direction === "side" ? entry.card.offsetWidth + 12 : entry.card.offsetHeight + 8;
|
|
23590
|
+
} else if (direction === "side") x = layer * peek;
|
|
23591
|
+
else y = (direction === "up" ? -1 : 1) * layer * peek;
|
|
23592
|
+
tallest = Math.max(tallest, entry.card.offsetHeight);
|
|
23593
|
+
const delay = reduced() ? 0 : motion === "expand" ? index * 0.05 : motion === "collapse" ? Math.max(0, cards.length - 1 - index) * 0.03 : 0;
|
|
23594
|
+
entry.card.style.setProperty("--mk-stack-delay", `${delay}s`);
|
|
23595
|
+
track(gsap.to(entry.card, { x, y, scale: expanded ? 1 : Math.max(0.84, 1 - index * 0.045), opacity: expanded || index < 3 ? 1 : 0, duration: reduced() ? 0 : 0.45, delay, ease: EASE.swatch, overwrite: "auto" }));
|
|
23596
|
+
if (motion === "expand" && index > 0 && !reduced()) track(gsap.fromTo(entry.card, { filter: "blur(6px)" }, { filter: "blur(0px)", duration: 0.4, delay, ease: "power2.out", clearProps: "filter" }));
|
|
23597
|
+
});
|
|
23598
|
+
const front = cards[0]?.card.offsetHeight || 100;
|
|
23599
|
+
const height = !cards.length ? 0 : direction === "side" ? expanded ? tallest : front : expanded ? offset - 8 : front + Math.min(cards.length - 1, 2) * peek;
|
|
23600
|
+
if (!expanded && direction === "side" && deck.scrollLeft) deck.scrollTo({ left: 0, behavior: reduced() ? "auto" : "smooth" });
|
|
23601
|
+
track(gsap.to(deck, { height, duration: reduced() ? 0 : 0.4, ease: EASE.signature, overwrite: "auto" }));
|
|
23602
|
+
empty.hidden = cards.length > 0;
|
|
23603
|
+
empty.textContent = opts.labels?.empty ?? "Todo al d\xEDa. No hay notificaciones.";
|
|
23604
|
+
toggle.hidden = cards.length < 2;
|
|
23605
|
+
toggle.disabled = !!opts.disabled;
|
|
23606
|
+
toggle.setAttribute("aria-expanded", String(expanded));
|
|
23607
|
+
const toggleLabel = expanded ? opts.labels?.collapse ?? "Recoger" : opts.labels?.expand ?? "Ver todas";
|
|
23608
|
+
if (toggleText.textContent !== toggleLabel) {
|
|
23609
|
+
toggleText.textContent = toggleLabel;
|
|
23610
|
+
if (motion) track(blurIn(toggleText, { from: "soft", duration: 0.25 }));
|
|
23611
|
+
}
|
|
23612
|
+
track(rollDigits(count, String(cards.length)));
|
|
23613
|
+
scope.attr(root, "aria-label", opts.label ?? "Notificaciones");
|
|
23614
|
+
scope.attr(root, "data-mk-expanded", String(expanded));
|
|
23615
|
+
scope.attr(root, "data-mk-disabled", opts.disabled ? "" : null);
|
|
23616
|
+
};
|
|
23617
|
+
const dismiss = (id) => {
|
|
23618
|
+
if (scope.disposed || opts.disabled) return;
|
|
23619
|
+
const entry = entries.get(id);
|
|
23620
|
+
if (!entry) return;
|
|
23621
|
+
pause(entry);
|
|
23622
|
+
resize?.unobserve(entry.card);
|
|
23623
|
+
const hadFocus = entry.card.contains(document.activeElement);
|
|
23624
|
+
entries.delete(id);
|
|
23625
|
+
if (hadFocus) {
|
|
23626
|
+
const next = [...entries.values()].reverse()[0];
|
|
23627
|
+
const target = next?.card.querySelector("button");
|
|
23628
|
+
if (target) {
|
|
23629
|
+
next.card.inert = false;
|
|
23630
|
+
target.focus();
|
|
23631
|
+
} else {
|
|
23632
|
+
root.setAttribute("tabindex", "-1");
|
|
23633
|
+
root.focus();
|
|
23634
|
+
}
|
|
23635
|
+
}
|
|
23636
|
+
gsap.killTweensOf(entry.card);
|
|
23637
|
+
entry.card.inert = true;
|
|
23638
|
+
entry.card.setAttribute("aria-hidden", "true");
|
|
23639
|
+
if (reduced()) entry.card.remove();
|
|
23640
|
+
else track(gsap.to(entry.card, { y: "-=18", scale: 0.94, opacity: 0, filter: "blur(8px)", duration: 0.23, ease: EASE.close, onComplete: () => entry.card.remove() }));
|
|
23641
|
+
layout();
|
|
23642
|
+
opts.onDismiss?.(id);
|
|
23643
|
+
root.dispatchEvent(new CustomEvent("mk:dismiss", { bubbles: true, detail: { id } }));
|
|
23644
|
+
};
|
|
23645
|
+
const build = (item) => {
|
|
23646
|
+
const card = document.createElement("article");
|
|
23647
|
+
card.className = "mk-notification-stack__card";
|
|
23648
|
+
card.dataset.mkNotification = item.id;
|
|
23649
|
+
card.dataset.mkTone = item.tone ?? "neutral";
|
|
23650
|
+
const mark = document.createElement("span");
|
|
23651
|
+
mark.className = "mk-notification-stack__mark";
|
|
23652
|
+
mark.setAttribute("aria-hidden", "true");
|
|
23653
|
+
mark.textContent = item.tone === "success" ? "\u2713" : item.tone === "error" ? "!" : "\u2197";
|
|
23654
|
+
const body = document.createElement("div");
|
|
23655
|
+
body.className = "mk-notification-stack__body";
|
|
23656
|
+
const title = document.createElement("strong");
|
|
23657
|
+
title.textContent = item.title;
|
|
23658
|
+
body.append(title);
|
|
23659
|
+
if (item.description) {
|
|
23660
|
+
const description = document.createElement("p");
|
|
23661
|
+
description.textContent = item.description;
|
|
23662
|
+
body.append(description);
|
|
23663
|
+
}
|
|
23664
|
+
if (item.action) {
|
|
23665
|
+
const action = document.createElement("button");
|
|
23666
|
+
action.type = "button";
|
|
23667
|
+
action.className = "mk-notification-stack__action";
|
|
23668
|
+
action.dataset.mkNotificationAction = item.id;
|
|
23669
|
+
action.textContent = item.action.label;
|
|
23670
|
+
action.disabled = !!opts.disabled;
|
|
23671
|
+
body.append(action);
|
|
23672
|
+
}
|
|
23673
|
+
card.append(mark, body);
|
|
23674
|
+
if (item.dismissible !== false) {
|
|
23675
|
+
const close = document.createElement("button");
|
|
23676
|
+
close.type = "button";
|
|
23677
|
+
close.className = "mk-notification-stack__dismiss";
|
|
23678
|
+
close.dataset.mkNotificationDismiss = item.id;
|
|
23679
|
+
close.setAttribute("aria-label", `${opts.labels?.dismiss ?? "Cerrar"}: ${item.title}`);
|
|
23680
|
+
close.textContent = "\xD7";
|
|
23681
|
+
close.disabled = !!opts.disabled;
|
|
23682
|
+
card.append(close);
|
|
23683
|
+
}
|
|
23684
|
+
return { item: { ...item }, card, remaining: duration(item), started: 0 };
|
|
23685
|
+
};
|
|
23686
|
+
const push = (item) => {
|
|
23687
|
+
if (scope.disposed || !item.id || entries.has(item.id)) return;
|
|
23688
|
+
const entry = build(item);
|
|
23689
|
+
entries.set(item.id, entry);
|
|
23690
|
+
deck.append(entry.card);
|
|
23691
|
+
resize?.observe(entry.card);
|
|
23692
|
+
layout();
|
|
23693
|
+
track(blurIn(entry.card, { from: "pop", duration: 0.35 }));
|
|
23694
|
+
live2.textContent = `${item.title}${item.description ? `. ${item.description}` : ""}`;
|
|
23695
|
+
start(entry);
|
|
23696
|
+
};
|
|
23697
|
+
const setExpanded = (next, notify = true, allowDisabled = false) => {
|
|
23698
|
+
if (scope.disposed || expanded === next || opts.disabled && !allowDisabled) return;
|
|
23699
|
+
if (!next && [...entries.values()].slice(0, -1).some((entry) => entry.card.contains(document.activeElement))) {
|
|
23700
|
+
if (opts.disabled) {
|
|
23701
|
+
root.tabIndex = -1;
|
|
23702
|
+
root.focus();
|
|
23703
|
+
} else toggle.focus();
|
|
23704
|
+
}
|
|
23705
|
+
expanded = next;
|
|
23706
|
+
layout(next ? "expand" : "collapse");
|
|
23707
|
+
if (notify) {
|
|
23708
|
+
opts.onExpandedChange?.(expanded);
|
|
23709
|
+
root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { expanded } }));
|
|
23710
|
+
}
|
|
23711
|
+
};
|
|
23712
|
+
scope.attr(root, "tabindex", root.getAttribute("tabindex"));
|
|
23713
|
+
scope.on(root, "pointerenter", () => {
|
|
23714
|
+
hovered = true;
|
|
23715
|
+
syncTimers();
|
|
23716
|
+
});
|
|
23717
|
+
scope.on(root, "pointerleave", () => {
|
|
23718
|
+
hovered = false;
|
|
23719
|
+
syncTimers();
|
|
23720
|
+
});
|
|
23721
|
+
scope.on(root, "focusin", () => {
|
|
23722
|
+
focused = true;
|
|
23723
|
+
syncTimers();
|
|
23724
|
+
});
|
|
23725
|
+
scope.on(root, "focusout", (event) => {
|
|
23726
|
+
focused = root.contains(event.relatedTarget);
|
|
23727
|
+
syncTimers();
|
|
23728
|
+
});
|
|
23729
|
+
scope.on(document, "visibilitychange", syncTimers);
|
|
23730
|
+
scope.on(deck, "pointerenter", () => {
|
|
23731
|
+
inviting = true;
|
|
23732
|
+
if (!expanded && entries.size > 1) layout();
|
|
23733
|
+
});
|
|
23734
|
+
scope.on(deck, "pointerleave", () => {
|
|
23735
|
+
inviting = false;
|
|
23736
|
+
if (!expanded && entries.size > 1) layout();
|
|
23737
|
+
});
|
|
23738
|
+
scope.on(root, "click", (event) => {
|
|
23739
|
+
if (opts.disabled) return;
|
|
23740
|
+
if (!expanded && entries.size > 1 && deck.contains(event.target) && !event.target.closest("button")) {
|
|
23741
|
+
setExpanded(true);
|
|
23742
|
+
return;
|
|
23743
|
+
}
|
|
23744
|
+
const button2 = event.target.closest("button");
|
|
23745
|
+
if (!button2 || !root.contains(button2) || button2.disabled) return;
|
|
23746
|
+
track(press(button2));
|
|
23747
|
+
if (button2 === toggle) setExpanded(!expanded);
|
|
23748
|
+
else if (button2.dataset.mkNotificationDismiss) dismiss(button2.dataset.mkNotificationDismiss);
|
|
23749
|
+
else if (button2.dataset.mkNotificationAction) {
|
|
23750
|
+
const id = button2.dataset.mkNotificationAction;
|
|
23751
|
+
entries.get(id)?.item.action?.onClick?.();
|
|
23752
|
+
opts.onAction?.(id);
|
|
23753
|
+
dismiss(id);
|
|
23754
|
+
}
|
|
23755
|
+
});
|
|
23756
|
+
if (typeof ResizeObserver === "function") {
|
|
23757
|
+
resize = scope.observe(new ResizeObserver((records) => {
|
|
23758
|
+
let changed = false;
|
|
23759
|
+
for (const record of records) {
|
|
23760
|
+
const card = record.target;
|
|
23761
|
+
if (heights.get(card) !== card.offsetHeight) {
|
|
23762
|
+
heights.set(card, card.offsetHeight);
|
|
23763
|
+
changed = true;
|
|
23764
|
+
}
|
|
23765
|
+
}
|
|
23766
|
+
if (changed) layout();
|
|
23767
|
+
}));
|
|
23768
|
+
}
|
|
23769
|
+
scope.on(window, "resize", () => layout(), { passive: true });
|
|
23770
|
+
const setOptions = (next) => {
|
|
23771
|
+
if (scope.disposed) return;
|
|
23772
|
+
opts = { ...opts, ...next };
|
|
23773
|
+
if (next.items) {
|
|
23774
|
+
const ids = new Set(next.items.map((item) => item.id));
|
|
23775
|
+
for (const [id, entry] of entries) if (!ids.has(id)) {
|
|
23776
|
+
pause(entry);
|
|
23777
|
+
resize?.unobserve(entry.card);
|
|
23778
|
+
if (entry.card.contains(document.activeElement)) {
|
|
23779
|
+
root.setAttribute("tabindex", "-1");
|
|
23780
|
+
root.focus();
|
|
23781
|
+
}
|
|
23782
|
+
gsap.killTweensOf(entry.card);
|
|
23783
|
+
entry.card.remove();
|
|
23784
|
+
entries.delete(id);
|
|
23785
|
+
}
|
|
23786
|
+
for (const item of next.items) {
|
|
23787
|
+
const existing = entries.get(item.id);
|
|
23788
|
+
if (!existing) {
|
|
23789
|
+
push(item);
|
|
23790
|
+
continue;
|
|
23791
|
+
}
|
|
23792
|
+
const replacement = build(item);
|
|
23793
|
+
if (existing.card.contains(document.activeElement)) {
|
|
23794
|
+
root.setAttribute("tabindex", "-1");
|
|
23795
|
+
root.focus();
|
|
23796
|
+
}
|
|
23797
|
+
pause(existing);
|
|
23798
|
+
replacement.remaining = existing.remaining;
|
|
23799
|
+
existing.card.replaceWith(replacement.card);
|
|
23800
|
+
gsap.killTweensOf(existing.card);
|
|
23801
|
+
entries.set(item.id, replacement);
|
|
23802
|
+
resize?.unobserve(existing.card);
|
|
23803
|
+
resize?.observe(replacement.card);
|
|
23804
|
+
}
|
|
23805
|
+
const ordered = next.items.map((item) => entries.get(item.id)).filter((entry) => !!entry);
|
|
23806
|
+
entries.clear();
|
|
23807
|
+
for (const entry of ordered) {
|
|
23808
|
+
entries.set(entry.item.id, entry);
|
|
23809
|
+
deck.append(entry.card);
|
|
23810
|
+
}
|
|
23811
|
+
}
|
|
23812
|
+
if (next.expanded !== void 0) setExpanded(next.expanded, false, true);
|
|
23813
|
+
for (const entry of entries.values()) entry.card.querySelectorAll("button").forEach((button2) => {
|
|
23814
|
+
button2.disabled = !!opts.disabled;
|
|
23815
|
+
if (button2.hasAttribute("data-mk-notification-dismiss")) button2.setAttribute("aria-label", `${opts.labels?.dismiss ?? "Cerrar"}: ${entry.item.title}`);
|
|
23816
|
+
});
|
|
23817
|
+
layout();
|
|
23818
|
+
syncTimers();
|
|
23819
|
+
};
|
|
23820
|
+
for (const item of options.items ?? []) push(item);
|
|
23821
|
+
layout();
|
|
23822
|
+
return {
|
|
23823
|
+
push,
|
|
23824
|
+
dismiss,
|
|
23825
|
+
clear() {
|
|
23826
|
+
for (const id of [...entries.keys()]) dismiss(id);
|
|
23827
|
+
},
|
|
23828
|
+
expand: () => setExpanded(true),
|
|
23829
|
+
collapse: () => setExpanded(false),
|
|
23830
|
+
toggle: () => setExpanded(!expanded),
|
|
23831
|
+
setOptions,
|
|
23832
|
+
get items() {
|
|
23833
|
+
return [...entries.values()].map((entry) => ({ ...entry.item }));
|
|
23834
|
+
},
|
|
23835
|
+
get expanded() {
|
|
23836
|
+
return expanded;
|
|
23837
|
+
},
|
|
23838
|
+
destroy() {
|
|
23839
|
+
if (scope.disposed) return;
|
|
23840
|
+
entries.forEach(pause);
|
|
23841
|
+
animations.forEach((animation) => animation.kill());
|
|
23842
|
+
gsap.killTweensOf([...root.querySelectorAll("*")]);
|
|
23843
|
+
scope.dispose();
|
|
23844
|
+
root.replaceChildren(...original);
|
|
23845
|
+
}
|
|
23846
|
+
};
|
|
23847
|
+
}
|
|
23848
|
+
|
|
23849
|
+
// src/components/bento-grid/engine.ts
|
|
23850
|
+
function createBentoGrid(root, options = {}) {
|
|
23851
|
+
if (!root) return inert({ refresh() {
|
|
23852
|
+
}, setFilter() {
|
|
23853
|
+
}, reorder() {
|
|
23854
|
+
}, mutate() {
|
|
23855
|
+
}, setOptions() {
|
|
23856
|
+
}, filter: null, keys: [] });
|
|
23857
|
+
registerMotion();
|
|
23858
|
+
const scope = createScope();
|
|
23859
|
+
let opts = { ...options };
|
|
23860
|
+
let filter = opts.filter ?? null;
|
|
23861
|
+
let animation = null;
|
|
23862
|
+
const micro = /* @__PURE__ */ new Set();
|
|
23863
|
+
const track = (value) => {
|
|
23864
|
+
if (value) micro.add(value);
|
|
23865
|
+
};
|
|
23866
|
+
const originals = [...root.childNodes];
|
|
23867
|
+
const originalItems = new Set(root.children);
|
|
23868
|
+
const remembered = /* @__PURE__ */ new Set();
|
|
23869
|
+
let queued = 0;
|
|
23870
|
+
scope.attr(root, "class", `${root.className} mk-bento-grid`.trim());
|
|
23871
|
+
scope.attr(root, "style", root.getAttribute("style"));
|
|
23872
|
+
scope.attr(root, "data-mk-ready", "");
|
|
23873
|
+
const items = () => [...root.children].filter((node) => node instanceof HTMLElement && node.hasAttribute("data-mk-bento-item"));
|
|
23874
|
+
const key2 = (item) => item.dataset.mkBentoItem;
|
|
23875
|
+
const visible = () => items().filter((item) => !item.hidden);
|
|
23876
|
+
const save = (item) => {
|
|
23877
|
+
if (remembered.has(item)) return;
|
|
23878
|
+
remembered.add(item);
|
|
23879
|
+
for (const attr of ["style", "hidden", "inert", "aria-hidden", "data-flip-id"]) scope.attr(item, attr, item.getAttribute(attr));
|
|
23880
|
+
};
|
|
23881
|
+
items().forEach(save);
|
|
23882
|
+
let last;
|
|
23883
|
+
const notify = () => {
|
|
23884
|
+
const keys = visible().map(key2);
|
|
23885
|
+
opts.onChange?.(keys);
|
|
23886
|
+
root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { keys, filter } }));
|
|
23887
|
+
};
|
|
23888
|
+
const paint = () => {
|
|
23889
|
+
const desired = Number.isFinite(opts.columns) ? Math.max(1, Math.min(12, Math.round(opts.columns))) : 3;
|
|
23890
|
+
const cols = root.clientWidth > 0 && root.clientWidth < 280 ? 1 : root.clientWidth > 0 && root.clientWidth < 440 ? Math.min(2, desired) : desired;
|
|
23891
|
+
root.style.setProperty("--mk-bento-columns", String(cols));
|
|
23892
|
+
root.style.setProperty("--mk-bento-gap", `${Math.max(0, opts.gap ?? 12)}px`);
|
|
23893
|
+
items().forEach((item) => {
|
|
23894
|
+
save(item);
|
|
23895
|
+
item.style.setProperty("--mk-bento-col-span", String(Math.max(1, Math.min(cols, Number(item.dataset.mkColSpan) || 1))));
|
|
23896
|
+
item.style.setProperty("--mk-bento-row-span", String(Math.max(1, Math.min(8, Number(item.dataset.mkRowSpan) || 1))));
|
|
23897
|
+
const show = !filter || (item.dataset.mkCategory ?? "").split(/\s+/).includes(filter);
|
|
23898
|
+
if (!show && item.contains(document.activeElement)) {
|
|
23899
|
+
scope.attr(root, "tabindex", root.getAttribute("tabindex"));
|
|
23900
|
+
root.tabIndex = -1;
|
|
23901
|
+
root.focus();
|
|
23902
|
+
}
|
|
23903
|
+
item.hidden = !show;
|
|
23904
|
+
item.inert = !show;
|
|
23905
|
+
item.setAttribute("aria-hidden", String(!show));
|
|
23906
|
+
});
|
|
23907
|
+
scope.attr(root, "data-mk-empty", visible().length ? null : "");
|
|
23908
|
+
if (!root.hasAttribute("data-mk-empty-label")) scope.attr(root, "data-mk-empty-label", "No hay elementos en esta vista.");
|
|
23909
|
+
};
|
|
23910
|
+
const transition = (state = last, entering = []) => {
|
|
23911
|
+
if (scope.disposed) return;
|
|
23912
|
+
animation?.kill();
|
|
23913
|
+
paint();
|
|
23914
|
+
if (!reduced()) {
|
|
23915
|
+
animation = Flip.from(state ?? Flip.getState([]), { targets: visible(), duration: Math.max(0, opts.duration ?? 0.55), ease: EASE.signature, stagger: 0.025, absolute: false, scale: false, prune: true, onComplete: () => {
|
|
23916
|
+
if (!scope.disposed) last = Flip.getState(visible());
|
|
23917
|
+
} });
|
|
23918
|
+
track(blurIn(entering.filter((item) => !item.hidden), { from: "soft", stagger: 0.04, duration: 0.35 }));
|
|
23919
|
+
}
|
|
23920
|
+
if (!reduced()) last = Flip.getState(visible());
|
|
23921
|
+
};
|
|
23922
|
+
const capture = () => {
|
|
23923
|
+
animation?.kill();
|
|
23924
|
+
if (reduced()) return void 0;
|
|
23925
|
+
const focused = document.activeElement;
|
|
23926
|
+
Flip.killFlipsOf(items());
|
|
23927
|
+
const state = Flip.getState(visible());
|
|
23928
|
+
if (focused?.isConnected && focused !== document.activeElement) focused.focus({ preventScroll: true });
|
|
23929
|
+
return state;
|
|
23930
|
+
};
|
|
23931
|
+
const mutate = (change) => {
|
|
23932
|
+
if (scope.disposed) return;
|
|
23933
|
+
const focused = document.activeElement;
|
|
23934
|
+
const state = capture();
|
|
23935
|
+
const before = new Set(items());
|
|
23936
|
+
change();
|
|
23937
|
+
transition(state, items().filter((item) => !before.has(item)));
|
|
23938
|
+
if (focused && focused !== document.body && root.contains(focused) && !focused.closest("[hidden], [inert]")) focused.focus({ preventScroll: true });
|
|
23939
|
+
else if (focused && !focused.isConnected) {
|
|
23940
|
+
scope.attr(root, "tabindex", root.getAttribute("tabindex"));
|
|
23941
|
+
root.tabIndex = -1;
|
|
23942
|
+
root.focus();
|
|
23943
|
+
}
|
|
23944
|
+
observer?.takeRecords();
|
|
23945
|
+
notify();
|
|
23946
|
+
};
|
|
23947
|
+
const setFilter = (next) => {
|
|
23948
|
+
if (scope.disposed || next === filter) return;
|
|
23949
|
+
const state = capture();
|
|
23950
|
+
const before = new Set(visible());
|
|
23951
|
+
filter = next;
|
|
23952
|
+
paint();
|
|
23953
|
+
transition(state, visible().filter((item) => !before.has(item)));
|
|
23954
|
+
notify();
|
|
23955
|
+
};
|
|
23956
|
+
const refresh = () => {
|
|
23957
|
+
if (scope.disposed) return;
|
|
23958
|
+
transition(last, items().filter((item) => !remembered.has(item)));
|
|
23959
|
+
};
|
|
23960
|
+
const observer = typeof MutationObserver === "function" ? scope.observe(new MutationObserver((records) => {
|
|
23961
|
+
if (!records.some((record) => record.type === "childList" ? record.target === root : record.target instanceof HTMLElement && record.target.parentElement === root)) return;
|
|
23962
|
+
cancelAnimationFrame(queued);
|
|
23963
|
+
queued = requestAnimationFrame(refresh);
|
|
23964
|
+
})) : null;
|
|
23965
|
+
observer?.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: ["data-mk-category", "data-mk-col-span", "data-mk-row-span"] });
|
|
23966
|
+
scope.on(root, "click", (event) => {
|
|
23967
|
+
const control = event.target.closest("button, a");
|
|
23968
|
+
if (control && root.contains(control) && !control.matches(':disabled, [aria-disabled="true"]')) {
|
|
23969
|
+
scope.attr(control, "style", control.getAttribute("style"));
|
|
23970
|
+
track(press(control));
|
|
23971
|
+
}
|
|
23972
|
+
});
|
|
23973
|
+
if (typeof ResizeObserver === "function") {
|
|
23974
|
+
let width = root.clientWidth;
|
|
23975
|
+
const resize = scope.observe(new ResizeObserver(() => {
|
|
23976
|
+
if (root.clientWidth !== width) {
|
|
23977
|
+
width = root.clientWidth;
|
|
23978
|
+
animation?.kill();
|
|
23979
|
+
paint();
|
|
23980
|
+
last = Flip.getState(visible());
|
|
23981
|
+
}
|
|
23982
|
+
}));
|
|
23983
|
+
resize.observe(root);
|
|
23984
|
+
}
|
|
23985
|
+
paint();
|
|
23986
|
+
if (!reduced()) last = Flip.getState(visible());
|
|
23987
|
+
track(blurIn(visible(), { from: "soft", stagger: 0.04 }));
|
|
23988
|
+
return {
|
|
23989
|
+
refresh,
|
|
23990
|
+
mutate,
|
|
23991
|
+
setFilter,
|
|
23992
|
+
reorder(keys) {
|
|
23993
|
+
mutate(() => {
|
|
23994
|
+
const byKey = new Map(items().map((item) => [key2(item), item]));
|
|
23995
|
+
for (const id of new Set(keys)) {
|
|
23996
|
+
const item = byKey.get(id);
|
|
23997
|
+
if (item) {
|
|
23998
|
+
root.append(item);
|
|
23999
|
+
byKey.delete(id);
|
|
24000
|
+
}
|
|
24001
|
+
}
|
|
24002
|
+
byKey.forEach((item) => root.append(item));
|
|
24003
|
+
});
|
|
24004
|
+
},
|
|
24005
|
+
setOptions(next) {
|
|
24006
|
+
if (scope.disposed) return;
|
|
24007
|
+
const state = capture();
|
|
24008
|
+
opts = { ...opts, ...next };
|
|
24009
|
+
if (next.filter !== void 0) filter = next.filter;
|
|
24010
|
+
transition(state);
|
|
24011
|
+
},
|
|
24012
|
+
get filter() {
|
|
24013
|
+
return filter;
|
|
24014
|
+
},
|
|
24015
|
+
get keys() {
|
|
24016
|
+
return visible().map(key2);
|
|
24017
|
+
},
|
|
24018
|
+
destroy() {
|
|
24019
|
+
if (scope.disposed) return;
|
|
24020
|
+
cancelAnimationFrame(queued);
|
|
24021
|
+
animation?.kill();
|
|
24022
|
+
micro.forEach((value) => value.kill());
|
|
24023
|
+
if (!reduced()) Flip.killFlipsOf(items());
|
|
24024
|
+
gsap.killTweensOf([...remembered]);
|
|
24025
|
+
scope.dispose();
|
|
24026
|
+
const added = [...root.childNodes].filter((node) => !originals.includes(node) && !(node instanceof Element && originalItems.has(node)));
|
|
24027
|
+
root.replaceChildren(...originals, ...added);
|
|
24028
|
+
}
|
|
24029
|
+
};
|
|
24030
|
+
}
|
|
24031
|
+
|
|
24032
|
+
// src/components/scroll-preview-dock/engine.ts
|
|
24033
|
+
function createScrollPreviewDock(root, options = {}) {
|
|
24034
|
+
if (!root) return inert({ select() {
|
|
24035
|
+
}, update() {
|
|
24036
|
+
}, setOptions() {
|
|
24037
|
+
}, value: "" });
|
|
24038
|
+
registerMotion();
|
|
24039
|
+
const scope = createScope();
|
|
24040
|
+
let opts = { ...options };
|
|
24041
|
+
let current3 = "";
|
|
24042
|
+
let previewed = "";
|
|
24043
|
+
let frame = 0;
|
|
24044
|
+
let scrolling = null;
|
|
24045
|
+
let unbindScroller = () => {
|
|
24046
|
+
};
|
|
24047
|
+
let scroller = null;
|
|
24048
|
+
const original = [...root.childNodes];
|
|
24049
|
+
const animations = /* @__PURE__ */ new Set();
|
|
24050
|
+
const track = (animation) => {
|
|
24051
|
+
if (animation) animations.add(animation);
|
|
24052
|
+
};
|
|
24053
|
+
const panel = document.createElement("div");
|
|
24054
|
+
panel.className = "mk-scroll-preview-dock__preview";
|
|
24055
|
+
panel.setAttribute("aria-hidden", "true");
|
|
24056
|
+
const image = document.createElement("span");
|
|
24057
|
+
image.className = "mk-scroll-preview-dock__image";
|
|
24058
|
+
const copy = document.createElement("span");
|
|
24059
|
+
const title = document.createElement("strong");
|
|
24060
|
+
const description = document.createElement("span");
|
|
24061
|
+
description.className = "mk-scroll-preview-dock__description";
|
|
24062
|
+
copy.append(title, description);
|
|
24063
|
+
panel.append(image, copy);
|
|
24064
|
+
const nav = document.createElement("nav");
|
|
24065
|
+
nav.className = "mk-scroll-preview-dock__nav";
|
|
24066
|
+
const pill = document.createElement("span");
|
|
24067
|
+
pill.className = "mk-scroll-preview-dock__pill";
|
|
24068
|
+
pill.setAttribute("aria-hidden", "true");
|
|
24069
|
+
const empty = document.createElement("p");
|
|
24070
|
+
empty.className = "mk-scroll-preview-dock__empty";
|
|
24071
|
+
empty.textContent = "No hay secciones para explorar.";
|
|
24072
|
+
root.replaceChildren(panel, nav, empty);
|
|
24073
|
+
scope.attr(root, "class", `${root.className} mk-scroll-preview-dock`.trim());
|
|
24074
|
+
scope.attr(root, "data-mk-ready", "");
|
|
24075
|
+
const items = () => opts.items ?? [];
|
|
24076
|
+
const enabled = (item) => !opts.disabled && !item.disabled;
|
|
24077
|
+
const section = (item) => {
|
|
24078
|
+
if (item.section instanceof HTMLElement) return item.section;
|
|
24079
|
+
if (!item.section) return document.getElementById(item.id);
|
|
24080
|
+
try {
|
|
24081
|
+
return (scroller ?? document).querySelector(item.section);
|
|
24082
|
+
} catch {
|
|
24083
|
+
return null;
|
|
24084
|
+
}
|
|
24085
|
+
};
|
|
24086
|
+
const links = () => [...nav.querySelectorAll("a")];
|
|
24087
|
+
const thumb = (node, item) => {
|
|
24088
|
+
node.replaceChildren();
|
|
24089
|
+
if (item.thumbnail) {
|
|
24090
|
+
const img = document.createElement("img");
|
|
24091
|
+
img.src = item.thumbnail;
|
|
24092
|
+
img.alt = "";
|
|
24093
|
+
img.draggable = false;
|
|
24094
|
+
node.append(img);
|
|
24095
|
+
} else {
|
|
24096
|
+
const letter = document.createElement("span");
|
|
24097
|
+
letter.textContent = item.label.slice(0, 2);
|
|
24098
|
+
node.append(letter);
|
|
24099
|
+
}
|
|
24100
|
+
};
|
|
24101
|
+
const preview = (id, animate = true) => {
|
|
24102
|
+
const item = items().find((item2) => item2.id === id);
|
|
24103
|
+
if (!item || previewed === id) return;
|
|
24104
|
+
previewed = id;
|
|
24105
|
+
thumb(image, item);
|
|
24106
|
+
title.textContent = item.label;
|
|
24107
|
+
description.textContent = item.description ?? "Explorar secci\xF3n";
|
|
24108
|
+
for (const link of links()) link.dataset.mkPreview = String(link.dataset.mkSection === id);
|
|
24109
|
+
if (animate) {
|
|
24110
|
+
gsap.killTweensOf(panel);
|
|
24111
|
+
track(blurIn(panel, { from: "soft", duration: 0.28 }));
|
|
24112
|
+
}
|
|
24113
|
+
};
|
|
24114
|
+
const place3 = (animate = true) => {
|
|
24115
|
+
const active = links().find((link) => link.dataset.mkSection === current3);
|
|
24116
|
+
pill.hidden = !active;
|
|
24117
|
+
if (!active) return;
|
|
24118
|
+
track(gsap.to(pill, { x: active.offsetLeft, y: active.offsetTop, width: active.offsetWidth, height: active.offsetHeight, duration: reduced() || !animate ? 0 : 0.45, ease: EASE.swatch, overwrite: "auto" }));
|
|
24119
|
+
};
|
|
24120
|
+
const activate = (id, notify = true) => {
|
|
24121
|
+
if (scope.disposed || current3 === id) return;
|
|
24122
|
+
current3 = id;
|
|
24123
|
+
for (const link of links()) {
|
|
24124
|
+
if (link.dataset.mkSection === id) link.setAttribute("aria-current", "location");
|
|
24125
|
+
else link.removeAttribute("aria-current");
|
|
24126
|
+
}
|
|
24127
|
+
place3();
|
|
24128
|
+
if (!root.contains(document.activeElement) && !root.matches(":hover")) preview(id);
|
|
24129
|
+
else if (!previewed) preview(id, false);
|
|
24130
|
+
if (notify) {
|
|
24131
|
+
opts.onChange?.(id);
|
|
24132
|
+
root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { value: id } }));
|
|
24133
|
+
}
|
|
24134
|
+
};
|
|
24135
|
+
const update = () => {
|
|
24136
|
+
frame = 0;
|
|
24137
|
+
if (scope.disposed) return;
|
|
24138
|
+
const top = scroller ? scroller.getBoundingClientRect().top + scroller.clientTop : 0;
|
|
24139
|
+
const height = scroller ? scroller.clientHeight : window.innerHeight;
|
|
24140
|
+
const line = top + Math.min(120, height * 0.3) + (opts.offset ?? 0);
|
|
24141
|
+
const targets = items().filter(enabled).map((item) => ({ item, node: section(item) })).filter((entry) => !!entry.node);
|
|
24142
|
+
let target = targets[0];
|
|
24143
|
+
for (const entry of targets) if (entry.node.getBoundingClientRect().top <= line) target = entry;
|
|
24144
|
+
const atEnd = scroller ? scroller.scrollHeight > scroller.clientHeight && scroller.scrollTop + scroller.clientHeight >= scroller.scrollHeight - 2 : document.documentElement.scrollHeight > window.innerHeight && window.scrollY + window.innerHeight >= document.documentElement.scrollHeight - 2;
|
|
24145
|
+
if (atEnd) target = targets.at(-1);
|
|
24146
|
+
if (target) activate(target.item.id);
|
|
24147
|
+
place3(false);
|
|
24148
|
+
};
|
|
24149
|
+
const queue = () => {
|
|
24150
|
+
if (!frame) frame = requestAnimationFrame(update);
|
|
24151
|
+
};
|
|
24152
|
+
const bindScroller = () => {
|
|
24153
|
+
unbindScroller();
|
|
24154
|
+
scroller = typeof opts.scroller === "string" ? (() => {
|
|
24155
|
+
try {
|
|
24156
|
+
return root.closest(opts.scroller) ?? document.querySelector(opts.scroller);
|
|
24157
|
+
} catch {
|
|
24158
|
+
return null;
|
|
24159
|
+
}
|
|
24160
|
+
})() : opts.scroller ?? null;
|
|
24161
|
+
const target = scroller ?? window;
|
|
24162
|
+
target.addEventListener("scroll", queue, { passive: true });
|
|
24163
|
+
target.addEventListener("wheel", cancelScroll, { passive: true });
|
|
24164
|
+
target.addEventListener("touchstart", cancelScroll, { passive: true });
|
|
24165
|
+
unbindScroller = () => {
|
|
24166
|
+
target.removeEventListener("scroll", queue);
|
|
24167
|
+
target.removeEventListener("wheel", cancelScroll);
|
|
24168
|
+
target.removeEventListener("touchstart", cancelScroll);
|
|
24169
|
+
};
|
|
24170
|
+
};
|
|
24171
|
+
function cancelScroll() {
|
|
24172
|
+
scrolling?.kill();
|
|
24173
|
+
scrolling = null;
|
|
24174
|
+
}
|
|
24175
|
+
const select = (id) => {
|
|
24176
|
+
if (scope.disposed) return;
|
|
24177
|
+
const item = items().find((entry) => entry.id === id);
|
|
24178
|
+
if (!item || !enabled(item)) return;
|
|
24179
|
+
const target = section(item);
|
|
24180
|
+
if (!target) return;
|
|
24181
|
+
cancelScroll();
|
|
24182
|
+
const top = Math.max(0, (scroller ? scroller.scrollTop + target.getBoundingClientRect().top - scroller.getBoundingClientRect().top - scroller.clientTop : window.scrollY + target.getBoundingClientRect().top) - (opts.offset ?? 0));
|
|
24183
|
+
activate(id);
|
|
24184
|
+
preview(id);
|
|
24185
|
+
if (scroller) {
|
|
24186
|
+
if (reduced()) scroller.scrollTop = top;
|
|
24187
|
+
else scrolling = gsap.to(scroller, { scrollTop: top, duration: 0.65, ease: EASE.signature, overwrite: "auto", onUpdate: queue });
|
|
24188
|
+
} else if (reduced()) window.scrollTo({ top, behavior: "instant" });
|
|
24189
|
+
else {
|
|
24190
|
+
const position2 = { top: window.scrollY };
|
|
24191
|
+
scrolling = gsap.to(position2, { top, duration: 0.65, ease: EASE.signature, onUpdate: () => {
|
|
24192
|
+
window.scrollTo(0, position2.top);
|
|
24193
|
+
queue();
|
|
24194
|
+
} });
|
|
24195
|
+
}
|
|
24196
|
+
};
|
|
24197
|
+
const render = () => {
|
|
24198
|
+
gsap.killTweensOf(pill);
|
|
24199
|
+
nav.replaceChildren(pill);
|
|
24200
|
+
nav.setAttribute("aria-label", opts.label ?? "Explorar secciones");
|
|
24201
|
+
const unique = /* @__PURE__ */ new Set();
|
|
24202
|
+
for (const item of items()) {
|
|
24203
|
+
if (!item.id || unique.has(item.id)) continue;
|
|
24204
|
+
unique.add(item.id);
|
|
24205
|
+
const link = document.createElement("a");
|
|
24206
|
+
link.href = `#${encodeURIComponent(section(item)?.id || item.id)}`;
|
|
24207
|
+
link.dataset.mkSection = item.id;
|
|
24208
|
+
link.className = "mk-scroll-preview-dock__item";
|
|
24209
|
+
const cover = document.createElement("span");
|
|
24210
|
+
cover.className = "mk-scroll-preview-dock__thumb";
|
|
24211
|
+
cover.setAttribute("aria-hidden", "true");
|
|
24212
|
+
thumb(cover, item);
|
|
24213
|
+
const label = document.createElement("span");
|
|
24214
|
+
label.textContent = item.label;
|
|
24215
|
+
link.append(cover, label);
|
|
24216
|
+
if (!enabled(item)) {
|
|
24217
|
+
link.setAttribute("aria-disabled", "true");
|
|
24218
|
+
link.tabIndex = -1;
|
|
24219
|
+
}
|
|
24220
|
+
nav.append(link);
|
|
24221
|
+
}
|
|
24222
|
+
empty.hidden = unique.size > 0;
|
|
24223
|
+
panel.hidden = unique.size === 0;
|
|
24224
|
+
nav.hidden = unique.size === 0;
|
|
24225
|
+
scope.attr(root, "data-mk-disabled", opts.disabled ? "" : null);
|
|
24226
|
+
previewed = "";
|
|
24227
|
+
const next = items().find((item) => item.id === current3 && enabled(item)) ?? items().find(enabled);
|
|
24228
|
+
current3 = "";
|
|
24229
|
+
if (next) {
|
|
24230
|
+
activate(next.id, false);
|
|
24231
|
+
preview(next.id, false);
|
|
24232
|
+
} else pill.hidden = true;
|
|
24233
|
+
};
|
|
24234
|
+
scope.on(nav, "click", (event) => {
|
|
24235
|
+
const link = event.target.closest("a[data-mk-section]");
|
|
24236
|
+
if (!link) return;
|
|
24237
|
+
if (link.getAttribute("aria-disabled") === "true") {
|
|
24238
|
+
event.preventDefault();
|
|
24239
|
+
return;
|
|
24240
|
+
}
|
|
24241
|
+
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey || event.button !== 0) return;
|
|
24242
|
+
const item = items().find((item2) => item2.id === link.dataset.mkSection);
|
|
24243
|
+
if (!item || !section(item)) return;
|
|
24244
|
+
event.preventDefault();
|
|
24245
|
+
track(press(link));
|
|
24246
|
+
select(item.id);
|
|
24247
|
+
});
|
|
24248
|
+
scope.on(nav, "pointerover", (event) => {
|
|
24249
|
+
const link = event.target.closest("a[data-mk-section]");
|
|
24250
|
+
if (link && link.getAttribute("aria-disabled") !== "true") preview(link.dataset.mkSection);
|
|
24251
|
+
});
|
|
24252
|
+
scope.on(nav, "focusin", (event) => {
|
|
24253
|
+
const link = event.target.closest("a[data-mk-section]");
|
|
24254
|
+
if (link) preview(link.dataset.mkSection);
|
|
24255
|
+
});
|
|
24256
|
+
scope.on(root, "pointerleave", () => {
|
|
24257
|
+
if (!root.contains(document.activeElement)) preview(current3);
|
|
24258
|
+
});
|
|
24259
|
+
scope.on(root, "focusout", (event) => {
|
|
24260
|
+
if (!root.contains(event.relatedTarget)) preview(current3);
|
|
24261
|
+
});
|
|
24262
|
+
scope.on(nav, "keydown", (event) => {
|
|
24263
|
+
if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
|
|
24264
|
+
if (["PageUp", "PageDown", "ArrowUp", "ArrowDown", " "].includes(event.key)) cancelScroll();
|
|
24265
|
+
return;
|
|
24266
|
+
}
|
|
24267
|
+
const available = links().filter((link) => link.getAttribute("aria-disabled") !== "true");
|
|
24268
|
+
const index = available.indexOf(document.activeElement);
|
|
24269
|
+
if (index < 0 || !available.length) return;
|
|
24270
|
+
event.preventDefault();
|
|
24271
|
+
available[event.key === "Home" ? 0 : event.key === "End" ? available.length - 1 : (index + (event.key === "ArrowRight" ? 1 : -1) + available.length) % available.length]?.focus();
|
|
24272
|
+
});
|
|
24273
|
+
scope.on(window, "resize", queue, { passive: true });
|
|
24274
|
+
if (typeof ResizeObserver === "function") {
|
|
24275
|
+
const resize = scope.observe(new ResizeObserver(queue));
|
|
24276
|
+
resize.observe(nav);
|
|
24277
|
+
}
|
|
24278
|
+
bindScroller();
|
|
24279
|
+
render();
|
|
24280
|
+
update();
|
|
24281
|
+
return {
|
|
24282
|
+
select,
|
|
24283
|
+
update,
|
|
24284
|
+
get value() {
|
|
24285
|
+
return current3;
|
|
24286
|
+
},
|
|
24287
|
+
setOptions(next) {
|
|
24288
|
+
if (scope.disposed) return;
|
|
24289
|
+
const focusedId = root.contains(document.activeElement) ? document.activeElement?.closest("a[data-mk-section]")?.dataset.mkSection : void 0;
|
|
24290
|
+
opts = { ...opts, ...next };
|
|
24291
|
+
if ("scroller" in next) {
|
|
24292
|
+
cancelScroll();
|
|
24293
|
+
bindScroller();
|
|
24294
|
+
}
|
|
24295
|
+
render();
|
|
24296
|
+
if (focusedId) {
|
|
24297
|
+
const target = links().find((link) => link.dataset.mkSection === focusedId && link.getAttribute("aria-disabled") !== "true") ?? links().find((link) => link.getAttribute("aria-disabled") !== "true");
|
|
24298
|
+
if (target) target.focus();
|
|
24299
|
+
else {
|
|
24300
|
+
scope.attr(root, "tabindex", root.getAttribute("tabindex"));
|
|
24301
|
+
root.tabIndex = -1;
|
|
24302
|
+
root.focus();
|
|
24303
|
+
}
|
|
24304
|
+
}
|
|
24305
|
+
update();
|
|
24306
|
+
},
|
|
24307
|
+
destroy() {
|
|
24308
|
+
if (scope.disposed) return;
|
|
24309
|
+
cancelAnimationFrame(frame);
|
|
24310
|
+
cancelScroll();
|
|
24311
|
+
unbindScroller();
|
|
24312
|
+
animations.forEach((animation) => animation.kill());
|
|
24313
|
+
gsap.killTweensOf([...root.querySelectorAll("*")]);
|
|
24314
|
+
scope.dispose();
|
|
24315
|
+
root.replaceChildren(...original);
|
|
24316
|
+
}
|
|
24317
|
+
};
|
|
24318
|
+
}
|
|
24319
|
+
|
|
24320
|
+
// src/components/sticky-header/engine.ts
|
|
24321
|
+
function createStickyHeader(root, options = {}) {
|
|
24322
|
+
const surface = root?.querySelector("[data-mk-sticky-surface]");
|
|
24323
|
+
if (!root || !surface) {
|
|
24324
|
+
if (root) warnOnce("sticky-header: needs an authored [data-mk-sticky-surface]");
|
|
24325
|
+
return inert({ update() {
|
|
24326
|
+
}, setOptions() {
|
|
24327
|
+
}, compact: false, progress: 0 });
|
|
24328
|
+
}
|
|
24329
|
+
registerMotion();
|
|
24330
|
+
const scope = createScope();
|
|
24331
|
+
let opts = { ...options };
|
|
24332
|
+
let scroller = null;
|
|
24333
|
+
let unbind = () => {
|
|
24334
|
+
};
|
|
24335
|
+
let frame = 0;
|
|
24336
|
+
let progress = -1;
|
|
24337
|
+
let compact2 = false;
|
|
24338
|
+
const title = surface.querySelector("[data-mk-sticky-title]");
|
|
24339
|
+
const subtitle = surface.querySelector("[data-mk-sticky-subtitle]");
|
|
24340
|
+
const animations = /* @__PURE__ */ new Set();
|
|
24341
|
+
const track = (animation) => {
|
|
24342
|
+
if (animation) animations.add(animation);
|
|
24343
|
+
};
|
|
24344
|
+
for (const node of [root, surface, title, subtitle]) if (node) scope.attr(node, "style", node.getAttribute("style"));
|
|
24345
|
+
scope.attr(root, "class", `${root.className} mk-sticky-header`.trim());
|
|
24346
|
+
scope.attr(root, "data-mk-ready", "");
|
|
24347
|
+
const dimensions = () => {
|
|
24348
|
+
const large = Number.isFinite(opts.expandedHeight) ? Math.max(48, opts.expandedHeight) : 104;
|
|
24349
|
+
const small = Number.isFinite(opts.compactHeight) ? Math.max(40, Math.min(large, opts.compactHeight)) : Math.min(64, large);
|
|
24350
|
+
root.style.setProperty("--mk-sticky-expanded-height", `${large}px`);
|
|
24351
|
+
root.style.setProperty("--mk-sticky-top", `${Math.max(0, opts.top ?? 0)}px`);
|
|
24352
|
+
return { large, small };
|
|
24353
|
+
};
|
|
24354
|
+
const update = () => {
|
|
24355
|
+
frame = 0;
|
|
24356
|
+
if (scope.disposed) return;
|
|
24357
|
+
const { large, small } = dimensions();
|
|
24358
|
+
const position2 = scroller ? scroller.scrollTop : window.scrollY;
|
|
24359
|
+
const next = opts.disabled ? 0 : Math.max(0, Math.min(1, (position2 - Math.max(0, opts.threshold ?? 8)) / Math.max(1, opts.range ?? 96)));
|
|
24360
|
+
if (next === progress) return;
|
|
24361
|
+
const initial = progress < 0;
|
|
24362
|
+
progress = next;
|
|
24363
|
+
const isCompact = next >= 0.5;
|
|
24364
|
+
scope.attr(root, "data-mk-compact", String(isCompact));
|
|
24365
|
+
scope.attr(root, "data-mk-disabled", opts.disabled ? "" : null);
|
|
24366
|
+
const duration = reduced() || initial ? 0 : 0.22;
|
|
24367
|
+
track(gsap.to(surface, { height: large + (small - large) * next, borderRadius: 24 - 8 * next, paddingLeft: 24 - 8 * next, paddingRight: 24 - 8 * next, duration, ease: EASE.swatch, overwrite: "auto" }));
|
|
24368
|
+
if (title) track(gsap.to(title, { scale: 1 - 0.16 * next, y: -2 * next, transformOrigin: "left center", duration, ease: EASE.swatch, overwrite: "auto" }));
|
|
24369
|
+
if (subtitle) track(gsap.to(subtitle, { opacity: 1 - next, y: -8 * next, height: `${(1 - next) * 1.5}em`, filter: `blur(${next * 4}px)`, duration, ease: EASE.signature, overwrite: "auto" }));
|
|
24370
|
+
if (isCompact !== compact2) {
|
|
24371
|
+
compact2 = isCompact;
|
|
24372
|
+
opts.onChange?.(compact2);
|
|
24373
|
+
root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { compact: compact2, progress } }));
|
|
24374
|
+
}
|
|
24375
|
+
};
|
|
24376
|
+
const queue = () => {
|
|
24377
|
+
if (!frame) frame = requestAnimationFrame(update);
|
|
24378
|
+
};
|
|
24379
|
+
const bind = () => {
|
|
24380
|
+
unbind();
|
|
24381
|
+
scroller = typeof opts.scroller === "string" ? (() => {
|
|
24382
|
+
try {
|
|
24383
|
+
return root.closest(opts.scroller) ?? document.querySelector(opts.scroller);
|
|
24384
|
+
} catch {
|
|
24385
|
+
return null;
|
|
24386
|
+
}
|
|
24387
|
+
})() : opts.scroller ?? null;
|
|
24388
|
+
const target = scroller ?? window;
|
|
24389
|
+
target.addEventListener("scroll", queue, { passive: true });
|
|
24390
|
+
unbind = () => target.removeEventListener("scroll", queue);
|
|
24391
|
+
};
|
|
24392
|
+
scope.on(window, "resize", queue, { passive: true });
|
|
24393
|
+
scope.on(surface, "click", (event) => {
|
|
24394
|
+
const control = event.target.closest("button, a");
|
|
24395
|
+
if (control && !control.matches(':disabled, [aria-disabled="true"]')) {
|
|
24396
|
+
scope.attr(control, "style", control.getAttribute("style"));
|
|
24397
|
+
track(press(control));
|
|
24398
|
+
}
|
|
24399
|
+
});
|
|
24400
|
+
if (typeof ResizeObserver === "function") {
|
|
24401
|
+
const observer = scope.observe(new ResizeObserver(queue));
|
|
24402
|
+
observer.observe(root);
|
|
24403
|
+
}
|
|
24404
|
+
bind();
|
|
24405
|
+
update();
|
|
24406
|
+
return {
|
|
24407
|
+
update,
|
|
24408
|
+
get compact() {
|
|
24409
|
+
return compact2;
|
|
24410
|
+
},
|
|
24411
|
+
get progress() {
|
|
24412
|
+
return Math.max(0, progress);
|
|
24413
|
+
},
|
|
24414
|
+
setOptions(next) {
|
|
24415
|
+
if (scope.disposed) return;
|
|
24416
|
+
opts = { ...opts, ...next };
|
|
24417
|
+
if ("scroller" in next) bind();
|
|
24418
|
+
progress = -1;
|
|
24419
|
+
update();
|
|
24420
|
+
},
|
|
24421
|
+
destroy() {
|
|
24422
|
+
if (scope.disposed) return;
|
|
24423
|
+
cancelAnimationFrame(frame);
|
|
24424
|
+
unbind();
|
|
24425
|
+
animations.forEach((animation) => animation.kill());
|
|
24426
|
+
gsap.killTweensOf([surface, title, subtitle].filter((node) => !!node));
|
|
24427
|
+
scope.dispose();
|
|
24428
|
+
}
|
|
24429
|
+
};
|
|
24430
|
+
}
|
|
24431
|
+
|
|
24432
|
+
// src/components/handwriting-text/glyphs.ts
|
|
24433
|
+
var GLYPHS = {
|
|
24434
|
+
A: { width: 35, strokes: ["M2 43L26 5L27 42", "M10 30L31 28"] },
|
|
24435
|
+
B: { width: 34, strokes: ["M4 43L14 7", "M10 8C40 -2 35 25 11 25C40 14 37 45 4 43"] },
|
|
24436
|
+
C: { width: 34, strokes: ["M33 12C18 -8 -3 20 5 36Q12 52 31 35"] },
|
|
24437
|
+
D: { width: 35, strokes: ["M5 43L15 7", "M10 7C46 -3 40 48 4 43"] },
|
|
24438
|
+
E: { width: 30, strokes: ["M31 7L13 9L4 42L29 40", "M10 25L27 23"] },
|
|
24439
|
+
F: { width: 29, strokes: ["M4 43L14 8L32 7", "M10 25L27 24"] },
|
|
24440
|
+
G: { width: 36, strokes: ["M33 12C15 -8 -4 27 7 39Q21 51 31 26L19 28"] },
|
|
24441
|
+
H: { width: 36, strokes: ["M4 43L14 7", "M28 43L37 7", "M8 27L32 24"] },
|
|
24442
|
+
I: { width: 20, strokes: ["M17 8L8 42", "M9 9L25 7", "M1 43L17 41"] },
|
|
24443
|
+
J: { width: 28, strokes: ["M19 8L32 7L24 33Q17 54 3 38"] },
|
|
24444
|
+
K: { width: 34, strokes: ["M4 43L14 7", "M35 7L10 29L29 43"] },
|
|
24445
|
+
L: { width: 28, strokes: ["M14 7L4 42Q15 39 29 41"] },
|
|
24446
|
+
M: { width: 47, strokes: ["M3 43L15 7L22 35L44 7L35 43"] },
|
|
24447
|
+
N: { width: 37, strokes: ["M4 43L14 7L28 42L38 7"] },
|
|
24448
|
+
O: { width: 36, strokes: ["M25 7C5 1 -5 43 15 43C35 46 46 3 25 7Z"] },
|
|
24449
|
+
P: { width: 32, strokes: ["M4 43L14 8C40 -2 39 30 8 27"] },
|
|
24450
|
+
Q: { width: 37, strokes: ["M25 7C5 1 -5 43 15 43C35 46 46 3 25 7Z", "M19 33L33 48"] },
|
|
24451
|
+
R: { width: 34, strokes: ["M4 43L14 8C40 -2 39 30 8 27L29 44"] },
|
|
24452
|
+
S: { width: 31, strokes: ["M31 12C19 -5 -4 16 16 25C39 35 12 55 2 36"] },
|
|
24453
|
+
T: { width: 31, strokes: ["M3 10L34 7", "M20 9L11 43"] },
|
|
24454
|
+
U: { width: 36, strokes: ["M13 7L5 31C-1 52 27 48 31 29L37 7"] },
|
|
24455
|
+
V: { width: 35, strokes: ["M7 7L10 43L37 7"] },
|
|
24456
|
+
W: { width: 48, strokes: ["M7 7L9 43L27 15L28 43L50 7"] },
|
|
24457
|
+
X: { width: 34, strokes: ["M10 7L28 43", "M36 7L2 43"] },
|
|
24458
|
+
Y: { width: 34, strokes: ["M8 7L19 27L37 7", "M19 27L14 43"] },
|
|
24459
|
+
Z: { width: 32, strokes: ["M7 9L34 7L2 43L29 41"] },
|
|
24460
|
+
a: { width: 27, strokes: ["M23 23C9 12 2 40 13 42C21 44 26 21 23 22L20 39Q20 47 29 37"] },
|
|
24461
|
+
b: { width: 27, strokes: ["M4 42Q21 -6 13 3Q5 7 7 36C19 7 34 30 19 40Q11 46 7 38L29 36"] },
|
|
24462
|
+
c: { width: 25, strokes: ["M23 24C17 13 3 26 6 37Q10 49 27 35"] },
|
|
24463
|
+
d: { width: 28, strokes: ["M22 24C8 12 0 39 11 42Q20 46 29 4Q31 -1 27 3L21 38Q21 46 31 35"] },
|
|
24464
|
+
e: { width: 25, strokes: ["M5 33Q25 29 21 21Q17 13 8 27C-1 43 15 49 27 35"] },
|
|
24465
|
+
f: { width: 23, strokes: ["M2 57Q1 63 7 52L22 7Q24 -3 16 5Q7 17 11 27L24 24", "M3 27L20 26"] },
|
|
24466
|
+
g: { width: 28, strokes: ["M24 24C10 12 1 39 12 42Q20 45 24 23L18 54Q12 68 6 57Q3 48 31 36"] },
|
|
24467
|
+
h: { width: 28, strokes: ["M4 42Q24 -6 14 4Q8 10 5 41C17 9 26 18 21 34Q17 49 31 35"] },
|
|
24468
|
+
i: { width: 15, strokes: ["M9 24L5 36Q2 47 18 35", "M12 13L12.2 13.2"] },
|
|
24469
|
+
j: { width: 18, strokes: ["M13 24L6 53Q1 68 -4 56Q-6 48 21 35", "M16 13L16.2 13.2"] },
|
|
24470
|
+
k: { width: 27, strokes: ["M4 42Q24 -7 14 4Q8 10 5 41", "M25 22Q8 38 10 32Q17 27 19 37Q21 45 30 35"] },
|
|
24471
|
+
l: { width: 18, strokes: ["M3 32Q28 -4 15 3Q7 8 6 31Q3 49 21 35"] },
|
|
24472
|
+
m: { width: 40, strokes: ["M3 41L9 23L5 39Q18 11 20 25L17 39Q31 11 32 25L29 36Q28 46 43 35"] },
|
|
24473
|
+
n: { width: 28, strokes: ["M3 41L9 23L5 39Q21 10 23 25L20 36Q19 46 31 35"] },
|
|
24474
|
+
o: { width: 27, strokes: ["M22 22C7 14 0 39 12 42Q22 46 26 28Q26 18 19 24Q15 33 30 32"] },
|
|
24475
|
+
p: { width: 28, strokes: ["M-1 58L11 22L7 35Q19 12 25 25Q29 40 14 42L8 39L31 35"] },
|
|
24476
|
+
q: { width: 28, strokes: ["M23 24C10 12 1 39 12 42Q22 45 24 23L17 58Q15 62 19 53L31 36"] },
|
|
24477
|
+
r: { width: 23, strokes: ["M2 41L9 22Q8 31 16 24Q20 18 21 23Q21 27 17 28L26 35"] },
|
|
24478
|
+
s: { width: 24, strokes: ["M22 21Q18 15 10 24Q6 28 17 33Q25 39 14 43Q3 46 6 38L27 35"] },
|
|
24479
|
+
t: { width: 21, strokes: ["M16 10L7 35Q3 48 24 35", "M2 25L23 23"] },
|
|
24480
|
+
u: { width: 29, strokes: ["M9 23L4 35Q1 52 24 24L20 38Q21 45 32 35"] },
|
|
24481
|
+
v: { width: 26, strokes: ["M6 23Q-1 58 22 27Q25 20 21 23Q19 31 29 31"] },
|
|
24482
|
+
w: { width: 39, strokes: ["M7 23Q-1 56 19 27Q10 56 34 27Q37 20 33 23Q31 31 42 31"] },
|
|
24483
|
+
x: { width: 25, strokes: ["M7 24Q14 28 17 39Q20 45 28 35", "M24 23L3 42"] },
|
|
24484
|
+
y: { width: 28, strokes: ["M8 23L4 35Q2 50 24 24L16 54Q11 67 5 58Q0 50 31 36"] },
|
|
24485
|
+
z: { width: 25, strokes: ["M6 25Q16 19 24 24L5 41Q14 36 20 43Q25 51 10 59Q1 63 5 54L28 36"] },
|
|
24486
|
+
"0": { width: 29, strokes: ["M23 8C4 0 -2 42 13 43C28 44 34 7 23 8Z"] },
|
|
24487
|
+
"1": { width: 20, strokes: ["M5 17L17 8L9 42", "M2 43L18 43"] },
|
|
24488
|
+
"2": { width: 28, strokes: ["M4 17C10 -2 35 7 23 22L3 42Q14 38 28 42"] },
|
|
24489
|
+
"3": { width: 27, strokes: ["M6 11Q32 0 23 20L13 25Q34 17 24 36Q17 48 3 39"] },
|
|
24490
|
+
"4": { width: 29, strokes: ["M20 7L2 31L30 29", "M25 9L17 43"] },
|
|
24491
|
+
"5": { width: 28, strokes: ["M29 8L10 9L5 25Q27 14 25 32Q20 49 3 39"] },
|
|
24492
|
+
"6": { width: 28, strokes: ["M25 8C7 -1 -6 43 13 43C30 43 29 16 13 25L5 33"] },
|
|
24493
|
+
"7": { width: 27, strokes: ["M4 10L29 9L9 43", "M9 26L24 25"] },
|
|
24494
|
+
"8": { width: 28, strokes: ["M18 24C-6 12 23 -2 27 12Q28 21 10 28C-5 37 13 52 24 38Q33 27 18 24Z"] },
|
|
24495
|
+
"9": { width: 28, strokes: ["M24 20Q5 38 4 21C4 3 31 1 25 21L14 44"] },
|
|
24496
|
+
".": { width: 12, strokes: ["M6 41L6.4 41.4"] },
|
|
24497
|
+
",": { width: 12, strokes: ["M8 40L4 49"] },
|
|
24498
|
+
"!": { width: 13, strokes: ["M12 5L6 31", "M5 41L5.4 41.4"] },
|
|
24499
|
+
"?": { width: 25, strokes: ["M3 14Q10 0 23 10Q29 18 16 24L11 31", "M9 42L9.4 42.4"] },
|
|
24500
|
+
"-": { width: 23, strokes: ["M4 28L22 27"] },
|
|
24501
|
+
"'": { width: 11, strokes: ["M9 7L6 15"] }
|
|
24502
|
+
};
|
|
24503
|
+
|
|
24504
|
+
// src/components/handwriting-text/engine.ts
|
|
24505
|
+
var SVG12 = "http://www.w3.org/2000/svg";
|
|
24506
|
+
function createHandwritingText(root, options = {}) {
|
|
24507
|
+
if (!root) return inert({ setText() {
|
|
24508
|
+
}, replay() {
|
|
24509
|
+
}, text: "" });
|
|
24510
|
+
registerMotion();
|
|
24511
|
+
const scope = createScope();
|
|
24512
|
+
let text = options.text ?? root.textContent ?? "";
|
|
24513
|
+
const authored = [...root.childNodes];
|
|
24514
|
+
const svg2 = document.createElementNS(SVG12, "svg");
|
|
24515
|
+
svg2.setAttribute("aria-hidden", "true");
|
|
24516
|
+
svg2.dataset.mkHandwritingDrawing = "";
|
|
24517
|
+
root.replaceChildren(svg2);
|
|
24518
|
+
scope.add(() => {
|
|
24519
|
+
svg2.remove();
|
|
24520
|
+
root.append(...authored);
|
|
24521
|
+
});
|
|
24522
|
+
scope.attr(root, "data-mk-handwriting", "");
|
|
24523
|
+
scope.attr(root, "data-mk-ready", "");
|
|
24524
|
+
scope.attr(root, "role", "img");
|
|
24525
|
+
let strokes = [];
|
|
24526
|
+
let timeline = null;
|
|
24527
|
+
const duration = Number.isFinite(options.duration) ? Math.max(0.1, Math.min(30, options.duration)) : 2.4;
|
|
24528
|
+
const complete = () => {
|
|
24529
|
+
if (scope.disposed) return;
|
|
24530
|
+
options.onComplete?.();
|
|
24531
|
+
root.dispatchEvent(new CustomEvent("mk:complete", { bubbles: true }));
|
|
24532
|
+
};
|
|
24533
|
+
const replay = () => {
|
|
24534
|
+
if (scope.disposed) return;
|
|
24535
|
+
timeline?.kill();
|
|
24536
|
+
timeline = null;
|
|
24537
|
+
if (reduced() || !strokes.length) {
|
|
24538
|
+
gsap.set(strokes, { strokeDashoffset: 0 });
|
|
24539
|
+
return;
|
|
24540
|
+
}
|
|
24541
|
+
gsap.set(strokes, { strokeDashoffset: 1 });
|
|
24542
|
+
timeline = gsap.timeline({ onComplete: complete });
|
|
24543
|
+
const step = duration / strokes.length;
|
|
24544
|
+
for (const stroke of strokes) timeline.to(stroke, { strokeDashoffset: 0, duration: step, ease: EASE.wipe });
|
|
24545
|
+
};
|
|
24546
|
+
const draw = () => {
|
|
24547
|
+
timeline?.kill();
|
|
24548
|
+
timeline = null;
|
|
24549
|
+
strokes = [];
|
|
24550
|
+
svg2.replaceChildren();
|
|
24551
|
+
scope.attr(root, "aria-label", text);
|
|
24552
|
+
scope.attr(root, "data-mk-empty", text ? null : "");
|
|
24553
|
+
let x = 5;
|
|
24554
|
+
let y = 6;
|
|
24555
|
+
let width = 10;
|
|
24556
|
+
for (const char of text) {
|
|
24557
|
+
if (char === "\n") {
|
|
24558
|
+
width = Math.max(width, x + 5);
|
|
24559
|
+
x = 5;
|
|
24560
|
+
y += 64;
|
|
24561
|
+
continue;
|
|
24562
|
+
}
|
|
24563
|
+
if (/\s/u.test(char)) {
|
|
24564
|
+
x += 14;
|
|
24565
|
+
continue;
|
|
24566
|
+
}
|
|
24567
|
+
const normalized = char.normalize("NFD");
|
|
24568
|
+
const glyph = GLYPHS[normalized[0]];
|
|
24569
|
+
if (glyph) {
|
|
24570
|
+
const paths = [...glyph.strokes];
|
|
24571
|
+
if (normalized.includes("\u0301")) paths.push("M16 14L23 7");
|
|
24572
|
+
if (normalized.includes("\u0303")) paths.push("M11 14Q16 8 20 13Q24 17 28 10");
|
|
24573
|
+
if (normalized.includes("\u0308")) paths.push("M12 12L12.3 12.3M23 12L23.3 12.3");
|
|
24574
|
+
for (const d of paths) {
|
|
24575
|
+
const path = document.createElementNS(SVG12, "path");
|
|
24576
|
+
path.setAttribute("d", d);
|
|
24577
|
+
path.setAttribute("transform", `translate(${x} ${y})`);
|
|
24578
|
+
path.setAttribute("pathLength", "1");
|
|
24579
|
+
path.setAttribute("stroke-dasharray", "1");
|
|
24580
|
+
path.setAttribute("stroke-dashoffset", "0");
|
|
24581
|
+
svg2.append(path);
|
|
24582
|
+
strokes.push(path);
|
|
24583
|
+
}
|
|
24584
|
+
x += glyph.width;
|
|
24585
|
+
} else {
|
|
24586
|
+
const fallback = document.createElementNS(SVG12, "text");
|
|
24587
|
+
fallback.textContent = char;
|
|
24588
|
+
fallback.setAttribute("x", String(x));
|
|
24589
|
+
fallback.setAttribute("y", String(y + 42));
|
|
24590
|
+
fallback.setAttribute("data-mk-handwriting-fallback", "");
|
|
24591
|
+
svg2.append(fallback);
|
|
24592
|
+
x += 34;
|
|
24593
|
+
}
|
|
24594
|
+
}
|
|
24595
|
+
svg2.setAttribute("viewBox", `0 0 ${Math.max(width, x + 8)} ${y + 64}`);
|
|
24596
|
+
svg2.setAttribute("preserveAspectRatio", "xMinYMid meet");
|
|
24597
|
+
};
|
|
24598
|
+
draw();
|
|
24599
|
+
if (options.autoplay !== false) replay();
|
|
24600
|
+
scope.add(() => {
|
|
24601
|
+
timeline?.kill();
|
|
24602
|
+
gsap.killTweensOf(strokes);
|
|
24603
|
+
});
|
|
24604
|
+
return {
|
|
24605
|
+
replay,
|
|
24606
|
+
setText(next, animate = true) {
|
|
24607
|
+
if (scope.disposed || next === text) return;
|
|
24608
|
+
text = String(next);
|
|
24609
|
+
draw();
|
|
24610
|
+
if (animate) replay();
|
|
24611
|
+
},
|
|
24612
|
+
get text() {
|
|
24613
|
+
return text;
|
|
24614
|
+
},
|
|
24615
|
+
destroy: () => scope.dispose()
|
|
24616
|
+
};
|
|
24617
|
+
}
|
|
24618
|
+
|
|
24619
|
+
// src/components/particle-button/engine.ts
|
|
24620
|
+
function createParticleButton(root, options = {}) {
|
|
24621
|
+
if (!root) return inert({ burst() {
|
|
24622
|
+
} });
|
|
24623
|
+
registerMotion();
|
|
24624
|
+
const scope = createScope();
|
|
24625
|
+
let button2 = root.matches("button") ? root : root.querySelector("button");
|
|
24626
|
+
if (!button2) {
|
|
24627
|
+
button2 = document.createElement("button");
|
|
24628
|
+
root.append(button2);
|
|
24629
|
+
const made = button2;
|
|
24630
|
+
scope.add(() => made.remove());
|
|
24631
|
+
}
|
|
24632
|
+
const control = button2;
|
|
24633
|
+
if (!control.textContent?.trim() && !control.querySelector("[aria-label], svg, img")) {
|
|
24634
|
+
const name = document.createElement("span");
|
|
24635
|
+
name.textContent = options.label ?? "Celebrar";
|
|
24636
|
+
control.append(name);
|
|
24637
|
+
scope.add(() => name.remove());
|
|
24638
|
+
}
|
|
24639
|
+
const originalStyle = control.getAttribute("style");
|
|
24640
|
+
const originalTransform = control.style.transform;
|
|
24641
|
+
scope.add(() => {
|
|
24642
|
+
if (originalStyle === null) control.removeAttribute("style");
|
|
24643
|
+
else control.setAttribute("style", originalStyle);
|
|
24644
|
+
});
|
|
24645
|
+
scope.attr(control, "type", control.getAttribute("type") ?? "button");
|
|
24646
|
+
scope.attr(control, "data-mk-particle-button", "");
|
|
24647
|
+
scope.attr(root, "data-mk-ready", "");
|
|
24648
|
+
const count = Number.isFinite(options.count) ? Math.min(16, Math.max(3, Math.round(options.count))) : 9;
|
|
24649
|
+
const distance = Number.isFinite(options.distance) ? Math.min(100, Math.max(12, options.distance)) : 52;
|
|
24650
|
+
let particles = null;
|
|
24651
|
+
let pressing = null;
|
|
24652
|
+
const fire = () => {
|
|
24653
|
+
if (scope.disposed || control.disabled || control.getAttribute("aria-disabled") === "true") return;
|
|
24654
|
+
particles?.kill();
|
|
24655
|
+
particles = reduced() ? null : burst(control, { count, distance, ring: false, size: 5, colors: ["var(--mk-text)", "var(--mk-accent)"] });
|
|
24656
|
+
};
|
|
24657
|
+
scope.on(control, "click", (event) => {
|
|
24658
|
+
if (control.disabled || control.getAttribute("aria-disabled") === "true") {
|
|
24659
|
+
event.preventDefault();
|
|
24660
|
+
return;
|
|
24661
|
+
}
|
|
24662
|
+
pressing?.kill();
|
|
24663
|
+
pressing = press(control);
|
|
24664
|
+
pressing?.eventCallback("onComplete", () => {
|
|
24665
|
+
gsap.set(control, { clearProps: "transform,scale" });
|
|
24666
|
+
control.style.transform = originalTransform;
|
|
24667
|
+
if (!control.getAttribute("style")) control.removeAttribute("style");
|
|
24668
|
+
});
|
|
24669
|
+
fire();
|
|
24670
|
+
options.onAction?.();
|
|
24671
|
+
root.dispatchEvent(new CustomEvent("mk:action", { bubbles: true }));
|
|
24672
|
+
});
|
|
24673
|
+
scope.add(() => {
|
|
24674
|
+
particles?.kill();
|
|
24675
|
+
pressing?.kill();
|
|
24676
|
+
});
|
|
24677
|
+
return { burst: fire, destroy: () => scope.dispose() };
|
|
24678
|
+
}
|
|
24679
|
+
|
|
24680
|
+
// src/components/magnetize-button/engine.ts
|
|
24681
|
+
function createMagnetizeButton(root, options = {}) {
|
|
24682
|
+
if (!root) return inert({ attract() {
|
|
24683
|
+
}, release() {
|
|
24684
|
+
}, attracted: false });
|
|
24685
|
+
registerMotion();
|
|
24686
|
+
const scope = createScope();
|
|
24687
|
+
let button2 = root.matches("button") ? root : root.querySelector("button");
|
|
24688
|
+
if (!button2) {
|
|
24689
|
+
button2 = document.createElement("button");
|
|
24690
|
+
root.append(button2);
|
|
24691
|
+
const made = button2;
|
|
24692
|
+
scope.add(() => made.remove());
|
|
24693
|
+
}
|
|
24694
|
+
const control = button2;
|
|
24695
|
+
if (!control.textContent?.trim() && !control.querySelector("[aria-label], svg, img")) {
|
|
24696
|
+
const label = document.createElement("span");
|
|
24697
|
+
label.textContent = options.label ?? "Reunir ideas";
|
|
24698
|
+
control.append(label);
|
|
24699
|
+
scope.add(() => label.remove());
|
|
24700
|
+
}
|
|
24701
|
+
const originalStyle = control.getAttribute("style");
|
|
24702
|
+
const originalTransform = control.style.transform;
|
|
24703
|
+
scope.add(() => {
|
|
24704
|
+
if (originalStyle === null) control.removeAttribute("style");
|
|
24705
|
+
else control.setAttribute("style", originalStyle);
|
|
24706
|
+
});
|
|
24707
|
+
scope.attr(control, "type", control.getAttribute("type") ?? "button");
|
|
24708
|
+
scope.attr(control, "data-mk-magnetize-button", "");
|
|
24709
|
+
scope.attr(root, "data-mk-ready", "");
|
|
24710
|
+
const layer = document.createElement("span");
|
|
24711
|
+
layer.dataset.mkMagnetParticles = "";
|
|
24712
|
+
layer.setAttribute("aria-hidden", "true");
|
|
24713
|
+
control.append(layer);
|
|
24714
|
+
scope.add(() => layer.remove());
|
|
24715
|
+
const count = Number.isFinite(options.count) ? Math.min(24, Math.max(4, Math.round(options.count))) : 14;
|
|
24716
|
+
const reach = Number.isFinite(options.reach) ? Math.min(90, Math.max(16, options.reach)) : 42;
|
|
24717
|
+
const dots = [];
|
|
24718
|
+
for (let i = 0; i < count; i++) {
|
|
24719
|
+
const dot = document.createElement("i");
|
|
24720
|
+
layer.append(dot);
|
|
24721
|
+
dots.push(dot);
|
|
24722
|
+
}
|
|
24723
|
+
let hovered = false;
|
|
24724
|
+
let focused = false;
|
|
24725
|
+
let attracted = false;
|
|
24726
|
+
let tween = null;
|
|
24727
|
+
let pressing = null;
|
|
24728
|
+
const disabled = () => control.disabled || control.getAttribute("aria-disabled") === "true";
|
|
24729
|
+
const positions = (near) => {
|
|
24730
|
+
const w = control.offsetWidth || 160;
|
|
24731
|
+
const h = control.offsetHeight || 48;
|
|
24732
|
+
return dots.map((_, i) => {
|
|
24733
|
+
const angle2 = i / count * Math.PI * 2 - Math.PI / 2;
|
|
24734
|
+
const c = Math.cos(angle2);
|
|
24735
|
+
const s = Math.sin(angle2);
|
|
24736
|
+
const boundary = Math.min((w / 2 + 4) / Math.max(1e-3, Math.abs(c)), (h / 2 + 4) / Math.max(1e-3, Math.abs(s)));
|
|
24737
|
+
const radius = boundary + (near ? 0 : reach * (0.72 + i % 3 * 0.14));
|
|
24738
|
+
return { x: c * radius, y: s * radius, opacity: near ? 0.88 : 0.25, scale: near ? 1 : 0.6 };
|
|
24739
|
+
});
|
|
24740
|
+
};
|
|
24741
|
+
const paint = (near, animate) => {
|
|
24742
|
+
tween?.kill();
|
|
24743
|
+
tween = null;
|
|
24744
|
+
layer.hidden = reduced() || disabled();
|
|
24745
|
+
if (layer.hidden) {
|
|
24746
|
+
attracted = false;
|
|
24747
|
+
scope.attr(control, "data-mk-attracted", null);
|
|
24748
|
+
return;
|
|
24749
|
+
}
|
|
24750
|
+
attracted = near;
|
|
24751
|
+
scope.attr(control, "data-mk-attracted", near ? "" : null);
|
|
24752
|
+
const targets = positions(near);
|
|
24753
|
+
if (!animate) {
|
|
24754
|
+
dots.forEach((dot, i) => gsap.set(dot, targets[i]));
|
|
24755
|
+
return;
|
|
24756
|
+
}
|
|
24757
|
+
tween = gsap.timeline();
|
|
24758
|
+
dots.forEach((dot, i) => tween.to(dot, { ...targets[i], duration: near ? 0.62 : 0.48, ease: near ? EASE.swatch : EASE.signature }, i * 8e-3));
|
|
24759
|
+
};
|
|
24760
|
+
const sync = () => paint(hovered || focused, true);
|
|
24761
|
+
scope.on(control, "pointerenter", () => {
|
|
24762
|
+
hovered = true;
|
|
24763
|
+
sync();
|
|
24764
|
+
});
|
|
24765
|
+
scope.on(control, "pointerleave", () => {
|
|
24766
|
+
hovered = false;
|
|
24767
|
+
sync();
|
|
24768
|
+
});
|
|
24769
|
+
scope.on(control, "focus", () => {
|
|
24770
|
+
focused = true;
|
|
24771
|
+
sync();
|
|
24772
|
+
});
|
|
24773
|
+
scope.on(control, "blur", () => {
|
|
24774
|
+
focused = false;
|
|
24775
|
+
sync();
|
|
24776
|
+
});
|
|
24777
|
+
scope.on(control, "click", (event) => {
|
|
24778
|
+
if (disabled()) {
|
|
24779
|
+
event.preventDefault();
|
|
24780
|
+
return;
|
|
24781
|
+
}
|
|
24782
|
+
pressing?.kill();
|
|
24783
|
+
pressing = press(control);
|
|
24784
|
+
pressing?.eventCallback("onComplete", () => {
|
|
24785
|
+
gsap.set(control, { clearProps: "transform,scale" });
|
|
24786
|
+
control.style.transform = originalTransform;
|
|
24787
|
+
if (!control.getAttribute("style")) control.removeAttribute("style");
|
|
24788
|
+
});
|
|
24789
|
+
options.onAction?.();
|
|
24790
|
+
root.dispatchEvent(new CustomEvent("mk:action", { bubbles: true }));
|
|
24791
|
+
});
|
|
24792
|
+
if (typeof ResizeObserver !== "undefined") scope.observe(new ResizeObserver(() => paint(attracted, false))).observe(control);
|
|
24793
|
+
if (typeof MutationObserver !== "undefined") scope.observe(new MutationObserver(() => paint(hovered || focused, false))).observe(control, { attributes: true, attributeFilter: ["disabled", "aria-disabled"] });
|
|
24794
|
+
if (typeof matchMedia === "function") {
|
|
24795
|
+
const media = matchMedia("(prefers-reduced-motion: reduce)");
|
|
24796
|
+
scope.on(media, "change", () => paint(hovered || focused, false));
|
|
24797
|
+
}
|
|
24798
|
+
paint(false, false);
|
|
24799
|
+
scope.add(() => {
|
|
24800
|
+
tween?.kill();
|
|
24801
|
+
pressing?.kill();
|
|
24802
|
+
gsap.killTweensOf(dots);
|
|
24803
|
+
});
|
|
24804
|
+
return { attract: () => {
|
|
24805
|
+
if (!scope.disposed) paint(true, true);
|
|
24806
|
+
}, release: () => {
|
|
24807
|
+
if (!scope.disposed) paint(false, true);
|
|
24808
|
+
}, get attracted() {
|
|
24809
|
+
return attracted;
|
|
24810
|
+
}, destroy: () => scope.dispose() };
|
|
24811
|
+
}
|
|
24812
|
+
|
|
24813
|
+
// src/components/badge-button/engine.ts
|
|
24814
|
+
var normalize2 = (value) => Number.isFinite(value) ? Math.max(0, Math.min(Number.MAX_SAFE_INTEGER, Math.round(value))) : 0;
|
|
24815
|
+
var sequence29 = 0;
|
|
24816
|
+
function createBadgeButton(root, options = {}) {
|
|
24817
|
+
if (!root) return inert({ setCount() {
|
|
24818
|
+
}, count: 0 });
|
|
24819
|
+
registerMotion();
|
|
24820
|
+
const scope = createScope();
|
|
24821
|
+
let button2 = root.matches("button") ? root : root.querySelector("button");
|
|
24822
|
+
if (!button2) {
|
|
24823
|
+
button2 = document.createElement("button");
|
|
24824
|
+
root.append(button2);
|
|
24825
|
+
const made = button2;
|
|
24826
|
+
scope.add(() => made.remove());
|
|
24827
|
+
}
|
|
24828
|
+
const control = button2;
|
|
24829
|
+
if (!control.textContent?.trim() && !control.querySelector("[aria-label], svg, img")) {
|
|
24830
|
+
const label = document.createElement("span");
|
|
24831
|
+
label.textContent = options.label ?? "Guardar";
|
|
24832
|
+
control.append(label);
|
|
24833
|
+
scope.add(() => label.remove());
|
|
24834
|
+
}
|
|
24835
|
+
const originalStyle = control.getAttribute("style");
|
|
24836
|
+
const originalTransform = control.style.transform;
|
|
24837
|
+
scope.add(() => {
|
|
24838
|
+
if (originalStyle === null) control.removeAttribute("style");
|
|
24839
|
+
else control.setAttribute("style", originalStyle);
|
|
24840
|
+
});
|
|
24841
|
+
const badge = document.createElement("span");
|
|
24842
|
+
badge.dataset.mkBadgeCount = "";
|
|
24843
|
+
badge.setAttribute("aria-hidden", "true");
|
|
24844
|
+
control.append(badge);
|
|
24845
|
+
scope.add(() => badge.remove());
|
|
24846
|
+
const spoken = document.createElement("span");
|
|
24847
|
+
spoken.className = "mk-sr-only";
|
|
24848
|
+
control.append(spoken);
|
|
24849
|
+
scope.add(() => spoken.remove());
|
|
24850
|
+
const authoredLabel = control.getAttribute("aria-label");
|
|
24851
|
+
const labelledBy = control.getAttribute("aria-labelledby");
|
|
24852
|
+
if (labelledBy?.trim()) {
|
|
24853
|
+
spoken.id = `mk-badge-quantity-${++sequence29}`;
|
|
24854
|
+
scope.attr(control, "aria-labelledby", `${labelledBy} ${spoken.id}`);
|
|
24855
|
+
}
|
|
24856
|
+
scope.attr(control, "type", control.getAttribute("type") ?? "button");
|
|
24857
|
+
scope.attr(control, "data-mk-badge-button", "");
|
|
24858
|
+
scope.attr(root, "data-mk-ready", "");
|
|
24859
|
+
let count = normalize2(options.count ?? 0);
|
|
24860
|
+
const max = Math.max(1, normalize2(options.max ?? 99));
|
|
24861
|
+
const step = Number.isFinite(options.step) ? Math.round(options.step) : 1;
|
|
24862
|
+
let rolling2 = null;
|
|
24863
|
+
let bump = null;
|
|
24864
|
+
let pressing = null;
|
|
24865
|
+
const format = () => count > max ? `${max}+` : String(count);
|
|
24866
|
+
const announce = () => {
|
|
24867
|
+
spoken.textContent = ` (${count})`;
|
|
24868
|
+
if (!labelledBy?.trim() && authoredLabel?.trim()) scope.attr(control, "aria-label", `${authoredLabel} (${count})`);
|
|
24869
|
+
};
|
|
24870
|
+
const paint = () => {
|
|
24871
|
+
badge.hidden = options.hideZero !== false && count === 0;
|
|
24872
|
+
badge.textContent = format();
|
|
24873
|
+
announce();
|
|
24874
|
+
};
|
|
24875
|
+
const setCount = (next, notify = false) => {
|
|
24876
|
+
if (scope.disposed || !Number.isFinite(next)) return;
|
|
24877
|
+
const previous = count;
|
|
24878
|
+
count = normalize2(next);
|
|
24879
|
+
if (count === previous) return;
|
|
24880
|
+
const wasHidden = badge.hidden;
|
|
24881
|
+
badge.hidden = options.hideZero !== false && count === 0;
|
|
24882
|
+
announce();
|
|
24883
|
+
rolling2?.kill();
|
|
24884
|
+
bump?.kill();
|
|
24885
|
+
if (reduced() || badge.hidden) paint();
|
|
24886
|
+
else {
|
|
24887
|
+
rolling2 = rollDigits(badge, format(), count >= previous ? 1 : -1, 0.34);
|
|
24888
|
+
bump = gsap.fromTo(badge, { scale: wasHidden ? 0.35 : 0.8, y: wasHidden ? 7 : 0 }, { scale: 1, y: 0, duration: 0.5, ease: wasHidden ? EASE.pop : EASE.swatch });
|
|
24889
|
+
}
|
|
24890
|
+
if (notify) {
|
|
24891
|
+
options.onChange?.(count);
|
|
24892
|
+
root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { count } }));
|
|
24893
|
+
}
|
|
24894
|
+
};
|
|
24895
|
+
scope.on(control, "click", (event) => {
|
|
24896
|
+
if (control.disabled || control.getAttribute("aria-disabled") === "true") {
|
|
24897
|
+
event.preventDefault();
|
|
24898
|
+
return;
|
|
24899
|
+
}
|
|
24900
|
+
pressing?.kill();
|
|
24901
|
+
pressing = press(control);
|
|
24902
|
+
pressing?.eventCallback("onComplete", () => {
|
|
24903
|
+
gsap.set(control, { clearProps: "transform,scale" });
|
|
24904
|
+
control.style.transform = originalTransform;
|
|
24905
|
+
if (!control.getAttribute("style")) control.removeAttribute("style");
|
|
24906
|
+
});
|
|
24907
|
+
setCount(count + step, true);
|
|
24908
|
+
});
|
|
24909
|
+
paint();
|
|
24910
|
+
scope.add(() => {
|
|
24911
|
+
rolling2?.kill();
|
|
24912
|
+
bump?.kill();
|
|
24913
|
+
pressing?.kill();
|
|
24914
|
+
gsap.killTweensOf(badge);
|
|
24915
|
+
});
|
|
24916
|
+
return { setCount, get count() {
|
|
24917
|
+
return count;
|
|
24918
|
+
}, destroy: () => scope.dispose() };
|
|
24919
|
+
}
|
|
24920
|
+
|
|
24921
|
+
// src/components/morphing-page-dots/engine.ts
|
|
24922
|
+
function createMorphingPageDots(root, options = {}) {
|
|
24923
|
+
if (!root) return inert({ setValue() {
|
|
24924
|
+
}, value: 0 });
|
|
24925
|
+
registerMotion();
|
|
24926
|
+
const scope = createScope();
|
|
24927
|
+
const count = Number.isFinite(options.count) ? Math.min(20, Math.max(1, Math.round(options.count))) : 5;
|
|
24928
|
+
const normalize3 = (index) => Math.min(count - 1, Math.max(0, Math.round(index)));
|
|
24929
|
+
let value = normalize3(Number.isFinite(options.value) ? options.value : 0);
|
|
24930
|
+
const authored = [...root.childNodes];
|
|
24931
|
+
const rail = document.createElement("span");
|
|
24932
|
+
rail.dataset.mkPageRail = "";
|
|
24933
|
+
const blob = document.createElement("i");
|
|
24934
|
+
blob.dataset.mkPageBlob = "";
|
|
24935
|
+
blob.setAttribute("aria-hidden", "true");
|
|
24936
|
+
rail.append(blob);
|
|
24937
|
+
const buttons = [];
|
|
24938
|
+
for (let i = 0; i < count; i++) {
|
|
24939
|
+
const button2 = document.createElement("button");
|
|
24940
|
+
button2.type = "button";
|
|
24941
|
+
button2.dataset.mkPageDot = "";
|
|
24942
|
+
button2.setAttribute("aria-label", options.labels?.[i] ?? `P\xE1gina ${i + 1} de ${count}`);
|
|
24943
|
+
if (options.pageIds?.[i]) button2.setAttribute("aria-controls", options.pageIds[i]);
|
|
24944
|
+
button2.disabled = Boolean(options.disabled);
|
|
24945
|
+
const dot = document.createElement("i");
|
|
24946
|
+
dot.setAttribute("aria-hidden", "true");
|
|
24947
|
+
button2.append(dot);
|
|
24948
|
+
rail.append(button2);
|
|
24949
|
+
buttons.push(button2);
|
|
24950
|
+
}
|
|
24951
|
+
root.replaceChildren(rail);
|
|
24952
|
+
scope.add(() => {
|
|
24953
|
+
rail.remove();
|
|
24954
|
+
root.append(...authored);
|
|
24955
|
+
});
|
|
24956
|
+
scope.attr(root, "role", "group");
|
|
24957
|
+
scope.attr(root, "aria-label", options.label ?? "P\xE1ginas");
|
|
24958
|
+
scope.attr(root, "data-mk-morphing-page-dots", "");
|
|
24959
|
+
scope.attr(root, "data-mk-ready", "");
|
|
24960
|
+
let moving = null;
|
|
24961
|
+
let pressing = null;
|
|
24962
|
+
const at = (index) => {
|
|
24963
|
+
const button2 = buttons[index];
|
|
24964
|
+
const size = button2.offsetWidth || 44;
|
|
24965
|
+
return (button2.offsetLeft || index * size) + size / 2 - 12;
|
|
24966
|
+
};
|
|
24967
|
+
const place3 = () => {
|
|
24968
|
+
moving?.kill();
|
|
24969
|
+
moving = null;
|
|
24970
|
+
gsap.set(blob, { left: at(value), width: 24, scaleY: 1 });
|
|
24971
|
+
};
|
|
24972
|
+
const paint = () => buttons.forEach((button2, i) => {
|
|
24973
|
+
button2.setAttribute("aria-current", i === value ? "page" : "false");
|
|
24974
|
+
button2.tabIndex = i === value ? 0 : -1;
|
|
24975
|
+
});
|
|
24976
|
+
const setValue = (index, notify = false) => {
|
|
24977
|
+
if (scope.disposed || !Number.isFinite(index)) return;
|
|
24978
|
+
const next = normalize3(index);
|
|
24979
|
+
if (value === next) return;
|
|
24980
|
+
const start = at(value);
|
|
24981
|
+
const end = at(next);
|
|
24982
|
+
value = next;
|
|
24983
|
+
paint();
|
|
24984
|
+
moving?.kill();
|
|
24985
|
+
if (reduced()) place3();
|
|
24986
|
+
else {
|
|
24987
|
+
const current3 = Number(gsap.getProperty(blob, "left")) || start;
|
|
24988
|
+
moving = gsap.timeline().to(blob, { left: Math.min(current3, end), width: Math.abs(end - current3) + 24, scaleY: 0.68, duration: 0.18, ease: EASE.wipe }).to(blob, { left: end, width: 24, scaleY: 1, duration: 0.48, ease: EASE.swatch }, 0.13);
|
|
24989
|
+
}
|
|
24990
|
+
if (notify) {
|
|
24991
|
+
options.onChange?.(value);
|
|
24992
|
+
root.dispatchEvent(new CustomEvent("mk:change", { bubbles: true, detail: { value } }));
|
|
24993
|
+
}
|
|
24994
|
+
};
|
|
24995
|
+
buttons.forEach((button2, i) => {
|
|
24996
|
+
scope.on(button2, "click", () => {
|
|
24997
|
+
if (button2.disabled) return;
|
|
24998
|
+
pressing?.kill();
|
|
24999
|
+
pressing = press(button2);
|
|
25000
|
+
setValue(i, true);
|
|
25001
|
+
});
|
|
25002
|
+
scope.on(button2, "keydown", (event) => {
|
|
25003
|
+
if (button2.disabled) return;
|
|
25004
|
+
const key2 = event.key;
|
|
25005
|
+
if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(key2)) return;
|
|
25006
|
+
event.preventDefault();
|
|
25007
|
+
const rtl = getComputedStyle(root).direction === "rtl";
|
|
25008
|
+
let next = key2 === "Home" ? 0 : key2 === "End" ? count - 1 : (value + (key2 === "ArrowRight" !== rtl ? 1 : -1) + count) % count;
|
|
25009
|
+
setValue(next, true);
|
|
25010
|
+
buttons[next].focus();
|
|
25011
|
+
});
|
|
25012
|
+
});
|
|
25013
|
+
if (typeof ResizeObserver !== "undefined") scope.observe(new ResizeObserver(place3)).observe(rail);
|
|
25014
|
+
paint();
|
|
25015
|
+
place3();
|
|
25016
|
+
scope.add(() => {
|
|
25017
|
+
moving?.kill();
|
|
25018
|
+
pressing?.kill();
|
|
25019
|
+
});
|
|
25020
|
+
return { setValue, get value() {
|
|
25021
|
+
return value;
|
|
25022
|
+
}, destroy: () => scope.dispose() };
|
|
25023
|
+
}
|
|
25024
|
+
|
|
25025
|
+
// src/components/not-found/engine.ts
|
|
25026
|
+
var ILLUSTRATION = '<svg viewBox="0 0 320 140" fill="none" aria-hidden="true"><path data-mk-lost-track d="M20 115H100Q118 115 118 95V72Q118 53 138 53H185Q205 53 205 73V95Q205 115 224 115H300"/><g data-mk-lost-four><path d="M72 23L35 79H84M77 23V107"/><path d="M263 23L226 79H275M268 23V107"/></g><g data-mk-lost-portal><rect x="124" y="18" width="72" height="96" rx="32"/><ellipse cx="160" cy="66" rx="17" ry="29"/><path d="M145 66h30M160 51v30"/></g><path data-mk-lost-star d="M211 13v12m-6-6h12M105 118v8m-4-4h8"/></svg>';
|
|
25027
|
+
function createNotFound(root, options = {}) {
|
|
25028
|
+
if (!root) return inert({ replay() {
|
|
25029
|
+
} });
|
|
25030
|
+
registerMotion();
|
|
25031
|
+
const scope = createScope();
|
|
25032
|
+
const authored = [...root.childNodes];
|
|
25033
|
+
const content = document.createElement("div");
|
|
25034
|
+
content.dataset.mkNotFoundContent = "";
|
|
25035
|
+
const art = document.createElement("div");
|
|
25036
|
+
art.dataset.mkNotFoundArt = "";
|
|
25037
|
+
art.innerHTML = ILLUSTRATION;
|
|
25038
|
+
const eyebrow = document.createElement("p");
|
|
25039
|
+
eyebrow.dataset.mkNotFoundCode = "";
|
|
25040
|
+
eyebrow.textContent = `404 \xB7 ${options.brand ?? "Motion Kit"}`;
|
|
25041
|
+
const heading = document.createElement("h2");
|
|
25042
|
+
heading.textContent = options.title ?? "Este camino se perdi\xF3.";
|
|
25043
|
+
const description = document.createElement("p");
|
|
25044
|
+
description.dataset.mkNotFoundDescription = "";
|
|
25045
|
+
description.textContent = options.description ?? "La p\xE1gina que buscas no est\xE1 aqu\xED. Volvamos a un lugar conocido.";
|
|
25046
|
+
const actions = document.createElement("div");
|
|
25047
|
+
actions.dataset.mkNotFoundActions = "";
|
|
25048
|
+
const home = document.createElement("a");
|
|
25049
|
+
home.href = options.homeHref ?? "/";
|
|
25050
|
+
home.textContent = options.homeLabel ?? "Volver al inicio";
|
|
25051
|
+
actions.append(home);
|
|
25052
|
+
const back = document.createElement("button");
|
|
25053
|
+
back.type = "button";
|
|
25054
|
+
back.textContent = options.backLabel ?? "Ir atr\xE1s";
|
|
25055
|
+
back.disabled = !options.onBack && history.length <= 1;
|
|
25056
|
+
if (options.showBack !== false) actions.append(back);
|
|
25057
|
+
content.append(art, eyebrow, heading, description, actions);
|
|
25058
|
+
root.replaceChildren(content);
|
|
25059
|
+
scope.add(() => {
|
|
25060
|
+
content.remove();
|
|
25061
|
+
root.append(...authored);
|
|
25062
|
+
});
|
|
25063
|
+
scope.attr(root, "data-mk-not-found", "");
|
|
25064
|
+
scope.attr(root, "data-mk-ready", "");
|
|
25065
|
+
let entering = null;
|
|
25066
|
+
let drawing = null;
|
|
25067
|
+
let pressing = null;
|
|
25068
|
+
const portal = art.querySelector("[data-mk-lost-portal]");
|
|
25069
|
+
const replay = () => {
|
|
25070
|
+
if (scope.disposed) return;
|
|
25071
|
+
entering?.kill();
|
|
25072
|
+
drawing?.kill();
|
|
25073
|
+
if (reduced()) {
|
|
25074
|
+
gsap.set([art, eyebrow, heading, description, actions], { clearProps: "all" });
|
|
25075
|
+
return;
|
|
25076
|
+
}
|
|
25077
|
+
entering = blurIn([art, eyebrow, heading, description, actions], { from: "soft", duration: 0.5, stagger: 0.055 });
|
|
25078
|
+
drawing = gsap.fromTo(portal, { rotation: -12, scale: 0.82, transformOrigin: "50% 50%" }, { rotation: 0, scale: 1, duration: 0.8, ease: EASE.swatch });
|
|
25079
|
+
};
|
|
25080
|
+
scope.on(back, "click", () => {
|
|
25081
|
+
if (!back.disabled) {
|
|
25082
|
+
pressing?.kill();
|
|
25083
|
+
pressing = press(back);
|
|
25084
|
+
if (options.onBack) options.onBack();
|
|
25085
|
+
else history.back();
|
|
25086
|
+
}
|
|
25087
|
+
});
|
|
25088
|
+
scope.on(home, "click", () => {
|
|
25089
|
+
pressing?.kill();
|
|
25090
|
+
pressing = press(home);
|
|
25091
|
+
});
|
|
25092
|
+
replay();
|
|
25093
|
+
scope.add(() => {
|
|
25094
|
+
entering?.kill();
|
|
25095
|
+
drawing?.kill();
|
|
25096
|
+
pressing?.kill();
|
|
25097
|
+
});
|
|
25098
|
+
return { replay, destroy: () => scope.dispose() };
|
|
25099
|
+
}
|
|
25100
|
+
|
|
22594
25101
|
export {
|
|
22595
25102
|
PATHS,
|
|
22596
25103
|
springPath,
|
|
@@ -22816,6 +25323,21 @@ export {
|
|
|
22816
25323
|
createWaveformPlayer,
|
|
22817
25324
|
createVoiceMessageBubble,
|
|
22818
25325
|
createDrilldownMenu,
|
|
22819
|
-
createWheelPicker
|
|
25326
|
+
createWheelPicker,
|
|
25327
|
+
createStepper,
|
|
25328
|
+
createRadioGroup,
|
|
25329
|
+
createEqualizerSlider,
|
|
25330
|
+
createTemperatureSlider,
|
|
25331
|
+
createRatingScale,
|
|
25332
|
+
createNotificationStack,
|
|
25333
|
+
createBentoGrid,
|
|
25334
|
+
createScrollPreviewDock,
|
|
25335
|
+
createStickyHeader,
|
|
25336
|
+
createHandwritingText,
|
|
25337
|
+
createParticleButton,
|
|
25338
|
+
createMagnetizeButton,
|
|
25339
|
+
createBadgeButton,
|
|
25340
|
+
createMorphingPageDots,
|
|
25341
|
+
createNotFound
|
|
22820
25342
|
};
|
|
22821
|
-
//# sourceMappingURL=chunk-
|
|
25343
|
+
//# sourceMappingURL=chunk-Q7IW4FV3.js.map
|