Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@nrk/core-dialog

Package Overview
Dependencies
Maintainers
105
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nrk/core-dialog

## `<dialog>` is an element with which the user interacts with to perform some task or decision. `@nrk/core-dialog` simply adds `dialog` functionality to a `<dialog>` if it is not supported (or extends functionality if is supported). `@nrk/core-dialog` su

  • 1.0.14
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
974
decreased by-42.71%
Maintainers
105
Weekly downloads
 
Created
Source

Core Dialog

<dialog> is an element with which the user interacts with to perform some task or decision. @nrk/core-dialog simply adds dialog functionality to a <dialog> if it is not supported (or extends functionality if is supported). @nrk/core-dialog supports nestability, keyboard navigation containment and restoring focus when dialog is closed.


Installation

npm install @nrk/core-dialog --save-exact
import coreDialog from '@nrk/core-dialog'     // Vanilla JS
import CoreDialog from '@nrk/core-dialog/jsx' // ...or React/Preact compatible JSX

Demo

<!--demo-->
<button data-core-dialog="my-dialog">Open dialog</button>
<dialog id="my-dialog" class="my-dialog" aria-label="første dialog tittel">
  <h1>This is a title</h1>
  <p>Nunc mi felis, condimentum quis hendrerit sed, porta eget libero. Aenean scelerisque ex eu nisi varius hendrerit. Suspendisse elementum quis massa at vehicula. Nulla lacinia mi pulvinar, venenatis nisi ut, commodo quam. Praesent egestas mi sit amet quam porttitor, mollis mattis mi rhoncus.</p>
  <button data-core-dialog="my-dialog-nested">Open an additional dialog</button>
  <button type="button" autofocus style="visibility: hidden">Should not be focusable</button>
  <button type="button" autofocus>Autofocus</button>
  <button data-core-dialog="close">Close</button>
</dialog>
<dialog id="my-dialog-nested" class="my-dialog" aria-label="andre dialog tittel">
  <h1>Another dialog, triggered inside the first dialog</h1>
  <p>Nunc mi felis, condimentum quis hendrerit sed, porta eget libero.</p>
  <button data-core-dialog="close">Close</button>
</dialog>
<button data-core-dialog="strict-dialog">Open strict dialog</button>
<dialog id="strict-dialog" class="my-dialog" aria-label="første dialog tittel">
  <h1>This is a title</h1>
  <p>Nunc mi felis, condimentum quis hendrerit sed, porta eget libero. Aenean scelerisque ex eu nisi varius hendrerit. Suspendisse elementum quis massa at vehicula. Nulla lacinia mi pulvinar, venenatis nisi ut, commodo quam. Praesent egestas mi sit amet quam porttitor, mollis mattis mi rhoncus.</p>
  <button type="button">This button does nothing</button>
  <button data-core-dialog="close">Close</button>
</dialog>
<div id="docs-react-dialog"></div>
<script>
  coreDialog('#my-dialog', {open: false});
  coreDialog('#my-dialog-nested', {open: false});
  coreDialog('#strict-dialog', {open: false, strict: true});
</script>
<!--demo-->
<div id="jsx-dialog"></div>
<div id="jsx-dialog-strict"></div>
<script type="text/jsx">
  class DialogContainerDemo extends React.Component {
    constructor (props) {
      super(props)
      this.state = {
        open: false,
        contentTitle: 'Dialog for JSX'
      }
      this.toggleDialog = this.toggleDialog.bind(this)
      this.handleToggle = this.handleToggle.bind(this)
    }

    toggleDialog () {
      this.setState({open: !this.state.open})
    }

    handleToggle (event) {
      event.preventDefault()
      this.setState({open: !event.detail.isOpen})
    }

    render () {
      return (
        <div>
          <button onClick={this.toggleDialog}>Open dialog jsx</button>
          <CoreDialog
            className="my-dialog"
            open={this.state.open}
            onToggle={this.handleToggle}
            aria-label="React dialog"
          >
            <h1>{this.state.contentTitle}</h1>
            <p>Nunc mi felis, condimentum quis hendrerit sed, porta eget libero. Aenean scelerisque ex eu nisi varius hendrerit. Suspendisse elementum quis massa at vehicula. Nulla lacinia mi pulvinar, venenatis nisi ut, commodo quam. Praesent egestas mi sit amet quam porttitor, mollis mattis mi rhoncus.</p>
            <button onClick={this.toggleDialog}>Lukk</button>
          </CoreDialog>
        </div>
      )
    }
  }

  class StrictDialogContainerDemo extends React.Component {
    constructor (props) {
      super(props);
      this.state = {
        open: false,
        contentTitle: 'Strict dialog for JSX'
      }
      this.toggleDialog = this.toggleDialog.bind(this)
    }

    toggleDialog () {
      this.setState({open: !this.state.open})
    }

    render () {
      return (
        <div>
          <button data-core-dialog="dialog-jsx">Open strict dialog jsx</button>
          <CoreDialog
            id="dialog-jsx"
            className="my-dialog"
            onToggle={this.handleStrictToggle}
            aria-label="React dialog"
            strict>
            <h1>{this.state.contentTitle}</h1>
            <p>Nunc mi felis, condimentum quis hendrerit sed, porta eget libero. Aenean scelerisque ex eu nisi varius hendrerit. Suspendisse elementum quis massa at vehicula. Nulla lacinia mi pulvinar, venenatis nisi ut, commodo quam. Praesent egestas mi sit amet quam porttitor, mollis mattis mi rhoncus.</p>
            <button data-core-dialog="close">Lukk</button>
          </CoreDialog>
        </div>
      )
    }
  }

  ReactDOM.render(<DialogContainerDemo />, document.getElementById('jsx-dialog'))
  ReactDOM.render(<StrictDialogContainerDemo />, document.getElementById('jsx-dialog-strict'))
</script>

Usage

HTML / JavaScript

<!-- Opening a dialog -->
<!-- By setting the data-core-dialog attribute with a ID reference to an element -->
<!-- we automatically set up a click handler that will open the dialog -->
<!-- Note: you need to initialize core-dialog -->
<button data-core-dialog="my-dialog">Open dialog</button>
<!-- Closing a dialog -->
<dialog id="my-dialog">
  <h1>Title of dialog</h1>
  <p>Some content</p>
  <!-- By setting the data-core-dialog attribute to "close" we automatically -->
  <!-- set up a click handler that will close the dialog -->
  <!-- Note: you need to initialize core-dialog -->
  <button data-core-dialog="close">Close dialog</button>
</dialog>
import coreDialog from '@nrk/core-dialog'

// Initialize a specific component or multiple components
coreDialog(String|Element|Elements, { // Accepts a selector string, NodeList, Element or array of Elements
  open: null,                         // Defaults to true if open is set, otherwise false. Use true|false to force open state
  strict: true|false,                 // Defaults to false. If set to true the dialog will not close on ESC-key nor on click on backdrop
  label: ''                           // Defaults to aria-label if set or an empty string. Should be implemented in order for the dialog to have a label readable by screen readers
})

// Example:
coreDialog('.my-dialog')
coreDialog('.my-dialog', {open: true, label: 'A super dialog'})

React / Preact

import CoreDialog from '@nrk/core-dialog/jsx'

<CoreDialog open={true|false} strict={true|false} onToggle={function(){}} aria-label="Title of dialog">
  <h1>My React/Preact dialog</h1>
  <p>Some content</p>
  <button onClick={closeDialog}></button>
</CoreDialog>

function closeDialog (event) {
  // change open state/props to false
}

Markup

Supporting IE9

If you need @nrk/core-dialog to support IE9, add the following code in your <head> tag:

<!--[if IE 9]><script>document.createElement('dialog')</script><![endif]-->

Elements order

Though not strictly required, the <button> opening a @nrk/core-dialog should be placed directly before the <dialog> itself. This eases the mental model for screen reader users.

Autofocus

If you have form elements inside a @nrk/core-dialog, you can optionally add an autofocus attribute to the most prominent form element. This helps the user navigate quickly when toggle is opened.


Events

document.addEventListener('dialog.toggle', (event) => {
  event.target                // The dialog container element
  event.detail.isOpen         // The current open state the dialog has
  event.detail.willOpen       // The open state that the dialog will get (unless event.preventDefault() is called)
})

Styling

.my-dialog {}                         /* Target dialog in closed state */
.my-dialog[open] {}                   /* Target dialog in open state */
.my-dialog + backdrop {}              /* Target backdrop in open state */
.my-dialog + backdrop[hidden] {}      /* Target backdrop in closed state */

Note : There is a z-index limit for the backdrop at 2000000000. Do not use higher z-index values in your site in order for core-dialog to work properly. The limit exists because some browser extensions, like ghostery have absurdly high z-indexes. The issue is further explained here.


FAQ

Why use <dialog> when it is not supported by all browsers?

There is currently minimal support for the <dialog> element. However, to ensure best accessibility, @nrk/core-dialog uses native functionality whenever possible, and augments with role="dialog" as a fallback. For more information about the dialog element visit the W3C HTML 5.2 specification. For more information about WAI-ARIA practices for the dialog element visit the W3C WAI-ARIA Authoring Practices 1.1

FAQs

Package last updated on 02 Nov 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc