fix: improve docs and examples for accordion & switch
This commit is contained in:
parent
5e7e43d221
commit
ae14f99875
13 changed files with 529 additions and 336 deletions
6
.changeset/weak-cats-pull.md
Normal file
6
.changeset/weak-cats-pull.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'@lion/accordion': patch
|
||||
'@lion/switch': patch
|
||||
---
|
||||
|
||||
Improve documentation and examples
|
||||
|
|
@ -7,5 +7,6 @@
|
|||
"first-line-h1": false,
|
||||
"no-trailing-punctuation": {
|
||||
"punctuation": ".,;。,;:!"
|
||||
}
|
||||
},
|
||||
"ol-prefix": false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,214 +0,0 @@
|
|||
# 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`
|
||||
<lion-accordion .expanded=${[1]}>
|
||||
<h3 slot="invoker">
|
||||
<button>Lorem</button>
|
||||
</h3>
|
||||
<p slot="content">Lorem ipsum dolor sit, amet consectetur adipisicing elit.</p>
|
||||
<h3 slot="invoker">
|
||||
<button>Laboriosam</button>
|
||||
</h3>
|
||||
<p slot="content">
|
||||
Laboriosam sequi odit cumque, enim aut assumenda itaque quis voluptas est quos fugiat unde
|
||||
labore reiciendis saepe, iure, optio officiis obcaecati quibusdam.
|
||||
</p>
|
||||
</lion-accordion>
|
||||
`;
|
||||
```
|
||||
|
||||
## Slots Order
|
||||
|
||||
The invoker and content slots are ordered by DOM order.
|
||||
|
||||
```js preview-story
|
||||
export const slotsOrder = () => html`
|
||||
<lion-accordion>
|
||||
<h3 slot="invoker">
|
||||
<button>Lorem</button>
|
||||
</h3>
|
||||
<p slot="content">Lorem ipsum dolor sit, amet consectetur adipisicing elit.</p>
|
||||
<h3 slot="invoker">
|
||||
<button>Laboriosam</button>
|
||||
</h3>
|
||||
<p slot="content">
|
||||
Laboriosam sequi odit cumque, enim aut assumenda itaque quis voluptas est quos fugiat unde
|
||||
labore reiciendis saepe, iure, optio officiis obcaecati quibusdam.
|
||||
</p>
|
||||
</lion-accordion>
|
||||
`;
|
||||
```
|
||||
|
||||
## Multiline header
|
||||
|
||||
A header can be multiline.
|
||||
|
||||
```js preview-story
|
||||
export const multilineHeader = () => html`
|
||||
<lion-accordion>
|
||||
<h3 slot="invoker">
|
||||
<button>
|
||||
header 1 with
|
||||
<br />
|
||||
multiple lines
|
||||
</button>
|
||||
</h3>
|
||||
<p slot="content">content 1</p>
|
||||
<h3 slot="invoker">
|
||||
<button>header 2</button>
|
||||
</h3>
|
||||
<p slot="content">content 2</p>
|
||||
</lion-accordion>
|
||||
`;
|
||||
```
|
||||
|
||||
## 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`
|
||||
<h3>Append</h3>
|
||||
<lion-accordion id="appendAccordion">
|
||||
<h4 slot="invoker">
|
||||
<button>header 1</button>
|
||||
</h4>
|
||||
<p slot="content">content 1</p>
|
||||
<h4 slot="invoker">
|
||||
<button>header 2</button>
|
||||
</h4>
|
||||
<p slot="content">content 2</p>
|
||||
</lion-accordion>
|
||||
<button @click="${this.__handleAppendClick}">Append</button>
|
||||
<hr />
|
||||
<h3>Push</h3>
|
||||
<lion-accordion id="pushTabs">
|
||||
<h4 slot="invoker">
|
||||
<button>header 1</button>
|
||||
</h4>
|
||||
<p slot="content">content 1</p>
|
||||
<h4 slot="invoker">
|
||||
<button>header 2</button>
|
||||
</h4>
|
||||
<p slot="content">content 2</p>
|
||||
${this.__collection.map(
|
||||
item => html`
|
||||
<h4 slot="invoker"><button>${item.invoker}</button></h4>
|
||||
<p slot="content">${item.content}</p>
|
||||
`,
|
||||
)}
|
||||
</lion-accordion>
|
||||
<button @click="${this.__handlePushClick}">Push</button>
|
||||
`;
|
||||
}
|
||||
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` <demo-accordion-add-dynamically></demo-accordion-add-dynamically> `;
|
||||
};
|
||||
```
|
||||
|
||||
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
|
||||
<lion-accordion id="pushAccordion">
|
||||
${myCollection.map(item => html`
|
||||
<h4 slot="invoker">
|
||||
<button>${item.invoker}</button>
|
||||
</h4>
|
||||
<p slot="content">${item.content}</p>
|
||||
`)}
|
||||
</lion-accordion>
|
||||
```
|
||||
|
|
@ -1,52 +1,127 @@
|
|||
# Content >> Accordion >> Overview ||10
|
||||
|
||||
A web component that can be used to toggle the display of sections of content.
|
||||
Its purpose is to reduce the need to scroll when presenting multiple sections of content on a single page. Accordions often allow users to get the big picture before focusing on details.
|
||||
<p class="lion-paragraph--emphasis">An accordion is a vertically stacked set of interactive headings that each contain a title representing a section of content. It allows users to toggle the display of sections of content.</p>
|
||||
|
||||
```js script
|
||||
import { html } from '@mdjs/mdjs-preview';
|
||||
import '@lion/accordion/define';
|
||||
import { html as previewHtml } from '@mdjs/mdjs-preview';
|
||||
```
|
||||
|
||||
```js preview-story
|
||||
export const main = () => html`
|
||||
import { html, LitElement, ScopedElementsMixin } from '@lion/core';
|
||||
import { LionAccordion } from '@lion/accordion';
|
||||
|
||||
class MyComponent extends ScopedElementsMixin(LitElement) {
|
||||
static get scopedElements() {
|
||||
return { 'lion-accordion': LionAccordion };
|
||||
}
|
||||
render() {
|
||||
return html`
|
||||
<lion-accordion>
|
||||
<h3 slot="invoker">
|
||||
<button>Lorem</button>
|
||||
<button>Sensory Factors</button>
|
||||
</h3>
|
||||
<p slot="content">Lorem ipsum dolor sit, amet consectetur adipisicing elit.</p>
|
||||
<h3 slot="invoker">
|
||||
<button>Laboriosam</button>
|
||||
</h3>
|
||||
<p slot="content">
|
||||
Laboriosam sequi odit cumque, enim aut assumenda itaque quis voluptas est quos fugiat unde
|
||||
labore reiciendis saepe, iure, optio officiis obcaecati quibusdam.
|
||||
<div slot="content">
|
||||
<p>
|
||||
The taste of oranges is determined mainly by the relative ratios of sugars and acids,
|
||||
whereas orange aroma derives from volatile organic compounds, including alcohols,
|
||||
aldehydes, ketones, terpenes, and esters. Bitter limonoid compounds, such as limonin,
|
||||
decrease gradually during development, whereas volatile aroma compounds tend to peak in
|
||||
mid– to late–season development. Taste quality tends to improve later in harvests when
|
||||
there is a higher sugar/acid ratio with less bitterness. As a citrus fruit, the orange
|
||||
is acidic, with pH levels ranging from 2.9 to 4.0.
|
||||
</p>
|
||||
<p>
|
||||
Sensory qualities vary according to genetic background, environmental conditions during
|
||||
development, ripeness at harvest, postharvest conditions, and storage duration.
|
||||
</p>
|
||||
</div>
|
||||
<h3 slot="invoker">
|
||||
<button>Nutritional value</button>
|
||||
</h3>
|
||||
<div slot="content">
|
||||
Orange flesh is 87% water, 12% carbohydrates, 1% protein, and contains negligible fat
|
||||
(table). In a 100 gram reference amount, orange flesh provides 47 calories, and is a rich
|
||||
source of vitamin C, providing 64% of the Daily Value. No other micronutrients are present
|
||||
in significant amounts (table).
|
||||
</div>
|
||||
</lion-accordion>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('my-component', MyComponent);
|
||||
|
||||
export const overview = () => previewHtml`<my-component></my-component>`;
|
||||
```
|
||||
|
||||
## When to use
|
||||
|
||||
- Accordions are commonly used to reduce the need to scroll when presenting multiple sections of content on a single page
|
||||
- Longer pages can benefit users. Accordions shorten pages and reduce scrolling, but they increase the interaction cost by requiring people to decide on topic headings.
|
||||
- Accordions conserve space on mobile but they can also cause disorientation and too much scrolling.
|
||||
- Accordions should be avoided when your audience needs most or all of the content on the page to answer their question. Better to show all page content at once when the use case supports it.
|
||||
- Accordions are more suitable when people need only a few key pieces of content on a single page. By hiding most of the content, users can spend their time more efficiently focused on the few topics that matter.
|
||||
|
||||
## Features
|
||||
|
||||
- content gets provided by users (slotted in)
|
||||
- handles accessibility
|
||||
- support navigation via keyboard
|
||||
- Content gets provided by users (slotted in)
|
||||
- Handles accessibility
|
||||
- Support navigation via keyboard
|
||||
|
||||
## Installation
|
||||
## How to use
|
||||
|
||||
### Code
|
||||
|
||||
1. Install
|
||||
|
||||
```bash
|
||||
npm i --save @lion/accordion
|
||||
```
|
||||
|
||||
2. Use scoped registry
|
||||
|
||||
```js
|
||||
import { html, LitElement, ScopedElementsMixin } from '@lion/core';
|
||||
import { LionAccordion } from '@lion/accordion';
|
||||
// or
|
||||
import '@lion/accordion/define';
|
||||
|
||||
class MyComponent extends ScopedElementsMixin(LitElement) {
|
||||
static get scopedElements() {
|
||||
return { 'lion-accordion': LionAccordion };
|
||||
}
|
||||
render() {
|
||||
return html`
|
||||
<lion-accordion>
|
||||
<h3 slot="invoker">
|
||||
<button>Nutritional value</button>
|
||||
</h3>
|
||||
<p slot="content">
|
||||
Orange flesh is 87% water, 12% carbohydrates, 1% protein, and contains negligible fat
|
||||
(table). In a 100 gram reference amount, orange flesh provides 47 calories, and is a
|
||||
rich source of vitamin C, providing 64% of the Daily Value. No other micronutrients are
|
||||
present in significant amounts (table).
|
||||
</p>
|
||||
</lion-accordion>
|
||||
`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Rationale
|
||||
3. Use html
|
||||
|
||||
### Contents are not focusable
|
||||
```html
|
||||
<script type="module">
|
||||
import '@lion/accordion/define';
|
||||
</script>
|
||||
|
||||
Focusable elements should be interactive. Contents themselves do not offer any interactivity.
|
||||
If there is a button or a form inside the tab panel then these elements get focused directly.
|
||||
<lion-accordion>
|
||||
<h3 slot="invoker">
|
||||
<button>Nutritional value</button>
|
||||
</h3>
|
||||
<p slot="content">
|
||||
Orange flesh is 87% water, 12% carbohydrates, 1% protein, and contains negligible fat
|
||||
(table). In a 100 gram reference amount, orange flesh provides 47 calories, and is a rich
|
||||
source of vitamin C, providing 64% of the Daily Value. No other micronutrients are present in
|
||||
significant amounts (table).
|
||||
</p>
|
||||
</lion-accordion>
|
||||
```
|
||||
|
|
|
|||
47
docs/components/content/accordion/reference.md
Normal file
47
docs/components/content/accordion/reference.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Content >> Accordion >> Reference ||30
|
||||
|
||||
<p class="lion-paragraph--emphasis">Everything you need to re-use the accordion.</p>
|
||||
|
||||
## Requirements
|
||||
|
||||
This component fulfils the following requirements:
|
||||
|
||||
1. An Accordion lets you toggle the visibility of content for a specific section
|
||||
2. An Accordion contains a visual indicator/icon as an affordance to toggle the visibility of the content
|
||||
3. Every section consists of a section title (always visible) and section content (visible when expanded)
|
||||
4. The individual sections (title + content) are clearly grouped
|
||||
5. Multiple sections can be expanded at the same time
|
||||
6. The section heading (title + visual indicator) is used as the interaction trigger
|
||||
7. An Accordion does not reposition the page when content drops out of the viewport when expanding a section (no auto scrolling)
|
||||
|
||||
## Rationale
|
||||
|
||||
### Contents are not focusable
|
||||
|
||||
Focusable elements should be interactive. Contents themselves do not offer any interactivity.
|
||||
If there is a button or a form inside the tab panel then these elements get focused directly.
|
||||
|
||||
## Keyboard interactions
|
||||
|
||||
| <kbd>Key</kbd> | Action |
|
||||
| :--------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <kbd>Enter or Spacebar</kbd> | When focus is on the accordion header for a collapsed panel, expands the associated panel. When focus is on the accordion header for an expanded panel, collapses the panel if the implementation supports collapsing |
|
||||
| <kbd>Tab</kbd> | Moves focus to the next focusable element; all focusable elements in the accordion are included in the page Tab sequence. |
|
||||
| <kbd>Shift+Tab</kbd> | Moves focus to the previous focusable element; all focusable elements in the accordion are included in the page Tab sequence. |
|
||||
| <kbd>Down arrow </kbd> | If focus is on an accordion header, moves focus to the next accordion header. If focus is on the last accordion header, either does nothing or moves focus to the first accordion header. |
|
||||
| <kbd>Up arrow</kbd> | If focus is on an accordion header, moves focus to the previous accordion header. If focus is on the first accordion header, either does nothing or moves focus to the last accordion header. |
|
||||
| <kbd>Home</kbd> | When focus is on an accordion header, moves focus to the first accordion header. |
|
||||
| <kbd>End</kbd> | When focus is on an accordion header, moves focus to the last accordion header. |
|
||||
|
||||
## WAI-ARIA roles
|
||||
|
||||
- The title of each accordion header is contained in an element with role button.
|
||||
- Each accordion header button is wrapped in an element with role heading that has a value set for aria-level that is appropriate for the information architecture of the page.
|
||||
- If the native host language has an element with an implicit heading and aria-level, such as an HTML heading tag, a native host language element may be used.
|
||||
- The button element is the only element inside the heading element. That is, if there are other visually persistent elements, they are not included inside the heading element.
|
||||
- If the accordion panel associated with an accordion header is visible, the header button element has aria-expanded set to true. If the panel is not visible, aria-expanded is set to false.
|
||||
- The accordion header button element has aria-controls set to the ID element containing the accordion panel content.
|
||||
- If the accordion panel associated with an accordion header is visible, and if the accordion does not permit the panel to be collapsed, the header button element has aria-disabled set to true.
|
||||
- Optionally, each element that serves as a container for panel content has role region and aria-labelledby with a value that refers to the button that controls display of the panel.
|
||||
- Avoid using the region role in circumstances that create landmark region proliferation, e.g. in an accordion that contains more than approximately 6 panels that can be expanded at the same time.
|
||||
- Role region is especially helpful to the perception of structure by screen reader users when panels contain heading elements or a nested accordion.
|
||||
252
docs/components/content/accordion/use-cases.md
Normal file
252
docs/components/content/accordion/use-cases.md
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
# Content >> Accordion >> Use Cases ||20
|
||||
|
||||
```js script
|
||||
import { html as previewHtml } from '@mdjs/mdjs-preview';
|
||||
|
||||
import '@lion/accordion/define';
|
||||
```
|
||||
|
||||
## Default Accordion collapsed
|
||||
|
||||
All accordion panels are collapsed by default.
|
||||
|
||||
```html preview-story
|
||||
<lion-accordion>
|
||||
<h3 slot="invoker">
|
||||
<button>Sensory Factors</button>
|
||||
</h3>
|
||||
<div slot="content" class="lion-paragraph-container">
|
||||
<p>
|
||||
The taste of oranges is determined mainly by the relative ratios of sugars and acids, whereas
|
||||
orange aroma derives from volatile organic compounds, including alcohols, aldehydes, ketones,
|
||||
terpenes, and esters. Bitter limonoid compounds, such as limonin, decrease gradually during
|
||||
development, whereas volatile aroma compounds tend to peak in mid– to late–season development.
|
||||
Taste quality tends to improve later in harvests when there is a higher sugar/acid ratio with
|
||||
less bitterness. As a citrus fruit, the orange is acidic, with pH levels ranging from 2.9 to
|
||||
4.0.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sensory qualities vary according to genetic background, environmental conditions during
|
||||
development, ripeness at harvest, postharvest conditions, and storage duration.
|
||||
</p>
|
||||
</div>
|
||||
<h3 slot="invoker">
|
||||
<button>Nutritional value</button>
|
||||
</h3>
|
||||
<div slot="content">
|
||||
Orange flesh is 87% water, 12% carbohydrates, 1% protein, and contains negligible fat (table).
|
||||
In a 100 gram reference amount, orange flesh provides 47 calories, and is a rich source of
|
||||
vitamin C, providing 64% of the Daily Value. No other micronutrients are present in significant
|
||||
amounts (table).
|
||||
</div>
|
||||
</lion-accordion>
|
||||
```
|
||||
|
||||
## Expanded
|
||||
|
||||
Multiple accordion panels can be expanded at the same time. When content drops out of the viewport when expanding an accordion panel, the accordion does not reposition the page (no autoscrolling).
|
||||
|
||||
```html preview-story
|
||||
<lion-accordion expanded="[1]">
|
||||
<h3 slot="invoker">
|
||||
<button>Sensory Factors</button>
|
||||
</h3>
|
||||
<div slot="content" class="lion-paragraph-container">
|
||||
<p>
|
||||
The taste of oranges is determined mainly by the relative ratios of sugars and acids, whereas
|
||||
orange aroma derives from volatile organic compounds, including alcohols, aldehydes, ketones,
|
||||
terpenes, and esters. Bitter limonoid compounds, such as limonin, decrease gradually during
|
||||
development, whereas volatile aroma compounds tend to peak in mid– to late–season development.
|
||||
Taste quality tends to improve later in harvests when there is a higher sugar/acid ratio with
|
||||
less bitterness. As a citrus fruit, the orange is acidic, with pH levels ranging from 2.9 to
|
||||
4.0.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sensory qualities vary according to genetic background, environmental conditions during
|
||||
development, ripeness at harvest, postharvest conditions, and storage duration.
|
||||
</p>
|
||||
</div>
|
||||
<h3 slot="invoker">
|
||||
<button>Nutritional value</button>
|
||||
</h3>
|
||||
<div slot="content">
|
||||
Orange flesh is 87% water, 12% carbohydrates, 1% protein, and contains negligible fat (table).
|
||||
In a 100 gram reference amount, orange flesh provides 47 calories, and is a rich source of
|
||||
vitamin C, providing 64% of the Daily Value. No other micronutrients are present in significant
|
||||
amounts (table).
|
||||
</div>
|
||||
</lion-accordion>
|
||||
```
|
||||
|
||||
## Slots Order
|
||||
|
||||
The invoker and content slots are ordered by DOM order. This means you can put all invoker nodes at the top followed by all container nodes and it will still retain the correct order.
|
||||
|
||||
```html preview-story
|
||||
<lion-accordion>
|
||||
<h3 slot="invoker">
|
||||
<button>Sensory Factors</button>
|
||||
</h3>
|
||||
<h3 slot="invoker">
|
||||
<button>Nutritional value</button>
|
||||
</h3>
|
||||
<div slot="content" class="lion-paragraph-container">
|
||||
<p>
|
||||
The taste of oranges is determined mainly by the relative ratios of sugars and acids, whereas
|
||||
orange aroma derives from volatile organic compounds, including alcohols, aldehydes, ketones,
|
||||
terpenes, and esters. Bitter limonoid compounds, such as limonin, decrease gradually during
|
||||
development, whereas volatile aroma compounds tend to peak in mid– to late–season development.
|
||||
Taste quality tends to improve later in harvests when there is a higher sugar/acid ratio with
|
||||
less bitterness. As a citrus fruit, the orange is acidic, with pH levels ranging from 2.9 to
|
||||
4.0.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sensory qualities vary according to genetic background, environmental conditions during
|
||||
development, ripeness at harvest, postharvest conditions, and storage duration.
|
||||
</p>
|
||||
</div>
|
||||
<div slot="content">
|
||||
Orange flesh is 87% water, 12% carbohydrates, 1% protein, and contains negligible fat (table).
|
||||
In a 100 gram reference amount, orange flesh provides 47 calories, and is a rich source of
|
||||
vitamin C, providing 64% of the Daily Value. No other micronutrients are present in significant
|
||||
amounts (table).
|
||||
</div>
|
||||
</lion-accordion>
|
||||
```
|
||||
|
||||
## Multiline header
|
||||
|
||||
A header can be multiline.
|
||||
|
||||
```html preview-story
|
||||
<lion-accordion>
|
||||
<h3 slot="invoker">
|
||||
<button>
|
||||
Sensory Factors <br />
|
||||
<small>or the experience of taste</small>
|
||||
</button>
|
||||
</h3>
|
||||
<div slot="content" class="lion-paragraph-container">
|
||||
<p>
|
||||
The taste of oranges is determined mainly by the relative ratios of sugars and acids, whereas
|
||||
orange aroma derives from volatile organic compounds, including alcohols, aldehydes, ketones,
|
||||
terpenes, and esters. Bitter limonoid compounds, such as limonin, decrease gradually during
|
||||
development, whereas volatile aroma compounds tend to peak in mid– to late–season development.
|
||||
Taste quality tends to improve later in harvests when there is a higher sugar/acid ratio with
|
||||
less bitterness. As a citrus fruit, the orange is acidic, with pH levels ranging from 2.9 to
|
||||
4.0.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sensory qualities vary according to genetic background, environmental conditions during
|
||||
development, ripeness at harvest, postharvest conditions, and storage duration.
|
||||
</p>
|
||||
</div>
|
||||
<h3 slot="invoker">
|
||||
<button>
|
||||
Nutritional value
|
||||
<small>or the raw data</small>
|
||||
</button>
|
||||
</h3>
|
||||
<div slot="content">
|
||||
Orange flesh is 87% water, 12% carbohydrates, 1% protein, and contains negligible fat (table).
|
||||
In a 100 gram reference amount, orange flesh provides 47 calories, and is a rich source of
|
||||
vitamin C, providing 64% of the Daily Value. No other micronutrients are present in significant
|
||||
amounts (table).
|
||||
</div>
|
||||
</lion-accordion>
|
||||
```
|
||||
|
||||
## Distribute New Elements
|
||||
|
||||
Below, we demonstrate how you could dynamically add a new invoker + content.
|
||||
|
||||
One way is by creating the DOM elements and appending them as needed. For how this work feel tree to check out the `__handleAppendClick` function.
|
||||
Another way is by adding data to the Lit property that you loop over in your template. See `__handlePushClick` for an example.
|
||||
|
||||
```js preview-story
|
||||
import { html, LitElement } from '@lion/core';
|
||||
|
||||
export const distributeNewElement = () => {
|
||||
class DemoDistribute extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
__collection: { type: Array },
|
||||
};
|
||||
}
|
||||
render() {
|
||||
return html`
|
||||
<h3>Append</h3>
|
||||
<lion-accordion id="appendAccordion">
|
||||
<h4 slot="invoker">
|
||||
<button>header 1</button>
|
||||
</h4>
|
||||
<p slot="content">content 1</p>
|
||||
<h4 slot="invoker">
|
||||
<button>header 2</button>
|
||||
</h4>
|
||||
<p slot="content">content 2</p>
|
||||
</lion-accordion>
|
||||
<button @click="${this.__handleAppendClick}">Append dom elements</button>
|
||||
<hr />
|
||||
<h3>Push</h3>
|
||||
<lion-accordion id="pushTabs">
|
||||
<h4 slot="invoker">
|
||||
<button>header 1</button>
|
||||
</h4>
|
||||
<p slot="content">content 1</p>
|
||||
<h4 slot="invoker">
|
||||
<button>header 2</button>
|
||||
</h4>
|
||||
<p slot="content">content 2</p>
|
||||
${this.__collection.map(
|
||||
item => html`
|
||||
<h4 slot="invoker"><button>${item.invoker}</button></h4>
|
||||
<p slot="content">${item.content}</p>
|
||||
`,
|
||||
)}
|
||||
</lion-accordion>
|
||||
<button @click="${this.__handlePushClick}">Push to tabs collection</button>
|
||||
`;
|
||||
}
|
||||
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}`,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
customElements.define('demo-distribute', DemoDistribute);
|
||||
|
||||
return previewHtml`<demo-distribute></demo-distribute>`;
|
||||
};
|
||||
```
|
||||
|
|
@ -1,14 +1,27 @@
|
|||
# Interaction >> Switch >> Overview ||10
|
||||
|
||||
<p class="paragraph--emphasis">The Switch is used to toggle a property or feature on or off.</p>
|
||||
<p class="lion-paragraph--emphasis">The Switch is used to toggle a property or feature on or off.</p>
|
||||
|
||||
```js script
|
||||
import { html } from '@mdjs/mdjs-preview';
|
||||
import { html as previewHtml } from '@mdjs/mdjs-preview';
|
||||
import '@lion/switch/define-switch';
|
||||
```
|
||||
|
||||
```js preview-story
|
||||
export const main = () => html`<lion-switch label="Label" help-text="Help text"></lion-switch>`;
|
||||
import { html, LitElement, ScopedElementsMixin } from '@lion/core';
|
||||
import { LionSwitch } from '@lion/switch';
|
||||
|
||||
class MyComponent extends ScopedElementsMixin(LitElement) {
|
||||
static get scopedElements() {
|
||||
return { 'lion-switch': LionSwitch };
|
||||
}
|
||||
render() {
|
||||
return html`<lion-switch label="Label" help-text="Help text"></lion-switch>`;
|
||||
}
|
||||
}
|
||||
customElements.define('my-component', MyComponent);
|
||||
|
||||
export const main = () => previewHtml`<my-component></my-component>`;
|
||||
```
|
||||
|
||||
## When to use
|
||||
|
|
@ -25,14 +38,36 @@ export const main = () => html`<lion-switch label="Label" help-text="Help text">
|
|||
|
||||
## How to use
|
||||
|
||||
### Installation
|
||||
### Code
|
||||
|
||||
1. Install
|
||||
|
||||
```bash
|
||||
npm i --save @lion/switch
|
||||
```
|
||||
|
||||
2. Use scoped registry
|
||||
|
||||
```js
|
||||
import { html, LitElement, ScopedElementsMixin } from '@lion/core';
|
||||
import { LionSwitch } from '@lion/switch';
|
||||
// or
|
||||
import '@lion/switch/define-switch';
|
||||
|
||||
class MyComponent extends ScopedElementsMixin(LitElement) {
|
||||
static get scopedElements() {
|
||||
return { 'lion-switch': LionSwitch };
|
||||
}
|
||||
render() {
|
||||
return html`<lion-switch></lion-switch>`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Use html
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import '@lion/switch/define-switch';
|
||||
</script>
|
||||
|
||||
<lion-switch></lion-switch>
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,6 +1,24 @@
|
|||
# Interaction >> Switch >> Reference ||30
|
||||
|
||||
<p class="paragraph--emphasis">Everything you need to re-use the switch.</p>
|
||||
<p class="lion-paragraph--emphasis">Everything you need to re-use the switch.</p>
|
||||
|
||||
## Requirements
|
||||
|
||||
This component fulfils the following requirements:
|
||||
|
||||
1. The component clearly communicates what is it for.
|
||||
2. The component supports helper text.
|
||||
3. The component supports smart defaults.
|
||||
4. The component supports the following states: on, off, hover (Web only), focused, disabled, pressed and processing
|
||||
5. The transformation between ON and OFF states are enhanced by an animation.
|
||||
6. Toggling the switch (on <-> off) will execute the underlying action immediately.
|
||||
|
||||
## Keyboard interactions
|
||||
|
||||
| <kbd>Key</kbd> | Action |
|
||||
| :------------------ | :------------------------------------------------------------------------------------------------ |
|
||||
| <kbd>Enter</kbd> | On keyboard focus, pressing <kbd>Enter</kbd> changes the state of the switch to “On” or “Off”. |
|
||||
| <kbd>Spacebar</kbd> | On keyboard focus, pressing <kbd>Spacebar</kbd> changes the state of the switch to “On” or “Off”. |
|
||||
|
||||
## WAI-ARIA roles
|
||||
|
||||
|
|
@ -19,21 +37,3 @@
|
|||
role: switch<br>
|
||||
state: aria-checked=“false”<br>
|
||||
SR: “Label, off, switch”
|
||||
|
||||
## Keyboard interactions
|
||||
|
||||
| <kbd>Key</kbd> | Action |
|
||||
| :------------------ | :------------------------------------------------------------------------------------------------ |
|
||||
| <kbd>Enter</kbd> | On keyboard focus, pressing <kbd>Enter</kbd> changes the state of the switch to “On” or “Off”. |
|
||||
| <kbd>Spacebar</kbd> | On keyboard focus, pressing <kbd>Spacebar</kbd> changes the state of the switch to “On” or “Off”. |
|
||||
|
||||
## Requirements
|
||||
|
||||
This component fulfils the following requirements:
|
||||
|
||||
1. The component clearly communicates what is it for.
|
||||
2. The component supports helper text.
|
||||
3. The component supports smart defaults.
|
||||
4. The component supports the following states: on, off, hover (Web only), focused, disabled, pressed and processing
|
||||
5. The transformation between ON and OFF states are enhanced by an animation.
|
||||
6. Toggling the switch (on <-> off) will execute the underlying action immediately.
|
||||
|
|
|
|||
|
|
@ -12,17 +12,16 @@ import '@lion/helpers/define-sb-action-logger';
|
|||
|
||||
You can disable switches.
|
||||
|
||||
```js preview-story
|
||||
export const disabled = () => html` <lion-switch label="Label" disabled></lion-switch> `;
|
||||
```html preview-story
|
||||
<lion-switch label="Label" disabled></lion-switch>
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
Simple example that illustrates where validation feedback will be displayed.
|
||||
An example that illustrates how an info validation feedback can be always displayed.
|
||||
|
||||
```js preview-story
|
||||
export const validation = () => {
|
||||
const IsTrue = class extends Validator {
|
||||
class IsTrue extends Validator {
|
||||
static get validatorName() {
|
||||
return 'IsTrue';
|
||||
}
|
||||
|
|
@ -32,34 +31,29 @@ export const validation = () => {
|
|||
static async getMessage() {
|
||||
return "You won't get the latest news!";
|
||||
}
|
||||
};
|
||||
const tagName = 'custom-switch';
|
||||
if (!customElements.get(tagName)) {
|
||||
customElements.define(
|
||||
tagName,
|
||||
}
|
||||
|
||||
class CustomSwitch extends LionSwitch {
|
||||
static get validationTypes() {
|
||||
return [...super.validationTypes, 'info'];
|
||||
}
|
||||
|
||||
_showFeedbackConditionFor(type) {
|
||||
_showFeedbackConditionFor(type, meta) {
|
||||
if (type === 'info') {
|
||||
return true;
|
||||
}
|
||||
return super._showFeedbackConditionFor(type);
|
||||
return super._showFeedbackConditionFor(type, meta);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
return html`
|
||||
customElements.define('custom-switch', CustomSwitch);
|
||||
|
||||
export const validation = () => html`
|
||||
<custom-switch
|
||||
id="newsletterCheck"
|
||||
name="newsletterCheck"
|
||||
label="Subscribe to newsletter"
|
||||
.validators="${[new IsTrue(null, { type: 'info' })]}"
|
||||
></custom-switch>
|
||||
`;
|
||||
};
|
||||
```
|
||||
|
||||
## With checked-changed handler
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
# Lion Accordion Features
|
||||
|
||||
[=> See Source <=](../../../docs/components/content/accordion/features.md)
|
||||
3
packages/accordion/docs/reference.md
Normal file
3
packages/accordion/docs/reference.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Lion Accordion Reference
|
||||
|
||||
[=> See Source <=](../../../docs/components/content/accordion/reference.md)
|
||||
3
packages/accordion/docs/use-cases.md
Normal file
3
packages/accordion/docs/use-cases.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Lion Accordion Use Cases
|
||||
|
||||
[=> See Source <=](../../../docs/components/content/accordion/use-cases.md)
|
||||
16
yarn.lock
16
yarn.lock
|
|
@ -1277,13 +1277,6 @@
|
|||
dependencies:
|
||||
vary "^1.1.2"
|
||||
|
||||
"@lion/accordion@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@lion/accordion/-/accordion-0.4.2.tgz#efeb56360113a2b68e182ff29ef0932edd17df8c"
|
||||
integrity sha512-xETjNmpBWYO1tYx2nBMq0I45UgydUJafZ4ft3szH3fQFjYWSBwjJjKsWxIhZSqX/IoTJzA0nNCdtbXoVEbSCLg==
|
||||
dependencies:
|
||||
"@lion/core" "0.16.0"
|
||||
|
||||
"@lion/core@0.16.0":
|
||||
version "0.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@lion/core/-/core-0.16.0.tgz#c4c8ac81b8d5bece6d40d561a392382c7ae73533"
|
||||
|
|
@ -1354,11 +1347,12 @@
|
|||
unist-util-visit "^2.0.3"
|
||||
|
||||
"@mdjs/mdjs-preview@^0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@mdjs/mdjs-preview/-/mdjs-preview-0.5.0.tgz#cd4177d303b5e034efe6472e424dbc91b7fbfec9"
|
||||
integrity sha512-GjLZLYJnXjFTrG77sxWqebSpFXoJHhIvTGDh1AjnIdtEOcnOqGjwaOrLjS751xPKSlS8GTo2G/6+usGeWfrx1Q==
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@mdjs/mdjs-preview/-/mdjs-preview-0.5.1.tgz#e8a252130cd21e8accdbc175f73ca109986a3039"
|
||||
integrity sha512-wxLR0dtku/Uv/LllEXx61r+H1S1n2pRM30Ht57aITukbFBoeh1xZoA/c9j/X+a2/paQNXzG9KsnMfUH0HKMsOQ==
|
||||
dependencies:
|
||||
"@lion/accordion" "^0.4.2"
|
||||
"@lion/accordion" "^0.6.1"
|
||||
"@open-wc/scoped-elements" "^2.0.0-next.3"
|
||||
lit "^2.0.0-rc.2"
|
||||
|
||||
"@mdjs/mdjs-story@^0.3.0":
|
||||
|
|
|
|||
Loading…
Reference in a new issue