@lekoala/date-picker 0.5.1 → 0.5.3
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 +296 -294
- package/custom-elements.json +3 -0
- package/dist/date-picker.js +256 -91
- package/dist/date-picker.min.css +1 -1
- package/dist/date-picker.min.js +11 -12
- package/dist/date-picker.standalone.min.js +12 -506
- package/dist/types/date-calendar.d.ts +5 -90
- package/dist/types/date-picker.d.ts +12 -314
- package/dist/types/date.d.ts.map +1 -1
- package/docs/API.md +444 -442
- package/docs/ARCHITECTURE.md +2 -0
- package/docs/DECISIONS.md +74 -74
- package/docs/USE_CASES.md +156 -156
- package/package.json +3 -3
- package/src/activation-intents.js +9 -0
- package/src/date-calendar.js +99 -18
- package/src/date-field.js +57 -10
- package/src/date-picker.js +187 -86
- package/src/date.js +4 -1
- package/dist/types/date-calendar.d.ts.map +0 -1
- package/dist/types/date-field.d.ts +0 -104
- package/dist/types/date-field.d.ts.map +0 -1
- package/dist/types/date-picker.d.ts.map +0 -1
- package/dist/types/time.d.ts +0 -8
- package/dist/types/time.d.ts.map +0 -1
- package/dist/types/upgrade-properties.d.ts +0 -8
- package/dist/types/upgrade-properties.d.ts.map +0 -1
package/dist/date-picker.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*** @lekoala/date-picker v0.5.
|
|
1
|
+
/*** @lekoala/date-picker v0.5.3 - https://github.com/lekoala/date-picker ***/
|
|
2
2
|
(() => {
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -44,6 +44,9 @@
|
|
|
44
44
|
defineDatePicker: () => defineDatePicker
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
// src/activation-intents.js
|
|
48
|
+
var activationIntents = new WeakMap;
|
|
49
|
+
|
|
47
50
|
// src/date.js
|
|
48
51
|
var DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
49
52
|
var MONTH_RE = /^(\d{4})-(\d{2})$/;
|
|
@@ -75,9 +78,11 @@
|
|
|
75
78
|
const text = String(value || "");
|
|
76
79
|
const monthMatch = MONTH_RE.exec(text);
|
|
77
80
|
if (monthMatch) {
|
|
81
|
+
const year = Number(monthMatch[1]);
|
|
78
82
|
const month = Number(monthMatch[2]);
|
|
79
|
-
if (month >= 1 && month <= 12)
|
|
83
|
+
if (year >= 1 && year <= 9999 && month >= 1 && month <= 12) {
|
|
80
84
|
return `${monthMatch[1]}-${String(month).padStart(2, "0")}`;
|
|
85
|
+
}
|
|
81
86
|
}
|
|
82
87
|
const parsed = parseDate(text);
|
|
83
88
|
if (!parsed)
|
|
@@ -846,8 +851,12 @@
|
|
|
846
851
|
this._id = `date-calendar-${++uid}`;
|
|
847
852
|
this._model = new CalendarModel;
|
|
848
853
|
this._connected = false;
|
|
854
|
+
this._lifecycleId = 0;
|
|
849
855
|
this._rendering = false;
|
|
856
|
+
this._heading = null;
|
|
857
|
+
this._renderRoot = null;
|
|
850
858
|
this._source = null;
|
|
859
|
+
this._hostIntent = null;
|
|
851
860
|
this._sourceStates = new Map;
|
|
852
861
|
this._loadedRanges = new Set;
|
|
853
862
|
this._loadController = null;
|
|
@@ -872,6 +881,7 @@
|
|
|
872
881
|
connectedCallback() {
|
|
873
882
|
if (this._connected)
|
|
874
883
|
return;
|
|
884
|
+
this._lifecycleId++;
|
|
875
885
|
upgradeProperties(this, [
|
|
876
886
|
"locale",
|
|
877
887
|
"min",
|
|
@@ -914,6 +924,7 @@
|
|
|
914
924
|
this._stopDefaultMessages?.();
|
|
915
925
|
this._stopDefaultMessages = null;
|
|
916
926
|
this._connected = false;
|
|
927
|
+
this._lifecycleId++;
|
|
917
928
|
this._loadController?.abort();
|
|
918
929
|
this._loadController = null;
|
|
919
930
|
this._loadingKey = "";
|
|
@@ -923,12 +934,43 @@
|
|
|
923
934
|
this.removeEventListener("keydown", this._onKeyDown);
|
|
924
935
|
this.removeEventListener("focusin", this._onFocusIn);
|
|
925
936
|
}
|
|
926
|
-
attributeChangedCallback() {
|
|
927
|
-
if (
|
|
937
|
+
attributeChangedCallback(name, _oldValue, newValue) {
|
|
938
|
+
if (this._rendering)
|
|
939
|
+
return;
|
|
940
|
+
if (name === "value" && newValue && !isDate(newValue)) {
|
|
941
|
+
this._reflect("value", this._model.value);
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if ((name === "min" || name === "max") && newValue && !isDate(newValue)) {
|
|
945
|
+
this._reflect(name, "");
|
|
946
|
+
if (this._connected) {
|
|
947
|
+
this._syncModel();
|
|
948
|
+
this.render();
|
|
949
|
+
}
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
if (name === "display" && newValue) {
|
|
953
|
+
try {
|
|
954
|
+
if (monthKey(newValue) !== newValue)
|
|
955
|
+
throw new TypeError("Non-canonical month");
|
|
956
|
+
} catch {
|
|
957
|
+
this._reflect("display", this._model.display);
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
if (!this._connected)
|
|
928
962
|
return;
|
|
929
963
|
this._syncModel();
|
|
930
964
|
this.render();
|
|
931
965
|
}
|
|
966
|
+
_queueFocus(callback) {
|
|
967
|
+
const lifecycleId = this._lifecycleId;
|
|
968
|
+
queueMicrotask(() => {
|
|
969
|
+
if (!this._connected || lifecycleId !== this._lifecycleId)
|
|
970
|
+
return;
|
|
971
|
+
callback();
|
|
972
|
+
});
|
|
973
|
+
}
|
|
932
974
|
get locale() {
|
|
933
975
|
return resolveLocale(this.getAttribute("locale") || "");
|
|
934
976
|
}
|
|
@@ -1269,7 +1311,7 @@
|
|
|
1269
1311
|
this._moveFocusDom(previousFocused, this._model.focused, moveFocus);
|
|
1270
1312
|
}
|
|
1271
1313
|
if (moveFocus)
|
|
1272
|
-
|
|
1314
|
+
this._queueFocus(() => this.focusGrid());
|
|
1273
1315
|
}
|
|
1274
1316
|
_moveFocusDom(previous, next, moveFocus = true) {
|
|
1275
1317
|
const prevCell = previous ? this.querySelector(`.dp-day[data-date="${CSS.escape(previous)}"]`) : null;
|
|
@@ -1284,6 +1326,15 @@
|
|
|
1284
1326
|
this.focusGrid();
|
|
1285
1327
|
}
|
|
1286
1328
|
}
|
|
1329
|
+
_syncRovingDom(date) {
|
|
1330
|
+
for (const cell of this.querySelectorAll('.dp-day[tabindex="0"]')) {
|
|
1331
|
+
if (cell instanceof HTMLElement && cell.dataset.date !== date)
|
|
1332
|
+
cell.tabIndex = -1;
|
|
1333
|
+
}
|
|
1334
|
+
const cell = this.querySelector(`.dp-day[data-date="${CSS.escape(date)}"]`);
|
|
1335
|
+
if (cell instanceof HTMLElement)
|
|
1336
|
+
cell.tabIndex = 0;
|
|
1337
|
+
}
|
|
1287
1338
|
_moveSelectionDom(previousValue, nextValue) {
|
|
1288
1339
|
if (previousValue) {
|
|
1289
1340
|
const prev = this.querySelector(`.dp-day[data-date="${CSS.escape(previousValue)}"]`);
|
|
@@ -1344,17 +1395,29 @@
|
|
|
1344
1395
|
target.focus();
|
|
1345
1396
|
}
|
|
1346
1397
|
async activateDate(date) {
|
|
1398
|
+
if (!this._connected)
|
|
1399
|
+
return false;
|
|
1400
|
+
const lifecycleId = this._lifecycleId;
|
|
1401
|
+
const hostIntent = this._hostIntent?.date === date ? this._hostIntent.intent : undefined;
|
|
1402
|
+
this._hostIntent = null;
|
|
1403
|
+
const tagged = (event) => {
|
|
1404
|
+
if (hostIntent !== undefined)
|
|
1405
|
+
activationIntents.set(event, hostIntent);
|
|
1406
|
+
return event;
|
|
1407
|
+
};
|
|
1347
1408
|
const confirmed = await this.ensureDate(date);
|
|
1409
|
+
if (!this._connected || lifecycleId !== this._lifecycleId)
|
|
1410
|
+
return false;
|
|
1348
1411
|
const state = this.getDateState(date);
|
|
1349
1412
|
if (!confirmed || state.disabled) {
|
|
1350
|
-
this.dispatchEvent(new CustomEvent("dateinvalid", { detail: { date, state }, bubbles: true }));
|
|
1413
|
+
this.dispatchEvent(tagged(new CustomEvent("dateinvalid", { detail: { date, state }, bubbles: true })));
|
|
1351
1414
|
return false;
|
|
1352
1415
|
}
|
|
1353
|
-
const accepted = this.dispatchEvent(new CustomEvent("dateactivate", {
|
|
1416
|
+
const accepted = this.dispatchEvent(tagged(new CustomEvent("dateactivate", {
|
|
1354
1417
|
detail: { date, state },
|
|
1355
1418
|
bubbles: true,
|
|
1356
1419
|
cancelable: true
|
|
1357
|
-
}));
|
|
1420
|
+
})));
|
|
1358
1421
|
if (!accepted)
|
|
1359
1422
|
return false;
|
|
1360
1423
|
if (this.selection === "single") {
|
|
@@ -1399,6 +1462,8 @@
|
|
|
1399
1462
|
this._reflect("display", this._model.display);
|
|
1400
1463
|
if (previousDisplay !== this.display)
|
|
1401
1464
|
this._emitDisplayChange();
|
|
1465
|
+
else
|
|
1466
|
+
this._syncRovingDom(this._model.focused);
|
|
1402
1467
|
this.activateDate(date);
|
|
1403
1468
|
}
|
|
1404
1469
|
_onChange(event) {
|
|
@@ -1409,7 +1474,7 @@
|
|
|
1409
1474
|
}
|
|
1410
1475
|
if (target instanceof HTMLInputElement && target.matches(".dp-year-input")) {
|
|
1411
1476
|
const year = Number(target.value);
|
|
1412
|
-
if (!Number.isInteger(year) || year < 1 || year >
|
|
1477
|
+
if (!Number.isInteger(year) || year < 1 || year > 9999) {
|
|
1413
1478
|
if (this._connected)
|
|
1414
1479
|
this.render(false);
|
|
1415
1480
|
return;
|
|
@@ -1425,6 +1490,7 @@
|
|
|
1425
1490
|
if (!isDate(date))
|
|
1426
1491
|
return;
|
|
1427
1492
|
this._model.focused = date;
|
|
1493
|
+
this._syncRovingDom(date);
|
|
1428
1494
|
this.dispatchEvent(new CustomEvent("datefocus", { detail: { date, state: this.getDateState(date) }, bubbles: true }));
|
|
1429
1495
|
}
|
|
1430
1496
|
_onKeyDown(event) {
|
|
@@ -1487,8 +1553,8 @@
|
|
|
1487
1553
|
const nextKey = stepMonthKey(display, 1);
|
|
1488
1554
|
const prevDisabled = Boolean(minMonth && prevKey !== null && prevKey < minMonth);
|
|
1489
1555
|
const nextDisabled = Boolean(maxMonth && nextKey !== null && nextKey > maxMonth);
|
|
1490
|
-
const minYearAttr =
|
|
1491
|
-
const maxYearAttr =
|
|
1556
|
+
const minYearAttr = ` min="${this.min ? Number(this.min.slice(0, 4)) : 1}"`;
|
|
1557
|
+
const maxYearAttr = ` max="${this.max ? Number(this.max.slice(0, 4)) : 9999}"`;
|
|
1492
1558
|
const showWeeks = this.showWeekNumbers && this.firstDay === 1;
|
|
1493
1559
|
const weekHeader = showWeeks ? `<th scope="col" class="dp-week-heading" abbr="${escapeHtml(this.messages.week)}">#</th>` : "";
|
|
1494
1560
|
const monthOptions = names.map((name, index) => {
|
|
@@ -1526,8 +1592,20 @@
|
|
|
1526
1592
|
<select id="${this._id}-month" class="dp-month-select ${monthClass}" aria-label="${escapeHtml(this.messages.month)}">${monthOptions}</select>`;
|
|
1527
1593
|
const yearControl = `<label class="dp-visually-hidden" for="${this._id}-year">${escapeHtml(this.messages.year)}</label>
|
|
1528
1594
|
<input id="${this._id}-year" class="dp-year-input ${yearClass}" type="number" inputmode="numeric" value="${displayYear}"${minYearAttr}${maxYearAttr} aria-label="${escapeHtml(this.messages.year)}">`;
|
|
1595
|
+
if (!this._heading?.isConnected || !this._renderRoot?.isConnected) {
|
|
1596
|
+
this.replaceChildren();
|
|
1597
|
+
const heading = document.createElement("h2");
|
|
1598
|
+
heading.id = headingId;
|
|
1599
|
+
heading.className = "dp-calendar-heading dp-visually-hidden";
|
|
1600
|
+
heading.setAttribute("aria-live", "polite");
|
|
1601
|
+
const renderRoot = document.createElement("div");
|
|
1602
|
+
renderRoot.className = "dp-calendar-render";
|
|
1603
|
+
this.append(heading, renderRoot);
|
|
1604
|
+
this._heading = heading;
|
|
1605
|
+
this._renderRoot = renderRoot;
|
|
1606
|
+
}
|
|
1529
1607
|
this._rendering = true;
|
|
1530
|
-
this.innerHTML = `
|
|
1608
|
+
this._renderRoot.innerHTML = `
|
|
1531
1609
|
<div class="dp-calendar-shell">
|
|
1532
1610
|
<div class="dp-calendar-header">
|
|
1533
1611
|
${yearFirst ? yearControl : monthControl}
|
|
@@ -1535,17 +1613,17 @@
|
|
|
1535
1613
|
<button type="button" class="dp-nav dp-prev ${navClass}" data-calendar-action="previous" aria-label="${escapeHtml(this.messages.previousMonth)}"${prevDisabled ? " disabled" : ""}><svg aria-hidden="true" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m4 10 4-4 4 4"/></svg></button>
|
|
1536
1614
|
<button type="button" class="dp-nav dp-next ${navClass}" data-calendar-action="next" aria-label="${escapeHtml(this.messages.nextMonth)}"${nextDisabled ? " disabled" : ""}><svg aria-hidden="true" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m4 6 4 4 4-4"/></svg></button>
|
|
1537
1615
|
</div>
|
|
1538
|
-
<h2 id="${headingId}" class="dp-calendar-heading dp-visually-hidden" aria-live="polite">${escapeHtml(formatMonthYear(`${display}-15`, locale))}</h2>
|
|
1539
1616
|
<table id="${gridId}" class="dp-grid" role="grid" aria-labelledby="${headingId}">
|
|
1540
1617
|
<thead><tr>${weekHeader}${dayHeaders}</tr></thead>
|
|
1541
1618
|
<tbody>${rows}</tbody>
|
|
1542
1619
|
</table>
|
|
1543
1620
|
</div>`;
|
|
1621
|
+
this._heading.textContent = formatMonthYear(`${display}-15`, locale);
|
|
1544
1622
|
this._rendering = false;
|
|
1545
1623
|
this._paintedRange = { ...this._highlightedRange };
|
|
1546
1624
|
this._paintedPreview = this.hasAttribute("data-range-preview");
|
|
1547
1625
|
if (focusKey) {
|
|
1548
|
-
|
|
1626
|
+
this._queueFocus(() => {
|
|
1549
1627
|
let selector = focusKey;
|
|
1550
1628
|
if (selector.startsWith(".dp-day[data-date=")) {
|
|
1551
1629
|
selector = `.dp-day[data-date="${CSS.escape(this._model.focused)}"]`;
|
|
@@ -1946,6 +2024,10 @@
|
|
|
1946
2024
|
}
|
|
1947
2025
|
|
|
1948
2026
|
// src/date-field.js
|
|
2027
|
+
function isEditable(input) {
|
|
2028
|
+
return !input.matches(":disabled") && !input.readOnly;
|
|
2029
|
+
}
|
|
2030
|
+
|
|
1949
2031
|
class DateFieldController {
|
|
1950
2032
|
constructor(input, options = {}) {
|
|
1951
2033
|
this.input = input;
|
|
@@ -1955,13 +2037,27 @@
|
|
|
1955
2037
|
this.canonical = "";
|
|
1956
2038
|
this._dirty = false;
|
|
1957
2039
|
this._commitId = 0;
|
|
2040
|
+
this._disposed = false;
|
|
1958
2041
|
this._originalName = input.getAttribute("name") || "";
|
|
1959
2042
|
this._attributeObserver = null;
|
|
1960
2043
|
this.onAttributesChanged = null;
|
|
1961
2044
|
this.confirm = null;
|
|
2045
|
+
this._generatedDefault = null;
|
|
1962
2046
|
}
|
|
1963
2047
|
setLocale(locale) {
|
|
2048
|
+
const generated = this._generatedDefault;
|
|
2049
|
+
const previous = generated ? this.adapter.format(generated) : null;
|
|
1964
2050
|
this.adapter = createDateAdapter(locale || "");
|
|
2051
|
+
if (generated && this.input.defaultValue === previous) {
|
|
2052
|
+
this.input.defaultValue = this.adapter.format(generated);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
adoptDefault() {
|
|
2056
|
+
const input = this.input;
|
|
2057
|
+
if (input.getAttribute("value") != null || input.defaultValue !== "")
|
|
2058
|
+
return;
|
|
2059
|
+
input.defaultValue = input.value;
|
|
2060
|
+
this._generatedDefault = this.canonical && input.value ? this.canonical : null;
|
|
1965
2061
|
}
|
|
1966
2062
|
setMessages(messages) {
|
|
1967
2063
|
this.messages = messages || {};
|
|
@@ -1976,7 +2072,7 @@
|
|
|
1976
2072
|
return this.adapter.placeholder;
|
|
1977
2073
|
}
|
|
1978
2074
|
get isDisabled() {
|
|
1979
|
-
return this.input.disabled;
|
|
2075
|
+
return this.input.matches(":disabled");
|
|
1980
2076
|
}
|
|
1981
2077
|
get isReadOnly() {
|
|
1982
2078
|
return this.input.readOnly;
|
|
@@ -2044,34 +2140,39 @@
|
|
|
2044
2140
|
async commit(options = {}) {
|
|
2045
2141
|
const input = this.input;
|
|
2046
2142
|
const commitId = ++this._commitId;
|
|
2143
|
+
if (this._disposed)
|
|
2144
|
+
return { status: "stale", commitId };
|
|
2047
2145
|
const text = input.value.trim();
|
|
2048
2146
|
if (!text) {
|
|
2049
2147
|
if (commitId !== this._commitId)
|
|
2050
|
-
return { status: "stale" };
|
|
2148
|
+
return { status: "stale", commitId };
|
|
2051
2149
|
input.setCustomValidity("");
|
|
2052
|
-
return { status: "clear", value: "" };
|
|
2150
|
+
return { status: "clear", value: "", commitId };
|
|
2053
2151
|
}
|
|
2054
2152
|
const parsed = this.adapter.parse(text);
|
|
2055
2153
|
if (!parsed) {
|
|
2056
2154
|
if (commitId !== this._commitId)
|
|
2057
|
-
return { status: "stale" };
|
|
2155
|
+
return { status: "stale", commitId };
|
|
2058
2156
|
if (this.hidden)
|
|
2059
2157
|
this.hidden.value = "";
|
|
2060
2158
|
input.setCustomValidity(this.messages.invalidDate);
|
|
2061
|
-
return { status: "invalid" };
|
|
2159
|
+
return { status: "invalid", commitId };
|
|
2062
2160
|
}
|
|
2063
2161
|
if (this.confirm) {
|
|
2064
2162
|
const result = await this.confirm(parsed, options);
|
|
2065
|
-
if (commitId !== this._commitId)
|
|
2066
|
-
return { status: "stale" };
|
|
2163
|
+
if (this._disposed || commitId !== this._commitId)
|
|
2164
|
+
return { status: "stale", commitId };
|
|
2067
2165
|
if (!result?.ok) {
|
|
2068
2166
|
if (this.hidden)
|
|
2069
2167
|
this.hidden.value = "";
|
|
2070
2168
|
input.setCustomValidity(result?.message || this.messages.unavailableDate);
|
|
2071
|
-
return { status: "invalid" };
|
|
2169
|
+
return { status: "invalid", commitId };
|
|
2072
2170
|
}
|
|
2073
2171
|
}
|
|
2074
|
-
return { status: "ok", value: parsed };
|
|
2172
|
+
return { status: "ok", value: parsed, commitId };
|
|
2173
|
+
}
|
|
2174
|
+
isCommitCurrent(commitId) {
|
|
2175
|
+
return commitId === this._commitId;
|
|
2075
2176
|
}
|
|
2076
2177
|
setCanonical(value, options = {}) {
|
|
2077
2178
|
const next = value || "";
|
|
@@ -2092,6 +2193,8 @@
|
|
|
2092
2193
|
return parsed && isDate(parsed) ? parsed : "";
|
|
2093
2194
|
}
|
|
2094
2195
|
teardown() {
|
|
2196
|
+
this.dirty();
|
|
2197
|
+
this._disposed = true;
|
|
2095
2198
|
this._attributeObserver?.disconnect();
|
|
2096
2199
|
this._attributeObserver = null;
|
|
2097
2200
|
const hiddenName = this.hidden?.getAttribute("name") || this._originalName;
|
|
@@ -2163,8 +2266,7 @@
|
|
|
2163
2266
|
this._timeFields = [null, null];
|
|
2164
2267
|
this._timeOrderOwned = new Set;
|
|
2165
2268
|
this._lastFocusEndpoint = "";
|
|
2166
|
-
this.
|
|
2167
|
-
this._pendingIntents = new Map;
|
|
2269
|
+
this._activationId = 0;
|
|
2168
2270
|
this._previewDate = "";
|
|
2169
2271
|
this._drag = null;
|
|
2170
2272
|
this._suppressGridClick = false;
|
|
@@ -2175,7 +2277,7 @@
|
|
|
2175
2277
|
this._originalDescribedBy = "";
|
|
2176
2278
|
this._rangeOriginalDescribedBy = ["", ""];
|
|
2177
2279
|
this._formatHint = null;
|
|
2178
|
-
this.
|
|
2280
|
+
this._generatedPlaceholders = new WeakSet;
|
|
2179
2281
|
this._controller = null;
|
|
2180
2282
|
this._stopTracking = null;
|
|
2181
2283
|
this._open = false;
|
|
@@ -2192,6 +2294,9 @@
|
|
|
2192
2294
|
_rangeMode() {
|
|
2193
2295
|
return this.hasAttribute("range") && Boolean(this._range);
|
|
2194
2296
|
}
|
|
2297
|
+
_ownsField(field) {
|
|
2298
|
+
return this._connected && (field === this._field || Boolean(this._fields?.includes(field)));
|
|
2299
|
+
}
|
|
2195
2300
|
connectedCallback() {
|
|
2196
2301
|
if (this._connected)
|
|
2197
2302
|
return;
|
|
@@ -2219,6 +2324,7 @@
|
|
|
2219
2324
|
if (this._messages === null)
|
|
2220
2325
|
this._refreshMessages();
|
|
2221
2326
|
});
|
|
2327
|
+
this.validate();
|
|
2222
2328
|
}
|
|
2223
2329
|
}
|
|
2224
2330
|
_connectSingle() {
|
|
@@ -2248,9 +2354,7 @@
|
|
|
2248
2354
|
input.setCustomValidity(this.messages.invalidDate);
|
|
2249
2355
|
if (this._field.hidden)
|
|
2250
2356
|
this._field.hidden.defaultValue = this._value;
|
|
2251
|
-
|
|
2252
|
-
input.defaultValue = input.value;
|
|
2253
|
-
}
|
|
2357
|
+
this._field.adoptDefault();
|
|
2254
2358
|
}
|
|
2255
2359
|
_discoverTimeFields() {
|
|
2256
2360
|
this._timeFields = [null, null];
|
|
@@ -2307,26 +2411,30 @@
|
|
|
2307
2411
|
const adapter = this._adapter();
|
|
2308
2412
|
const initialStart = isDate(startInput.value) ? startInput.value : adapter.parse(startInput.value);
|
|
2309
2413
|
const initialEnd = isDate(endInput.value) ? endInput.value : adapter.parse(endInput.value);
|
|
2414
|
+
const startText = startInput.value;
|
|
2415
|
+
const endText = endInput.value;
|
|
2310
2416
|
this._setRange(initialStart || "", initialEnd || "", { emit: false });
|
|
2311
|
-
|
|
2312
|
-
startInput
|
|
2313
|
-
|
|
2314
|
-
|
|
2417
|
+
for (const [input, text, initial] of [
|
|
2418
|
+
[startInput, startText, initialStart],
|
|
2419
|
+
[endInput, endText, initialEnd]
|
|
2420
|
+
]) {
|
|
2421
|
+
if (!text.trim() || isDate(initial))
|
|
2422
|
+
continue;
|
|
2423
|
+
input.value = text;
|
|
2424
|
+
input.setCustomValidity(this.messages.invalidDate);
|
|
2425
|
+
}
|
|
2315
2426
|
if (this._fields[0].hidden)
|
|
2316
2427
|
this._fields[0].hidden.defaultValue = this._range.start;
|
|
2317
2428
|
if (this._fields[1].hidden)
|
|
2318
2429
|
this._fields[1].hidden.defaultValue = this._range.end;
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
}
|
|
2322
|
-
if (endInput.getAttribute("value") == null && endInput.defaultValue === "") {
|
|
2323
|
-
endInput.defaultValue = endInput.value;
|
|
2324
|
-
}
|
|
2430
|
+
for (const field of this._fields)
|
|
2431
|
+
field.adoptDefault();
|
|
2325
2432
|
}
|
|
2326
2433
|
disconnectedCallback() {
|
|
2327
2434
|
this._stopDefaultMessages?.();
|
|
2328
2435
|
this._stopDefaultMessages = null;
|
|
2329
2436
|
this._connected = false;
|
|
2437
|
+
this._suppressFocusOpen = false;
|
|
2330
2438
|
this.hide(false);
|
|
2331
2439
|
this._controller?.abort();
|
|
2332
2440
|
this._controller = null;
|
|
@@ -2367,13 +2475,29 @@
|
|
|
2367
2475
|
input.removeAttribute("aria-controls");
|
|
2368
2476
|
}
|
|
2369
2477
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
2370
|
-
if (
|
|
2478
|
+
if (this._reflecting || oldValue === newValue)
|
|
2479
|
+
return;
|
|
2480
|
+
if (name === "value" && newValue && !isDate(newValue)) {
|
|
2481
|
+
this._reflectValue(this._value);
|
|
2482
|
+
return;
|
|
2483
|
+
}
|
|
2484
|
+
if ((name === "min" || name === "max") && newValue && !isDate(newValue)) {
|
|
2485
|
+
this.removeAttribute(name);
|
|
2486
|
+
if (this._connected) {
|
|
2487
|
+
this._syncCalendarOptions();
|
|
2488
|
+
this.validate();
|
|
2489
|
+
}
|
|
2490
|
+
return;
|
|
2491
|
+
}
|
|
2492
|
+
if (!this._connected)
|
|
2371
2493
|
return;
|
|
2372
2494
|
if (name === "value") {
|
|
2373
2495
|
if (this._rangeMode())
|
|
2374
2496
|
return;
|
|
2375
|
-
if (!newValue || isDate(newValue))
|
|
2497
|
+
if (!newValue || isDate(newValue)) {
|
|
2498
|
+
this._supersedeActivations();
|
|
2376
2499
|
this._setValue(newValue || "", { emit: false, format: true, reflect: false });
|
|
2500
|
+
}
|
|
2377
2501
|
return;
|
|
2378
2502
|
}
|
|
2379
2503
|
if (name === "locale")
|
|
@@ -2398,6 +2522,7 @@
|
|
|
2398
2522
|
}
|
|
2399
2523
|
if (value && !isDate(value))
|
|
2400
2524
|
throw new TypeError(`Invalid date-picker value: ${value}`);
|
|
2525
|
+
this._supersedeActivations();
|
|
2401
2526
|
this._setValue(value || "", { emit: false, format: true });
|
|
2402
2527
|
}
|
|
2403
2528
|
get range() {
|
|
@@ -2407,6 +2532,7 @@
|
|
|
2407
2532
|
if (!this._rangeMode())
|
|
2408
2533
|
throw new TypeError("range is only available on <date-picker range>");
|
|
2409
2534
|
const { start, end } = normalizeRange(value);
|
|
2535
|
+
this._supersedeActivations();
|
|
2410
2536
|
this._setRange(start, end);
|
|
2411
2537
|
}
|
|
2412
2538
|
get locale() {
|
|
@@ -2547,7 +2673,7 @@
|
|
|
2547
2673
|
const button = this._buttons[0]?.button;
|
|
2548
2674
|
if (button)
|
|
2549
2675
|
button.disabled = input.disabled || input.readOnly;
|
|
2550
|
-
if (this._open && (input
|
|
2676
|
+
if (this._open && !isEditable(input))
|
|
2551
2677
|
this.hide(false);
|
|
2552
2678
|
}
|
|
2553
2679
|
_syncRangeFields() {
|
|
@@ -2562,9 +2688,9 @@
|
|
|
2562
2688
|
}
|
|
2563
2689
|
this._syncDragAffordance();
|
|
2564
2690
|
const active = this._range?.activeEndpoint === "end" ? 1 : 0;
|
|
2565
|
-
|
|
2691
|
+
const activeInput = this._fields[active]?.input;
|
|
2692
|
+
if (this._open && activeInput && !isEditable(activeInput))
|
|
2566
2693
|
this.hide(false);
|
|
2567
|
-
}
|
|
2568
2694
|
}
|
|
2569
2695
|
_setRangeAria() {
|
|
2570
2696
|
if (!this._fields || !this._panel || !this._formatHint)
|
|
@@ -2650,7 +2776,7 @@
|
|
|
2650
2776
|
return;
|
|
2651
2777
|
this.hide(false);
|
|
2652
2778
|
queueMicrotask(() => {
|
|
2653
|
-
if (!event.defaultPrevented)
|
|
2779
|
+
if (!signal.aborted && !event.defaultPrevented)
|
|
2654
2780
|
restore();
|
|
2655
2781
|
});
|
|
2656
2782
|
}, { capture: true, signal });
|
|
@@ -2692,7 +2818,7 @@
|
|
|
2692
2818
|
button.addEventListener("click", (event) => {
|
|
2693
2819
|
if (this._open) {
|
|
2694
2820
|
if (event.detail === 0) {
|
|
2695
|
-
|
|
2821
|
+
this._defer(() => this._calendar?.focusGrid());
|
|
2696
2822
|
return;
|
|
2697
2823
|
}
|
|
2698
2824
|
this.hide(false);
|
|
@@ -2701,15 +2827,23 @@
|
|
|
2701
2827
|
this.show({ returnFocus: button });
|
|
2702
2828
|
}, { signal });
|
|
2703
2829
|
button.addEventListener("keydown", (event) => this._onTriggerKeyDown("", event), { signal });
|
|
2830
|
+
calendar.addEventListener("click", (event) => this._captureGridIntent(event), { capture: true, signal });
|
|
2831
|
+
calendar.addEventListener("keydown", (event) => this._captureGridIntent(event), {
|
|
2832
|
+
capture: true,
|
|
2833
|
+
signal
|
|
2834
|
+
});
|
|
2704
2835
|
calendar.addEventListener("dateactivate", (event) => {
|
|
2705
2836
|
const custom = event;
|
|
2706
2837
|
const date = custom.detail?.date;
|
|
2707
2838
|
if (!isDate(date))
|
|
2708
2839
|
return;
|
|
2840
|
+
const intent = activationIntents.get(custom);
|
|
2709
2841
|
queueMicrotask(() => {
|
|
2710
|
-
if (custom.defaultPrevented || !this._connected)
|
|
2842
|
+
if (signal.aborted || custom.defaultPrevented || !this._connected)
|
|
2711
2843
|
return;
|
|
2712
|
-
if (
|
|
2844
|
+
if (intent && intent.id !== this._activationId)
|
|
2845
|
+
return;
|
|
2846
|
+
if (!this._input || !isEditable(this._input))
|
|
2713
2847
|
return;
|
|
2714
2848
|
this._field?.dirty();
|
|
2715
2849
|
this._setValue(date, { emit: true, format: true });
|
|
@@ -2729,7 +2863,12 @@
|
|
|
2729
2863
|
const { signal } = controller;
|
|
2730
2864
|
for (const [index, field] of this._fields.entries()) {
|
|
2731
2865
|
const endpoint = index === 1 ? "end" : "start";
|
|
2732
|
-
field.input.addEventListener("input", () =>
|
|
2866
|
+
field.input.addEventListener("input", () => {
|
|
2867
|
+
field.handleInput();
|
|
2868
|
+
this._orderTags.delete(index);
|
|
2869
|
+
if (!field.isDirty)
|
|
2870
|
+
this._revalidateRange(endpoint);
|
|
2871
|
+
}, { signal });
|
|
2733
2872
|
field.input.addEventListener("change", () => void this._commitFieldText(endpoint), { signal });
|
|
2734
2873
|
field.input.addEventListener("blur", () => void this._commitFieldText(endpoint), { signal });
|
|
2735
2874
|
field.input.addEventListener("focus", (event) => this._onFieldFocus(endpoint, event), { signal });
|
|
@@ -2765,12 +2904,11 @@
|
|
|
2765
2904
|
if (!isDate(date))
|
|
2766
2905
|
return;
|
|
2767
2906
|
queueMicrotask(() => {
|
|
2768
|
-
if (custom.defaultPrevented || !this._connected || !this._range)
|
|
2907
|
+
if (signal.aborted || custom.defaultPrevented || !this._connected || !this._range)
|
|
2769
2908
|
return;
|
|
2770
|
-
const intent =
|
|
2771
|
-
if (intent === undefined || intent.id !== this.
|
|
2909
|
+
const intent = activationIntents.get(custom);
|
|
2910
|
+
if (intent === undefined || intent.id !== this._activationId)
|
|
2772
2911
|
return;
|
|
2773
|
-
this._pendingIntents.delete(date);
|
|
2774
2912
|
const editable = (bound) => this._boundEditable(bound);
|
|
2775
2913
|
const result = intent.endpoint ? this._range.moveEndpoint(date, intent.endpoint, editable) : this._range.activate(date, editable);
|
|
2776
2914
|
if (result.status === "refused") {
|
|
@@ -2805,8 +2943,7 @@
|
|
|
2805
2943
|
if (!this._range || !calendar)
|
|
2806
2944
|
return;
|
|
2807
2945
|
this._range.focus(endpoint);
|
|
2808
|
-
this.
|
|
2809
|
-
this._pendingIntents.clear();
|
|
2946
|
+
this._activationId++;
|
|
2810
2947
|
this._lastFocusEndpoint = endpoint;
|
|
2811
2948
|
const target = this._boundCanonical(endpoint) || todayISO();
|
|
2812
2949
|
calendar.display = monthKey(target);
|
|
@@ -2820,7 +2957,7 @@
|
|
|
2820
2957
|
}
|
|
2821
2958
|
if (event.detail === 0) {
|
|
2822
2959
|
this._activateRangeEndpoint(endpoint);
|
|
2823
|
-
|
|
2960
|
+
this._defer(() => this._calendar?.focusGrid());
|
|
2824
2961
|
return;
|
|
2825
2962
|
}
|
|
2826
2963
|
if (endpoint !== this._range?.activeEndpoint) {
|
|
@@ -2836,7 +2973,7 @@
|
|
|
2836
2973
|
if (this._open) {
|
|
2837
2974
|
if (this._rangeMode() && endpoint)
|
|
2838
2975
|
this._activateRangeEndpoint(endpoint);
|
|
2839
|
-
|
|
2976
|
+
this._defer(() => this._calendar?.focusGrid());
|
|
2840
2977
|
return;
|
|
2841
2978
|
}
|
|
2842
2979
|
if (this._rangeMode())
|
|
@@ -2852,7 +2989,7 @@
|
|
|
2852
2989
|
this._range?.focus(endpoint);
|
|
2853
2990
|
}
|
|
2854
2991
|
if (this._open) {
|
|
2855
|
-
|
|
2992
|
+
this._defer(() => this._calendar?.focusGrid());
|
|
2856
2993
|
} else {
|
|
2857
2994
|
this.show();
|
|
2858
2995
|
}
|
|
@@ -2868,8 +3005,7 @@
|
|
|
2868
3005
|
this._lastFocusEndpoint = endpoint;
|
|
2869
3006
|
this._range?.focus(endpoint);
|
|
2870
3007
|
if (switched) {
|
|
2871
|
-
this.
|
|
2872
|
-
this._pendingIntents.clear();
|
|
3008
|
+
this._activationId++;
|
|
2873
3009
|
}
|
|
2874
3010
|
if (!this.openOnFocus || this._suppressFocusOpen)
|
|
2875
3011
|
return;
|
|
@@ -2880,25 +3016,34 @@
|
|
|
2880
3016
|
this.show({ moveFocus: false });
|
|
2881
3017
|
}
|
|
2882
3018
|
_captureGridIntent(event) {
|
|
2883
|
-
if (
|
|
3019
|
+
if (this._rangeMode() ? !this._range : !this._field)
|
|
2884
3020
|
return;
|
|
2885
3021
|
if (event.type === "keydown") {
|
|
2886
3022
|
const key = event.key;
|
|
2887
3023
|
if (key !== "Enter" && key !== " ")
|
|
2888
3024
|
return;
|
|
2889
3025
|
}
|
|
3026
|
+
if (event.type === "click" && this._suppressGridClick)
|
|
3027
|
+
return;
|
|
2890
3028
|
if (!(event.target instanceof Element))
|
|
2891
3029
|
return;
|
|
2892
3030
|
const cell = event.target.closest(".dp-day[data-date]");
|
|
2893
3031
|
const date = cell?.getAttribute("data-date") || "";
|
|
2894
3032
|
if (!isDate(date))
|
|
2895
3033
|
return;
|
|
2896
|
-
this.
|
|
2897
|
-
|
|
3034
|
+
this._attachIntent(date, "");
|
|
3035
|
+
}
|
|
3036
|
+
_attachIntent(date, endpoint) {
|
|
3037
|
+
if (!this._calendar)
|
|
3038
|
+
return;
|
|
3039
|
+
this._calendar._hostIntent = { date, intent: { id: ++this._activationId, endpoint } };
|
|
3040
|
+
}
|
|
3041
|
+
_supersedeActivations() {
|
|
3042
|
+
this._activationId++;
|
|
2898
3043
|
}
|
|
2899
3044
|
_boundEditable(bound) {
|
|
2900
3045
|
const field = this._fields?.[bound === "end" ? 1 : 0];
|
|
2901
|
-
return field != null &&
|
|
3046
|
+
return field != null && isEditable(field.input);
|
|
2902
3047
|
}
|
|
2903
3048
|
_applyRangeTransition(transition) {
|
|
2904
3049
|
const fields = this._fields;
|
|
@@ -3046,8 +3191,7 @@
|
|
|
3046
3191
|
return;
|
|
3047
3192
|
}
|
|
3048
3193
|
const target = drag.endpoint === "start" ? transition.range.start : transition.range.end;
|
|
3049
|
-
this.
|
|
3050
|
-
this._pendingIntents.set(target, { id: ++this._rangeCommitId, endpoint: drag.endpoint });
|
|
3194
|
+
this._attachIntent(target, drag.endpoint);
|
|
3051
3195
|
this._calendar?.activateDate(target);
|
|
3052
3196
|
}
|
|
3053
3197
|
_onGridPointerCancel(event) {
|
|
@@ -3115,9 +3259,9 @@
|
|
|
3115
3259
|
this._fields[1].setLocale(this.locale);
|
|
3116
3260
|
hint.textContent = `${this.messages.formatHint}: ${this._fields[0].placeholder}`;
|
|
3117
3261
|
for (const [index, field] of this._fields.entries()) {
|
|
3118
|
-
if (!field.input.hasAttribute("placeholder") || this.
|
|
3262
|
+
if (!field.input.hasAttribute("placeholder") || this._generatedPlaceholders.has(field.input)) {
|
|
3119
3263
|
field.input.placeholder = field.placeholder;
|
|
3120
|
-
this.
|
|
3264
|
+
this._generatedPlaceholders.add(field.input);
|
|
3121
3265
|
}
|
|
3122
3266
|
const canonical = index === 1 ? this._range?.end || "" : this._range?.start || "";
|
|
3123
3267
|
if (canonical)
|
|
@@ -3131,9 +3275,9 @@
|
|
|
3131
3275
|
return;
|
|
3132
3276
|
field.setLocale(this.locale);
|
|
3133
3277
|
hint.textContent = `${this.messages.formatHint}: ${field.placeholder}`;
|
|
3134
|
-
if (!field.input.hasAttribute("placeholder") || this.
|
|
3278
|
+
if (!field.input.hasAttribute("placeholder") || this._generatedPlaceholders.has(field.input)) {
|
|
3135
3279
|
field.input.placeholder = field.placeholder;
|
|
3136
|
-
this.
|
|
3280
|
+
this._generatedPlaceholders.add(field.input);
|
|
3137
3281
|
}
|
|
3138
3282
|
if (this._value)
|
|
3139
3283
|
field.input.value = field.format(this._value);
|
|
@@ -3216,6 +3360,9 @@
|
|
|
3216
3360
|
if (!options.force && !field.isDirty)
|
|
3217
3361
|
return false;
|
|
3218
3362
|
const result = await field.commit(options);
|
|
3363
|
+
if (!this._ownsField(field) || !field.isCommitCurrent(result.commitId)) {
|
|
3364
|
+
return false;
|
|
3365
|
+
}
|
|
3219
3366
|
if (result.status === "stale" || result.status === "invalid")
|
|
3220
3367
|
return false;
|
|
3221
3368
|
this._setValue(result.value || "", {
|
|
@@ -3234,6 +3381,8 @@
|
|
|
3234
3381
|
if (!field?.isDirty)
|
|
3235
3382
|
return false;
|
|
3236
3383
|
const result = await field.commit();
|
|
3384
|
+
if (!this._ownsField(field) || !field.isCommitCurrent(result.commitId))
|
|
3385
|
+
return false;
|
|
3237
3386
|
if (result.status === "stale")
|
|
3238
3387
|
return false;
|
|
3239
3388
|
if (result.status === "invalid") {
|
|
@@ -3253,7 +3402,7 @@
|
|
|
3253
3402
|
const field = fields[index];
|
|
3254
3403
|
if (!field)
|
|
3255
3404
|
return false;
|
|
3256
|
-
if (options.user === true && (field.input
|
|
3405
|
+
if (options.user === true && !isEditable(field.input))
|
|
3257
3406
|
return false;
|
|
3258
3407
|
const next = value || "";
|
|
3259
3408
|
const previous = field.canonical;
|
|
@@ -3337,8 +3486,8 @@
|
|
|
3337
3486
|
const [startInput, endInput] = this._timeFields;
|
|
3338
3487
|
const bounds = ["start", "end"];
|
|
3339
3488
|
const inputs = [startInput, endInput];
|
|
3340
|
-
const startValue = startInput && !startInput.disabled ? startInput.value.trim() : "";
|
|
3341
|
-
const endValue = endInput && !endInput.disabled ? endInput.value.trim() : "";
|
|
3489
|
+
const startValue = startInput && !startInput.matches(":disabled") ? startInput.value.trim() : "";
|
|
3490
|
+
const endValue = endInput && !endInput.matches(":disabled") ? endInput.value.trim() : "";
|
|
3342
3491
|
const inverted = Boolean(startInput && endInput && startValue && endValue) && isTime(startValue) && isTime(endValue) && compareTimes(endValue, startValue) < 0;
|
|
3343
3492
|
for (const [index, bound] of bounds.entries()) {
|
|
3344
3493
|
const input = inputs[index];
|
|
@@ -3360,6 +3509,14 @@
|
|
|
3360
3509
|
input.setCustomValidity("");
|
|
3361
3510
|
this._timeOrderOwned.clear();
|
|
3362
3511
|
}
|
|
3512
|
+
_defer(callback) {
|
|
3513
|
+
const controller = this._controller;
|
|
3514
|
+
setTimeout(() => {
|
|
3515
|
+
if (!this._connected || !controller || controller.signal.aborted || this._controller !== controller)
|
|
3516
|
+
return;
|
|
3517
|
+
callback();
|
|
3518
|
+
}, 0);
|
|
3519
|
+
}
|
|
3363
3520
|
_restoreDefault() {
|
|
3364
3521
|
const field = this._field;
|
|
3365
3522
|
if (!field)
|
|
@@ -3396,10 +3553,10 @@
|
|
|
3396
3553
|
if (!input)
|
|
3397
3554
|
return;
|
|
3398
3555
|
this._suppressFocusOpen = true;
|
|
3399
|
-
|
|
3556
|
+
this._defer(() => {
|
|
3400
3557
|
input.focus();
|
|
3401
3558
|
this._suppressFocusOpen = false;
|
|
3402
|
-
}
|
|
3559
|
+
});
|
|
3403
3560
|
}
|
|
3404
3561
|
_restoreFocus() {
|
|
3405
3562
|
const target = this._returnFocus;
|
|
@@ -3407,22 +3564,22 @@
|
|
|
3407
3564
|
if (!(target instanceof HTMLElement) || !target.isConnected || target.matches(":disabled"))
|
|
3408
3565
|
return;
|
|
3409
3566
|
this._suppressFocusOpen = true;
|
|
3410
|
-
|
|
3567
|
+
this._defer(() => {
|
|
3411
3568
|
target.focus();
|
|
3412
3569
|
this._suppressFocusOpen = false;
|
|
3413
|
-
}
|
|
3570
|
+
});
|
|
3414
3571
|
}
|
|
3415
3572
|
_resolveRangeEndpoint() {
|
|
3416
3573
|
if (!this._fields)
|
|
3417
3574
|
return "";
|
|
3418
3575
|
const preferred = this._lastFocusEndpoint || "start";
|
|
3419
3576
|
const preferredIndex = preferred === "end" ? 1 : 0;
|
|
3420
|
-
if (
|
|
3577
|
+
if (isEditable(this._fields[preferredIndex].input)) {
|
|
3421
3578
|
return preferred;
|
|
3422
3579
|
}
|
|
3423
3580
|
const alternative = preferred === "end" ? "start" : "end";
|
|
3424
3581
|
const alternativeIndex = alternative === "end" ? 1 : 0;
|
|
3425
|
-
if (
|
|
3582
|
+
if (isEditable(this._fields[alternativeIndex].input)) {
|
|
3426
3583
|
return alternative;
|
|
3427
3584
|
}
|
|
3428
3585
|
return "";
|
|
@@ -3434,6 +3591,10 @@
|
|
|
3434
3591
|
return true;
|
|
3435
3592
|
for (const [index, field] of fields.entries()) {
|
|
3436
3593
|
const result = await field.commit({ moveDisplay: false });
|
|
3594
|
+
if (!this._ownsField(field) || !field.isCommitCurrent(result.commitId))
|
|
3595
|
+
continue;
|
|
3596
|
+
if (result.status === "invalid")
|
|
3597
|
+
this._orderTags.delete(index);
|
|
3437
3598
|
if (result.status === "ok" || result.status === "clear") {
|
|
3438
3599
|
const which = index === 1 ? "end" : "start";
|
|
3439
3600
|
this._setBound(which, result.value || "", { format: result.status === "ok" });
|
|
@@ -3444,13 +3605,12 @@
|
|
|
3444
3605
|
return fields.every((field) => field.input.checkValidity());
|
|
3445
3606
|
}
|
|
3446
3607
|
const input = this._field?.input;
|
|
3447
|
-
if (!input)
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
} else {
|
|
3452
|
-
await this._commitText(false, { force: true, moveDisplay: false });
|
|
3608
|
+
if (!input) {
|
|
3609
|
+
const dateInputs = this.hasAttribute("range") ? this.querySelectorAll(":scope > input[data-range-start], :scope > input[data-range-end]") : this._input ? [this._input] : [];
|
|
3610
|
+
const timeInputs = this.querySelectorAll(":scope > input[type=time][data-time-start], :scope > input[type=time][data-time-end]");
|
|
3611
|
+
return [...dateInputs, ...timeInputs].every((candidate) => candidate instanceof HTMLInputElement && candidate.checkValidity());
|
|
3453
3612
|
}
|
|
3613
|
+
await this._commitText(false, { force: true, moveDisplay: false });
|
|
3454
3614
|
this._revalidateTimeOrder("start");
|
|
3455
3615
|
this._revalidateTimeOrder("end");
|
|
3456
3616
|
const timesValid = this._timeFields.every((timeInput) => timeInput?.checkValidity() ?? true);
|
|
@@ -3468,7 +3628,7 @@
|
|
|
3468
3628
|
this._activateRangeEndpoint(endpoint);
|
|
3469
3629
|
} else {
|
|
3470
3630
|
const input = this._input;
|
|
3471
|
-
if (!input || input
|
|
3631
|
+
if (!input || !isEditable(input))
|
|
3472
3632
|
return;
|
|
3473
3633
|
const target = this._value || this._adapter().parse(input.value) || todayISO();
|
|
3474
3634
|
calendar.display = monthKey(target);
|
|
@@ -3488,8 +3648,14 @@
|
|
|
3488
3648
|
});
|
|
3489
3649
|
position();
|
|
3490
3650
|
this._stopTracking = autoUpdate(this, panel, position);
|
|
3491
|
-
if (options.moveFocus !== false)
|
|
3492
|
-
|
|
3651
|
+
if (options.moveFocus !== false) {
|
|
3652
|
+
const controller = this._controller;
|
|
3653
|
+
queueMicrotask(() => {
|
|
3654
|
+
if (!this._connected || !controller || controller.signal.aborted || this._controller !== controller)
|
|
3655
|
+
return;
|
|
3656
|
+
calendar.focusGrid();
|
|
3657
|
+
});
|
|
3658
|
+
}
|
|
3493
3659
|
this.dispatchEvent(new Event("open", { bubbles: true }));
|
|
3494
3660
|
}
|
|
3495
3661
|
_setExpanded(expanded) {
|
|
@@ -3510,8 +3676,7 @@
|
|
|
3510
3676
|
} catch {}
|
|
3511
3677
|
this._open = false;
|
|
3512
3678
|
this._setExpanded(false);
|
|
3513
|
-
this.
|
|
3514
|
-
this._pendingIntents.clear();
|
|
3679
|
+
this._supersedeActivations();
|
|
3515
3680
|
this._suppressGridClick = false;
|
|
3516
3681
|
if (this._drag) {
|
|
3517
3682
|
this._releaseDragCapture(this._drag.pointerId);
|
|
@@ -3534,7 +3699,7 @@
|
|
|
3534
3699
|
if (active) {
|
|
3535
3700
|
const index = active === "end" ? 1 : 0;
|
|
3536
3701
|
const field = this._fields?.[index];
|
|
3537
|
-
if (field &&
|
|
3702
|
+
if (field && isEditable(field.input))
|
|
3538
3703
|
return active;
|
|
3539
3704
|
}
|
|
3540
3705
|
return this._resolveRangeEndpoint();
|