diff --git a/.changeset/four-ghosts-change.md b/.changeset/four-ghosts-change.md new file mode 100644 index 000000000..a53893006 --- /dev/null +++ b/.changeset/four-ghosts-change.md @@ -0,0 +1,5 @@ +--- +'@lion/progress-indicator': minor +--- + +Initial release diff --git a/packages/progress-indicator/README.md b/packages/progress-indicator/README.md new file mode 100644 index 000000000..ae1e8e5ad --- /dev/null +++ b/packages/progress-indicator/README.md @@ -0,0 +1,90 @@ +[//]: # 'AUTO INSERT HEADER PREPUBLISH' + +# Progress Indicator + +`lion-progress-indicator` implements accessibility requirements for progress indicators. + +```js script +import { html } from 'lit-html'; +import './demo/custom-progress-indicator.js'; + +export default { + title: 'Others/Progress Indicator', +}; +``` + +## Features + +- Accessibility compliant +- Localized "Loading" label +- Implementation independent of visuals + +## How to use + +### Installation + +```bash +npm i --save @lion/progress-indicator +``` + +```js +import { LionProgressIndicator } from '@lion/progress-indicator'; +// or +import '@lion/progress-indicator/lion-progress-indicator.js'; +``` + +### Example + +```html + +``` + +## Extended indicator with a custom visual + +`LionProgressIndicator` is designed to be extended to add visuals. Implement the `_graphicTemplate` method to set the rendered content, and apply styles normally. + +### Example extension + +```js +class CustomProgressIndicator extends LionProgressIndicator { + static get styles() { + return [ + css` + svg { + animation: spinner-rotate 2s linear infinite; + display: inline-block; + height: 48px; + width: 48px; + } + + circle { + fill: none; + stroke-width: 3.6; + stroke: firebrick; + stroke-dasharray: 100, 28; + } + + @keyframes spinner-rotate { + to { + transform: rotate(360deg); + } + } + `, + ]; + } + + _graphicTemplate() { + return html` + + `; + } +} +``` + +### Result + +```js preview-story +export const customProgressDemo = () => html` + +`; +``` diff --git a/packages/progress-indicator/demo/CustomProgressIndicator.js b/packages/progress-indicator/demo/CustomProgressIndicator.js new file mode 100644 index 000000000..85fc4d1c5 --- /dev/null +++ b/packages/progress-indicator/demo/CustomProgressIndicator.js @@ -0,0 +1,56 @@ +import { svg, css } from '@lion/core'; +import { LionProgressIndicator } from '../index.js'; + +export class CustomProgressIndicator extends LionProgressIndicator { + static get styles() { + return [ + css` + :host { + display: inline-block; + } + + svg { + animation: spinner-rotate 2s linear infinite; + display: inline-block; + height: 48px; + width: 48px; + } + + circle { + animation: spinner-dash 1.35s ease-in-out infinite; + fill: none; + stroke-width: 3.6; + stroke: firebrick; + stroke-dasharray: 100, 28; /* This is a fallback for IE11 */ + } + + @keyframes spinner-rotate { + to { + transform: rotate(360deg); + } + } + + @keyframes spinner-dash { + 0% { + stroke-dasharray: 6, 122; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 100, 28; + stroke-dashoffset: -16; + } + 100% { + stroke-dasharray: 6, 122; + stroke-dashoffset: -127; + } + } + `, + ]; + } + + _graphicTemplate() { + return svg` + + `; + } +} diff --git a/packages/progress-indicator/demo/custom-progress-indicator.js b/packages/progress-indicator/demo/custom-progress-indicator.js new file mode 100644 index 000000000..a8079806b --- /dev/null +++ b/packages/progress-indicator/demo/custom-progress-indicator.js @@ -0,0 +1,3 @@ +import { CustomProgressIndicator } from './CustomProgressIndicator.js'; + +customElements.define('custom-progress-indicator', CustomProgressIndicator); diff --git a/packages/progress-indicator/index.js b/packages/progress-indicator/index.js new file mode 100644 index 000000000..851df3d26 --- /dev/null +++ b/packages/progress-indicator/index.js @@ -0,0 +1 @@ +export { LionProgressIndicator } from './src/LionProgressIndicator.js'; diff --git a/packages/progress-indicator/lion-progress-indicator.js b/packages/progress-indicator/lion-progress-indicator.js new file mode 100644 index 000000000..81977b6d2 --- /dev/null +++ b/packages/progress-indicator/lion-progress-indicator.js @@ -0,0 +1,3 @@ +import { LionProgressIndicator } from './src/LionProgressIndicator.js'; + +customElements.define('lion-progress-indicator', LionProgressIndicator); diff --git a/packages/progress-indicator/package.json b/packages/progress-indicator/package.json new file mode 100644 index 000000000..c54e129ee --- /dev/null +++ b/packages/progress-indicator/package.json @@ -0,0 +1,46 @@ +{ + "name": "@lion/progress-indicator", + "version": "0.0.0", + "description": "A progress indicator that is easily styleable and accessible in all contexts", + "license": "MIT", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/progress-indicator" + }, + "main": "index.js", + "module": "index.js", + "files": [ + "*.d.ts", + "*.js", + "src", + "test", + "translations", + "types" + ], + "scripts": { + "prepublishOnly": "../../scripts/npm-prepublish.js", + "start": "cd ../../ && yarn dev-server --open packages/progress-indicator/README.md", + "test": "cd ../../ && yarn test:browser --grep \"packages/progress-indicator/test/**/*.test.js\"", + "test:watch": "cd ../../ && yarn test:browser:watch --grep \"packages/progress-indicator/test/**/*.test.js\"" + }, + "sideEffects": [ + "lion-progress-indicator.js" + ], + "dependencies": { + "@lion/core": "0.8.0", + "@lion/localize": "0.13.1" + }, + "keywords": [ + "lion", + "loading-indicator", + "progress-indicator", + "spinner", + "web-components" + ], + "publishConfig": { + "access": "public" + } +} diff --git a/packages/progress-indicator/src/LionProgressIndicator.js b/packages/progress-indicator/src/LionProgressIndicator.js new file mode 100644 index 000000000..e8f89a15a --- /dev/null +++ b/packages/progress-indicator/src/LionProgressIndicator.js @@ -0,0 +1,88 @@ +/* eslint-disable class-methods-use-this */ + +import { nothing, LitElement } from '@lion/core'; +import { localize, LocalizeMixin } from '@lion/localize'; + +export class LionProgressIndicator extends LocalizeMixin(LitElement) { + static get localizeNamespaces() { + return [ + { + 'lion-progress-indicator': locale => { + switch (locale) { + case 'bg-BG': + case 'bg': + return import('../translations/bg.js'); + case 'cs-CZ': + case 'cs': + return import('../translations/cs.js'); + case 'de-DE': + case 'de': + return import('../translations/de.js'); + case 'en-AU': + case 'en-GB': + case 'en-US': + case 'en-PH': + case 'en': + return import('../translations/en.js'); + case 'es-ES': + case 'es': + return import('../translations/es.js'); + case 'fr-BE': + case 'fr-FR': + case 'fr': + return import('../translations/fr.js'); + case 'hu-HU': + case 'hu': + return import('../translations/hu.js'); + case 'it-IT': + case 'it': + return import('../translations/it.js'); + case 'nl-BE': + case 'nl-NL': + case 'nl': + return import('../translations/nl.js'); + case 'pl-PL': + case 'pl': + return import('../translations/pl.js'); + case 'ro-RO': + case 'ro': + return import('../translations/ro.js'); + case 'ru-RU': + case 'ru': + return import('../translations/ru.js'); + case 'sk-SK': + case 'sk': + return import('./translations/sk.js'); + case 'uk-UA': + case 'uk': + return import('../translations/uk.js'); + case 'zh-CN': + case 'zh': + return import('../translations/zh.js'); + default: + return import('../translations/en.js'); + } + }, + }, + ]; + } + + _graphicTemplate() { + return nothing; + } + + render() { + return this._graphicTemplate(); + } + + connectedCallback() { + super.connectedCallback(); + this.setAttribute('role', 'status'); + this.setAttribute('aria-live', 'polite'); + } + + onLocaleUpdated() { + const label = localize.msg('lion-progress-indicator:loading'); + this.setAttribute('aria-label', label); + } +} diff --git a/packages/progress-indicator/test/lion-progress-indicator.test.js b/packages/progress-indicator/test/lion-progress-indicator.test.js new file mode 100644 index 000000000..e92798e56 --- /dev/null +++ b/packages/progress-indicator/test/lion-progress-indicator.test.js @@ -0,0 +1,23 @@ +import { expect, fixture } from '@open-wc/testing'; +import { html } from '@lion/core'; + +import '../lion-progress-indicator.js'; + +describe('lion-progress-indicator', () => { + describe('Accessibility', () => { + it('adds a label', async () => { + const el = await fixture(html` `); + expect(el.getAttribute('aria-label')).to.equal('Loading'); + }); + + it('sets the right role', async () => { + const el = await fixture(html` `); + expect(el.getAttribute('role')).to.equal('status'); + }); + + it('sets aria-live to "polite"', async () => { + const el = await fixture(html` `); + expect(el.getAttribute('aria-live')).to.equal('polite'); + }); + }); +}); diff --git a/packages/progress-indicator/translations/bg.js b/packages/progress-indicator/translations/bg.js new file mode 100644 index 000000000..1aae3649c --- /dev/null +++ b/packages/progress-indicator/translations/bg.js @@ -0,0 +1,3 @@ +export default { + loading: 'Зареждане', +}; diff --git a/packages/progress-indicator/translations/cs.js b/packages/progress-indicator/translations/cs.js new file mode 100644 index 000000000..2750a1315 --- /dev/null +++ b/packages/progress-indicator/translations/cs.js @@ -0,0 +1,3 @@ +export default { + loading: 'Načítání', +}; diff --git a/packages/progress-indicator/translations/de.js b/packages/progress-indicator/translations/de.js new file mode 100644 index 000000000..ec1bad6bf --- /dev/null +++ b/packages/progress-indicator/translations/de.js @@ -0,0 +1,3 @@ +export default { + loading: 'Wird geladen', +}; diff --git a/packages/progress-indicator/translations/en.js b/packages/progress-indicator/translations/en.js new file mode 100644 index 000000000..ad6168eaa --- /dev/null +++ b/packages/progress-indicator/translations/en.js @@ -0,0 +1,3 @@ +export default { + loading: 'Loading', +}; diff --git a/packages/progress-indicator/translations/es.js b/packages/progress-indicator/translations/es.js new file mode 100644 index 000000000..902f7389d --- /dev/null +++ b/packages/progress-indicator/translations/es.js @@ -0,0 +1,3 @@ +export default { + loading: 'Cargando', +}; diff --git a/packages/progress-indicator/translations/fr.js b/packages/progress-indicator/translations/fr.js new file mode 100644 index 000000000..380402186 --- /dev/null +++ b/packages/progress-indicator/translations/fr.js @@ -0,0 +1,3 @@ +export default { + loading: 'Chargement', +}; diff --git a/packages/progress-indicator/translations/hu.js b/packages/progress-indicator/translations/hu.js new file mode 100644 index 000000000..90f637de3 --- /dev/null +++ b/packages/progress-indicator/translations/hu.js @@ -0,0 +1,3 @@ +export default { + loading: 'Betöltés', +}; diff --git a/packages/progress-indicator/translations/it.js b/packages/progress-indicator/translations/it.js new file mode 100644 index 000000000..9de48d3da --- /dev/null +++ b/packages/progress-indicator/translations/it.js @@ -0,0 +1,3 @@ +export default { + loading: 'Caricamento in corso', +}; diff --git a/packages/progress-indicator/translations/nl.js b/packages/progress-indicator/translations/nl.js new file mode 100644 index 000000000..bf4b0d5fc --- /dev/null +++ b/packages/progress-indicator/translations/nl.js @@ -0,0 +1,3 @@ +export default { + loading: 'Laden', +}; diff --git a/packages/progress-indicator/translations/pl.js b/packages/progress-indicator/translations/pl.js new file mode 100644 index 000000000..15c638ca6 --- /dev/null +++ b/packages/progress-indicator/translations/pl.js @@ -0,0 +1,3 @@ +export default { + loading: 'Ładuję', +}; diff --git a/packages/progress-indicator/translations/ro.js b/packages/progress-indicator/translations/ro.js new file mode 100644 index 000000000..b2656aa3b --- /dev/null +++ b/packages/progress-indicator/translations/ro.js @@ -0,0 +1,3 @@ +export default { + loading: 'Se incarca', +}; diff --git a/packages/progress-indicator/translations/ru.js b/packages/progress-indicator/translations/ru.js new file mode 100644 index 000000000..d0f354099 --- /dev/null +++ b/packages/progress-indicator/translations/ru.js @@ -0,0 +1,3 @@ +export default { + loading: 'погрузка', +}; diff --git a/packages/progress-indicator/translations/sk.js b/packages/progress-indicator/translations/sk.js new file mode 100644 index 000000000..d0f354099 --- /dev/null +++ b/packages/progress-indicator/translations/sk.js @@ -0,0 +1,3 @@ +export default { + loading: 'погрузка', +}; diff --git a/packages/progress-indicator/translations/uk.js b/packages/progress-indicator/translations/uk.js new file mode 100644 index 000000000..5aabcd125 --- /dev/null +++ b/packages/progress-indicator/translations/uk.js @@ -0,0 +1,3 @@ +export default { + loading: 'завантаження', +}; diff --git a/packages/progress-indicator/translations/zh.js b/packages/progress-indicator/translations/zh.js new file mode 100644 index 000000000..2e6008fa5 --- /dev/null +++ b/packages/progress-indicator/translations/zh.js @@ -0,0 +1,3 @@ +export default { + loading: '载入中', +};