@bliss-design-system/alert
Version:
`<bliss-alert>` provides a messaging mechanism for alerting and informing.
127 lines (126 loc) • 3.97 kB
JavaScript
import { __decorate } from "tslib";
import { IconMixin } from '@bliss-design-system/shared';
import { ifDefined } from 'lit-html/directives/if-defined';
import { html, property, LitElement, } from 'lit-element';
import { styles } from './index.css.js';
/**
* @element bliss-alert
*
* @attr {small|medium} [size] - alert size
* @attr {default|neutral|positive|notice|warning|critical} [theme] - alert theme
* @attr {String} [heading] - text for the alert heading
* @attr {String} [icon] - which icon to display to accompany the alert message
* @attr {String} [close-text] - text for the close button aria-label
* @attr {Boolean} [dismissible=false] - whether or not to display close button inside the alert
*
* @slot - Default content slot
*/
export class BlissAlert extends IconMixin(LitElement) {
constructor() {
super(...arguments);
this.size = 'medium';
this.theme = 'default';
this.dismissible = false;
this.closeText = 'Close';
this.status = 'polite';
}
static get styles() {
return [styles];
}
close() {
var _a;
(_a = this.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this);
}
connectedCallback() {
super.connectedCallback();
this.setStatus();
this.checkHeading();
if (!this.icon) {
this.icon = 'info';
super.setIcon();
}
}
checkHeading() {
if (this.heading && this.size !== 'medium') {
console.warn('%c[Bliss Warn]:', 'font-weight: 600;', `The '${this.size}' alert size does not support a heading. If you'd like to use one, please set the size to 'medium'.`);
}
}
updated(changes) {
if (changes.has('icon')) {
super.setIcon();
}
if (changes.has('theme')) {
this.setStatus();
}
if (changes.has('heading') || changes.has('size')) {
this.checkHeading();
}
}
setStatus() {
if (this.theme === 'critical') {
this.status = 'assertive';
}
}
get alertContent() {
const label = this.heading && this.size === 'medium' ? 'bliss-alert-heading' : undefined;
const heading = html `<h3 part="heading" id="bliss-alert-heading">
${this.heading}
</h3>`;
const content = [html `<slot id="bliss-alert-content"></slot>`];
if (label) {
content.unshift(heading);
}
return html `<div
part="content"
aria-labelledby="${ifDefined(label)}"
aria-describedby="bliss-alert-content"
aria-live="${this.status}"
>
${content}
</div>`;
}
get renderAlert() {
const icon = html `
<bliss-icon part="icon" name="${this.icon}" aria-hidden="true"></bliss-icon>
${super.setSVGSymbol()}
`;
const closeButton = html `<bliss-button
part="close"
id="bliss-alert-close"
variant="ghost"
size="small"
icon="close-clean"
icon-only
transparent
@click=${this.close}
>
${this.closeText}
</bliss-button>`;
const template = [icon, this.alertContent];
if (this.dismissible) {
template.push(closeButton);
}
return html `<div part="alert">${template}</div>`;
}
render() {
return this.renderAlert;
}
}
__decorate([
property({ type: String })
], BlissAlert.prototype, "heading", void 0);
__decorate([
property({ type: String })
], BlissAlert.prototype, "size", void 0);
__decorate([
property({ type: String })
], BlissAlert.prototype, "theme", void 0);
__decorate([
property({ type: Boolean })
], BlissAlert.prototype, "dismissible", void 0);
__decorate([
property({ type: String, attribute: 'close-text' })
], BlissAlert.prototype, "closeText", void 0);
__decorate([
property({ type: String })
], BlissAlert.prototype, "status", void 0);