@everymatrix/general-input 1.22.0 → 1.22.2

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, b as isElementFocused, L as LabelMixin, c as DelegateFocusMixin, e as InputController, f as LabelledInputController, h as html, T as TooltipController, g as defineCustomElement$1, E as ElementMixin, j as ThemableMixin, P as PolymerElement, k as requiredField, l as helper, F as FieldMixin, m 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
 
@@ -214,134 +223,214 @@ const CheckedMixin = dedupingMixin(
214
223
 
215
224
  /**
216
225
  * @license
217
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
226
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
218
227
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
219
228
  */
220
229
 
221
230
  /**
222
- * A controller to copy the content from a source slot to a target element.
231
+ * A mixin providing common checkbox functionality.
232
+ *
233
+ * @polymerMixin
234
+ * @mixes ActiveMixin
235
+ * @mixes CheckedMixin
236
+ * @mixes DelegateFocusMixin
237
+ * @mixes LabelMixin
223
238
  */
224
- class SlotTargetController {
225
- constructor(sourceSlot, targetFactory, callback) {
226
- /**
227
- * The source `<slot>` element to copy nodes from.
228
- */
229
- this.sourceSlot = sourceSlot;
239
+ const CheckboxMixin = (superclass) =>
240
+ class CheckboxMixinClass extends LabelMixin(CheckedMixin(DelegateFocusMixin(ActiveMixin(superclass)))) {
241
+ static get properties() {
242
+ return {
243
+ /**
244
+ * True if the checkbox is in the indeterminate state which means
245
+ * it is not possible to say whether it is checked or unchecked.
246
+ * The state is reset once the user switches the checkbox by hand.
247
+ *
248
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Indeterminate_state_checkboxes
249
+ *
250
+ * @type {boolean}
251
+ */
252
+ indeterminate: {
253
+ type: Boolean,
254
+ notify: true,
255
+ value: false,
256
+ reflectToAttribute: true,
257
+ },
258
+
259
+ /**
260
+ * The name of the checkbox.
261
+ *
262
+ * @type {string}
263
+ */
264
+ name: {
265
+ type: String,
266
+ value: '',
267
+ },
268
+ };
269
+ }
270
+
271
+ /** @override */
272
+ static get delegateProps() {
273
+ return [...super.delegateProps, 'indeterminate'];
274
+ }
275
+
276
+ /** @override */
277
+ static get delegateAttrs() {
278
+ return [...super.delegateAttrs, 'name'];
279
+ }
280
+
281
+ constructor() {
282
+ super();
283
+
284
+ this._setType('checkbox');
285
+
286
+ // Set the string "on" as the default value for the checkbox following the HTML specification:
287
+ // https://html.spec.whatwg.org/multipage/input.html#dom-input-value-default-on
288
+ this.value = 'on';
289
+ }
290
+
291
+ /** @protected */
292
+ ready() {
293
+ super.ready();
294
+
295
+ this.addController(
296
+ new InputController(this, (input) => {
297
+ this._setInputElement(input);
298
+ this._setFocusElement(input);
299
+ this.stateTarget = input;
300
+ this.ariaTarget = input;
301
+ }),
302
+ );
303
+ this.addController(new LabelledInputController(this.inputElement, this._labelController));
304
+ }
230
305
 
231
306
  /**
232
- * Function used to get a reference to slot target.
307
+ * Override method inherited from `ActiveMixin` to prevent setting
308
+ * `active` attribute when clicking a link placed inside the label.
309
+ *
310
+ * @param {Event} event
311
+ * @return {boolean}
312
+ * @protected
313
+ * @override
233
314
  */
234
- this.targetFactory = targetFactory;
315
+ _shouldSetActive(event) {
316
+ if (event.target.localName === 'a') {
317
+ return false;
318
+ }
319
+
320
+ return super._shouldSetActive(event);
321
+ }
235
322
 
236
323
  /**
237
- * Function called after copying nodes to target.
324
+ * Override method inherited from `CheckedMixin` to reset
325
+ * `indeterminate` state checkbox is toggled by the user.
326
+ *
327
+ * @param {boolean} checked
328
+ * @protected
329
+ * @override
238
330
  */
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
- });
331
+ _toggleChecked(checked) {
332
+ if (this.indeterminate) {
333
+ this.indeterminate = false;
334
+ }
335
+
336
+ super._toggleChecked(checked);
250
337
  }
338
+ };
339
+
340
+ /**
341
+ * @license
342
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
343
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
344
+ */
345
+
346
+ const checkboxStyles = i`
347
+ :host {
348
+ display: inline-block;
251
349
  }
252
350
 
253
- hostConnected() {
254
- this.__sourceSlotObserver = new MutationObserver(() => this.__checkAndCopyNodesToSlotTarget());
351
+ :host([hidden]) {
352
+ display: none !important;
353
+ }
255
354
 
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
- }
355
+ :host([disabled]) {
356
+ -webkit-tap-highlight-color: transparent;
263
357
  }
264
358
 
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();
359
+ .vaadin-checkbox-container {
360
+ display: grid;
361
+ grid-template-columns: auto 1fr;
362
+ align-items: baseline;
363
+ }
273
364
 
274
- // Ensure slot target element is up to date.
275
- const slotTarget = this.targetFactory();
365
+ [part='checkbox'],
366
+ ::slotted(input),
367
+ ::slotted(label) {
368
+ grid-row: 1;
369
+ }
276
370
 
277
- if (!slotTarget) {
278
- return;
279
- }
371
+ [part='checkbox'],
372
+ ::slotted(input) {
373
+ grid-column: 1;
374
+ }
280
375
 
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
- }
376
+ [part='checkbox'] {
377
+ width: var(--vaadin-checkbox-size, 1em);
378
+ height: var(--vaadin-checkbox-size, 1em);
379
+ --_input-border-width: var(--vaadin-input-field-border-width, 0);
380
+ --_input-border-color: var(--vaadin-input-field-border-color, transparent);
381
+ box-shadow: inset 0 0 0 var(--_input-border-width, 0) var(--_input-border-color);
382
+ }
290
383
 
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() === ''));
384
+ [part='checkbox']::before {
385
+ display: block;
386
+ content: '\\202F';
387
+ line-height: var(--vaadin-checkbox-size, 1em);
388
+ contain: paint;
389
+ }
295
390
 
296
- if (nodes.length > 0) {
297
- slotTarget.innerHTML = '';
391
+ /* visually hidden */
392
+ ::slotted(input) {
393
+ opacity: 0;
394
+ cursor: inherit;
395
+ margin: 0;
396
+ align-self: stretch;
397
+ -webkit-appearance: none;
398
+ width: initial;
399
+ height: initial;
400
+ }
298
401
 
299
- // Ignore next slotchange
300
- this.__copying = true;
402
+ @media (forced-colors: active) {
403
+ [part='checkbox'] {
404
+ outline: 1px solid;
405
+ outline-offset: -1px;
406
+ }
301
407
 
302
- this.__copyNodesToSlotTarget(nodes, slotTarget);
408
+ :host([disabled]) [part='checkbox'],
409
+ :host([disabled]) [part='checkbox']::after {
410
+ outline-color: GrayText;
303
411
  }
304
- }
305
412
 
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
- });
413
+ :host(:is([checked], [indeterminate])) [part='checkbox']::after {
414
+ outline: 1px solid;
415
+ outline-offset: -1px;
416
+ border-radius: inherit;
417
+ }
331
418
 
332
- // Run callback e.g. to show a deprecation warning
333
- if (typeof this.copyCallback === 'function') {
334
- this.copyCallback(nodes);
419
+ :host([focused]) [part='checkbox'],
420
+ :host([focused]) [part='checkbox']::after {
421
+ outline-width: 2px;
335
422
  }
336
423
  }
337
- }
424
+ `;
338
425
 
339
426
  /**
340
427
  * @license
341
- * Copyright (c) 2017 - 2022 Vaadin Ltd.
428
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
342
429
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
343
430
  */
344
431
 
432
+ registerStyles('vaadin-checkbox', checkboxStyles, { moduleId: 'vaadin-checkbox-styles' });
433
+
345
434
  /**
346
435
  * `<vaadin-checkbox>` is an input field representing a binary choice.
347
436
  *
@@ -354,227 +443,59 @@ class SlotTargetController {
354
443
  * The following shadow DOM parts are available for styling:
355
444
  *
356
445
  * Part name | Description
357
- * ------------|----------------
358
- * `checkbox` | The wrapper element that contains slotted <input type="checkbox">.
446
+ * ------------|-------------
447
+ * `checkbox` | The element representing a stylable custom checkbox.
359
448
  *
360
449
  * The following state attributes are available for styling:
361
450
  *
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`
451
+ * Attribute | Description
452
+ * ----------------|-------------
453
+ * `active` | Set when the checkbox is activated with mouse, touch or the keyboard.
454
+ * `checked` | Set when the checkbox is checked.
455
+ * `disabled` | Set when the checkbox is disabled.
456
+ * `focus-ring` | Set when the checkbox is focused using the keyboard.
457
+ * `focused` | Set when the checkbox is focused.
458
+ * `indeterminate` | Set when the checkbox is in the indeterminate state.
459
+ * `has-label` | Set when the checkbox has a label.
371
460
  *
372
- * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
461
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
373
462
  *
374
463
  * @fires {CustomEvent} checked-changed - Fired when the `checked` property changes.
375
464
  * @fires {CustomEvent} indeterminate-changed - Fired when the `indeterminate` property changes.
376
465
  *
466
+ * @customElement
377
467
  * @extends HTMLElement
378
- * @mixes ControllerMixin
468
+ * @mixes CheckboxMixin
379
469
  * @mixes ThemableMixin
380
470
  * @mixes ElementMixin
381
- * @mixes ActiveMixin
382
- * @mixes DelegateFocusMixin
383
- * @mixes CheckedMixin
384
- * @mixes LabelMixin
385
471
  */
386
- class Checkbox extends LabelMixin(
387
- CheckedMixin(DelegateFocusMixin(ActiveMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))))),
388
- ) {
472
+ class Checkbox extends CheckboxMixin(ElementMixin(ThemableMixin(PolymerElement))) {
389
473
  static get is() {
390
474
  return 'vaadin-checkbox';
391
475
  }
392
476
 
393
477
  static get template() {
394
478
  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
- width: initial;
445
- height: initial;
446
- }
447
- </style>
448
479
  <div class="vaadin-checkbox-container">
449
- <div part="checkbox"></div>
480
+ <div part="checkbox" aria-hidden="true"></div>
450
481
  <slot name="input"></slot>
451
482
  <slot name="label"></slot>
452
-
453
- <div style="display: none !important">
454
- <slot id="noop"></slot>
455
- </div>
456
483
  </div>
457
484
  <slot name="tooltip"></slot>
458
485
  `;
459
486
  }
460
487
 
461
- static get properties() {
462
- return {
463
- /**
464
- * True if the checkbox is in the indeterminate state which means
465
- * it is not possible to say whether it is checked or unchecked.
466
- * The state is reset once the user switches the checkbox by hand.
467
- *
468
- * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Indeterminate_state_checkboxes
469
- *
470
- * @type {boolean}
471
- */
472
- indeterminate: {
473
- type: Boolean,
474
- notify: true,
475
- value: false,
476
- reflectToAttribute: true,
477
- },
478
-
479
- /**
480
- * The name of the checkbox.
481
- *
482
- * @type {string}
483
- */
484
- name: {
485
- type: String,
486
- value: '',
487
- },
488
- };
489
- }
490
-
491
- /** @override */
492
- static get delegateProps() {
493
- return [...super.delegateProps, 'indeterminate'];
494
- }
495
-
496
- /** @override */
497
- static get delegateAttrs() {
498
- return [...super.delegateAttrs, 'name'];
499
- }
500
-
501
- constructor() {
502
- super();
503
-
504
- this._setType('checkbox');
505
-
506
- // Set the string "on" as the default value for the checkbox following the HTML specification:
507
- // https://html.spec.whatwg.org/multipage/input.html#dom-input-value-default-on
508
- this.value = 'on';
509
- }
510
-
511
488
  /** @protected */
512
489
  ready() {
513
490
  super.ready();
514
491
 
515
- this.addController(
516
- new InputController(this, (input) => {
517
- this._setInputElement(input);
518
- this._setFocusElement(input);
519
- this.stateTarget = input;
520
- this.ariaTarget = input;
521
- }),
522
- );
523
- this.addController(new LabelledInputController(this.inputElement, this._labelController));
524
- this.addController(
525
- new SlotTargetController(
526
- this.$.noop,
527
- () => this._labelController.node,
528
- () => this.__warnDeprecated(),
529
- ),
530
- );
531
492
  this._tooltipController = new TooltipController(this);
493
+ this._tooltipController.setAriaTarget(this.inputElement);
532
494
  this.addController(this._tooltipController);
533
495
  }
534
-
535
- /** @private */
536
- __warnDeprecated() {
537
- console.warn(
538
- `WARNING: Since Vaadin 22, placing the label as a direct child of a <vaadin-checkbox> is deprecated.
539
- Please use <label slot="label"> wrapper or the label property instead.`,
540
- );
541
- }
542
-
543
- /**
544
- * Extends the method from `ActiveMixin` in order to
545
- * prevent setting the `active` attribute when interacting with a link inside the label.
546
- *
547
- * @param {Event} event
548
- * @return {boolean}
549
- * @protected
550
- * @override
551
- */
552
- _shouldSetActive(event) {
553
- if (event.target.localName === 'a') {
554
- return false;
555
- }
556
-
557
- return super._shouldSetActive(event);
558
- }
559
-
560
- /**
561
- * Extends the method from `CheckedMixin` in order to
562
- * reset the indeterminate state once the user switches the checkbox.
563
- *
564
- * @param {boolean} checked
565
- * @protected
566
- * @override
567
- */
568
- _toggleChecked(checked) {
569
- if (this.indeterminate) {
570
- this.indeterminate = false;
571
- }
572
-
573
- super._toggleChecked(checked);
574
- }
575
496
  }
576
497
 
577
- customElements.define(Checkbox.is, Checkbox);
498
+ defineCustomElement$1(Checkbox);
578
499
 
579
500
  const checkboxGroup = i`
580
501
  :host {
@@ -596,7 +517,6 @@ const checkboxGroup = i`
596
517
  }
597
518
 
598
519
  :host([theme~='vertical']) [part='group-field'] {
599
- display: flex;
600
520
  flex-direction: column;
601
521
  }
602
522
 
@@ -628,7 +548,7 @@ registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup],
628
548
 
629
549
  /**
630
550
  * @license
631
- * Copyright (c) 2018 - 2022 Vaadin Ltd.
551
+ * Copyright (c) 2018 - 2023 Vaadin Ltd.
632
552
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
633
553
  */
634
554
 
@@ -636,10 +556,11 @@ registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup],
636
556
  * `<vaadin-checkbox-group>` is a web component that allows the user to choose several items from a group of binary choices.
637
557
  *
638
558
  * ```html
639
- * <vaadin-checkbox-group label="Preferred language of contact:">
640
- * <vaadin-checkbox value="en" label="English"></vaadin-checkbox>
641
- * <vaadin-checkbox value="fr" label="Français"></vaadin-checkbox>
642
- * <vaadin-checkbox value="de" label="Deutsch"></vaadin-checkbox>
559
+ * <vaadin-checkbox-group label="Export data">
560
+ * <vaadin-checkbox value="0" label="Order ID"></vaadin-checkbox>
561
+ * <vaadin-checkbox value="1" label="Product name"></vaadin-checkbox>
562
+ * <vaadin-checkbox value="2" label="Customer"></vaadin-checkbox>
563
+ * <vaadin-checkbox value="3" label="Status"></vaadin-checkbox>
643
564
  * </vaadin-checkbox-group>
644
565
  * ```
645
566
  *
@@ -667,12 +588,13 @@ registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup],
667
588
  * `has-helper` | Set when the element has helper text | :host
668
589
  * `has-error-message` | Set when the element has an error message | :host
669
590
  *
670
- * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
591
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
671
592
  *
672
593
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
673
594
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
674
595
  * @fires {CustomEvent} validated - Fired whenever the field is validated.
675
596
  *
597
+ * @customElement
676
598
  * @extends HTMLElement
677
599
  * @mixes ThemableMixin
678
600
  * @mixes DisabledMixin
@@ -708,6 +630,11 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
708
630
  width: 100%;
709
631
  }
710
632
 
633
+ [part='group-field'] {
634
+ display: flex;
635
+ flex-wrap: wrap;
636
+ }
637
+
711
638
  :host(:not([has-label])) [part='label'] {
712
639
  display: none;
713
640
  }
@@ -761,6 +688,29 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
761
688
  this.__registerCheckbox = this.__registerCheckbox.bind(this);
762
689
  this.__unregisterCheckbox = this.__unregisterCheckbox.bind(this);
763
690
  this.__onCheckboxCheckedChanged = this.__onCheckboxCheckedChanged.bind(this);
691
+
692
+ this._tooltipController = new TooltipController(this);
693
+ this._tooltipController.addEventListener('tooltip-changed', (event) => {
694
+ const tooltip = event.detail.node;
695
+ if (tooltip && tooltip.isConnected) {
696
+ // Tooltip element has been added to the DOM
697
+ const inputs = this.__checkboxes.map((checkbox) => checkbox.inputElement);
698
+ this._tooltipController.setAriaTarget(inputs);
699
+ } else {
700
+ // Tooltip element is no longer connected
701
+ this._tooltipController.setAriaTarget([]);
702
+ }
703
+ });
704
+ }
705
+
706
+ /**
707
+ * A collection of the checkboxes.
708
+ *
709
+ * @return {!Array<!Checkbox>}
710
+ * @private
711
+ */
712
+ get __checkboxes() {
713
+ return this.__filterCheckboxes([...this.children]);
764
714
  }
765
715
 
766
716
  /** @protected */
@@ -772,17 +722,20 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
772
722
  // See https://github.com/vaadin/vaadin-web-components/issues/94
773
723
  this.setAttribute('role', 'group');
774
724
 
775
- this._observer = new FlattenedNodesObserver(this, ({ addedNodes, removedNodes }) => {
725
+ const slot = this.shadowRoot.querySelector('slot:not([name])');
726
+ this._observer = new SlotObserver(slot, ({ addedNodes, removedNodes }) => {
776
727
  const addedCheckboxes = this.__filterCheckboxes(addedNodes);
777
728
  const removedCheckboxes = this.__filterCheckboxes(removedNodes);
778
729
 
779
730
  addedCheckboxes.forEach(this.__registerCheckbox);
780
731
  removedCheckboxes.forEach(this.__unregisterCheckbox);
781
732
 
733
+ const inputs = this.__checkboxes.map((checkbox) => checkbox.inputElement);
734
+ this._tooltipController.setAriaTarget(inputs);
735
+
782
736
  this.__warnOfCheckboxesWithoutValue(addedCheckboxes);
783
737
  });
784
738
 
785
- this._tooltipController = new TooltipController(this);
786
739
  this.addController(this._tooltipController);
787
740
  }
788
741
 
@@ -806,16 +759,6 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
806
759
  return nodes.filter((child) => child instanceof Checkbox);
807
760
  }
808
761
 
809
- /**
810
- * A collection of the checkboxes.
811
- *
812
- * @return {!Array<!Checkbox>}
813
- * @private
814
- */
815
- get __checkboxes() {
816
- return this.__filterCheckboxes([...this.children]);
817
- }
818
-
819
762
  /**
820
763
  * @param {!Array<!Checkbox>} checkboxes
821
764
  * @private
@@ -972,13 +915,15 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
972
915
  _setFocused(focused) {
973
916
  super._setFocused(focused);
974
917
 
975
- if (!focused) {
918
+ // Do not validate when focusout is caused by document
919
+ // losing focus, which happens on browser tab switch.
920
+ if (!focused && document.hasFocus()) {
976
921
  this.validate();
977
922
  }
978
923
  }
979
924
  }
980
925
 
981
- customElements.define(CheckboxGroup.is, CheckboxGroup);
926
+ defineCustomElement$1(CheckboxGroup);
982
927
 
983
928
  const checkboxGroupInputCss = "*,*::before,*::after{padding:0;margin:0;box-sizing:border-box}.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__label{font-style:inherit;font-family:inherit;font-weight:400;font-size:16px;color:#2B2D3F;line-height:14px}.checkboxgroup__label-text{font-size:16px}.checkboxgroup__error-message{position:absolute;top:calc(100% + 5px);left:0;color:#cc0000b3}.checkboxgroup__tooltip-icon{width:16px;height:auto}.checkboxgroup__tooltip{position:absolute;top:0;right:0;background-color:#FFFFFF;border:1px solid #B0B0B0;color:#2B2D3F;padding:10px;border-radius:5px;opacity:0;transition:opacity 0.3s ease-in-out;z-index:10}.checkboxgroup__tooltip.visible{opacity:1}";
984
929