shoelace/src/components/avatar/avatar.ts

83 wiersze
2.3 KiB
TypeScript
Czysty Zwykły widok Historia

import { html, LitElement } from 'lit';
2021-05-27 21:00:43 +00:00
import { customElement, property, state } from 'lit/decorators.js';
2021-09-29 12:40:26 +00:00
import { classMap } from 'lit/directives/class-map.js';
2022-03-24 11:48:03 +00:00
import '~/components/icon/icon';
2021-07-10 00:45:44 +00:00
import styles from './avatar.styles';
2021-07-12 14:36:06 +00:00
2021-02-26 14:09:13 +00:00
/**
* @since 2.0
* @status stable
*
* @dependency sl-icon
*
2021-06-25 20:25:46 +00:00
* @slot icon - The default icon to use when no image or initials are present.
2021-02-26 14:09:13 +00:00
*
2022-03-09 20:54:18 +00:00
* @csspart base - The component's internal wrapper.
2021-06-25 20:25:46 +00:00
* @csspart icon - The container that wraps the avatar icon.
* @csspart initials - The container that wraps the avatar initials.
* @csspart image - The avatar image.
*
2021-06-25 20:25:46 +00:00
* @cssproperty --size - The size of the avatar.
2021-02-26 14:09:13 +00:00
*/
2021-03-18 13:04:23 +00:00
@customElement('sl-avatar')
2021-03-09 00:14:32 +00:00
export default class SlAvatar extends LitElement {
2021-07-10 00:45:44 +00:00
static styles = styles;
2021-02-26 14:09:13 +00:00
@state() private hasError = false;
2021-02-26 14:09:13 +00:00
/** The image source to use for the avatar. */
@property() image?: string;
2021-02-26 14:09:13 +00:00
2021-12-31 16:02:27 +00:00
/** A label to use to describe the avatar to assistive devices. */
@property() label = '';
2021-02-26 14:09:13 +00:00
/** Initials to use as a fallback when no image is available (1-2 characters max recommended). */
@property() initials?: string;
2021-02-26 14:09:13 +00:00
/** The shape of the avatar. */
2021-03-06 17:01:39 +00:00
@property({ reflect: true }) shape: 'circle' | 'square' | 'rounded' = 'circle';
2021-02-26 14:09:13 +00:00
render() {
return html`
<div
part="base"
class=${classMap({
avatar: true,
'avatar--circle': this.shape === 'circle',
'avatar--rounded': this.shape === 'rounded',
'avatar--square': this.shape === 'square'
})}
2021-11-12 22:40:26 +00:00
role="img"
2021-12-31 16:02:27 +00:00
aria-label=${this.label}
2021-02-26 14:09:13 +00:00
>
2022-01-19 14:37:07 +00:00
${this.initials
2021-02-26 14:09:13 +00:00
? html` <div part="initials" class="avatar__initials">${this.initials}</div> `
: html`
2021-11-12 22:40:26 +00:00
<div part="icon" class="avatar__icon" aria-hidden="true">
2021-02-26 14:09:13 +00:00
<slot name="icon">
<sl-icon name="person-fill" library="system"></sl-icon>
2021-02-26 14:09:13 +00:00
</slot>
</div>
`}
${typeof this.image === 'string' && !this.hasError
2021-02-26 14:09:13 +00:00
? html`
<img
part="image"
class="avatar__image"
src="${this.image}"
alt=""
@error="${() => (this.hasError = true)}"
/>
2021-02-26 14:09:13 +00:00
`
: ''}
</div>
`;
}
}
2021-03-12 14:09:08 +00:00
declare global {
interface HTMLElementTagNameMap {
'sl-avatar': SlAvatar;
}
}