@vaadin/vaadin-avatar
Advanced tools
Comparing version 1.0.0-alpha2 to 1.0.0-alpha3
@@ -13,3 +13,3 @@ { | ||
"name": "@vaadin/vaadin-avatar", | ||
"version": "1.0.0-alpha2", | ||
"version": "1.0.0-alpha3", | ||
"main": "vaadin-avatar-group.js", | ||
@@ -16,0 +16,0 @@ "author": "Vaadin Ltd", |
@@ -45,23 +45,22 @@ /** | ||
align-items: center; | ||
--vaadin-avatar-group-overlap: 8px; | ||
--vaadin-avatar-group-overlap-border: 2px; | ||
--vaadin-avatar-size: 64px; | ||
} | ||
[part="avatar"] { | ||
border: calc(var(--_avatar-group-offset) / 20) solid white; | ||
[part="avatar"]:not(:first-child) { | ||
margin-left: calc(var(--vaadin-avatar-group-overlap) * -1 - var(--vaadin-avatar-outline-width) * 1); | ||
-webkit-mask-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMzAwIDMwMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMwMCAwSDBWMzAwSDMwMFYwWk0xNTAgMjAwQzE3Ny42MTQgMjAwIDIwMCAxNzcuNjE0IDIwMCAxNTBDMjAwIDEyMi4zODYgMTc3LjYxNCAxMDAgMTUwIDEwMEMxMjIuMzg2IDEwMCAxMDAgMTIyLjM4NiAxMDAgMTUwQzEwMCAxNzcuNjE0IDEyMi4zODYgMjAwIDE1MCAyMDBaIiBmaWxsPSJibGFjayIvPjwvc3ZnPg==); | ||
mask-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMzAwIDMwMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMwMCAwSDBWMzAwSDMwMFYwWk0xNTAgMjAwQzE3Ny42MTQgMjAwIDIwMCAxNzcuNjE0IDIwMCAxNTBDMjAwIDEyMi4zODYgMTc3LjYxNCAxMDAgMTUwIDEwMEMxMjIuMzg2IDEwMCAxMDAgMTIyLjM4NiAxMDAgMTUwQzEwMCAxNzcuNjE0IDEyMi4zODYgMjAwIDE1MCAyMDBaIiBmaWxsPSJibGFjayIvPjwvc3ZnPg==); | ||
-webkit-mask-size: calc(300% + var(--vaadin-avatar-group-overlap-border) * 6 - var(--vaadin-avatar-outline-width) * 6); | ||
mask-size: calc(300% + var(--vaadin-avatar-group-overlap-border) * 6 - var(--vaadin-avatar-outline-width) * 6); | ||
-webkit-mask-position: calc(50% - var(--vaadin-avatar-size) + var(--vaadin-avatar-group-overlap)); | ||
mask-position: calc(50% - var(--vaadin-avatar-size) + var(--vaadin-avatar-group-overlap)); | ||
} | ||
#container vaadin-avatar:not(:first-child) { | ||
/* Should take scalability of the host into account */ | ||
margin-left: calc(var(--_avatar-group-offset) / -3); | ||
-webkit-mask-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSI0MDIiIHdpZHRoPSI1ODIiIHk9Ii0xIiB4PSItMSIvPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxwYXRoIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTYsMTUuOTk5OTk5OTk5OTk5OTk4KSAiIGlkPSJzdmdfMSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMzQsLTAuOTc1NzdjLTYuOTkxMTUsMi40NzEwMiAtMTIsOS4xMzg0NiAtMTIsMTYuOTc1NzdjMCw3LjgzNzMxIDUuMDA4ODUsMTQuNTA0NzUgMTIsMTYuOTc1NzdsMCwxLjAyNDIzbC0zNiwwbDAsLTM2bDM2LDBsMCwxLjAyNDIzeiIvPgogPC9nPgo8L3N2Zz4=); | ||
mask-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSI0MDIiIHdpZHRoPSI1ODIiIHk9Ii0xIiB4PSItMSIvPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxwYXRoIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTYsMTUuOTk5OTk5OTk5OTk5OTk4KSAiIGlkPSJzdmdfMSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMzQsLTAuOTc1NzdjLTYuOTkxMTUsMi40NzEwMiAtMTIsOS4xMzg0NiAtMTIsMTYuOTc1NzdjMCw3LjgzNzMxIDUuMDA4ODUsMTQuNTA0NzUgMTIsMTYuOTc1NzdsMCwxLjAyNDIzbC0zNiwwbDAsLTM2bDM2LDBsMCwxLjAyNDIzeiIvPgogPC9nPgo8L3N2Zz4=); | ||
-webkit-mask-size: 100% 100%; | ||
mask-size: 100% 100%; | ||
flex: none; | ||
} | ||
</style> | ||
<div id="container"> | ||
<template is="dom-repeat" items="[[__computeItems(items.*, max)]]"> | ||
<vaadin-avatar name="[[item.name]]" abbr="[[item.abbr]]" img="[[item.img]]" part="avatar" theme\$="[[theme]]"></vaadin-avatar> | ||
<vaadin-avatar name="[[item.name]]" abbr="[[item.abbr]]" img="[[item.img]]" part="avatar" theme\$="[[theme]]" color-index="[[item.colorIndex]]"></vaadin-avatar> | ||
</template> | ||
<vaadin-avatar id="overflow" part="avatar" hidden\$="[[!__maxReached]]" name="[[__computeMore(items.length, max)]]" abbr="[[__computeMore(items.length, max)]]" theme\$="[[theme]]" on-click="_onOverflowClick" on-keydown="_onOverflowKeyDown"></vaadin-avatar> | ||
<vaadin-avatar id="overflow" part="avatar" hidden\$="[[!__maxReached]]" abbr="[[__computeMore(items.length, max)]]" theme\$="[[theme]]" on-click="_onOverflowClick" on-keydown="_onOverflowKeyDown"></vaadin-avatar> | ||
</div> | ||
@@ -88,3 +87,3 @@ <vaadin-avatar-group-overlay id="overlay" opened="{{_opened}}" on-vaadin-overlay-close="_onVaadinOverlayClose"> | ||
static get version() { | ||
return '1.0.0-alpha2'; | ||
return '1.0.0-alpha3'; | ||
} | ||
@@ -98,4 +97,3 @@ | ||
items: { | ||
type: Array, | ||
observer: '__itemsChanged' | ||
type: Array | ||
}, | ||
@@ -125,2 +123,6 @@ | ||
static get observers() { | ||
return ['__computeMoreTitle(items.length, max)']; | ||
} | ||
ready() { | ||
@@ -161,3 +163,2 @@ super.ready(); | ||
_onResize() { | ||
this.__updateOffset(); | ||
this.__setPosition(); | ||
@@ -190,2 +191,15 @@ } | ||
__computeMoreTitle(items, max) { | ||
if (max == null) { | ||
return; | ||
} | ||
const result = []; | ||
for (let i = max; i < items; i++) { | ||
const item = this.items[i]; | ||
result.push(item.name || item.abbr || 'anonymous'); | ||
} | ||
// override generated title attribute | ||
this.$.overflow.setAttribute('title', result.join('\n')); | ||
} | ||
__itemsChanged(items) { | ||
@@ -237,13 +251,2 @@ this.__updateOffset(); | ||
} | ||
__updateOffset() { | ||
if (this.items && this.items.length > 0) { | ||
requestAnimationFrame(() => { | ||
const width = this.$.container.clientWidth; | ||
const itemsCount = this.items.length; | ||
this.updateStyles({'--_avatar-group-offset': width / itemsCount + 'px'}); | ||
}); | ||
} | ||
} | ||
} | ||
@@ -250,0 +253,0 @@ |
@@ -55,4 +55,9 @@ /** | ||
overflow: hidden; | ||
height: 64px; | ||
width: 64px; | ||
height: var(--vaadin-avatar-size); | ||
width: var(--vaadin-avatar-size); | ||
border: var(--vaadin-avatar-outline-width) solid transparent; | ||
margin: calc(var(--vaadin-avatar-outline-width) * -1); | ||
background-clip: content-box; | ||
--vaadin-avatar-outline-width: 2px; | ||
--vaadin-avatar-size: 64px; | ||
} | ||
@@ -84,2 +89,18 @@ | ||
} | ||
:host([has-color-index]) { | ||
position: relative; | ||
} | ||
:host([has-color-index])::before { | ||
position: absolute; | ||
z-index: 1; | ||
content: ''; | ||
top: 0; | ||
left: 0; | ||
bottom: 0; | ||
right: 0; | ||
border-radius: 50%; | ||
box-shadow: inset 0 0 0 2px var(--vaadin-avatar-border-color); | ||
} | ||
</style> | ||
@@ -101,3 +122,3 @@ <img hidden\$="[[!__imgVisible]]" src\$="[[img]]"> | ||
static get version() { | ||
return '1.0.0-alpha2'; | ||
return '1.0.0-alpha3'; | ||
} | ||
@@ -130,6 +151,13 @@ | ||
type: String, | ||
reflectToAttribute: true, | ||
observer: '__nameChanged' | ||
reflectToAttribute: true | ||
}, | ||
/** | ||
* Color index used for avatar border. | ||
*/ | ||
colorIndex: { | ||
type: Number, | ||
observer: '__colorIndexChanged' | ||
}, | ||
/** @private */ | ||
@@ -157,4 +185,6 @@ __imgVisible: Boolean, | ||
// Should set `anonymous` if name is not provided | ||
this.__setTitleFromName(this.name); | ||
// Should set `anonymous` if name / abbr is not provided | ||
if (!this.name && !this.abbr) { | ||
this.__setTitle(this.name); | ||
} | ||
@@ -165,32 +195,46 @@ if (!this.hasAttribute('tabindex')) { | ||
this.addEventListener('focusin', this._onFocusIn); | ||
this.addEventListener('focusout', this._onFocusOut); | ||
} | ||
this.addEventListener('focusin', () => { | ||
this._setFocused(true); | ||
}); | ||
_onFocusIn(event) { | ||
this._setFocused(event.composedPath()[0], true); | ||
this.addEventListener('focusout', () => { | ||
this._setFocused(false); | ||
}); | ||
} | ||
_onFocusOut(event) { | ||
this._setFocused(event.composedPath()[0], false); | ||
} | ||
_setFocused(target, focused) { | ||
_setFocused(focused) { | ||
if (focused) { | ||
target.setAttribute('focused', ''); | ||
this.setAttribute('focused', ''); | ||
if (keyboardActive) { | ||
target.setAttribute('focus-ring', ''); | ||
this.setAttribute('focus-ring', ''); | ||
} | ||
} else { | ||
target.removeAttribute('focused'); | ||
target.removeAttribute('focus-ring'); | ||
this.removeAttribute('focused'); | ||
this.removeAttribute('focus-ring'); | ||
} | ||
} | ||
__colorIndexChanged(index) { | ||
if (index != null) { | ||
this.setAttribute('has-color-index', ''); | ||
if (window.ShadyCSS && !window.ShadyCSS.nativeCss) { | ||
window.ShadyCSS.styleSubtree(this, { | ||
'--vaadin-avatar-border-color': `var(--user-color-${index})` | ||
}); | ||
} else { | ||
this.style.setProperty('--vaadin-avatar-border-color', `var(--user-color-${index})`); | ||
} | ||
} else { | ||
this.removeAttribute('has-color-index'); | ||
} | ||
} | ||
__imgOrAbbrOrNameChanged(img, abbr, name) { | ||
this.__updateVisibility(); | ||
if (img || | ||
(abbr && abbr !== this.__generatedAbbr)) { | ||
if (img || (abbr && abbr !== this.__generatedAbbr)) { | ||
if (abbr) { | ||
this.__setTitle(abbr); | ||
} | ||
return; | ||
@@ -204,2 +248,4 @@ } | ||
} | ||
this.__setTitle(name); | ||
} | ||
@@ -213,9 +259,5 @@ | ||
__nameChanged(name) { | ||
this.__setTitleFromName(name); | ||
} | ||
__setTitleFromName(name) { | ||
if (name) { | ||
this.setAttribute('title', name); | ||
__setTitle(title) { | ||
if (title) { | ||
this.setAttribute('title', title); | ||
} else { | ||
@@ -222,0 +264,0 @@ this.setAttribute('title', 'anonymous'); |
@@ -10,5 +10,26 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
<style> | ||
[part~="avatar"] { | ||
border: calc(var(--_avatar-group-offset) / 20) solid var(--lumo-base-color); | ||
[part="avatar"]:not(:first-child) { | ||
-webkit-mask-position: calc(50% - var(--lumo-size-m) + var(--vaadin-avatar-group-overlap)); | ||
mask-position: calc(50% - var(--lumo-size-m) + var(--vaadin-avatar-group-overlap)); | ||
} | ||
:host([theme~="xlarge"]) [part="avatar"]:not(:first-child) { | ||
-webkit-mask-position: calc(50% - var(--lumo-size-xl) + var(--vaadin-avatar-group-overlap)); | ||
mask-position: calc(50% - var(--lumo-size-xl) + var(--vaadin-avatar-group-overlap)); | ||
} | ||
:host([theme~="large"]) [part="avatar"]:not(:first-child) { | ||
-webkit-mask-position: calc(50% - var(--lumo-size-l) + var(--vaadin-avatar-group-overlap)); | ||
mask-position: calc(50% - var(--lumo-size-l) + var(--vaadin-avatar-group-overlap)); | ||
} | ||
:host([theme~="small"]) [part="avatar"]:not(:first-child) { | ||
-webkit-mask-position: calc(50% - var(--lumo-size-s) + var(--vaadin-avatar-group-overlap)); | ||
mask-position: calc(50% - var(--lumo-size-s) + var(--vaadin-avatar-group-overlap)); | ||
} | ||
:host([theme~="xsmall"]) [part="avatar"]:not(:first-child) { | ||
-webkit-mask-position: calc(50% - var(--lumo-size-xs) + var(--vaadin-avatar-group-overlap)); | ||
mask-position: calc(50% - var(--lumo-size-xs) + var(--vaadin-avatar-group-overlap)); | ||
} | ||
</style> | ||
@@ -15,0 +36,0 @@ </template> |
@@ -12,3 +12,2 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
:host { | ||
box-sizing: border-box; | ||
width: var(--lumo-size-m); | ||
@@ -26,5 +25,4 @@ height: var(--lumo-size-m); | ||
/* TODO: does not work with <img> */ | ||
:host([focus-ring]) { | ||
box-shadow: inset 0 0 0 2px var(--lumo-primary-color-50pct); | ||
border-color: var(--lumo-primary-color-50pct); | ||
} | ||
@@ -31,0 +29,0 @@ |
@@ -9,5 +9,3 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
:host { | ||
box-sizing: border-box; | ||
width: 2.25rem; | ||
height: 2.25rem; | ||
--vaadin-avatar-size: 2.25rem; | ||
color: var(--material-secondary-text-color); | ||
@@ -23,5 +21,4 @@ background-color: var(--material-secondary-background-color); | ||
/* TODO: does not work with <img> */ | ||
:host([focus-ring]) { | ||
box-shadow: inset 0 0 0 2px var(--material-primary-color); | ||
border-color: var(--material-primary-color); | ||
} | ||
@@ -28,0 +25,0 @@ |
43740
738