shoelace/src/components/tab/tab.ts

100 wiersze
2.6 KiB
TypeScript
Czysty Zwykły widok Historia

import { LitElement, html, unsafeCSS } from 'lit';
2021-05-27 21:00:43 +00:00
import { customElement, property, query } from 'lit/decorators.js';
2021-03-06 17:01:39 +00:00
import { classMap } from 'lit-html/directives/class-map';
import { emit } from '../../internal/event';
2021-02-26 14:09:13 +00:00
import styles from 'sass:./tab.scss';
let id = 0;
/**
* @since 2.0
* @status stable
*
* @dependency sl-icon-button
*
* @slot default The tab's label.
2021-02-26 14:09:13 +00:00
*
* @event sl-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, which is the icon button's base wrapper.
*
* @cssproperty --focus-ring The focus ring's box shadow.
2021-02-26 14:09:13 +00:00
*/
2021-03-18 13:04:23 +00:00
@customElement('sl-tab')
2021-03-09 00:14:32 +00:00
export default class SlTab extends LitElement {
2021-03-06 17:01:39 +00:00
static styles = unsafeCSS(styles);
@query('.tab') tab: HTMLElement;
2021-02-26 14:09:13 +00:00
private componentId = `tab-${++id}`;
/** The name of the tab panel the tab will control. The panel must be located in the same tab group. */
2021-03-06 17:01:39 +00:00
@property() panel = '';
2021-02-26 14:09:13 +00:00
/** Draws the tab in an active state. */
2021-03-06 17:01:39 +00:00
@property({ type: Boolean, reflect: true }) active = false;
2021-02-26 14:09:13 +00:00
/** Makes the tab closable and shows a close icon. */
2021-03-06 20:34:33 +00:00
@property({ type: Boolean }) closable = false;
2021-02-26 14:09:13 +00:00
/** Draws the tab in a disabled state. */
2021-03-06 17:01:39 +00:00
@property({ type: Boolean, reflect: true }) disabled = false;
2021-02-26 14:09:13 +00:00
/** Sets focus to the tab. */
focus(options?: FocusOptions) {
2021-02-26 14:09:13 +00:00
this.tab.focus(options);
}
/** Removes focus from the tab. */
blur() {
2021-02-26 14:09:13 +00:00
this.tab.blur();
}
handleCloseClick() {
emit(this, 'sl-close');
2021-02-26 14:09:13 +00:00
}
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 || this.componentId;
return html`
<div
part="base"
class=${classMap({
tab: true,
'tab--active': this.active,
'tab--closable': this.closable,
'tab--disabled': this.disabled
})}
role="tab"
aria-disabled=${this.disabled ? 'true' : 'false'}
aria-selected=${this.active ? 'true' : 'false'}
tabindex=${this.disabled || !this.active ? '-1' : '0'}
>
2021-03-06 17:01:39 +00:00
<slot></slot>
2021-02-26 14:09:13 +00:00
${this.closable
? html`
<sl-icon-button
name="x"
library="system"
2021-02-26 14:09:13 +00:00
exportparts="base:close-button"
class="tab__close-button"
2021-03-06 17:01:39 +00:00
@click=${this.handleCloseClick}
2021-02-26 14:09:13 +00:00
tabindex="-1"
aria-hidden="true"
2021-03-06 17:01:39 +00:00
></sl-icon-button>
2021-02-26 14:09:13 +00:00
`
: ''}
</div>
`;
}
}
2021-03-12 14:09:08 +00:00
declare global {
interface HTMLElementTagNameMap {
'sl-tab': SlTab;
}
}