| .. | ||
| demo | ||
| src | ||
| test | ||
| CHANGELOG.md | ||
| index.js | ||
| lion-collapsible.js | ||
| package.json | ||
| README.md | ||
Collapsible
lion-collapsible is a combination of a button (the invoker), a chunk of 'extra content', and an animation that is used to disclose the extra content. There are two slots available respectively; invoker to specify collapsible invoker and content for the extra content of the collapsible.
import { html } from 'lit-html';
import './lion-collapsible.js';
import './demo/custom-collapsible.js';
import './demo/applyDemoCollapsibleStyles.js';
export default {
title: 'Others/Collapsible',
};
export const main = () => html`
<lion-collapsible>
<button slot="invoker">More about cars</button>
<div slot="content">
Most definitions of cars say that they run primarily on roads, seat one to eight people, have
four tires, and mainly transport people rather than goods.
</div>
</lion-collapsible>
`;
Features
- Use
openedortoggle()to render default open invokerslot can be custom template e.g.lion-buttonor nativebuttonwith custom styling- Observe the state with the help of
@opened-changedevent show()andhide()are helper methods to hide or show the content from outside
How to use
Installation
npm i --save @lion/collapsible
import { LionCollapsible } from '@lion/collapsible';
// or
import '@lion/collapsible/lion-collapsible.js';
Usage
<lion-collapsible>
<button slot="invoker">Invoker Text</button>
<div slot="content">
Extra content
</div>
</lion-collapsible>
Examples
Default open
Add the opened attribute to keep the component default open.
export const defaultOpen = () => html`
<lion-collapsible opened>
<button slot="invoker">More about cars</button>
<div slot="content">
Most definitions of cars say that they run primarily on roads, seat one to eight people, have
four tires, and mainly transport people rather than goods.
</div>
</lion-collapsible>
`;
Methods
There are the following methods available to control the extra content for the collapsible.
toggle(): toggle the extra contentshow(): show the extra contenthide(): hide the extra content
export const methods = () => html`
<lion-collapsible id="car-collapsible">
<button slot="invoker">More about cars</button>
<div slot="content">
Most definitions of cars say that they run primarily on roads, seat one to eight people, have
four tires, and mainly transport people rather than goods.
</div>
</lion-collapsible>
<section style="margin-top:16px">
<button @click=${() => document.querySelector('#car-collapsible').toggle()}>
Toggle content
</button>
<button @click=${() => document.querySelector('#car-collapsible').show()}>
Show content
</button>
<button @click=${() => document.querySelector('#car-collapsible').hide()}>
Hide content
</button>
</section>
`;
Events
lion-collapsible fires an event on invoker click to notify the component's current state. It is useful for analytics purposes or to perform some actions while expanding and collapsing the component.
@opened-changed: triggers when collapsible either gets opened or closed
export const events = () => html`
<div class="demo-custom-collapsible-state-container">
<strong id="collapsible-state"></strong>
</div>
<lion-collapsible
@opened-changed=${e => {
const collapsibleState = document.getElementById('collapsible-state');
collapsibleState.innerText = `Opened: ${e.target.opened}`;
}}
>
<button slot="invoker">More about cars</button>
<div slot="content">
Most definitions of cars say that they run primarily on roads, seat one to eight people, have
four tires, and mainly transport people rather than goods.
</div>
</lion-collapsible>
`;
Custom Invoker Template
A custom template can be specified to the invoker slot. It can be any button or custom component which mimics the button behavior for better accessibility support. In the below example, lion-button and native button with styling is used as a collapsible invoker.
export const customInvokerTemplate = () => html`
<lion-collapsible>
<button class="demo-custom-collapsible-invoker" slot="invoker">
MORE ABOUT CARS
</button>
<div slot="content">
Most definitions of cars say that they run primarily on roads, seat one to eight people, have
four tires, and mainly transport people rather than goods.
</div>
</lion-collapsible>
<lion-collapsible style="margin-top:16px;">
<lion-button slot="invoker">More about cars</lion-button>
<div slot="content">
Most definitions of cars say that they run primarily on roads, seat one to eight people, have
four tires, and mainly transport people rather than goods.
</div>
</lion-collapsible>
`;
Extended collapsible with animation
LionCollapsible can easily be extended to add more features in the component, for example, animation.
export const customAnimation = () => html`
<div class="demo-custom-collapsible-container">
<div class="demo-custom-collapsible-body">
A motorcycle, often called a motorbike, bike, or cycle, is a two- or three-wheeled motor
vehicle.
</div>
<custom-collapsible>
<button class="demo-custom-collapsible-invoker" slot="invoker">
MORE ABOUT MOTORCYCLES
</button>
<div slot="content">
Motorcycle design varies greatly to suit a range of different purposes: long distance
travel, commuting, cruising, sport including racing, and off-road riding. Motorcycling is
riding a motorcycle and related social activity such as joining a motorcycle club and
attending motorcycle rallies.
</div>
</custom-collapsible>
</div>
<div class="demo-custom-collapsible-container">
<div class="demo-custom-collapsible-body">
A car (or automobile) is a wheeled motor vehicle used for transportation.
</div>
<custom-collapsible opened>
<button class="demo-custom-collapsible-invoker" slot="invoker">
MORE ABOUT CARS
</button>
<div slot="content">
Most definitions of cars say that they run primarily on roads, seat one to eight people,
have four tires, and mainly transport people rather than goods.
</div>
</custom-collapsible>
</div>
`;
Use _showAnimation and _hideAnimation methods to customize open and close behavior. Check the full example for the custom-collapsible here.
_showAnimation({ contentNode }) {
const expectedHeight = await this.__calculateHeight(contentNode);
contentNode.style.setProperty('opacity', '1');
contentNode.style.setProperty('padding', '12px 0');
contentNode.style.setProperty('max-height', '0px');
await new Promise(resolve => requestAnimationFrame(() => resolve()));
contentNode.style.setProperty('max-height', expectedHeight);
await this._waitForTransition({ contentNode });
}
_hideAnimation({ contentNode }) {
if (this._contentHeight === '0px') {
return;
}
['opacity', 'padding', 'max-height'].map(prop => contentNode.style.setProperty(prop, 0));
await this._waitForTransition({ contentNode });
}