From 2e763d4454ef71c4707767a3962f6735a9e34f1f Mon Sep 17 00:00:00 2001 From: Jeri Peier Date: Tue, 30 Jan 2024 20:12:53 +0100 Subject: [PATCH] feat(sbb-screenreader-only): initial implementation (#2377) --- .../screenreader-only.spec.snap.js | 15 +++++++ src/components/screenreader-only/index.ts | 1 + src/components/screenreader-only/readme.md | 15 +++++++ .../screenreader-only.e2e.ts | 16 ++++++++ .../screenreader-only/screenreader-only.scss | 5 +++ .../screenreader-only.spec.ts | 17 ++++++++ .../screenreader-only.stories.ts | 40 +++++++++++++++++++ .../screenreader-only/screenreader-only.ts | 26 ++++++++++++ 8 files changed, 135 insertions(+) create mode 100644 src/components/screenreader-only/__snapshots__/screenreader-only.spec.snap.js create mode 100644 src/components/screenreader-only/index.ts create mode 100644 src/components/screenreader-only/readme.md create mode 100644 src/components/screenreader-only/screenreader-only.e2e.ts create mode 100644 src/components/screenreader-only/screenreader-only.scss create mode 100644 src/components/screenreader-only/screenreader-only.spec.ts create mode 100644 src/components/screenreader-only/screenreader-only.stories.ts create mode 100644 src/components/screenreader-only/screenreader-only.ts diff --git a/src/components/screenreader-only/__snapshots__/screenreader-only.spec.snap.js b/src/components/screenreader-only/__snapshots__/screenreader-only.spec.snap.js new file mode 100644 index 0000000000..6c61796930 --- /dev/null +++ b/src/components/screenreader-only/__snapshots__/screenreader-only.spec.snap.js @@ -0,0 +1,15 @@ +/* @web/test-runner snapshot v1 */ +export const snapshots = {}; + +snapshots["with Light DOM"] = +` + +`; +/* end snapshot with Light DOM */ + +snapshots["with Shadow DOM"] = +` + +`; +/* end snapshot with Shadow DOM */ + diff --git a/src/components/screenreader-only/index.ts b/src/components/screenreader-only/index.ts new file mode 100644 index 0000000000..b07ca35525 --- /dev/null +++ b/src/components/screenreader-only/index.ts @@ -0,0 +1 @@ +export * from './screenreader-only'; diff --git a/src/components/screenreader-only/readme.md b/src/components/screenreader-only/readme.md new file mode 100644 index 0000000000..fea0d0d476 --- /dev/null +++ b/src/components/screenreader-only/readme.md @@ -0,0 +1,15 @@ +The `sbb-screenreader-only` is a component to visually hide content but present it to screen readers. + +```html + + Content visually hidden, but presented to screen reader. + +``` + + + +## Slots + +| Name | Description | +| ---- | ---------------------------------------- | +| | Use the unnamed slot to provide content. | diff --git a/src/components/screenreader-only/screenreader-only.e2e.ts b/src/components/screenreader-only/screenreader-only.e2e.ts new file mode 100644 index 0000000000..6567794bb0 --- /dev/null +++ b/src/components/screenreader-only/screenreader-only.e2e.ts @@ -0,0 +1,16 @@ +import { assert, fixture } from '@open-wc/testing'; +import { html } from 'lit/static-html.js'; + +import { SbbScreenreaderOnlyElement } from './screenreader-only'; + +describe('sbb-screenreader-only', () => { + let element: SbbScreenreaderOnlyElement; + + beforeEach(async () => { + element = await fixture(html`Hidden text.`); + }); + + it('renders', async () => { + assert.instanceOf(element, SbbScreenreaderOnlyElement); + }); +}); diff --git a/src/components/screenreader-only/screenreader-only.scss b/src/components/screenreader-only/screenreader-only.scss new file mode 100644 index 0000000000..aa75875263 --- /dev/null +++ b/src/components/screenreader-only/screenreader-only.scss @@ -0,0 +1,5 @@ +@use '../core/styles' as sbb; + +:host { + @include sbb.screen-reader-only; +} diff --git a/src/components/screenreader-only/screenreader-only.spec.ts b/src/components/screenreader-only/screenreader-only.spec.ts new file mode 100644 index 0000000000..aaa4ef7243 --- /dev/null +++ b/src/components/screenreader-only/screenreader-only.spec.ts @@ -0,0 +1,17 @@ +import { expect, fixture } from '@open-wc/testing'; +import { html } from 'lit/static-html.js'; +import './screenreader-only'; + +describe('sbb-screenreader-only', () => { + describe('renders', async () => { + const root = await fixture(html``); + + it('with Light DOM', async () => { + await expect(root).dom.to.be.equalSnapshot(); + }); + + it('with Shadow DOM', async () => { + await expect(root).shadowDom.to.be.equalSnapshot(); + }); + }); +}); diff --git a/src/components/screenreader-only/screenreader-only.stories.ts b/src/components/screenreader-only/screenreader-only.stories.ts new file mode 100644 index 0000000000..2704838f85 --- /dev/null +++ b/src/components/screenreader-only/screenreader-only.stories.ts @@ -0,0 +1,40 @@ +import { withActions } from '@storybook/addon-actions/decorator'; +import type { InputType } from '@storybook/types'; +import type { Args, Decorator, Meta, StoryObj } from '@storybook/web-components'; +import type { TemplateResult } from 'lit'; +import { html } from 'lit'; + +import readme from './readme.md?raw'; + +import './screenreader-only'; + +const content: InputType = { + control: { + type: 'text', + }, +}; + +const Template = (args: Args): TemplateResult => + html`There is a visually hidden text here: + ${args.content}`; + +export const Default: StoryObj = { + render: Template, + argTypes: { content }, + args: { content: `I'm visually hidden, but read to screen reader.` }, +}; + +const meta: Meta = { + decorators: [withActions as Decorator], + parameters: { + backgrounds: { + disable: true, + }, + docs: { + extractComponentDescription: () => readme, + }, + }, + title: 'internals/sbb-screenreader-only', +}; + +export default meta; diff --git a/src/components/screenreader-only/screenreader-only.ts b/src/components/screenreader-only/screenreader-only.ts new file mode 100644 index 0000000000..ab0668ff92 --- /dev/null +++ b/src/components/screenreader-only/screenreader-only.ts @@ -0,0 +1,26 @@ +import type { CSSResultGroup, TemplateResult } from 'lit'; +import { html, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +import style from './screenreader-only.scss?lit&inline'; + +/** + * This component can be used to visually hide content but present it to screen readers. + * + * @slot - Use the unnamed slot to provide content. + */ +@customElement('sbb-screenreader-only') +export class SbbScreenreaderOnlyElement extends LitElement { + public static override styles: CSSResultGroup = style; + + protected override render(): TemplateResult { + return html``; + } +} + +declare global { + interface HTMLElementTagNameMap { + // eslint-disable-next-line @typescript-eslint/naming-convention + 'sbb-screenreader-only': SbbScreenreaderOnlyElement; + } +}