/** * Copyright Aquera Inc 2023 * * This source code is licensed under the BSD-3-Clause license found in the * LICENSE file in the root directory of this source tree. */ import { LitElement, html, CSSResultArray, TemplateResult, } from 'lit'; import { styles } from './nile-badge.css'; import '../nile-icon-button/nile-icon-button'; import { classMap } from 'lit/directives/class-map.js'; import { customElement, property } from 'lit/decorators.js'; import { HasSlotController } from '../internal/slot'; import NileElement, { setupA11yMetadata } from '../internal/nile-element'; import type { CSSResultGroup } from 'lit'; import { A11yProperty } from '../internal/accessibility/a11y.property.enum'; import { A11yRole } from '../internal/accessibility/a11y.role.enum'; import { Role } from '../internal/accessibility/role.enum'; import { A11yCustomValue } from '../internal/accessibility/a11y.custom-value.enum'; /** * Nile icon component. * * @tag nile-badge * */ /** * @summary badges are used as labels to organize things or to indicate a selection. * @status stable * * @dependency nile-icon-button * * @slot - The badge's content. * @slot prefix - Content placed before the badge's content, such as an icon, dot or avatar. * @slot suffix - Content placed after the badge's content, such as an icon, count or button. * * @csspart base - The component's base wrapper. * @csspart prefix - The container that wraps the prefix slot. * @csspart content - The badge's content. * @csspart suffix - The container that wraps the suffix slot. */ @customElement('nile-badge') export class NileBadge extends NileElement { static styles: CSSResultGroup = styles; private readonly hasSlotController = new HasSlotController(this, 'prefix', 'suffix'); connectedCallback(): void { super.connectedCallback(); setupA11yMetadata(this, { [Role.Role]: A11yRole.Text, [A11yProperty.AriaLabel]: this.getLabelText() || A11yCustomValue.Badge, }); } /** Text of the default slot only, so prefix and suffix content stays out of the label. */ private getLabelText(): string { return [...this.childNodes] .filter( node => node.nodeType === Node.TEXT_NODE || (node.nodeType === Node.ELEMENT_NODE && !(node as Element).hasAttribute('slot')) ) .map(node => node.textContent ?? '') .join('') .trim(); } /** The badge's theme variant. */ @property({ reflect: true }) variant: | 'primary' | 'success' | 'normal' | 'warning' | 'error' | 'info' | 'gray' | 'brand' | 'blue-light' | 'blue' | 'indigo' | 'purple' | 'pink' | 'orange' | 'blue-gray' | 'gray-blue' = 'normal'; /** Draws a pill-style badge with rounded edges. */ @property({ type: Boolean, reflect: true }) rounded = false; // For setting pill type @property({ reflect: true }) pilltype: | 'pill-color' | 'pill-outline' | 'badge-color'='badge-color'; /** The badge's size. `md` keeps the existing default dimensions. */ @property({ reflect: true }) size: 'sm' | 'md' | 'lg' = 'md'; render() { const hasPrefix = this.hasSlotController.test('prefix'); const hasSuffix = this.hasSlotController.test('suffix'); return html` `; } } export default NileBadge; declare global { interface HTMLElementTagNameMap { 'nile-badge': NileBadge; } }