@vanduo-oss/framework 1.3.5 → 1.3.7
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 +5 -4
- package/css/components/cards.css +11 -1
- package/css/components/datepicker.css +10 -1
- package/css/components/expanding-cards.css +215 -0
- package/css/components/spotlight.css +8 -3
- package/css/components/timeline.css +47 -0
- package/css/effects/morph.css +0 -12
- package/css/vanduo.css +1 -0
- package/dist/build-info.json +3 -3
- package/dist/vanduo.cjs.js +647 -63
- package/dist/vanduo.cjs.js.map +3 -3
- package/dist/vanduo.cjs.min.js +4 -4
- package/dist/vanduo.cjs.min.js.map +4 -4
- package/dist/vanduo.css +255 -24
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.esm.js +647 -63
- package/dist/vanduo.esm.js.map +3 -3
- package/dist/vanduo.esm.min.js +4 -4
- package/dist/vanduo.esm.min.js.map +4 -4
- package/dist/vanduo.js +647 -63
- package/dist/vanduo.js.map +3 -3
- package/dist/vanduo.min.css +2 -2
- package/dist/vanduo.min.css.map +1 -1
- package/dist/vanduo.min.js +4 -4
- package/dist/vanduo.min.js.map +4 -4
- package/js/components/datepicker.js +392 -70
- package/js/components/expanding-cards.js +136 -0
- package/js/components/morph.js +0 -3
- package/js/components/timeline.js +226 -0
- package/js/index.js +2 -0
- package/package.json +1 -1
package/dist/vanduo.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Vanduo v1.3.
|
|
1
|
+
/*! Vanduo v1.3.7 | Built: 2026-04-18T12:05:32.603Z | git:20b2d08 | development */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -132,7 +132,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
132
132
|
// js/vanduo.js
|
|
133
133
|
(function() {
|
|
134
134
|
"use strict";
|
|
135
|
-
const VANDUO_VERSION = true ? "1.3.
|
|
135
|
+
const VANDUO_VERSION = true ? "1.3.7" : "0.0.0-dev";
|
|
136
136
|
const Vanduo2 = {
|
|
137
137
|
version: VANDUO_VERSION,
|
|
138
138
|
components: {},
|
|
@@ -6694,10 +6694,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
6694
6694
|
next.classList.remove("vd-morph-next");
|
|
6695
6695
|
next.classList.add("vd-morph-current");
|
|
6696
6696
|
}
|
|
6697
|
-
el.classList.add("morph-done");
|
|
6698
|
-
setTimeout(function() {
|
|
6699
|
-
el.classList.remove("morph-done");
|
|
6700
|
-
}, 350);
|
|
6701
6697
|
if (typeof onComplete === "function") onComplete();
|
|
6702
6698
|
}, duration);
|
|
6703
6699
|
}
|
|
@@ -6708,6 +6704,303 @@ module.exports = __toCommonJS(index_exports);
|
|
|
6708
6704
|
window.VanduoMorph = Morph;
|
|
6709
6705
|
})();
|
|
6710
6706
|
|
|
6707
|
+
// js/components/expanding-cards.js
|
|
6708
|
+
(function() {
|
|
6709
|
+
"use strict";
|
|
6710
|
+
const ExpandingCards = {
|
|
6711
|
+
instances: /* @__PURE__ */ new Map(),
|
|
6712
|
+
init: function() {
|
|
6713
|
+
document.querySelectorAll(".vd-expanding-cards").forEach(function(el) {
|
|
6714
|
+
if (el.getAttribute("data-vd-expanding-cards") === "manual") return;
|
|
6715
|
+
if (ExpandingCards.instances.has(el)) return;
|
|
6716
|
+
ExpandingCards.initContainer(el);
|
|
6717
|
+
});
|
|
6718
|
+
},
|
|
6719
|
+
initContainer: function(container) {
|
|
6720
|
+
const cleanup = [];
|
|
6721
|
+
const getCards = function() {
|
|
6722
|
+
return Array.prototype.slice.call(container.querySelectorAll(".vd-expanding-card"));
|
|
6723
|
+
};
|
|
6724
|
+
const setActive = function(card) {
|
|
6725
|
+
const cards = getCards();
|
|
6726
|
+
if (!card || cards.indexOf(card) === -1) return;
|
|
6727
|
+
cards.forEach(function(c) {
|
|
6728
|
+
c.classList.toggle("is-active", c === card);
|
|
6729
|
+
});
|
|
6730
|
+
card.focus({ preventScroll: true });
|
|
6731
|
+
};
|
|
6732
|
+
const onClick = function(e) {
|
|
6733
|
+
const t = e.target;
|
|
6734
|
+
const card = t.closest ? t.closest(".vd-expanding-card") : null;
|
|
6735
|
+
if (!card || !container.contains(card)) return;
|
|
6736
|
+
setActive(card);
|
|
6737
|
+
};
|
|
6738
|
+
const onKeydown = function(e) {
|
|
6739
|
+
if (e.key !== "ArrowLeft" && e.key !== "ArrowRight" && e.key !== "Home" && e.key !== "End") {
|
|
6740
|
+
return;
|
|
6741
|
+
}
|
|
6742
|
+
const cards = getCards().filter(function(c) {
|
|
6743
|
+
return c.offsetParent !== null || c.getClientRects().length > 0;
|
|
6744
|
+
});
|
|
6745
|
+
if (!cards.length) return;
|
|
6746
|
+
const activeEl = document.activeElement;
|
|
6747
|
+
let idx = cards.indexOf(activeEl);
|
|
6748
|
+
if (idx < 0) {
|
|
6749
|
+
idx = cards.findIndex(function(c) {
|
|
6750
|
+
return c.classList.contains("is-active");
|
|
6751
|
+
});
|
|
6752
|
+
}
|
|
6753
|
+
if (idx < 0) idx = 0;
|
|
6754
|
+
if (e.key === "ArrowLeft") {
|
|
6755
|
+
e.preventDefault();
|
|
6756
|
+
setActive(cards[Math.max(0, idx - 1)]);
|
|
6757
|
+
} else if (e.key === "ArrowRight") {
|
|
6758
|
+
e.preventDefault();
|
|
6759
|
+
setActive(cards[Math.min(cards.length - 1, idx + 1)]);
|
|
6760
|
+
} else if (e.key === "Home") {
|
|
6761
|
+
e.preventDefault();
|
|
6762
|
+
setActive(cards[0]);
|
|
6763
|
+
} else if (e.key === "End") {
|
|
6764
|
+
e.preventDefault();
|
|
6765
|
+
setActive(cards[cards.length - 1]);
|
|
6766
|
+
}
|
|
6767
|
+
};
|
|
6768
|
+
container.addEventListener("click", onClick);
|
|
6769
|
+
cleanup.push(function() {
|
|
6770
|
+
container.removeEventListener("click", onClick);
|
|
6771
|
+
});
|
|
6772
|
+
container.addEventListener("keydown", onKeydown);
|
|
6773
|
+
cleanup.push(function() {
|
|
6774
|
+
container.removeEventListener("keydown", onKeydown);
|
|
6775
|
+
});
|
|
6776
|
+
getCards().forEach(function(card) {
|
|
6777
|
+
if (!card.hasAttribute("tabindex")) {
|
|
6778
|
+
card.setAttribute("tabindex", "0");
|
|
6779
|
+
}
|
|
6780
|
+
card.setAttribute("role", "button");
|
|
6781
|
+
if (!card.hasAttribute("aria-pressed")) {
|
|
6782
|
+
card.setAttribute("aria-pressed", card.classList.contains("is-active") ? "true" : "false");
|
|
6783
|
+
}
|
|
6784
|
+
});
|
|
6785
|
+
const syncAria = function() {
|
|
6786
|
+
getCards().forEach(function(card) {
|
|
6787
|
+
card.setAttribute("aria-pressed", card.classList.contains("is-active") ? "true" : "false");
|
|
6788
|
+
});
|
|
6789
|
+
};
|
|
6790
|
+
const mo = new MutationObserver(syncAria);
|
|
6791
|
+
mo.observe(container, { attributes: true, subtree: true, attributeFilter: ["class"] });
|
|
6792
|
+
cleanup.push(function() {
|
|
6793
|
+
mo.disconnect();
|
|
6794
|
+
});
|
|
6795
|
+
syncAria();
|
|
6796
|
+
ExpandingCards.instances.set(container, { cleanup });
|
|
6797
|
+
},
|
|
6798
|
+
destroy: function(container) {
|
|
6799
|
+
const inst = this.instances.get(container);
|
|
6800
|
+
if (!inst) return;
|
|
6801
|
+
inst.cleanup.forEach(function(fn) {
|
|
6802
|
+
fn();
|
|
6803
|
+
});
|
|
6804
|
+
this.instances.delete(container);
|
|
6805
|
+
},
|
|
6806
|
+
destroyAll: function() {
|
|
6807
|
+
this.instances.forEach(function(_, el) {
|
|
6808
|
+
ExpandingCards.destroy(el);
|
|
6809
|
+
});
|
|
6810
|
+
}
|
|
6811
|
+
};
|
|
6812
|
+
if (typeof window.Vanduo !== "undefined") {
|
|
6813
|
+
window.Vanduo.register("expandingCards", ExpandingCards);
|
|
6814
|
+
}
|
|
6815
|
+
window.VanduoExpandingCards = ExpandingCards;
|
|
6816
|
+
})();
|
|
6817
|
+
|
|
6818
|
+
// js/components/timeline.js
|
|
6819
|
+
(function() {
|
|
6820
|
+
"use strict";
|
|
6821
|
+
const STAGGER_MS = 140;
|
|
6822
|
+
const MAX_STAGGER_INDEX = 7;
|
|
6823
|
+
const PLAY_INTERVAL_MS = 800;
|
|
6824
|
+
function countRevealedPrefix(items) {
|
|
6825
|
+
let count = 0;
|
|
6826
|
+
for (let i = 0; i < items.length; i++) {
|
|
6827
|
+
if (!items[i].classList.contains("is-revealed")) break;
|
|
6828
|
+
count++;
|
|
6829
|
+
}
|
|
6830
|
+
return count;
|
|
6831
|
+
}
|
|
6832
|
+
function findPlaybackControls(container) {
|
|
6833
|
+
return container.parentElement || document.body;
|
|
6834
|
+
}
|
|
6835
|
+
function initPlayback(container, items, cleanup) {
|
|
6836
|
+
items.forEach(function(item) {
|
|
6837
|
+
item.classList.remove("is-revealed");
|
|
6838
|
+
});
|
|
6839
|
+
const scope = findPlaybackControls(container);
|
|
6840
|
+
const prevBtn = scope.querySelector("[data-vd-timeline-prev]");
|
|
6841
|
+
const nextBtn = scope.querySelector("[data-vd-timeline-next]");
|
|
6842
|
+
const playBtn = scope.querySelector("[data-vd-timeline-play]");
|
|
6843
|
+
const pauseBtn = scope.querySelector("[data-vd-timeline-pause]");
|
|
6844
|
+
let playTimer = null;
|
|
6845
|
+
function updateNavButtons() {
|
|
6846
|
+
const k = countRevealedPrefix(items);
|
|
6847
|
+
const n = items.length;
|
|
6848
|
+
if (prevBtn) {
|
|
6849
|
+
const atStart = k === 0;
|
|
6850
|
+
prevBtn.disabled = atStart;
|
|
6851
|
+
prevBtn.setAttribute("aria-disabled", atStart ? "true" : "false");
|
|
6852
|
+
}
|
|
6853
|
+
if (nextBtn) {
|
|
6854
|
+
const atEnd = k >= n;
|
|
6855
|
+
nextBtn.disabled = atEnd;
|
|
6856
|
+
nextBtn.setAttribute("aria-disabled", atEnd ? "true" : "false");
|
|
6857
|
+
}
|
|
6858
|
+
if (playBtn) {
|
|
6859
|
+
playBtn.setAttribute("aria-pressed", playTimer ? "true" : "false");
|
|
6860
|
+
}
|
|
6861
|
+
if (pauseBtn) {
|
|
6862
|
+
pauseBtn.disabled = !playTimer;
|
|
6863
|
+
}
|
|
6864
|
+
}
|
|
6865
|
+
function stepNext() {
|
|
6866
|
+
const k = countRevealedPrefix(items);
|
|
6867
|
+
if (k < items.length) {
|
|
6868
|
+
items[k].classList.add("is-revealed");
|
|
6869
|
+
}
|
|
6870
|
+
updateNavButtons();
|
|
6871
|
+
}
|
|
6872
|
+
function stepPrev() {
|
|
6873
|
+
const k = countRevealedPrefix(items);
|
|
6874
|
+
if (k > 0) {
|
|
6875
|
+
items[k - 1].classList.remove("is-revealed");
|
|
6876
|
+
}
|
|
6877
|
+
updateNavButtons();
|
|
6878
|
+
}
|
|
6879
|
+
function play() {
|
|
6880
|
+
if (playTimer) return;
|
|
6881
|
+
playTimer = setInterval(function() {
|
|
6882
|
+
if (countRevealedPrefix(items) >= items.length) {
|
|
6883
|
+
pause();
|
|
6884
|
+
return;
|
|
6885
|
+
}
|
|
6886
|
+
stepNext();
|
|
6887
|
+
}, PLAY_INTERVAL_MS);
|
|
6888
|
+
updateNavButtons();
|
|
6889
|
+
}
|
|
6890
|
+
function pause() {
|
|
6891
|
+
if (playTimer) {
|
|
6892
|
+
clearInterval(playTimer);
|
|
6893
|
+
playTimer = null;
|
|
6894
|
+
}
|
|
6895
|
+
updateNavButtons();
|
|
6896
|
+
}
|
|
6897
|
+
function addClick(el, fn) {
|
|
6898
|
+
if (!el) return;
|
|
6899
|
+
const handler = function(e) {
|
|
6900
|
+
e.preventDefault();
|
|
6901
|
+
fn();
|
|
6902
|
+
};
|
|
6903
|
+
el.addEventListener("click", handler);
|
|
6904
|
+
cleanup.push(function() {
|
|
6905
|
+
el.removeEventListener("click", handler);
|
|
6906
|
+
});
|
|
6907
|
+
}
|
|
6908
|
+
addClick(prevBtn, stepPrev);
|
|
6909
|
+
addClick(nextBtn, stepNext);
|
|
6910
|
+
addClick(playBtn, play);
|
|
6911
|
+
addClick(pauseBtn, pause);
|
|
6912
|
+
cleanup.push(function() {
|
|
6913
|
+
pause();
|
|
6914
|
+
});
|
|
6915
|
+
updateNavButtons();
|
|
6916
|
+
return {
|
|
6917
|
+
stepNext,
|
|
6918
|
+
stepPrev,
|
|
6919
|
+
play,
|
|
6920
|
+
pause
|
|
6921
|
+
};
|
|
6922
|
+
}
|
|
6923
|
+
const Timeline = {
|
|
6924
|
+
instances: /* @__PURE__ */ new Map(),
|
|
6925
|
+
init: function() {
|
|
6926
|
+
document.querySelectorAll(".vd-timeline.vd-timeline-animated").forEach(function(el) {
|
|
6927
|
+
if (Timeline.instances.has(el)) return;
|
|
6928
|
+
Timeline.initInstance(el);
|
|
6929
|
+
});
|
|
6930
|
+
},
|
|
6931
|
+
reinit: function() {
|
|
6932
|
+
Timeline.destroyAll();
|
|
6933
|
+
Timeline.init();
|
|
6934
|
+
},
|
|
6935
|
+
initInstance: function(container) {
|
|
6936
|
+
const cleanup = [];
|
|
6937
|
+
const items = Array.prototype.filter.call(container.children, function(child) {
|
|
6938
|
+
return child.classList && child.classList.contains("vd-timeline-item");
|
|
6939
|
+
});
|
|
6940
|
+
items.forEach(function(item, i) {
|
|
6941
|
+
const idx = Math.min(i, MAX_STAGGER_INDEX);
|
|
6942
|
+
item.style.setProperty("--vd-timeline-reveal-delay", idx * STAGGER_MS + "ms");
|
|
6943
|
+
});
|
|
6944
|
+
const reducedMotion = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
6945
|
+
if (reducedMotion) {
|
|
6946
|
+
items.forEach(function(item) {
|
|
6947
|
+
item.classList.add("is-revealed");
|
|
6948
|
+
});
|
|
6949
|
+
Timeline.instances.set(container, { cleanup });
|
|
6950
|
+
return;
|
|
6951
|
+
}
|
|
6952
|
+
const playback = container.classList && container.classList.contains("vd-timeline-playback");
|
|
6953
|
+
if (playback) {
|
|
6954
|
+
const playbackApi = initPlayback(container, items, cleanup);
|
|
6955
|
+
Timeline.instances.set(container, { cleanup, playback: playbackApi });
|
|
6956
|
+
return;
|
|
6957
|
+
}
|
|
6958
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
6959
|
+
items.forEach(function(item) {
|
|
6960
|
+
item.classList.add("is-revealed");
|
|
6961
|
+
});
|
|
6962
|
+
Timeline.instances.set(container, { cleanup });
|
|
6963
|
+
return;
|
|
6964
|
+
}
|
|
6965
|
+
const observer = new IntersectionObserver(function(entries) {
|
|
6966
|
+
entries.forEach(function(entry) {
|
|
6967
|
+
if (!entry.isIntersecting) return;
|
|
6968
|
+
entry.target.classList.add("is-revealed");
|
|
6969
|
+
observer.unobserve(entry.target);
|
|
6970
|
+
});
|
|
6971
|
+
}, {
|
|
6972
|
+
root: null,
|
|
6973
|
+
rootMargin: "0px 0px -10% 0px",
|
|
6974
|
+
threshold: 0.15
|
|
6975
|
+
});
|
|
6976
|
+
items.forEach(function(item) {
|
|
6977
|
+
observer.observe(item);
|
|
6978
|
+
});
|
|
6979
|
+
cleanup.push(function() {
|
|
6980
|
+
observer.disconnect();
|
|
6981
|
+
});
|
|
6982
|
+
Timeline.instances.set(container, { cleanup });
|
|
6983
|
+
},
|
|
6984
|
+
destroy: function(container) {
|
|
6985
|
+
const inst = this.instances.get(container);
|
|
6986
|
+
if (!inst) return;
|
|
6987
|
+
inst.cleanup.forEach(function(fn) {
|
|
6988
|
+
fn();
|
|
6989
|
+
});
|
|
6990
|
+
this.instances.delete(container);
|
|
6991
|
+
},
|
|
6992
|
+
destroyAll: function() {
|
|
6993
|
+
this.instances.forEach(function(_, el) {
|
|
6994
|
+
Timeline.destroy(el);
|
|
6995
|
+
});
|
|
6996
|
+
}
|
|
6997
|
+
};
|
|
6998
|
+
if (typeof window.Vanduo !== "undefined") {
|
|
6999
|
+
window.Vanduo.register("timeline", Timeline);
|
|
7000
|
+
}
|
|
7001
|
+
window.VanduoTimeline = Timeline;
|
|
7002
|
+
})();
|
|
7003
|
+
|
|
6711
7004
|
// js/components/flow.js
|
|
6712
7005
|
(function() {
|
|
6713
7006
|
"use strict";
|
|
@@ -7724,6 +8017,115 @@ module.exports = __toCommonJS(index_exports);
|
|
|
7724
8017
|
"use strict";
|
|
7725
8018
|
const DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
7726
8019
|
const MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
8020
|
+
function escapeRegexChar(c) {
|
|
8021
|
+
return c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8022
|
+
}
|
|
8023
|
+
function buildParseFormat(format) {
|
|
8024
|
+
let regex = "^";
|
|
8025
|
+
const order = [];
|
|
8026
|
+
let i = 0;
|
|
8027
|
+
while (i < format.length) {
|
|
8028
|
+
const slice = format.slice(i);
|
|
8029
|
+
if (slice.toLowerCase().startsWith("yyyy")) {
|
|
8030
|
+
regex += "(\\d{4})";
|
|
8031
|
+
order.push("y");
|
|
8032
|
+
i += 4;
|
|
8033
|
+
} else if (slice.toLowerCase().startsWith("mm")) {
|
|
8034
|
+
regex += "(\\d{2})";
|
|
8035
|
+
order.push("m");
|
|
8036
|
+
i += 2;
|
|
8037
|
+
} else if (slice.toLowerCase().startsWith("dd")) {
|
|
8038
|
+
regex += "(\\d{2})";
|
|
8039
|
+
order.push("d");
|
|
8040
|
+
i += 2;
|
|
8041
|
+
} else {
|
|
8042
|
+
regex += escapeRegexChar(format[i]);
|
|
8043
|
+
i++;
|
|
8044
|
+
}
|
|
8045
|
+
}
|
|
8046
|
+
regex += "$";
|
|
8047
|
+
return { regex: new RegExp(regex), order };
|
|
8048
|
+
}
|
|
8049
|
+
function parseDateFromFormat(value, format) {
|
|
8050
|
+
if (!value || !format) return null;
|
|
8051
|
+
const { regex, order } = buildParseFormat(format);
|
|
8052
|
+
const m = value.trim().match(regex);
|
|
8053
|
+
if (!m) return null;
|
|
8054
|
+
let y;
|
|
8055
|
+
let mo;
|
|
8056
|
+
let d;
|
|
8057
|
+
let ci = 1;
|
|
8058
|
+
for (let k = 0; k < order.length; k++) {
|
|
8059
|
+
const part = order[k];
|
|
8060
|
+
const v = parseInt(m[ci++], 10);
|
|
8061
|
+
if (Number.isNaN(v)) return null;
|
|
8062
|
+
if (part === "y") y = v;
|
|
8063
|
+
else if (part === "m") mo = v - 1;
|
|
8064
|
+
else if (part === "d") d = v;
|
|
8065
|
+
}
|
|
8066
|
+
if (y === void 0 || mo === void 0 || d === void 0) return null;
|
|
8067
|
+
const dt = new Date(y, mo, d);
|
|
8068
|
+
if (dt.getFullYear() !== y || dt.getMonth() !== mo || dt.getDate() !== d) return null;
|
|
8069
|
+
return dt;
|
|
8070
|
+
}
|
|
8071
|
+
function formatDate(d, format) {
|
|
8072
|
+
const yyyy = String(d.getFullYear());
|
|
8073
|
+
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
|
8074
|
+
const dd = String(d.getDate()).padStart(2, "0");
|
|
8075
|
+
let out = "";
|
|
8076
|
+
let i = 0;
|
|
8077
|
+
while (i < format.length) {
|
|
8078
|
+
const slice = format.slice(i);
|
|
8079
|
+
if (slice.toLowerCase().startsWith("yyyy")) {
|
|
8080
|
+
out += yyyy;
|
|
8081
|
+
i += 4;
|
|
8082
|
+
} else if (slice.toLowerCase().startsWith("mm")) {
|
|
8083
|
+
out += mm;
|
|
8084
|
+
i += 2;
|
|
8085
|
+
} else if (slice.toLowerCase().startsWith("dd")) {
|
|
8086
|
+
out += dd;
|
|
8087
|
+
i += 2;
|
|
8088
|
+
} else {
|
|
8089
|
+
out += format[i];
|
|
8090
|
+
i++;
|
|
8091
|
+
}
|
|
8092
|
+
}
|
|
8093
|
+
return out;
|
|
8094
|
+
}
|
|
8095
|
+
function dateKey(d) {
|
|
8096
|
+
return d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
|
|
8097
|
+
}
|
|
8098
|
+
function addDays(d, n) {
|
|
8099
|
+
const x = new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8100
|
+
x.setDate(x.getDate() + n);
|
|
8101
|
+
return x;
|
|
8102
|
+
}
|
|
8103
|
+
function addMonthsClamped(d, n) {
|
|
8104
|
+
return new Date(d.getFullYear(), d.getMonth() + n, d.getDate());
|
|
8105
|
+
}
|
|
8106
|
+
function parseYmdLocal(ymd) {
|
|
8107
|
+
if (!ymd || typeof ymd !== "string") return null;
|
|
8108
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(ymd.trim());
|
|
8109
|
+
if (!m) return null;
|
|
8110
|
+
const y = +m[1];
|
|
8111
|
+
const mo = +m[2] - 1;
|
|
8112
|
+
const day = +m[3];
|
|
8113
|
+
const dt = new Date(y, mo, day);
|
|
8114
|
+
if (dt.getFullYear() !== y || dt.getMonth() !== mo || dt.getDate() !== day) return null;
|
|
8115
|
+
return dt;
|
|
8116
|
+
}
|
|
8117
|
+
function startOfWeekSunday(d) {
|
|
8118
|
+
const x = new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8119
|
+
const day = x.getDay();
|
|
8120
|
+
x.setDate(x.getDate() - day);
|
|
8121
|
+
return x;
|
|
8122
|
+
}
|
|
8123
|
+
function endOfWeekSunday(d) {
|
|
8124
|
+
const x = new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8125
|
+
const day = x.getDay();
|
|
8126
|
+
x.setDate(x.getDate() + (6 - day));
|
|
8127
|
+
return x;
|
|
8128
|
+
}
|
|
7727
8129
|
const Datepicker = {
|
|
7728
8130
|
instances: /* @__PURE__ */ new Map(),
|
|
7729
8131
|
init: function() {
|
|
@@ -7735,28 +8137,70 @@ module.exports = __toCommonJS(index_exports);
|
|
|
7735
8137
|
},
|
|
7736
8138
|
initInstance: function(input) {
|
|
7737
8139
|
const cleanup = [];
|
|
7738
|
-
const format = input.getAttribute("data-vd-datepicker-format") || "
|
|
8140
|
+
const format = input.getAttribute("data-vd-datepicker-format") || "YYYY-MM-DD";
|
|
7739
8141
|
const minStr = input.getAttribute("data-vd-datepicker-min");
|
|
7740
8142
|
const maxStr = input.getAttribute("data-vd-datepicker-max");
|
|
7741
|
-
const minDate = minStr ?
|
|
7742
|
-
const maxDate = maxStr ?
|
|
8143
|
+
const minDate = minStr ? parseYmdLocal(minStr) : null;
|
|
8144
|
+
const maxDate = maxStr ? parseYmdLocal(maxStr) : null;
|
|
7743
8145
|
const today = /* @__PURE__ */ new Date();
|
|
7744
8146
|
let viewYear = today.getFullYear();
|
|
7745
8147
|
let viewMonth = today.getMonth();
|
|
7746
8148
|
let selectedDate = null;
|
|
7747
8149
|
let viewMode = "days";
|
|
8150
|
+
let focusedDate = null;
|
|
8151
|
+
let skipNextFocusOpen = false;
|
|
8152
|
+
const isDisabled = (d) => {
|
|
8153
|
+
if (minDate) {
|
|
8154
|
+
const t = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
|
|
8155
|
+
if (t < minDate.getTime()) return true;
|
|
8156
|
+
}
|
|
8157
|
+
if (maxDate) {
|
|
8158
|
+
const t = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
|
|
8159
|
+
if (t > maxDate.getTime()) return true;
|
|
8160
|
+
}
|
|
8161
|
+
return false;
|
|
8162
|
+
};
|
|
8163
|
+
const ensureMonthInRange = (y, m) => {
|
|
8164
|
+
if (!minDate && !maxDate) return { y, m };
|
|
8165
|
+
const first = new Date(y, m, 1);
|
|
8166
|
+
const last = new Date(y, m + 1, 0);
|
|
8167
|
+
if (minDate && last.getTime() < minDate.getTime()) {
|
|
8168
|
+
return { y: minDate.getFullYear(), m: minDate.getMonth() };
|
|
8169
|
+
}
|
|
8170
|
+
if (maxDate && first.getTime() > maxDate.getTime()) {
|
|
8171
|
+
return { y: maxDate.getFullYear(), m: maxDate.getMonth() };
|
|
8172
|
+
}
|
|
8173
|
+
return { y, m };
|
|
8174
|
+
};
|
|
8175
|
+
const firstSelectableInMonth = (y, m) => {
|
|
8176
|
+
const last = new Date(y, m + 1, 0).getDate();
|
|
8177
|
+
for (let day = 1; day <= last; day++) {
|
|
8178
|
+
const dt = new Date(y, m, day);
|
|
8179
|
+
if (!isDisabled(dt)) return dt;
|
|
8180
|
+
}
|
|
8181
|
+
return new Date(y, m, 1);
|
|
8182
|
+
};
|
|
7748
8183
|
if (input.value) {
|
|
7749
|
-
const
|
|
7750
|
-
|
|
8184
|
+
const trimmed = input.value.trim();
|
|
8185
|
+
let parsed = parseDateFromFormat(trimmed, format);
|
|
8186
|
+
if (!parsed) {
|
|
8187
|
+
const fallback = new Date(trimmed);
|
|
8188
|
+
if (!isNaN(fallback.getTime())) parsed = fallback;
|
|
8189
|
+
}
|
|
8190
|
+
if (parsed) {
|
|
7751
8191
|
selectedDate = parsed;
|
|
7752
8192
|
viewYear = parsed.getFullYear();
|
|
7753
8193
|
viewMonth = parsed.getMonth();
|
|
7754
8194
|
}
|
|
7755
8195
|
}
|
|
8196
|
+
const clampedInit = ensureMonthInRange(viewYear, viewMonth);
|
|
8197
|
+
viewYear = clampedInit.y;
|
|
8198
|
+
viewMonth = clampedInit.m;
|
|
7756
8199
|
const popup = document.createElement("div");
|
|
7757
8200
|
popup.className = "vd-datepicker-popup";
|
|
7758
8201
|
popup.setAttribute("role", "dialog");
|
|
7759
8202
|
popup.setAttribute("aria-label", "Choose date");
|
|
8203
|
+
popup.tabIndex = -1;
|
|
7760
8204
|
const wrapper = document.createElement("div");
|
|
7761
8205
|
wrapper.className = "vd-suggest-wrapper";
|
|
7762
8206
|
wrapper.style.position = "relative";
|
|
@@ -7764,18 +8208,80 @@ module.exports = __toCommonJS(index_exports);
|
|
|
7764
8208
|
input.parentNode.insertBefore(wrapper, input);
|
|
7765
8209
|
wrapper.appendChild(input);
|
|
7766
8210
|
wrapper.appendChild(popup);
|
|
7767
|
-
const
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
8211
|
+
const isSameDay = (a, b) => a && b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
8212
|
+
const selectDate = (date) => {
|
|
8213
|
+
selectedDate = date;
|
|
8214
|
+
viewYear = date.getFullYear();
|
|
8215
|
+
viewMonth = date.getMonth();
|
|
8216
|
+
input.value = formatDate(date, format);
|
|
8217
|
+
skipNextFocusOpen = true;
|
|
8218
|
+
close();
|
|
8219
|
+
input.dispatchEvent(new CustomEvent("datepicker:select", {
|
|
8220
|
+
detail: { date, formatted: input.value },
|
|
8221
|
+
bubbles: true
|
|
8222
|
+
}));
|
|
8223
|
+
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
8224
|
+
input.focus();
|
|
7772
8225
|
};
|
|
7773
|
-
const
|
|
7774
|
-
if (
|
|
7775
|
-
|
|
7776
|
-
|
|
8226
|
+
const focusFocusedDay = () => {
|
|
8227
|
+
if (viewMode !== "days" || !focusedDate) return;
|
|
8228
|
+
const key = dateKey(focusedDate);
|
|
8229
|
+
const btn = popup.querySelector('[data-vd-date="' + key + '"]');
|
|
8230
|
+
if (btn && !btn.classList.contains("is-outside") && btn.getAttribute("aria-disabled") !== "true") {
|
|
8231
|
+
btn.focus();
|
|
8232
|
+
}
|
|
8233
|
+
};
|
|
8234
|
+
const skipDisabled = (d, stepDir, maxSteps) => {
|
|
8235
|
+
let x = new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8236
|
+
const step = stepDir > 0 ? 1 : -1;
|
|
8237
|
+
for (let i = 0; i < maxSteps; i++) {
|
|
8238
|
+
if (!isDisabled(x)) return x;
|
|
8239
|
+
x = addDays(x, step);
|
|
8240
|
+
}
|
|
8241
|
+
return d;
|
|
8242
|
+
};
|
|
8243
|
+
const createDayBtn = (day, outside, date) => {
|
|
8244
|
+
const btn = document.createElement("button");
|
|
8245
|
+
btn.type = "button";
|
|
8246
|
+
btn.className = "vd-datepicker-day";
|
|
8247
|
+
btn.textContent = day;
|
|
8248
|
+
btn.setAttribute("role", "gridcell");
|
|
8249
|
+
if (outside) {
|
|
8250
|
+
btn.classList.add("is-outside");
|
|
8251
|
+
btn.tabIndex = -1;
|
|
8252
|
+
btn.setAttribute("aria-disabled", "true");
|
|
8253
|
+
return btn;
|
|
8254
|
+
}
|
|
8255
|
+
btn.setAttribute("data-vd-date", dateKey(date));
|
|
8256
|
+
if (date && isSameDay(date, today)) btn.classList.add("is-today");
|
|
8257
|
+
if (date && isSameDay(date, selectedDate)) btn.classList.add("is-selected");
|
|
8258
|
+
if (date && isDisabled(date)) {
|
|
8259
|
+
btn.classList.add("is-disabled");
|
|
8260
|
+
btn.setAttribute("aria-disabled", "true");
|
|
8261
|
+
btn.tabIndex = -1;
|
|
8262
|
+
return btn;
|
|
8263
|
+
}
|
|
8264
|
+
if (date) {
|
|
8265
|
+
const isFocused = focusedDate && isSameDay(date, focusedDate);
|
|
8266
|
+
btn.tabIndex = isFocused ? 0 : -1;
|
|
8267
|
+
btn.addEventListener("click", () => {
|
|
8268
|
+
selectedDate = date;
|
|
8269
|
+
viewYear = date.getFullYear();
|
|
8270
|
+
viewMonth = date.getMonth();
|
|
8271
|
+
focusedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
8272
|
+
input.value = formatDate(date, format);
|
|
8273
|
+
skipNextFocusOpen = true;
|
|
8274
|
+
close();
|
|
8275
|
+
input.dispatchEvent(new CustomEvent("datepicker:select", {
|
|
8276
|
+
detail: { date, formatted: input.value },
|
|
8277
|
+
bubbles: true
|
|
8278
|
+
}));
|
|
8279
|
+
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
8280
|
+
input.focus();
|
|
8281
|
+
});
|
|
8282
|
+
}
|
|
8283
|
+
return btn;
|
|
7777
8284
|
};
|
|
7778
|
-
const isSameDay = (a, b) => a && b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
7779
8285
|
const render = () => {
|
|
7780
8286
|
popup.innerHTML = "";
|
|
7781
8287
|
const header = document.createElement("div");
|
|
@@ -7845,35 +8351,53 @@ module.exports = __toCommonJS(index_exports);
|
|
|
7845
8351
|
header.appendChild(nextBtn);
|
|
7846
8352
|
popup.appendChild(header);
|
|
7847
8353
|
if (viewMode === "days") {
|
|
8354
|
+
const gridWrap = document.createElement("div");
|
|
8355
|
+
gridWrap.className = "vd-datepicker-grid";
|
|
8356
|
+
gridWrap.setAttribute("role", "grid");
|
|
8357
|
+
gridWrap.setAttribute("aria-label", "Calendar");
|
|
7848
8358
|
const weekdays = document.createElement("div");
|
|
7849
8359
|
weekdays.className = "vd-datepicker-weekdays";
|
|
7850
|
-
|
|
8360
|
+
weekdays.setAttribute("role", "row");
|
|
8361
|
+
DAYS.forEach(function(d) {
|
|
7851
8362
|
const span = document.createElement("span");
|
|
8363
|
+
span.setAttribute("role", "columnheader");
|
|
8364
|
+
span.setAttribute("aria-label", d);
|
|
7852
8365
|
span.textContent = d;
|
|
7853
8366
|
weekdays.appendChild(span);
|
|
7854
8367
|
});
|
|
7855
|
-
|
|
7856
|
-
const grid = document.createElement("div");
|
|
7857
|
-
grid.className = "vd-datepicker-days";
|
|
8368
|
+
gridWrap.appendChild(weekdays);
|
|
7858
8369
|
const firstDay = new Date(viewYear, viewMonth, 1).getDay();
|
|
7859
8370
|
const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
|
|
7860
8371
|
const daysInPrev = new Date(viewYear, viewMonth, 0).getDate();
|
|
8372
|
+
const cells = [];
|
|
7861
8373
|
for (let i = firstDay - 1; i >= 0; i--) {
|
|
7862
|
-
const
|
|
7863
|
-
|
|
8374
|
+
const dayNum = daysInPrev - i;
|
|
8375
|
+
const prevMonth = viewMonth === 0 ? 11 : viewMonth - 1;
|
|
8376
|
+
const prevYear = viewMonth === 0 ? viewYear - 1 : viewYear;
|
|
8377
|
+
const date = new Date(prevYear, prevMonth, dayNum);
|
|
8378
|
+
cells.push({ day: dayNum, outside: true, date });
|
|
7864
8379
|
}
|
|
7865
8380
|
for (let d = 1; d <= daysInMonth; d++) {
|
|
7866
8381
|
const date = new Date(viewYear, viewMonth, d);
|
|
7867
|
-
|
|
7868
|
-
grid.appendChild(btn);
|
|
8382
|
+
cells.push({ day: d, outside: false, date });
|
|
7869
8383
|
}
|
|
7870
8384
|
const totalCells = firstDay + daysInMonth;
|
|
7871
8385
|
const remaining = totalCells % 7 === 0 ? 0 : 7 - totalCells % 7;
|
|
7872
8386
|
for (let i = 1; i <= remaining; i++) {
|
|
7873
|
-
const
|
|
7874
|
-
|
|
8387
|
+
const date = new Date(viewYear, viewMonth + 1, i);
|
|
8388
|
+
cells.push({ day: i, outside: true, date });
|
|
7875
8389
|
}
|
|
7876
|
-
|
|
8390
|
+
for (let r = 0; r < cells.length; r += 7) {
|
|
8391
|
+
const row = document.createElement("div");
|
|
8392
|
+
row.className = "vd-datepicker-row";
|
|
8393
|
+
row.setAttribute("role", "row");
|
|
8394
|
+
for (let c = 0; c < 7; c++) {
|
|
8395
|
+
const cell = cells[r + c];
|
|
8396
|
+
row.appendChild(createDayBtn(cell.day, cell.outside, cell.date));
|
|
8397
|
+
}
|
|
8398
|
+
gridWrap.appendChild(row);
|
|
8399
|
+
}
|
|
8400
|
+
popup.appendChild(gridWrap);
|
|
7877
8401
|
} else if (viewMode === "months") {
|
|
7878
8402
|
const grid = document.createElement("div");
|
|
7879
8403
|
grid.className = "vd-datepicker-months";
|
|
@@ -7914,65 +8438,125 @@ module.exports = __toCommonJS(index_exports);
|
|
|
7914
8438
|
popup.appendChild(grid);
|
|
7915
8439
|
}
|
|
7916
8440
|
};
|
|
7917
|
-
const
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
if (
|
|
7923
|
-
|
|
7924
|
-
btn.tabIndex = -1;
|
|
7925
|
-
return btn;
|
|
8441
|
+
const handleGridKeydown = (e) => {
|
|
8442
|
+
if (!popup.classList.contains("is-open") || viewMode !== "days") return;
|
|
8443
|
+
const grid = popup.querySelector(".vd-datepicker-grid");
|
|
8444
|
+
if (!grid || !grid.contains(e.target)) return;
|
|
8445
|
+
const key = e.key;
|
|
8446
|
+
if (key !== "ArrowLeft" && key !== "ArrowRight" && key !== "ArrowUp" && key !== "ArrowDown" && key !== "Home" && key !== "End" && key !== "PageUp" && key !== "PageDown" && key !== "Enter" && key !== " " && key !== "Escape") {
|
|
8447
|
+
return;
|
|
7926
8448
|
}
|
|
7927
|
-
if (
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
8449
|
+
if (key === "Escape") {
|
|
8450
|
+
e.preventDefault();
|
|
8451
|
+
e.stopPropagation();
|
|
8452
|
+
skipNextFocusOpen = true;
|
|
8453
|
+
close();
|
|
8454
|
+
input.focus();
|
|
8455
|
+
return;
|
|
7932
8456
|
}
|
|
7933
|
-
if (
|
|
7934
|
-
|
|
7935
|
-
selectedDate = date;
|
|
7936
|
-
viewYear = date.getFullYear();
|
|
7937
|
-
viewMonth = date.getMonth();
|
|
7938
|
-
input.value = formatDate(date);
|
|
7939
|
-
close();
|
|
7940
|
-
input.dispatchEvent(new CustomEvent("datepicker:select", {
|
|
7941
|
-
detail: { date, formatted: input.value },
|
|
7942
|
-
bubbles: true
|
|
7943
|
-
}));
|
|
7944
|
-
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
7945
|
-
});
|
|
8457
|
+
if (!focusedDate) {
|
|
8458
|
+
focusedDate = firstSelectableInMonth(viewYear, viewMonth);
|
|
7946
8459
|
}
|
|
7947
|
-
|
|
8460
|
+
if (key === "Enter" || key === " ") {
|
|
8461
|
+
e.preventDefault();
|
|
8462
|
+
if (focusedDate && !isDisabled(focusedDate)) {
|
|
8463
|
+
selectDate(new Date(focusedDate.getFullYear(), focusedDate.getMonth(), focusedDate.getDate()));
|
|
8464
|
+
}
|
|
8465
|
+
return;
|
|
8466
|
+
}
|
|
8467
|
+
e.preventDefault();
|
|
8468
|
+
let next = new Date(focusedDate.getFullYear(), focusedDate.getMonth(), focusedDate.getDate());
|
|
8469
|
+
let skipDir = 1;
|
|
8470
|
+
if (key === "ArrowLeft") {
|
|
8471
|
+
next = addDays(next, -1);
|
|
8472
|
+
skipDir = -1;
|
|
8473
|
+
} else if (key === "ArrowRight") {
|
|
8474
|
+
next = addDays(next, 1);
|
|
8475
|
+
skipDir = 1;
|
|
8476
|
+
} else if (key === "ArrowUp") {
|
|
8477
|
+
next = addDays(next, -7);
|
|
8478
|
+
skipDir = -1;
|
|
8479
|
+
} else if (key === "ArrowDown") {
|
|
8480
|
+
next = addDays(next, 7);
|
|
8481
|
+
skipDir = 1;
|
|
8482
|
+
} else if (key === "Home") {
|
|
8483
|
+
next = startOfWeekSunday(next);
|
|
8484
|
+
skipDir = 1;
|
|
8485
|
+
} else if (key === "End") {
|
|
8486
|
+
next = endOfWeekSunday(next);
|
|
8487
|
+
skipDir = -1;
|
|
8488
|
+
} else if (key === "PageUp") {
|
|
8489
|
+
next = addMonthsClamped(next, -1);
|
|
8490
|
+
skipDir = -1;
|
|
8491
|
+
} else if (key === "PageDown") {
|
|
8492
|
+
next = addMonthsClamped(next, 1);
|
|
8493
|
+
skipDir = 1;
|
|
8494
|
+
}
|
|
8495
|
+
next = skipDisabled(next, skipDir, 400);
|
|
8496
|
+
if (next.getMonth() !== viewMonth || next.getFullYear() !== viewYear) {
|
|
8497
|
+
viewYear = next.getFullYear();
|
|
8498
|
+
viewMonth = next.getMonth();
|
|
8499
|
+
const cl = ensureMonthInRange(viewYear, viewMonth);
|
|
8500
|
+
viewYear = cl.y;
|
|
8501
|
+
viewMonth = cl.m;
|
|
8502
|
+
}
|
|
8503
|
+
focusedDate = next;
|
|
8504
|
+
render();
|
|
8505
|
+
requestAnimationFrame(focusFocusedDay);
|
|
7948
8506
|
};
|
|
7949
8507
|
const open = () => {
|
|
8508
|
+
viewMode = "days";
|
|
8509
|
+
if (selectedDate) {
|
|
8510
|
+
viewYear = selectedDate.getFullYear();
|
|
8511
|
+
viewMonth = selectedDate.getMonth();
|
|
8512
|
+
}
|
|
8513
|
+
const cl = ensureMonthInRange(viewYear, viewMonth);
|
|
8514
|
+
viewYear = cl.y;
|
|
8515
|
+
viewMonth = cl.m;
|
|
8516
|
+
if (selectedDate) {
|
|
8517
|
+
focusedDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
|
|
8518
|
+
} else {
|
|
8519
|
+
focusedDate = firstSelectableInMonth(viewYear, viewMonth);
|
|
8520
|
+
}
|
|
7950
8521
|
render();
|
|
7951
8522
|
popup.classList.add("is-open");
|
|
7952
8523
|
input.setAttribute("aria-expanded", "true");
|
|
8524
|
+
requestAnimationFrame(focusFocusedDay);
|
|
7953
8525
|
};
|
|
7954
8526
|
const close = () => {
|
|
7955
8527
|
popup.classList.remove("is-open");
|
|
7956
8528
|
input.setAttribute("aria-expanded", "false");
|
|
7957
8529
|
viewMode = "days";
|
|
7958
8530
|
};
|
|
7959
|
-
const focusHandler = () =>
|
|
8531
|
+
const focusHandler = () => {
|
|
8532
|
+
if (skipNextFocusOpen) {
|
|
8533
|
+
skipNextFocusOpen = false;
|
|
8534
|
+
return;
|
|
8535
|
+
}
|
|
8536
|
+
open();
|
|
8537
|
+
};
|
|
7960
8538
|
const outsideHandler = (e) => {
|
|
7961
8539
|
if (!wrapper.contains(e.target)) close();
|
|
7962
8540
|
};
|
|
7963
8541
|
const escHandler = (e) => {
|
|
7964
|
-
if (e.key === "Escape"
|
|
8542
|
+
if (e.key === "Escape" && popup.classList.contains("is-open")) {
|
|
8543
|
+
skipNextFocusOpen = true;
|
|
8544
|
+
close();
|
|
8545
|
+
input.focus();
|
|
8546
|
+
}
|
|
7965
8547
|
};
|
|
7966
8548
|
input.addEventListener("focus", focusHandler);
|
|
7967
8549
|
document.addEventListener("click", outsideHandler, true);
|
|
7968
8550
|
document.addEventListener("keydown", escHandler);
|
|
8551
|
+
popup.addEventListener("keydown", handleGridKeydown);
|
|
7969
8552
|
input.setAttribute("aria-haspopup", "dialog");
|
|
7970
8553
|
input.setAttribute("aria-expanded", "false");
|
|
7971
8554
|
input.setAttribute("autocomplete", "off");
|
|
7972
8555
|
cleanup.push(
|
|
7973
8556
|
() => input.removeEventListener("focus", focusHandler),
|
|
7974
8557
|
() => document.removeEventListener("click", outsideHandler, true),
|
|
7975
|
-
() => document.removeEventListener("keydown", escHandler)
|
|
8558
|
+
() => document.removeEventListener("keydown", escHandler),
|
|
8559
|
+
() => popup.removeEventListener("keydown", handleGridKeydown)
|
|
7976
8560
|
);
|
|
7977
8561
|
this.instances.set(input, { cleanup, open, close, popup });
|
|
7978
8562
|
},
|