@everymatrix/general-registration 1.21.2 → 1.21.4

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.
@@ -1,27 +1,810 @@
1
- import { r as registerStyles, i, T as ThemableMixin, A as DirMixin, P as PolymerElement, h as html, j as requiredField, k as helper, d as dedupingMixin, D as DelegateStateMixin, V as ValidateMixin, I as InputMixin, c as DelegateFocusMixin, F as FieldMixin, K as KeyboardMixin, y as Debouncer, z as timeOut } from './field-mixin.js';
1
+ import { o, i, h as html, P as PolymerElement, d as dedupingMixin, I as InputMixin, K as KeyboardMixin, D as DelegateStateMixin, V as ValidateMixin, c as DelegateFocusMixin, F as FieldMixin } from './field-mixin.js';
2
+
3
+ /**
4
+ * @license
5
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
6
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
7
+ */
8
+ function defineCustomElement(CustomElement) {
9
+ const defined = customElements.get(CustomElement.is);
10
+ if (!defined) {
11
+ customElements.define(CustomElement.is, CustomElement);
12
+ } else {
13
+ const definedVersion = defined.version;
14
+ if (definedVersion && CustomElement.version && definedVersion === CustomElement.version) {
15
+ // Just loading the same thing again
16
+ console.warn(`The component ${CustomElement.is} has been loaded twice`);
17
+ } else {
18
+ console.error(
19
+ `Tried to define ${CustomElement.is} version ${CustomElement.version} when version ${defined.version} is already in use. Something will probably break.`,
20
+ );
21
+ }
22
+ }
23
+ }
24
+
25
+ /**
26
+ * @license
27
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
28
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
29
+ */
30
+
31
+ /**
32
+ * Dummy custom element used for collecting
33
+ * development time usage statistics.
34
+ *
35
+ * @private
36
+ */
37
+ class Lumo extends HTMLElement {
38
+ static get is() {
39
+ return 'vaadin-lumo-styles';
40
+ }
41
+
42
+ static get version() {
43
+ return '24.2.3';
44
+ }
45
+ }
46
+
47
+ defineCustomElement(Lumo);
48
+
49
+ /**
50
+ * @license
51
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
52
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
53
+ */
54
+ /**
55
+ * @polymerMixin
56
+ */
57
+ const ThemePropertyMixin = (superClass) =>
58
+ class VaadinThemePropertyMixin extends superClass {
59
+ static get properties() {
60
+ return {
61
+ /**
62
+ * Helper property with theme attribute value facilitating propagation
63
+ * in shadow DOM.
64
+ *
65
+ * Enables the component implementation to propagate the `theme`
66
+ * attribute value to the sub-components in Shadow DOM by binding
67
+ * the sub-component's "theme" attribute to the `theme` property of
68
+ * the host.
69
+ *
70
+ * **NOTE:** Extending the mixin only provides the property for binding,
71
+ * and does not make the propagation alone.
72
+ *
73
+ * See [Styling Components: Sub-components](https://vaadin.com/docs/latest/styling/styling-components/#sub-components).
74
+ * page for more information.
75
+ *
76
+ * @protected
77
+ */
78
+ _theme: {
79
+ type: String,
80
+ readOnly: true,
81
+ },
82
+ };
83
+ }
84
+
85
+ static get observedAttributes() {
86
+ return [...super.observedAttributes, 'theme'];
87
+ }
88
+
89
+ /** @protected */
90
+ attributeChangedCallback(name, oldValue, newValue) {
91
+ super.attributeChangedCallback(name, oldValue, newValue);
92
+
93
+ if (name === 'theme') {
94
+ this._set_theme(newValue);
95
+ }
96
+ }
97
+ };
98
+
99
+ /**
100
+ * @license
101
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
102
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
103
+ */
104
+
105
+ /**
106
+ * @typedef {Object} Theme
107
+ * @property {string} themeFor
108
+ * @property {CSSResult[]} styles
109
+ * @property {string | string[]} [include]
110
+ * @property {string} [moduleId]
111
+ *
112
+ * @typedef {CSSResult[] | CSSResult} CSSResultGroup
113
+ */
114
+
115
+ /**
116
+ * @type {Theme[]}
117
+ */
118
+ const themeRegistry = [];
119
+
120
+ /**
121
+ * Check if the custom element type has themes applied.
122
+ * @param {Function} elementClass
123
+ * @returns {boolean}
124
+ */
125
+ function classHasThemes(elementClass) {
126
+ return elementClass && Object.prototype.hasOwnProperty.call(elementClass, '__themes');
127
+ }
128
+
129
+ /**
130
+ * Check if the custom element type has themes applied.
131
+ * @param {string} tagName
132
+ * @returns {boolean}
133
+ */
134
+ function hasThemes(tagName) {
135
+ return classHasThemes(customElements.get(tagName));
136
+ }
137
+
138
+ /**
139
+ * Flattens the styles into a single array of styles.
140
+ * @param {CSSResultGroup} styles
141
+ * @param {CSSResult[]} result
142
+ * @returns {CSSResult[]}
143
+ */
144
+ function flattenStyles(styles = []) {
145
+ return [styles].flat(Infinity).filter((style) => {
146
+ if (style instanceof o) {
147
+ return true;
148
+ }
149
+ console.warn('An item in styles is not of type CSSResult. Use `unsafeCSS` or `css`.');
150
+ return false;
151
+ });
152
+ }
153
+
154
+ /**
155
+ * Registers CSS styles for a component type. Make sure to register the styles before
156
+ * the first instance of a component of the type is attached to DOM.
157
+ *
158
+ * @param {string} themeFor The local/tag name of the component type to register the styles for
159
+ * @param {CSSResultGroup} styles The CSS style rules to be registered for the component type
160
+ * matching themeFor and included in the local scope of each component instance
161
+ * @param {{moduleId?: string, include?: string | string[]}} options Additional options
162
+ * @return {void}
163
+ */
164
+ function registerStyles(themeFor, styles, options = {}) {
165
+ if (themeFor) {
166
+ if (hasThemes(themeFor)) {
167
+ console.warn(`The custom element definition for "${themeFor}"
168
+ was finalized before a style module was registered.
169
+ Make sure to add component specific style modules before
170
+ importing the corresponding custom element.`);
171
+ }
172
+ }
173
+
174
+ styles = flattenStyles(styles);
175
+
176
+ if (window.Vaadin && window.Vaadin.styleModules) {
177
+ window.Vaadin.styleModules.registerStyles(themeFor, styles, options);
178
+ } else {
179
+ themeRegistry.push({
180
+ themeFor,
181
+ styles,
182
+ include: options.include,
183
+ moduleId: options.moduleId,
184
+ });
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Returns all registered themes. By default the themeRegistry is returned as is.
190
+ * In case the style-modules adapter is imported, the themes are obtained from there instead
191
+ * @returns {Theme[]}
192
+ */
193
+ function getAllThemes() {
194
+ if (window.Vaadin && window.Vaadin.styleModules) {
195
+ return window.Vaadin.styleModules.getAllThemes();
196
+ }
197
+ return themeRegistry;
198
+ }
199
+
200
+ /**
201
+ * Returns true if the themeFor string matches the tag name
202
+ * @param {string} themeFor
203
+ * @param {string} tagName
204
+ * @returns {boolean}
205
+ */
206
+ function matchesThemeFor(themeFor, tagName) {
207
+ return (themeFor || '').split(' ').some((themeForToken) => {
208
+ return new RegExp(`^${themeForToken.split('*').join('.*')}$`, 'u').test(tagName);
209
+ });
210
+ }
211
+
212
+ /**
213
+ * Maps the moduleName to an include priority number which is used for
214
+ * determining the order in which styles are applied.
215
+ * @param {string} moduleName
216
+ * @returns {number}
217
+ */
218
+ function getIncludePriority(moduleName = '') {
219
+ let includePriority = 0;
220
+ if (moduleName.startsWith('lumo-') || moduleName.startsWith('material-')) {
221
+ includePriority = 1;
222
+ } else if (moduleName.startsWith('vaadin-')) {
223
+ includePriority = 2;
224
+ }
225
+ return includePriority;
226
+ }
227
+
228
+ /**
229
+ * Gets an array of CSSResults matching the include property of the theme.
230
+ * @param {Theme} theme
231
+ * @returns {CSSResult[]}
232
+ */
233
+ function getIncludedStyles(theme) {
234
+ const includedStyles = [];
235
+ if (theme.include) {
236
+ [].concat(theme.include).forEach((includeModuleId) => {
237
+ const includedTheme = getAllThemes().find((s) => s.moduleId === includeModuleId);
238
+ if (includedTheme) {
239
+ includedStyles.push(...getIncludedStyles(includedTheme), ...includedTheme.styles);
240
+ } else {
241
+ console.warn(`Included moduleId ${includeModuleId} not found in style registry`);
242
+ }
243
+ }, theme.styles);
244
+ }
245
+ return includedStyles;
246
+ }
247
+
248
+ /**
249
+ * Includes the styles to the template.
250
+ * @param {CSSResult[]} styles
251
+ * @param {HTMLTemplateElement} template
252
+ */
253
+ function addStylesToTemplate(styles, template) {
254
+ const styleEl = document.createElement('style');
255
+ styleEl.innerHTML = styles.map((style) => style.cssText).join('\n');
256
+ template.content.appendChild(styleEl);
257
+ }
258
+
259
+ /**
260
+ * Returns an array of themes that should be used for styling a component matching
261
+ * the tag name. The array is sorted by the include order.
262
+ * @param {string} tagName
263
+ * @returns {Theme[]}
264
+ */
265
+ function getThemes(tagName) {
266
+ const defaultModuleName = `${tagName}-default-theme`;
267
+
268
+ const themes = getAllThemes()
269
+ // Filter by matching themeFor properties
270
+ .filter((theme) => theme.moduleId !== defaultModuleName && matchesThemeFor(theme.themeFor, tagName))
271
+ .map((theme) => ({
272
+ ...theme,
273
+ // Prepend styles from included themes
274
+ styles: [...getIncludedStyles(theme), ...theme.styles],
275
+ // Map moduleId to includePriority
276
+ includePriority: getIncludePriority(theme.moduleId),
277
+ }))
278
+ // Sort by includePriority
279
+ .sort((themeA, themeB) => themeB.includePriority - themeA.includePriority);
280
+
281
+ if (themes.length > 0) {
282
+ return themes;
283
+ }
284
+ // No theme modules found, return the default module if it exists
285
+ return getAllThemes().filter((theme) => theme.moduleId === defaultModuleName);
286
+ }
287
+
288
+ /**
289
+ * @polymerMixin
290
+ * @mixes ThemePropertyMixin
291
+ */
292
+ const ThemableMixin = (superClass) =>
293
+ class VaadinThemableMixin extends ThemePropertyMixin(superClass) {
294
+ /**
295
+ * Covers PolymerElement based component styling
296
+ * @protected
297
+ */
298
+ static finalize() {
299
+ super.finalize();
300
+
301
+ // Make sure not to run the logic intended for PolymerElement when LitElement is used.
302
+ if (this.elementStyles) {
303
+ return;
304
+ }
305
+
306
+ const template = this.prototype._template;
307
+ if (!template || classHasThemes(this)) {
308
+ return;
309
+ }
310
+
311
+ addStylesToTemplate(this.getStylesForThis(), template);
312
+ }
313
+
314
+ /**
315
+ * Covers LitElement based component styling
316
+ *
317
+ * @protected
318
+ */
319
+ static finalizeStyles(styles) {
320
+ // The "styles" object originates from the "static get styles()" function of
321
+ // a LitElement based component. The theme styles are added after it
322
+ // so that they can override the component styles.
323
+ const themeStyles = this.getStylesForThis();
324
+ return styles ? [...super.finalizeStyles(styles), ...themeStyles] : themeStyles;
325
+ }
326
+
327
+ /**
328
+ * Get styles for the component type
329
+ *
330
+ * @private
331
+ */
332
+ static getStylesForThis() {
333
+ const parent = Object.getPrototypeOf(this.prototype);
334
+ const inheritedThemes = (parent ? parent.constructor.__themes : []) || [];
335
+ this.__themes = [...inheritedThemes, ...getThemes(this.is)];
336
+ const themeStyles = this.__themes.flatMap((theme) => theme.styles);
337
+ // Remove duplicates
338
+ return themeStyles.filter((style, index) => index === themeStyles.lastIndexOf(style));
339
+ }
340
+ };
341
+
342
+ /**
343
+ * @license
344
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
345
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
346
+ */
347
+
348
+ /**
349
+ * This is for use internally by Lumo and Material styles.
350
+ *
351
+ * @param {string} id the id to set on the created element, only for informational purposes
352
+ * @param {CSSResultGroup[]} styles the styles to add
353
+ */
354
+ const addGlobalThemeStyles = (id, ...styles) => {
355
+ const styleTag = document.createElement('style');
356
+ styleTag.id = id;
357
+ styleTag.textContent = styles
358
+ .map((style) => style.toString())
359
+ .join('\n')
360
+ .replace(':host', 'html');
361
+
362
+ document.head.insertAdjacentElement('afterbegin', styleTag);
363
+ };
364
+
365
+ const addLumoGlobalStyles = (id, ...styles) => {
366
+ addGlobalThemeStyles(`lumo-${id}`, styles);
367
+ };
368
+
369
+ /**
370
+ * @license
371
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
372
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
373
+ */
374
+
375
+ const colorBase = i`
376
+ :host {
377
+ /* Base (background) */
378
+ --lumo-base-color: #fff;
379
+
380
+ /* Tint */
381
+ --lumo-tint-5pct: hsla(0, 0%, 100%, 0.3);
382
+ --lumo-tint-10pct: hsla(0, 0%, 100%, 0.37);
383
+ --lumo-tint-20pct: hsla(0, 0%, 100%, 0.44);
384
+ --lumo-tint-30pct: hsla(0, 0%, 100%, 0.5);
385
+ --lumo-tint-40pct: hsla(0, 0%, 100%, 0.57);
386
+ --lumo-tint-50pct: hsla(0, 0%, 100%, 0.64);
387
+ --lumo-tint-60pct: hsla(0, 0%, 100%, 0.7);
388
+ --lumo-tint-70pct: hsla(0, 0%, 100%, 0.77);
389
+ --lumo-tint-80pct: hsla(0, 0%, 100%, 0.84);
390
+ --lumo-tint-90pct: hsla(0, 0%, 100%, 0.9);
391
+ --lumo-tint: #fff;
392
+
393
+ /* Shade */
394
+ --lumo-shade-5pct: hsla(214, 61%, 25%, 0.05);
395
+ --lumo-shade-10pct: hsla(214, 57%, 24%, 0.1);
396
+ --lumo-shade-20pct: hsla(214, 53%, 23%, 0.16);
397
+ --lumo-shade-30pct: hsla(214, 50%, 22%, 0.26);
398
+ --lumo-shade-40pct: hsla(214, 47%, 21%, 0.38);
399
+ --lumo-shade-50pct: hsla(214, 45%, 20%, 0.52);
400
+ --lumo-shade-60pct: hsla(214, 43%, 19%, 0.6);
401
+ --lumo-shade-70pct: hsla(214, 42%, 18%, 0.69);
402
+ --lumo-shade-80pct: hsla(214, 41%, 17%, 0.83);
403
+ --lumo-shade-90pct: hsla(214, 40%, 16%, 0.94);
404
+ --lumo-shade: hsl(214, 35%, 15%);
405
+
406
+ /* Contrast */
407
+ --lumo-contrast-5pct: var(--lumo-shade-5pct);
408
+ --lumo-contrast-10pct: var(--lumo-shade-10pct);
409
+ --lumo-contrast-20pct: var(--lumo-shade-20pct);
410
+ --lumo-contrast-30pct: var(--lumo-shade-30pct);
411
+ --lumo-contrast-40pct: var(--lumo-shade-40pct);
412
+ --lumo-contrast-50pct: var(--lumo-shade-50pct);
413
+ --lumo-contrast-60pct: var(--lumo-shade-60pct);
414
+ --lumo-contrast-70pct: var(--lumo-shade-70pct);
415
+ --lumo-contrast-80pct: var(--lumo-shade-80pct);
416
+ --lumo-contrast-90pct: var(--lumo-shade-90pct);
417
+ --lumo-contrast: var(--lumo-shade);
418
+
419
+ /* Text */
420
+ --lumo-header-text-color: var(--lumo-contrast);
421
+ --lumo-body-text-color: var(--lumo-contrast-90pct);
422
+ --lumo-secondary-text-color: var(--lumo-contrast-70pct);
423
+ --lumo-tertiary-text-color: var(--lumo-contrast-50pct);
424
+ --lumo-disabled-text-color: var(--lumo-contrast-30pct);
425
+
426
+ /* Primary */
427
+ --lumo-primary-color: hsl(214, 100%, 48%);
428
+ --lumo-primary-color-50pct: hsla(214, 100%, 49%, 0.76);
429
+ --lumo-primary-color-10pct: hsla(214, 100%, 60%, 0.13);
430
+ --lumo-primary-text-color: hsl(214, 100%, 43%);
431
+ --lumo-primary-contrast-color: #fff;
432
+
433
+ /* Error */
434
+ --lumo-error-color: hsl(3, 85%, 48%);
435
+ --lumo-error-color-50pct: hsla(3, 85%, 49%, 0.5);
436
+ --lumo-error-color-10pct: hsla(3, 85%, 49%, 0.1);
437
+ --lumo-error-text-color: hsl(3, 89%, 42%);
438
+ --lumo-error-contrast-color: #fff;
439
+
440
+ /* Success */
441
+ --lumo-success-color: hsl(145, 72%, 30%);
442
+ --lumo-success-color-50pct: hsla(145, 72%, 31%, 0.5);
443
+ --lumo-success-color-10pct: hsla(145, 72%, 31%, 0.1);
444
+ --lumo-success-text-color: hsl(145, 85%, 25%);
445
+ --lumo-success-contrast-color: #fff;
446
+
447
+ /* Warning */
448
+ --lumo-warning-color: hsl(48, 100%, 50%);
449
+ --lumo-warning-color-10pct: hsla(48, 100%, 50%, 0.25);
450
+ --lumo-warning-text-color: hsl(32, 100%, 30%);
451
+ --lumo-warning-contrast-color: var(--lumo-shade-90pct);
452
+ }
453
+
454
+ /* forced-colors mode adjustments */
455
+ @media (forced-colors: active) {
456
+ html {
457
+ --lumo-disabled-text-color: GrayText;
458
+ }
459
+ }
460
+ `;
461
+
462
+ addLumoGlobalStyles('color-props', colorBase);
463
+
464
+ const color = i`
465
+ [theme~='dark'] {
466
+ /* Base (background) */
467
+ --lumo-base-color: hsl(214, 35%, 21%);
468
+
469
+ /* Tint */
470
+ --lumo-tint-5pct: hsla(214, 65%, 85%, 0.06);
471
+ --lumo-tint-10pct: hsla(214, 60%, 80%, 0.14);
472
+ --lumo-tint-20pct: hsla(214, 64%, 82%, 0.23);
473
+ --lumo-tint-30pct: hsla(214, 69%, 84%, 0.32);
474
+ --lumo-tint-40pct: hsla(214, 73%, 86%, 0.41);
475
+ --lumo-tint-50pct: hsla(214, 78%, 88%, 0.5);
476
+ --lumo-tint-60pct: hsla(214, 82%, 90%, 0.58);
477
+ --lumo-tint-70pct: hsla(214, 87%, 92%, 0.69);
478
+ --lumo-tint-80pct: hsla(214, 91%, 94%, 0.8);
479
+ --lumo-tint-90pct: hsla(214, 96%, 96%, 0.9);
480
+ --lumo-tint: hsl(214, 100%, 98%);
481
+
482
+ /* Shade */
483
+ --lumo-shade-5pct: hsla(214, 0%, 0%, 0.07);
484
+ --lumo-shade-10pct: hsla(214, 4%, 2%, 0.15);
485
+ --lumo-shade-20pct: hsla(214, 8%, 4%, 0.23);
486
+ --lumo-shade-30pct: hsla(214, 12%, 6%, 0.32);
487
+ --lumo-shade-40pct: hsla(214, 16%, 8%, 0.41);
488
+ --lumo-shade-50pct: hsla(214, 20%, 10%, 0.5);
489
+ --lumo-shade-60pct: hsla(214, 24%, 12%, 0.6);
490
+ --lumo-shade-70pct: hsla(214, 28%, 13%, 0.7);
491
+ --lumo-shade-80pct: hsla(214, 32%, 13%, 0.8);
492
+ --lumo-shade-90pct: hsla(214, 33%, 13%, 0.9);
493
+ --lumo-shade: hsl(214, 33%, 13%);
494
+
495
+ /* Contrast */
496
+ --lumo-contrast-5pct: var(--lumo-tint-5pct);
497
+ --lumo-contrast-10pct: var(--lumo-tint-10pct);
498
+ --lumo-contrast-20pct: var(--lumo-tint-20pct);
499
+ --lumo-contrast-30pct: var(--lumo-tint-30pct);
500
+ --lumo-contrast-40pct: var(--lumo-tint-40pct);
501
+ --lumo-contrast-50pct: var(--lumo-tint-50pct);
502
+ --lumo-contrast-60pct: var(--lumo-tint-60pct);
503
+ --lumo-contrast-70pct: var(--lumo-tint-70pct);
504
+ --lumo-contrast-80pct: var(--lumo-tint-80pct);
505
+ --lumo-contrast-90pct: var(--lumo-tint-90pct);
506
+ --lumo-contrast: var(--lumo-tint);
507
+
508
+ /* Text */
509
+ --lumo-header-text-color: var(--lumo-contrast);
510
+ --lumo-body-text-color: var(--lumo-contrast-90pct);
511
+ --lumo-secondary-text-color: var(--lumo-contrast-70pct);
512
+ --lumo-tertiary-text-color: var(--lumo-contrast-50pct);
513
+ --lumo-disabled-text-color: var(--lumo-contrast-30pct);
514
+
515
+ /* Primary */
516
+ --lumo-primary-color: hsl(214, 90%, 48%);
517
+ --lumo-primary-color-50pct: hsla(214, 90%, 70%, 0.69);
518
+ --lumo-primary-color-10pct: hsla(214, 90%, 55%, 0.13);
519
+ --lumo-primary-text-color: hsl(214, 90%, 77%);
520
+ --lumo-primary-contrast-color: #fff;
521
+
522
+ /* Error */
523
+ --lumo-error-color: hsl(3, 79%, 49%);
524
+ --lumo-error-color-50pct: hsla(3, 75%, 62%, 0.5);
525
+ --lumo-error-color-10pct: hsla(3, 75%, 62%, 0.14);
526
+ --lumo-error-text-color: hsl(3, 100%, 80%);
527
+
528
+ /* Success */
529
+ --lumo-success-color: hsl(145, 72%, 30%);
530
+ --lumo-success-color-50pct: hsla(145, 92%, 51%, 0.5);
531
+ --lumo-success-color-10pct: hsla(145, 92%, 51%, 0.1);
532
+ --lumo-success-text-color: hsl(145, 85%, 46%);
533
+
534
+ /* Warning */
535
+ --lumo-warning-color: hsl(43, 100%, 48%);
536
+ --lumo-warning-color-10pct: hsla(40, 100%, 50%, 0.2);
537
+ --lumo-warning-text-color: hsl(45, 100%, 60%);
538
+ --lumo-warning-contrast-color: var(--lumo-shade-90pct);
539
+ }
540
+
541
+ html {
542
+ color: var(--lumo-body-text-color);
543
+ background-color: var(--lumo-base-color);
544
+ color-scheme: light;
545
+ }
546
+
547
+ [theme~='dark'] {
548
+ color: var(--lumo-body-text-color);
549
+ background-color: var(--lumo-base-color);
550
+ color-scheme: dark;
551
+ }
552
+
553
+ h1,
554
+ h2,
555
+ h3,
556
+ h4,
557
+ h5,
558
+ h6 {
559
+ color: var(--lumo-header-text-color);
560
+ }
561
+
562
+ a:where(:any-link) {
563
+ color: var(--lumo-primary-text-color);
564
+ }
565
+
566
+ a:not(:any-link) {
567
+ color: var(--lumo-disabled-text-color);
568
+ }
569
+
570
+ blockquote {
571
+ color: var(--lumo-secondary-text-color);
572
+ }
573
+
574
+ code,
575
+ pre {
576
+ background-color: var(--lumo-contrast-10pct);
577
+ border-radius: var(--lumo-border-radius-m);
578
+ }
579
+ `;
580
+
581
+ registerStyles('', color, { moduleId: 'lumo-color' });
582
+
583
+ /**
584
+ * @license
585
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
586
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
587
+ */
588
+
589
+ const sizing = i`
590
+ :host {
591
+ --lumo-size-xs: 1.625rem;
592
+ --lumo-size-s: 1.875rem;
593
+ --lumo-size-m: 2.25rem;
594
+ --lumo-size-l: 2.75rem;
595
+ --lumo-size-xl: 3.5rem;
596
+
597
+ /* Icons */
598
+ --lumo-icon-size-s: 1.25em;
599
+ --lumo-icon-size-m: 1.5em;
600
+ --lumo-icon-size-l: 2.25em;
601
+ /* For backwards compatibility */
602
+ --lumo-icon-size: var(--lumo-icon-size-m);
603
+ }
604
+ `;
605
+
606
+ addLumoGlobalStyles('sizing-props', sizing);
607
+
608
+ /**
609
+ * @license
610
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
611
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
612
+ */
613
+
614
+ const style = i`
615
+ :host {
616
+ /* Border radius */
617
+ --lumo-border-radius-s: 0.25em; /* Checkbox, badge, date-picker year indicator, etc */
618
+ --lumo-border-radius-m: var(--lumo-border-radius, 0.25em); /* Button, text field, menu overlay, etc */
619
+ --lumo-border-radius-l: 0.5em; /* Dialog, notification, etc */
620
+
621
+ /* Shadow */
622
+ --lumo-box-shadow-xs: 0 1px 4px -1px var(--lumo-shade-50pct);
623
+ --lumo-box-shadow-s: 0 2px 4px -1px var(--lumo-shade-20pct), 0 3px 12px -1px var(--lumo-shade-30pct);
624
+ --lumo-box-shadow-m: 0 2px 6px -1px var(--lumo-shade-20pct), 0 8px 24px -4px var(--lumo-shade-40pct);
625
+ --lumo-box-shadow-l: 0 3px 18px -2px var(--lumo-shade-20pct), 0 12px 48px -6px var(--lumo-shade-40pct);
626
+ --lumo-box-shadow-xl: 0 4px 24px -3px var(--lumo-shade-20pct), 0 18px 64px -8px var(--lumo-shade-40pct);
627
+
628
+ /* Clickable element cursor */
629
+ --lumo-clickable-cursor: default;
630
+ }
631
+ `;
632
+
633
+ /**
634
+ * Default values for component-specific custom properties.
635
+ */
636
+ i`
637
+ html {
638
+ --vaadin-checkbox-size: calc(var(--lumo-size-m) / 2);
639
+ --vaadin-radio-button-size: calc(var(--lumo-size-m) / 2);
640
+ --vaadin-input-field-border-radius: var(--lumo-border-radius-m);
641
+ }
642
+ `;
643
+
644
+ addLumoGlobalStyles('style-props', style);
645
+
646
+ /**
647
+ * @license
648
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
649
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
650
+ */
651
+
652
+ const font = i`
653
+ :host {
654
+ /* prettier-ignore */
655
+ --lumo-font-family: -apple-system, BlinkMacSystemFont, 'Roboto', 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
656
+
657
+ /* Font sizes */
658
+ --lumo-font-size-xxs: 0.75rem;
659
+ --lumo-font-size-xs: 0.8125rem;
660
+ --lumo-font-size-s: 0.875rem;
661
+ --lumo-font-size-m: 1rem;
662
+ --lumo-font-size-l: 1.125rem;
663
+ --lumo-font-size-xl: 1.375rem;
664
+ --lumo-font-size-xxl: 1.75rem;
665
+ --lumo-font-size-xxxl: 2.5rem;
666
+
667
+ /* Line heights */
668
+ --lumo-line-height-xs: 1.25;
669
+ --lumo-line-height-s: 1.375;
670
+ --lumo-line-height-m: 1.625;
671
+ }
672
+ `;
673
+
674
+ const typography = i`
675
+ body,
676
+ :host {
677
+ font-family: var(--lumo-font-family);
678
+ font-size: var(--lumo-font-size-m);
679
+ line-height: var(--lumo-line-height-m);
680
+ -webkit-text-size-adjust: 100%;
681
+ -webkit-font-smoothing: antialiased;
682
+ -moz-osx-font-smoothing: grayscale;
683
+ }
684
+
685
+ small,
686
+ [theme~='font-size-s'] {
687
+ font-size: var(--lumo-font-size-s);
688
+ line-height: var(--lumo-line-height-s);
689
+ }
690
+
691
+ [theme~='font-size-xs'] {
692
+ font-size: var(--lumo-font-size-xs);
693
+ line-height: var(--lumo-line-height-xs);
694
+ }
695
+
696
+ :where(h1, h2, h3, h4, h5, h6) {
697
+ font-weight: 600;
698
+ line-height: var(--lumo-line-height-xs);
699
+ margin-block: 0;
700
+ }
701
+
702
+ :where(h1) {
703
+ font-size: var(--lumo-font-size-xxxl);
704
+ }
705
+
706
+ :where(h2) {
707
+ font-size: var(--lumo-font-size-xxl);
708
+ }
709
+
710
+ :where(h3) {
711
+ font-size: var(--lumo-font-size-xl);
712
+ }
713
+
714
+ :where(h4) {
715
+ font-size: var(--lumo-font-size-l);
716
+ }
717
+
718
+ :where(h5) {
719
+ font-size: var(--lumo-font-size-m);
720
+ }
721
+
722
+ :where(h6) {
723
+ font-size: var(--lumo-font-size-xs);
724
+ text-transform: uppercase;
725
+ letter-spacing: 0.03em;
726
+ }
727
+
728
+ p,
729
+ blockquote {
730
+ margin-top: 0.5em;
731
+ margin-bottom: 0.75em;
732
+ }
733
+
734
+ a {
735
+ text-decoration: none;
736
+ }
737
+
738
+ a:where(:any-link):hover {
739
+ text-decoration: underline;
740
+ }
741
+
742
+ hr {
743
+ display: block;
744
+ align-self: stretch;
745
+ height: 1px;
746
+ border: 0;
747
+ padding: 0;
748
+ margin: var(--lumo-space-s) calc(var(--lumo-border-radius-m) / 2);
749
+ background-color: var(--lumo-contrast-10pct);
750
+ }
751
+
752
+ blockquote {
753
+ border-left: 2px solid var(--lumo-contrast-30pct);
754
+ }
755
+
756
+ b,
757
+ strong {
758
+ font-weight: 600;
759
+ }
760
+
761
+ /* RTL specific styles */
762
+ blockquote[dir='rtl'] {
763
+ border-left: none;
764
+ border-right: 2px solid var(--lumo-contrast-30pct);
765
+ }
766
+ `;
767
+
768
+ registerStyles('', typography, { moduleId: 'lumo-typography' });
769
+ addLumoGlobalStyles('typography-props', font);
2
770
 
3
771
  registerStyles(
4
772
  'vaadin-input-container',
5
773
  i`
6
774
  :host {
7
- border-radius: var(--lumo-border-radius-m);
8
775
  background-color: var(--lumo-contrast-10pct);
9
- padding: 0 calc(0.375em + var(--lumo-border-radius-m) / 4 - 1px);
776
+ padding: 0 calc(0.375em + var(--_input-container-radius) / 4 - 1px);
10
777
  font-weight: 500;
11
778
  line-height: 1;
12
779
  position: relative;
13
780
  cursor: text;
14
781
  box-sizing: border-box;
782
+ border-radius:
783
+ /* See https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius#syntax */
784
+ var(--vaadin-input-field-top-start-radius, var(--_input-container-radius))
785
+ var(--vaadin-input-field-top-end-radius, var(--_input-container-radius))
786
+ var(--vaadin-input-field-bottom-end-radius, var(--_input-container-radius))
787
+ var(--vaadin-input-field-bottom-start-radius, var(--_input-container-radius));
788
+ /* Fallback */
789
+ --_input-container-radius: var(--vaadin-input-field-border-radius, var(--lumo-border-radius-m));
790
+ /* Default field border color */
791
+ --_input-border-color: var(--vaadin-input-field-border-color, var(--lumo-contrast-50pct));
792
+ }
793
+
794
+ :host([dir='rtl']) {
795
+ border-radius:
796
+ /* Don't use logical props, see https://github.com/vaadin/vaadin-time-picker/issues/145 */
797
+ var(--vaadin-input-field-top-end-radius, var(--_input-container-radius))
798
+ var(--vaadin-input-field-top-start-radius, var(--_input-container-radius))
799
+ var(--vaadin-input-field-bottom-start-radius, var(--_input-container-radius))
800
+ var(--vaadin-input-field-bottom-end-radius, var(--_input-container-radius));
15
801
  }
16
802
 
17
803
  /* Used for hover and activation effects */
18
804
  :host::after {
19
805
  content: '';
20
806
  position: absolute;
21
- top: 0;
22
- right: 0;
23
- bottom: 0;
24
- left: 0;
807
+ inset: 0;
25
808
  border-radius: inherit;
26
809
  pointer-events: none;
27
810
  background-color: var(--lumo-contrast-50pct);
@@ -72,7 +855,6 @@ registerStyles(
72
855
  }
73
856
 
74
857
  /* Slotted icons */
75
- ::slotted(iron-icon),
76
858
  ::slotted(vaadin-icon) {
77
859
  color: var(--lumo-contrast-60pct);
78
860
  width: var(--lumo-icon-size-m);
@@ -80,7 +862,6 @@ registerStyles(
80
862
  }
81
863
 
82
864
  /* Vaadin icons are based on a 16x16 grid (unlike Lumo and Material icons with 24x24), so they look too big by default */
83
- ::slotted(iron-icon[icon^='vaadin:']),
84
865
  ::slotted(vaadin-icon[icon^='vaadin:']) {
85
866
  padding: 0.25em;
86
867
  box-sizing: border-box !important;
@@ -162,10 +943,162 @@ registerStyles(
162
943
 
163
944
  /**
164
945
  * @license
165
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
946
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
947
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
948
+ */
949
+
950
+ /**
951
+ * Array of Vaadin custom element classes that have been subscribed to the dir changes.
952
+ */
953
+ const directionSubscribers = [];
954
+
955
+ function alignDirs(element, documentDir, elementDir = element.getAttribute('dir')) {
956
+ if (documentDir) {
957
+ element.setAttribute('dir', documentDir);
958
+ } else if (elementDir != null) {
959
+ element.removeAttribute('dir');
960
+ }
961
+ }
962
+
963
+ function getDocumentDir() {
964
+ return document.documentElement.getAttribute('dir');
965
+ }
966
+
967
+ function directionUpdater() {
968
+ const documentDir = getDocumentDir();
969
+ directionSubscribers.forEach((element) => {
970
+ alignDirs(element, documentDir);
971
+ });
972
+ }
973
+
974
+ const directionObserver = new MutationObserver(directionUpdater);
975
+ directionObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['dir'] });
976
+
977
+ /**
978
+ * A mixin to handle `dir` attribute based on the one set on the `<html>` element.
979
+ *
980
+ * @polymerMixin
981
+ */
982
+ const DirMixin = (superClass) =>
983
+ class VaadinDirMixin extends superClass {
984
+ static get properties() {
985
+ return {
986
+ /**
987
+ * @protected
988
+ */
989
+ dir: {
990
+ type: String,
991
+ value: '',
992
+ reflectToAttribute: true,
993
+ converter: {
994
+ fromAttribute: (attr) => {
995
+ return !attr ? '' : attr;
996
+ },
997
+ toAttribute: (prop) => {
998
+ return prop === '' ? null : prop;
999
+ },
1000
+ },
1001
+ },
1002
+ };
1003
+ }
1004
+
1005
+ /**
1006
+ * @return {boolean}
1007
+ * @protected
1008
+ */
1009
+ get __isRTL() {
1010
+ return this.getAttribute('dir') === 'rtl';
1011
+ }
1012
+
1013
+ /** @protected */
1014
+ connectedCallback() {
1015
+ super.connectedCallback();
1016
+
1017
+ if (!this.hasAttribute('dir') || this.__restoreSubscription) {
1018
+ this.__subscribe();
1019
+ alignDirs(this, getDocumentDir(), null);
1020
+ }
1021
+ }
1022
+
1023
+ /** @protected */
1024
+ attributeChangedCallback(name, oldValue, newValue) {
1025
+ super.attributeChangedCallback(name, oldValue, newValue);
1026
+ if (name !== 'dir') {
1027
+ return;
1028
+ }
1029
+
1030
+ const documentDir = getDocumentDir();
1031
+
1032
+ // New value equals to the document direction and the element is not subscribed to the changes
1033
+ const newValueEqlDocDir = newValue === documentDir && directionSubscribers.indexOf(this) === -1;
1034
+ // Value was emptied and the element is not subscribed to the changes
1035
+ const newValueEmptied = !newValue && oldValue && directionSubscribers.indexOf(this) === -1;
1036
+ // New value is different and the old equals to document direction and the element is not subscribed to the changes
1037
+ const newDiffValue = newValue !== documentDir && oldValue === documentDir;
1038
+
1039
+ if (newValueEqlDocDir || newValueEmptied) {
1040
+ this.__subscribe();
1041
+ alignDirs(this, documentDir, newValue);
1042
+ } else if (newDiffValue) {
1043
+ this.__unsubscribe();
1044
+ }
1045
+ }
1046
+
1047
+ /** @protected */
1048
+ disconnectedCallback() {
1049
+ super.disconnectedCallback();
1050
+ this.__restoreSubscription = directionSubscribers.includes(this);
1051
+ this.__unsubscribe();
1052
+ }
1053
+
1054
+ /** @protected */
1055
+ _valueToNodeAttribute(node, value, attribute) {
1056
+ // Override default Polymer attribute reflection to match native behavior of HTMLElement.dir property
1057
+ // If the property contains an empty string then it should not create an empty attribute
1058
+ if (attribute === 'dir' && value === '' && !node.hasAttribute('dir')) {
1059
+ return;
1060
+ }
1061
+ super._valueToNodeAttribute(node, value, attribute);
1062
+ }
1063
+
1064
+ /** @protected */
1065
+ _attributeToProperty(attribute, value, type) {
1066
+ // Override default Polymer attribute reflection to match native behavior of HTMLElement.dir property
1067
+ // If the attribute is removed, then the dir property should contain an empty string instead of null
1068
+ if (attribute === 'dir' && !value) {
1069
+ this.dir = '';
1070
+ } else {
1071
+ super._attributeToProperty(attribute, value, type);
1072
+ }
1073
+ }
1074
+
1075
+ /** @private */
1076
+ __subscribe() {
1077
+ if (!directionSubscribers.includes(this)) {
1078
+ directionSubscribers.push(this);
1079
+ }
1080
+ }
1081
+
1082
+ /** @private */
1083
+ __unsubscribe() {
1084
+ if (directionSubscribers.includes(this)) {
1085
+ directionSubscribers.splice(directionSubscribers.indexOf(this), 1);
1086
+ }
1087
+ }
1088
+ };
1089
+
1090
+ /**
1091
+ * @license
1092
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
166
1093
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
167
1094
  */
168
1095
 
1096
+ /**
1097
+ * @customElement
1098
+ * @extends HTMLElement
1099
+ * @mixes ThemableMixin
1100
+ * @mixes DirMixin
1101
+ */
169
1102
  class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
170
1103
  static get is() {
171
1104
  return 'vaadin-input-container';
@@ -178,6 +1111,25 @@ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
178
1111
  display: flex;
179
1112
  align-items: center;
180
1113
  flex: 0 1 auto;
1114
+ border-radius:
1115
+ /* See https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius */
1116
+ var(--vaadin-input-field-top-start-radius, var(--__border-radius))
1117
+ var(--vaadin-input-field-top-end-radius, var(--__border-radius))
1118
+ var(--vaadin-input-field-bottom-end-radius, var(--__border-radius))
1119
+ var(--vaadin-input-field-bottom-start-radius, var(--__border-radius));
1120
+ --_border-radius: var(--vaadin-input-field-border-radius, 0px);
1121
+ --_input-border-width: var(--vaadin-input-field-border-width, 0);
1122
+ --_input-border-color: var(--vaadin-input-field-border-color, transparent);
1123
+ box-shadow: inset 0 0 0 var(--_input-border-width, 0) var(--_input-border-color);
1124
+ }
1125
+
1126
+ :host([dir='rtl']) {
1127
+ border-radius:
1128
+ /* Don't use logical props, see https://github.com/vaadin/vaadin-time-picker/issues/145 */
1129
+ var(--vaadin-input-field-top-end-radius, var(--_border-radius))
1130
+ var(--vaadin-input-field-top-start-radius, var(--_border-radius))
1131
+ var(--vaadin-input-field-bottom-start-radius, var(--_border-radius))
1132
+ var(--vaadin-input-field-bottom-end-radius, var(--_border-radius));
181
1133
  }
182
1134
 
183
1135
  :host([hidden]) {
@@ -278,221 +1230,426 @@ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
278
1230
  }
279
1231
  }
280
1232
 
281
- customElements.define(InputContainer.is, InputContainer);
1233
+ defineCustomElement(InputContainer);
282
1234
 
283
1235
  /**
284
1236
  * @license
285
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
286
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1237
+ * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
1238
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
1239
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
1240
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
1241
+ * Code distributed by Google as part of the polymer project is also
1242
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
287
1243
  */
288
1244
 
289
- const testUserAgent = (regexp) => regexp.test(navigator.userAgent);
290
-
291
- const testPlatform = (regexp) => regexp.test(navigator.platform);
1245
+ /**
1246
+ * Async interface wrapper around `setTimeout`.
1247
+ *
1248
+ * @namespace
1249
+ * @summary Async interface wrapper around `setTimeout`.
1250
+ */
1251
+ const timeOut = {
1252
+ /**
1253
+ * Returns a sub-module with the async interface providing the provided
1254
+ * delay.
1255
+ *
1256
+ * @memberof timeOut
1257
+ * @param {number=} delay Time to wait before calling callbacks in ms
1258
+ * @return {!AsyncInterface} An async timeout interface
1259
+ */
1260
+ after(delay) {
1261
+ return {
1262
+ run(fn) {
1263
+ return window.setTimeout(fn, delay);
1264
+ },
1265
+ cancel(handle) {
1266
+ window.clearTimeout(handle);
1267
+ },
1268
+ };
1269
+ },
1270
+ /**
1271
+ * Enqueues a function called in the next task.
1272
+ *
1273
+ * @memberof timeOut
1274
+ * @param {!Function} fn Callback to run
1275
+ * @param {number=} delay Delay in milliseconds
1276
+ * @return {number} Handle used for canceling task
1277
+ */
1278
+ run(fn, delay) {
1279
+ return window.setTimeout(fn, delay);
1280
+ },
1281
+ /**
1282
+ * Cancels a previously enqueued `timeOut` callback.
1283
+ *
1284
+ * @memberof timeOut
1285
+ * @param {number} handle Handle returned from `run` of callback to cancel
1286
+ * @return {void}
1287
+ */
1288
+ cancel(handle) {
1289
+ window.clearTimeout(handle);
1290
+ },
1291
+ };
292
1292
 
293
- const testVendor = (regexp) => regexp.test(navigator.vendor);
1293
+ /**
1294
+ @license
1295
+ Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
1296
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
1297
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
1298
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
1299
+ Code distributed by Google as part of the polymer project is also
1300
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
1301
+ */
294
1302
 
295
- testUserAgent(/Android/);
1303
+ const debouncerQueue = new Set();
296
1304
 
297
- testUserAgent(/Chrome/) && testVendor(/Google Inc/);
1305
+ /**
1306
+ * @summary Collapse multiple callbacks into one invocation after a timer.
1307
+ */
1308
+ class Debouncer {
1309
+ /**
1310
+ * Creates a debouncer if no debouncer is passed as a parameter
1311
+ * or it cancels an active debouncer otherwise. The following
1312
+ * example shows how a debouncer can be called multiple times within a
1313
+ * microtask and "debounced" such that the provided callback function is
1314
+ * called once. Add this method to a custom element:
1315
+ *
1316
+ * ```js
1317
+ * import {microTask} from '@vaadin/component-base/src/async.js';
1318
+ * import {Debouncer} from '@vaadin/component-base/src/debounce.js';
1319
+ * // ...
1320
+ *
1321
+ * _debounceWork() {
1322
+ * this._debounceJob = Debouncer.debounce(this._debounceJob,
1323
+ * microTask, () => this._doWork());
1324
+ * }
1325
+ * ```
1326
+ *
1327
+ * If the `_debounceWork` method is called multiple times within the same
1328
+ * microtask, the `_doWork` function will be called only once at the next
1329
+ * microtask checkpoint.
1330
+ *
1331
+ * Note: In testing it is often convenient to avoid asynchrony. To accomplish
1332
+ * this with a debouncer, you can use `enqueueDebouncer` and
1333
+ * `flush`. For example, extend the above example by adding
1334
+ * `enqueueDebouncer(this._debounceJob)` at the end of the
1335
+ * `_debounceWork` method. Then in a test, call `flush` to ensure
1336
+ * the debouncer has completed.
1337
+ *
1338
+ * @param {Debouncer?} debouncer Debouncer object.
1339
+ * @param {!AsyncInterface} asyncModule Object with Async interface
1340
+ * @param {function()} callback Callback to run.
1341
+ * @return {!Debouncer} Returns a debouncer object.
1342
+ */
1343
+ static debounce(debouncer, asyncModule, callback) {
1344
+ if (debouncer instanceof Debouncer) {
1345
+ // Cancel the async callback, but leave in debouncerQueue if it was
1346
+ // enqueued, to maintain 1.x flush order
1347
+ debouncer._cancelAsync();
1348
+ } else {
1349
+ debouncer = new Debouncer();
1350
+ }
1351
+ debouncer.setConfig(asyncModule, callback);
1352
+ return debouncer;
1353
+ }
298
1354
 
299
- const isFirefox = testUserAgent(/Firefox/);
1355
+ constructor() {
1356
+ this._asyncModule = null;
1357
+ this._callback = null;
1358
+ this._timer = null;
1359
+ }
300
1360
 
301
- // IPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
302
- const isIPad = testPlatform(/^iPad/) || (testPlatform(/^Mac/) && navigator.maxTouchPoints > 1);
1361
+ /**
1362
+ * Sets the scheduler; that is, a module with the Async interface,
1363
+ * a callback and optional arguments to be passed to the run function
1364
+ * from the async module.
1365
+ *
1366
+ * @param {!AsyncInterface} asyncModule Object with Async interface.
1367
+ * @param {function()} callback Callback to run.
1368
+ * @return {void}
1369
+ */
1370
+ setConfig(asyncModule, callback) {
1371
+ this._asyncModule = asyncModule;
1372
+ this._callback = callback;
1373
+ this._timer = this._asyncModule.run(() => {
1374
+ this._timer = null;
1375
+ debouncerQueue.delete(this);
1376
+ this._callback();
1377
+ });
1378
+ }
303
1379
 
304
- const isIPhone = testPlatform(/^iPhone/);
1380
+ /**
1381
+ * Cancels an active debouncer and returns a reference to itself.
1382
+ *
1383
+ * @return {void}
1384
+ */
1385
+ cancel() {
1386
+ if (this.isActive()) {
1387
+ this._cancelAsync();
1388
+ // Canceling a debouncer removes its spot from the flush queue,
1389
+ // so if a debouncer is manually canceled and re-debounced, it
1390
+ // will reset its flush order (this is a very minor difference from 1.x)
1391
+ // Re-debouncing via the `debounce` API retains the 1.x FIFO flush order
1392
+ debouncerQueue.delete(this);
1393
+ }
1394
+ }
305
1395
 
306
- const isIOS = isIPhone || isIPad;
1396
+ /**
1397
+ * Cancels a debouncer's async callback.
1398
+ *
1399
+ * @return {void}
1400
+ */
1401
+ _cancelAsync() {
1402
+ if (this.isActive()) {
1403
+ this._asyncModule.cancel(/** @type {number} */ (this._timer));
1404
+ this._timer = null;
1405
+ }
1406
+ }
307
1407
 
308
- const isSafari = testUserAgent(/^((?!chrome|android).)*safari/i);
1408
+ /**
1409
+ * Flushes an active debouncer and returns a reference to itself.
1410
+ *
1411
+ * @return {void}
1412
+ */
1413
+ flush() {
1414
+ if (this.isActive()) {
1415
+ this.cancel();
1416
+ this._callback();
1417
+ }
1418
+ }
309
1419
 
310
- const isTouch = (() => {
311
- try {
312
- document.createEvent('TouchEvent');
313
- return true;
314
- } catch (e) {
315
- return false;
1420
+ /**
1421
+ * Returns true if the debouncer is active.
1422
+ *
1423
+ * @return {boolean} True if active.
1424
+ */
1425
+ isActive() {
1426
+ return this._timer != null;
316
1427
  }
317
- })();
1428
+ }
318
1429
 
319
1430
  /**
320
1431
  * @license
321
- * Copyright (c) 2017 - 2022 Vaadin Ltd.
1432
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
322
1433
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
323
1434
  */
324
1435
 
325
- const fieldButton = i`
326
- [part$='button'] {
327
- flex: none;
328
- width: 1em;
329
- height: 1em;
330
- line-height: 1;
331
- font-size: var(--lumo-icon-size-m);
332
- text-align: center;
333
- color: var(--lumo-contrast-60pct);
334
- transition: 0.2s color;
335
- cursor: var(--lumo-clickable-cursor);
336
- }
337
-
338
- [part$='button']:hover {
339
- color: var(--lumo-contrast-90pct);
340
- }
1436
+ const stylesMap = new WeakMap();
341
1437
 
342
- :host([disabled]) [part$='button'],
343
- :host([readonly]) [part$='button'] {
344
- color: var(--lumo-contrast-20pct);
345
- cursor: default;
1438
+ /**
1439
+ * Get all the styles inserted into root.
1440
+ * @param {DocumentOrShadowRoot} root
1441
+ * @return {Set<string>}
1442
+ */
1443
+ function getRootStyles(root) {
1444
+ if (!stylesMap.has(root)) {
1445
+ stylesMap.set(root, new Set());
346
1446
  }
347
1447
 
348
- [part$='button']::before {
349
- font-family: 'lumo-icons';
350
- display: block;
351
- }
352
- `;
353
- registerStyles('', fieldButton, { moduleId: 'lumo-field-button' });
1448
+ return stylesMap.get(root);
1449
+ }
354
1450
 
355
1451
  /**
356
- * @license
357
- * Copyright (c) 2017 - 2022 Vaadin Ltd.
358
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1452
+ * Insert styles into the root.
1453
+ * @param {string} styles
1454
+ * @param {DocumentOrShadowRoot} root
359
1455
  */
1456
+ function insertStyles(styles, root) {
1457
+ const style = document.createElement('style');
1458
+ style.textContent = styles;
360
1459
 
361
- const inputField = i`
362
- :host {
363
- --lumo-text-field-size: var(--lumo-size-m);
364
- color: var(--lumo-body-text-color);
365
- font-size: var(--lumo-font-size-m);
366
- font-family: var(--lumo-font-family);
367
- -webkit-font-smoothing: antialiased;
368
- -moz-osx-font-smoothing: grayscale;
369
- -webkit-tap-highlight-color: transparent;
370
- padding: var(--lumo-space-xs) 0;
1460
+ if (root === document) {
1461
+ document.head.appendChild(style);
1462
+ } else {
1463
+ root.insertBefore(style, root.firstChild);
371
1464
  }
1465
+ }
372
1466
 
373
- :host::before {
374
- height: var(--lumo-text-field-size);
375
- box-sizing: border-box;
376
- display: inline-flex;
377
- align-items: center;
378
- }
1467
+ /**
1468
+ * Mixin to insert styles into the outer scope to handle slotted components.
1469
+ * This is useful e.g. to hide native `<input type="number">` controls.
1470
+ *
1471
+ * @polymerMixin
1472
+ */
1473
+ const SlotStylesMixin = dedupingMixin(
1474
+ (superclass) =>
1475
+ class SlotStylesMixinClass extends superclass {
1476
+ /**
1477
+ * List of styles to insert into root.
1478
+ * @protected
1479
+ */
1480
+ get slotStyles() {
1481
+ return {};
1482
+ }
379
1483
 
380
- :host([focused]:not([readonly])) [part='label'] {
381
- color: var(--lumo-primary-text-color);
382
- }
1484
+ /** @protected */
1485
+ connectedCallback() {
1486
+ super.connectedCallback();
383
1487
 
384
- :host([focused]) [part='input-field'] ::slotted(:is(input, textarea)) {
385
- -webkit-mask-image: none;
386
- mask-image: none;
387
- }
1488
+ this.__applySlotStyles();
1489
+ }
388
1490
 
389
- ::slotted(:is(input, textarea):placeholder-shown) {
390
- color: var(--lumo-secondary-text-color);
391
- }
1491
+ /** @private */
1492
+ __applySlotStyles() {
1493
+ const root = this.getRootNode();
1494
+ const rootStyles = getRootStyles(root);
392
1495
 
393
- /* Hover */
394
- :host(:hover:not([readonly]):not([focused])) [part='label'] {
395
- color: var(--lumo-body-text-color);
396
- }
1496
+ this.slotStyles.forEach((styles) => {
1497
+ if (!rootStyles.has(styles)) {
1498
+ insertStyles(styles, root);
1499
+ rootStyles.add(styles);
1500
+ }
1501
+ });
1502
+ }
1503
+ },
1504
+ );
397
1505
 
398
- :host(:hover:not([readonly]):not([focused])) [part='input-field']::after {
399
- opacity: 0.1;
400
- }
1506
+ /**
1507
+ * @license
1508
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
1509
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1510
+ */
401
1511
 
402
- /* Touch device adjustment */
403
- @media (pointer: coarse) {
404
- :host(:hover:not([readonly]):not([focused])) [part='label'] {
405
- color: var(--lumo-secondary-text-color);
406
- }
1512
+ const testUserAgent = (regexp) => regexp.test(navigator.userAgent);
407
1513
 
408
- :host(:hover:not([readonly]):not([focused])) [part='input-field']::after {
409
- opacity: 0;
410
- }
1514
+ const testPlatform = (regexp) => regexp.test(navigator.platform);
411
1515
 
412
- :host(:active:not([readonly]):not([focused])) [part='input-field']::after {
413
- opacity: 0.2;
414
- }
415
- }
1516
+ const testVendor = (regexp) => regexp.test(navigator.vendor);
416
1517
 
417
- /* Trigger when not focusing using the keyboard */
418
- :host([focused]:not([focus-ring]):not([readonly])) [part='input-field']::after {
419
- transform: scaleX(0);
420
- transition-duration: 0.15s, 1s;
421
- }
1518
+ testUserAgent(/Android/u);
1519
+
1520
+ testUserAgent(/Chrome/u) && testVendor(/Google Inc/u);
422
1521
 
423
- /* Focus-ring */
424
- :host([focus-ring]) [part='input-field'] {
425
- box-shadow: 0 0 0 2px var(--lumo-primary-color-50pct);
426
- }
1522
+ testUserAgent(/Firefox/u);
427
1523
 
428
- /* Read-only and disabled */
429
- :host(:is([readonly], [disabled])) ::slotted(:is(input, textarea):placeholder-shown) {
430
- opacity: 0;
431
- }
1524
+ // IPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
1525
+ testPlatform(/^iPad/u) || (testPlatform(/^Mac/u) && navigator.maxTouchPoints > 1);
432
1526
 
433
- /* Disabled style */
434
- :host([disabled]) {
435
- pointer-events: none;
436
- }
1527
+ testPlatform(/^iPhone/u);
437
1528
 
438
- :host([disabled]) [part='label'],
439
- :host([disabled]) [part='input-field'] ::slotted(*) {
440
- color: var(--lumo-disabled-text-color);
441
- -webkit-text-fill-color: var(--lumo-disabled-text-color);
442
- }
1529
+ testUserAgent(/^((?!chrome|android).)*safari/iu);
443
1530
 
444
- /* Invalid style */
445
- :host([invalid][focus-ring]) [part='input-field'] {
446
- box-shadow: 0 0 0 2px var(--lumo-error-color-50pct);
1531
+ const isTouch = (() => {
1532
+ try {
1533
+ document.createEvent('TouchEvent');
1534
+ return true;
1535
+ } catch (e) {
1536
+ return false;
447
1537
  }
1538
+ })();
448
1539
 
449
- :host([input-prevented]) [part='input-field'] {
450
- animation: shake 0.15s infinite;
451
- }
1540
+ /**
1541
+ * @license
1542
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
1543
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1544
+ */
452
1545
 
453
- @keyframes shake {
454
- 25% {
455
- transform: translateX(4px);
1546
+ /**
1547
+ * A mixin that manages the clear button.
1548
+ *
1549
+ * @polymerMixin
1550
+ * @mixes InputMixin
1551
+ * @mixes KeyboardMixin
1552
+ */
1553
+ const ClearButtonMixin = (superclass) =>
1554
+ class ClearButtonMixinClass extends InputMixin(KeyboardMixin(superclass)) {
1555
+ static get properties() {
1556
+ return {
1557
+ /**
1558
+ * Set to true to display the clear icon which clears the input.
1559
+ *
1560
+ * It is up to the component to choose where to place the clear icon:
1561
+ * in the Shadow DOM or in the light DOM. In any way, a reference to
1562
+ * the clear icon element should be provided via the `clearElement` getter.
1563
+ *
1564
+ * @attr {boolean} clear-button-visible
1565
+ */
1566
+ clearButtonVisible: {
1567
+ type: Boolean,
1568
+ reflectToAttribute: true,
1569
+ value: false,
1570
+ },
1571
+ };
456
1572
  }
457
- 75% {
458
- transform: translateX(-4px);
1573
+
1574
+ /**
1575
+ * Any element extending this mixin is required to implement this getter.
1576
+ * It returns the reference to the clear button element.
1577
+ *
1578
+ * @protected
1579
+ * @return {Element | null | undefined}
1580
+ */
1581
+ get clearElement() {
1582
+ console.warn(`Please implement the 'clearElement' property in <${this.localName}>`);
1583
+ return null;
459
1584
  }
460
- }
461
1585
 
462
- /* Small theme */
463
- :host([theme~='small']) {
464
- font-size: var(--lumo-font-size-s);
465
- --lumo-text-field-size: var(--lumo-size-s);
466
- }
1586
+ /** @protected */
1587
+ ready() {
1588
+ super.ready();
467
1589
 
468
- :host([theme~='small']) [part='label'] {
469
- font-size: var(--lumo-font-size-xs);
470
- }
1590
+ if (this.clearElement) {
1591
+ this.clearElement.addEventListener('mousedown', (event) => this._onClearButtonMouseDown(event));
1592
+ this.clearElement.addEventListener('click', (event) => this._onClearButtonClick(event));
1593
+ }
1594
+ }
471
1595
 
472
- :host([theme~='small']) [part='error-message'] {
473
- font-size: var(--lumo-font-size-xxs);
474
- }
1596
+ /**
1597
+ * @param {Event} event
1598
+ * @protected
1599
+ */
1600
+ _onClearButtonClick(event) {
1601
+ event.preventDefault();
1602
+ this._onClearAction();
1603
+ }
475
1604
 
476
- /* Slotted content */
477
- [part='input-field'] ::slotted(:not(iron-icon):not(vaadin-icon):not(input):not(textarea)) {
478
- color: var(--lumo-secondary-text-color);
479
- font-weight: 400;
480
- }
1605
+ /**
1606
+ * @param {MouseEvent} event
1607
+ * @protected
1608
+ */
1609
+ _onClearButtonMouseDown(event) {
1610
+ event.preventDefault();
1611
+ if (!isTouch) {
1612
+ this.inputElement.focus();
1613
+ }
1614
+ }
481
1615
 
482
- [part='clear-button']::before {
483
- content: var(--lumo-icons-cross);
484
- }
485
- `;
1616
+ /**
1617
+ * Override an event listener inherited from `KeydownMixin` to clear on Esc.
1618
+ * Components that extend this mixin can prevent this behavior by overriding
1619
+ * this method without calling `super._onEscape` to provide custom logic.
1620
+ *
1621
+ * @param {KeyboardEvent} event
1622
+ * @protected
1623
+ * @override
1624
+ */
1625
+ _onEscape(event) {
1626
+ super._onEscape(event);
486
1627
 
487
- const inputFieldShared$1 = [requiredField, fieldButton, helper, inputField];
1628
+ if (this.clearButtonVisible && !!this.value) {
1629
+ event.stopPropagation();
1630
+ this._onClearAction();
1631
+ }
1632
+ }
488
1633
 
489
- registerStyles('', inputFieldShared$1, {
490
- moduleId: 'lumo-input-field-shared-styles',
491
- });
1634
+ /**
1635
+ * Clears the value and dispatches `input` and `change` events
1636
+ * on the input element. This method should be called
1637
+ * when the clear action originates from the user.
1638
+ *
1639
+ * @protected
1640
+ */
1641
+ _onClearAction() {
1642
+ this.clear();
1643
+ // Note, according to the HTML spec, the native change event isn't composed
1644
+ // while the input event is composed.
1645
+ this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
1646
+ this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
1647
+ }
1648
+ };
492
1649
 
493
1650
  /**
494
1651
  * @license
495
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
1652
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
496
1653
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
497
1654
  */
498
1655
 
@@ -620,83 +1777,7 @@ const InputConstraintsMixin = dedupingMixin(
620
1777
 
621
1778
  /**
622
1779
  * @license
623
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
624
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
625
- */
626
-
627
- const stylesMap = new WeakMap();
628
-
629
- /**
630
- * Get all the styles inserted into root.
631
- * @param {DocumentOrShadowRoot} root
632
- * @return {Set<string>}
633
- */
634
- function getRootStyles(root) {
635
- if (!stylesMap.has(root)) {
636
- stylesMap.set(root, new Set());
637
- }
638
-
639
- return stylesMap.get(root);
640
- }
641
-
642
- /**
643
- * Insert styles into the root.
644
- * @param {string} styles
645
- * @param {DocumentOrShadowRoot} root
646
- */
647
- function insertStyles(styles, root) {
648
- const style = document.createElement('style');
649
- style.textContent = styles;
650
-
651
- if (root === document) {
652
- document.head.appendChild(style);
653
- } else {
654
- root.insertBefore(style, root.firstChild);
655
- }
656
- }
657
-
658
- /**
659
- * Mixin to insert styles into the outer scope to handle slotted components.
660
- * This is useful e.g. to hide native `<input type="number">` controls.
661
- *
662
- * @polymerMixin
663
- */
664
- const SlotStylesMixin = dedupingMixin(
665
- (superclass) =>
666
- class SlotStylesMixinClass extends superclass {
667
- /**
668
- * List of styles to insert into root.
669
- * @protected
670
- */
671
- get slotStyles() {
672
- return {};
673
- }
674
-
675
- /** @protected */
676
- connectedCallback() {
677
- super.connectedCallback();
678
-
679
- this.__applySlotStyles();
680
- }
681
-
682
- /** @private */
683
- __applySlotStyles() {
684
- const root = this.getRootNode();
685
- const rootStyles = getRootStyles(root);
686
-
687
- this.slotStyles.forEach((styles) => {
688
- if (!rootStyles.has(styles)) {
689
- insertStyles(styles, root);
690
- rootStyles.add(styles);
691
- }
692
- });
693
- }
694
- },
695
- );
696
-
697
- /**
698
- * @license
699
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
1780
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
700
1781
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
701
1782
  */
702
1783
 
@@ -708,11 +1789,12 @@ const SlotStylesMixin = dedupingMixin(
708
1789
  * @mixes FieldMixin
709
1790
  * @mixes InputConstraintsMixin
710
1791
  * @mixes KeyboardMixin
1792
+ * @mixes ClearButtonMixin
711
1793
  * @mixes SlotStylesMixin
712
1794
  */
713
1795
  const InputControlMixin = (superclass) =>
714
1796
  class InputControlMixinClass extends SlotStylesMixin(
715
- DelegateFocusMixin(InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass)))),
1797
+ DelegateFocusMixin(InputConstraintsMixin(FieldMixin(ClearButtonMixin(KeyboardMixin(superclass))))),
716
1798
  ) {
717
1799
  static get properties() {
718
1800
  return {
@@ -741,16 +1823,6 @@ const InputControlMixin = (superclass) =>
741
1823
  value: false,
742
1824
  },
743
1825
 
744
- /**
745
- * Set to true to display the clear icon which clears the input.
746
- * @attr {boolean} clear-button-visible
747
- */
748
- clearButtonVisible: {
749
- type: Boolean,
750
- reflectToAttribute: true,
751
- value: false,
752
- },
753
-
754
1826
  /**
755
1827
  * The name of this field.
756
1828
  */
@@ -798,17 +1870,6 @@ const InputControlMixin = (superclass) =>
798
1870
  this._boundOnBeforeInput = this._onBeforeInput.bind(this);
799
1871
  }
800
1872
 
801
- /**
802
- * Any element extending this mixin is required to implement this getter.
803
- * It returns the reference to the clear button element.
804
- * @protected
805
- * @return {Element | null | undefined}
806
- */
807
- get clearElement() {
808
- console.warn(`Please implement the 'clearElement' property in <${this.localName}>`);
809
- return null;
810
- }
811
-
812
1873
  /** @protected */
813
1874
  get slotStyles() {
814
1875
  // Needed for Safari, where ::slotted(...)::placeholder does not work
@@ -822,36 +1883,6 @@ const InputControlMixin = (superclass) =>
822
1883
  ];
823
1884
  }
824
1885
 
825
- /** @protected */
826
- ready() {
827
- super.ready();
828
-
829
- if (this.clearElement) {
830
- this.clearElement.addEventListener('click', (e) => this._onClearButtonClick(e));
831
- this.clearElement.addEventListener('mousedown', (e) => this._onClearButtonMouseDown(e));
832
- }
833
- }
834
-
835
- /**
836
- * @param {Event} event
837
- * @protected
838
- */
839
- _onClearButtonClick(event) {
840
- event.preventDefault();
841
- this.__clear();
842
- }
843
-
844
- /**
845
- * @param {Event} event
846
- * @protected
847
- */
848
- _onClearButtonMouseDown(event) {
849
- event.preventDefault();
850
- if (!isTouch) {
851
- this.inputElement.focus();
852
- }
853
- }
854
-
855
1886
  /**
856
1887
  * Override an event listener from `DelegateFocusMixin`.
857
1888
  * @param {FocusEvent} event
@@ -866,23 +1897,6 @@ const InputControlMixin = (superclass) =>
866
1897
  }
867
1898
  }
868
1899
 
869
- /**
870
- * Override an event listener inherited from `KeydownMixin` to clear on Esc.
871
- * Components that extend this mixin can prevent this behavior by overriding
872
- * this method without calling `super._onEscape` to provide custom logic.
873
- * @param {KeyboardEvent} event
874
- * @protected
875
- * @override
876
- */
877
- _onEscape(event) {
878
- super._onEscape(event);
879
-
880
- if (this.clearButtonVisible && !!this.value) {
881
- event.stopPropagation();
882
- this.__clear();
883
- }
884
- }
885
-
886
1900
  /**
887
1901
  * Override an event listener inherited from `InputMixin`
888
1902
  * to capture native `change` event and make sure that
@@ -907,13 +1921,6 @@ const InputControlMixin = (superclass) =>
907
1921
  );
908
1922
  }
909
1923
 
910
- /** @private */
911
- __clear() {
912
- this.clear();
913
- this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
914
- this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
915
- }
916
-
917
1924
  /**
918
1925
  * Override a method from `InputMixin`.
919
1926
  * @param {!HTMLElement} input
@@ -1015,8 +2022,8 @@ const InputControlMixin = (superclass) =>
1015
2022
  _allowedCharPatternChanged(charPattern) {
1016
2023
  if (charPattern) {
1017
2024
  try {
1018
- this.__allowedCharRegExp = new RegExp(`^${charPattern}$`);
1019
- this.__allowedTextRegExp = new RegExp(`^${charPattern}*$`);
2025
+ this.__allowedCharRegExp = new RegExp(`^${charPattern}$`, 'u');
2026
+ this.__allowedTextRegExp = new RegExp(`^${charPattern}*$`, 'u');
1020
2027
  } catch (e) {
1021
2028
  console.error(e);
1022
2029
  }
@@ -1039,7 +2046,7 @@ const InputControlMixin = (superclass) =>
1039
2046
 
1040
2047
  /**
1041
2048
  * @license
1042
- * Copyright (c) 2021 - 2022 Vaadin Ltd..
2049
+ * Copyright (c) 2021 - 2023 Vaadin Ltd..
1043
2050
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1044
2051
  */
1045
2052
 
@@ -1050,7 +2057,7 @@ const clearButton = i`
1050
2057
  }
1051
2058
 
1052
2059
  [part='clear-button']::before {
1053
- content: '';
2060
+ content: '\\2715';
1054
2061
  }
1055
2062
 
1056
2063
  :host([clear-button-visible][has-value]:not([disabled]):not([readonly])) [part='clear-button'] {
@@ -1060,7 +2067,7 @@ const clearButton = i`
1060
2067
 
1061
2068
  /**
1062
2069
  * @license
1063
- * Copyright (c) 2021 - 2022 Vaadin Ltd..
2070
+ * Copyright (c) 2021 - 2023 Vaadin Ltd..
1064
2071
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1065
2072
  */
1066
2073
 
@@ -1085,11 +2092,24 @@ const fieldShared = i`
1085
2092
  :host(:not([has-label])) [part='label'] {
1086
2093
  display: none;
1087
2094
  }
2095
+
2096
+ @media (forced-colors: active) {
2097
+ :host(:not([readonly])) [part='input-field'] {
2098
+ outline: 1px solid;
2099
+ outline-offset: -1px;
2100
+ }
2101
+ :host([focused]) [part='input-field'] {
2102
+ outline-width: 2px;
2103
+ }
2104
+ :host([disabled]) [part='input-field'] {
2105
+ outline-color: GrayText;
2106
+ }
2107
+ }
1088
2108
  `;
1089
2109
 
1090
2110
  /**
1091
2111
  * @license
1092
- * Copyright (c) 2021 - 2022 Vaadin Ltd..
2112
+ * Copyright (c) 2021 - 2023 Vaadin Ltd..
1093
2113
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1094
2114
  */
1095
2115
 
@@ -1105,10 +2125,10 @@ const inputFieldContainer = i`
1105
2125
 
1106
2126
  /**
1107
2127
  * @license
1108
- * Copyright (c) 2021 - 2022 Vaadin Ltd..
2128
+ * Copyright (c) 2021 - 2023 Vaadin Ltd..
1109
2129
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1110
2130
  */
1111
2131
 
1112
2132
  const inputFieldShared = [fieldShared, inputFieldContainer, clearButton];
1113
2133
 
1114
- export { InputConstraintsMixin as I, isFirefox as a, isIOS as b, InputControlMixin as c, inputFieldShared as d, isSafari as e, isTouch as f, inputFieldShared$1 as i };
2134
+ export { InputConstraintsMixin as I, InputControlMixin as a, inputFieldShared as i };