UNPKG

@limetech/lime-elements

Version:
167 lines (166 loc) 4.96 kB
import { h, Host, } from '@stencil/core'; import { dispatchResizeEvent } from '../../util/dispatch-resize-event'; /** * The `limel-tab-panel` component uses the `limel-tab-bar` component together * with custom slotted components and will display the content for the currently * active tab. Each slotted component must have an id equal to the id of the * corresponding tab it belongs to. These components should implement the * [TabPanelComponent](#/type/TabPanelComponent/) interface. * * The `limel-tab-panel` component will automatically set each tab configuration * on the corresponding slotted component as a property named `tab` so that the * component can take action upon that. Sometimes it might be desirable to not * load data or render anything until the tab is active. * * The slotted components can also emit the `changeTab` event to update anything * inside the actual tab, e.g. to change the icon, color or badge. * * @slot - Content to put inside the `limel-tab-panel`. Each slotted element * must have the `id` attribute equal to the id of the tab it belongs to. * @exampleComponent limel-example-tab-panel */ export class TabPanel { constructor() { this.slotElements = []; this.tabs = []; this.handleChangeTabs = this.handleChangeTabs.bind(this); this.setSlotElements = this.setSlotElements.bind(this); this.setTabStatus = this.setTabStatus.bind(this); } connectedCallback() { this.initialize(); } componentDidLoad() { this.initialize(); } initialize() { const slot = this.getSlot(); if (!slot) { return; } slot.addEventListener('slotchange', this.setSlotElements); this.setSlotElements(); // eslint-disable-next-line unicorn/no-array-for-each this.tabs.forEach(this.setTabStatus); } disconnectedCallback() { const slot = this.getSlot(); slot.removeEventListener('slotchange', this.setSlotElements); } tabsChanged() { this.hidePanels(); // eslint-disable-next-line unicorn/no-array-for-each this.tabs.forEach(this.setTabStatus); } render() { return (h(Host, { onChangeTab: this.handleChangeTabs }, h("div", { class: "tab-panel" }, h("limel-tab-bar", { tabs: this.tabs }), h("div", { class: "tab-content" }, h("slot", null))))); } setSlotElements() { const slot = this.getSlot(); this.hidePanels(); this.slotElements = Array.prototype.slice.call(slot.assignedElements()); // eslint-disable-next-line unicorn/no-array-for-each this.tabs.forEach(this.setTabStatus); } setTabStatus(tab) { const element = this.slotElements.find((e) => e.id === tab.id); if (!element) { return; } if (tab.active) { element.style.display = ''; } else { element.style.display = 'none'; } element['tab'] = tab; } handleChangeTabs(event) { this.tabs = this.tabs.map((tab) => { if (tab.id === event.detail.id) { return event.detail; } return tab; }); this.setTabStatus(event.detail); // Content inside the newly activated tab may need to redraw once // visible, so we use the resize event trick. /Ads setTimeout(dispatchResizeEvent); } getSlot() { return this.host.shadowRoot.querySelector('slot'); } hidePanels() { for (const element of this.slotElements) { element.style.display = 'none'; } } static get is() { return "limel-tab-panel"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["tab-panel.scss"] }; } static get styleUrls() { return { "$": ["tab-panel.css"] }; } static get properties() { return { "tabs": { "type": "unknown", "mutable": true, "complexType": { "original": "Tab[]", "resolved": "Tab[]", "references": { "Tab": { "location": "import", "path": "../tab-bar/tab.types" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "The tabs to display in the panel" }, "defaultValue": "[]" } }; } static get events() { return [{ "method": "changeTab", "name": "changeTab", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when a tab has been changed" }, "complexType": { "original": "Tab", "resolved": "Tab", "references": { "Tab": { "location": "import", "path": "../tab-bar/tab.types" } } } }]; } static get elementRef() { return "host"; } static get watchers() { return [{ "propName": "tabs", "methodName": "tabsChanged" }]; } } //# sourceMappingURL=tab-panel.js.map