@everymatrix/general-input 1.27.6 → 1.27.8

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,6 +1,6 @@
1
1
  import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
2
2
  import { t as translate, a as tooltipIconSvg } from './tooltipIcon.js';
3
- import { r as registerStyles, i, d as dedupingMixin, D as DelegateStateMixin, a as DisabledMixin, I as InputMixin, b as isElementFocused, L as LabelMixin, c as DelegateFocusMixin, E as ElementMixin, T as ThemableMixin, C as ControllerMixin, P as PolymerElement, h as html, e as InputController, f as LabelledInputController, g as TooltipController, j as requiredField, k as helper, F as FieldMixin, l as FocusMixin, m as FlattenedNodesObserver } from './field-mixin.js';
3
+ import { r as registerStyles, i, d as dedupingMixin, D as DelegateStateMixin, a as DisabledMixin, I as InputMixin, L as LabelMixin, b as DelegateFocusMixin, c as InputController, e as LabelledInputController, h as html, T as TooltipController, f as defineCustomElement$1, E as ElementMixin, g as ThemableMixin, P as PolymerElement, j as requiredField, k as helper, F as FieldMixin, l as FocusMixin, S as SlotObserver } from './field-mixin.js';
4
4
  import { A as ActiveMixin } from './active-mixin.js';
5
5
 
6
6
  registerStyles(
@@ -36,6 +36,13 @@ registerStyles(
36
36
  background-color: var(--lumo-contrast-20pct);
37
37
  transition: transform 0.2s cubic-bezier(0.12, 0.32, 0.54, 2), background-color 0.15s;
38
38
  cursor: var(--lumo-clickable-cursor);
39
+ /* Default field border color */
40
+ --_input-border-color: var(--vaadin-input-field-border-color, var(--lumo-contrast-50pct));
41
+ }
42
+
43
+ :host([indeterminate]),
44
+ :host([checked]) {
45
+ --vaadin-input-field-border-color: transparent;
39
46
  }
40
47
 
41
48
  :host([indeterminate]) [part='checkbox'],
@@ -77,13 +84,15 @@ registerStyles(
77
84
 
78
85
  /* Focus ring */
79
86
  :host([focus-ring]) [part='checkbox'] {
80
- box-shadow: 0 0 0 1px var(--lumo-base-color), 0 0 0 3px var(--lumo-primary-color-50pct);
87
+ box-shadow: 0 0 0 1px var(--lumo-base-color), 0 0 0 3px var(--lumo-primary-color-50pct),
88
+ inset 0 0 0 var(--_input-border-width, 0) var(--_input-border-color);
81
89
  }
82
90
 
83
91
  /* Disabled */
84
92
  :host([disabled]) {
85
93
  pointer-events: none;
86
94
  color: var(--lumo-disabled-text-color);
95
+ --vaadin-input-field-border-color: var(--lumo-contrast-20pct);
87
96
  }
88
97
 
89
98
  :host([disabled]) ::slotted(label) {
@@ -154,7 +163,7 @@ registerStyles(
154
163
 
155
164
  /**
156
165
  * @license
157
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
166
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
158
167
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
159
168
  */
160
169
 
@@ -197,12 +206,6 @@ const CheckedMixin = dedupingMixin(
197
206
  const input = event.target;
198
207
 
199
208
  this._toggleChecked(input.checked);
200
-
201
- // Clicking the checkbox or radio-button in Safari
202
- // does not make it focused, so we do it manually.
203
- if (!isElementFocused(input)) {
204
- input.focus();
205
- }
206
209
  }
207
210
 
208
211
  /** @protected */
@@ -214,134 +217,226 @@ const CheckedMixin = dedupingMixin(
214
217
 
215
218
  /**
216
219
  * @license
217
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
220
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
218
221
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
219
222
  */
220
223
 
221
224
  /**
222
- * A controller to copy the content from a source slot to a target element.
225
+ * A mixin providing common checkbox functionality.
226
+ *
227
+ * @polymerMixin
228
+ * @mixes ActiveMixin
229
+ * @mixes CheckedMixin
230
+ * @mixes DelegateFocusMixin
231
+ * @mixes LabelMixin
223
232
  */
224
- class SlotTargetController {
225
- constructor(sourceSlot, targetFactory, callback) {
226
- /**
227
- * The source `<slot>` element to copy nodes from.
228
- */
229
- this.sourceSlot = sourceSlot;
233
+ const CheckboxMixin = (superclass) =>
234
+ class CheckboxMixinClass extends LabelMixin(CheckedMixin(DelegateFocusMixin(ActiveMixin(superclass)))) {
235
+ static get properties() {
236
+ return {
237
+ /**
238
+ * True if the checkbox is in the indeterminate state which means
239
+ * it is not possible to say whether it is checked or unchecked.
240
+ * The state is reset once the user switches the checkbox by hand.
241
+ *
242
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Indeterminate_state_checkboxes
243
+ *
244
+ * @type {boolean}
245
+ */
246
+ indeterminate: {
247
+ type: Boolean,
248
+ notify: true,
249
+ value: false,
250
+ reflectToAttribute: true,
251
+ },
252
+
253
+ /**
254
+ * The name of the checkbox.
255
+ *
256
+ * @type {string}
257
+ */
258
+ name: {
259
+ type: String,
260
+ value: '',
261
+ },
262
+
263
+ /**
264
+ * Indicates whether the element can be focused and where it participates in sequential keyboard navigation.
265
+ *
266
+ * @override
267
+ * @protected
268
+ */
269
+ tabindex: {
270
+ type: Number,
271
+ value: 0,
272
+ reflectToAttribute: true,
273
+ },
274
+ };
275
+ }
276
+
277
+ /** @override */
278
+ static get delegateProps() {
279
+ return [...super.delegateProps, 'indeterminate'];
280
+ }
281
+
282
+ /** @override */
283
+ static get delegateAttrs() {
284
+ return [...super.delegateAttrs, 'name'];
285
+ }
286
+
287
+ constructor() {
288
+ super();
289
+
290
+ this._setType('checkbox');
291
+
292
+ // Set the string "on" as the default value for the checkbox following the HTML specification:
293
+ // https://html.spec.whatwg.org/multipage/input.html#dom-input-value-default-on
294
+ this.value = 'on';
295
+ }
296
+
297
+ /** @protected */
298
+ ready() {
299
+ super.ready();
300
+
301
+ this.addController(
302
+ new InputController(this, (input) => {
303
+ this._setInputElement(input);
304
+ this._setFocusElement(input);
305
+ this.stateTarget = input;
306
+ this.ariaTarget = input;
307
+ }),
308
+ );
309
+ this.addController(new LabelledInputController(this.inputElement, this._labelController));
310
+ }
230
311
 
231
312
  /**
232
- * Function used to get a reference to slot target.
313
+ * Override method inherited from `ActiveMixin` to prevent setting
314
+ * `active` attribute when clicking a link placed inside the label.
315
+ *
316
+ * @param {Event} event
317
+ * @return {boolean}
318
+ * @protected
319
+ * @override
233
320
  */
234
- this.targetFactory = targetFactory;
321
+ _shouldSetActive(event) {
322
+ if (event.target.localName === 'a') {
323
+ return false;
324
+ }
325
+
326
+ return super._shouldSetActive(event);
327
+ }
235
328
 
236
329
  /**
237
- * Function called after copying nodes to target.
330
+ * Override method inherited from `CheckedMixin` to reset
331
+ * `indeterminate` state checkbox is toggled by the user.
332
+ *
333
+ * @param {boolean} checked
334
+ * @protected
335
+ * @override
238
336
  */
239
- this.copyCallback = callback;
240
-
241
- if (sourceSlot) {
242
- sourceSlot.addEventListener('slotchange', () => {
243
- // Copy in progress, ignore this event.
244
- if (this.__copying) {
245
- this.__copying = false;
246
- } else {
247
- this.__checkAndCopyNodesToSlotTarget();
248
- }
249
- });
337
+ _toggleChecked(checked) {
338
+ if (this.indeterminate) {
339
+ this.indeterminate = false;
340
+ }
341
+
342
+ super._toggleChecked(checked);
250
343
  }
344
+ };
345
+
346
+ /**
347
+ * @license
348
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
349
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
350
+ */
351
+
352
+ const checkboxStyles = i`
353
+ :host {
354
+ display: inline-block;
251
355
  }
252
356
 
253
- hostConnected() {
254
- this.__sourceSlotObserver = new MutationObserver(() => this.__checkAndCopyNodesToSlotTarget());
357
+ :host([hidden]) {
358
+ display: none !important;
359
+ }
255
360
 
256
- // Ensure the content is up to date when host is connected
257
- // to handle e.g. mutating text content while disconnected.
258
- // Note, `hostConnected()` is called twice if the controller
259
- // is initialized in `ready()` when using `ControllerMixin`.
260
- if (!this.__copying) {
261
- this.__checkAndCopyNodesToSlotTarget();
262
- }
361
+ :host([disabled]) {
362
+ -webkit-tap-highlight-color: transparent;
263
363
  }
264
364
 
265
- /**
266
- * Copies every node from the source slot to the target element
267
- * once the source slot' content is changed.
268
- *
269
- * @private
270
- */
271
- __checkAndCopyNodesToSlotTarget() {
272
- this.__sourceSlotObserver.disconnect();
365
+ .vaadin-checkbox-container {
366
+ display: grid;
367
+ grid-template-columns: auto 1fr;
368
+ align-items: baseline;
369
+ }
273
370
 
274
- // Ensure slot target element is up to date.
275
- const slotTarget = this.targetFactory();
371
+ [part='checkbox'],
372
+ ::slotted(input),
373
+ ::slotted(label) {
374
+ grid-row: 1;
375
+ }
276
376
 
277
- if (!slotTarget) {
278
- return;
279
- }
377
+ [part='checkbox'],
378
+ ::slotted(input) {
379
+ grid-column: 1;
380
+ }
280
381
 
281
- // Remove any existing clones from the slot target
282
- if (this.__slotTargetClones) {
283
- this.__slotTargetClones.forEach((node) => {
284
- if (node.parentElement === slotTarget) {
285
- slotTarget.removeChild(node);
286
- }
287
- });
288
- delete this.__slotTargetClones;
289
- }
382
+ [part='checkbox'] {
383
+ width: var(--vaadin-checkbox-size, 1em);
384
+ height: var(--vaadin-checkbox-size, 1em);
385
+ --_input-border-width: var(--vaadin-input-field-border-width, 0);
386
+ --_input-border-color: var(--vaadin-input-field-border-color, transparent);
387
+ box-shadow: inset 0 0 0 var(--_input-border-width, 0) var(--_input-border-color);
388
+ }
290
389
 
291
- // Exclude whitespace text nodes
292
- const nodes = this.sourceSlot
293
- .assignedNodes({ flatten: true })
294
- .filter((node) => !(node.nodeType === Node.TEXT_NODE && node.textContent.trim() === ''));
390
+ [part='checkbox']::before {
391
+ display: block;
392
+ content: '\\202F';
393
+ line-height: var(--vaadin-checkbox-size, 1em);
394
+ contain: paint;
395
+ }
295
396
 
296
- if (nodes.length > 0) {
297
- slotTarget.innerHTML = '';
397
+ /* visually hidden */
398
+ ::slotted(input) {
399
+ opacity: 0;
400
+ cursor: inherit;
401
+ margin: 0;
402
+ align-self: stretch;
403
+ -webkit-appearance: none;
404
+ width: initial;
405
+ height: initial;
406
+ }
298
407
 
299
- // Ignore next slotchange
300
- this.__copying = true;
408
+ @media (forced-colors: active) {
409
+ [part='checkbox'] {
410
+ outline: 1px solid;
411
+ outline-offset: -1px;
412
+ }
301
413
 
302
- this.__copyNodesToSlotTarget(nodes, slotTarget);
414
+ :host([disabled]) [part='checkbox'],
415
+ :host([disabled]) [part='checkbox']::after {
416
+ outline-color: GrayText;
303
417
  }
304
- }
305
418
 
306
- /**
307
- * Copies the nodes to the target element.
308
- *
309
- * @param {!Array<!Node>} nodes
310
- * @param {HTMLElement} slotTarget
311
- * @private
312
- */
313
- __copyNodesToSlotTarget(nodes, slotTarget) {
314
- this.__slotTargetClones = this.__slotTargetClones || [];
315
-
316
- nodes.forEach((node) => {
317
- // Clone the nodes and append the clones to the target
318
- const clone = node.cloneNode(true);
319
- this.__slotTargetClones.push(clone);
320
-
321
- slotTarget.appendChild(clone);
322
-
323
- // Observe all changes to the source node to have the clones updated
324
- this.__sourceSlotObserver.observe(node, {
325
- attributes: true,
326
- childList: true,
327
- subtree: true,
328
- characterData: true,
329
- });
330
- });
419
+ :host(:is([checked], [indeterminate])) [part='checkbox']::after {
420
+ outline: 1px solid;
421
+ outline-offset: -1px;
422
+ border-radius: inherit;
423
+ }
331
424
 
332
- // Run callback e.g. to show a deprecation warning
333
- if (typeof this.copyCallback === 'function') {
334
- this.copyCallback(nodes);
425
+ :host([focused]) [part='checkbox'],
426
+ :host([focused]) [part='checkbox']::after {
427
+ outline-width: 2px;
335
428
  }
336
429
  }
337
- }
430
+ `;
338
431
 
339
432
  /**
340
433
  * @license
341
- * Copyright (c) 2017 - 2022 Vaadin Ltd.
434
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
342
435
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
343
436
  */
344
437
 
438
+ registerStyles('vaadin-checkbox', checkboxStyles, { moduleId: 'vaadin-checkbox-styles' });
439
+
345
440
  /**
346
441
  * `<vaadin-checkbox>` is an input field representing a binary choice.
347
442
  *
@@ -354,225 +449,59 @@ class SlotTargetController {
354
449
  * The following shadow DOM parts are available for styling:
355
450
  *
356
451
  * Part name | Description
357
- * ------------|----------------
358
- * `checkbox` | The wrapper element that contains slotted <input type="checkbox">.
452
+ * ------------|-------------
453
+ * `checkbox` | The element representing a stylable custom checkbox.
359
454
  *
360
455
  * The following state attributes are available for styling:
361
456
  *
362
- * Attribute | Description | Part name
363
- * ----------------|-------------|--------------
364
- * `active` | Set when the checkbox is pressed down, either with mouse, touch or the keyboard. | `:host`
365
- * `disabled` | Set when the checkbox is disabled. | `:host`
366
- * `focus-ring` | Set when the checkbox is focused using the keyboard. | `:host`
367
- * `focused` | Set when the checkbox is focused. | `:host`
368
- * `indeterminate` | Set when the checkbox is in the indeterminate state. | `:host`
369
- * `checked` | Set when the checkbox is checked. | `:host`
370
- * `has-label` | Set when the checkbox has a label. | `:host`
457
+ * Attribute | Description
458
+ * ----------------|-------------
459
+ * `active` | Set when the checkbox is activated with mouse, touch or the keyboard.
460
+ * `checked` | Set when the checkbox is checked.
461
+ * `disabled` | Set when the checkbox is disabled.
462
+ * `focus-ring` | Set when the checkbox is focused using the keyboard.
463
+ * `focused` | Set when the checkbox is focused.
464
+ * `indeterminate` | Set when the checkbox is in the indeterminate state.
465
+ * `has-label` | Set when the checkbox has a label.
371
466
  *
372
- * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
467
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
373
468
  *
374
469
  * @fires {CustomEvent} checked-changed - Fired when the `checked` property changes.
375
470
  * @fires {CustomEvent} indeterminate-changed - Fired when the `indeterminate` property changes.
376
471
  *
472
+ * @customElement
377
473
  * @extends HTMLElement
378
- * @mixes ControllerMixin
474
+ * @mixes CheckboxMixin
379
475
  * @mixes ThemableMixin
380
476
  * @mixes ElementMixin
381
- * @mixes ActiveMixin
382
- * @mixes DelegateFocusMixin
383
- * @mixes CheckedMixin
384
- * @mixes LabelMixin
385
477
  */
386
- class Checkbox extends LabelMixin(
387
- CheckedMixin(DelegateFocusMixin(ActiveMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))))),
388
- ) {
478
+ class Checkbox extends CheckboxMixin(ElementMixin(ThemableMixin(PolymerElement))) {
389
479
  static get is() {
390
480
  return 'vaadin-checkbox';
391
481
  }
392
482
 
393
483
  static get template() {
394
484
  return html`
395
- <style>
396
- :host {
397
- display: inline-block;
398
- }
399
-
400
- :host([hidden]) {
401
- display: none !important;
402
- }
403
-
404
- :host([disabled]) {
405
- -webkit-tap-highlight-color: transparent;
406
- }
407
-
408
- .vaadin-checkbox-container {
409
- display: grid;
410
- grid-template-columns: auto 1fr;
411
- align-items: baseline;
412
- }
413
-
414
- [part='checkbox'],
415
- ::slotted(input),
416
- ::slotted(label) {
417
- grid-row: 1;
418
- }
419
-
420
- [part='checkbox'],
421
- ::slotted(input) {
422
- grid-column: 1;
423
- }
424
-
425
- [part='checkbox'] {
426
- width: var(--vaadin-checkbox-size, 1em);
427
- height: var(--vaadin-checkbox-size, 1em);
428
- }
429
-
430
- [part='checkbox']::before {
431
- display: block;
432
- content: '\\202F';
433
- line-height: var(--vaadin-checkbox-size, 1em);
434
- contain: paint;
435
- }
436
-
437
- /* visually hidden */
438
- ::slotted(input) {
439
- opacity: 0;
440
- cursor: inherit;
441
- margin: 0;
442
- align-self: stretch;
443
- -webkit-appearance: none;
444
- }
445
- </style>
446
485
  <div class="vaadin-checkbox-container">
447
- <div part="checkbox"></div>
486
+ <div part="checkbox" aria-hidden="true"></div>
448
487
  <slot name="input"></slot>
449
488
  <slot name="label"></slot>
450
-
451
- <div style="display: none !important">
452
- <slot id="noop"></slot>
453
- </div>
454
489
  </div>
455
490
  <slot name="tooltip"></slot>
456
491
  `;
457
492
  }
458
493
 
459
- static get properties() {
460
- return {
461
- /**
462
- * True if the checkbox is in the indeterminate state which means
463
- * it is not possible to say whether it is checked or unchecked.
464
- * The state is reset once the user switches the checkbox by hand.
465
- *
466
- * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Indeterminate_state_checkboxes
467
- *
468
- * @type {boolean}
469
- */
470
- indeterminate: {
471
- type: Boolean,
472
- notify: true,
473
- value: false,
474
- reflectToAttribute: true,
475
- },
476
-
477
- /**
478
- * The name of the checkbox.
479
- *
480
- * @type {string}
481
- */
482
- name: {
483
- type: String,
484
- value: '',
485
- },
486
- };
487
- }
488
-
489
- /** @override */
490
- static get delegateProps() {
491
- return [...super.delegateProps, 'indeterminate'];
492
- }
493
-
494
- /** @override */
495
- static get delegateAttrs() {
496
- return [...super.delegateAttrs, 'name'];
497
- }
498
-
499
- constructor() {
500
- super();
501
-
502
- this._setType('checkbox');
503
-
504
- // Set the string "on" as the default value for the checkbox following the HTML specification:
505
- // https://html.spec.whatwg.org/multipage/input.html#dom-input-value-default-on
506
- this.value = 'on';
507
- }
508
-
509
494
  /** @protected */
510
495
  ready() {
511
496
  super.ready();
512
497
 
513
- this.addController(
514
- new InputController(this, (input) => {
515
- this._setInputElement(input);
516
- this._setFocusElement(input);
517
- this.stateTarget = input;
518
- this.ariaTarget = input;
519
- }),
520
- );
521
- this.addController(new LabelledInputController(this.inputElement, this._labelController));
522
- this.addController(
523
- new SlotTargetController(
524
- this.$.noop,
525
- () => this._labelController.node,
526
- () => this.__warnDeprecated(),
527
- ),
528
- );
529
498
  this._tooltipController = new TooltipController(this);
499
+ this._tooltipController.setAriaTarget(this.inputElement);
530
500
  this.addController(this._tooltipController);
531
501
  }
532
-
533
- /** @private */
534
- __warnDeprecated() {
535
- console.warn(
536
- `WARNING: Since Vaadin 22, placing the label as a direct child of a <vaadin-checkbox> is deprecated.
537
- Please use <label slot="label"> wrapper or the label property instead.`,
538
- );
539
- }
540
-
541
- /**
542
- * Extends the method from `ActiveMixin` in order to
543
- * prevent setting the `active` attribute when interacting with a link inside the label.
544
- *
545
- * @param {Event} event
546
- * @return {boolean}
547
- * @protected
548
- * @override
549
- */
550
- _shouldSetActive(event) {
551
- if (event.target.localName === 'a') {
552
- return false;
553
- }
554
-
555
- return super._shouldSetActive(event);
556
- }
557
-
558
- /**
559
- * Extends the method from `CheckedMixin` in order to
560
- * reset the indeterminate state once the user switches the checkbox.
561
- *
562
- * @param {boolean} checked
563
- * @protected
564
- * @override
565
- */
566
- _toggleChecked(checked) {
567
- if (this.indeterminate) {
568
- this.indeterminate = false;
569
- }
570
-
571
- super._toggleChecked(checked);
572
- }
573
502
  }
574
503
 
575
- customElements.define(Checkbox.is, Checkbox);
504
+ defineCustomElement$1(Checkbox);
576
505
 
577
506
  const checkboxGroup = i`
578
507
  :host {
@@ -594,7 +523,6 @@ const checkboxGroup = i`
594
523
  }
595
524
 
596
525
  :host([theme~='vertical']) [part='group-field'] {
597
- display: flex;
598
526
  flex-direction: column;
599
527
  }
600
528
 
@@ -626,7 +554,7 @@ registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup],
626
554
 
627
555
  /**
628
556
  * @license
629
- * Copyright (c) 2018 - 2022 Vaadin Ltd.
557
+ * Copyright (c) 2018 - 2023 Vaadin Ltd.
630
558
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
631
559
  */
632
560
 
@@ -634,10 +562,11 @@ registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup],
634
562
  * `<vaadin-checkbox-group>` is a web component that allows the user to choose several items from a group of binary choices.
635
563
  *
636
564
  * ```html
637
- * <vaadin-checkbox-group label="Preferred language of contact:">
638
- * <vaadin-checkbox value="en" label="English"></vaadin-checkbox>
639
- * <vaadin-checkbox value="fr" label="Français"></vaadin-checkbox>
640
- * <vaadin-checkbox value="de" label="Deutsch"></vaadin-checkbox>
565
+ * <vaadin-checkbox-group label="Export data">
566
+ * <vaadin-checkbox value="0" label="Order ID"></vaadin-checkbox>
567
+ * <vaadin-checkbox value="1" label="Product name"></vaadin-checkbox>
568
+ * <vaadin-checkbox value="2" label="Customer"></vaadin-checkbox>
569
+ * <vaadin-checkbox value="3" label="Status"></vaadin-checkbox>
641
570
  * </vaadin-checkbox-group>
642
571
  * ```
643
572
  *
@@ -665,12 +594,13 @@ registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup],
665
594
  * `has-helper` | Set when the element has helper text | :host
666
595
  * `has-error-message` | Set when the element has an error message | :host
667
596
  *
668
- * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
597
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
669
598
  *
670
599
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
671
600
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
672
601
  * @fires {CustomEvent} validated - Fired whenever the field is validated.
673
602
  *
603
+ * @customElement
674
604
  * @extends HTMLElement
675
605
  * @mixes ThemableMixin
676
606
  * @mixes DisabledMixin
@@ -706,6 +636,11 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
706
636
  width: 100%;
707
637
  }
708
638
 
639
+ [part='group-field'] {
640
+ display: flex;
641
+ flex-wrap: wrap;
642
+ }
643
+
709
644
  :host(:not([has-label])) [part='label'] {
710
645
  display: none;
711
646
  }
@@ -759,6 +694,29 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
759
694
  this.__registerCheckbox = this.__registerCheckbox.bind(this);
760
695
  this.__unregisterCheckbox = this.__unregisterCheckbox.bind(this);
761
696
  this.__onCheckboxCheckedChanged = this.__onCheckboxCheckedChanged.bind(this);
697
+
698
+ this._tooltipController = new TooltipController(this);
699
+ this._tooltipController.addEventListener('tooltip-changed', (event) => {
700
+ const tooltip = event.detail.node;
701
+ if (tooltip && tooltip.isConnected) {
702
+ // Tooltip element has been added to the DOM
703
+ const inputs = this.__checkboxes.map((checkbox) => checkbox.inputElement);
704
+ this._tooltipController.setAriaTarget(inputs);
705
+ } else {
706
+ // Tooltip element is no longer connected
707
+ this._tooltipController.setAriaTarget([]);
708
+ }
709
+ });
710
+ }
711
+
712
+ /**
713
+ * A collection of the checkboxes.
714
+ *
715
+ * @return {!Array<!Checkbox>}
716
+ * @private
717
+ */
718
+ get __checkboxes() {
719
+ return this.__filterCheckboxes([...this.children]);
762
720
  }
763
721
 
764
722
  /** @protected */
@@ -770,17 +728,20 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
770
728
  // See https://github.com/vaadin/vaadin-web-components/issues/94
771
729
  this.setAttribute('role', 'group');
772
730
 
773
- this._observer = new FlattenedNodesObserver(this, ({ addedNodes, removedNodes }) => {
731
+ const slot = this.shadowRoot.querySelector('slot:not([name])');
732
+ this._observer = new SlotObserver(slot, ({ addedNodes, removedNodes }) => {
774
733
  const addedCheckboxes = this.__filterCheckboxes(addedNodes);
775
734
  const removedCheckboxes = this.__filterCheckboxes(removedNodes);
776
735
 
777
736
  addedCheckboxes.forEach(this.__registerCheckbox);
778
737
  removedCheckboxes.forEach(this.__unregisterCheckbox);
779
738
 
739
+ const inputs = this.__checkboxes.map((checkbox) => checkbox.inputElement);
740
+ this._tooltipController.setAriaTarget(inputs);
741
+
780
742
  this.__warnOfCheckboxesWithoutValue(addedCheckboxes);
781
743
  });
782
744
 
783
- this._tooltipController = new TooltipController(this);
784
745
  this.addController(this._tooltipController);
785
746
  }
786
747
 
@@ -804,16 +765,6 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
804
765
  return nodes.filter((child) => child instanceof Checkbox);
805
766
  }
806
767
 
807
- /**
808
- * A collection of the checkboxes.
809
- *
810
- * @return {!Array<!Checkbox>}
811
- * @private
812
- */
813
- get __checkboxes() {
814
- return this.__filterCheckboxes([...this.children]);
815
- }
816
-
817
768
  /**
818
769
  * @param {!Array<!Checkbox>} checkboxes
819
770
  * @private
@@ -970,13 +921,15 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
970
921
  _setFocused(focused) {
971
922
  super._setFocused(focused);
972
923
 
973
- if (!focused) {
924
+ // Do not validate when focusout is caused by document
925
+ // losing focus, which happens on browser tab switch.
926
+ if (!focused && document.hasFocus()) {
974
927
  this.validate();
975
928
  }
976
929
  }
977
930
  }
978
931
 
979
- customElements.define(CheckboxGroup.is, CheckboxGroup);
932
+ defineCustomElement$1(CheckboxGroup);
980
933
 
981
934
  const checkboxGroupInputCss = "*,*::before,*::after{padding:0;margin:0;box-sizing:border-box}vaadin-checkbox-group{margin-top:5px;margin-left:40px}.checkboxgroup{font-family:\"Roboto\";font-style:normal;font-size:15px}.checkboxgroup__wrapper{position:relative}.checkboxgroup__wrapper--flex{display:flex;gap:5px;align-content:flex-start}.checkboxgroup__wrapper--relative{position:relative;display:inline}.checkboxgroup__input{vertical-align:baseline}.checkboxgroup__input[indeterminate]::part(checkbox)::after,.checkboxgroup__input[indeterminate]::part(checkbox),.checkboxgroup__input[checked]::part(checkbox){background-color:var(--emfe-w-login-color-primary, var(--emfe-w-color-primary, #D0046C))}.checkboxgroup__label{font-style:inherit;font-family:inherit;font-weight:400;font-size:16px;color:var(--emfe-w-registration-typography, var(--emfe-w-color-black, #000000));line-height:1.5;padding-left:10px;vertical-align:baseline}.checkboxgroup__label-text{font-size:16px}.checkboxgroup__label a{color:var(--emfe-w-login-color-primary, var(--emfe-w-color-primary, #D0046C))}.checkboxgroup__error-message{position:absolute;top:calc(100% + 5px);left:0;color:var(--emfe-w-color-error, var(--emfe-w-color-red, #ed0909))}.checkboxgroup__tooltip-icon{width:16px;height:auto}.checkboxgroup__tooltip{position:absolute;top:0;right:0;background-color:var(--emfe-w-color-white, #FFFFFF);border:1px solid var(--emfe-w-color-gray-100, #E6E6E6);color:var(--emfe-w-registration-typography, var(--emfe-w-color-black, #000000));padding:10px;border-radius:5px;opacity:0;transition:opacity 0.3s ease-in-out;z-index:10}.checkboxgroup__tooltip.visible{opacity:1}.checkbox__input[indeterminate]::part(checkbox),.checkbox__input[checked]::part(checkbox){background-color:var(--emfe-w-login-color-primary, var(--emfe-w-color-primary, #D0046C))}";
982
935