@vaadin/vaadin-avatar
Advanced tools
Comparing version 1.0.0-alpha6 to 1.0.0-alpha7
@@ -13,3 +13,3 @@ { | ||
"name": "@vaadin/vaadin-avatar", | ||
"version": "1.0.0-alpha6", | ||
"version": "1.0.0-alpha7", | ||
"main": "vaadin-avatar-group.js", | ||
@@ -16,0 +16,0 @@ "author": "Vaadin Ltd", |
@@ -29,5 +29,13 @@ # <vaadin-avatar> | ||
```html | ||
<vaadin-avatar> | ||
... | ||
</vaadin-avatar> | ||
<vaadin-avatar></vaadin-avatar> | ||
<vaadin-avatar name="Jens Jansson"></vaadin-avatar> | ||
<vaadin-avatar abbr="SK"></vaadin-avatar> | ||
<vaadin-avatar-group max="2"></vaadin-avatar-group> | ||
<script> | ||
document.querySelector('vaadin-avatar-group').items = [ | ||
{name: 'Foo Bar', colorIndex: 1}, | ||
{colorIndex: 2}, | ||
{name: 'Foo Bar', colorIndex: 3} | ||
]; | ||
</script> | ||
``` | ||
@@ -58,2 +66,3 @@ | ||
<link rel="import" href="bower_components/vaadin-avatar/vaadin-avatar.html"> | ||
<link rel="import" href="bower_components/vaadin-avatar/vaadin-avatar-group.html"> | ||
``` | ||
@@ -73,2 +82,3 @@ | ||
import '@vaadin/vaadin-avatar/vaadin-avatar.js'; | ||
import '@vaadin/vaadin-avatar/vaadin-avatar-group.js'; | ||
``` | ||
@@ -84,13 +94,16 @@ | ||
- The component with the Lumo theme: | ||
- The components with the Lumo theme: | ||
`theme/lumo/vaadin-avatar.html` | ||
`theme/lumo/vaadin-avatar-group.html` | ||
- The component with the Material theme: | ||
- The components with the Material theme: | ||
`theme/material/vaadin-avatar.html` | ||
`theme/material/vaadin-avatar-group.html` | ||
- Alias for `theme/lumo/vaadin-avatar.html`: | ||
- Alias for `theme/lumo/vaadin-avatar.html` `theme/lumo/vaadin-avatar-group.html`: | ||
`vaadin-avatar.html` | ||
`vaadin-avatar-group.html` | ||
@@ -97,0 +110,0 @@ |
@@ -16,2 +16,6 @@ /** | ||
import {timeOut} from '@polymer/polymer/lib/utils/async.js'; | ||
import {Debouncer} from '@polymer/polymer/lib/utils/debounce.js'; | ||
import {ThemableMixin} from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; | ||
@@ -25,2 +29,4 @@ | ||
import {afterNextRender} from '@polymer/polymer/lib/utils/render-status.js'; | ||
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js'; | ||
@@ -43,2 +49,3 @@ | ||
PolymerElement)) { | ||
readonly _avatars: HTMLElement[]; | ||
@@ -45,0 +52,0 @@ /** |
@@ -8,2 +8,4 @@ /** | ||
import { timeOut } from '@polymer/polymer/lib/utils/async.js'; | ||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js'; | ||
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; | ||
@@ -17,2 +19,3 @@ import { IronResizableBehavior } from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js'; | ||
import { html } from '@polymer/polymer/lib/utils/html-tag.js'; | ||
import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js'; | ||
import { mixinBehaviors } from '@polymer/polymer/lib/legacy/class.js'; | ||
@@ -45,4 +48,3 @@ | ||
:host { | ||
display: flex; | ||
align-items: center; | ||
display: block; | ||
--vaadin-avatar-group-overlap: 8px; | ||
@@ -53,2 +55,13 @@ --vaadin-avatar-group-overlap-border: 2px; | ||
[part="container"] { | ||
display: flex; | ||
position: relative; | ||
width: 100%; | ||
flex-wrap: nowrap; | ||
} | ||
[part="avatar"] { | ||
flex-shrink: 0; | ||
} | ||
[part="avatar"]:not(:first-child) { | ||
@@ -73,7 +86,7 @@ -webkit-mask-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMzAwIDMwMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMwMCAwSDBWMzAwSDMwMFYwWk0xNTAgMjAwQzE3Ny42MTQgMjAwIDIwMCAxNzcuNjE0IDIwMCAxNTBDMjAwIDEyMi4zODYgMTc3LjYxNCAxMDAgMTUwIDEwMEMxMjIuMzg2IDEwMCAxMDAgMTIyLjM4NiAxMDAgMTUwQzEwMCAxNzcuNjE0IDEyMi4zODYgMjAwIDE1MCAyMDBaIiBmaWxsPSJibGFjayIvPjwvc3ZnPg==); | ||
</style> | ||
<div id="container"> | ||
<template is="dom-repeat" items="[[__computeItems(items.*, max)]]"> | ||
<div id="container" part="container"> | ||
<template is="dom-repeat" items="[[__computeItems(items.*, __itemsInView, max)]]"> | ||
<vaadin-avatar name="[[item.name]]" abbr="[[item.abbr]]" img="[[item.img]]" part="avatar" theme\$="[[theme]]" i18n="[[i18n]]" color-index="[[item.colorIndex]]"></vaadin-avatar> | ||
</template> | ||
<vaadin-avatar id="overflow" part="avatar" hidden\$="[[!__maxReached]]" abbr="[[__computeMore(items.length, max)]]" theme\$="[[theme]]" on-click="_onOverflowClick" on-keydown="_onOverflowKeyDown" aria-haspopup="listbox"></vaadin-avatar> | ||
<vaadin-avatar id="overflow" part="avatar" hidden\$="[[__computeMoreHidden(items.length, __itemsInView, __maxReached)]]" abbr="[[__computeMore(items.length, __itemsInView, max)]]" theme\$="[[theme]]" on-click="_onOverflowClick" on-keydown="_onOverflowKeyDown" aria-haspopup="listbox"></vaadin-avatar> | ||
</div> | ||
@@ -83,3 +96,3 @@ <vaadin-avatar-group-overlay id="overlay" opened="{{_opened}}" on-vaadin-overlay-close="_onVaadinOverlayClose"> | ||
<vaadin-avatar-group-list-box on-keydown="_onListKeyDown"> | ||
<template is="dom-repeat" items="[[__computeExtraItems(items.*, max)]]"> | ||
<template is="dom-repeat" items="[[__computeExtraItems(items.*, __itemsInView, max)]]"> | ||
<vaadin-item theme="avatar-group-item" role="option"> | ||
@@ -101,3 +114,3 @@ <vaadin-avatar name="[[item.name]]" abbr="[[item.abbr]]" img="[[item.img]]" i18n="[[i18n]]" part="avatar" theme\$="[[theme]]" color-index="[[item.colorIndex]]" tabindex="-1" aria-hidden="true"></vaadin-avatar> | ||
static get version() { | ||
return '1.0.0-alpha6'; | ||
return '1.0.0-alpha7'; | ||
} | ||
@@ -162,2 +175,8 @@ | ||
/** @private */ | ||
__itemsInView: { | ||
type: Number, | ||
value: null | ||
}, | ||
/** @private */ | ||
_opened: { | ||
@@ -173,3 +192,4 @@ type: Boolean, | ||
return [ | ||
'__computeMoreTitle(items.length, max)', | ||
'__computeMoreTitle(items.length, __itemsInView, max)', | ||
'__itemsChanged(items.length)', | ||
'__i18nItemsChanged(i18n.*, items.length)' | ||
@@ -188,2 +208,6 @@ ]; | ||
this._overlayElement = this.shadowRoot.querySelector('vaadin-avatar-group-overlay'); | ||
afterNextRender(this, () => { | ||
this.__setItemsInView(); | ||
}); | ||
} | ||
@@ -204,2 +228,10 @@ | ||
/** | ||
* @return {!Array<!HTMLElement>} | ||
* @protected | ||
*/ | ||
get _avatars() { | ||
return this.shadowRoot.querySelectorAll('vaadin-avatar'); | ||
} | ||
/** @private */ | ||
@@ -234,3 +266,10 @@ _onOverflowClick(e) { | ||
_onResize() { | ||
this.__setPosition(); | ||
this.__debounceResize = Debouncer.debounce( | ||
this.__debounceResize, | ||
timeOut.after(0), | ||
() => { | ||
this.__setItemsInView(); | ||
this.__setPosition(); | ||
} | ||
); | ||
} | ||
@@ -246,11 +285,13 @@ | ||
/** @private */ | ||
__computeItems(arr, max) { | ||
__computeItems(arr, itemsInView, max) { | ||
const items = arr.base || []; | ||
return max != null ? items.slice(0, max) : items; | ||
const limit = this.__getLimit(items.length, itemsInView, max); | ||
return limit ? items.slice(0, limit) : items; | ||
} | ||
/** @private */ | ||
__computeExtraItems(arr, max) { | ||
__computeExtraItems(arr, itemsInView, max) { | ||
const items = arr.base || []; | ||
return max != null ? items.slice(max) : items; | ||
const limit = this.__getLimit(items.length, itemsInView, max); | ||
return limit ? items.slice(limit) : items; | ||
} | ||
@@ -264,13 +305,19 @@ | ||
/** @private */ | ||
__computeMore(items, max) { | ||
return `+${items - max}`; | ||
__computeMore(items, itemsInView, max) { | ||
return max != null ? `+${items - max}` : `+${items - itemsInView}`; | ||
} | ||
/** @private */ | ||
__computeMoreTitle(items, max) { | ||
if (max == null) { | ||
__computeMoreHidden(items, itemsInView, maxReached) { | ||
return !maxReached && !(itemsInView && itemsInView < items); | ||
} | ||
/** @private */ | ||
__computeMoreTitle(items, itemsInView, max) { | ||
const limit = this.__getLimit(items, itemsInView, max); | ||
if (limit == null) { | ||
return; | ||
} | ||
const result = []; | ||
for (let i = max; i < items; i++) { | ||
for (let i = limit; i < items; i++) { | ||
const item = this.items[i]; | ||
@@ -284,2 +331,18 @@ result.push(item.name || item.abbr || 'anonymous'); | ||
/** @private */ | ||
__getLimit(items, itemsInView, max) { | ||
let limit = null; | ||
if (max != null) { | ||
limit = max; | ||
} else if (itemsInView && itemsInView < items) { | ||
limit = itemsInView; | ||
} | ||
return limit; | ||
} | ||
/** @private */ | ||
__itemsChanged(items) { | ||
this.__setItemsInView(); | ||
} | ||
/** @private */ | ||
__i18nItemsChanged(i18n, items) { | ||
@@ -322,2 +385,32 @@ const {base} = i18n; | ||
/** @private */ | ||
__setItemsInView() { | ||
const avatars = this._avatars; | ||
if (!avatars || avatars.length < 2) { | ||
return; | ||
} | ||
// assume all the avatars have the same width | ||
const avatarWidth = avatars[0].clientWidth; | ||
// take negative margin into account | ||
const {marginLeft, marginRight} = getComputedStyle(avatars[1]); | ||
const offset = this.getAttribute('dir') == 'rtl' ? | ||
parseInt(marginRight, 0) - parseInt(marginLeft, 0) : | ||
parseInt(marginLeft, 0) - parseInt(marginRight, 0); | ||
const result = Math.floor((this.$.container.offsetWidth - avatarWidth) / (avatarWidth + offset)); | ||
// close overlay if all avatars become visible | ||
if (result >= this.items.length && this._opened) { | ||
this.$.overlay.close(); | ||
// FIXME: hack to avoid jump before closing | ||
this.$.overlay._flushAnimation('closing'); | ||
} | ||
// reserve space for overflow avatar | ||
this.__itemsInView = result; | ||
} | ||
/** @private */ | ||
__setPosition() { | ||
@@ -324,0 +417,0 @@ if (!this._opened) { |
@@ -91,2 +91,3 @@ /** | ||
position: relative; | ||
background-color: var(--vaadin-avatar-user-color); | ||
} | ||
@@ -103,3 +104,3 @@ | ||
border-radius: 50%; | ||
box-shadow: inset 0 0 0 2px var(--vaadin-avatar-border-color); | ||
box-shadow: inset 0 0 0 2px var(--vaadin-avatar-user-color); | ||
} | ||
@@ -122,3 +123,3 @@ </style> | ||
static get version() { | ||
return '1.0.0-alpha6'; | ||
return '1.0.0-alpha7'; | ||
} | ||
@@ -249,6 +250,6 @@ | ||
window.ShadyCSS.styleSubtree(this, { | ||
'--vaadin-avatar-border-color': color | ||
'--vaadin-avatar-user-color': color | ||
}); | ||
} else { | ||
this.style.setProperty('--vaadin-avatar-border-color', color); | ||
this.style.setProperty('--vaadin-avatar-user-color', color); | ||
} | ||
@@ -255,0 +256,0 @@ } else { |
@@ -113,1 +113,35 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
document.head.appendChild($_documentContainer.content); | ||
const isIE = !!(navigator.userAgent.match(/Trident/) && !navigator.userAgent.match(/MSIE/)); | ||
// NOTE(web-padawan): re-declaring same custom CSS property crashes IE11 | ||
if (!isIE) { | ||
const AvatarGroupStyles = document.createElement('dom-module'); | ||
AvatarGroupStyles.setAttribute('theme-for', 'vaadin-avatar-group'); | ||
const tpl = document.createElement('template'); | ||
tpl.innerHTML = ` | ||
<style> | ||
:host([theme~="xlarge"]) { | ||
--vaadin-avatar-group-overlap: 12px; | ||
--vaadin-avatar-group-overlap-border: 3px; | ||
} | ||
:host([theme~="large"]) { | ||
--vaadin-avatar-group-overlap: 10px; | ||
--vaadin-avatar-group-overlap-border: 3px; | ||
} | ||
:host([theme~="small"]) { | ||
--vaadin-avatar-group-overlap: 6px; | ||
--vaadin-avatar-group-overlap-border: 2px; | ||
} | ||
:host([theme~="xsmall"]) { | ||
--vaadin-avatar-group-overlap: 4px; | ||
--vaadin-avatar-group-overlap-border: 2px; | ||
} | ||
</style> | ||
`; | ||
AvatarGroupStyles.appendChild(tpl); | ||
AvatarGroupStyles.register('lumo-avatar-group-variants'); | ||
} |
@@ -20,2 +20,3 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
user-select: none; | ||
-webkit-tap-highlight-color: transparent; | ||
-webkit-font-smoothing: antialiased; | ||
@@ -25,2 +26,6 @@ -moz-osx-font-smoothing: grayscale; | ||
:host([has-color-index]) { | ||
color: var(--lumo-base-color); | ||
} | ||
:host([focus-ring]) { | ||
@@ -37,17 +42,20 @@ border-color: var(--lumo-primary-color-50pct); | ||
font-family: var(--lumo-font-family); | ||
font-size: 3em; | ||
font-size: 2.4375em; | ||
font-weight: 500; | ||
} | ||
:host([theme~="xlarge"]) [part="abbr"], | ||
:host([theme~="xlarge"]) [part="abbr"] { | ||
font-size: 2.5em; | ||
} | ||
:host([theme~="large"]) [part="abbr"] { | ||
font-size: 2.875em; | ||
font-size: 2.375em; | ||
} | ||
:host([theme~="small"]) [part="abbr"] { | ||
font-size: 3.2em; | ||
font-size: 2.75em; | ||
} | ||
:host([theme~="xsmall"]) [part="abbr"] { | ||
font-size: 3.5em; | ||
font-size: 3em; | ||
} | ||
@@ -54,0 +62,0 @@ |
@@ -16,2 +16,3 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
user-select: none; | ||
-webkit-tap-highlight-color: transparent; | ||
-webkit-font-smoothing: antialiased; | ||
@@ -21,2 +22,6 @@ -moz-osx-font-smoothing: grayscale; | ||
:host([has-color-index]) { | ||
color: var(--material-primary-contrast-color); | ||
} | ||
:host([focus-ring]) { | ||
@@ -28,3 +33,3 @@ border-color: var(--material-primary-color); | ||
[part="abbr"] { | ||
fill: var(--material-secondary-text-color); | ||
fill: currentColor; | ||
} | ||
@@ -31,0 +36,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
60470
1179
150