Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A highly accessible, customizable and lightweight dialog

License

NotificationsYou must be signed in to change notification settings

andreasbm/web-dialog

Repository files navigation

Downloads per monthNPM VersionDependenciesContributors

A highly accessible, customizable and lightweight dialog.
Try the dialog yourself atCodepen. Go here to see a demohttps://appnest-demo.firebaseapp.com/web-dialog/.


Building a good dialog is hard - there are many things you might not think about if you try to build one. This dialog has been build using theWAI-ARIA Authoring Practices and follows all of the best practices. This makes the dialog:

  • Accessible - The dialog is accessible. When opening the dialog, the focus is trapped inside the dialog and outside scrolling is blocked. When the dialog is closed, the focus is restored to what it was before opening it. It is also possible to close the dialog pressing the escape key.
  • Works well withShadow DOM - The dialog works very well with Shadow DOM and is therefore super Web Component friendly. Many people don't think about Shadow DOM when they build a dialog - this one has been build with Web Components in mind.
  • Incredible lightweight - The footprint of the dialog is around 2500 bytes gzipped.
  • Customizable - It is easy to customize the dialog with a fewCSS variables or styling the exposedShadow Parts.
  • Works withall frameworks - It exposes aWeb Component that can be used with your favorite framework.
  • Can be nested - The dialogs can spawn on top of each other.

-----------------------------------------------------

➤ Table of Contents

-----------------------------------------------------

➤ Installation

It is recommended that you install the library throughNPM.

$ npm i web-dialog

-----------------------------------------------------

➤ Usage

To use this library you first need to get import the library through code somewhere (import "web-dialog";). After you have done this you'll be able to use theweb-dialog web component. In-between the opening and closing tags you can add whatever content you'd want to show in the dialog.

<web-dialog><span>This is a default dialog!</span></web-dialog>

To open the dialog you will have to add theopen attribute to the element.

<web-dialogopen><span>This is a default dialog!</span></web-dialog>

Alternatively you can set the.open property of the dialog to true through Javascript.

const$dialog=document.querySelector("web-dialog");$dialog.open=true;

When the dialog opens it will look like this.

-----------------------------------------------------

➤ Center the dialog

You probably noticed the dialog is not centered as default. This is because, as default, the dialog uses the container around the element to scroll in instead of using the inside of the dialog. To center the dialog you can add thecenter attribute or set the.center property to true.

<web-dialogcenter><span>This is a default centered dialog!</span></web-dialog>

When opened the dialog will look like this.

-----------------------------------------------------

➤ Sticky header and footer

What about a sticky header and footer? No problem at all. Just make sure to useheader,article andfooter HTML tags for your content and center the dialog. This will style the content in such as way that the footer and header is sticky.

<web-dialogcenter><header><h3>The standard Lorem Ipsum passage</h3></header><article><p>Lorem ipsum dolor sit amet, consectetur adipiscing...</p></article><footer><button>Okay...</button></footer></web-dialog>

To make thing look nice you can add some CSS and apply a bottom border to the header, a top border to the footer and add some padding to the elements. When opened the dialog will look like this.

-----------------------------------------------------

➤ Customize

The dialog can be customized by setting some CSS variables or modifying the shadow parts. You can read about all of the CSS variables you can set and shadow parts you can changehere. Let's say you want to create a fullscreen dialog. Then you could change the following CSS variable to achieve it.

web-dialog {--dialog-container-padding:0;--dialog-border-radius:0;--dialog-max-width:100vw;--dialog-height:100%;--dialog-animation-duration:0;}
<web-dialog><header><h3>The standard Lorem Ipsum passage</h3></header><article><p>Lorem ipsum dolor sit amet, consectetur adipiscing...</p></article><footer><button>Okay...</button></footer></web-dialog>

When opened the dialog will look like this.

-----------------------------------------------------

➤ Events

The dialog can dispatch 3 different events.

  • open - The first event is theopen event which is dispatched when the dialog opens.
  • closing - The second event is theclosing event which is dispatched when the dialog is about to close due to the user clicking on the backdrop or pressing escape. If.preventDefault() is called on this event the dialog won't close.
  • close - The third event is theclose event which is dispatched when the dialog closes. If.result is set on the dialog, the.detail property of theclose event will have the value of the result.

Here's an example on how you'd use the events.

const$dialog=document.querySelector("web-dialog");$dialog.addEventListener("open",()=>{console.log("The dialog opened!");});$dialog.addEventListener("closing",()=>{console.log("The dialog is about to close because the backdrop was clicked or because escape was pressed!");// Don't allow the dialog to closee.preventDefault();});$dialog.addEventListener("close",e=>{console.log("The dialog closed!",e.detail);});

-----------------------------------------------------

openDialog(...)

If you want to use the dialog programmatically you can use theopenDialog(...) function. This function makes sure to append content inside the dialog, adds it to the DOM and removes it when it closes. You can give an object with the following fields to the function.

  • $content - A DOM element that will be placed inside the dialog as content. This can also be a function that takes the dialog and appends the content for the dialog.
  • $container - A DOM element where the dialog will be placed inside. As default this is thebody element.
  • center - Whether the dialog is centered. As default this is false.
  • initialize - A function that returns an instance ofWebDialog. This is smart to overwrite if you for example have extended the WebDialog class and want to open that custom dialog instead.

In it's most simple form you can open a dialog like this:

import{openDialog}from"web-dialog";const$template=document.createElement("template");$template.innerHTML=`  <span>This is some content for the dialog!</span>`;openDialog({$content:$template.content.cloneNode(true)});

When theopenDialog(...) function above is called it will look like this.

TheopenDialog(...) function returns an object with the following two properties.

  • $dialog - The dialog HTML element.
  • resolver - A promise that will resolve with the result of the dialog when closed.

Based on the information above, here's a little more advanced example.

import{openDialog}from"web-dialog";// Create a templateconst$template=document.createElement("template");$template.innerHTML=`  <button data-value="no">No</button>  <button data-value="yes">Yes</button>`;// Open the dialogconst{$dialog, resolver}=openDialog({$content:$template.content.cloneNode(true)});// Attach an event listener that sets the closes the dialog with the result when a button is clicked$dialog.querySelectorAll("button").forEach($button=>$button.addEventListener("click",e=>{constresult=e.target.dataset.value;$dialog.close(result);}));// Wait for the resultconstresult=awaitresolver;// Print the resultconsole.log(`The result was${result}`);

-----------------------------------------------------

➤ lit-html & lit-element

Here's a little trick for you if you uselit-element orlit-html. If you want to quickly open a dialog with some content you can use the render function oflit-html like this.

import{openDialog}from"web-dialog";import{render}from"lit-html";openDialog({$content:$dialog=>render(html`<h3>Do you like this dialog?</h3><button@click="${()=>$dialog.close()}">Umm, yeah!</button>  `,$dialog)});

-----------------------------------------------------

➤ Extend WebDialog

It is totally possible to extend the dialog. The only thing you have to do is define a new class and extend theWebDialog class. Then you can add your custom logic and define a new custom element with your new class. Here's an example of what you could if you for example want a custom dialog that shows an image.

import{WebDialog}from"web-dialog";// Create a template for the content of the dialogconst$template=document.createElement("template");$template.innerHTML=`  <style>    #img {      width: 100%;      height: 400px;      object-fit: cover;    }  </style>  <img />`;// Create a class extending the WebDialog class.classImageDialogextendsWebDialog{// Observe the src attribute so we can react each time it changesstaticgetobservedAttributes(){return["src"];}// Make sure the src property is getting reflected as an attributegetsrc(){returnthis.hasAttribute("src");}setsrc(value){this.setAttribute("src",value);}constructor(){super();// Append the dialog contentthis.$dialog.appendChild($template.content.cloneNode(true));// Get a reference to the img elementthis.$img=this.shadowRoot.querySelector("#img");}// Each time the src attribute changes we set the src of the image elementattributeChangedCallback(name,newValue){switch(name){case"src":this.$img.src=newValue;break;}}}// Remember to define your new custom elementcustomElements.define("image-dialog",ImageDialog);

After you have defined your new dialog you are be able to use it like this.

<image-dialogopencentersrc="https://i.ytimg.com/vi/NCZ0eg1zEvw/maxresdefault.jpg"></image-dialog>

Or this

import{openDialog}from"web-dialog";openDialog({initialize:()=>{const$dialog=newImageDialog();$dialog.src=`https://i.ytimg.com/vi/NCZ0eg1zEvw/maxresdefault.jpg`;$dialog.center=true;return$dialog;}});

When our custom dialog opens it will look like this.

-----------------------------------------------------

➤ Documentation

This section documents theattributes,css variables andslots of the web components this library exposes.

web-dialog

A dialog web component that can be used to display highly interruptive messages.

Properties

PropertyAttributeTypeDescription
centercenterWhether the dialog is centered on the page.
onBackdropClick
onKeyDown
openopenWhether the dialog is opened.
resultR | undefined

Methods

MethodTypeDescription
assertClosing(): anyDispatches an event that, if asserts whether the dialog can be closed.
If "preventDefault()" is called on the event, assertClosing will return true
if the event was not cancelled. It will return false if the event was cancelled.
close(result?: R | undefined): voidCloses the dialog with a result.
didClose(): voidClean up the dialog after it has closed.
didOpen(): voidSetup the dialog after it has opened.
onBackdropClick(): voidCloses the dialog when the backdrop is clicked.
onKeyDown(e: any): voidCloses the dialog when escape is pressed.
show(): voidShows the dialog.

Events

EventDescription
closeThis event is fired when the dialog closes.
closingThis event is fired before the dialog is closed by clicking escape or on the backdrop. The event is cancellable which meansevent.preventDefault() can cancel the closing of the dialog.
openThis event is fired when the dialog opens.

CSS Shadow Parts

PartDescription
backdropBackdrop part.
dialogDialog part.

CSS Custom Properties

PropertyDescription
--dialog-animation-durationDuration of the dialog animation.
--dialog-animation-easingEasing of the dialog animation.
--dialog-backdrop-bgBackground of the backdrop.
--dialog-bgBackground of the dialog.
--dialog-border-radiusBorder radius of the dialog.
--dialog-box-shadowBox shadow of the dialog.
--dialog-colorColor of the dialog.
--dialog-container-paddingPadding of the host container of the dialog.
--dialog-heightHeight of the dialog.
--dialog-max-heightMax height of the dialog.
--dialog-max-widthMax width of the dialog.
--dialog-overflow-xOverflow of the x-axis.
--dialog-overflow-yOverflow of the y-axis.
--dialog-paddingPadding of the dialog.
--dialog-widthWidth of the dialog.
--dialog-z-indexZ-index of the dialog.

-----------------------------------------------------

➤ Contributors

Andreas MehlsenYou?
Andreas MehlsenYou?

-----------------------------------------------------

➤ License

Licensed underMIT.


[8]ページ先頭

©2009-2025 Movatter.jp