@lekoala/date-picker 0.5.0 → 0.5.2
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 -281
- package/custom-elements.json +45 -2
- package/dist/date-picker.js +300 -107
- package/dist/date-picker.min.css +1 -1
- package/dist/date-picker.min.js +11 -11
- package/dist/date-picker.standalone.min.js +13 -506
- package/dist/types/activation-intents.d.ts +10 -0
- package/dist/types/activation-intents.d.ts.map +1 -0
- package/dist/types/control-classes.d.ts +11 -1
- package/dist/types/control-classes.d.ts.map +1 -1
- package/dist/types/date-calendar.d.ts +39 -51
- package/dist/types/date-calendar.d.ts.map +1 -1
- package/dist/types/date-field.d.ts +14 -0
- package/dist/types/date-field.d.ts.map +1 -1
- package/dist/types/date-picker.d.ts +71 -81
- package/dist/types/date-picker.d.ts.map +1 -1
- package/dist/types/messages.d.ts +2 -0
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/upgrade-properties.d.ts +8 -0
- package/dist/types/upgrade-properties.d.ts.map +1 -0
- package/docs/API.md +442 -430
- package/docs/DECISIONS.md +74 -68
- package/docs/USE_CASES.md +156 -156
- package/package.json +2 -2
- package/src/activation-intents.js +9 -0
- package/src/control-classes.js +36 -6
- package/src/date-calendar.js +127 -35
- package/src/date-field.js +32 -1
- package/src/date-picker.js +202 -101
- package/src/messages.js +12 -0
- package/src/upgrade-properties.js +14 -0
package/src/date-calendar.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import { activationIntents } from "./activation-intents.js";
|
|
1
2
|
import { CalendarModel } from "./calendar-model.js";
|
|
2
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getDefaultControlClasses,
|
|
5
|
+
normalizeControlClasses,
|
|
6
|
+
resolveControlClasses,
|
|
7
|
+
sameControlClasses,
|
|
8
|
+
setDefaultControlClasses,
|
|
9
|
+
subscribeDefaultControlClasses,
|
|
10
|
+
usesDefaultControlClasses,
|
|
11
|
+
} from "./control-classes.js";
|
|
3
12
|
import {
|
|
4
13
|
addDays,
|
|
5
14
|
clampDate,
|
|
@@ -21,8 +30,9 @@ import {
|
|
|
21
30
|
resolveLocale,
|
|
22
31
|
weekdayNames,
|
|
23
32
|
} from "./intl.js";
|
|
24
|
-
import { getDefaultMessages } from "./messages.js";
|
|
33
|
+
import { getDefaultMessages, setDefaultMessages, subscribeDefaultMessages } from "./messages.js";
|
|
25
34
|
import { normalizeDateStates } from "./source.js";
|
|
35
|
+
import { upgradeProperties } from "./upgrade-properties.js";
|
|
26
36
|
|
|
27
37
|
let uid = 0;
|
|
28
38
|
|
|
@@ -128,6 +138,26 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
128
138
|
"month-format",
|
|
129
139
|
];
|
|
130
140
|
|
|
141
|
+
/** @public @param {Partial<import("./control-classes.js").ControlClasses>} classes */
|
|
142
|
+
static setDefaultControlClasses(classes) {
|
|
143
|
+
setDefaultControlClasses(classes);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** @public */
|
|
147
|
+
static getDefaultControlClasses() {
|
|
148
|
+
return getDefaultControlClasses();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** @public @param {Partial<typeof import("./messages.js").DEFAULT_MESSAGES>} messages */
|
|
152
|
+
static setDefaultMessages(messages) {
|
|
153
|
+
setDefaultMessages(messages);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** @public */
|
|
157
|
+
static getDefaultMessages() {
|
|
158
|
+
return getDefaultMessages();
|
|
159
|
+
}
|
|
160
|
+
|
|
131
161
|
constructor() {
|
|
132
162
|
super();
|
|
133
163
|
this._id = `date-calendar-${++uid}`;
|
|
@@ -136,6 +166,9 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
136
166
|
this._rendering = false;
|
|
137
167
|
/** @type {DateSource | null} */
|
|
138
168
|
this._source = null;
|
|
169
|
+
/** Intent the host attached to the next activation of `date`.
|
|
170
|
+
* @type {{date: string, intent: unknown} | null} */
|
|
171
|
+
this._hostIntent = null;
|
|
139
172
|
this._sourceStates = new Map();
|
|
140
173
|
this._loadedRanges = new Set();
|
|
141
174
|
this._loadController = null;
|
|
@@ -158,8 +191,14 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
158
191
|
this._paintedPreview = false;
|
|
159
192
|
/** @type {Map<string, DateState>} States of the current rendered grid. */
|
|
160
193
|
this._renderedStates = new Map();
|
|
161
|
-
|
|
162
|
-
this.
|
|
194
|
+
/** @type {typeof import("./messages.js").DEFAULT_MESSAGES | null} */
|
|
195
|
+
this._messages = null;
|
|
196
|
+
/** @type {Partial<import("./control-classes.js").ControlClasses> | null} */
|
|
197
|
+
this._controlClasses = null;
|
|
198
|
+
/** @type {(() => void) | null} */
|
|
199
|
+
this._stopDefaultMessages = null;
|
|
200
|
+
/** @type {(() => void) | null} */
|
|
201
|
+
this._stopDefaultControlClasses = null;
|
|
163
202
|
this._onClick = this._onClick.bind(this);
|
|
164
203
|
this._onChange = this._onChange.bind(this);
|
|
165
204
|
this._onKeyDown = this._onKeyDown.bind(this);
|
|
@@ -168,16 +207,46 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
168
207
|
|
|
169
208
|
connectedCallback() {
|
|
170
209
|
if (this._connected) return;
|
|
210
|
+
upgradeProperties(this, [
|
|
211
|
+
"locale",
|
|
212
|
+
"min",
|
|
213
|
+
"max",
|
|
214
|
+
"firstDay",
|
|
215
|
+
"selection",
|
|
216
|
+
"monthFormat",
|
|
217
|
+
"fixedWeeks",
|
|
218
|
+
"showWeekNumbers",
|
|
219
|
+
"controlClasses",
|
|
220
|
+
"messages",
|
|
221
|
+
"source",
|
|
222
|
+
"dateState",
|
|
223
|
+
"renderDay",
|
|
224
|
+
"isDateDisabled",
|
|
225
|
+
"highlightedRange",
|
|
226
|
+
"value",
|
|
227
|
+
"display",
|
|
228
|
+
]);
|
|
229
|
+
this._syncModel();
|
|
230
|
+
upgradeProperties(this, ["focusedDate"]);
|
|
231
|
+
this._stopDefaultControlClasses = subscribeDefaultControlClasses(() => {
|
|
232
|
+
if (usesDefaultControlClasses(this._controlClasses)) this.render();
|
|
233
|
+
});
|
|
234
|
+
this._stopDefaultMessages = subscribeDefaultMessages(() => {
|
|
235
|
+
if (this._messages === null) this.render();
|
|
236
|
+
});
|
|
171
237
|
this._connected = true;
|
|
172
238
|
this.addEventListener("click", this._onClick);
|
|
173
239
|
this.addEventListener("change", this._onChange);
|
|
174
240
|
this.addEventListener("keydown", this._onKeyDown);
|
|
175
241
|
this.addEventListener("focusin", this._onFocusIn);
|
|
176
|
-
this._syncModel();
|
|
177
242
|
this.render();
|
|
178
243
|
}
|
|
179
244
|
|
|
180
245
|
disconnectedCallback() {
|
|
246
|
+
this._stopDefaultControlClasses?.();
|
|
247
|
+
this._stopDefaultControlClasses = null;
|
|
248
|
+
this._stopDefaultMessages?.();
|
|
249
|
+
this._stopDefaultMessages = null;
|
|
181
250
|
this._connected = false;
|
|
182
251
|
this._loadController?.abort();
|
|
183
252
|
this._loadController = null;
|
|
@@ -328,29 +397,30 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
328
397
|
}
|
|
329
398
|
|
|
330
399
|
/**
|
|
331
|
-
* Author classes for header controls;
|
|
400
|
+
* Author classes for header controls; omitted roles follow current global defaults.
|
|
332
401
|
* @public
|
|
333
402
|
* @returns {import("./control-classes.js").ControlClasses}
|
|
334
403
|
*/
|
|
335
404
|
get controlClasses() {
|
|
336
|
-
return
|
|
405
|
+
return resolveControlClasses(this._controlClasses);
|
|
337
406
|
}
|
|
338
407
|
|
|
339
408
|
/** @param {Partial<import("./control-classes.js").ControlClasses> | null} value */
|
|
340
409
|
set controlClasses(value) {
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
this.
|
|
410
|
+
const previous = this.controlClasses;
|
|
411
|
+
this._controlClasses = normalizeControlClasses(value);
|
|
412
|
+
if (sameControlClasses(previous, this.controlClasses)) return;
|
|
344
413
|
if (this._connected) this.render();
|
|
345
414
|
}
|
|
346
415
|
|
|
347
|
-
/** @public */
|
|
416
|
+
/** @public @returns {typeof import("./messages.js").DEFAULT_MESSAGES} */
|
|
348
417
|
get messages() {
|
|
349
|
-
return this._messages;
|
|
418
|
+
return this._messages ?? getDefaultMessages();
|
|
350
419
|
}
|
|
351
420
|
|
|
421
|
+
/** @param {Partial<typeof import("./messages.js").DEFAULT_MESSAGES> | null} value */
|
|
352
422
|
set messages(value) {
|
|
353
|
-
this._messages = { ...getDefaultMessages(), ...
|
|
423
|
+
this._messages = value == null ? null : { ...getDefaultMessages(), ...value };
|
|
354
424
|
if (this._connected) this.render();
|
|
355
425
|
}
|
|
356
426
|
|
|
@@ -471,7 +541,7 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
471
541
|
return { start: first[0], end: last[6] };
|
|
472
542
|
}
|
|
473
543
|
|
|
474
|
-
/** @public @param {string} date */
|
|
544
|
+
/** @public @param {string} date @returns {DateState & {disabled: boolean}} */
|
|
475
545
|
getDateState(date) {
|
|
476
546
|
const fromSource = this._sourceStates.get(date) || {};
|
|
477
547
|
const local = this._dateState?.(date, { ...fromSource }) || {};
|
|
@@ -615,6 +685,16 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
615
685
|
}
|
|
616
686
|
}
|
|
617
687
|
|
|
688
|
+
/** Leave exactly one roving tab stop, on `date`'s cell when rendered.
|
|
689
|
+
* @param {string} date */
|
|
690
|
+
_syncRovingDom(date) {
|
|
691
|
+
for (const cell of this.querySelectorAll('.dp-day[tabindex="0"]')) {
|
|
692
|
+
if (cell instanceof HTMLElement && cell.dataset.date !== date) cell.tabIndex = -1;
|
|
693
|
+
}
|
|
694
|
+
const cell = this.querySelector(`.dp-day[data-date="${CSS.escape(date)}"]`);
|
|
695
|
+
if (cell instanceof HTMLElement) cell.tabIndex = 0;
|
|
696
|
+
}
|
|
697
|
+
|
|
618
698
|
/** @param {string} previousValue @param {string} nextValue */
|
|
619
699
|
_moveSelectionDom(previousValue, nextValue) {
|
|
620
700
|
if (previousValue) {
|
|
@@ -648,8 +728,8 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
648
728
|
return [
|
|
649
729
|
formatLongDate(date, this.locale),
|
|
650
730
|
description,
|
|
651
|
-
rangeLabel ? this.
|
|
652
|
-
state.disabled ? this.
|
|
731
|
+
rangeLabel ? this.messages[rangeLabel] : "",
|
|
732
|
+
state.disabled ? this.messages.unavailable : "",
|
|
653
733
|
]
|
|
654
734
|
.filter(Boolean)
|
|
655
735
|
.join(". ");
|
|
@@ -701,21 +781,30 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
701
781
|
* @param {string} date @returns {Promise<boolean>}
|
|
702
782
|
*/
|
|
703
783
|
async activateDate(date) {
|
|
784
|
+
const hostIntent = this._hostIntent?.date === date ? this._hostIntent.intent : undefined;
|
|
785
|
+
this._hostIntent = null;
|
|
786
|
+
/** @param {Event} event */
|
|
787
|
+
const tagged = (event) => {
|
|
788
|
+
if (hostIntent !== undefined) activationIntents.set(event, hostIntent);
|
|
789
|
+
return event;
|
|
790
|
+
};
|
|
704
791
|
// Guarantee remote state before deciding: a date clicked before the
|
|
705
792
|
// source resolves must not be treated as available, and a cancelled or
|
|
706
793
|
// failed load must not authorize it either.
|
|
707
794
|
const confirmed = await this.ensureDate(date);
|
|
708
795
|
const state = this.getDateState(date);
|
|
709
796
|
if (!confirmed || state.disabled) {
|
|
710
|
-
this.dispatchEvent(new CustomEvent("dateinvalid", { detail: { date, state }, bubbles: true }));
|
|
797
|
+
this.dispatchEvent(tagged(new CustomEvent("dateinvalid", { detail: { date, state }, bubbles: true })));
|
|
711
798
|
return false;
|
|
712
799
|
}
|
|
713
800
|
const accepted = this.dispatchEvent(
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
801
|
+
tagged(
|
|
802
|
+
new CustomEvent("dateactivate", {
|
|
803
|
+
detail: { date, state },
|
|
804
|
+
bubbles: true,
|
|
805
|
+
cancelable: true,
|
|
806
|
+
}),
|
|
807
|
+
),
|
|
719
808
|
);
|
|
720
809
|
if (!accepted) return false;
|
|
721
810
|
if (this.selection === "single") {
|
|
@@ -754,6 +843,8 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
754
843
|
this._model.setFocused(this._clamp(date));
|
|
755
844
|
this._reflect("display", this._model.display);
|
|
756
845
|
if (previousDisplay !== this.display) this._emitDisplayChange();
|
|
846
|
+
// Engines that do not focus a clicked cell still need the tab stop moved.
|
|
847
|
+
else this._syncRovingDom(this._model.focused);
|
|
757
848
|
void this.activateDate(date);
|
|
758
849
|
}
|
|
759
850
|
|
|
@@ -766,9 +857,8 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
766
857
|
}
|
|
767
858
|
if (target instanceof HTMLInputElement && target.matches(".dp-year-input")) {
|
|
768
859
|
const year = Number(target.value);
|
|
769
|
-
// 9999
|
|
770
|
-
|
|
771
|
-
if (!Number.isInteger(year) || year < 1 || year > 9998) {
|
|
860
|
+
// 9999-12 overflows into 10000, but _setDisplay() clamps it to 9999-11.
|
|
861
|
+
if (!Number.isInteger(year) || year < 1 || year > 9999) {
|
|
772
862
|
if (this._connected) this.render(false);
|
|
773
863
|
return;
|
|
774
864
|
}
|
|
@@ -789,6 +879,8 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
789
879
|
const date = target.dataset.date || "";
|
|
790
880
|
if (!isDate(date)) return;
|
|
791
881
|
this._model.focused = date;
|
|
882
|
+
// A pointer focuses the cell directly; keep exactly one tab stop on it.
|
|
883
|
+
this._syncRovingDom(date);
|
|
792
884
|
this.dispatchEvent(
|
|
793
885
|
new CustomEvent("datefocus", { detail: { date, state: this.getDateState(date) }, bubbles: true }),
|
|
794
886
|
);
|
|
@@ -849,11 +941,11 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
849
941
|
const nextKey = stepMonthKey(display, 1);
|
|
850
942
|
const prevDisabled = Boolean(minMonth && prevKey !== null && prevKey < minMonth);
|
|
851
943
|
const nextDisabled = Boolean(maxMonth && nextKey !== null && nextKey > maxMonth);
|
|
852
|
-
const minYearAttr =
|
|
853
|
-
const maxYearAttr =
|
|
944
|
+
const minYearAttr = ` min="${this.min ? Number(this.min.slice(0, 4)) : 1}"`;
|
|
945
|
+
const maxYearAttr = ` max="${this.max ? Number(this.max.slice(0, 4)) : 9999}"`;
|
|
854
946
|
const showWeeks = this.showWeekNumbers && this.firstDay === 1;
|
|
855
947
|
const weekHeader = showWeeks
|
|
856
|
-
? `<th scope="col" class="dp-week-heading" abbr="${escapeHtml(this.
|
|
948
|
+
? `<th scope="col" class="dp-week-heading" abbr="${escapeHtml(this.messages.week)}">#</th>`
|
|
857
949
|
: "";
|
|
858
950
|
|
|
859
951
|
const monthOptions = names
|
|
@@ -906,14 +998,14 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
906
998
|
// select via `data-year-first`.
|
|
907
999
|
const yearFirst = monthYearOrder(locale)[0] === "year";
|
|
908
1000
|
this.toggleAttribute("data-year-first", yearFirst);
|
|
909
|
-
const classes = this.
|
|
1001
|
+
const classes = this.controlClasses;
|
|
910
1002
|
const monthClass = escapeHtml(classes.month || "dp-skin");
|
|
911
1003
|
const yearClass = escapeHtml(classes.year || "dp-skin");
|
|
912
1004
|
const navClass = escapeHtml(classes.nav || "dp-skin");
|
|
913
|
-
const monthControl = `<label class="dp-visually-hidden" for="${this._id}-month">${escapeHtml(this.
|
|
914
|
-
<select id="${this._id}-month" class="dp-month-select ${monthClass}" aria-label="${escapeHtml(this.
|
|
915
|
-
const yearControl = `<label class="dp-visually-hidden" for="${this._id}-year">${escapeHtml(this.
|
|
916
|
-
<input id="${this._id}-year" class="dp-year-input ${yearClass}" type="number" inputmode="numeric" value="${displayYear}"${minYearAttr}${maxYearAttr} aria-label="${escapeHtml(this.
|
|
1005
|
+
const monthControl = `<label class="dp-visually-hidden" for="${this._id}-month">${escapeHtml(this.messages.month)}</label>
|
|
1006
|
+
<select id="${this._id}-month" class="dp-month-select ${monthClass}" aria-label="${escapeHtml(this.messages.month)}">${monthOptions}</select>`;
|
|
1007
|
+
const yearControl = `<label class="dp-visually-hidden" for="${this._id}-year">${escapeHtml(this.messages.year)}</label>
|
|
1008
|
+
<input id="${this._id}-year" class="dp-year-input ${yearClass}" type="number" inputmode="numeric" value="${displayYear}"${minYearAttr}${maxYearAttr} aria-label="${escapeHtml(this.messages.year)}">`;
|
|
917
1009
|
|
|
918
1010
|
this._rendering = true;
|
|
919
1011
|
this.innerHTML = `
|
|
@@ -921,8 +1013,8 @@ export class DateCalendarElement extends HTMLElement {
|
|
|
921
1013
|
<div class="dp-calendar-header">
|
|
922
1014
|
${yearFirst ? yearControl : monthControl}
|
|
923
1015
|
${yearFirst ? monthControl : yearControl}
|
|
924
|
-
<button type="button" class="dp-nav dp-prev ${navClass}" data-calendar-action="previous" aria-label="${escapeHtml(this.
|
|
925
|
-
<button type="button" class="dp-nav dp-next ${navClass}" data-calendar-action="next" aria-label="${escapeHtml(this.
|
|
1016
|
+
<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>
|
|
1017
|
+
<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>
|
|
926
1018
|
</div>
|
|
927
1019
|
<h2 id="${headingId}" class="dp-calendar-heading dp-visually-hidden" aria-live="polite">${escapeHtml(formatMonthYear(`${display}-15`, locale))}</h2>
|
|
928
1020
|
<table id="${gridId}" class="dp-grid" role="grid" aria-labelledby="${headingId}">
|
package/src/date-field.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { isDate } from "./date.js";
|
|
2
2
|
import { createDateAdapter } from "./intl.js";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Whether the user may edit this input right now. `:disabled` is the effective
|
|
6
|
+
* state: the `disabled` property misses a disabled ancestor `<fieldset>`.
|
|
7
|
+
* @param {HTMLInputElement} input
|
|
8
|
+
*/
|
|
9
|
+
export function isEditable(input) {
|
|
10
|
+
return !input.matches(":disabled") && !input.readOnly;
|
|
11
|
+
}
|
|
12
|
+
|
|
4
13
|
/**
|
|
5
14
|
* Owns a single editable form field inside a picker: the visible input, its
|
|
6
15
|
* hidden canonical ISO field, the Intl adapter and the text commit pipeline
|
|
@@ -38,11 +47,33 @@ export class DateFieldController {
|
|
|
38
47
|
* @type {((date: string, options?: {moveDisplay?: boolean}) => Promise<{ok: boolean, message?: string}>) | null}
|
|
39
48
|
*/
|
|
40
49
|
this.confirm = null;
|
|
50
|
+
/** Canonical value behind a `defaultValue` the enhancement generated, or null. @type {string | null} */
|
|
51
|
+
this._generatedDefault = null;
|
|
41
52
|
}
|
|
42
53
|
|
|
43
54
|
/** @param {string} locale */
|
|
44
55
|
setLocale(locale) {
|
|
56
|
+
const generated = this._generatedDefault;
|
|
57
|
+
const previous = generated ? this.adapter.format(generated) : null;
|
|
45
58
|
this.adapter = createDateAdapter(locale || "");
|
|
59
|
+
// A generated default is localized text: reformat it so a later form reset
|
|
60
|
+
// never parses the old locale's text with the new adapter. An app-changed
|
|
61
|
+
// default no longer matches and stays untouched.
|
|
62
|
+
if (generated && this.input.defaultValue === previous) {
|
|
63
|
+
this.input.defaultValue = this.adapter.format(generated);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Make the current text the reset default when the author provided none.
|
|
69
|
+
* Never redefine an author-provided `input.defaultValue`: the next reset must
|
|
70
|
+
* use the native default (which the app may change).
|
|
71
|
+
*/
|
|
72
|
+
adoptDefault() {
|
|
73
|
+
const input = this.input;
|
|
74
|
+
if (input.getAttribute("value") != null || input.defaultValue !== "") return;
|
|
75
|
+
input.defaultValue = input.value;
|
|
76
|
+
this._generatedDefault = this.canonical && input.value ? this.canonical : null;
|
|
46
77
|
}
|
|
47
78
|
|
|
48
79
|
/** @param {Record<string, string>} messages */
|
|
@@ -65,7 +96,7 @@ export class DateFieldController {
|
|
|
65
96
|
}
|
|
66
97
|
|
|
67
98
|
get isDisabled() {
|
|
68
|
-
return this.input.disabled;
|
|
99
|
+
return this.input.matches(":disabled");
|
|
69
100
|
}
|
|
70
101
|
|
|
71
102
|
get isReadOnly() {
|