lion/packages/collapsible/README.md
Joren Broekema 874ff48339 feat(form-core): form-core types
Co-authored-by: Thijs Louisse <Thijs.Louisse@ing.com>
2020-09-02 09:02:47 +02:00

209 lines
7.3 KiB
Markdown

# 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.
```js script
import { html } from 'lit-html';
import './lion-collapsible.js';
import './demo/custom-collapsible.js';
import './demo/applyDemoCollapsibleStyles.js';
export default {
title: 'Others/Collapsible',
};
```
```js preview-story
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 `opened` or `toggle()` to render default open
- `invoker` slot can be custom template e.g. `lion-button` or native `button` with custom styling
- Observe the state with the help of `@opened-changed` event
- `show()` and `hide()` are helper methods to hide or show the content from outside
## How to use
### Installation
```bash
npm i --save @lion/collapsible
```
```js
import { LionCollapsible } from '@lion/collapsible';
// or
import '@lion/collapsible/lion-collapsible.js';
```
### Usage
```html
<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.
```js preview-story
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 content
- `show()`: show the extra content
- `hide()`: hide the extra content
```js preview-story
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
```js preview-story
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.
```js preview-story
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.
```js preview-story
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](https://github.com/ing-bank/lion/blob/master/packages/collapsible/demo/CustomCollapsible.js).
```js
_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 });
}
```