@vaadin/avatar-group 23.3.0-alpha5 → 24.0.0-alpha2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/avatar-group",
3
- "version": "23.3.0-alpha5",
3
+ "version": "24.0.0-alpha2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,14 +37,15 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@polymer/polymer": "^3.0.0",
40
- "@vaadin/avatar": "23.3.0-alpha5",
41
- "@vaadin/component-base": "23.3.0-alpha5",
42
- "@vaadin/item": "23.3.0-alpha5",
43
- "@vaadin/list-box": "23.3.0-alpha5",
44
- "@vaadin/overlay": "23.3.0-alpha5",
45
- "@vaadin/vaadin-lumo-styles": "23.3.0-alpha5",
46
- "@vaadin/vaadin-material-styles": "23.3.0-alpha5",
47
- "@vaadin/vaadin-themable-mixin": "23.3.0-alpha5"
40
+ "@vaadin/avatar": "24.0.0-alpha2",
41
+ "@vaadin/component-base": "24.0.0-alpha2",
42
+ "@vaadin/item": "24.0.0-alpha2",
43
+ "@vaadin/list-box": "24.0.0-alpha2",
44
+ "@vaadin/overlay": "24.0.0-alpha2",
45
+ "@vaadin/vaadin-lumo-styles": "24.0.0-alpha2",
46
+ "@vaadin/vaadin-material-styles": "24.0.0-alpha2",
47
+ "@vaadin/vaadin-themable-mixin": "24.0.0-alpha2",
48
+ "lit": "^2.0.0"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@esm-bundle/chai": "^4.3.4",
@@ -55,5 +56,5 @@
55
56
  "web-types.json",
56
57
  "web-types.lit.json"
57
58
  ],
58
- "gitHead": "0b6fdcf444683e97e3efb433d603e1274d5bcd66"
59
+ "gitHead": "0c16c01a6807e629a84f5a982793afecc1a7ced0"
59
60
  }
@@ -4,6 +4,7 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { AvatarI18n } from '@vaadin/avatar/src/vaadin-avatar.js';
7
+ import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
7
8
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
8
9
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
9
10
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
@@ -51,7 +52,9 @@ export interface AvatarGroupItem {
51
52
  * Part name | Description
52
53
  * ----------- | ---------------
53
54
  * `container` | The container element
54
- * `avatar` | Individual avatars
55
+ *
56
+ * See the [`<vaadin-avatar>`](#/elements/vaadin-avatar) documentation for the available
57
+ * state attributes and stylable shadow parts of avatar elements.
55
58
  *
56
59
  * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
57
60
  *
@@ -60,10 +63,9 @@ export interface AvatarGroupItem {
60
63
  * In addition to `<vaadin-avatar-group>` itself, the following internal
61
64
  * components are themable:
62
65
  *
63
- * - `<vaadin-avatar-group-list-box>` - has the same API as [`<vaadin-list-box>`](#/elements/vaadin-list-box).
64
66
  * - `<vaadin-avatar-group-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
65
67
  */
66
- declare class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(HTMLElement))) {
68
+ declare class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(ControllerMixin(HTMLElement)))) {
67
69
  readonly _avatars: HTMLElement[];
68
70
 
69
71
  /**
@@ -3,17 +3,19 @@
3
3
  * Copyright (c) 2020 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import '@polymer/polymer/lib/elements/dom-repeat.js';
7
6
  import '@vaadin/avatar/src/vaadin-avatar.js';
8
7
  import '@vaadin/item/src/vaadin-item.js';
9
- import './vaadin-avatar-group-list-box.js';
8
+ import '@vaadin/list-box/src/vaadin-list-box.js';
10
9
  import './vaadin-avatar-group-overlay.js';
11
10
  import { calculateSplices } from '@polymer/polymer/lib/utils/array-splice.js';
12
11
  import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';
13
- import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
12
+ import { html as legacyHtml, PolymerElement } from '@polymer/polymer/polymer-element.js';
13
+ import { html, render } from 'lit';
14
14
  import { announce } from '@vaadin/component-base/src/a11y-announcer.js';
15
+ import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
15
16
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
16
17
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
18
+ import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
17
19
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
18
20
 
19
21
  const MINIMUM_DISPLAYED_AVATARS = 2;
@@ -43,7 +45,9 @@ const MINIMUM_DISPLAYED_AVATARS = 2;
43
45
  * Part name | Description
44
46
  * ----------- | ---------------
45
47
  * `container` | The container element
46
- * `avatar` | Individual avatars
48
+ *
49
+ * See the [`<vaadin-avatar>`](#/elements/vaadin-avatar) documentation for the available
50
+ * state attributes and stylable shadow parts of avatar elements.
47
51
  *
48
52
  * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
49
53
  *
@@ -52,17 +56,17 @@ const MINIMUM_DISPLAYED_AVATARS = 2;
52
56
  * In addition to `<vaadin-avatar-group>` itself, the following internal
53
57
  * components are themable:
54
58
  *
55
- * - `<vaadin-avatar-group-list-box>` - has the same API as [`<vaadin-list-box>`](#/elements/vaadin-list-box).
56
59
  * - `<vaadin-avatar-group-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
57
60
  *
58
61
  * @extends HTMLElement
62
+ * @mixes ControllerMixin
59
63
  * @mixes ElementMixin
60
64
  * @mixes ThemableMixin
61
65
  * @mixes ResizeMixin
62
66
  */
63
- class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement))) {
67
+ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))) {
64
68
  static get template() {
65
- return html`
69
+ return legacyHtml`
66
70
  <style>
67
71
  :host {
68
72
  display: block;
@@ -82,7 +86,7 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
82
86
  flex-wrap: nowrap;
83
87
  }
84
88
 
85
- [part='avatar']:not(:first-child) {
89
+ ::slotted(vaadin-avatar:not(:first-child)) {
86
90
  -webkit-mask-image: url('data:image/svg+xml;utf8,<svg viewBox=%220 0 300 300%22 fill=%22none%22 xmlns=%22http://www.w3.org/2000/svg%22><path fill-rule=%22evenodd%22 clip-rule=%22evenodd%22 d=%22M300 0H0V300H300V0ZM150 200C177.614 200 200 177.614 200 150C200 122.386 177.614 100 150 100C122.386 100 100 122.386 100 150C100 177.614 122.386 200 150 200Z%22 fill=%22black%22/></svg>');
87
91
  mask-image: url('data:image/svg+xml;utf8,<svg viewBox=%220 0 300 300%22 fill=%22none%22 xmlns=%22http://www.w3.org/2000/svg%22><path fill-rule=%22evenodd%22 clip-rule=%22evenodd%22 d=%22M300 0H0V300H300V0ZM150 200C177.614 200 200 177.614 200 150C200 122.386 177.614 100 150 100C122.386 100 100 122.386 100 150C100 177.614 122.386 200 150 200Z%22 fill=%22black%22/></svg>');
88
92
  -webkit-mask-size: calc(
@@ -93,13 +97,13 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
93
97
  );
94
98
  }
95
99
 
96
- [part='avatar']:not([dir='rtl']):not(:first-child) {
100
+ ::slotted(vaadin-avatar:not([dir='rtl']):not(:first-child)) {
97
101
  margin-left: calc(var(--vaadin-avatar-group-overlap) * -1 - var(--vaadin-avatar-outline-width));
98
102
  -webkit-mask-position: calc(50% - var(--vaadin-avatar-size) + var(--vaadin-avatar-group-overlap));
99
103
  mask-position: calc(50% - var(--vaadin-avatar-size) + var(--vaadin-avatar-group-overlap));
100
104
  }
101
105
 
102
- [part='avatar'][dir='rtl']:not(:first-child) {
106
+ ::slotted(vaadin-avatar[dir='rtl']:not(:first-child)) {
103
107
  margin-right: calc(var(--vaadin-avatar-group-overlap) * -1);
104
108
  -webkit-mask-position: calc(
105
109
  50% + var(--vaadin-avatar-size) - var(--vaadin-avatar-group-overlap) + var(--vaadin-avatar-outline-width)
@@ -110,58 +114,16 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
110
114
  }
111
115
  </style>
112
116
  <div id="container" part="container">
113
- <template id="items" is="dom-repeat" items="[[__computeItems(items.*, __itemsInView, maxItemsVisible)]]">
114
- <vaadin-avatar
115
- name="[[item.name]]"
116
- abbr="[[item.abbr]]"
117
- img="[[item.img]]"
118
- part="avatar"
119
- theme$="[[_theme]]"
120
- i18n="[[i18n]]"
121
- color-index="[[item.colorIndex]]"
122
- with-tooltip
123
- ></vaadin-avatar>
124
- </template>
125
- <vaadin-avatar
126
- id="overflow"
127
- part="avatar"
128
- hidden$="[[__computeMoreHidden(items.length, __itemsInView, __maxReached)]]"
129
- abbr="[[__computeMore(items.length, __itemsInView, maxItemsVisible)]]"
130
- theme$="[[_theme]]"
131
- on-click="_onOverflowClick"
132
- on-keydown="_onOverflowKeyDown"
133
- aria-haspopup="listbox"
134
- >
135
- <vaadin-tooltip slot="tooltip" generator="[[__overflowTextGenerator]]"></vaadin-tooltip>
136
- </vaadin-avatar>
117
+ <slot></slot>
118
+ <slot name="overflow"></slot>
137
119
  </div>
138
120
  <vaadin-avatar-group-overlay
139
121
  id="overlay"
140
122
  opened="{{_opened}}"
123
+ position-target="[[_overflow]]"
141
124
  no-vertical-overlap
142
125
  on-vaadin-overlay-close="_onVaadinOverlayClose"
143
- >
144
- <template>
145
- <vaadin-avatar-group-list-box on-keydown="_onListKeyDown">
146
- <template is="dom-repeat" items="[[__computeExtraItems(items.*, __itemsInView, maxItemsVisible)]]">
147
- <vaadin-item theme="avatar-group-item" role="option">
148
- <vaadin-avatar
149
- name="[[item.name]]"
150
- abbr="[[item.abbr]]"
151
- img="[[item.img]]"
152
- i18n="[[i18n]]"
153
- part="avatar"
154
- theme$="[[_theme]]"
155
- color-index="[[item.colorIndex]]"
156
- tabindex="-1"
157
- aria-hidden="true"
158
- ></vaadin-avatar>
159
- [[item.name]]
160
- </vaadin-item>
161
- </template>
162
- </vaadin-avatar-group-list-box>
163
- </template>
164
- </vaadin-avatar-group-overlay>
126
+ ></vaadin-avatar-group-overlay>
165
127
  `;
166
128
  }
167
129
 
@@ -254,35 +216,63 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
254
216
  },
255
217
  },
256
218
 
219
+ /** @private */
220
+ _avatars: {
221
+ type: Array,
222
+ value: () => [],
223
+ },
224
+
257
225
  /** @private */
258
226
  __maxReached: {
259
227
  type: Boolean,
260
228
  computed: '__computeMaxReached(items.length, maxItemsVisible)',
261
229
  },
262
230
 
231
+ /** @private */
232
+ __items: {
233
+ type: Array,
234
+ },
235
+
263
236
  /** @private */
264
237
  __itemsInView: {
265
238
  type: Number,
266
239
  value: null,
267
240
  },
268
241
 
242
+ /** @private */
243
+ _overflow: {
244
+ type: Object,
245
+ },
246
+
247
+ /** @private */
248
+ _overflowItems: {
249
+ type: Array,
250
+ observer: '__overflowItemsChanged',
251
+ computed: '__computeOverflowItems(items.*, __itemsInView, maxItemsVisible)',
252
+ },
253
+
254
+ /** @private */
255
+ _overflowTooltip: {
256
+ type: Object,
257
+ },
258
+
269
259
  /** @private */
270
260
  _opened: {
271
261
  type: Boolean,
272
262
  observer: '__openedChanged',
273
- value: false,
274
263
  },
275
-
276
- /** @private */
277
- __overflowTextGenerator: Object,
278
264
  };
279
265
  }
280
266
 
281
267
  static get observers() {
282
268
  return [
283
- '__computeMoreTooltip(items.length, __itemsInView, maxItemsVisible)',
284
269
  '__itemsChanged(items.splices, items.*)',
285
270
  '__i18nItemsChanged(i18n.*, items.length)',
271
+ '__updateAvatarsTheme(_overflow, _avatars, _theme)',
272
+ '__updateAvatars(items.*, __itemsInView, maxItemsVisible, _overflow, i18n)',
273
+ '__updateOverflowAbbr(_overflow, items.length, __itemsInView, maxItemsVisible)',
274
+ '__updateOverflowHidden(_overflow, items.length, __itemsInView, __maxReached)',
275
+ '__updateOverflowTooltip(_overflowTooltip, items.length, __itemsInView, maxItemsVisible)',
286
276
  ];
287
277
  }
288
278
 
@@ -290,8 +280,27 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
290
280
  ready() {
291
281
  super.ready();
292
282
 
293
- this._overlayElement = this.shadowRoot.querySelector('vaadin-avatar-group-overlay');
294
- this._overlayElement.positionTarget = this.$.overflow;
283
+ this._overflowController = new SlotController(
284
+ this,
285
+ 'overflow',
286
+ () => document.createElement('vaadin-avatar'),
287
+ (_, overflow) => {
288
+ overflow.setAttribute('aria-haspopup', 'listbox');
289
+ overflow.setAttribute('aria-expanded', 'false');
290
+ overflow.addEventListener('click', (e) => this._onOverflowClick(e));
291
+ overflow.addEventListener('keydown', (e) => this._onOverflowKeyDown(e));
292
+
293
+ const tooltip = document.createElement('vaadin-tooltip');
294
+ tooltip.setAttribute('slot', 'tooltip');
295
+ overflow.appendChild(tooltip);
296
+
297
+ this._overflow = overflow;
298
+ this._overflowTooltip = tooltip;
299
+ },
300
+ );
301
+ this.addController(this._overflowController);
302
+
303
+ this.$.overlay.renderer = this.__overlayRenderer.bind(this);
295
304
 
296
305
  afterNextRender(this, () => {
297
306
  this.__setItemsInView();
@@ -305,17 +314,64 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
305
314
  this._opened = false;
306
315
  }
307
316
 
317
+ /** @private */
318
+ __getMessage(user, action) {
319
+ return action.replace('{user}', user.name || user.abbr || this.i18n.anonymous);
320
+ }
321
+
308
322
  /**
309
- * @return {!Array<!HTMLElement>}
310
- * @protected
323
+ * Renders items when they are provided by the `items` property and clears the content otherwise.
324
+ * @param {!HTMLElement} root
325
+ * @param {!Select} _select
326
+ * @private
311
327
  */
312
- get _avatars() {
313
- return this.shadowRoot.querySelectorAll('vaadin-avatar');
328
+ __overlayRenderer(root) {
329
+ let listBox = root.firstElementChild;
330
+ if (!listBox) {
331
+ listBox = document.createElement('vaadin-list-box');
332
+ listBox.addEventListener('keydown', (event) => this._onListKeyDown(event));
333
+ root.appendChild(listBox);
334
+ }
335
+
336
+ listBox.textContent = '';
337
+
338
+ if (!this._overflowItems) {
339
+ return;
340
+ }
341
+
342
+ this._overflowItems.forEach((item) => {
343
+ listBox.appendChild(this.__createItemElement(item));
344
+ });
314
345
  }
315
346
 
316
347
  /** @private */
317
- __getMessage(user, action) {
318
- return action.replace('{user}', user.name || user.abbr || this.i18n.anonymous);
348
+ __createItemElement(item) {
349
+ const itemElement = document.createElement('vaadin-item');
350
+ itemElement.setAttribute('theme', 'avatar-group-item');
351
+ itemElement.setAttribute('role', 'option');
352
+
353
+ const avatar = document.createElement('vaadin-avatar');
354
+ itemElement.appendChild(avatar);
355
+
356
+ avatar.setAttribute('aria-hidden', 'true');
357
+ avatar.setAttribute('tabindex', '-1');
358
+ avatar.i18n = this.i18n;
359
+
360
+ if (this._theme) {
361
+ avatar.setAttribute('theme', this._theme);
362
+ }
363
+
364
+ avatar.name = item.name;
365
+ avatar.abbr = item.abbr;
366
+ avatar.img = item.img;
367
+ avatar.colorIndex = item.colorIndex;
368
+
369
+ if (item.name) {
370
+ const text = document.createTextNode(item.name);
371
+ itemElement.appendChild(text);
372
+ }
373
+
374
+ return itemElement;
319
375
  }
320
376
 
321
377
  /** @private */
@@ -361,17 +417,47 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
361
417
  }
362
418
 
363
419
  /** @private */
364
- __computeItems(arr, itemsInView, maxItemsVisible) {
420
+ __renderAvatars(items) {
421
+ render(
422
+ html`
423
+ ${items.map(
424
+ (item) =>
425
+ html`
426
+ <vaadin-avatar
427
+ .name="${item.name}"
428
+ .abbr="${item.abbr}"
429
+ .img="${item.img}"
430
+ .colorIndex="${item.colorIndex}"
431
+ .i18n="${this.i18n}"
432
+ with-tooltip
433
+ ></vaadin-avatar>
434
+ `,
435
+ )}
436
+ `,
437
+ this,
438
+ { renderBefore: this._overflow },
439
+ );
440
+ }
441
+
442
+ /** @private */
443
+ __updateAvatars(arr, itemsInView, maxItemsVisible, overflow) {
444
+ if (!overflow) {
445
+ return;
446
+ }
447
+
365
448
  const items = arr.base || [];
366
449
  const limit = this.__getLimit(items.length, itemsInView, maxItemsVisible);
367
- return limit ? items.slice(0, limit) : items;
450
+
451
+ this.__renderAvatars(limit ? items.slice(0, limit) : items);
452
+
453
+ this._avatars = [...this.querySelectorAll('vaadin-avatar')];
368
454
  }
369
455
 
370
456
  /** @private */
371
- __computeExtraItems(arr, itemsInView, maxItemsVisible) {
457
+ __computeOverflowItems(arr, itemsInView, maxItemsVisible) {
372
458
  const items = arr.base || [];
373
459
  const limit = this.__getLimit(items.length, itemsInView, maxItemsVisible);
374
- return limit ? items.slice(limit) : items;
460
+ return limit ? items.slice(limit) : [];
375
461
  }
376
462
 
377
463
  /** @private */
@@ -380,21 +466,43 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
380
466
  }
381
467
 
382
468
  /** @private */
383
- __computeMore(items, itemsInView, maxItemsVisible) {
384
- return `+${items - this.__getLimit(items, itemsInView, maxItemsVisible)}`;
469
+ __updateOverflowAbbr(overflow, items, itemsInView, maxItemsVisible) {
470
+ if (overflow) {
471
+ overflow.abbr = `+${items - this.__getLimit(items, itemsInView, maxItemsVisible)}`;
472
+ }
385
473
  }
386
474
 
387
475
  /** @private */
388
- __computeMoreHidden(items, itemsInView, maxReached) {
389
- return !maxReached && !(itemsInView && itemsInView < items);
476
+ __updateOverflowHidden(overflow, items, itemsInView, maxReached) {
477
+ if (overflow) {
478
+ overflow.toggleAttribute('hidden', !maxReached && !(itemsInView && itemsInView < items));
479
+ }
390
480
  }
391
481
 
392
482
  /** @private */
393
- __computeMoreTooltip(items, itemsInView, maxItemsVisible) {
483
+ __updateAvatarsTheme(overflow, avatars, theme) {
484
+ if (overflow) {
485
+ [overflow, ...avatars].forEach((avatar) => {
486
+ if (theme) {
487
+ avatar.setAttribute('theme', theme);
488
+ } else {
489
+ avatar.removeAttribute('theme');
490
+ }
491
+ });
492
+ }
493
+ }
494
+
495
+ /** @private */
496
+ __updateOverflowTooltip(tooltip, items, itemsInView, maxItemsVisible) {
497
+ if (!tooltip) {
498
+ return;
499
+ }
500
+
394
501
  const limit = this.__getLimit(items, itemsInView, maxItemsVisible);
395
502
  if (limit == null) {
396
503
  return;
397
504
  }
505
+
398
506
  const result = [];
399
507
  for (let i = limit; i < items; i++) {
400
508
  const item = this.items[i];
@@ -402,8 +510,8 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
402
510
  result.push(item.name || item.abbr || 'anonymous');
403
511
  }
404
512
  }
405
- // Override generated tooltip text
406
- this.__overflowTextGenerator = () => result.join('\n');
513
+
514
+ tooltip.text = result.join('\n');
407
515
  }
408
516
 
409
517
  /** @private */
@@ -428,7 +536,6 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
428
536
  /** @private */
429
537
  __itemsChanged(splices, itemsChange) {
430
538
  const items = itemsChange.base;
431
- this.$.items.render();
432
539
  this.__setItemsInView();
433
540
 
434
541
  // Mutation using group.splice('items')
@@ -476,6 +583,10 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
476
583
  if (base.activeUsers[field]) {
477
584
  this.setAttribute('aria-label', base.activeUsers[field].replace('{count}', items || 0));
478
585
  }
586
+
587
+ this._avatars.forEach((avatar) => {
588
+ avatar.i18n = base;
589
+ });
479
590
  }
480
591
  }
481
592
 
@@ -483,20 +594,27 @@ class AvatarGroup extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)
483
594
  __openedChanged(opened, wasOpened) {
484
595
  if (opened) {
485
596
  if (!this._menuElement) {
486
- this._menuElement = this._overlayElement.content.querySelector('vaadin-avatar-group-list-box');
597
+ this._menuElement = this.$.overlay.querySelector('vaadin-list-box');
487
598
  this._menuElement.setAttribute('role', 'listbox');
488
599
  }
489
600
 
490
- this._openedWithFocusRing = this.$.overflow.hasAttribute('focus-ring');
601
+ this._openedWithFocusRing = this._overflow.hasAttribute('focus-ring');
491
602
 
492
603
  this._menuElement.focus();
493
604
  } else if (wasOpened) {
494
- this.$.overflow.focus();
605
+ this._overflow.focus();
495
606
  if (this._openedWithFocusRing) {
496
- this.$.overflow.setAttribute('focus-ring', '');
607
+ this._overflow.setAttribute('focus-ring', '');
497
608
  }
498
609
  }
499
- this.$.overflow.setAttribute('aria-expanded', opened === true);
610
+ this._overflow.setAttribute('aria-expanded', opened === true);
611
+ }
612
+
613
+ /** @private */
614
+ __overflowItemsChanged(items, oldItems) {
615
+ if (items || oldItems) {
616
+ this.$.overlay.requestContentUpdate();
617
+ }
500
618
  }
501
619
 
502
620
  /** @private */
@@ -55,24 +55,13 @@ registerStyles('vaadin-avatar-group-overlay', [overlay, menuOverlayCore, avatarG
55
55
  });
56
56
 
57
57
  registerStyles(
58
- 'vaadin-avatar-group-list-box',
58
+ 'vaadin-item',
59
59
  css`
60
- [part='items'] ::slotted(vaadin-item[theme='avatar-group-item']) {
60
+ :host([theme='avatar-group-item']) {
61
61
  padding: var(--lumo-space-xs);
62
- padding-right: var(--lumo-space-m);
62
+ padding-inline-end: var(--lumo-space-m);
63
63
  }
64
64
 
65
- :host([dir='rtl']) [part='items'] ::slotted(vaadin-item[theme='avatar-group-item']) {
66
- padding: var(--lumo-space-xs);
67
- padding-left: var(--lumo-space-m);
68
- }
69
- `,
70
- { moduleId: 'lumo-avatar-group-list-box' },
71
- );
72
-
73
- registerStyles(
74
- 'vaadin-item',
75
- css`
76
65
  :host([theme='avatar-group-item']) [part='content'] {
77
66
  display: flex;
78
67
  align-items: center;
@@ -47,24 +47,13 @@ registerStyles('vaadin-avatar-group-overlay', [menuOverlay, avatarGroupOverlay],
47
47
  });
48
48
 
49
49
  registerStyles(
50
- 'vaadin-avatar-group-list-box',
50
+ 'vaadin-item',
51
51
  css`
52
- [part='items'] ::slotted(vaadin-item[theme='avatar-group-item']) {
52
+ :host([theme='avatar-group-item']) {
53
53
  padding: 8px;
54
- padding-right: 24px;
54
+ padding-inline-end: 24px;
55
55
  }
56
56
 
57
- :host([dir='rtl']) [part='items'] ::slotted(vaadin-item[theme='avatar-group-item']) {
58
- padding: 8px;
59
- padding-left: 24px;
60
- }
61
- `,
62
- { moduleId: 'material-avatar-group-list-box' },
63
- );
64
-
65
- registerStyles(
66
- 'vaadin-item',
67
- css`
68
57
  :host([theme='avatar-group-item']) [part='content'] {
69
58
  display: flex;
70
59
  align-items: center;
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/avatar-group",
4
- "version": "23.3.0-alpha5",
4
+ "version": "24.0.0-alpha2",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-avatar-group",
11
- "description": "`<vaadin-avatar-group>` is a Web Component providing avatar group displaying functionality.\n\nTo create the avatar group, first add the component to the page:\n\n```\n<vaadin-avatar-group></vaadin-avatar-group>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-avatar-group#property-items) property to initialize the structure:\n\n```\ndocument.querySelector('vaadin-avatar-group').items = [\n {name: 'John Doe'},\n {abbr: 'AB'}\n];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n----------- | ---------------\n`container` | The container element\n`avatar` | Individual avatars\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-avatar-group>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-avatar-group-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-list-box).\n- `<vaadin-avatar-group-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-overlay).",
11
+ "description": "`<vaadin-avatar-group>` is a Web Component providing avatar group displaying functionality.\n\nTo create the avatar group, first add the component to the page:\n\n```\n<vaadin-avatar-group></vaadin-avatar-group>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar-group#property-items) property to initialize the structure:\n\n```\ndocument.querySelector('vaadin-avatar-group').items = [\n {name: 'John Doe'},\n {abbr: 'AB'}\n];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n----------- | ---------------\n`container` | The container element\n\nSee the [`<vaadin-avatar>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar) documentation for the available\nstate attributes and stylable shadow parts of avatar elements.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-avatar-group>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-avatar-group-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-overlay).",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "max-items-visible",
@@ -37,7 +37,7 @@
37
37
  "properties": [
38
38
  {
39
39
  "name": "items",
40
- "description": "An array containing the items which will be stamped as avatars.\n\nThe items objects allow to configure [`name`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-avatar#property-name),\n[`abbr`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-avatar#property-abbr), [`img`](#/elements/vaadin-avatar#property-img)\nand [`colorIndex`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-avatar#property-colorIndex) properties on the\nstamped avatars.\n\n#### Example\n\n```js\ngroup.items = [\n {\n name: 'User name',\n img: 'url-to-image.png'\n },\n {\n abbr: 'JD',\n colorIndex: 1\n },\n];\n```",
40
+ "description": "An array containing the items which will be stamped as avatars.\n\nThe items objects allow to configure [`name`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar#property-name),\n[`abbr`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar#property-abbr), [`img`](#/elements/vaadin-avatar#property-img)\nand [`colorIndex`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar#property-colorIndex) properties on the\nstamped avatars.\n\n#### Example\n\n```js\ngroup.items = [\n {\n name: 'User name',\n img: 'url-to-image.png'\n },\n {\n abbr: 'JD',\n colorIndex: 1\n },\n];\n```",
41
41
  "value": {
42
42
  "type": [
43
43
  "Array.<AvatarGroupItem>",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/avatar-group",
4
- "version": "23.3.0-alpha5",
4
+ "version": "24.0.0-alpha2",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,12 +16,12 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-avatar-group",
19
- "description": "`<vaadin-avatar-group>` is a Web Component providing avatar group displaying functionality.\n\nTo create the avatar group, first add the component to the page:\n\n```\n<vaadin-avatar-group></vaadin-avatar-group>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-avatar-group#property-items) property to initialize the structure:\n\n```\ndocument.querySelector('vaadin-avatar-group').items = [\n {name: 'John Doe'},\n {abbr: 'AB'}\n];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n----------- | ---------------\n`container` | The container element\n`avatar` | Individual avatars\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-avatar-group>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-avatar-group-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-list-box).\n- `<vaadin-avatar-group-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-overlay).",
19
+ "description": "`<vaadin-avatar-group>` is a Web Component providing avatar group displaying functionality.\n\nTo create the avatar group, first add the component to the page:\n\n```\n<vaadin-avatar-group></vaadin-avatar-group>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar-group#property-items) property to initialize the structure:\n\n```\ndocument.querySelector('vaadin-avatar-group').items = [\n {name: 'John Doe'},\n {abbr: 'AB'}\n];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n----------- | ---------------\n`container` | The container element\n\nSee the [`<vaadin-avatar>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar) documentation for the available\nstate attributes and stylable shadow parts of avatar elements.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-avatar-group>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-avatar-group-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-overlay).",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {
23
23
  "name": ".items",
24
- "description": "An array containing the items which will be stamped as avatars.\n\nThe items objects allow to configure [`name`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-avatar#property-name),\n[`abbr`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-avatar#property-abbr), [`img`](#/elements/vaadin-avatar#property-img)\nand [`colorIndex`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha5/#/elements/vaadin-avatar#property-colorIndex) properties on the\nstamped avatars.\n\n#### Example\n\n```js\ngroup.items = [\n {\n name: 'User name',\n img: 'url-to-image.png'\n },\n {\n abbr: 'JD',\n colorIndex: 1\n },\n];\n```",
24
+ "description": "An array containing the items which will be stamped as avatars.\n\nThe items objects allow to configure [`name`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar#property-name),\n[`abbr`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar#property-abbr), [`img`](#/elements/vaadin-avatar#property-img)\nand [`colorIndex`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha2/#/elements/vaadin-avatar#property-colorIndex) properties on the\nstamped avatars.\n\n#### Example\n\n```js\ngroup.items = [\n {\n name: 'User name',\n img: 'url-to-image.png'\n },\n {\n abbr: 'JD',\n colorIndex: 1\n },\n];\n```",
25
25
  "value": {
26
26
  "kind": "expression"
27
27
  }
@@ -1,20 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2020 - 2022 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { ListBox } from '@vaadin/list-box/src/vaadin-list-box.js';
7
-
8
- /**
9
- * An element used internally by `<vaadin-avatar-group>`. Not intended to be used separately.
10
- *
11
- * @extends ListBox
12
- * @private
13
- */
14
- class AvatarGroupListBox extends ListBox {
15
- static get is() {
16
- return 'vaadin-avatar-group-list-box';
17
- }
18
- }
19
-
20
- customElements.define(AvatarGroupListBox.is, AvatarGroupListBox);