Skip to content

Commit 875d46e

Browse files
authored
feat: Visually hidden component (#593)
* Add visually hidden package * Adjust visually hidden component * Format code * Simplify export of module * Run format prettier * Add description * Update readme
1 parent 61c62e4 commit 875d46e

10 files changed

+209
-0
lines changed

package-lock.json

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# uui-visually-hidden
2+
3+
![npm](https://img.shields.io/npm/v/@umbraco-ui/uui-visually-hidden?logoColor=%231B264F)
4+
5+
Umbraco style visually-hidden component.
6+
7+
The visually hidden utility makes content accessible to assistive devices without displaying it on the screen.
8+
9+
According to [The A11Y Project](https://www.a11yproject.com/posts/how-to-hide-content/):
10+
11+
> There are real world situations where visually hiding content may be appropriate, while the content should remain available to assistive technologies, such as screen readers. For instance, hiding a search field's label as a common magnifying glass icon is used in its stead.
12+
13+
Since visually hidden content can receive focus when tabbing, the element will become visible when something inside receives focus. This behavior is intentional, as sighted keyboard user won’t be able to determine where the focus indicator is without it.
14+
15+
## Installation
16+
17+
### ES imports
18+
19+
```zsh
20+
npm i @umbraco-ui/uui-visually-hidden
21+
```
22+
23+
Import the registration of `<uui-visually-hidden>` via:
24+
25+
```javascript
26+
import '@umbraco-ui/uui-visually-hidden';
27+
```
28+
29+
When looking to leverage the `UUIVisuallyHiddenElement` base class as a type and/or for extension purposes, do so via:
30+
31+
```javascript
32+
import { UUIVisuallyHiddenElement } from '@umbraco-ui/uui-visually-hidden';
33+
```
34+
35+
## Usage
36+
37+
```html
38+
<uui-visually-hidden></uui-visually-hidden>
39+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './uui-visually-hidden.element';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
2+
import { css, html, LitElement } from 'lit';
3+
4+
/**
5+
* @element uui-visually-hidden
6+
*/
7+
@defineElement('uui-visually-hidden')
8+
export class UUIVisuallyHiddenElement extends LitElement {
9+
static styles = [
10+
css`
11+
:host(:not(:focus-within)) {
12+
position: absolute !important;
13+
width: 1px !important;
14+
height: 1px !important;
15+
clip: rect(0 0 0 0) !important;
16+
clip-path: inset(50%) !important;
17+
border: none !important;
18+
overflow: hidden !important;
19+
white-space: nowrap !important;
20+
padding: 0 !important;
21+
}
22+
`,
23+
];
24+
25+
render() {
26+
return html`<slot></slot>`;
27+
}
28+
}
29+
30+
declare global {
31+
interface HTMLElementTagNameMap {
32+
'uui-visually-hidden': UUIVisuallyHiddenElement;
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { Meta, StoryObj } from '@storybook/web-components';
2+
3+
import './uui-visually-hidden.element';
4+
import type { UUIVisuallyHiddenElement } from './uui-visually-hidden.element';
5+
import readme from '../README.md?raw';
6+
7+
const meta: Meta<UUIVisuallyHiddenElement> = {
8+
id: 'uui-visually-hidden',
9+
title: 'Visually Hidden',
10+
component: 'uui-visually-hidden',
11+
parameters: {
12+
readme: { markdown: readme },
13+
docs: {
14+
source: {
15+
code: `<uui-visually-hidden></uui-visually-hidden>`,
16+
},
17+
},
18+
},
19+
};
20+
21+
export default meta;
22+
type Story = StoryObj<UUIVisuallyHiddenElement>;
23+
24+
export const Overview: Story = {};
25+
26+
export const SkipNavigation: Story = {
27+
args: {},
28+
parameters: {
29+
docs: {
30+
source: {
31+
code: `<uui-visually-hidden>
32+
<a href="#">Skip to main content</a>
33+
</uui-visually-hidden>`,
34+
},
35+
},
36+
},
37+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { html, fixture, expect } from '@open-wc/testing';
2+
import { UUIVisuallyHiddenElement } from './uui-visually-hidden.element';
3+
4+
describe('UUIVisuallyHiddenElement', () => {
5+
let element: UUIVisuallyHiddenElement;
6+
7+
beforeEach(async () => {
8+
element = await fixture(
9+
html` <uui-visually-hidden></uui-visually-hidden> `
10+
);
11+
});
12+
13+
it('is defined with its own instance', () => {
14+
expect(element).to.be.instanceOf(UUIVisuallyHiddenElement);
15+
});
16+
17+
it('passes the a11y audit', async () => {
18+
await expect(element).shadowDom.to.be.accessible();
19+
});
20+
});
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@umbraco-ui/uui-visually-hidden",
3+
"version": "0.0.0",
4+
"license": "MIT",
5+
"keywords": [
6+
"Umbraco",
7+
"Custom elements",
8+
"Web components",
9+
"UI",
10+
"Lit",
11+
"Visually Hidden"
12+
],
13+
"description": "Umbraco UI visually-hidden component",
14+
"repository": {
15+
"type": "git",
16+
"url": "https://github.com/umbraco/Umbraco.UI.git",
17+
"directory": "packages/uui-visually-hidden"
18+
},
19+
"bugs": {
20+
"url": "https://github.com/umbraco/Umbraco.UI/issues"
21+
},
22+
"main": "./lib/index.js",
23+
"module": "./lib/index.js",
24+
"types": "./lib/index.d.ts",
25+
"type": "module",
26+
"customElements": "custom-elements.json",
27+
"files": [
28+
"lib/**/*.d.ts",
29+
"lib/**/*.js",
30+
"custom-elements.json"
31+
],
32+
"dependencies": {
33+
"@umbraco-ui/uui-base": "1.5.0-rc.0"
34+
},
35+
"scripts": {
36+
"build": "npm run analyze && tsc --build --force && rollup -c rollup.config.js",
37+
"clean": "tsc --build --clean && rimraf -g dist lib/*.js lib/**/*.js *.tgz lib/**/*.d.ts custom-elements.json",
38+
"analyze": "web-component-analyzer **/*.element.ts --outFile custom-elements.json"
39+
},
40+
"publishConfig": {
41+
"access": "public"
42+
},
43+
"homepage": "https://uui.umbraco.com/?path=/story/uui-visually-hidden"
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { UUIProdConfig } from '../rollup-package.config.mjs';
2+
3+
export default UUIProdConfig({
4+
entryPoints: ['index'],
5+
});
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Don't edit this file directly. It is generated by /scripts/generate-ts-config.js
2+
3+
{
4+
"extends": "../../tsconfig.json",
5+
"compilerOptions": {
6+
"outDir": "./lib",
7+
"rootDir": "./lib",
8+
"composite": true
9+
},
10+
"include": ["./**/*.ts"],
11+
"exclude": ["./**/*.test.ts", "./**/*.story.ts"],
12+
"references": [
13+
{
14+
"path": "../uui-base"
15+
}
16+
]
17+
}

packages/uui/lib/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,4 @@ export * from '@umbraco-ui/uui-toast-notification-container/lib';
7878
export * from '@umbraco-ui/uui-toast-notification-layout/lib';
7979
export * from '@umbraco-ui/uui-toast-notification/lib';
8080
export * from '@umbraco-ui/uui-toggle/lib';
81+
export * from '@umbraco-ui/uui-visually-hidden/lib';

0 commit comments

Comments
 (0)