tyrell-components 1.0.0-TC57 → 1.0.0-TC59
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-colors-static.css +14 -0
- package/css/tyrell-theme.css +1 -0
- package/css/tyrell.css +8 -6
- package/dist/tyrell-colors-static.css +1 -1
- package/dist/tyrell-theme.css +1 -1
- package/dist/tyrell.js +1 -1
- package/lib/base/ty-component.d.ts +20 -15
- package/lib/base/ty-component.js +58 -25
- package/lib/components/button.d.ts +14 -0
- package/lib/components/button.js +55 -7
- package/lib/components/calendar-month.d.ts +7 -1
- package/lib/components/calendar-month.js +35 -28
- package/lib/components/calendar-navigation.js +19 -6
- package/lib/components/calendar.d.ts +25 -4
- package/lib/components/calendar.js +98 -67
- package/lib/components/checkbox.d.ts +6 -1
- package/lib/components/checkbox.js +20 -6
- package/lib/components/copy.d.ts +2 -0
- package/lib/components/copy.js +15 -31
- package/lib/components/date-picker.d.ts +52 -19
- package/lib/components/date-picker.js +211 -147
- package/lib/components/file-upload.d.ts +2 -1
- package/lib/components/file-upload.js +8 -3
- package/lib/components/input.d.ts +4 -6
- package/lib/components/input.js +37 -62
- package/lib/components/modal.js +86 -9
- package/lib/components/option.js +2 -5
- package/lib/components/popup.js +99 -11
- package/lib/components/radio.d.ts +8 -1
- package/lib/components/radio.js +14 -29
- package/lib/components/resize-observer.js +2 -0
- package/lib/components/scroll-container.js +2 -0
- package/lib/components/select.d.ts +53 -6
- package/lib/components/select.js +127 -29
- package/lib/components/switch.d.ts +7 -1
- package/lib/components/switch.js +20 -6
- package/lib/components/tabs.js +1 -1
- package/lib/components/textarea.d.ts +45 -4
- package/lib/components/textarea.js +75 -18
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/styles/button.js +21 -19
- package/lib/styles/calendar-month.js +1 -1
- package/lib/styles/calendar.js +3 -0
- package/lib/styles/checkbox.js +11 -5
- package/lib/styles/date-picker.js +15 -3
- package/lib/styles/input.js +5 -9
- package/lib/styles/option.d.ts +1 -1
- package/lib/styles/option.js +4 -0
- package/lib/styles/popup.d.ts +1 -1
- package/lib/styles/popup.js +2 -0
- package/lib/styles/radio.js +10 -4
- package/lib/styles/select-base.js +24 -3
- package/lib/styles/select.d.ts +1 -1
- package/lib/styles/select.js +4 -0
- package/lib/styles/switch.js +10 -5
- package/lib/styles/tag.js +2 -1
- package/lib/styles/textarea.d.ts +1 -1
- package/lib/styles/textarea.js +7 -0
- package/lib/utils/calendar-utils.d.ts +49 -0
- package/lib/utils/calendar-utils.js +63 -6
- package/lib/utils/scroll-lock.d.ts +10 -4
- package/lib/utils/scroll-lock.js +102 -2
- package/lib/utils/upgrade-properties.d.ts +21 -0
- package/lib/utils/upgrade-properties.js +47 -0
- package/lib/utils/validity.d.ts +89 -5
- package/lib/utils/validity.js +198 -25
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +2 -1
- 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
|
@@ -50,6 +50,8 @@ export declare class TyCalendar extends HTMLElement {
|
|
|
50
50
|
private _internals?;
|
|
51
51
|
private _validity?;
|
|
52
52
|
private _initialValue;
|
|
53
|
+
private _valueSets;
|
|
54
|
+
private _pressing;
|
|
53
55
|
private _localeObserver?;
|
|
54
56
|
static formAssociated: boolean;
|
|
55
57
|
static get observedAttributes(): string[];
|
|
@@ -63,6 +65,8 @@ export declare class TyCalendar extends HTMLElement {
|
|
|
63
65
|
set max(value: string | undefined);
|
|
64
66
|
get flavor(): string;
|
|
65
67
|
set flavor(value: string);
|
|
68
|
+
get required(): boolean;
|
|
69
|
+
set required(value: boolean);
|
|
66
70
|
get year(): number | undefined;
|
|
67
71
|
set year(value: number | undefined);
|
|
68
72
|
get month(): number | undefined;
|
|
@@ -84,7 +88,12 @@ export declare class TyCalendar extends HTMLElement {
|
|
|
84
88
|
get customCSS(): CSSStyleSheet | undefined;
|
|
85
89
|
set customCSS(sheet: CSSStyleSheet | undefined);
|
|
86
90
|
get value(): string;
|
|
87
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Reads what ty-date-picker reads: 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm[:ss]'
|
|
93
|
+
* (that day), an ISO instant with Z/offset or epoch ms / a Date (its local
|
|
94
|
+
* day). The value stays 'YYYY-MM-DD'; anything else is no value.
|
|
95
|
+
*/
|
|
96
|
+
set value(isoDate: string | number | Date | null | undefined);
|
|
88
97
|
/**
|
|
89
98
|
* Initialize state from HTML attributes on first load
|
|
90
99
|
*/
|
|
@@ -94,8 +103,12 @@ export declare class TyCalendar extends HTMLElement {
|
|
|
94
103
|
private syncChildComponents;
|
|
95
104
|
private updateFormValue;
|
|
96
105
|
/**
|
|
97
|
-
*
|
|
98
|
-
* UI can't
|
|
106
|
+
* required with no selection => valueMissing; a selection outside
|
|
107
|
+
* [min, max] => rangeUnderflow/rangeOverflow (UI can't pick one, days are
|
|
108
|
+
* disabled, but programmatic values can). With a native date input's
|
|
109
|
+
* message. The grid's tab stop is the anchor, so a submit focuses it and
|
|
110
|
+
* the browser shows its bubble there; the cells are rebuilt on every grid
|
|
111
|
+
* render, so each one runs this again.
|
|
99
112
|
*/
|
|
100
113
|
private updateValidity;
|
|
101
114
|
get form(): HTMLFormElement | null;
|
|
@@ -128,7 +141,15 @@ export declare class TyCalendar extends HTMLElement {
|
|
|
128
141
|
private pickMonth;
|
|
129
142
|
private handleKeydown;
|
|
130
143
|
private focusNavTitle;
|
|
131
|
-
/**
|
|
144
|
+
/**
|
|
145
|
+
* The grid's tab stop: the focused day, or month in the month view. When
|
|
146
|
+
* every day shown is disabled (a value outside min/max) there is none: then
|
|
147
|
+
* the selected day, or the first one; disabled cells still take focus.
|
|
148
|
+
* Disabled month cells don't (buttons): with every month of the year
|
|
149
|
+
* disabled, the navigation title (back to the days) stands in.
|
|
150
|
+
*/
|
|
151
|
+
private gridCell;
|
|
152
|
+
/** Focus the grid's tab stop (see gridCell). */
|
|
132
153
|
focus(options?: FocusOptions): void;
|
|
133
154
|
private focusDayGrid;
|
|
134
155
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ensureStyles } from '../utils/styles.js';
|
|
2
|
+
import { liftProperties, upgradeProperties } from '../utils/upgrade-properties.js';
|
|
2
3
|
import { calendarStyles } from '../styles/calendar.js';
|
|
3
4
|
import './calendar-month.js';
|
|
4
5
|
import './calendar-navigation.js';
|
|
5
|
-
import {
|
|
6
|
+
import { parseDateDay, formatISODay, toISODay, getMonthName, localMidnight, utcMidnight } from '../utils/calendar-utils.js';
|
|
6
7
|
import { getEffectiveLocale, observeLocaleChanges } from '../utils/locale.js';
|
|
7
|
-
import { ValidityController } from '../utils/validity.js';
|
|
8
|
+
import { ValidityController, nativeMessage } from '../utils/validity.js';
|
|
8
9
|
function getCurrentDate() {
|
|
9
10
|
const now = new Date();
|
|
10
11
|
return {
|
|
@@ -31,14 +32,12 @@ const day = parseInt(dayStr, 10);
|
|
|
31
32
|
const daysInMonth = new Date(year, month, 0).getDate();
|
|
32
33
|
return day >= 1 && day <= daysInMonth ? day : null;
|
|
33
34
|
}
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
const dayStr = day.toString().padStart(2, '0');
|
|
37
|
-
return `${year}-${monthStr}-${dayStr}`;
|
|
35
|
+
function formatYear(year) {
|
|
36
|
+
return year.toString().padStart(4, '0');
|
|
38
37
|
}
|
|
39
38
|
export class TyCalendar extends HTMLElement {
|
|
40
39
|
static get observedAttributes() {
|
|
41
|
-
return ['value', 'year', 'month', 'day', 'hide-navigation', 'stateless', 'locale', 'name', 'size', 'width', 'min', 'max', 'flavor'];
|
|
40
|
+
return ['value', 'year', 'month', 'day', 'hide-navigation', 'stateless', 'locale', 'name', 'size', 'width', 'min', 'max', 'flavor', 'required'];
|
|
42
41
|
}
|
|
43
42
|
constructor() {
|
|
44
43
|
super();
|
|
@@ -49,12 +48,15 @@ this._flavor = 'primary';
|
|
|
49
48
|
this._view = 'days';
|
|
50
49
|
this._dayGridHeight = 0;
|
|
51
50
|
this._initialValue = '';
|
|
51
|
+
this._valueSets = 0;
|
|
52
|
+
this._pressing = false;
|
|
52
53
|
const current = getCurrentDate();
|
|
53
54
|
this._state = {
|
|
54
55
|
displayYear: current.year,
|
|
55
56
|
displayMonth: current.month,
|
|
56
57
|
};
|
|
57
|
-
this.attachShadow({ mode: 'open' });
|
|
58
|
+
this.attachShadow({ mode: 'open', delegatesFocus: true });
|
|
59
|
+
liftProperties(this);
|
|
58
60
|
if ('attachInternals' in this) {
|
|
59
61
|
this._internals = this.attachInternals();
|
|
60
62
|
this._validity = new ValidityController(this, this._internals);
|
|
@@ -62,36 +64,7 @@ this._validity = new ValidityController(this, this._internals);
|
|
|
62
64
|
}
|
|
63
65
|
connectedCallback() {
|
|
64
66
|
this.initializeFromAttributes();
|
|
65
|
-
|
|
66
|
-
if (plainDayContentFn && !this._dayContentFn) {
|
|
67
|
-
this._dayContentFn = plainDayContentFn;
|
|
68
|
-
delete this.dayContentFn;
|
|
69
|
-
}
|
|
70
|
-
const plainCustomCSS = this.customCSS;
|
|
71
|
-
if (plainCustomCSS && !this._customCSS) {
|
|
72
|
-
this._customCSS = plainCustomCSS;
|
|
73
|
-
delete this.customCSS;
|
|
74
|
-
}
|
|
75
|
-
const plainValue = this.value;
|
|
76
|
-
if (plainValue && typeof plainValue === 'string' && plainValue !== this.value) {
|
|
77
|
-
const match = plainValue.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
78
|
-
if (match) {
|
|
79
|
-
const year = parseInt(match[1], 10);
|
|
80
|
-
const month = parseInt(match[2], 10);
|
|
81
|
-
const day = parseInt(match[3], 10);
|
|
82
|
-
this._state.selectedYear = year;
|
|
83
|
-
this._state.selectedMonth = month;
|
|
84
|
-
this._state.selectedDay = day;
|
|
85
|
-
this._state.displayYear = year;
|
|
86
|
-
this._state.displayMonth = month;
|
|
87
|
-
if (!this._stateless) {
|
|
88
|
-
this.setAttribute('year', year.toString());
|
|
89
|
-
this.setAttribute('month', month.toString());
|
|
90
|
-
this.setAttribute('day', day.toString());
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
delete this.value;
|
|
94
|
-
}
|
|
67
|
+
upgradeProperties(this);
|
|
95
68
|
this.render();
|
|
96
69
|
this.updateFormValue();
|
|
97
70
|
this._localeObserver = observeLocaleChanges(this, () => {
|
|
@@ -158,6 +131,9 @@ this[name === 'min' ? '_min' : '_max'] = newValue || undefined;
|
|
|
158
131
|
this.syncChildComponents();
|
|
159
132
|
this.updateValidity();
|
|
160
133
|
break;
|
|
134
|
+
case 'required':
|
|
135
|
+
this.updateValidity();
|
|
136
|
+
break;
|
|
161
137
|
case 'flavor':
|
|
162
138
|
this._flavor = newValue || 'primary';
|
|
163
139
|
this.syncChildComponents();
|
|
@@ -191,6 +167,12 @@ this.setAttribute('flavor', value);
|
|
|
191
167
|
else
|
|
192
168
|
this.removeAttribute('flavor');
|
|
193
169
|
}
|
|
170
|
+
get required() {
|
|
171
|
+
return this.hasAttribute('required');
|
|
172
|
+
}
|
|
173
|
+
set required(value) {
|
|
174
|
+
this.toggleAttribute('required', !!value);
|
|
175
|
+
}
|
|
194
176
|
get year() {
|
|
195
177
|
return this._state.selectedYear;
|
|
196
178
|
}
|
|
@@ -198,12 +180,12 @@ set year(value) {
|
|
|
198
180
|
if (value !== undefined) {
|
|
199
181
|
if (this._stateless) {
|
|
200
182
|
this._state.displayYear = value;
|
|
201
|
-
this.setAttribute('year', value
|
|
183
|
+
this.setAttribute('year', formatYear(value));
|
|
202
184
|
}
|
|
203
185
|
else {
|
|
204
186
|
this._state.selectedYear = value;
|
|
205
187
|
this._state.displayYear = value;
|
|
206
|
-
this.setAttribute('year', value
|
|
188
|
+
this.setAttribute('year', formatYear(value));
|
|
207
189
|
}
|
|
208
190
|
}
|
|
209
191
|
else {
|
|
@@ -332,35 +314,43 @@ this.syncChildComponents();
|
|
|
332
314
|
get value() {
|
|
333
315
|
const { selectedYear, selectedMonth, selectedDay } = this._state;
|
|
334
316
|
if (selectedYear && selectedMonth && selectedDay) {
|
|
335
|
-
return
|
|
317
|
+
return formatISODay(selectedYear, selectedMonth, selectedDay);
|
|
336
318
|
}
|
|
337
319
|
return '';
|
|
338
320
|
}
|
|
339
321
|
set value(isoDate) {
|
|
340
|
-
|
|
322
|
+
const set = ++this._valueSets;
|
|
323
|
+
const superseded = () => set !== this._valueSets;
|
|
324
|
+
if (isoDate === null || isoDate === undefined || isoDate === '') {
|
|
341
325
|
delete this._state.selectedYear;
|
|
342
326
|
delete this._state.selectedMonth;
|
|
343
327
|
delete this._state.selectedDay;
|
|
344
328
|
if (!this._stateless) {
|
|
345
329
|
this.removeAttribute('year');
|
|
330
|
+
if (superseded())
|
|
331
|
+
return;
|
|
346
332
|
this.removeAttribute('month');
|
|
333
|
+
if (superseded())
|
|
334
|
+
return;
|
|
347
335
|
this.removeAttribute('day');
|
|
348
336
|
}
|
|
349
337
|
}
|
|
350
338
|
else {
|
|
351
|
-
const
|
|
352
|
-
if (
|
|
353
|
-
const year =
|
|
354
|
-
const month = parseInt(match[2], 10);
|
|
355
|
-
const day = parseInt(match[3], 10);
|
|
339
|
+
const parsed = parseDateDay(isoDate);
|
|
340
|
+
if (parsed) {
|
|
341
|
+
const { year, month, day } = parsed;
|
|
356
342
|
this._state.selectedYear = year;
|
|
357
343
|
this._state.selectedMonth = month;
|
|
358
344
|
this._state.selectedDay = day;
|
|
359
345
|
this._state.displayYear = year;
|
|
360
346
|
this._state.displayMonth = month;
|
|
361
347
|
if (!this._stateless) {
|
|
362
|
-
this.setAttribute('year', year
|
|
348
|
+
this.setAttribute('year', formatYear(year));
|
|
349
|
+
if (superseded())
|
|
350
|
+
return;
|
|
363
351
|
this.setAttribute('month', month.toString());
|
|
352
|
+
if (superseded())
|
|
353
|
+
return;
|
|
364
354
|
this.setAttribute('day', day.toString());
|
|
365
355
|
}
|
|
366
356
|
}
|
|
@@ -471,13 +461,13 @@ this._monthDisplay.customCSS = this._customCSS;
|
|
|
471
461
|
}
|
|
472
462
|
const { selectedYear, selectedMonth, selectedDay } = this._state;
|
|
473
463
|
if (selectedYear && selectedMonth && selectedDay) {
|
|
474
|
-
|
|
475
|
-
this._monthDisplay.value = date.getTime();
|
|
464
|
+
this._monthDisplay.value = localMidnight(selectedYear, selectedMonth, selectedDay).getTime();
|
|
476
465
|
}
|
|
477
466
|
else {
|
|
478
467
|
this._monthDisplay.value = null;
|
|
479
468
|
}
|
|
480
469
|
}
|
|
470
|
+
this.updateValidity();
|
|
481
471
|
}
|
|
482
472
|
updateFormValue() {
|
|
483
473
|
if (this._stateless)
|
|
@@ -487,7 +477,7 @@ return;
|
|
|
487
477
|
const elementName = this.getAttribute('name');
|
|
488
478
|
const { selectedYear, selectedMonth, selectedDay } = this._state;
|
|
489
479
|
if (elementName && selectedYear && selectedMonth && selectedDay) {
|
|
490
|
-
const isoDate =
|
|
480
|
+
const isoDate = formatISODay(selectedYear, selectedMonth, selectedDay);
|
|
491
481
|
this._internals.setFormValue(isoDate);
|
|
492
482
|
}
|
|
493
483
|
else {
|
|
@@ -498,21 +488,27 @@ this.updateValidity();
|
|
|
498
488
|
updateValidity() {
|
|
499
489
|
if (!this._internals)
|
|
500
490
|
return;
|
|
491
|
+
const anchor = this.gridCell() ?? undefined;
|
|
501
492
|
const { selectedYear, selectedMonth, selectedDay } = this._state;
|
|
502
493
|
if (selectedYear && selectedMonth && selectedDay) {
|
|
503
|
-
const sel =
|
|
504
|
-
const min = this._min ?
|
|
505
|
-
const max = this._max ?
|
|
506
|
-
|
|
507
|
-
|
|
494
|
+
const sel = utcMidnight(selectedYear, selectedMonth, selectedDay);
|
|
495
|
+
const min = this._min ? parseDateDay(this._min) : null;
|
|
496
|
+
const max = this._max ? parseDateDay(this._max) : null;
|
|
497
|
+
const message = () => nativeMessage('input', { type: 'date', min: toISODay(this._min) ?? undefined, max: toISODay(this._max) ?? undefined }, formatISODay(selectedYear, selectedMonth, selectedDay));
|
|
498
|
+
if (min && sel < utcMidnight(min.year, min.month, min.day)) {
|
|
499
|
+
this._validity.set({ rangeUnderflow: true }, message(), anchor);
|
|
508
500
|
return;
|
|
509
501
|
}
|
|
510
|
-
if (max && sel >
|
|
511
|
-
this._validity.set({ rangeOverflow: true },
|
|
502
|
+
if (max && sel > utcMidnight(max.year, max.month, max.day)) {
|
|
503
|
+
this._validity.set({ rangeOverflow: true }, message(), anchor);
|
|
512
504
|
return;
|
|
513
505
|
}
|
|
514
506
|
}
|
|
515
|
-
this.
|
|
507
|
+
else if (this.required) {
|
|
508
|
+
this._validity.set({ valueMissing: true }, nativeMessage('input', { type: 'date', required: true }), anchor);
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
this._validity.set({}, undefined, anchor);
|
|
516
512
|
}
|
|
517
513
|
get form() { return this._internals?.form ?? null; }
|
|
518
514
|
get validity() { return this._internals?.validity; }
|
|
@@ -562,7 +558,7 @@ this._state.selectedMonth = month;
|
|
|
562
558
|
this._state.selectedDay = day;
|
|
563
559
|
this._state.displayYear = year;
|
|
564
560
|
this._state.displayMonth = month;
|
|
565
|
-
this.setAttribute('year', year
|
|
561
|
+
this.setAttribute('year', formatYear(year));
|
|
566
562
|
this.setAttribute('month', month.toString());
|
|
567
563
|
this.setAttribute('day', day.toString());
|
|
568
564
|
this.updateFormValue();
|
|
@@ -587,6 +583,7 @@ this.syncChildComponents();
|
|
|
587
583
|
if (this._monthDisplay && typeof this._monthDisplay.refresh === 'function') {
|
|
588
584
|
this._monthDisplay.refresh();
|
|
589
585
|
}
|
|
586
|
+
this.updateValidity();
|
|
590
587
|
}
|
|
591
588
|
createNavigation() {
|
|
592
589
|
const nav = document.createElement('ty-calendar-navigation');
|
|
@@ -622,8 +619,7 @@ month.width = this._width;
|
|
|
622
619
|
}
|
|
623
620
|
const { selectedYear, selectedMonth, selectedDay } = this._state;
|
|
624
621
|
if (selectedYear && selectedMonth && selectedDay) {
|
|
625
|
-
|
|
626
|
-
month.value = date.getTime();
|
|
622
|
+
month.value = localMidnight(selectedYear, selectedMonth, selectedDay).getTime();
|
|
627
623
|
}
|
|
628
624
|
if (this._dayContentFn) {
|
|
629
625
|
month.dayContentFn = this._dayContentFn;
|
|
@@ -632,6 +628,7 @@ if (this._customCSS) {
|
|
|
632
628
|
month.customCSS = this._customCSS;
|
|
633
629
|
}
|
|
634
630
|
month.addEventListener('day-click', (e) => this.handleDayClick(e));
|
|
631
|
+
month.shadowRoot?.addEventListener('focusin', () => this.updateValidity());
|
|
635
632
|
this._monthDisplay = month;
|
|
636
633
|
return month;
|
|
637
634
|
}
|
|
@@ -644,7 +641,23 @@ root.innerHTML = '';
|
|
|
644
641
|
this._monthGrid = undefined;
|
|
645
642
|
const container = document.createElement('div');
|
|
646
643
|
container.className = 'calendar-container';
|
|
644
|
+
container.tabIndex = -1;
|
|
645
|
+
const press = () => {
|
|
646
|
+
this._pressing = true;
|
|
647
|
+
setTimeout(() => { this._pressing = false; });
|
|
648
|
+
};
|
|
649
|
+
container.addEventListener('pointerdown', press);
|
|
650
|
+
container.addEventListener('mousedown', press);
|
|
651
|
+
container.addEventListener('focus', () => {
|
|
652
|
+
if (this._pressing)
|
|
653
|
+
return;
|
|
654
|
+
queueMicrotask(() => {
|
|
655
|
+
if (this.shadowRoot?.activeElement === container)
|
|
656
|
+
this.gridCell()?.focus();
|
|
657
|
+
});
|
|
658
|
+
});
|
|
647
659
|
container.addEventListener('keydown', (e) => this.handleKeydown(e));
|
|
660
|
+
container.addEventListener('focusin', () => this.updateValidity());
|
|
648
661
|
this._container = container;
|
|
649
662
|
if (!this._hideNavigation) {
|
|
650
663
|
const nav = this.createNavigation();
|
|
@@ -655,6 +668,7 @@ container.appendChild(month);
|
|
|
655
668
|
root.appendChild(container);
|
|
656
669
|
if (this._view === 'months')
|
|
657
670
|
this.showBody();
|
|
671
|
+
this.updateValidity();
|
|
658
672
|
}
|
|
659
673
|
setView(view) {
|
|
660
674
|
if (view === this._view)
|
|
@@ -666,6 +680,7 @@ this._view = view;
|
|
|
666
680
|
if (this._navigation)
|
|
667
681
|
this._navigation.view = view;
|
|
668
682
|
this.showBody();
|
|
683
|
+
this.updateValidity();
|
|
669
684
|
}
|
|
670
685
|
showBody() {
|
|
671
686
|
const container = this._container;
|
|
@@ -691,8 +706,8 @@ static monthIndex(year, month) {
|
|
|
691
706
|
return year * 12 + (month - 1);
|
|
692
707
|
}
|
|
693
708
|
boundIndices() {
|
|
694
|
-
const min = this._min ?
|
|
695
|
-
const max = this._max ?
|
|
709
|
+
const min = this._min ? parseDateDay(this._min) : null;
|
|
710
|
+
const max = this._max ? parseDateDay(this._max) : null;
|
|
696
711
|
return {
|
|
697
712
|
minIdx: min ? TyCalendar.monthIndex(min.year, min.month) : null,
|
|
698
713
|
maxIdx: max ? TyCalendar.monthIndex(max.year, max.month) : null,
|
|
@@ -757,6 +772,11 @@ this.goTo(month, this._state.displayYear);
|
|
|
757
772
|
this.focusDayGrid();
|
|
758
773
|
}
|
|
759
774
|
handleKeydown(e) {
|
|
775
|
+
if (e.target === this._container && e.key.startsWith('Arrow')) {
|
|
776
|
+
e.preventDefault();
|
|
777
|
+
this.gridCell()?.focus();
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
760
780
|
if (e.key === 'Escape' && this._view === 'months') {
|
|
761
781
|
e.preventDefault();
|
|
762
782
|
e.stopPropagation();
|
|
@@ -792,10 +812,21 @@ requestAnimationFrame(() => {
|
|
|
792
812
|
this._navigation?.shadowRoot?.querySelector('.nav-title')?.focus();
|
|
793
813
|
});
|
|
794
814
|
}
|
|
815
|
+
gridCell() {
|
|
816
|
+
if (this._view === 'months') {
|
|
817
|
+
return this._monthGrid?.querySelector('.month-cell[tabindex="0"]:not(:disabled)')
|
|
818
|
+
?? this._monthGrid?.querySelector('.month-cell:not(:disabled)')
|
|
819
|
+
?? this._navigation?.shadowRoot?.querySelector('.nav-title')
|
|
820
|
+
?? null;
|
|
821
|
+
}
|
|
822
|
+
const root = this._monthDisplay?.shadowRoot;
|
|
823
|
+
return root?.querySelector('.calendar-day-cell[tabindex="0"]')
|
|
824
|
+
?? root?.querySelector('.calendar-day-cell.selected')
|
|
825
|
+
?? root?.querySelector('.calendar-day-cell')
|
|
826
|
+
?? null;
|
|
827
|
+
}
|
|
795
828
|
focus(options) {
|
|
796
|
-
const cell = this.
|
|
797
|
-
? this._monthGrid?.querySelector('.month-cell[tabindex="0"]')
|
|
798
|
-
: this._monthDisplay?.shadowRoot?.querySelector('.calendar-day-cell[tabindex="0"]');
|
|
829
|
+
const cell = this.gridCell();
|
|
799
830
|
if (cell)
|
|
800
831
|
cell.focus(options);
|
|
801
832
|
else
|
|
@@ -32,6 +32,8 @@ export interface TyCheckboxElement extends HTMLElement {
|
|
|
32
32
|
*/
|
|
33
33
|
export declare class TyCheckbox extends TyComponent<CheckboxState> implements TyCheckboxElement {
|
|
34
34
|
static formAssociated: boolean;
|
|
35
|
+
protected static delegatesFocus: boolean;
|
|
36
|
+
protected static labelClicks: boolean;
|
|
35
37
|
protected static properties: {
|
|
36
38
|
checked: {
|
|
37
39
|
type: "boolean";
|
|
@@ -98,6 +100,9 @@ export declare class TyCheckbox extends TyComponent<CheckboxState> implements Ty
|
|
|
98
100
|
protected getFormValue(): FormDataEntryValue | null;
|
|
99
101
|
private buildClassList;
|
|
100
102
|
private handleCheckboxClick;
|
|
103
|
+
/** The ring is for keyboard use: keys show it, a click hides it — also a
|
|
104
|
+
* <label>'s, which in Chromium focuses the box as :focus-visible. */
|
|
105
|
+
private showFocusRing;
|
|
101
106
|
private handleCheckboxKeydown;
|
|
102
107
|
private removeEventListeners;
|
|
103
108
|
/**
|
|
@@ -112,7 +117,7 @@ export declare class TyCheckbox extends TyComponent<CheckboxState> implements Ty
|
|
|
112
117
|
protected render(): void;
|
|
113
118
|
/** Focus the checkbox itself (the host is not focusable; its role element is). */
|
|
114
119
|
focus(options?: FocusOptions): void;
|
|
115
|
-
/** required + unchecked => valueMissing; otherwise valid. */
|
|
120
|
+
/** required + unchecked => valueMissing (the browser's own message); otherwise valid. */
|
|
116
121
|
private updateValidity;
|
|
117
122
|
get checked(): boolean;
|
|
118
123
|
set checked(value: boolean);
|
|
@@ -3,6 +3,7 @@ import { TyComponent } from "../base/ty-component.js";
|
|
|
3
3
|
import { ensureStyles } from "../utils/styles.js";
|
|
4
4
|
import { syncCustomFlavorSheet } from "../utils/flavor-sheet.js";
|
|
5
5
|
import { checkboxStyles, checkboxCustomFlavorCss } from "../styles/checkbox.js";
|
|
6
|
+
import { nativeMessage } from "../utils/validity.js";
|
|
6
7
|
const CHECK_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>`;
|
|
7
8
|
const DASH_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/></svg>`;
|
|
8
9
|
export class TyCheckbox extends TyComponent {
|
|
@@ -20,6 +21,9 @@ ensureStyles(shadow, { css: checkboxStyles, id: "ty-checkbox" });
|
|
|
20
21
|
onConnect() {
|
|
21
22
|
this.setupEventListeners();
|
|
22
23
|
this._syncCustomFlavor();
|
|
24
|
+
const el = this.shadowRoot.querySelector(".checkbox-container");
|
|
25
|
+
if (el && this.shadowRoot.activeElement !== el)
|
|
26
|
+
el.classList.remove("focused");
|
|
23
27
|
}
|
|
24
28
|
_syncCustomFlavor() {
|
|
25
29
|
this._customFlavorSheet = syncCustomFlavorSheet(this.shadowRoot, this._customFlavorSheet, this.flavor, ({ base }) => checkboxCustomFlavorCss(base));
|
|
@@ -46,8 +50,7 @@ return classes.join(" ");
|
|
|
46
50
|
handleCheckboxClick(e) {
|
|
47
51
|
if (this.disabled)
|
|
48
52
|
return;
|
|
49
|
-
|
|
50
|
-
return;
|
|
53
|
+
this.showFocusRing(e instanceof KeyboardEvent);
|
|
51
54
|
const newValue = this.indeterminate ? true : !this.checked;
|
|
52
55
|
if (this.indeterminate)
|
|
53
56
|
this.indeterminate = false;
|
|
@@ -71,6 +74,9 @@ composed: true,
|
|
|
71
74
|
}));
|
|
72
75
|
}, 0);
|
|
73
76
|
}
|
|
77
|
+
showFocusRing(on) {
|
|
78
|
+
this.shadowRoot?.querySelector(".checkbox-container")?.classList.toggle("focused", on);
|
|
79
|
+
}
|
|
74
80
|
handleCheckboxKeydown(e) {
|
|
75
81
|
if (this.disabled)
|
|
76
82
|
return;
|
|
@@ -123,7 +129,7 @@ this._keydownHandler = (e) => {
|
|
|
123
129
|
this.handleCheckboxKeydown(e);
|
|
124
130
|
};
|
|
125
131
|
this._focusHandler = () => {
|
|
126
|
-
checkboxEl.classList.
|
|
132
|
+
checkboxEl.classList.toggle("focused", checkboxEl.matches(":focus-visible"));
|
|
127
133
|
};
|
|
128
134
|
this._blurHandler = () => {
|
|
129
135
|
checkboxEl.classList.remove("focused");
|
|
@@ -142,7 +148,8 @@ const ariaChecked = this.indeterminate ? "mixed" : String(this.checked);
|
|
|
142
148
|
if (!checkboxEl) {
|
|
143
149
|
checkboxEl = document.createElement("div");
|
|
144
150
|
checkboxEl.className = "checkbox-container " + classes;
|
|
145
|
-
|
|
151
|
+
if (!this.disabled)
|
|
152
|
+
checkboxEl.tabIndex = 0;
|
|
146
153
|
checkboxEl.setAttribute("role", "checkbox");
|
|
147
154
|
checkboxEl.setAttribute("aria-checked", ariaChecked);
|
|
148
155
|
checkboxEl.setAttribute("aria-disabled", String(this.disabled));
|
|
@@ -153,8 +160,13 @@ checkboxEl.appendChild(checkboxIcon);
|
|
|
153
160
|
shadow.appendChild(checkboxEl);
|
|
154
161
|
}
|
|
155
162
|
else {
|
|
163
|
+
const focused = checkboxEl.classList.contains("focused") && shadow.activeElement === checkboxEl;
|
|
156
164
|
checkboxEl.className = "checkbox-container " + classes;
|
|
157
|
-
checkboxEl.
|
|
165
|
+
checkboxEl.classList.toggle("focused", focused && !this.disabled);
|
|
166
|
+
if (this.disabled)
|
|
167
|
+
checkboxEl.removeAttribute("tabindex");
|
|
168
|
+
else
|
|
169
|
+
checkboxEl.tabIndex = 0;
|
|
158
170
|
checkboxEl.setAttribute("aria-checked", ariaChecked);
|
|
159
171
|
checkboxEl.setAttribute("aria-disabled", String(this.disabled));
|
|
160
172
|
checkboxEl.setAttribute("aria-required", String(this.required));
|
|
@@ -179,7 +191,7 @@ this.applyValidity({});
|
|
|
179
191
|
return;
|
|
180
192
|
}
|
|
181
193
|
if (this.required && !this.checked) {
|
|
182
|
-
this.applyValidity({ valueMissing: true }, "
|
|
194
|
+
this.applyValidity({ valueMissing: true }, nativeMessage("input", { type: "checkbox", required: true }), anchor ?? undefined);
|
|
183
195
|
}
|
|
184
196
|
else {
|
|
185
197
|
this.applyValidity({});
|
|
@@ -238,6 +250,8 @@ return this._internals.form;
|
|
|
238
250
|
}
|
|
239
251
|
}
|
|
240
252
|
TyCheckbox.formAssociated = true;
|
|
253
|
+
TyCheckbox.delegatesFocus = true;
|
|
254
|
+
TyCheckbox.labelClicks = true;
|
|
241
255
|
TyCheckbox.properties = {
|
|
242
256
|
checked: {
|
|
243
257
|
type: "boolean",
|
package/lib/components/copy.d.ts
CHANGED
|
@@ -109,6 +109,8 @@ export declare class TyCopy extends TyComponent<CopyState> implements TyCopyElem
|
|
|
109
109
|
* Uses state flag so render() can show the correct icon
|
|
110
110
|
*/
|
|
111
111
|
private showCopySuccess;
|
|
112
|
+
/** Feedback over: the copy icon again. */
|
|
113
|
+
private resetCopyButton;
|
|
112
114
|
/**
|
|
113
115
|
* Show copy error animation
|
|
114
116
|
* Swaps copy icon → red X icon → copy icon
|
package/lib/components/copy.js
CHANGED
|
@@ -32,7 +32,7 @@ this._customFlavorSheet = syncCustomFlavorSheet(this.shadowRoot, this._customFla
|
|
|
32
32
|
onDisconnect() {
|
|
33
33
|
if (this._copyTimeout !== null) {
|
|
34
34
|
clearTimeout(this._copyTimeout);
|
|
35
|
-
this.
|
|
35
|
+
this.resetCopyButton();
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
onPropertiesChanged(changes) {
|
|
@@ -61,15 +61,15 @@ composed: true
|
|
|
61
61
|
}));
|
|
62
62
|
}
|
|
63
63
|
catch (err) {
|
|
64
|
-
|
|
64
|
+
const focused = this.shadowRoot.activeElement;
|
|
65
65
|
const textarea = document.createElement('textarea');
|
|
66
|
+
try {
|
|
66
67
|
textarea.value = value;
|
|
67
68
|
textarea.style.position = 'fixed';
|
|
68
69
|
textarea.style.opacity = '0';
|
|
69
70
|
document.body.appendChild(textarea);
|
|
70
71
|
textarea.select();
|
|
71
72
|
document.execCommand('copy');
|
|
72
|
-
document.body.removeChild(textarea);
|
|
73
73
|
this.dispatchEvent(new CustomEvent('copy-success', {
|
|
74
74
|
detail: { value },
|
|
75
75
|
bubbles: true,
|
|
@@ -86,6 +86,10 @@ composed: true
|
|
|
86
86
|
this.showCopyError();
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
|
+
finally {
|
|
90
|
+
textarea.remove();
|
|
91
|
+
focused?.focus();
|
|
92
|
+
}
|
|
89
93
|
}
|
|
90
94
|
this.showCopySuccess();
|
|
91
95
|
}
|
|
@@ -100,16 +104,17 @@ copyButton.classList.add('success');
|
|
|
100
104
|
copyButton.innerHTML = CHECK_ICON_SVG;
|
|
101
105
|
copyButton.setAttribute('aria-label', 'Copied!');
|
|
102
106
|
}
|
|
103
|
-
this._copyTimeout = window.setTimeout(() =>
|
|
107
|
+
this._copyTimeout = window.setTimeout(() => this.resetCopyButton(), 2000);
|
|
108
|
+
}
|
|
109
|
+
resetCopyButton() {
|
|
104
110
|
this._showingSuccess = false;
|
|
105
111
|
const btn = this.shadowRoot.querySelector('.copy-button');
|
|
106
112
|
if (btn) {
|
|
107
|
-
btn.classList.remove('success');
|
|
113
|
+
btn.classList.remove('success', 'error');
|
|
108
114
|
btn.innerHTML = COPY_ICON_SVG;
|
|
109
115
|
btn.setAttribute('aria-label', 'Copy to clipboard');
|
|
110
116
|
}
|
|
111
117
|
this._copyTimeout = null;
|
|
112
|
-
}, 2000);
|
|
113
118
|
}
|
|
114
119
|
showCopyError() {
|
|
115
120
|
if (this._copyTimeout !== null) {
|
|
@@ -122,34 +127,13 @@ copyButton.classList.add('error');
|
|
|
122
127
|
copyButton.innerHTML = ERROR_ICON_SVG;
|
|
123
128
|
copyButton.setAttribute('aria-label', 'Copy failed');
|
|
124
129
|
}
|
|
125
|
-
this._copyTimeout = window.setTimeout(() =>
|
|
126
|
-
const btn = this.shadowRoot.querySelector('.copy-button');
|
|
127
|
-
if (btn) {
|
|
128
|
-
btn.classList.remove('error');
|
|
129
|
-
btn.innerHTML = COPY_ICON_SVG;
|
|
130
|
-
btn.setAttribute('aria-label', 'Copy to clipboard');
|
|
131
|
-
}
|
|
132
|
-
this._copyTimeout = null;
|
|
133
|
-
}, 2000);
|
|
130
|
+
this._copyTimeout = window.setTimeout(() => this.resetCopyButton(), 2000);
|
|
134
131
|
}
|
|
135
132
|
setupEventListeners() {
|
|
136
|
-
const
|
|
137
|
-
const inputWrapper = shadow.querySelector('.input-wrapper');
|
|
138
|
-
const copyButton = shadow.querySelector('.copy-button');
|
|
133
|
+
const inputWrapper = this.shadowRoot.querySelector('.input-wrapper');
|
|
139
134
|
if (inputWrapper && !this.disabled) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (e.target === copyButton || e.target.closest('.copy-button')) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
this.copyToClipboard();
|
|
146
|
-
});
|
|
147
|
-
wrapperEl.style.cursor = 'pointer';
|
|
148
|
-
}
|
|
149
|
-
if (copyButton) {
|
|
150
|
-
copyButton.addEventListener('click', () => {
|
|
151
|
-
this.copyToClipboard();
|
|
152
|
-
});
|
|
135
|
+
inputWrapper.addEventListener('click', () => this.copyToClipboard());
|
|
136
|
+
inputWrapper.style.cursor = 'pointer';
|
|
153
137
|
}
|
|
154
138
|
}
|
|
155
139
|
render() {
|