All Projects → reecelucas → svelte-accessible-dialog

reecelucas / svelte-accessible-dialog

Licence: MIT license
An accessible dialog component for Svelte apps

Programming Languages

Svelte
593 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to svelte-accessible-dialog

A11y Dialog
A very lightweight and flexible accessible modal dialog script.
Stars: ✭ 1,768 (+7266.67%)
Mutual labels:  accessibility, a11y, modal, dialog
Launchy
Launchy: An Accessible Modal Window
Stars: ✭ 89 (+270.83%)
Mutual labels:  accessibility, a11y, modal, dialog
Jbox
jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.
Stars: ✭ 1,251 (+5112.5%)
Mutual labels:  alert, modal, dialog
Customalertviewdialogue
Custom AlertView Dialogue is the world's most advanced alert view library. Custom AlertView Dialogue includes simple message popups, confirmation alerts, selector popups, action sheet bottom menus, and input/feedback contact forms.
Stars: ✭ 100 (+316.67%)
Mutual labels:  alert, modal, dialog
Pmalertcontroller
PMAlertController is a great and customizable alert that can substitute UIAlertController
Stars: ✭ 2,397 (+9887.5%)
Mutual labels:  alert, modal, dialog
Sweetalert
A beautiful replacement for JavaScript's "alert"
Stars: ✭ 21,871 (+91029.17%)
Mutual labels:  alert, modal, dialog
React Native Alert Pro
The Pro Version of React Native Alert (Android & iOS)
Stars: ✭ 69 (+187.5%)
Mutual labels:  alert, modal, dialog
Bdialog
Extend the Bootstrap Modal features, making dialog more functions and easier to use, dialog type including modal, alert, mask and toast types
Stars: ✭ 174 (+625%)
Mutual labels:  alert, modal, dialog
jquery.dialog.js
A lightweight replacement for the browser's default dialog boxes.
Stars: ✭ 17 (-29.17%)
Mutual labels:  alert, modal, dialog
react-st-modal
Simple and flexible modal dialog component for React JS
Stars: ✭ 41 (+70.83%)
Mutual labels:  alert, modal, dialog
Nativepopup
Clone of Apple iOS App's feedback popup, and easily customizable.
Stars: ✭ 247 (+929.17%)
Mutual labels:  alert, modal, dialog
vue-modal
A customizable, stackable, and lightweight modal component for Vue.
Stars: ✭ 96 (+300%)
Mutual labels:  a11y, modal, dialog
s-date-range-picker
📅 A date range picker built with Svelte
Stars: ✭ 13 (-45.83%)
Mutual labels:  svelte, sveltejs, svelte3
Ngx Sweetalert2
Declarative, reactive, and template-driven SweetAlert2 integration for Angular
Stars: ✭ 503 (+1995.83%)
Mutual labels:  alert, modal, dialog
Ng Popups
🎉 Alert, confirm and prompt dialogs for Angular. Simple as that.
Stars: ✭ 80 (+233.33%)
Mutual labels:  alert, modal, dialog
Popupdialog
A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.
Stars: ✭ 3,709 (+15354.17%)
Mutual labels:  alert, modal, dialog
Alertifyjs
A javascript framework for developing pretty browser dialogs and notifications.
Stars: ✭ 1,922 (+7908.33%)
Mutual labels:  alert, modal, dialog
react-redux-modal-flex
[DEPRECATED] Make easy a modal/popup with Redux
Stars: ✭ 14 (-41.67%)
Mutual labels:  alert, modal, dialog
Accessible modal window
Accessible modal dialogs
Stars: ✭ 196 (+716.67%)
Mutual labels:  accessibility, a11y, dialog
Wc Messagebox
基于 Vue 2.0 开发的 Alert, Toast, Confirm 插件, UI仿照 iOS 原生
Stars: ✭ 203 (+745.83%)
Mutual labels:  alert, modal, dialog

svelte-accessible-dialog

An accessible dialog component for Svelte apps. Demo.

Coverage Status Build Status npm bundle size npm GitHub

Installation

npm install svelte-accessible-dialog

Usage

Basic

<script>
  import { DialogOverlay, DialogContent } from 'svelte-accessible-dialog';

  let isOpen;

  const open = () => {
    isOpen = true;
  };

  const close = () => {
    isOpen = false;
  };
</script>

<button on:click={open}>Open Dialog</button>

<DialogOverlay {isOpen} onDismiss={close}>
  <DialogContent aria-label="Announcement">
    <button on:click={close}>Close</button>
    <p>I am a dialog</p>
  </DialogContent>
</DialogOverlay>

Setting Initial Focus

By default, the first focusable element will receive focus when the dialog opens, but you can provide an element to focus instead.

<script>
  import { DialogOverlay, DialogContent } from 'svelte-accessible-dialog';

  let isOpen;
  let initialFocusElement;

  const open = () => {
    isOpen = true;
  };

  const close = () => {
    isOpen = false;
  };
</script>

<button on:click={open}>Open Dialog</button>

<DialogOverlay {isOpen} {initialFocusElement} onDismiss={close}>
  <DialogContent aria-label="Announcement">
    <button on:click={close}>Close</button>
    <label>
      Name: <input type="text" bind:this={initialFocusElement} />
    </label>
    <p>I am a dialog</p>
  </DialogContent>
</DialogOverlay>

Setting Return Focus

By default, the element that invoked the dialog will receive focus when the dialog closes, but you can provide an element to focus instead.

See the WAI-ARIA authoring practices for more detail about when you might want to do this.

<script>
  import { DialogOverlay, DialogContent } from 'svelte-accessible-dialog';

  let isOpen;
  let returnFocusElement;

  const open = () => {
    isOpen = true;
  };

  const close = () => {
    isOpen = false;
  };
</script>

<button on:click={open}>Open Dialog</button>
<button bind:this={returnFocusElement}>I focus on close</button>

<DialogOverlay {isOpen} {returnFocusElement} onDismiss={close}>
  <DialogContent aria-label="Announcement">
    <button on:click={close}>Close</button>
    <p>I am a dialog</p>
  </DialogContent>
</DialogOverlay>

Legacy Support for aria-modal

DialogContent has the aria-modal attribute. This indicates to screen readers that only content contained within the dialog should be accessible to the user. Modern screen readers respect this attribute, but you can enable a legacy workaround if you require deeper support.

See the WAI-ARIA authoring practices for more detail.

<script>
  import { DialogOverlay, DialogContent } from 'svelte-accessible-dialog';

  let isOpen;

  const open = () => {
    isOpen = true;
  };

  const close = () => {
    isOpen = false;
  };
</script>

<button on:click={open}>Open Dialog</button>

<DialogOverlay {isOpen} ariaModalLegacy={true} onDismiss={close}>
  <DialogContent aria-label="Announcement">
    <button on:click={close}>Close</button>
    <p>I am a dialog</p>
  </DialogContent>
</DialogOverlay>

Styling

:global

<style>
  :global([data-svelte-dialog-overlay].overlay) {
    z-index: 10;
  }

  :global([data-svelte-dialog-content].content) {
    border: 2px solid #000;
  }
</style>

<DialogOverlay class="overlay">
  <DialogContent class="content">
    <p>I am a dialog</p>
  </DialogContent>
</DialogOverlay>

Inline Styles

<DialogOverlay style="z-index: 10">
  <DialogContent style="border: 2px solid #000">
    <p>I am a dialog</p>
  </DialogContent>
</DialogOverlay>

Props

DialogOverlay

Must render DialogContent. Any props not listed below will be spread onto the underlying div.

Prop Type Required Description
isOpen Boolean Yes Controls whether the dialog is open or not.
onDismiss () => void Yes This function is called whenever the user hits "Escape" or clicks outside the dialog. The dialog must be closed on onDismiss.
initialFocusElement HTMLElement No The element that will receive focus when the dialog is open. Defaults to the first focusable element.
returnFocusElement HTMLElement No The element that will receive focus when the dialog closes. Defaults to the element that invoked the dialog.
ariaModalLegacy Boolean No Enables a fallback for the aria-modal attribute. When true, all content outside of the active dialog will have the aria-hidden and inert attributes set to "true".

DialogContent

Must be a child of DialogOverlay. Element props will be spread onto the underlying div.

Accessibility

WAI-ARIA: https://www.w3.org/TR/wai-aria-practices-1.2/#dialog_modal

Keyboard Accessibility

key action
Escape Dismisses the dialog

Tabbable Elements

It's recommended to have at least one tabbable element in the DialogContent. Ideally, the first element in the dialog should be a close button. If no tabbable elements are found, the dialog content element itself will receive focus.

Hiding Page Content from Screen Readers

Until fairly recently, keeping a screen reader within an active dialog was difficult. A focus trap prevents focus from leaving a dialog, but does nothing to stop a wandering virtual cursor. A common solution to this problem was to set the aria-hidden and inert attributes on all elements outside of the active dialog.

ARIA 1.1 introduced the aria-modal attribute. aria-modal indicates to screen readers that only content contained within a dialog with aria-modal="true" should be accessible to the user. Modern screen readers respect this attribute, so svelte-accessible-dialog does not implement the legacy workaround by default.

If support for aria-modal is inadequate for your app, you can pass ariaModalLegacy={true} to DialogOverlay to enable the legacy workaround.

Labelling

A dialog needs to be properly labelled to provide context for users that rely on assistive technology. If a dialog is announced to the user without a label, it can be confusing and difficult to navigate.

There are two general approaches to labelling: aria-label and aria-labelledby. If the text is visible on the screen, you should provide the label's HTML element with a unique id attribute. That id is then given to an aria-labelledby attribute on the DialogContent. With this context, the screen reader will announce whatever text is nested inside that ID'd markup as the title for the Dialog.

If a design doesn't include a visible label on the screen, you need to provide an aria-label prop on the DialogContent instead.

aria-label

<DialogContent aria-label="Cookie notice">
  <p>We use cookies to improve your website experience</p>
  <button>Not interested</button>
  <button>Ok, thanks</button>
</DialogContent>

aria-labelledby

<DialogContent aria-labelledby="cookie-dialog-title">
  <h2 id="cookie-dialog-title">Cookie Notice</h2>
  <p>We use cookies to improve your website experience</p>
  <button>Not interested</button>
  <button>Ok, thanks</button>
</DialogContent>

Z-index

DialogOverlay does not set a z-index. It depends on DOM order to be on top of the page content (it's inserted at the end of the document when it's opened). If you're fighting z-index wars, make sure to add a z-index to DialogOverlay.

Configuring webpack

If you're using webpack with svelte-loader, make sure to add "svelte" to resolve.mainFields in your webpack config. This ensures that webpack imports the uncompiled components (src/index.js) rather than the compiled version (dist/index.mjs), which is more efficient.

If you're using Rollup with rollup-plugin-svelte, this will happen automatically.

Tests

Tests use Jest and svelte-testing-library.

git clone [email protected]:reecelucas/svelte-accessible-dialog.git
cd svelte-accessible-dialog
yarn
yarn test

LICENSE

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].