# Content >> Accordion >> Features ||20 ```js script import { LitElement, html } from '@mdjs/mdjs-preview'; import '@lion/accordion/define'; ``` ## Expanded You can set `expanded` to pre-expand a certain invoker. ```js preview-story export const expanded = () => html`

Lorem ipsum dolor sit, amet consectetur adipisicing elit.

Laboriosam sequi odit cumque, enim aut assumenda itaque quis voluptas est quos fugiat unde labore reiciendis saepe, iure, optio officiis obcaecati quibusdam.

`; ``` ## Slots Order The invoker and content slots are ordered by DOM order. ```js preview-story export const slotsOrder = () => html`

Lorem ipsum dolor sit, amet consectetur adipisicing elit.

Laboriosam sequi odit cumque, enim aut assumenda itaque quis voluptas est quos fugiat unde labore reiciendis saepe, iure, optio officiis obcaecati quibusdam.

`; ``` ## Multiline header A header can be multiline. ```js preview-story export const multilineHeader = () => html`

content 1

content 2

`; ``` ## Distribute New Elements Below, we demonstrate how you could dynamically add a new invoker + content. ```js preview-story export const distributeNewElement = () => { const tagName = 'demo-accordion-add-dynamically'; if (!customElements.get(tagName)) { customElements.define( tagName, class extends LitElement { static get properties() { return { __collection: { type: Array }, }; } render() { return html`

Append

content 1

content 2


Push

content 1

content 2

${this.__collection.map( item => html`

${item.content}

`, )}
`; } constructor() { super(); this.__collection = []; } __handleAppendClick() { const accordionElement = this.shadowRoot.querySelector('#appendAccordion'); const c = 2; const n = Math.floor(accordionElement.children.length / 2); for (let i = n + 1; i < n + c; i += 1) { const invoker = document.createElement('h4'); const button = document.createElement('button'); button.innerText = `header ${i}`; invoker.setAttribute('slot', 'invoker'); invoker.appendChild(button); const content = document.createElement('p'); content.setAttribute('slot', 'content'); content.innerText = `content ${i}`; accordionElement.append(invoker); accordionElement.append(content); } } __handlePushClick() { const accordionElement = this.shadowRoot.querySelector('#pushTabs'); const i = Math.floor(accordionElement.children.length / 2) + 1; this.__collection = [ ...this.__collection, { invoker: `header ${i}`, content: `content ${i}`, }, ]; } }, ); } return html` `; }; ``` One way is by creating the DOM elements and appending them as needed. Inside your `lion-accordion` extension, an example for appending nodes on a certain button click: ```js __handleAppendClick() { const accordionAmount = this.children.length / 2; const invoker = document.createElement('h4'); const button = document.createElement('button'); button.innerText = `header ${accordionAmount + 1}`; invoker.setAttribute('slot', 'invoker'); invoker.appendChild(button); const content = document.createElement('p'); content.setAttribute('slot', 'content'); content.innerText = `content ${accordionAmount + 1}`; this.append(invoker); this.append(content); } ``` 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 accordionAmount = this.children.length; myCollection = [ ...myCollection, { invoker: `header ${accordionAmount + 1}`, content: `content ${accordionAmount + 1}`, }, ]; renderMyCollection(); } ``` Make sure your template re-renders when myCollection is updated. ```html ${myCollection.map(item => html`

${item.content}

`)}
```