tyrell-components 1.0.0-TC56 → 1.0.0-TC58
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/css/tyrell.css +3 -3
- package/dist/tyrell.js +1 -1
- package/dist/tyrell.js.map +1 -0
- package/lib/base/ty-component.d.ts +15 -3
- package/lib/base/ty-component.js +26 -18
- package/lib/components/button.d.ts +4 -0
- package/lib/components/button.js +33 -6
- package/lib/components/calendar-month.js +3 -10
- package/lib/components/calendar.d.ts +5 -1
- package/lib/components/calendar.js +28 -34
- package/lib/components/checkbox.d.ts +3 -1
- package/lib/components/checkbox.js +9 -1
- package/lib/components/date-picker.d.ts +61 -7
- package/lib/components/date-picker.js +274 -133
- package/lib/components/file-upload.d.ts +4 -1
- package/lib/components/file-upload.js +17 -3
- package/lib/components/input.d.ts +82 -3
- package/lib/components/input.js +178 -20
- package/lib/components/modal.d.ts +2 -0
- package/lib/components/modal.js +49 -10
- package/lib/components/option.js +7 -5
- package/lib/components/popup.js +59 -10
- package/lib/components/radio.d.ts +4 -1
- package/lib/components/radio.js +10 -1
- package/lib/components/resize-observer.js +2 -0
- package/lib/components/scroll-container.js +2 -0
- package/lib/components/select.d.ts +34 -3
- package/lib/components/select.js +135 -11
- package/lib/components/selected-tags.d.ts +7 -1
- package/lib/components/selected-tags.js +10 -1
- package/lib/components/switch.d.ts +5 -1
- package/lib/components/switch.js +9 -1
- package/lib/components/textarea.d.ts +46 -2
- package/lib/components/textarea.js +60 -9
- package/lib/styles/button.js +20 -19
- package/lib/styles/date-picker.js +18 -1
- package/lib/styles/file-upload.d.ts +1 -1
- package/lib/styles/file-upload.js +3 -3
- package/lib/styles/icon.d.ts +1 -1
- package/lib/styles/icon.js +2 -2
- package/lib/styles/input.js +1 -1
- package/lib/styles/radio.js +2 -2
- package/lib/styles/select-base.js +26 -0
- package/lib/styles/textarea.d.ts +1 -1
- package/lib/styles/textarea.js +7 -0
- package/lib/utils/error-flavor.d.ts +8 -0
- package/lib/utils/error-flavor.js +1 -0
- package/lib/utils/property-manager.d.ts +6 -0
- package/lib/utils/property-manager.js +15 -5
- package/lib/utils/upgrade-properties.d.ts +21 -0
- package/lib/utils/upgrade-properties.js +47 -0
- package/lib/utils/validity.d.ts +72 -2
- package/lib/utils/validity.js +192 -8
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +3 -2
- package/lib/base/ty-component.d.ts.map +0 -1
- package/lib/base/ty-component.js.map +0 -1
- package/lib/components/button.d.ts.map +0 -1
- package/lib/components/button.js.map +0 -1
- package/lib/components/calendar-month.d.ts.map +0 -1
- package/lib/components/calendar-month.js.map +0 -1
- package/lib/components/calendar-navigation.d.ts.map +0 -1
- package/lib/components/calendar-navigation.js.map +0 -1
- package/lib/components/calendar.d.ts.map +0 -1
- package/lib/components/calendar.js.map +0 -1
- package/lib/components/checkbox.d.ts.map +0 -1
- package/lib/components/checkbox.js.map +0 -1
- package/lib/components/copy.d.ts.map +0 -1
- package/lib/components/copy.js.map +0 -1
- package/lib/components/date-picker.d.ts.map +0 -1
- package/lib/components/date-picker.js.map +0 -1
- package/lib/components/dropdown.d.ts +0 -403
- package/lib/components/dropdown.d.ts.map +0 -1
- package/lib/components/dropdown.js +0 -1315
- package/lib/components/dropdown.js.map +0 -1
- package/lib/components/icon.d.ts.map +0 -1
- package/lib/components/icon.js.map +0 -1
- package/lib/components/input.d.ts.map +0 -1
- package/lib/components/input.js.map +0 -1
- package/lib/components/modal.d.ts.map +0 -1
- package/lib/components/modal.js.map +0 -1
- package/lib/components/multiselect.d.ts +0 -389
- package/lib/components/multiselect.d.ts.map +0 -1
- package/lib/components/multiselect.js +0 -1301
- package/lib/components/multiselect.js.map +0 -1
- package/lib/components/option.d.ts.map +0 -1
- package/lib/components/option.js.map +0 -1
- package/lib/components/popup.d.ts.map +0 -1
- package/lib/components/popup.js.map +0 -1
- package/lib/components/resize-observer.d.ts.map +0 -1
- package/lib/components/resize-observer.js.map +0 -1
- package/lib/components/scroll-container.d.ts.map +0 -1
- package/lib/components/scroll-container.js.map +0 -1
- package/lib/components/step.d.ts.map +0 -1
- package/lib/components/step.js.map +0 -1
- package/lib/components/tab.d.ts.map +0 -1
- package/lib/components/tab.js.map +0 -1
- package/lib/components/tabs.d.ts.map +0 -1
- package/lib/components/tabs.js.map +0 -1
- package/lib/components/tag.d.ts.map +0 -1
- package/lib/components/tag.js.map +0 -1
- package/lib/components/textarea.d.ts.map +0 -1
- package/lib/components/textarea.js.map +0 -1
- package/lib/components/tooltip.d.ts.map +0 -1
- package/lib/components/tooltip.js.map +0 -1
- package/lib/components/wizard.d.ts.map +0 -1
- package/lib/components/wizard.js.map +0 -1
- package/lib/icons/fontawesome/brands.d.ts.map +0 -1
- package/lib/icons/fontawesome/brands.js.map +0 -1
- package/lib/icons/fontawesome/regular.d.ts.map +0 -1
- package/lib/icons/fontawesome/regular.js.map +0 -1
- package/lib/icons/fontawesome/solid.d.ts.map +0 -1
- package/lib/icons/fontawesome/solid.js.map +0 -1
- package/lib/icons/heroicons/micro.d.ts.map +0 -1
- package/lib/icons/heroicons/micro.js.map +0 -1
- package/lib/icons/heroicons/mini.d.ts.map +0 -1
- package/lib/icons/heroicons/mini.js.map +0 -1
- package/lib/icons/heroicons/outline.d.ts.map +0 -1
- package/lib/icons/heroicons/outline.js.map +0 -1
- package/lib/icons/heroicons/solid.d.ts.map +0 -1
- package/lib/icons/heroicons/solid.js.map +0 -1
- package/lib/icons/lucide.d.ts.map +0 -1
- package/lib/icons/lucide.js.map +0 -1
- package/lib/icons/material/filled.d.ts.map +0 -1
- package/lib/icons/material/filled.js.map +0 -1
- package/lib/icons/material/outlined.d.ts.map +0 -1
- package/lib/icons/material/outlined.js.map +0 -1
- package/lib/icons/material/round.d.ts.map +0 -1
- package/lib/icons/material/round.js.map +0 -1
- package/lib/icons/material/sharp.d.ts.map +0 -1
- package/lib/icons/material/sharp.js.map +0 -1
- package/lib/icons/material/two-tone.d.ts.map +0 -1
- package/lib/icons/material/two-tone.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/styles/button.d.ts.map +0 -1
- package/lib/styles/button.js.map +0 -1
- package/lib/styles/calendar-month.d.ts.map +0 -1
- package/lib/styles/calendar-month.js.map +0 -1
- package/lib/styles/calendar-navigation.d.ts.map +0 -1
- package/lib/styles/calendar-navigation.js.map +0 -1
- package/lib/styles/calendar.d.ts.map +0 -1
- package/lib/styles/calendar.js.map +0 -1
- package/lib/styles/copy.d.ts.map +0 -1
- package/lib/styles/copy.js.map +0 -1
- package/lib/styles/date-picker.d.ts.map +0 -1
- package/lib/styles/date-picker.js.map +0 -1
- package/lib/styles/dropdown.d.ts +0 -12
- package/lib/styles/dropdown.d.ts.map +0 -1
- package/lib/styles/dropdown.js +0 -725
- package/lib/styles/dropdown.js.map +0 -1
- package/lib/styles/icon.d.ts.map +0 -1
- package/lib/styles/icon.js.map +0 -1
- package/lib/styles/input.d.ts.map +0 -1
- package/lib/styles/input.js.map +0 -1
- package/lib/styles/modal.d.ts.map +0 -1
- package/lib/styles/modal.js.map +0 -1
- package/lib/styles/multiselect.d.ts +0 -6
- package/lib/styles/multiselect.d.ts.map +0 -1
- package/lib/styles/multiselect.js +0 -568
- package/lib/styles/multiselect.js.map +0 -1
- package/lib/styles/option.d.ts.map +0 -1
- package/lib/styles/option.js.map +0 -1
- package/lib/styles/popup.d.ts.map +0 -1
- package/lib/styles/popup.js.map +0 -1
- package/lib/styles/resize-observer.d.ts.map +0 -1
- package/lib/styles/resize-observer.js.map +0 -1
- package/lib/styles/scroll-container.d.ts.map +0 -1
- package/lib/styles/scroll-container.js.map +0 -1
- package/lib/styles/step.d.ts.map +0 -1
- package/lib/styles/step.js.map +0 -1
- package/lib/styles/tab.d.ts.map +0 -1
- package/lib/styles/tab.js.map +0 -1
- package/lib/styles/tabs.d.ts.map +0 -1
- package/lib/styles/tabs.js.map +0 -1
- package/lib/styles/tag.d.ts.map +0 -1
- package/lib/styles/tag.js.map +0 -1
- package/lib/styles/textarea.d.ts.map +0 -1
- package/lib/styles/textarea.js.map +0 -1
- package/lib/styles/tooltip.d.ts.map +0 -1
- package/lib/styles/tooltip.js.map +0 -1
- package/lib/styles/wizard.d.ts.map +0 -1
- package/lib/styles/wizard.js.map +0 -1
- package/lib/types/common.d.ts.map +0 -1
- package/lib/types/common.js.map +0 -1
- package/lib/utils/calendar-utils.d.ts.map +0 -1
- package/lib/utils/calendar-utils.js.map +0 -1
- package/lib/utils/icon-registry.d.ts.map +0 -1
- package/lib/utils/icon-registry.js.map +0 -1
- package/lib/utils/locale.d.ts.map +0 -1
- package/lib/utils/locale.js.map +0 -1
- package/lib/utils/number-format.d.ts.map +0 -1
- package/lib/utils/number-format.js.map +0 -1
- package/lib/utils/parse-boolean.d.ts +0 -39
- package/lib/utils/parse-boolean.d.ts.map +0 -1
- package/lib/utils/parse-boolean.js +0 -23
- package/lib/utils/parse-boolean.js.map +0 -1
- package/lib/utils/positioning.d.ts.map +0 -1
- package/lib/utils/positioning.js.map +0 -1
- package/lib/utils/property-capture.d.ts.map +0 -1
- package/lib/utils/property-capture.js.map +0 -1
- package/lib/utils/property-manager.d.ts.map +0 -1
- package/lib/utils/property-manager.js.map +0 -1
- package/lib/utils/resize-observer.d.ts.map +0 -1
- package/lib/utils/resize-observer.js.map +0 -1
- package/lib/utils/scroll-lock.d.ts.map +0 -1
- package/lib/utils/scroll-lock.js.map +0 -1
- package/lib/utils/styles.d.ts.map +0 -1
- package/lib/utils/styles.js.map +0 -1
- package/lib/version.d.ts.map +0 -1
- package/lib/version.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ensureStyles } from '../utils/styles.js';
|
|
2
2
|
import { syncCustomFlavorSheet } from '../utils/flavor-sheet.js';
|
|
3
|
+
import { ERROR_FLAVOR } from '../utils/error-flavor.js';
|
|
3
4
|
import { datePickerStyles, datePickerCustomFlavorCss } from '../styles/date-picker.js';
|
|
4
5
|
import { lockScroll, unlockScroll } from '../utils/scroll-lock.js';
|
|
5
6
|
import { computeAnchoredPosition, placementToAnchored } from '../utils/positioning.js';
|
|
@@ -7,6 +8,7 @@ import { getEffectiveLocale, observeLocaleChanges } from '../utils/locale.js';
|
|
|
7
8
|
import { isMobileTouch } from '../utils/mobile.js';
|
|
8
9
|
import { TyComponent } from '../base/ty-component.js';
|
|
9
10
|
import { DEFAULT_SIZE } from '../types/common.js';
|
|
11
|
+
import { nativeMessage } from '../utils/validity.js';
|
|
10
12
|
const CALENDAR_ICON_SVG = `<svg stroke='currentColor' fill='none' stroke-width='2' viewBox='0 0 24 24' width='16' height='16' xmlns='http://www.w3.org/2000/svg'><rect x='3' y='4' width='18' height='18' rx='2' ry='2'></rect><line x1='16' y1='2' x2='16' y2='6'></line><line x1='8' y1='2' x2='8' y2='6'></line><line x1='3' y1='10' x2='21' y2='10'></line></svg>`;
|
|
11
13
|
const CLEAR_ICON_SVG = `<svg stroke='currentColor' fill='none' stroke-width='2' viewBox='0 0 24 24' width='14' height='14' xmlns='http://www.w3.org/2000/svg'><line x1='18' y1='6' x2='6' y2='18'></line><line x1='6' y1='6' x2='18' y2='18'></line></svg>`;
|
|
12
14
|
const SCHEDULE_ICON_SVG = `<svg stroke='currentColor' fill='none' stroke-width='2' viewBox='0 0 24 24' width='16' height='16' xmlns='http://www.w3.org/2000/svg'><circle cx='12' cy='12' r='10'></circle><polyline points='12,6 12,12 16,14'></polyline></svg>`;
|
|
@@ -20,48 +22,63 @@ elementIds.set(element, id);
|
|
|
20
22
|
}
|
|
21
23
|
return id;
|
|
22
24
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
const LOCAL_VALUE = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?)?$/;
|
|
26
|
+
function wallClockDate(c) {
|
|
27
|
+
const date = new Date(0);
|
|
28
|
+
date.setUTCFullYear(c.year, c.month - 1, c.day);
|
|
29
|
+
date.setUTCHours(c.hour || 0, c.minute || 0, c.second || 0);
|
|
30
|
+
return date;
|
|
31
|
+
}
|
|
32
|
+
function parseValue(value) {
|
|
33
|
+
if (value === null || value === undefined || value === '')
|
|
25
34
|
return null;
|
|
26
|
-
let dateObj = null;
|
|
27
35
|
if (typeof value === 'string') {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const year =
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
dateObj = new Date(value);
|
|
37
|
-
}
|
|
36
|
+
const local = LOCAL_VALUE.exec(value);
|
|
37
|
+
if (local) {
|
|
38
|
+
const [year, month, day, hour, minute, second] = local.slice(1, 7).map((g) => Number(g ?? 0));
|
|
39
|
+
const components = { year, month, day, hour, minute, second };
|
|
40
|
+
const check = wallClockDate(components);
|
|
41
|
+
const real = check.getUTCMonth() === month - 1 && check.getUTCDate() === day &&
|
|
42
|
+
hour < 24 && minute < 60 && second < 60;
|
|
43
|
+
return real ? components : null;
|
|
38
44
|
}
|
|
39
|
-
else if (typeof value === 'number') {
|
|
40
|
-
dateObj = new Date(value);
|
|
41
45
|
}
|
|
46
|
+
const dateObj = typeof value === 'number' || typeof value === 'string' ? new Date(value) : null;
|
|
42
47
|
if (!dateObj || isNaN(dateObj.getTime())) {
|
|
43
48
|
return null;
|
|
44
49
|
}
|
|
45
|
-
|
|
50
|
+
return {
|
|
46
51
|
year: dateObj.getFullYear(),
|
|
47
52
|
month: dateObj.getMonth() + 1,
|
|
48
53
|
day: dateObj.getDate(),
|
|
49
|
-
hour:
|
|
50
|
-
minute:
|
|
54
|
+
hour: dateObj.getHours(),
|
|
55
|
+
minute: dateObj.getMinutes(),
|
|
56
|
+
second: dateObj.getSeconds(),
|
|
57
|
+
epoch: dateObj.getTime(),
|
|
51
58
|
};
|
|
52
|
-
return components;
|
|
53
59
|
}
|
|
54
60
|
function componentsToDateObject(components) {
|
|
55
|
-
const { year, month, day, hour, minute } = components;
|
|
61
|
+
const { year, month, day, hour, minute, second } = components;
|
|
56
62
|
if (!year || !month || !day)
|
|
57
63
|
return null;
|
|
58
|
-
|
|
64
|
+
const date = new Date(2000, 0, 1, 12);
|
|
65
|
+
date.setFullYear(year, month - 1, day);
|
|
66
|
+
date.setHours(hour || 0, minute || 0, second || 0, 0);
|
|
67
|
+
return date;
|
|
68
|
+
}
|
|
69
|
+
function effectiveComponents(components, withTime) {
|
|
70
|
+
return withTime ? components : { ...components, hour: 0, minute: 0, second: 0, epoch: undefined };
|
|
59
71
|
}
|
|
60
|
-
function componentsToOutputValue(components) {
|
|
72
|
+
function componentsToOutputValue(components, withTime, native) {
|
|
61
73
|
if (!components.year || !components.month || !components.day) {
|
|
62
74
|
return null;
|
|
63
75
|
}
|
|
64
|
-
const
|
|
76
|
+
const c = effectiveComponents(components, withTime);
|
|
77
|
+
if (native)
|
|
78
|
+
return componentsToLocalValue(c, withTime);
|
|
79
|
+
if (c.epoch !== undefined)
|
|
80
|
+
return new Date(c.epoch).toISOString();
|
|
81
|
+
const dateObj = componentsToDateObject(c);
|
|
65
82
|
return dateObj ? dateObj.toISOString() : null;
|
|
66
83
|
}
|
|
67
84
|
function componentsToLocalValue(components, withTime) {
|
|
@@ -74,27 +91,34 @@ const day = components.day.toString().padStart(2, '0');
|
|
|
74
91
|
if (withTime) {
|
|
75
92
|
const hour = (components.hour || 0).toString().padStart(2, '0');
|
|
76
93
|
const minute = (components.minute || 0).toString().padStart(2, '0');
|
|
77
|
-
|
|
94
|
+
const second = components.second ? `:${components.second.toString().padStart(2, '0')}` : '';
|
|
95
|
+
return `${year}-${month}-${day}T${hour}:${minute}${second}`;
|
|
78
96
|
}
|
|
79
97
|
else {
|
|
80
98
|
return `${year}-${month}-${day}`;
|
|
81
99
|
}
|
|
82
100
|
}
|
|
83
|
-
function
|
|
101
|
+
function displayDate(components, native) {
|
|
102
|
+
return native
|
|
103
|
+
? { date: wallClockDate(components), timeZone: 'UTC' }
|
|
104
|
+
: { date: componentsToDateObject(components) };
|
|
105
|
+
}
|
|
106
|
+
function formatDisplayValue(components, formatType, locale, withTime, native) {
|
|
84
107
|
if (!components.year || !components.month || !components.day) {
|
|
85
108
|
return null;
|
|
86
109
|
}
|
|
87
|
-
const
|
|
88
|
-
if (!
|
|
110
|
+
const { date, timeZone } = displayDate(components, native);
|
|
111
|
+
if (!date)
|
|
89
112
|
return null;
|
|
90
113
|
const options = {
|
|
91
114
|
dateStyle: formatType || 'long',
|
|
115
|
+
timeZone,
|
|
92
116
|
};
|
|
93
117
|
if (withTime) {
|
|
94
118
|
options.timeStyle = 'short';
|
|
95
119
|
}
|
|
96
120
|
const formatter = new Intl.DateTimeFormat(locale, options);
|
|
97
|
-
return formatter.format(
|
|
121
|
+
return formatter.format(date);
|
|
98
122
|
}
|
|
99
123
|
class TimeFields {
|
|
100
124
|
constructor(hourEl, minuteEl, onChange, hour = 0, minute = 0) {
|
|
@@ -213,14 +237,20 @@ withTime: false,
|
|
|
213
237
|
open: false,
|
|
214
238
|
};
|
|
215
239
|
this._closeTimestamp = 0;
|
|
240
|
+
this._initialized = false;
|
|
241
|
+
this._syncing = false;
|
|
216
242
|
this._customFlavorSheet = null;
|
|
217
243
|
const shadow = this.shadowRoot;
|
|
218
244
|
ensureStyles(shadow, { css: datePickerStyles, id: 'ty-date-picker' });
|
|
219
245
|
}
|
|
220
246
|
onConnect() {
|
|
247
|
+
if (this._initialized)
|
|
248
|
+
this._state.open = false;
|
|
249
|
+
else
|
|
221
250
|
this.initializeState();
|
|
251
|
+
this.syncErrorFlavor();
|
|
222
252
|
this.render();
|
|
223
|
-
this.
|
|
253
|
+
this.updateFormValue();
|
|
224
254
|
this._localeObserver = observeLocaleChanges(this, () => {
|
|
225
255
|
this.render();
|
|
226
256
|
});
|
|
@@ -241,6 +271,10 @@ onPropertiesChanged(changes) {
|
|
|
241
271
|
for (const { name, newValue } of changes) {
|
|
242
272
|
switch (name) {
|
|
243
273
|
case 'flavor':
|
|
274
|
+
if (newValue !== 'danger') {
|
|
275
|
+
this.removeAttribute(ERROR_FLAVOR);
|
|
276
|
+
this.syncErrorFlavor();
|
|
277
|
+
}
|
|
244
278
|
this._syncCustomFlavor();
|
|
245
279
|
break;
|
|
246
280
|
case 'size':
|
|
@@ -254,73 +288,69 @@ case 'noClear':
|
|
|
254
288
|
case 'format':
|
|
255
289
|
case 'locale':
|
|
256
290
|
break;
|
|
291
|
+
case 'error':
|
|
292
|
+
this.syncErrorFlavor();
|
|
293
|
+
break;
|
|
257
294
|
case 'value': {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const hasDate = this._state.year !== undefined ||
|
|
261
|
-
this._state.month !== undefined ||
|
|
262
|
-
this._state.day !== undefined;
|
|
263
|
-
if (hasDate) {
|
|
295
|
+
if (!this._initialized || this._syncing)
|
|
296
|
+
break;
|
|
264
297
|
this._state = {
|
|
265
298
|
withTime: this._state.withTime,
|
|
266
299
|
open: this._state.open,
|
|
300
|
+
...parseValue(newValue),
|
|
267
301
|
};
|
|
268
|
-
}
|
|
269
302
|
this.syncFormValue();
|
|
270
303
|
break;
|
|
271
304
|
}
|
|
272
|
-
const currentComponents = {
|
|
273
|
-
year: this._state.year,
|
|
274
|
-
month: this._state.month,
|
|
275
|
-
day: this._state.day,
|
|
276
|
-
hour: this._state.hour,
|
|
277
|
-
minute: this._state.minute,
|
|
278
|
-
};
|
|
279
|
-
const changed = newComponents?.year !== currentComponents.year ||
|
|
280
|
-
newComponents?.month !== currentComponents.month ||
|
|
281
|
-
newComponents?.day !== currentComponents.day ||
|
|
282
|
-
newComponents?.hour !== currentComponents.hour ||
|
|
283
|
-
newComponents?.minute !== currentComponents.minute;
|
|
284
|
-
if (changed) {
|
|
285
|
-
this._state = {
|
|
286
|
-
...this._state,
|
|
287
|
-
...newComponents,
|
|
288
|
-
};
|
|
289
|
-
this.syncFormValue();
|
|
290
|
-
}
|
|
291
|
-
break;
|
|
292
|
-
}
|
|
293
305
|
case 'with-time': {
|
|
306
|
+
if (!this._initialized)
|
|
307
|
+
break;
|
|
294
308
|
const newWithTime = newValue;
|
|
295
|
-
|
|
296
|
-
if (newWithTime !== oldWithTime) {
|
|
309
|
+
if (newWithTime !== this._state.withTime) {
|
|
297
310
|
this._state.withTime = newWithTime;
|
|
298
|
-
const hasDate = this._state.year !== undefined &&
|
|
299
|
-
this._state.month !== undefined &&
|
|
300
|
-
this._state.day !== undefined;
|
|
301
|
-
if (hasDate) {
|
|
302
311
|
this.syncFormValue();
|
|
303
|
-
|
|
312
|
+
this.updateValidity();
|
|
304
313
|
}
|
|
305
314
|
break;
|
|
306
315
|
}
|
|
316
|
+
case 'native':
|
|
317
|
+
if (this._initialized)
|
|
318
|
+
this.syncFormValue();
|
|
319
|
+
break;
|
|
307
320
|
}
|
|
308
321
|
}
|
|
309
322
|
}
|
|
310
323
|
getFormValue() {
|
|
311
|
-
return
|
|
324
|
+
return this.outputValue(this.getComponents());
|
|
325
|
+
}
|
|
326
|
+
outputValue(components) {
|
|
327
|
+
return componentsToOutputValue(components, this._state.withTime, !!this.getProperty('native'));
|
|
312
328
|
}
|
|
313
329
|
updateFormValue() {
|
|
314
|
-
|
|
330
|
+
this._internals.setFormValue(this.getFormValue() ?? '');
|
|
315
331
|
this.updateValidity();
|
|
316
332
|
}
|
|
333
|
+
focusTarget() {
|
|
334
|
+
return this.shadowRoot?.querySelector('.native-date-input')
|
|
335
|
+
?? this.shadowRoot?.querySelector('.date-picker-stub')
|
|
336
|
+
?? null;
|
|
337
|
+
}
|
|
338
|
+
focus(options) {
|
|
339
|
+
if (this.getProperty('disabled'))
|
|
340
|
+
return;
|
|
341
|
+
const target = this.focusTarget();
|
|
342
|
+
if (target)
|
|
343
|
+
target.focus(options);
|
|
344
|
+
else
|
|
345
|
+
super.focus(options);
|
|
346
|
+
}
|
|
317
347
|
updateValidity() {
|
|
318
348
|
if (this.getProperty('disabled') || !this.getProperty('required') || this.getFormValue()) {
|
|
319
349
|
this.applyValidity({});
|
|
320
350
|
return;
|
|
321
351
|
}
|
|
322
|
-
const
|
|
323
|
-
this.applyValidity({ valueMissing: true }, '
|
|
352
|
+
const type = this._state.withTime ? 'datetime-local' : 'date';
|
|
353
|
+
this.applyValidity({ valueMissing: true }, nativeMessage('input', { type, required: true }), this.focusTarget() ?? undefined);
|
|
324
354
|
}
|
|
325
355
|
getComponents() {
|
|
326
356
|
return {
|
|
@@ -329,6 +359,8 @@ month: this._state.month,
|
|
|
329
359
|
day: this._state.day,
|
|
330
360
|
hour: this._state.hour,
|
|
331
361
|
minute: this._state.minute,
|
|
362
|
+
second: this._state.second,
|
|
363
|
+
epoch: this._state.epoch,
|
|
332
364
|
};
|
|
333
365
|
}
|
|
334
366
|
hasDate() {
|
|
@@ -338,25 +370,15 @@ getFormattedValue(components) {
|
|
|
338
370
|
const c = components || this.getComponents();
|
|
339
371
|
if (!c.year || !c.month || !c.day)
|
|
340
372
|
return null;
|
|
341
|
-
return formatDisplayValue(c, this.getProperty('format') || 'long', getEffectiveLocale(this, this.getProperty('locale')), this._state.withTime);
|
|
373
|
+
return formatDisplayValue(c, this.getProperty('format') || 'long', getEffectiveLocale(this, this.getProperty('locale')), this._state.withTime, !!this.getProperty('native'));
|
|
342
374
|
}
|
|
343
375
|
initializeState() {
|
|
344
|
-
const valueAttr = this.getProperty('value');
|
|
345
|
-
const withTime = this.getProperty('with-time');
|
|
346
|
-
const components = parseValue(valueAttr, withTime);
|
|
347
|
-
if (components === null) {
|
|
348
|
-
this._state = {
|
|
349
|
-
withTime,
|
|
350
|
-
open: false,
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
376
|
this._state = {
|
|
355
|
-
...
|
|
356
|
-
withTime,
|
|
377
|
+
...parseValue(this.getProperty('value')),
|
|
378
|
+
withTime: this.getProperty('with-time'),
|
|
357
379
|
open: false,
|
|
358
380
|
};
|
|
359
|
-
|
|
381
|
+
this._initialized = true;
|
|
360
382
|
this.syncFormValue();
|
|
361
383
|
}
|
|
362
384
|
updateState(updates, forceSync = false) {
|
|
@@ -367,24 +389,47 @@ this.syncFormValue();
|
|
|
367
389
|
}
|
|
368
390
|
}
|
|
369
391
|
syncFormValue() {
|
|
370
|
-
const
|
|
392
|
+
const formValue = this.getFormValue();
|
|
371
393
|
const currentValue = this.getProperty('value');
|
|
372
|
-
if (
|
|
373
|
-
|
|
374
|
-
|
|
394
|
+
if (formValue !== currentValue) {
|
|
395
|
+
this._syncing = true;
|
|
396
|
+
try {
|
|
397
|
+
this.setProperty('value', formValue || null);
|
|
375
398
|
}
|
|
376
|
-
|
|
377
|
-
this.
|
|
399
|
+
finally {
|
|
400
|
+
this._syncing = false;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
syncErrorFlavor() {
|
|
405
|
+
if (!this._connected)
|
|
406
|
+
return;
|
|
407
|
+
const flavor = this.getProperty('flavor');
|
|
408
|
+
const replaced = this.getAttribute(ERROR_FLAVOR);
|
|
409
|
+
if (this.getProperty('error')) {
|
|
410
|
+
if (replaced === null && (flavor === 'default' || flavor === 'neutral')) {
|
|
411
|
+
this.setAttribute(ERROR_FLAVOR, this.getAttribute('flavor') ?? '');
|
|
412
|
+
this.setProperty('flavor', 'danger');
|
|
378
413
|
}
|
|
379
414
|
}
|
|
415
|
+
else if (replaced !== null) {
|
|
416
|
+
this.removeAttribute(ERROR_FLAVOR);
|
|
417
|
+
if (flavor !== 'danger')
|
|
418
|
+
return;
|
|
419
|
+
if (!replaced)
|
|
420
|
+
this.removeAttribute('flavor');
|
|
421
|
+
else
|
|
422
|
+
this.setProperty('flavor', replaced);
|
|
423
|
+
}
|
|
380
424
|
}
|
|
381
425
|
handleTimeInputChange(hour, minute) {
|
|
382
426
|
if (!this.hasDate())
|
|
383
427
|
return;
|
|
384
|
-
const components = { ...this.getComponents(), hour, minute };
|
|
428
|
+
const components = { ...this.getComponents(), hour, minute, second: 0, epoch: undefined };
|
|
385
429
|
this.updateState(components, true);
|
|
386
430
|
this.emitChangeEvent(components, 'time-change');
|
|
387
431
|
this.updateTimeSummary();
|
|
432
|
+
this.revealValidity();
|
|
388
433
|
}
|
|
389
434
|
updateTimeSummary(summary = this.shadowRoot?.querySelector('.time-summary')) {
|
|
390
435
|
if (!summary)
|
|
@@ -398,19 +443,22 @@ iso.textContent = '';
|
|
|
398
443
|
return;
|
|
399
444
|
}
|
|
400
445
|
const locale = getEffectiveLocale(this, this.getProperty('locale')) || undefined;
|
|
401
|
-
const date
|
|
402
|
-
const day = new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric' }).format(date);
|
|
403
|
-
const time = new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).format(date);
|
|
446
|
+
const { date, timeZone } = displayDate(c, !!this.getProperty('native'));
|
|
447
|
+
const day = new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric', timeZone }).format(date);
|
|
448
|
+
const time = new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit', hourCycle: 'h23', timeZone }).format(date);
|
|
404
449
|
text.textContent = `${day} · ${time}`;
|
|
405
450
|
iso.textContent = componentsToLocalValue(c, true) ?? '';
|
|
406
451
|
}
|
|
407
452
|
emitChangeEvent(components, source) {
|
|
408
|
-
const
|
|
453
|
+
const value = components ? this.outputValue(components) : null;
|
|
409
454
|
const localValue = components ? componentsToLocalValue(components, this._state.withTime) : null;
|
|
410
|
-
const
|
|
455
|
+
const effective = components && effectiveComponents(components, this._state.withTime);
|
|
456
|
+
const milliseconds = effective
|
|
457
|
+
? effective.epoch ?? componentsToDateObject(effective)?.getTime() ?? null
|
|
458
|
+
: null;
|
|
411
459
|
const formatted = components ? this.getFormattedValue(components) : null;
|
|
412
460
|
const detail = {
|
|
413
|
-
value
|
|
461
|
+
value,
|
|
414
462
|
localValue,
|
|
415
463
|
milliseconds,
|
|
416
464
|
formatted,
|
|
@@ -428,7 +476,15 @@ set size(v) { this.setProperty('size', v); }
|
|
|
428
476
|
get placement() { return this.getProperty('placement'); }
|
|
429
477
|
set placement(v) { this.setProperty('placement', v); }
|
|
430
478
|
get flavor() { return this.getProperty('flavor'); }
|
|
431
|
-
set flavor(v) {
|
|
479
|
+
set flavor(v) {
|
|
480
|
+
this.removeAttribute(ERROR_FLAVOR);
|
|
481
|
+
this.setProperty('flavor', v);
|
|
482
|
+
}
|
|
483
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
484
|
+
if (name === 'flavor' && newValue === 'danger' && oldValue === newValue)
|
|
485
|
+
this.removeAttribute(ERROR_FLAVOR);
|
|
486
|
+
super.attributeChangedCallback(name, oldValue, newValue);
|
|
487
|
+
}
|
|
432
488
|
get label() { return this.getProperty('label'); }
|
|
433
489
|
set label(v) { this.setProperty('label', v); }
|
|
434
490
|
get placeholder() { return this.getProperty('placeholder'); }
|
|
@@ -451,16 +507,26 @@ get max() { return this.getProperty('max'); }
|
|
|
451
507
|
set max(v) { this.setProperty('max', v ?? ''); }
|
|
452
508
|
get withTime() { return this.getProperty('with-time'); }
|
|
453
509
|
set withTime(v) { this.setProperty('with-time', v); }
|
|
510
|
+
get native() { return this.getProperty('native'); }
|
|
511
|
+
set native(v) { this.setProperty('native', v); }
|
|
512
|
+
get error() { return this.getProperty('error'); }
|
|
513
|
+
set error(v) { this.setProperty('error', v); }
|
|
454
514
|
get value() {
|
|
515
|
+
if (this._initialized)
|
|
455
516
|
return this.getProperty('value') || null;
|
|
517
|
+
const parsed = parseValue(this.getProperty('value'));
|
|
518
|
+
return parsed && componentsToOutputValue(parsed, !!this.getProperty('with-time'), !!this.getProperty('native'));
|
|
456
519
|
}
|
|
457
520
|
set value(val) {
|
|
458
521
|
if (val === null || val === undefined || val === '') {
|
|
459
522
|
this.setProperty('value', null);
|
|
460
523
|
}
|
|
524
|
+
else if (typeof val === 'string') {
|
|
525
|
+
this.setProperty('value', val);
|
|
526
|
+
}
|
|
461
527
|
else {
|
|
462
|
-
const
|
|
463
|
-
this.setProperty('value',
|
|
528
|
+
const date = new Date(val);
|
|
529
|
+
this.setProperty('value', isNaN(date.getTime()) ? null : date.toISOString());
|
|
464
530
|
}
|
|
465
531
|
}
|
|
466
532
|
clear() {
|
|
@@ -472,6 +538,8 @@ if (this.getProperty('disabled'))
|
|
|
472
538
|
classes.push('disabled');
|
|
473
539
|
if (this.getProperty('required'))
|
|
474
540
|
classes.push('required');
|
|
541
|
+
if (this.getProperty('error'))
|
|
542
|
+
classes.push('error');
|
|
475
543
|
if (this._state.open)
|
|
476
544
|
classes.push('open');
|
|
477
545
|
return classes.join(' ');
|
|
@@ -494,7 +562,7 @@ stub.setAttribute('aria-labelledby', `date-picker-label-${getElementHash(this)}`
|
|
|
494
562
|
}
|
|
495
563
|
stub.addEventListener('keydown', (e) => {
|
|
496
564
|
const ke = e;
|
|
497
|
-
if (this._state.open)
|
|
565
|
+
if (this._state.open || e.target !== stub)
|
|
498
566
|
return;
|
|
499
567
|
if (ke.key === 'Enter' || ke.key === ' ') {
|
|
500
568
|
ke.preventDefault();
|
|
@@ -604,8 +672,8 @@ if (min)
|
|
|
604
672
|
calendar.setAttribute('min', min);
|
|
605
673
|
if (max)
|
|
606
674
|
calendar.setAttribute('max', max);
|
|
607
|
-
const flavor = this.
|
|
608
|
-
if (flavor
|
|
675
|
+
const flavor = this.calendarFlavor();
|
|
676
|
+
if (flavor)
|
|
609
677
|
calendar.setAttribute('flavor', flavor);
|
|
610
678
|
calendar.addEventListener('change', (e) => this.handleCalendarChange(e));
|
|
611
679
|
contentWrapper.appendChild(calendar);
|
|
@@ -613,11 +681,17 @@ if (this._state.withTime) {
|
|
|
613
681
|
contentWrapper.appendChild(this.renderTimeSection());
|
|
614
682
|
}
|
|
615
683
|
dialog.appendChild(contentWrapper);
|
|
616
|
-
|
|
617
|
-
this.
|
|
618
|
-
|
|
684
|
+
new MutationObserver(() => {
|
|
685
|
+
if (this._state.open && !dialog.open && this.isConnected)
|
|
686
|
+
this.closeDropdown();
|
|
687
|
+
}).observe(dialog, { attributes: true, attributeFilter: ['open'] });
|
|
619
688
|
return dialog;
|
|
620
689
|
}
|
|
690
|
+
calendarFlavor() {
|
|
691
|
+
const replaced = this.getAttribute(ERROR_FLAVOR);
|
|
692
|
+
const flavor = replaced ?? this.getProperty('flavor');
|
|
693
|
+
return flavor && flavor !== 'default' ? flavor : null;
|
|
694
|
+
}
|
|
621
695
|
renderNativeInput() {
|
|
622
696
|
const wrapper = document.createElement('div');
|
|
623
697
|
wrapper.className = 'dropdown-wrapper';
|
|
@@ -629,21 +703,8 @@ stub.setAttribute('disabled', 'true');
|
|
|
629
703
|
}
|
|
630
704
|
const input = document.createElement('input');
|
|
631
705
|
input.className = 'native-date-input';
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
input.disabled = true;
|
|
635
|
-
if (this.getProperty('required'))
|
|
636
|
-
input.required = true;
|
|
637
|
-
const minBound = this.getProperty('min');
|
|
638
|
-
const maxBound = this.getProperty('max');
|
|
639
|
-
if (minBound)
|
|
640
|
-
input.min = this._state.withTime ? `${minBound}T00:00` : minBound;
|
|
641
|
-
if (maxBound)
|
|
642
|
-
input.max = this._state.withTime ? `${maxBound}T23:59` : maxBound;
|
|
643
|
-
const localValue = componentsToLocalValue(this.getComponents(), this._state.withTime);
|
|
644
|
-
if (localValue) {
|
|
645
|
-
input.value = localValue;
|
|
646
|
-
}
|
|
706
|
+
this.syncNativeInput(input);
|
|
707
|
+
const localValue = input.value;
|
|
647
708
|
const placeholder = this.getProperty('placeholder') || 'Select date...';
|
|
648
709
|
const formattedValue = this.getFormattedValue();
|
|
649
710
|
const placeholderEl = document.createElement('span');
|
|
@@ -652,13 +713,17 @@ placeholderEl.textContent = formattedValue || placeholder;
|
|
|
652
713
|
input.addEventListener('change', () => {
|
|
653
714
|
if (!input.value) {
|
|
654
715
|
this.clearValue();
|
|
655
|
-
return;
|
|
656
716
|
}
|
|
657
|
-
|
|
717
|
+
else {
|
|
718
|
+
const parsed = parseValue(input.value);
|
|
658
719
|
if (parsed) {
|
|
659
|
-
this.
|
|
660
|
-
|
|
720
|
+
const { hour, minute, second } = this._state.withTime ? parsed : this._state;
|
|
721
|
+
const components = { ...parsed, hour, minute, second, epoch: undefined };
|
|
722
|
+
this.updateState(components, true);
|
|
723
|
+
this.emitChangeEvent(components, 'selection');
|
|
724
|
+
}
|
|
661
725
|
}
|
|
726
|
+
this.revealValidity();
|
|
662
727
|
});
|
|
663
728
|
const startSlot = document.createElement('slot');
|
|
664
729
|
startSlot.name = 'start';
|
|
@@ -684,6 +749,23 @@ stub.appendChild(iconContainer);
|
|
|
684
749
|
wrapper.appendChild(stub);
|
|
685
750
|
return wrapper;
|
|
686
751
|
}
|
|
752
|
+
syncNativeInput(input) {
|
|
753
|
+
const withTime = this._state.withTime;
|
|
754
|
+
input.type = withTime ? 'datetime-local' : 'date';
|
|
755
|
+
input.disabled = !!this.getProperty('disabled');
|
|
756
|
+
input.required = !!this.getProperty('required');
|
|
757
|
+
const min = this.getProperty('min');
|
|
758
|
+
const max = this.getProperty('max');
|
|
759
|
+
if (min)
|
|
760
|
+
input.min = withTime ? `${min}T00:00` : min;
|
|
761
|
+
else
|
|
762
|
+
input.removeAttribute('min');
|
|
763
|
+
if (max)
|
|
764
|
+
input.max = withTime ? `${max}T23:59` : max;
|
|
765
|
+
else
|
|
766
|
+
input.removeAttribute('max');
|
|
767
|
+
input.value = componentsToLocalValue(this.getComponents(), withTime) ?? '';
|
|
768
|
+
}
|
|
687
769
|
calculateCalendarPosition() {
|
|
688
770
|
if (!this.shadowRoot)
|
|
689
771
|
return;
|
|
@@ -750,6 +832,8 @@ this.shadowRoot.innerHTML = '';
|
|
|
750
832
|
const container = this.renderContainer();
|
|
751
833
|
container.appendChild(this.renderNativeInput());
|
|
752
834
|
this.shadowRoot.appendChild(container);
|
|
835
|
+
this.syncErrorLine();
|
|
836
|
+
this.updateValidity();
|
|
753
837
|
return;
|
|
754
838
|
}
|
|
755
839
|
const existingDialog = this.shadowRoot.querySelector('.calendar-dialog');
|
|
@@ -759,6 +843,7 @@ this.updateDisplay();
|
|
|
759
843
|
this.calculateCalendarPosition();
|
|
760
844
|
return;
|
|
761
845
|
}
|
|
846
|
+
const hadFocus = !!this.shadowRoot.activeElement;
|
|
762
847
|
this.shadowRoot.innerHTML = '';
|
|
763
848
|
const container = this.renderContainer();
|
|
764
849
|
const wrapper = document.createElement('div');
|
|
@@ -767,7 +852,33 @@ wrapper.appendChild(this.renderStub());
|
|
|
767
852
|
wrapper.appendChild(this.renderCalendarDropdown());
|
|
768
853
|
container.appendChild(wrapper);
|
|
769
854
|
this.shadowRoot.appendChild(container);
|
|
855
|
+
this.syncErrorLine();
|
|
770
856
|
this.setupEventListeners();
|
|
857
|
+
this.updateValidity();
|
|
858
|
+
if (hadFocus)
|
|
859
|
+
this.focus({ preventScroll: true });
|
|
860
|
+
}
|
|
861
|
+
syncErrorLine() {
|
|
862
|
+
const container = this.shadowRoot?.querySelector('.dropdown-container');
|
|
863
|
+
if (!container)
|
|
864
|
+
return;
|
|
865
|
+
const error = this.getProperty('error');
|
|
866
|
+
const errorId = `date-picker-error-${getElementHash(this)}`;
|
|
867
|
+
let line = container.querySelector(':scope > .error-message');
|
|
868
|
+
if (error) {
|
|
869
|
+
if (!line) {
|
|
870
|
+
line = document.createElement('div');
|
|
871
|
+
line.className = 'error-message';
|
|
872
|
+
line.id = errorId;
|
|
873
|
+
container.appendChild(line);
|
|
874
|
+
}
|
|
875
|
+
line.textContent = error;
|
|
876
|
+
this.focusTarget()?.setAttribute('aria-describedby', errorId);
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
line?.remove();
|
|
880
|
+
this.focusTarget()?.removeAttribute('aria-describedby');
|
|
881
|
+
}
|
|
771
882
|
}
|
|
772
883
|
updateDisplay() {
|
|
773
884
|
if (!this.shadowRoot)
|
|
@@ -786,12 +897,15 @@ const clearButton = this.shadowRoot.querySelector('.stub-clear');
|
|
|
786
897
|
if (clearButton) {
|
|
787
898
|
clearButton.style.display = (clearable && hasValue && !isDisabled) ? '' : 'none';
|
|
788
899
|
}
|
|
900
|
+
const stub = this.shadowRoot.querySelector('.date-picker-stub');
|
|
901
|
+
if (stub)
|
|
902
|
+
stub.className = this.buildStubClasses();
|
|
903
|
+
this.syncErrorLine();
|
|
789
904
|
if (isMobileTouch()) {
|
|
790
905
|
const nativeInput = this.shadowRoot.querySelector('.native-date-input');
|
|
791
|
-
if (nativeInput)
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
}
|
|
906
|
+
if (nativeInput)
|
|
907
|
+
this.syncNativeInput(nativeInput);
|
|
908
|
+
stub?.toggleAttribute('disabled', !!isDisabled);
|
|
795
909
|
return;
|
|
796
910
|
}
|
|
797
911
|
const calendar = this.shadowRoot.querySelector('ty-calendar');
|
|
@@ -801,8 +915,8 @@ calendar.setAttribute('month', this._state.month.toString());
|
|
|
801
915
|
calendar.setAttribute('day', this._state.day.toString());
|
|
802
916
|
}
|
|
803
917
|
if (calendar) {
|
|
804
|
-
const flavor = this.
|
|
805
|
-
if (flavor
|
|
918
|
+
const flavor = this.calendarFlavor();
|
|
919
|
+
if (flavor)
|
|
806
920
|
calendar.setAttribute('flavor', flavor);
|
|
807
921
|
else
|
|
808
922
|
calendar.removeAttribute('flavor');
|
|
@@ -844,7 +958,7 @@ event.preventDefault();
|
|
|
844
958
|
const dialog = this.shadowRoot?.querySelector('.calendar-dialog');
|
|
845
959
|
if (this._state.open && (!dialog || !dialog.open)) {
|
|
846
960
|
this.updateState({ open: false }, true);
|
|
847
|
-
unlockScroll(`date-picker-${this
|
|
961
|
+
unlockScroll(`date-picker-${getElementHash(this)}`);
|
|
848
962
|
}
|
|
849
963
|
const disabled = this.getProperty('disabled');
|
|
850
964
|
if (!disabled && Date.now() - this._closeTimestamp > 300) {
|
|
@@ -858,6 +972,8 @@ month: undefined,
|
|
|
858
972
|
day: undefined,
|
|
859
973
|
hour: undefined,
|
|
860
974
|
minute: undefined,
|
|
975
|
+
second: undefined,
|
|
976
|
+
epoch: undefined,
|
|
861
977
|
}, true);
|
|
862
978
|
this.value = null;
|
|
863
979
|
this.emitChangeEvent(null, 'clear');
|
|
@@ -867,6 +983,11 @@ handleClearClick(event) {
|
|
|
867
983
|
event.preventDefault();
|
|
868
984
|
event.stopPropagation();
|
|
869
985
|
this.clearValue();
|
|
986
|
+
const active = document.activeElement;
|
|
987
|
+
if (this.matches(':focus-within') || !active || active === document.body) {
|
|
988
|
+
this.shadowRoot?.querySelector('.native-date-input')?.focus({ preventScroll: true });
|
|
989
|
+
}
|
|
990
|
+
this.revealValidity();
|
|
870
991
|
}
|
|
871
992
|
handleCalendarChange(event) {
|
|
872
993
|
event.preventDefault();
|
|
@@ -882,9 +1003,12 @@ month: dayContext.month,
|
|
|
882
1003
|
day: dayContext.dayInMonth,
|
|
883
1004
|
hour: this._state.hour,
|
|
884
1005
|
minute: this._state.minute,
|
|
1006
|
+
second: this._state.second,
|
|
1007
|
+
epoch: undefined,
|
|
885
1008
|
};
|
|
886
1009
|
this.updateState(newComponents, true);
|
|
887
1010
|
this.emitChangeEvent(newComponents, 'selection');
|
|
1011
|
+
this.revealValidity();
|
|
888
1012
|
if (!this._state.withTime) {
|
|
889
1013
|
this.closeDropdown();
|
|
890
1014
|
}
|
|
@@ -938,9 +1062,15 @@ this.render();
|
|
|
938
1062
|
requestAnimationFrame(() => {
|
|
939
1063
|
if (!this.shadowRoot)
|
|
940
1064
|
return;
|
|
1065
|
+
if (!this._state.open || !this.isConnected)
|
|
1066
|
+
return;
|
|
1067
|
+
if (this.shadowRoot.querySelector('.date-picker-stub')?.checkVisibility() === false) {
|
|
1068
|
+
this.closeDropdown();
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
941
1071
|
const dialog = this.shadowRoot.querySelector('.calendar-dialog');
|
|
942
1072
|
if (dialog) {
|
|
943
|
-
const pickerId = `date-picker-${this
|
|
1073
|
+
const pickerId = `date-picker-${getElementHash(this)}`;
|
|
944
1074
|
lockScroll(pickerId);
|
|
945
1075
|
dialog.showModal();
|
|
946
1076
|
this.calculateCalendarPosition();
|
|
@@ -959,7 +1089,7 @@ closeDropdown() {
|
|
|
959
1089
|
if (!this._state.open)
|
|
960
1090
|
return;
|
|
961
1091
|
this._closeTimestamp = Date.now();
|
|
962
|
-
const pickerId = `date-picker-${this
|
|
1092
|
+
const pickerId = `date-picker-${getElementHash(this)}`;
|
|
963
1093
|
this.updateState({ open: false }, true);
|
|
964
1094
|
unlockScroll(pickerId);
|
|
965
1095
|
if (this.shadowRoot) {
|
|
@@ -974,6 +1104,7 @@ stubEl.setAttribute('aria-expanded', 'false');
|
|
|
974
1104
|
}
|
|
975
1105
|
this.dispatchEvent(new CustomEvent('close'));
|
|
976
1106
|
this.render();
|
|
1107
|
+
this.focus();
|
|
977
1108
|
}
|
|
978
1109
|
cleanup() {
|
|
979
1110
|
if (this._clickListener) {
|
|
@@ -989,7 +1120,7 @@ dialog.removeEventListener('click', this._dialogClickListener);
|
|
|
989
1120
|
}
|
|
990
1121
|
}
|
|
991
1122
|
if (this._state.open) {
|
|
992
|
-
const pickerId = `date-picker-${this
|
|
1123
|
+
const pickerId = `date-picker-${getElementHash(this)}`;
|
|
993
1124
|
unlockScroll(pickerId);
|
|
994
1125
|
}
|
|
995
1126
|
this._clickListener = undefined;
|
|
@@ -1062,6 +1193,11 @@ type: 'boolean',
|
|
|
1062
1193
|
visual: true,
|
|
1063
1194
|
default: false
|
|
1064
1195
|
},
|
|
1196
|
+
error: {
|
|
1197
|
+
type: 'string',
|
|
1198
|
+
visual: true,
|
|
1199
|
+
default: ''
|
|
1200
|
+
},
|
|
1065
1201
|
format: {
|
|
1066
1202
|
type: 'string',
|
|
1067
1203
|
visual: true,
|
|
@@ -1092,6 +1228,11 @@ default: null
|
|
|
1092
1228
|
type: 'boolean',
|
|
1093
1229
|
visual: true,
|
|
1094
1230
|
default: false
|
|
1231
|
+
},
|
|
1232
|
+
native: {
|
|
1233
|
+
type: 'boolean',
|
|
1234
|
+
visual: true,
|
|
1235
|
+
default: false
|
|
1095
1236
|
}
|
|
1096
1237
|
};
|
|
1097
1238
|
TyDatePicker.formAssociated = true;
|