Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/keiya01/aria-modal

Accessible modal with Web Components
https://github.com/keiya01/aria-modal

Last synced: 22 days ago
JSON representation

Accessible modal with Web Components

Awesome Lists containing this project

README

        

[![npm](https://img.shields.io/npm/v/aria-modal.svg)](https://npmjs.org/package/aria-modal) [![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/aria-modal)

# aria-modal

Accessible modal with Web Components

## About

aria-modal that is a fully accessible is built according to [WAI-ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#dialog_modal). And it provide the only simple features. It makes be easy to implement accessible modal. If you use polyfill, you can use [@webcomponents/webcomponentsjs](https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs).

## Features

- Focus is moved to first-focus element. Tab and Shift+Tab keys will cycle through the modal's focusable nodes.
- ESC key closes the modal.
- Scrolling is frozen on the document.body.
- When the modal closes, focus returns to the element that was focused before the modal are shown.
- The dialog element has an ARIA role of dialog by default(You can change role).
- The dialog element must has either aria-label or aria-labelledby.
- If clicking the backdrop, the modal is closed.
- If animation property is true, the modal can use the fade-in(out) animation.

## DEMO

https://keiya01.github.io/aria-modal-doc/top/

## Install

Using npm:

```bash
$ npm install aria-modal
```

## Usage

```js

import 'aria-modal';

/**
* do something
*/

```

### Append Your Modal

You can append your modal inside aria-modal with `slot`. If you use `slot`, you can use accessible feature for modal.
Please see following example.

```html




```

If you use custom element, see the following code.

```html


```

### Style

Using css variables, you can apply your style to ``.

```css

aria-modal {
--backdrop-display: block; /* or flex, inline-block, etc... */
--backdrop-color: rgba(0, 0, 0, 0.3); /* background-color for backdrop */
--backdrop-position: fixed; /* or fixed */
--backdrop-z-index: none;
--animation-function: linear;
--animation-duration: 300ms;
/* required, if fade property is false */
--animation-delay: none;
}

```

#### Tips

If you want to set your modal to center, you can use `margin: auto;` and `flexbox` property.

```css

aria-modal {
--backdrop-display: flex;
/* ... */
}

.your-modal {
margin: auto;
height: 300px;
width: 500px;
background-color: #fff;
}

```

### Props

#### open

Required: `false`, Type: `boolean`, Default: `false`

It is used to show modal. You can set `true` if you want to open modal.

#### first-focus

Required: `true`, Type: `string` or `function firstFocus(): HTMLElement`

It is used to focus to first element when modal is opened. You should assign `id` name.

If `first-focus` element is a custom element or inside a custom element, You must implement `firstFocus` method to your slotted element. That is, slotted element must be custom element if `first-focus` element is custom element.

```js

class SampleModal extends HTMLElement {
get template() {
const template = document.createElement('template');
template.innerHTML = `


Button

`;
}

constructor() {
super();

const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(this.template.content.cloneNode(true));
}

/**
* Do something
*/

// You must implement `firstFocus()`, if you use custom element.
firstFocus() {
return this.shadowRoot.getElementById('first-element');
}
}

```

#### app

Required: `true`, Type: `string`

It is used to set `aria-hidden` to your `app` element. You should set main contents `id` name.

**Notice**: Don't contain `aria-modal` inside main contents. If you contain `aria-modal` to your main contents, screen readers can not find `aria-modal`.

#### animation

Required: `false`, Type: `boolean`, Default: `false`

If `true`, you can use animation. aria-modal run fade animation by default.
If you want to use custom animation, you can use `active` and `hide` properties.

#### fade

Required: `false`, Type: `boolean`, Default: `true`

If `false`, default fade animation is disabled.

#### active

Required: `false`, Type: `string`

`active` is class name that is added when `open` props is changed to `true`.

#### hide

Required: `false`, Type: `string`

`hide` is class name that is added when `open` props is changed to `false`.

#### disabled

Required: `false`, Type: `boolean`

If true, disable clicking on the backdrop.

#### aria-label or aria-labelledby

Required: `true`, Type: `string`

You must include `aria-label` or `aria-labelledby` property to your modal.
See https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-labelledby_attribute

#### aria-describedby

Required: `false`, Type: `string`

See https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-describedby_attribute

#### role

Required: `true`, Type: `string`

You must include `role` property to your modal.
Assignable value is `dialog` or `alertdialog`. See https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles

#### aria-modal

Required: `false`, Type: `boolean`, Default: `false`

This property is some problems, see this article https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
And if you want to know about `aria-modal`, see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/dialog_role

### Warning

If the active class is not set to `aria-modal`, it may flicker when reloaded on browser. When you set active class, you should set your modal to `display: none;` and you should set your active class to `display: block; /* or flex, inline-block, etc... */`.
This problem is occurred by rendering process for Web Components. Your modal is assigned to `slot` element in `aria-modal`, and `slot` is rendered after JavaScript file(and Web Components) have loaded. That is, this problem is occurred by your modal is rendered without your modal is assigned to slot.

### Example

https://github.com/keiya01/aria-modal/tree/master/example

## License

[MIT License](https://github.com/keiya01/aria-modal/blob/master/LICENSE)