@superkoders/modal
v2.1.1
Published
Fancybox like modal
Downloads
730
Readme
Modal window/popup which main purpose is to open as image galery. But it can handle also other type of content like Youtube, Vimeo or HTML5 videos, iframes, custom HTML content or HTML content from some existing element on the page. It can recognize type of media from the source url. If it is not possible to recognize media type, default type is iframe. You can force media type by medium
parameter (see examples below).
Installing
Using npm
$ npm install @superkoders/modal
Using yarn
$ yarn add @superkoders/modal
How to use
There are two methods exported: initModal
and createModal
. First one adds click listeners to each element in given context which matches modalSelector
option (by default '[data-modal]'
). It returns array of modal instances created. Second one is for creating custom modal instance.
initModal: (options: SKModalOptions) => SKModal[]
import { initModal } from '@superkoders/modal';
// use default options
initModal();
// or set some custom options
initModal({
customWrapperClass: 'my-custom-modal',
closeOnBgClick: true,
});
How to create modal triggers in your HTML code
The easiest way is to do it with an a
tag using its href
attribute as an url for modal.
<a href="https://www.youtube.com/watch?v=RhMYBfF7-hE" data-modal>Open Youtube video in the modal</a>
If you want to use some other element like button
, you need to specify url in the data-modal
attribute.
<button data-modal='{"url": "https://www.youtube.com/watch?v=RhMYBfF7-hE"}'>Open Youtube video in the modal</button>
createModal: (items: SKModalItem | SKModalItem[], options?: Partial<SKModalOptions>) => SKModal
In this case, there are no triggers which open modal. Once you create an instance, you need to open it by yourself. Also you need to pass modal items, where only mandatory property is url
. In our example below the modal will have two items, first is some image, second is some video.
import { createModal } from '@superkoders/modal';
const items = [
{
url: 'url/to/some/image.jpg'
},
{
url: 'url/to/some/video.mp4'
}
]
// create instance
const customModal = createModal(items, {
customWrapperClass: 'my-custom-modal',
closeOnBgClick: true,
});
// open modal
customModal.methods.open();
// go to next slide
customModal.methods.next();
// close modal
customModal.methods.close();
Documentation
Modal options SKModalOptions
These options you can adjust during initialization.
context: Element | Document
Context element, in which to search for modal items (triggers)
Default value: document
parentElement: Element
Element, which is used as a parent for modal element in DOM
Default value: document.body
modalSelector: string
Element selector, which is used for modal triggers
Default value: '[data-modal]'
closeSelector: string
Element selector, which is used to close the modal
Default value: '.js-modal-close'
customWrapperClass: string
Custom CSS class, which is added to the modal element
Default value: undefined
infinite: boolean
It determines if modal items are shown in a loop
Default value: false
closeOnBgClick: boolean
It determines if modal will close after background click
Default value: undefined
plugins: SKModalPlugin[]
Plugins array to initialize
Default value: undefined
hideNav: boolean
It determines if the navigation (arrows, bullets) is hidden or not
Default value: undefined
customData: any
Any data which you can use for example in plugins
Default value: undefined
closeIcon: string
String which represents an icon for close button, it can be also HTML code
Default value: '×'
prevIcon: string
String which represents an icon for previous button, it can be also HTML code
Default value: '←'
nextIcon: string
String which represents an icon for next button, it can be also HTML code
Default value: '→'
loadIcon: string
String which represents an icon for loader, it can be also HTML code
Default value: '<span class="b-modal__loader-icon"><span>↺</span></span>'
removeOnClose: boolean
It determines if modal element will be removed from DOM after close
Default value: false
enableFocusTrap: boolean
Enables or disables focus trap.
Default value: true
focusTrapOptions: FocusTrapOptions
Focus trap custom options. See Focus trap package page for more info Default value:
{
allowOutsideClick: true,
}
useSwipe: boolean
Enables or disables swipe slide change on touch devices.
Default value: true
ariaLabel: string
Modal title for assistive technologies.
Default value: undefined
buildStructure: (modal: Element, fragments: SKModalFragments) => void
Method which builds the modal HTML structure, not really necessary to change if you use grid for CSS
Default value:
(modal, {
ariaLabel,
header,
titleElem,
descElem,
content,
prevElem,
nextElem,
navElem,
loader,
bg,
}) => {
const wrapper = document.createElement('div');
wrapper.classList.add('b-modal__wrapper');
if (ariaLabel) {
modal.setAttribute('aria-labelledby', ariaLabel.id);
modal.appendChild(ariaLabel);
}
wrapper.appendChild(header);
wrapper.appendChild(titleElem);
wrapper.appendChild(descElem);
wrapper.appendChild(content);
wrapper.appendChild(prevElem);
wrapper.appendChild(nextElem);
wrapper.appendChild(navElem);
modal.appendChild(wrapper);
modal.appendChild(loader);
modal.appendChild(bg);
}
headerTpl: (options?: SKModalOptions) => string
Method for header template
Default value:
(options) => `
<button type="button" class="b-modal__close ${ModalClasses.CLOSE}">
<span class="b-modal__close-text u-vhide">Close</span>
${options.closeIcon}
</button>
`
titleTpl: (text: string) => string
Method for title template
Default value:
(text: string) => `<h3>${text}</h3>`
descTpl: (text: string) => string
Method for description template
Default value:
(text: string) => `<p>${text}<p>`
prevTpl: (options?: SKModalOptions) => string
Method for previous button template
Default value:
(options) => `<button type="button" class="b-modal__prev-btn ${ModalClasses.PREV_TRIGGER}">${options.prevIcon}</button>`
nextTpl: (options?: SKModalOptions) => string
Method for next button template
Default value:
(options) => `<button type="button" class="b-modal__next-btn ${ModalClasses.NEXT_TRIGGER}">${options.nextIcon}</button>`
navTpl: (items: SKModalItem[]) => string
Method for navigation (bullets) template
Default value:
(items) =>
items
.map((_item, index) => `<span class="b-modal__nav-item ${ModalClasses.NAV_TRIGGER}" data-modal-index="${index}"></span>`)
.join('')
loaderTpl: (options?: SKModalOptions) => string
Method for loader template
Default value:
(options) => `<span class="b-modal__loader-icon"><span>${options.loadIcon}</span></span>`
imageLoader: (src: string) => Promise<Node>
Method which is used for loading images
Default value:
(src) => {
return new Promise((resolve, reject) => {
let img = new Image();
img.addEventListener('load', () => resolve(img));
img.addEventListener('error', () => {
reject(new Error(`Failed to load image with src: ${src}`));
});
img.draggable = false;
img.src = src;
});
}
fetchLoader: (url: string, element?: Element) => Promise<string>
Method which is used for fetching content from a server
Default value:
async (url) => await fetch(url).then((response) => response.text())
onModalOpen: (event?: Event, data?: { id: number }) => void
Handler, which runs after modal is opened
Default value: undefined
onModalClose: (event?: Event, data?: { id: number }) => void
Handler, which runs after modal is closed
Default value: undefined
onModalContentLoaded: (event?: Event, data?: { modal: SKModal }) => void
Handler, which runs after modal content is loaded
Default value: undefined
onModalSlideChanged: (event?: Event, data?: { page: number }) => void
Handler, which runs after modal slide has changed
Default value: undefined
Modal items (SKModalItem)
All these parameters is possible to add to data-modal
attribute. In case of createModal
, these are properties of the modal item object.
url: string | string[]
Media url. In case of images, it can be an array. Then more images are shown on one slide.
medium: ModalMedium
Media type. Posible values in ModalMedium
enum exported from @superkoders/modal
title: string
Text, which will appear in modal title
desc: string
Text, which will appear in modal description
gallery: string
Gallery key, which is used for grouping items into one modal. If it is undefined, each modal uses its own popup.
modalClass: string
CSS class which will be aplied for modal wrapper element, when modal is opened.
[key: string]: any
It is possible to add more custom parameters, which can be used in plugins for example.
Plugins (SKModalPlugin)
Plugins enable another modal customization. It has these three parameters:
init: (modal: SKModal) => void
Init method
destroy: (modal: SKModal) => void
Destroy method, it runs after modal redraw (if reInitOnRedraw
is set to true
) or after modal destroy
reInitOnRedraw: boolean
It determines, if plugin should be reinitialized after modal redraw.
Plugin example
my-plugin.js
export const myPlugin = {
init: (modal) => {
// do some stuff like add event listeners or add some elements to DOM
},
destroy: (modal) => {
// use when you need to remove some listeners or remove some elements from DOM
},
reInitOnRedraw: true,
}
modal.js
import { initModal } from '@superkoders/modal';
import { myPlugin } from './my-plugin.js';
initModal({
plugins: [myPlugin]
});
Version 2.0 major changes
- The wrapper element is now a
dialog
element. It has better accessibility. You can check browser support here. If you need to support browser wich don't supportdialog
element, you can use older version (1.7.0). scroll-lock
npm package has been removed. We prefer to use CSS pure solution. It can be done by addingscrollbar-gutter: stable
onhtml
element andoverflow: clip
on body element. For this purpose, classis-modal-open
is added tobody
when dialog is opened. If you prefer to usescroll-lock
, you can use older version (1.7.0)- The
dialog
element comes with its own focus trap functionality. This however did not meet our requirements, so we are still usingfocus-trap
npm package for this. If you prefer to use nativedialog
focus trap functionality, you can disable focus trap withenableFocusTrap
option (set it tofalse
).
Troubleshooting
@superkoders/modal
uses some functionality from @superkoders/sk-tools
. If you are already using @superkoders/sk-tools
on your project, check if the version is at least 1.4.0
. If not, you need to update the package.