# lea Tabs > This is not a real implementation! > > It is an example of how you can reuse the functionality of Lion to create your own Style System `lea-tabs` implements tabs view to allow users to quickly move between a small number of equally important views. ```js script import { html } from 'lit-html'; import { LitElement } from '@lion/core'; import '../lea-tabs.js'; import '../lea-tab.js'; import '../lea-tab-panel.js'; export default { title: 'Intro/Tabs Example', }; ``` ```js preview-story export const main = () => html` Info Info page with lots of information about us. Work Work page that showcases our work. `; ``` ## How to use ### Installation ```sh npm i --save @lion/tabs; ``` ### Usage ```js import '@lion/tabs/lea-tabs.js'; ``` ```html Info Info page with lots of information about us. Work Work page that showcases our work. ``` ## Examples ### Selected Index You can set the `selectedIndex` to select a certain tab. ```js preview-story export const selectedIndex = () => html` Info Info page with lots of information about us. Work Work page that showcases our work. `; ``` ### Slots Order The tab and panel slots are ordered by DOM order. This means you can switch the grouping in your `lea-tabs` from tab + panel to all tabs first or all panels first. ```js preview-story export const slotsOrder = () => html` Info Work Info page with lots of information about us. Work page that showcases our work. `; ``` ### Distribute New Elements Below, we demonstrate on how you could dynamically add new tab + panels. ```js preview-story export const distributeNewElements = () => { const tagName = 'lea-tabs-experimental'; if (!customElements.get(tagName)) { customElements.define( tagName, class extends LitElement { static get properties() { return { __collection: { type: Array }, }; } render() { return html`

Append

tab 1 panel 1 tab 2 panel 2

Push

tab 1 panel 1 tab 2 panel 2 ${this.__collection.map( item => html` ${item.button} ${item.panel} `, )} `; } constructor() { super(); this.__collection = []; } __handleAppendClick() { const tabsElement = this.shadowRoot.querySelector('#appendTabs'); const c = 2; const n = Math.floor(tabsElement.children.length / 2); for (let i = n + 1; i < n + c; i += 1) { const tab = document.createElement('lea-tab'); tab.setAttribute('slot', 'tab'); tab.innerText = `tab ${i}`; const panel = document.createElement('lea-tab-panel'); panel.setAttribute('slot', 'panel'); panel.innerText = `panel ${i}`; tabsElement.append(tab); tabsElement.append(panel); } } __handlePushClick() { const tabsElement = this.shadowRoot.querySelector('#pushTabs'); const i = Math.floor(tabsElement.children.length / 2) + 1; this.__collection = [ ...this.__collection, { button: `tab ${i}`, panel: `panel ${i}`, }, ]; } }, ); } return html` `; }; ``` One way is by creating the DOM elements and appending them as needed. Inside your `lea-tabs` extension, an example for appending nodes on a certain button click: ```js __handleAppendClick() { const tabsAmount = this.children.length / 2; const tab = document.createElement('lea-tab'); tab.setAttribute('slot', 'tab'); tab.innerText = `tab ${tabsAmount + 1}`; const panel = document.createElement('lea-tab-panel'); panel.setAttribute('slot', 'panel'); panel.innerText = `panel ${tabsAmount + 1}`; this.append(tab); this.append(panel); } ``` The other way is by adding data to a Lit property where you loop over this property in your template. You then need to ensure this causes a re-render. ```js __handlePushClick() { const tabsAmount = this.children.length; myCollection = [ ...myCollection, { button: `tab ${tabsAmount + 1}`, panel: `panel ${tabsAmount + 1}`, }, ]; renderMyCollection(); } ``` Make sure your template re-renders when myCollection is updated. ```html ${myCollection.map(item => html` ${item.button} ${item.panel} `)} ``` ## Rationale ### No separate active/focus state when using keyboard We will immediately switch content as all our content comes from light dom (e.g. no latency) See Note at > It is recommended that tabs activate automatically when they receive focus as long as their > associated tab panels are displayed without noticeable latency. This typically requires tab > panel content to be preloaded. ### Panels are not focusable Focusable elements should have a means to interact with them. Tab panels themselves do not offer any interactiveness. If there is a button or a form inside the tab panel then these elements get focused directly.