From 2949a0f72e2fe01d1454659df02fafaaf70e2679 Mon Sep 17 00:00:00 2001 From: Alexandrshy Date: Mon, 22 Jun 2020 08:35:19 +0400 Subject: [PATCH] feat: added the ability to block the scroll, added the open and close methods by the selector --- src/consts.ts | 5 ++++ src/index.ts | 82 ++++++++++++++++++++++++++++++++++++++++++++++----- src/types.ts | 13 ++++++-- 3 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/consts.ts b/src/consts.ts index 25ca383..c271cac 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -2,3 +2,8 @@ export const ATTRIBUTES = { OPEN: 'data-keukenhof-open', CLOSE: 'data-keukenhof-close', }; + +export const SCROLL_STATE = { + DISABLE: 'disable', + ENABLE: 'enable', +} as const; diff --git a/src/index.ts b/src/index.ts index 02a907b..da2fb1c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import {ConfigType, ModalType, KeukenhofType} from './types'; -import {ATTRIBUTES} from './consts'; +import {ATTRIBUTES, SCROLL_STATE} from './consts'; export const Keukenhof = ((): KeukenhofType => { /** @@ -10,11 +10,16 @@ export const Keukenhof = ((): KeukenhofType => { openAttribute: string; closeAttribute: string; openClass: string; + scrollBehavior: { + isDisabled: boolean; + container: string; + defaultValue: string; + }; /** * Modal constructor * - * @param {ConfigType} param - config + * @param {ConfigType} param - Config */ constructor({ selector = '', @@ -22,11 +27,18 @@ export const Keukenhof = ((): KeukenhofType => { openAttribute = ATTRIBUTES.OPEN, closeAttribute = ATTRIBUTES.CLOSE, openClass = 'isOpen', + scrollBehavior = {}, }: ConfigType) { this.$modal = document.querySelector(selector); this.openAttribute = openAttribute; this.closeAttribute = closeAttribute; this.openClass = openClass; + this.scrollBehavior = { + isDisabled: true, + container: 'body', + defaultValue: 'visible', + ...scrollBehavior, + }; this.registerNodes(triggers); @@ -36,7 +48,7 @@ export const Keukenhof = ((): KeukenhofType => { /** * Add handlers for clicking on elements to open related modal windows * - * @param {Array} nodeList - list of elements for opening modal windows + * @param {Array} nodeList - List of elements for opening modal windows */ registerNodes(nodeList: HTMLElement[]) { nodeList @@ -49,6 +61,7 @@ export const Keukenhof = ((): KeukenhofType => { */ open() { this.$modal?.classList.add(this.openClass); + this.changeScrollBehavior(SCROLL_STATE.DISABLE); this.addEventListeners(); } @@ -57,9 +70,20 @@ export const Keukenhof = ((): KeukenhofType => { */ close() { this.$modal?.classList.remove(this.openClass); + this.changeScrollBehavior(SCROLL_STATE.ENABLE); this.removeEventListeners(); } + /** + * Close modal window by selector + * + * @param {string} selector - Modal window selector to close + */ + closeBySelector(selector: string) { + this.$modal = document.querySelector(selector); + if (this.$modal) this.close(); + } + /** * Click handler * @@ -84,6 +108,27 @@ export const Keukenhof = ((): KeukenhofType => { this.$modal?.removeEventListener('touchstart', this.onClick); this.$modal?.removeEventListener('click', this.onClick); } + + /** + * Change scroll behavior + * + * @param {string} value - Scroll state value + */ + changeScrollBehavior(value: 'disable' | 'enable') { + if (!this.scrollBehavior.isDisabled) return; + const element = document.querySelector(this.scrollBehavior.container); + if (!element) return; + switch (value) { + case SCROLL_STATE.DISABLE: + element.setAttribute('style', 'overflow: hidden;'); + break; + case SCROLL_STATE.ENABLE: + element.setAttribute('style', `overflow: ${this.scrollBehavior.defaultValue};`); + break; + default: + break; + } + } } let modal: ModalType; @@ -91,9 +136,9 @@ export const Keukenhof = ((): KeukenhofType => { /** * Create a map for registering modal windows * - * @param {Array} nodeList - list of items - * @param {string} attribute - selector for opening - * @returns {object} - nodes map + * @param {Array} nodeList - List of items + * @param {string} attribute - Selector for opening + * @returns {object} - Nodes map */ const createRegisterMap = (nodeList: HTMLElement[], attribute: string) => { return nodeList.reduce((acc: {[key: string]: HTMLElement[]}, element: HTMLElement): { @@ -107,6 +152,29 @@ export const Keukenhof = ((): KeukenhofType => { }, {}); }; + /** + * Open modal window by selector + * + * @param {string} selector - Modal window selector + * @param {ConfigType} config - Modal window configuration + */ + const open = (selector: string, config?: ConfigType) => { + const options = config || {}; + if (modal) modal.removeEventListeners(); + modal = new Modal({...options, selector}); + modal.open(); + }; + + /** + * Close modal + * + * @param {string} selector - Modal window selector + */ + const close = (selector?: string) => { + if (!modal) return; + selector ? modal.closeBySelector(selector) : modal.close(); + }; + /** * Initialize modal windows according to markup * @@ -125,7 +193,7 @@ export const Keukenhof = ((): KeukenhofType => { } }; - return {init}; + return {init, open, close}; })(); window.Keukenhof = Keukenhof; diff --git a/src/types.ts b/src/types.ts index 6465ed3..1de583f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,13 +4,22 @@ export type ConfigType = { openAttribute?: string; closeAttribute?: string; openClass?: string; + scrollBehavior?: { + isDisabled?: boolean; + container?: string; + defaultValue?: string; + }; }; export type ModalType = { - open: (event: Event) => void; - close: (event: Event) => void; + open: (event?: Event) => void; + close: (event?: Event) => void; + removeEventListeners: () => void; + closeBySelector: (selector: string) => void; }; export type KeukenhofType = { init: (config?: ConfigType) => void; + open: (selector: string, config?: ConfigType) => void; + close: (selector?: string) => void; };