import { classMap } from 'lit/directives/class-map.js'; import { html } from 'lit'; import { LocalizeController } from '../../utilities/localize.js'; import { property, query } from 'lit/decorators.js'; import { watch } from '../../internal/watch.js'; import styles from './tab.styles.js'; import WaIconButton from '../icon-button/icon-button.component.js'; import WebAwesomeElement from '../../internal/webawesome-element.js'; import type { CSSResultGroup } from 'lit'; let id = 0; /** * @summary Tabs are used inside [tab groups](/components/tab-group) to represent and activate [tab panels](/components/tab-panel). * @documentation https://shoelace.style/components/tab * @status stable * @since 2.0 * * @dependency wa-icon-button * * @slot - The tab's label. * * @event wa-close - Emitted when the tab is closable and the close button is activated. * * @csspart base - The component's base wrapper. * @csspart close-button - The close button, an ``. * @csspart close-button__base - The close button's exported `base` part. */ export default class WaTab extends WebAwesomeElement { static styles: CSSResultGroup = styles; static dependencies = { 'wa-icon-button': WaIconButton }; private readonly localize = new LocalizeController(this); private readonly attrId = ++id; private readonly componentId = `wa-tab-${this.attrId}`; @query('.tab') tab: HTMLElement; /** The name of the tab panel this tab is associated with. The panel must be located in the same tab group. */ @property({ reflect: true }) panel = ''; /** Draws the tab in an active state. */ @property({ type: Boolean, reflect: true }) active = false; /** Makes the tab closable and shows a close button. */ @property({ type: Boolean }) closable = false; /** Disables the tab and prevents selection. */ @property({ type: Boolean, reflect: true }) disabled = false; connectedCallback() { super.connectedCallback(); this.setAttribute('role', 'tab'); } private handleCloseClick(event: Event) { event.stopPropagation(); this.emit('wa-close'); } @watch('active') handleActiveChange() { this.setAttribute('aria-selected', this.active ? 'true' : 'false'); } @watch('disabled') handleDisabledChange() { this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false'); } /** Sets focus to the tab. */ focus(options?: FocusOptions) { this.tab.focus(options); } /** Removes focus from the tab. */ blur() { this.tab.blur(); } render() { // If the user didn't provide an ID, we'll set one so we can link tabs and tab panels with aria labels this.id = this.id.length > 0 ? this.id : this.componentId; return html`
${this.closable ? html` ` : ''}
`; } } declare global { interface HTMLElementTagNameMap { 'wa-tab': WaTab; } }