@everymatrix/general-registration 1.10.12 → 1.10.13

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.
@@ -0,0 +1,1432 @@
1
+ import { i, r as registerStyles, G as microTask, H as DisabledMixin, K as KeyboardMixin, J as TabindexMixin, F as FocusMixin, p as ElementMixin, T as ThemableMixin, C as ControllerMixin, P as PolymerElement, h as html, n as TooltipController } from './input-field-shared-styles.js';
2
+
3
+ const button = i`
4
+ :host {
5
+ /* Sizing */
6
+ --lumo-button-size: var(--lumo-size-m);
7
+ min-width: calc(var(--lumo-button-size) * 2);
8
+ height: var(--lumo-button-size);
9
+ padding: 0 calc(var(--lumo-button-size) / 3 + var(--lumo-border-radius-m) / 2);
10
+ margin: var(--lumo-space-xs) 0;
11
+ box-sizing: border-box;
12
+ /* Style */
13
+ font-family: var(--lumo-font-family);
14
+ font-size: var(--lumo-font-size-m);
15
+ font-weight: 500;
16
+ color: var(--_lumo-button-color, var(--lumo-primary-text-color));
17
+ background-color: var(--_lumo-button-background-color, var(--lumo-contrast-5pct));
18
+ border-radius: var(--lumo-border-radius-m);
19
+ cursor: var(--lumo-clickable-cursor);
20
+ -webkit-tap-highlight-color: transparent;
21
+ -webkit-font-smoothing: antialiased;
22
+ -moz-osx-font-smoothing: grayscale;
23
+ }
24
+
25
+ /* Set only for the internal parts so we don't affect the host vertical alignment */
26
+ [part='label'],
27
+ [part='prefix'],
28
+ [part='suffix'] {
29
+ line-height: var(--lumo-line-height-xs);
30
+ }
31
+
32
+ [part='label'] {
33
+ padding: calc(var(--lumo-button-size) / 6) 0;
34
+ }
35
+
36
+ :host([theme~='small']) {
37
+ font-size: var(--lumo-font-size-s);
38
+ --lumo-button-size: var(--lumo-size-s);
39
+ }
40
+
41
+ :host([theme~='large']) {
42
+ font-size: var(--lumo-font-size-l);
43
+ --lumo-button-size: var(--lumo-size-l);
44
+ }
45
+
46
+ /* For interaction states */
47
+ :host::before,
48
+ :host::after {
49
+ content: '';
50
+ /* We rely on the host always being relative */
51
+ position: absolute;
52
+ z-index: 1;
53
+ top: 0;
54
+ right: 0;
55
+ bottom: 0;
56
+ left: 0;
57
+ background-color: currentColor;
58
+ border-radius: inherit;
59
+ opacity: 0;
60
+ pointer-events: none;
61
+ }
62
+
63
+ /* Hover */
64
+
65
+ @media (any-hover: hover) {
66
+ :host(:hover)::before {
67
+ opacity: 0.02;
68
+ }
69
+ }
70
+
71
+ /* Active */
72
+
73
+ :host::after {
74
+ transition: opacity 1.4s, transform 0.1s;
75
+ filter: blur(8px);
76
+ }
77
+
78
+ :host([active])::before {
79
+ opacity: 0.05;
80
+ transition-duration: 0s;
81
+ }
82
+
83
+ :host([active])::after {
84
+ opacity: 0.1;
85
+ transition-duration: 0s, 0s;
86
+ transform: scale(0);
87
+ }
88
+
89
+ /* Keyboard focus */
90
+
91
+ :host([focus-ring]) {
92
+ box-shadow: 0 0 0 2px var(--lumo-primary-color-50pct);
93
+ }
94
+
95
+ :host([theme~='primary'][focus-ring]) {
96
+ box-shadow: 0 0 0 1px var(--lumo-base-color), 0 0 0 3px var(--lumo-primary-color-50pct);
97
+ }
98
+
99
+ /* Types (primary, tertiary, tertiary-inline */
100
+
101
+ :host([theme~='tertiary']),
102
+ :host([theme~='tertiary-inline']) {
103
+ background-color: transparent !important;
104
+ min-width: 0;
105
+ }
106
+
107
+ :host([theme~='tertiary']) {
108
+ padding: 0 calc(var(--lumo-button-size) / 6);
109
+ }
110
+
111
+ :host([theme~='tertiary-inline'])::before {
112
+ display: none;
113
+ }
114
+
115
+ :host([theme~='tertiary-inline']) {
116
+ margin: 0;
117
+ height: auto;
118
+ padding: 0;
119
+ line-height: inherit;
120
+ font-size: inherit;
121
+ }
122
+
123
+ :host([theme~='tertiary-inline']) [part='label'] {
124
+ padding: 0;
125
+ overflow: visible;
126
+ line-height: inherit;
127
+ }
128
+
129
+ :host([theme~='primary']) {
130
+ background-color: var(--_lumo-button-primary-background-color, var(--lumo-primary-color));
131
+ color: var(--_lumo-button-primary-color, var(--lumo-primary-contrast-color));
132
+ font-weight: 600;
133
+ min-width: calc(var(--lumo-button-size) * 2.5);
134
+ }
135
+
136
+ :host([theme~='primary'])::before {
137
+ background-color: black;
138
+ }
139
+
140
+ @media (any-hover: hover) {
141
+ :host([theme~='primary']:hover)::before {
142
+ opacity: 0.05;
143
+ }
144
+ }
145
+
146
+ :host([theme~='primary'][active])::before {
147
+ opacity: 0.1;
148
+ }
149
+
150
+ :host([theme~='primary'][active])::after {
151
+ opacity: 0.2;
152
+ }
153
+
154
+ /* Colors (success, error, contrast) */
155
+
156
+ :host([theme~='success']) {
157
+ color: var(--lumo-success-text-color);
158
+ }
159
+
160
+ :host([theme~='success'][theme~='primary']) {
161
+ background-color: var(--lumo-success-color);
162
+ color: var(--lumo-success-contrast-color);
163
+ }
164
+
165
+ :host([theme~='error']) {
166
+ color: var(--lumo-error-text-color);
167
+ }
168
+
169
+ :host([theme~='error'][theme~='primary']) {
170
+ background-color: var(--lumo-error-color);
171
+ color: var(--lumo-error-contrast-color);
172
+ }
173
+
174
+ :host([theme~='contrast']) {
175
+ color: var(--lumo-contrast);
176
+ }
177
+
178
+ :host([theme~='contrast'][theme~='primary']) {
179
+ background-color: var(--lumo-contrast);
180
+ color: var(--lumo-base-color);
181
+ }
182
+
183
+ /* Disabled state. Keep selectors after other color variants. */
184
+
185
+ :host([disabled]) {
186
+ pointer-events: none;
187
+ color: var(--lumo-disabled-text-color);
188
+ }
189
+
190
+ :host([theme~='primary'][disabled]) {
191
+ background-color: var(--lumo-contrast-30pct);
192
+ color: var(--lumo-base-color);
193
+ }
194
+
195
+ :host([theme~='primary'][disabled]) [part] {
196
+ opacity: 0.7;
197
+ }
198
+
199
+ /* Icons */
200
+
201
+ [part] ::slotted(vaadin-icon),
202
+ [part] ::slotted(iron-icon) {
203
+ display: inline-block;
204
+ width: var(--lumo-icon-size-m);
205
+ height: var(--lumo-icon-size-m);
206
+ }
207
+
208
+ /* Vaadin icons are based on a 16x16 grid (unlike Lumo and Material icons with 24x24), so they look too big by default */
209
+ [part] ::slotted(vaadin-icon[icon^='vaadin:']),
210
+ [part] ::slotted(iron-icon[icon^='vaadin:']) {
211
+ padding: 0.25em;
212
+ box-sizing: border-box !important;
213
+ }
214
+
215
+ [part='prefix'] {
216
+ margin-left: -0.25em;
217
+ margin-right: 0.25em;
218
+ }
219
+
220
+ [part='suffix'] {
221
+ margin-left: 0.25em;
222
+ margin-right: -0.25em;
223
+ }
224
+
225
+ /* Icon-only */
226
+
227
+ :host([theme~='icon']:not([theme~='tertiary-inline'])) {
228
+ min-width: var(--lumo-button-size);
229
+ padding-left: calc(var(--lumo-button-size) / 4);
230
+ padding-right: calc(var(--lumo-button-size) / 4);
231
+ }
232
+
233
+ :host([theme~='icon']) [part='prefix'],
234
+ :host([theme~='icon']) [part='suffix'] {
235
+ margin-left: 0;
236
+ margin-right: 0;
237
+ }
238
+
239
+ /* RTL specific styles */
240
+
241
+ :host([dir='rtl']) [part='prefix'] {
242
+ margin-left: 0.25em;
243
+ margin-right: -0.25em;
244
+ }
245
+
246
+ :host([dir='rtl']) [part='suffix'] {
247
+ margin-left: -0.25em;
248
+ margin-right: 0.25em;
249
+ }
250
+
251
+ :host([dir='rtl'][theme~='icon']) [part='prefix'],
252
+ :host([dir='rtl'][theme~='icon']) [part='suffix'] {
253
+ margin-left: 0;
254
+ margin-right: 0;
255
+ }
256
+ `;
257
+
258
+ registerStyles('vaadin-button', button, { moduleId: 'lumo-button' });
259
+
260
+ /**
261
+ @license
262
+ Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
263
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
264
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
265
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
266
+ Code distributed by Google as part of the polymer project is also
267
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
268
+ */
269
+
270
+ const passiveTouchGestures = false;
271
+ const wrap = (node) => node;
272
+
273
+ // Detect native touch action support
274
+ const HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
275
+ const GESTURE_KEY = '__polymerGestures';
276
+ const HANDLED_OBJ = '__polymerGesturesHandled';
277
+ const TOUCH_ACTION = '__polymerGesturesTouchAction';
278
+ // Radius for tap and track
279
+ const TAP_DISTANCE = 25;
280
+ const TRACK_DISTANCE = 5;
281
+ // Number of last N track positions to keep
282
+ const TRACK_LENGTH = 2;
283
+
284
+ const MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'click'];
285
+ // An array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons
286
+ const MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];
287
+ const MOUSE_HAS_BUTTONS = (function () {
288
+ try {
289
+ return new MouseEvent('test', { buttons: 1 }).buttons === 1;
290
+ } catch (e) {
291
+ return false;
292
+ }
293
+ })();
294
+
295
+ /**
296
+ * @param {string} name Possible mouse event name
297
+ * @return {boolean} true if mouse event, false if not
298
+ */
299
+ function isMouseEvent(name) {
300
+ return MOUSE_EVENTS.indexOf(name) > -1;
301
+ }
302
+
303
+ /* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
304
+ // check for passive event listeners
305
+ let supportsPassive = false;
306
+ (function () {
307
+ try {
308
+ const opts = Object.defineProperty({}, 'passive', {
309
+ // eslint-disable-next-line getter-return
310
+ get() {
311
+ supportsPassive = true;
312
+ },
313
+ });
314
+ window.addEventListener('test', null, opts);
315
+ window.removeEventListener('test', null, opts);
316
+ } catch (e) {}
317
+ })();
318
+
319
+ /**
320
+ * Generate settings for event listeners, dependant on `passiveTouchGestures`
321
+ *
322
+ * @param {string} eventName Event name to determine if `{passive}` option is
323
+ * needed
324
+ * @return {{passive: boolean} | undefined} Options to use for addEventListener
325
+ * and removeEventListener
326
+ */
327
+ function PASSIVE_TOUCH(eventName) {
328
+ if (isMouseEvent(eventName) || eventName === 'touchend') {
329
+ return;
330
+ }
331
+ if (HAS_NATIVE_TA && supportsPassive && passiveTouchGestures) {
332
+ return { passive: true };
333
+ }
334
+ }
335
+
336
+ // Check for touch-only devices
337
+ const IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
338
+
339
+ // Defined at https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
340
+ /** @type {!Object<boolean>} */
341
+ const canBeDisabled = {
342
+ button: true,
343
+ command: true,
344
+ fieldset: true,
345
+ input: true,
346
+ keygen: true,
347
+ optgroup: true,
348
+ option: true,
349
+ select: true,
350
+ textarea: true,
351
+ };
352
+
353
+ /**
354
+ * @param {MouseEvent} ev event to test for left mouse button down
355
+ * @return {boolean} has left mouse button down
356
+ */
357
+ function hasLeftMouseButton(ev) {
358
+ const type = ev.type;
359
+ // Exit early if the event is not a mouse event
360
+ if (!isMouseEvent(type)) {
361
+ return false;
362
+ }
363
+ // Ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
364
+ // instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)
365
+ if (type === 'mousemove') {
366
+ // Allow undefined for testing events
367
+ let buttons = ev.buttons === undefined ? 1 : ev.buttons;
368
+ if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
369
+ buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
370
+ }
371
+ // Buttons is a bitmask, check that the left button bit is set (1)
372
+ return Boolean(buttons & 1);
373
+ }
374
+ // Allow undefined for testing events
375
+ const button = ev.button === undefined ? 0 : ev.button;
376
+ // Ev.button is 0 in mousedown/mouseup/click for left button activation
377
+ return button === 0;
378
+ }
379
+
380
+ function isSyntheticClick(ev) {
381
+ if (ev.type === 'click') {
382
+ // Ev.detail is 0 for HTMLElement.click in most browsers
383
+ if (ev.detail === 0) {
384
+ return true;
385
+ }
386
+ // In the worst case, check that the x/y position of the click is within
387
+ // the bounding box of the target of the event
388
+ // Thanks IE 10 >:(
389
+ const t = _findOriginalTarget(ev);
390
+ // Make sure the target of the event is an element so we can use getBoundingClientRect,
391
+ // if not, just assume it is a synthetic click
392
+ if (!t.nodeType || /** @type {Element} */ (t).nodeType !== Node.ELEMENT_NODE) {
393
+ return true;
394
+ }
395
+ const bcr = /** @type {Element} */ (t).getBoundingClientRect();
396
+ // Use page x/y to account for scrolling
397
+ const x = ev.pageX,
398
+ y = ev.pageY;
399
+ // Ev is a synthetic click if the position is outside the bounding box of the target
400
+ return !(x >= bcr.left && x <= bcr.right && y >= bcr.top && y <= bcr.bottom);
401
+ }
402
+ return false;
403
+ }
404
+
405
+ const POINTERSTATE = {
406
+ mouse: {
407
+ target: null,
408
+ mouseIgnoreJob: null,
409
+ },
410
+ touch: {
411
+ x: 0,
412
+ y: 0,
413
+ id: -1,
414
+ scrollDecided: false,
415
+ },
416
+ };
417
+
418
+ function firstTouchAction(ev) {
419
+ let ta = 'auto';
420
+ const path = getComposedPath(ev);
421
+ for (let i = 0, n; i < path.length; i++) {
422
+ n = path[i];
423
+ if (n[TOUCH_ACTION]) {
424
+ ta = n[TOUCH_ACTION];
425
+ break;
426
+ }
427
+ }
428
+ return ta;
429
+ }
430
+
431
+ function trackDocument(stateObj, movefn, upfn) {
432
+ stateObj.movefn = movefn;
433
+ stateObj.upfn = upfn;
434
+ document.addEventListener('mousemove', movefn);
435
+ document.addEventListener('mouseup', upfn);
436
+ }
437
+
438
+ function untrackDocument(stateObj) {
439
+ document.removeEventListener('mousemove', stateObj.movefn);
440
+ document.removeEventListener('mouseup', stateObj.upfn);
441
+ stateObj.movefn = null;
442
+ stateObj.upfn = null;
443
+ }
444
+
445
+ /**
446
+ * Returns the composedPath for the given event.
447
+ * @param {Event} event to process
448
+ * @return {!Array<!EventTarget>} Path of the event
449
+ */
450
+ const getComposedPath =
451
+ window.ShadyDOM && window.ShadyDOM.noPatch
452
+ ? window.ShadyDOM.composedPath
453
+ : (event) => (event.composedPath && event.composedPath()) || [];
454
+
455
+ /** @type {!Object<string, !GestureRecognizer>} */
456
+ const gestures = {};
457
+
458
+ /** @type {!Array<!GestureRecognizer>} */
459
+ const recognizers = [];
460
+
461
+ /**
462
+ * Finds the element rendered on the screen at the provided coordinates.
463
+ *
464
+ * Similar to `document.elementFromPoint`, but pierces through
465
+ * shadow roots.
466
+ *
467
+ * @param {number} x Horizontal pixel coordinate
468
+ * @param {number} y Vertical pixel coordinate
469
+ * @return {Element} Returns the deepest shadowRoot inclusive element
470
+ * found at the screen position given.
471
+ */
472
+ function deepTargetFind(x, y) {
473
+ let node = document.elementFromPoint(x, y);
474
+ let next = node;
475
+ // This code path is only taken when native ShadowDOM is used
476
+ // if there is a shadowroot, it may have a node at x/y
477
+ // if there is not a shadowroot, exit the loop
478
+ while (next && next.shadowRoot && !window.ShadyDOM) {
479
+ // If there is a node at x/y in the shadowroot, look deeper
480
+ const oldNext = next;
481
+ next = next.shadowRoot.elementFromPoint(x, y);
482
+ // On Safari, elementFromPoint may return the shadowRoot host
483
+ if (oldNext === next) {
484
+ break;
485
+ }
486
+ if (next) {
487
+ node = next;
488
+ }
489
+ }
490
+ return node;
491
+ }
492
+
493
+ /**
494
+ * A cheaper check than ev.composedPath()[0];
495
+ *
496
+ * @private
497
+ * @param {Event|Touch} ev Event.
498
+ * @return {EventTarget} Returns the event target.
499
+ */
500
+ function _findOriginalTarget(ev) {
501
+ const path = getComposedPath(/** @type {?Event} */ (ev));
502
+ // It shouldn't be, but sometimes path is empty (window on Safari).
503
+ return path.length > 0 ? path[0] : ev.target;
504
+ }
505
+
506
+ /**
507
+ * @private
508
+ * @param {Event} ev Event.
509
+ * @return {void}
510
+ */
511
+ function _handleNative(ev) {
512
+ const type = ev.type;
513
+ const node = ev.currentTarget;
514
+ const gobj = node[GESTURE_KEY];
515
+ if (!gobj) {
516
+ return;
517
+ }
518
+ const gs = gobj[type];
519
+ if (!gs) {
520
+ return;
521
+ }
522
+ if (!ev[HANDLED_OBJ]) {
523
+ ev[HANDLED_OBJ] = {};
524
+ if (type.startsWith('touch')) {
525
+ const t = ev.changedTouches[0];
526
+ if (type === 'touchstart') {
527
+ // Only handle the first finger
528
+ if (ev.touches.length === 1) {
529
+ POINTERSTATE.touch.id = t.identifier;
530
+ }
531
+ }
532
+ if (POINTERSTATE.touch.id !== t.identifier) {
533
+ return;
534
+ }
535
+ if (!HAS_NATIVE_TA) {
536
+ if (type === 'touchstart' || type === 'touchmove') {
537
+ _handleTouchAction(ev);
538
+ }
539
+ }
540
+ }
541
+ }
542
+ const handled = ev[HANDLED_OBJ];
543
+ // Used to ignore synthetic mouse events
544
+ if (handled.skip) {
545
+ return;
546
+ }
547
+ // Reset recognizer state
548
+ for (let i = 0, r; i < recognizers.length; i++) {
549
+ r = recognizers[i];
550
+ if (gs[r.name] && !handled[r.name]) {
551
+ if (r.flow && r.flow.start.indexOf(ev.type) > -1 && r.reset) {
552
+ r.reset();
553
+ }
554
+ }
555
+ }
556
+ // Enforce gesture recognizer order
557
+ for (let i = 0, r; i < recognizers.length; i++) {
558
+ r = recognizers[i];
559
+ if (gs[r.name] && !handled[r.name]) {
560
+ handled[r.name] = true;
561
+ r[type](ev);
562
+ }
563
+ }
564
+ }
565
+
566
+ /**
567
+ * @private
568
+ * @param {TouchEvent} ev Event.
569
+ * @return {void}
570
+ */
571
+ function _handleTouchAction(ev) {
572
+ const t = ev.changedTouches[0];
573
+ const type = ev.type;
574
+ if (type === 'touchstart') {
575
+ POINTERSTATE.touch.x = t.clientX;
576
+ POINTERSTATE.touch.y = t.clientY;
577
+ POINTERSTATE.touch.scrollDecided = false;
578
+ } else if (type === 'touchmove') {
579
+ if (POINTERSTATE.touch.scrollDecided) {
580
+ return;
581
+ }
582
+ POINTERSTATE.touch.scrollDecided = true;
583
+ const ta = firstTouchAction(ev);
584
+ let shouldPrevent = false;
585
+ const dx = Math.abs(POINTERSTATE.touch.x - t.clientX);
586
+ const dy = Math.abs(POINTERSTATE.touch.y - t.clientY);
587
+ if (!ev.cancelable) ; else if (ta === 'none') {
588
+ shouldPrevent = true;
589
+ } else if (ta === 'pan-x') {
590
+ shouldPrevent = dy > dx;
591
+ } else if (ta === 'pan-y') {
592
+ shouldPrevent = dx > dy;
593
+ }
594
+ if (shouldPrevent) {
595
+ ev.preventDefault();
596
+ } else {
597
+ prevent('track');
598
+ }
599
+ }
600
+ }
601
+
602
+ /**
603
+ * Adds an event listener to a node for the given gesture type.
604
+ *
605
+ * @param {!EventTarget} node Node to add listener on
606
+ * @param {string} evType Gesture type: `down`, `up`, `track`, or `tap`
607
+ * @param {!function(!Event):void} handler Event listener function to call
608
+ * @return {boolean} Returns true if a gesture event listener was added.
609
+ */
610
+ function addListener(node, evType, handler) {
611
+ if (gestures[evType]) {
612
+ _add(node, evType, handler);
613
+ return true;
614
+ }
615
+ return false;
616
+ }
617
+
618
+ /**
619
+ * Automate the event listeners for the native events
620
+ *
621
+ * @private
622
+ * @param {!EventTarget} node Node on which to add the event.
623
+ * @param {string} evType Event type to add.
624
+ * @param {function(!Event)} handler Event handler function.
625
+ * @return {void}
626
+ */
627
+ function _add(node, evType, handler) {
628
+ const recognizer = gestures[evType];
629
+ const deps = recognizer.deps;
630
+ const name = recognizer.name;
631
+ let gobj = node[GESTURE_KEY];
632
+ if (!gobj) {
633
+ node[GESTURE_KEY] = gobj = {};
634
+ }
635
+ for (let i = 0, dep, gd; i < deps.length; i++) {
636
+ dep = deps[i];
637
+ // Don't add mouse handlers on iOS because they cause gray selection overlays
638
+ if (IS_TOUCH_ONLY && isMouseEvent(dep) && dep !== 'click') {
639
+ continue;
640
+ }
641
+ gd = gobj[dep];
642
+ if (!gd) {
643
+ gobj[dep] = gd = { _count: 0 };
644
+ }
645
+ if (gd._count === 0) {
646
+ node.addEventListener(dep, _handleNative, PASSIVE_TOUCH(dep));
647
+ }
648
+ gd[name] = (gd[name] || 0) + 1;
649
+ gd._count = (gd._count || 0) + 1;
650
+ }
651
+ node.addEventListener(evType, handler);
652
+ if (recognizer.touchAction) {
653
+ setTouchAction(node, recognizer.touchAction);
654
+ }
655
+ }
656
+
657
+ /**
658
+ * Registers a new gesture event recognizer for adding new custom
659
+ * gesture event types.
660
+ *
661
+ * @param {!GestureRecognizer} recog Gesture recognizer descriptor
662
+ * @return {void}
663
+ */
664
+ function register(recog) {
665
+ recognizers.push(recog);
666
+ for (let i = 0; i < recog.emits.length; i++) {
667
+ gestures[recog.emits[i]] = recog;
668
+ }
669
+ }
670
+
671
+ /**
672
+ * @private
673
+ * @param {string} evName Event name.
674
+ * @return {Object} Returns the gesture for the given event name.
675
+ */
676
+ function _findRecognizerByEvent(evName) {
677
+ for (let i = 0, r; i < recognizers.length; i++) {
678
+ r = recognizers[i];
679
+ for (let j = 0, n; j < r.emits.length; j++) {
680
+ n = r.emits[j];
681
+ if (n === evName) {
682
+ return r;
683
+ }
684
+ }
685
+ }
686
+ return null;
687
+ }
688
+
689
+ /**
690
+ * Sets scrolling direction on node.
691
+ *
692
+ * This value is checked on first move, thus it should be called prior to
693
+ * adding event listeners.
694
+ *
695
+ * @param {!EventTarget} node Node to set touch action setting on
696
+ * @param {string} value Touch action value
697
+ * @return {void}
698
+ */
699
+ function setTouchAction(node, value) {
700
+ if (HAS_NATIVE_TA && node instanceof HTMLElement) {
701
+ // NOTE: add touchAction async so that events can be added in
702
+ // custom element constructors. Otherwise we run afoul of custom
703
+ // elements restriction against settings attributes (style) in the
704
+ // constructor.
705
+ microTask.run(() => {
706
+ node.style.touchAction = value;
707
+ });
708
+ }
709
+ node[TOUCH_ACTION] = value;
710
+ }
711
+
712
+ /**
713
+ * Dispatches an event on the `target` element of `type` with the given
714
+ * `detail`.
715
+ * @private
716
+ * @param {!EventTarget} target The element on which to fire an event.
717
+ * @param {string} type The type of event to fire.
718
+ * @param {!Object=} detail The detail object to populate on the event.
719
+ * @return {void}
720
+ */
721
+ function _fire(target, type, detail) {
722
+ const ev = new Event(type, { bubbles: true, cancelable: true, composed: true });
723
+ ev.detail = detail;
724
+ wrap(/** @type {!Node} */ (target)).dispatchEvent(ev);
725
+ // Forward `preventDefault` in a clean way
726
+ if (ev.defaultPrevented) {
727
+ const preventer = detail.preventer || detail.sourceEvent;
728
+ if (preventer && preventer.preventDefault) {
729
+ preventer.preventDefault();
730
+ }
731
+ }
732
+ }
733
+
734
+ /**
735
+ * Prevents the dispatch and default action of the given event name.
736
+ *
737
+ * @param {string} evName Event name.
738
+ * @return {void}
739
+ */
740
+ function prevent(evName) {
741
+ const recognizer = _findRecognizerByEvent(evName);
742
+ if (recognizer.info) {
743
+ recognizer.info.prevent = true;
744
+ }
745
+ }
746
+
747
+ register({
748
+ name: 'downup',
749
+ deps: ['mousedown', 'touchstart', 'touchend'],
750
+ flow: {
751
+ start: ['mousedown', 'touchstart'],
752
+ end: ['mouseup', 'touchend'],
753
+ },
754
+ emits: ['down', 'up'],
755
+
756
+ info: {
757
+ movefn: null,
758
+ upfn: null,
759
+ },
760
+
761
+ /**
762
+ * @this {GestureRecognizer}
763
+ * @return {void}
764
+ */
765
+ reset() {
766
+ untrackDocument(this.info);
767
+ },
768
+
769
+ /**
770
+ * @this {GestureRecognizer}
771
+ * @param {MouseEvent} e
772
+ * @return {void}
773
+ */
774
+ mousedown(e) {
775
+ if (!hasLeftMouseButton(e)) {
776
+ return;
777
+ }
778
+ const t = _findOriginalTarget(e);
779
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
780
+ const self = this;
781
+ const movefn = (e) => {
782
+ if (!hasLeftMouseButton(e)) {
783
+ downupFire('up', t, e);
784
+ untrackDocument(self.info);
785
+ }
786
+ };
787
+ const upfn = (e) => {
788
+ if (hasLeftMouseButton(e)) {
789
+ downupFire('up', t, e);
790
+ }
791
+ untrackDocument(self.info);
792
+ };
793
+ trackDocument(this.info, movefn, upfn);
794
+ downupFire('down', t, e);
795
+ },
796
+
797
+ /**
798
+ * @this {GestureRecognizer}
799
+ * @param {TouchEvent} e
800
+ * @return {void}
801
+ */
802
+ touchstart(e) {
803
+ downupFire('down', _findOriginalTarget(e), e.changedTouches[0], e);
804
+ },
805
+
806
+ /**
807
+ * @this {GestureRecognizer}
808
+ * @param {TouchEvent} e
809
+ * @return {void}
810
+ */
811
+ touchend(e) {
812
+ downupFire('up', _findOriginalTarget(e), e.changedTouches[0], e);
813
+ },
814
+ });
815
+
816
+ /**
817
+ * @param {string} type
818
+ * @param {EventTarget} target
819
+ * @param {Event|Touch} event
820
+ * @param {Event=} preventer
821
+ * @return {void}
822
+ */
823
+ function downupFire(type, target, event, preventer) {
824
+ if (!target) {
825
+ return;
826
+ }
827
+ _fire(target, type, {
828
+ x: event.clientX,
829
+ y: event.clientY,
830
+ sourceEvent: event,
831
+ preventer,
832
+ prevent(e) {
833
+ return prevent(e);
834
+ },
835
+ });
836
+ }
837
+
838
+ register({
839
+ name: 'track',
840
+ touchAction: 'none',
841
+ deps: ['mousedown', 'touchstart', 'touchmove', 'touchend'],
842
+ flow: {
843
+ start: ['mousedown', 'touchstart'],
844
+ end: ['mouseup', 'touchend'],
845
+ },
846
+ emits: ['track'],
847
+
848
+ info: {
849
+ x: 0,
850
+ y: 0,
851
+ state: 'start',
852
+ started: false,
853
+ moves: [],
854
+ /** @this {GestureInfo} */
855
+ addMove(move) {
856
+ if (this.moves.length > TRACK_LENGTH) {
857
+ this.moves.shift();
858
+ }
859
+ this.moves.push(move);
860
+ },
861
+ movefn: null,
862
+ upfn: null,
863
+ prevent: false,
864
+ },
865
+
866
+ /**
867
+ * @this {GestureRecognizer}
868
+ * @return {void}
869
+ */
870
+ reset() {
871
+ this.info.state = 'start';
872
+ this.info.started = false;
873
+ this.info.moves = [];
874
+ this.info.x = 0;
875
+ this.info.y = 0;
876
+ this.info.prevent = false;
877
+ untrackDocument(this.info);
878
+ },
879
+
880
+ /**
881
+ * @this {GestureRecognizer}
882
+ * @param {MouseEvent} e
883
+ * @return {void}
884
+ */
885
+ mousedown(e) {
886
+ if (!hasLeftMouseButton(e)) {
887
+ return;
888
+ }
889
+ const t = _findOriginalTarget(e);
890
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
891
+ const self = this;
892
+ const movefn = (e) => {
893
+ const x = e.clientX,
894
+ y = e.clientY;
895
+ if (trackHasMovedEnough(self.info, x, y)) {
896
+ // First move is 'start', subsequent moves are 'move', mouseup is 'end'
897
+ self.info.state = self.info.started ? (e.type === 'mouseup' ? 'end' : 'track') : 'start';
898
+ if (self.info.state === 'start') {
899
+ // If and only if tracking, always prevent tap
900
+ prevent('tap');
901
+ }
902
+ self.info.addMove({ x, y });
903
+ if (!hasLeftMouseButton(e)) {
904
+ // Always fire "end"
905
+ self.info.state = 'end';
906
+ untrackDocument(self.info);
907
+ }
908
+ if (t) {
909
+ trackFire(self.info, t, e);
910
+ }
911
+ self.info.started = true;
912
+ }
913
+ };
914
+ const upfn = (e) => {
915
+ if (self.info.started) {
916
+ movefn(e);
917
+ }
918
+
919
+ // Remove the temporary listeners
920
+ untrackDocument(self.info);
921
+ };
922
+ // Add temporary document listeners as mouse retargets
923
+ trackDocument(this.info, movefn, upfn);
924
+ this.info.x = e.clientX;
925
+ this.info.y = e.clientY;
926
+ },
927
+
928
+ /**
929
+ * @this {GestureRecognizer}
930
+ * @param {TouchEvent} e
931
+ * @return {void}
932
+ */
933
+ touchstart(e) {
934
+ const ct = e.changedTouches[0];
935
+ this.info.x = ct.clientX;
936
+ this.info.y = ct.clientY;
937
+ },
938
+
939
+ /**
940
+ * @this {GestureRecognizer}
941
+ * @param {TouchEvent} e
942
+ * @return {void}
943
+ */
944
+ touchmove(e) {
945
+ const t = _findOriginalTarget(e);
946
+ const ct = e.changedTouches[0];
947
+ const x = ct.clientX,
948
+ y = ct.clientY;
949
+ if (trackHasMovedEnough(this.info, x, y)) {
950
+ if (this.info.state === 'start') {
951
+ // If and only if tracking, always prevent tap
952
+ prevent('tap');
953
+ }
954
+ this.info.addMove({ x, y });
955
+ trackFire(this.info, t, ct);
956
+ this.info.state = 'track';
957
+ this.info.started = true;
958
+ }
959
+ },
960
+
961
+ /**
962
+ * @this {GestureRecognizer}
963
+ * @param {TouchEvent} e
964
+ * @return {void}
965
+ */
966
+ touchend(e) {
967
+ const t = _findOriginalTarget(e);
968
+ const ct = e.changedTouches[0];
969
+ // Only trackend if track was started and not aborted
970
+ if (this.info.started) {
971
+ // Reset started state on up
972
+ this.info.state = 'end';
973
+ this.info.addMove({ x: ct.clientX, y: ct.clientY });
974
+ trackFire(this.info, t, ct);
975
+ }
976
+ },
977
+ });
978
+
979
+ /**
980
+ * @param {!GestureInfo} info
981
+ * @param {number} x
982
+ * @param {number} y
983
+ * @return {boolean}
984
+ */
985
+ function trackHasMovedEnough(info, x, y) {
986
+ if (info.prevent) {
987
+ return false;
988
+ }
989
+ if (info.started) {
990
+ return true;
991
+ }
992
+ const dx = Math.abs(info.x - x);
993
+ const dy = Math.abs(info.y - y);
994
+ return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE;
995
+ }
996
+
997
+ /**
998
+ * @param {!GestureInfo} info
999
+ * @param {?EventTarget} target
1000
+ * @param {Touch} touch
1001
+ * @return {void}
1002
+ */
1003
+ function trackFire(info, target, touch) {
1004
+ if (!target) {
1005
+ return;
1006
+ }
1007
+ const secondlast = info.moves[info.moves.length - 2];
1008
+ const lastmove = info.moves[info.moves.length - 1];
1009
+ const dx = lastmove.x - info.x;
1010
+ const dy = lastmove.y - info.y;
1011
+ let ddx,
1012
+ ddy = 0;
1013
+ if (secondlast) {
1014
+ ddx = lastmove.x - secondlast.x;
1015
+ ddy = lastmove.y - secondlast.y;
1016
+ }
1017
+ _fire(target, 'track', {
1018
+ state: info.state,
1019
+ x: touch.clientX,
1020
+ y: touch.clientY,
1021
+ dx,
1022
+ dy,
1023
+ ddx,
1024
+ ddy,
1025
+ sourceEvent: touch,
1026
+ hover() {
1027
+ return deepTargetFind(touch.clientX, touch.clientY);
1028
+ },
1029
+ });
1030
+ }
1031
+
1032
+ register({
1033
+ name: 'tap',
1034
+ deps: ['mousedown', 'click', 'touchstart', 'touchend'],
1035
+ flow: {
1036
+ start: ['mousedown', 'touchstart'],
1037
+ end: ['click', 'touchend'],
1038
+ },
1039
+ emits: ['tap'],
1040
+ info: {
1041
+ x: NaN,
1042
+ y: NaN,
1043
+ prevent: false,
1044
+ },
1045
+
1046
+ /**
1047
+ * @this {GestureRecognizer}
1048
+ * @return {void}
1049
+ */
1050
+ reset() {
1051
+ this.info.x = NaN;
1052
+ this.info.y = NaN;
1053
+ this.info.prevent = false;
1054
+ },
1055
+
1056
+ /**
1057
+ * @this {GestureRecognizer}
1058
+ * @param {MouseEvent} e
1059
+ * @return {void}
1060
+ */
1061
+ mousedown(e) {
1062
+ if (hasLeftMouseButton(e)) {
1063
+ this.info.x = e.clientX;
1064
+ this.info.y = e.clientY;
1065
+ }
1066
+ },
1067
+
1068
+ /**
1069
+ * @this {GestureRecognizer}
1070
+ * @param {MouseEvent} e
1071
+ * @return {void}
1072
+ */
1073
+ click(e) {
1074
+ if (hasLeftMouseButton(e)) {
1075
+ trackForward(this.info, e);
1076
+ }
1077
+ },
1078
+
1079
+ /**
1080
+ * @this {GestureRecognizer}
1081
+ * @param {TouchEvent} e
1082
+ * @return {void}
1083
+ */
1084
+ touchstart(e) {
1085
+ const touch = e.changedTouches[0];
1086
+ this.info.x = touch.clientX;
1087
+ this.info.y = touch.clientY;
1088
+ },
1089
+
1090
+ /**
1091
+ * @this {GestureRecognizer}
1092
+ * @param {TouchEvent} e
1093
+ * @return {void}
1094
+ */
1095
+ touchend(e) {
1096
+ trackForward(this.info, e.changedTouches[0], e);
1097
+ },
1098
+ });
1099
+
1100
+ /**
1101
+ * @param {!GestureInfo} info
1102
+ * @param {Event | Touch} e
1103
+ * @param {Event=} preventer
1104
+ * @return {void}
1105
+ */
1106
+ function trackForward(info, e, preventer) {
1107
+ const dx = Math.abs(e.clientX - info.x);
1108
+ const dy = Math.abs(e.clientY - info.y);
1109
+ // Find original target from `preventer` for TouchEvents, or `e` for MouseEvents
1110
+ const t = _findOriginalTarget(preventer || e);
1111
+ if (!t || (canBeDisabled[/** @type {!HTMLElement} */ (t).localName] && t.hasAttribute('disabled'))) {
1112
+ return;
1113
+ }
1114
+ // Dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`
1115
+ if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {
1116
+ // Prevent taps from being generated if an event has canceled them
1117
+ if (!info.prevent) {
1118
+ _fire(t, 'tap', {
1119
+ x: e.clientX,
1120
+ y: e.clientY,
1121
+ sourceEvent: e,
1122
+ preventer,
1123
+ });
1124
+ }
1125
+ }
1126
+ }
1127
+
1128
+ /**
1129
+ * @license
1130
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
1131
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1132
+ */
1133
+
1134
+ /**
1135
+ * A mixin to toggle the `active` attribute.
1136
+ *
1137
+ * The attribute is set whenever the user activates the element by a pointer
1138
+ * or presses an activation key on the element from the keyboard.
1139
+ *
1140
+ * The attribute is removed as soon as the element is deactivated
1141
+ * by the pointer or by releasing the activation key.
1142
+ *
1143
+ * @polymerMixin
1144
+ */
1145
+ const ActiveMixin = (superclass) =>
1146
+ class ActiveMixinClass extends DisabledMixin(KeyboardMixin(superclass)) {
1147
+ /**
1148
+ * An array of activation keys.
1149
+ *
1150
+ * See possible values here:
1151
+ * https://developer.mozilla.org/ru/docs/Web/API/KeyboardEvent/key/Key_Values
1152
+ *
1153
+ * @protected
1154
+ * @return {!Array<!string>}
1155
+ */
1156
+ get _activeKeys() {
1157
+ return [' '];
1158
+ }
1159
+
1160
+ /** @protected */
1161
+ ready() {
1162
+ super.ready();
1163
+
1164
+ addListener(this, 'down', (event) => {
1165
+ if (this._shouldSetActive(event)) {
1166
+ this._setActive(true);
1167
+ }
1168
+ });
1169
+
1170
+ addListener(this, 'up', () => {
1171
+ this._setActive(false);
1172
+ });
1173
+ }
1174
+
1175
+ /** @protected */
1176
+ disconnectedCallback() {
1177
+ super.disconnectedCallback();
1178
+
1179
+ // When the element is disconnecting from the DOM at the moment being active,
1180
+ // the `active` attribute needs to be manually removed from the element.
1181
+ // Otherwise, it will preserve on the element until the element is activated once again.
1182
+ // The case reproduces for `<vaadin-date-picker>` when closing on `Cancel` or `Today` click.
1183
+ this._setActive(false);
1184
+ }
1185
+
1186
+ /**
1187
+ * @param {KeyboardEvent | MouseEvent} _event
1188
+ * @protected
1189
+ */
1190
+ _shouldSetActive(_event) {
1191
+ return !this.disabled;
1192
+ }
1193
+
1194
+ /**
1195
+ * Sets the `active` attribute on the element if an activation key is pressed.
1196
+ *
1197
+ * @param {KeyboardEvent} event
1198
+ * @protected
1199
+ * @override
1200
+ */
1201
+ _onKeyDown(event) {
1202
+ super._onKeyDown(event);
1203
+
1204
+ if (this._shouldSetActive(event) && this._activeKeys.includes(event.key)) {
1205
+ this._setActive(true);
1206
+
1207
+ // Element can become hidden before the `keyup` event, e.g. on button click.
1208
+ // Use document listener to ensure `active` attribute is removed correctly.
1209
+ document.addEventListener(
1210
+ 'keyup',
1211
+ (e) => {
1212
+ if (this._activeKeys.includes(e.key)) {
1213
+ this._setActive(false);
1214
+ }
1215
+ },
1216
+ { once: true },
1217
+ );
1218
+ }
1219
+ }
1220
+
1221
+ /**
1222
+ * Toggles the `active` attribute on the element.
1223
+ *
1224
+ * @param {boolean} active
1225
+ * @protected
1226
+ */
1227
+ _setActive(active) {
1228
+ this.toggleAttribute('active', active);
1229
+ }
1230
+ };
1231
+
1232
+ /**
1233
+ * @license
1234
+ * Copyright (c) 2017 - 2022 Vaadin Ltd.
1235
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1236
+ */
1237
+
1238
+ /**
1239
+ * A mixin providing common button functionality.
1240
+ *
1241
+ * @polymerMixin
1242
+ * @mixes ActiveMixin
1243
+ * @mixes FocusMixin
1244
+ * @mixes TabindexMixin
1245
+ */
1246
+ const ButtonMixin = (superClass) =>
1247
+ class ButtonMixinClass extends ActiveMixin(TabindexMixin(FocusMixin(superClass))) {
1248
+ static get properties() {
1249
+ return {
1250
+ /**
1251
+ * Indicates whether the element can be focused and where it participates in sequential keyboard navigation.
1252
+ *
1253
+ * @override
1254
+ * @protected
1255
+ */
1256
+ tabindex: {
1257
+ value: 0,
1258
+ },
1259
+ };
1260
+ }
1261
+
1262
+ /**
1263
+ * By default, `Space` is the only possible activation key for a focusable HTML element.
1264
+ * Nonetheless, the button is an exception as it can be also activated by pressing `Enter`.
1265
+ * See the "Keyboard Support" section in https://www.w3.org/TR/wai-aria-practices/examples/button/button.html.
1266
+ *
1267
+ * @protected
1268
+ * @override
1269
+ */
1270
+ get _activeKeys() {
1271
+ return ['Enter', ' '];
1272
+ }
1273
+
1274
+ /** @protected */
1275
+ ready() {
1276
+ super.ready();
1277
+
1278
+ // By default, if the user hasn't provided a custom role,
1279
+ // the role attribute is set to "button".
1280
+ if (!this.hasAttribute('role')) {
1281
+ this.setAttribute('role', 'button');
1282
+ }
1283
+ }
1284
+
1285
+ /**
1286
+ * Since the button component is designed on the base of the `[role=button]` attribute,
1287
+ * and doesn't have a native <button> inside, in order to be fully accessible from the keyboard,
1288
+ * it should manually fire the `click` event once an activation key is pressed,
1289
+ * as it follows from the WAI-ARIA specifications:
1290
+ * https://www.w3.org/TR/wai-aria-practices-1.1/#button
1291
+ *
1292
+ * According to the UI Events specifications,
1293
+ * the `click` event should be fired exactly on `keydown`:
1294
+ * https://www.w3.org/TR/uievents/#event-type-keydown
1295
+ *
1296
+ * @param {KeyboardEvent} event
1297
+ * @protected
1298
+ * @override
1299
+ */
1300
+ _onKeyDown(event) {
1301
+ super._onKeyDown(event);
1302
+
1303
+ if (this._activeKeys.includes(event.key)) {
1304
+ event.preventDefault();
1305
+
1306
+ // `DisabledMixin` overrides the standard `click()` method
1307
+ // so that it doesn't fire the `click` event when the element is disabled.
1308
+ this.click();
1309
+ }
1310
+ }
1311
+ };
1312
+
1313
+ /**
1314
+ * @license
1315
+ * Copyright (c) 2017 - 2022 Vaadin Ltd.
1316
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1317
+ */
1318
+
1319
+ /**
1320
+ * `<vaadin-button>` is an accessible and customizable button that allows users to perform actions.
1321
+ *
1322
+ * ```html
1323
+ * <vaadin-button>Press me</vaadin-button>
1324
+ * ```
1325
+ *
1326
+ * ### Styling
1327
+ *
1328
+ * The following shadow DOM parts are available for styling:
1329
+ *
1330
+ * Part name | Description
1331
+ * ----------|-------------
1332
+ * `label` | The label (text) inside the button.
1333
+ * `prefix` | A slot for content before the label (e.g. an icon).
1334
+ * `suffix` | A slot for content after the label (e.g. an icon).
1335
+ *
1336
+ * The following attributes are available for styling:
1337
+ *
1338
+ * Attribute | Description
1339
+ * -------------|-------------
1340
+ * `active` | Set when the button is pressed down, either with mouse, touch or the keyboard.
1341
+ * `disabled` | Set when the button is disabled.
1342
+ * `focus-ring` | Set when the button is focused using the keyboard.
1343
+ * `focused` | Set when the button is focused.
1344
+ *
1345
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
1346
+ *
1347
+ * @extends HTMLElement
1348
+ * @mixes ButtonMixin
1349
+ * @mixes ControllerMixin
1350
+ * @mixes ElementMixin
1351
+ * @mixes ThemableMixin
1352
+ */
1353
+ class Button extends ButtonMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))) {
1354
+ static get is() {
1355
+ return 'vaadin-button';
1356
+ }
1357
+
1358
+ static get template() {
1359
+ return html`
1360
+ <style>
1361
+ :host {
1362
+ display: inline-block;
1363
+ position: relative;
1364
+ outline: none;
1365
+ white-space: nowrap;
1366
+ -webkit-user-select: none;
1367
+ -moz-user-select: none;
1368
+ user-select: none;
1369
+ }
1370
+
1371
+ :host([hidden]) {
1372
+ display: none !important;
1373
+ }
1374
+
1375
+ /* Aligns the button with form fields when placed on the same line.
1376
+ Note, to make it work, the form fields should have the same "::before" pseudo-element. */
1377
+ .vaadin-button-container::before {
1378
+ content: '\\2003';
1379
+ display: inline-block;
1380
+ width: 0;
1381
+ max-height: 100%;
1382
+ }
1383
+
1384
+ .vaadin-button-container {
1385
+ display: inline-flex;
1386
+ align-items: center;
1387
+ justify-content: center;
1388
+ text-align: center;
1389
+ width: 100%;
1390
+ height: 100%;
1391
+ min-height: inherit;
1392
+ text-shadow: inherit;
1393
+ }
1394
+
1395
+ [part='prefix'],
1396
+ [part='suffix'] {
1397
+ flex: none;
1398
+ }
1399
+
1400
+ [part='label'] {
1401
+ white-space: nowrap;
1402
+ overflow: hidden;
1403
+ text-overflow: ellipsis;
1404
+ }
1405
+ </style>
1406
+ <div class="vaadin-button-container">
1407
+ <span part="prefix" aria-hidden="true">
1408
+ <slot name="prefix"></slot>
1409
+ </span>
1410
+ <span part="label">
1411
+ <slot></slot>
1412
+ </span>
1413
+ <span part="suffix" aria-hidden="true">
1414
+ <slot name="suffix"></slot>
1415
+ </span>
1416
+ </div>
1417
+ <slot name="tooltip"></slot>
1418
+ `;
1419
+ }
1420
+
1421
+ /** @protected */
1422
+ ready() {
1423
+ super.ready();
1424
+
1425
+ this._tooltipController = new TooltipController(this);
1426
+ this.addController(this._tooltipController);
1427
+ }
1428
+ }
1429
+
1430
+ customElements.define(Button.is, Button);
1431
+
1432
+ export { Button as B, addListener as a, button as b, setTouchAction as s };