ldCover

Nested, Promise-based Dialog in Vanilla JS


Try Me
GitHub

Dialog Made Easy

ldCover is a JavaScript library that helps you control the state of your dialog / popup with Promise.

Download

ldCover is available for downloading in its Github Repo. Or, you can get it directly with following links:

You could also use ldCover directly via CDN like jsDelivr:

Or, via npm:

npm i ldCover

Basic Usage

First include required JS and CSS files ( could be found in ldCover's Github Repo ). Then, prepare a modal root node, and use it to create an ldCover object:

<!-- 1. include required files --> <link rel="stylesheet" type="text/css" href="ldcv.css"/> <script src="ldcv.js"></script> <!-- 2. prepare modal root node --> <div id="my-modal" class="ldcv">CLICK TO DISMISS</div> <!-- 4. trigger modal by toggle --> <div onclick="ldcv.toggle()">Try Me</div>

/* 3. create ldCover object with the modal node */ var ldcv = new ldCover({ root: "#my-modal" });
Try Me
CLICK TO DISMISS

ldCover is designed with following features:

Vanilla JS

ldCover is implemented with Vanilla JS. There is no single external dependency which makes it easy to maintain and as light as possible - file size only about 6KB in total.

Framework Agnostic

ldCover is independent to any JS libraries or frameworks. Thus, it's quite easy to integrate it into your project regardless which framework you use. It will work on React, Vue, Angular or any JS frameworks.

Promise Based

With promise, you can toggle modals in asynchronous way, e.g., wait for user event, polling for server response... Everything made simple with promise.

Nesting Supported

ldCover automatically manages z-index of your modal which makes it easy and useful working with complicated workflows that might involves multiple dialogs.

While ldCover is framework agnostic, we will use Bootstrap 4 in following examples. Bootstrap is not necessary so you can use your favorite framework.

Basic Dialog

ldCover uses 3-Level DOM structure to define a dialog, with classNames "ldcv", "base", and "inner":

<div class="ldcv"> <!-- root of the dialog --> <div class="base"> <!-- optional. control the position of dialog --> <div class="inner"> <!-- dialog body. transition happens here --> your content here... </div> </div> </div>

Roles of each node are:

Here is a simple example of dialog with only one line of text:

<div class="ldcv"> <div class="base"> <div class="inner"> Hello World! </div> </div> </div> <div onclick="ldcv.toggle()">Show Dialog</div>

var ldcv = new ldCover({root: ".ldcv"}); ldcv.toggle();
Hello World!
Show Dialog

Basic Styling

You can customize your own dialog by styling the inner element. In following examples, we will use bootstrap 4's card component to style our dialog:

<div class="ldcv"> <div class="base"> <div class="inner card"> <div class="card-body"> Hello World! </div> </div> </div> </div> <div onclick="ldcv.toggle()">Show Dialog</div>
var ldcv = new ldCover({root: ".ldcv"});
Hello World!
Show Dialog

Toggle / Dismiss

As shown in previous demo, you can call toggle() to toggle on/off the target dialog. Additionally, you can set the data-ldcv-set attribute of any element inside the root element to transfer that element into a close button:

<div class="ldcv"> <div class="base"> <div class="inner card"> <div class="card-body"> Hello World! <hr> <div class="btn btn-primary" data-ldcv-set=""> Close </div> </div> </div> </div> </div> <div onclick="ldcv.toggle()">Show Dialog</div>

var ldcv = new ldCover({root: ".ldcv"});
Hello World!
Close
Show Dialog

User Response

Value of data-ldcv-set could actually be used to determine how users respond to your dialog. To get users response, toggle dialog with get() instead of toggle(); get() returns a Promise which is resolved with the data-ldcv-set attribute for the clicked element:

<div class="ldcv"> <div class="base"> <div class="inner card"> <div class="card-body"> <h3>What's Your Choice?</h3> <hr> <div class="btn btn-primary mr-2" data-ldcv-set="Yes"> Yes </div> <div class="btn btn-primary" data-ldcv-set="No"> No </div> </div> </div> </div> </div> <div onclick="prompt()">Show Dialog</div>

var ldcv = new ldCover({root: ".ldcv"}); function prompt() { ldcv.get().then(function(ret) { alert("User chooses: " + ret); }); }

What's Your Choice?


Yes
No
Show Dialog

Or, if you prefer to handle events by yourself, you can invoke set() to manually set the value for resolving Promise:

<div class="ldcv"> <div class="base"> <div class="inner card"> <div class="card-body"> <h3>Click When You Are Ready</h3> <hr> <div class="btn btn-primary" onclick="finish()"> I'm Ready </div> </div> </div> </div> </div> <div onclick="prompt()">Show Dialog</div>

var ldcv = new ldCover({root: ".ldcv"}); function prompt() { var start = Date.now(); ldcv.get().then(function(ret) { alert("User wait " + (+ret - Date.now()) + " ms to respond."); }); } function finish() { ldcv.set(Date.now()); }

Click When You Are Ready


I'm Ready
Show Dialog

Customization

In following section we'll demonstrate how you can change the ldCover's behavior or even extend it.

Dimension

You can manually adjust size of your dialog by changing style of .inner element, but we also provide 3 CSS class for quickly setting dialog's size:

  • md: 720px x 500px
  • lg: 960px x 700px
  • full: fullscreen
<div class="ldcv"> <div class="base"> <!-- set width and height manually --> <div class="inner" style="width:600px;height:200px"> ... </div> </div> </div>
<!-- use predefined class --> <div class="ldcv full"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Effects on Transition

ldCover is shipped with some prebuilt effects on transition. To use them, include an additional CSS file ldcv.effects.css and add the class for desired effects in the root element. Following are classes for these effects, you can preview the effects by clicking corresponding buttons:

ldcv-scale

Effect Preview


Put "ldcv-scale" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-scale"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-zoom

Effect Preview


Put "ldcv-zoom" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-zoom"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-vortex

Effect Preview


Put "ldcv-vortex" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-vortex"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-slide-rtl

Effect Preview


Put "ldcv-slide-rtl" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-slide-rtl"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-slide-ltr

Effect Preview


Put "ldcv-slide-ltr" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-slide-ltr"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-slide-ttb

Effect Preview


Put "ldcv-slide-ttb" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-slide-ttb"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-slide-btt

Effect Preview


Put "ldcv-slide-btt" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-slide-btt"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-flip-h-left

Effect Preview


Put "ldcv-flip-h-left" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-flip-h-left"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-flip-h-right

Effect Preview


Put "ldcv-flip-h-right" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-flip-h-right"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-flip-v-top

Effect Preview


Put "ldcv-flip-v-top" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-flip-v-top"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-flip-v-bottom

Effect Preview


Put "ldcv-flip-v-bottom" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-flip-v-bottom"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.
ldcv-fade

Effect Preview


Put "ldcv-fade" in the root element's class will do the trick, for example:

<div class="ldcv ldcv-fade"> <div class="base"> <div class="inner"> ... </div> </div> </div>

Got it.

Custom Transition

If you don't like the built-in effects, you can also write your own class or use external libraries. To make your own effect, simply define your own class with two states ( with / without active class ), and styling the inner class:

.ldcv-my-effect > .base > .inner { transform: translate(100%,0) scale(10); opacity: 0; } .ldcv-my-effect.active > .base > .inner { transform: translate(0,0) scale(0); opacity: 1; }

<div class="ldcv ldcv-my-effect"> ... </div>
Show Me

Hello World!


Close

Custom Animation

If you want to use CSS Animation instead of CSS Transition to animate your dialog, we also provide the animation attribute that helps you to toggle desired classes when dialog changes it's state; here we use transition.css as an example:

var ldcv = new ldCover({ root: "#my-ldcv", animation: "ld ld-bounce-in" });

Custom Animation Rocks!


transition.css is available here. Go visit for more information about how to use it.

Close

CSS Animation grants you more powerful and subtle controls to your dialog animation, and transition.css provides about 40 different prebuilt animations for you to choose. If you are interested in using transition.css, follow this link directly to get more detail about how to use it.

Configurations

Except the configurations described above, you can also alter ldCover's behavior by following configurations:

APIs

a ldCover instance exposes following API functions:

Browser Compatibility

ldCover is compatible with all modern browsers. However, it uses two modern web features that fails in IE older than version 11:

Fortunately you can easily find polyfills for both classList and Promise to support these browsers.

License

ldCover is released under MIT License. License file can be found under ldCover's GitHub repository.

Comments

Any questions or suggestion? Feel free to leave comment here. :)

loader

Hi There!

It's a Promise-based Dialog.


What's Promise-based?
Just Quit

What's Promise-based?

Say you have a chain of modals to show. You can write like this:

modal1.get().then(function(ret) { return modal2.get(); }).then(function(ret) { return modal3.get(); });

Great. Now how do I break the chain?
Just Quit

Chain Breaking

Promise.reject is what you need. Handle your own returned rejection does all the trick.

modal1.get().then(function(ret) { return ret ? modal2.get() : Promise.reject(new Error("interrupted")); }).then(function(ret) { return modal3.get(); }).catch(function() { /* handle by case */ });

But How about.. Dialog over Dialog?
Just Quit

Auto Nesting

ldCover auto z-indexing your dialogs. Simiply toggle your dialogs in desired order will do:

modal1.get().then(function(ret) { return modal2.get(); }).then(function() {; return modal3.get(); }); /* resolve returned promise by invoking "set" */ function ShowMeClicked() { modal4.get().then(function() { modal3.set("done"); }); }
Show Me.
Just Quit

Here We Go.

This dialog popups over the last one you just clicked.


I Want More
Got it. Thanks!

Here We Go.

Just another dialog over all of them.


Got it. Thanks!
Things don't work?
It might be AdBlock. Why?
By continuing to browse, you agree to our use of cookies.
For more details please check our privacy policy.
Details
OK

loading.io loader

Loading.io is brought to you by:
PlotDB Ltd. brand logo / 見聞科技有限公司 VAT No. 52518929

Service for making ajax loaders / loading gifs / preloaders and animated icons, live background, animated text in GIF / SVG / APNG / CSS.

Customer Service: [email protected]
LOADING.IO