npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

moodal

v0.1.3

Published

A pure JavaScript library for modal dialog.

Downloads

804

Readme

Moodal

A pure JavaScript library for modal dialog.

NPM

npm version

Get Started

1. Install

Install from NPM

npm install moodal --save
# or using yarn
yarn add moodal
// import Moodal js
import Moodal from 'moodal';

// import required style
import 'moodal/lib/css/moodal-core.css';

Use CDN

<script
  src="https://unpkg.com/moodal/lib/standalone/moodal.min.js"
  defer
></script>
<link
  rel="stylesheet"
  href="https://unpkg.com/moodal/lib/css/moodal-core.css"
/>

Use ES modules in browser.

<script type="module" src="https://unpkg.com/moodal/lib/esm/index.mjs"></script>
<link
  rel="stylesheet"
  href="https://unpkg.com/moodal/lib/css/moodal-core.css"
/>

2. Add markup

  • [data-moodal-container] element is requied. And this shoud be left empty. (will be rewrited innerHTML)
  • [data-moodal-close] elements can be anywhere. The modal is close on it clicked.
<div class="c-moodal" tabindex="-1" aria-hidden="true">
  <div class="c-moodal__bg"></div>
  <div class="c-moodal__loader">...Loading</div>
  <div class="c-moodal__container">
    <!-- close modal on `data-moodal-close` element clicked -->
    <div class="c-moodal__overlay" data-moodal-close></div>
    <div class="c-moodal__inner">
      <div class="c-moodal__body">
        <button class="c-moodal__close" type="button" data-moodal-close>
          Close
        </button>
        <div
          class="c-moodal__content"
          role="dialog"
          aria-modal="true"
          data-moodal-container
        >
          <!-- Will be appended content here -->
        </div>
      </div>
    </div>
  </div>
</div>

Minimum

<div class="c-moodal" tabindex="-1" aria-hidden="true">
  <div class="c-moodal__container">
    <div class="c-moodal__inner">
      <div class="c-moodal__body">
        <div
          class="c-moodal__content"
          role="dialog"
          aria-modal="true"
          data-moodal-container
        ></div>
      </div>
    </div>
  </div>
</div>

3. Initialize Core

new Moodal( wrapperElement: string|HTMLElement, <options>);

// Init Core
const myModal = new Moodal('.c-moodal'); // selector or HTMLElement
// Init Core with options
const myModal = new Moodal('.c-moodal', {
  noBackgroundScroll: true,
  backgroundElement: document.querySelector('.page-wrapper'),
  waitContentLoaded: true,
  stateClasses: {
    isVissible: 'is-vissible',
    isLoading: 'is-loading',
  },
});

4. Add Controller

moodal.addController(<params>)

  • Example 1: Get content from DOM element in the page.
<!-- controller -->
<button type="button" data-moodal-anchor="myContent">
  Show Modal of `myContent`
</button>
<!-- template for content -->
<template id="myContent" style="display:none;">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,...</p>
</template>
const modalCtrl = myModal.addController({
  controllerAttr: 'data-moodal-anchor',
  getContent: (trigger) => {
    // `trigger` is value of attribute `data-moodal-anchor`.
    const targetEl = document.getElementById(trigger);
    if (!targetEl) return;
    const content = document.createElement('div');
    content.innerHTML = targetEl.innerHTML;
    // Must return a HTMLElement
    return content;
  },
});

// You can show/hide modal by JavaScript
modalCtrl.show('myContent');
modalCtrl.hide();
  • Example 2: Get content from page by fetch
<!-- controller -->
<button data-moodal-ajax="target.html">Show Modal of `target.html`</button>
const modalCtrlAjax = myModal.addController({
  controllerAttr: 'data-moodal-ajax',
  getContent: async (trigger) => {
    const response = await fetch(trigger, {
      method: 'GET',
    });
    const data = await response.text();
    const wrapper = document.createElement('div');
    wrapper.innerHTML = data;
    const content = wrapper.querySelector('article');
    if (!content) {
      throw new Error('No Content!');
    }
    return content;
  },
});

5. Styling

No theme styles is included in this library.
You need to add the theme css yourself.

.c-moodal__bg {
  background-color: rgba(0, 0, 0, 0.7);
}
.c-moodal__inner {
  padding-top: 60px;
  padding-bottom: 60px;
}
.c-moodal__body {
  border-radius: 6px;
  padding: 40px;
  background-color: #fff;
}

Life cycle

life cycle diagram


Core Params

| Param Name | Type | Default | Desc | | ----------------------- | ------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | containerSelector | string | "[data-moodal-container]" | Selector for the element appended content | | hideOnClickSelector | string | "[data-moodal-close]" | Selector for elements that close modal when clicked | | noBackgroundScroll | boolean | false | if true, fix scrolling element | | backgroundElement | HTMLElement | undefined | The element you want to stop scrolling. ex. document.querySelector(".page-wrapper") * require if noBackgroundScroll is true | | waitContentLoaded | boolean | true | if true, the modal is shown after <img> or <iframe> element is loaded. | | stateClasses | Object | | Classes for showing / loading state | | stateClasses.isVissible | string | string[] | is-vissible | Class on showing modal | | stateClasses.isLoading | string | string[] | is-loading | Class on loading modal | | logLevel | number | 2 | 0 = off, 1 = error, 2 = warning, 3 = info, 4 = debug | | enableFocusTrap | boolean | true | Trap focus within a modal container on showing | | hideByEscKey | boolean | true | Hide modadal using the ESC Key |

Controller Params

myModal.addController({
  getContent: (trigger) => {
    // You must make content element form `trigger`
    // ...some code
    return content; // return HTMLElement
  },
  controllerAttr: 'data-modal-control',
});

| Param Name | Type | Default | Desc | | ----------------- | ---------------------------------------------------------- | ------------------------------ | --------------------------------------------------- | | getContent | (trigger: string) => Promise<HTMLElement> | HTMLElement | undefind * required | Get the content(HTMLElement) from trigger argment | | controllerAttr | string | "" | Data attribute name for button elements. | | waitContentLoaded | boolean | initialParam.waitContentLoaded | Overide the core option | | manualShow | boolean | false | if true, you need show the modal manualy |

Lifecycle Hooks

myModal.addController({
    getContent: (target)=> {
        ...
    },
    beforeAppend: (context) => {
        // context argment is object  { content: HTMLElement, trigger:string }
        console.log('on before append:',context);
    },
    afterAppend: ({content,trigger}) => {
        // if this return `Promise`, proccess wait for resolve.
       return new Promise((resolve, rejects) => {
           console.log('content:',content,'trigger:',trigger);
            setTimeout(() => {
                console.log('1000ms later after appending');
                resolve();
            }, 1000);
        });
    }

})

Hooks

| Hook Name | Type | Desc | | ------------ | ------------------------------------- | --------------------------------- | | beforeAppend | (context) => Promise<void> | void; | Hook before appending the content | | afterAppend | (context) => Promise<void> | void; | Hook after appending the content | | beforeShow | (context) => Promise<void> | void; | Hook before showing the modal | | afterShow | (context) => Promise<void> | void; | Hook after showing the modal | | beforeHide | (context) => Promise<void> | void; | Hook before hiding the modal | | afterHide | (context) => Promise<void> | void; | Hook after hiding the modal |

Filter

| Hook Name | Type | Desc | | ---------------- | ------------------------------------------------------------------------ | --------------------------------------------------- | | contentCreated() | (content: HTMLElement) => HTMLElement | Promise<HTMLElement> | void; | Filtering the content before beforeAppend running |


Browser support

Moodal is using Promose. Can I use
If you need support legacy browser like IE11, use polyfill


License

MIT