UNPKG

phonon

Version:

Phonon is an open source HTML, CSS and JavaScript agnostic framework that allows to create a website or a hybrid Web app.

431 lines (419 loc) 16.9 kB
/*! * Accordion v2.0.0-alpha.1 (https://github.com/quark-dev/Phonon-Framework) * Copyright 2015-2019 qathom * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ 'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var Util = _interopDefault(require('../util.js')); /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var Component = (function () { function Component(name, defaultProps, props) { var _this = this; this.template = ''; this.id = null; this.eventHandlers = []; this.registeredElements = []; this.name = name; var element = typeof props.element === 'string' ? document.querySelector(props.element) : props.element; var config = {}; if (element) { var dataConfig = Util.Selector.attrConfig(element); if (dataConfig) { config = dataConfig; } } this.defaultProps = defaultProps; this.props = Object.assign(defaultProps, config, props, { element: element }); this.id = this.uid(); this.elementListener = function (event) { return _this.onBeforeElementEvent(event); }; this.setEventsHandler(); } Component.prototype.setTemplate = function (template) { this.template = template; }; Component.prototype.getTemplate = function () { return this.template; }; Component.prototype.getElement = function () { return this.getProp('element') || null; }; Component.prototype.setElement = function (element) { this.props.element = element; }; Component.prototype.getId = function () { return this.id; }; Component.prototype.uid = function () { return Math.random().toString(36).substr(2, 10); }; Component.prototype.getName = function () { return this.name; }; Component.prototype.getProps = function () { return this.props; }; Component.prototype.getProp = function (name) { var defaultValue = this.defaultProps[name]; return typeof this.props[name] !== 'undefined' ? this.props[name] : defaultValue; }; Component.prototype.setProps = function (props) { var componentProps = Object.assign({}, props); this.props = Object.assign(this.props, componentProps); }; Component.prototype.setProp = function (name, value) { if (typeof this.props[name] === 'undefined') { throw new Error('Cannot set an invalid prop'); } this.props[name] = value; }; Component.prototype.registerElements = function (elements) { var _this = this; elements.forEach(function (element) { return _this.registerElement(element); }); }; Component.prototype.registerElement = function (element) { element.target.addEventListener(element.event, this.elementListener); this.registeredElements.push(element); }; Component.prototype.unregisterElements = function () { var _this = this; this.registeredElements.forEach(function (element) { _this.unregisterElement(element); }); }; Component.prototype.unregisterElement = function (element) { var registeredElementIndex = this.registeredElements .findIndex(function (el) { return el.target === element.target && el.event === element.event; }); if (registeredElementIndex > -1) { element.target.removeEventListener(element.event, this.elementListener); this.registeredElements.splice(registeredElementIndex, 1); } else { console.error('Warning! Could not remove element:' + ' ' + (element.target + " with event: " + element.event + ".")); } }; Component.prototype.triggerEvent = function (eventName, detail, objectEventOnly) { var _this = this; if (detail === void 0) { detail = {}; } if (objectEventOnly === void 0) { objectEventOnly = false; } var eventNameObject = eventName.split('.').reduce(function (acc, current, index) { if (index === 0) { return current; } return acc + current.charAt(0).toUpperCase() + current.slice(1); }); var eventNameAlias = "on" + eventNameObject .charAt(0).toUpperCase() + eventNameObject.slice(1); var props = this.getProps(); this.eventHandlers.forEach(function (scope) { if (typeof scope[eventNameObject] === 'function') { scope[eventNameObject].apply(_this, [detail]); } if (typeof scope[eventNameAlias] === 'function') { props[eventNameAlias].apply(_this, [detail]); } }); if (objectEventOnly) { return; } var element = this.getElement(); if (element) { Util.Dispatch.elementEvent(element, eventName, this.name, detail); } else { Util.Dispatch.winDocEvent(eventName, this.name, detail); } }; Component.prototype.preventClosable = function () { return false; }; Component.prototype.destroy = function () { this.unregisterElements(); }; Component.prototype.onElementEvent = function (event) { }; Component.prototype.setEventsHandler = function () { var props = this.getProps(); var scope = Object.keys(props).reduce(function (cur, key) { if (typeof props[key] === 'function') { cur[key] = props[key]; } return cur; }, {}); if (Object.keys(scope).length > 0) { this.eventHandlers.push(scope); } }; Component.prototype.onBeforeElementEvent = function (event) { if (this.preventClosable()) { return; } this.onElementEvent(event); }; return Component; }()); var Collapse = (function (_super) { __extends(Collapse, _super); function Collapse(props) { if (props === void 0) { props = { toggle: false }; } var _this = _super.call(this, 'collapse', { toggle: false }, props) || this; var toggle = _this.getProp('toggle'); if (toggle) { _this.toggle(); } return _this; } Collapse.attachDOM = function () { var className = 'collapse'; Util.Observer.subscribe({ componentClass: className, onAdded: function (element, create) { create(new Collapse({ element: element })); }, onRemoved: function (element, remove) { remove('Collapse', element); }, }); document.addEventListener(Util.Event.CLICK, function (event) { if (!event.target) { return; } var target = Util.Selector.closest(event.target, '[data-toggle]'); if (!target) { return; } var dataToggleAttr = target.getAttribute('data-toggle'); if (dataToggleAttr && dataToggleAttr === className) { var id = target.getAttribute('data-target') || target.getAttribute('href'); if (!id) { return; } event.preventDefault(); var collapse = document.querySelector(id); if (!collapse) { return; } var collapseComponent = Util.Observer.getComponent(className, { element: collapse }); if (!collapseComponent) { return; } collapseComponent.toggle({ element: collapse, toggle: true }); } }); }; Collapse.prototype.getHeight = function () { return this.getElement().getBoundingClientRect(this.getElement()).height; }; Collapse.prototype.toggle = function () { if (this.isVisible()) { return this.hide(); } return this.show(); }; Collapse.prototype.show = function () { var _this = this; var element = this.getElement(); if (element.classList.contains('collapsing') || this.isVisible()) { return false; } this.triggerEvent(Util.Event.SHOW); var onCollapsed = function () { _this.triggerEvent(Util.Event.SHOWN); element.classList.add('show'); element.classList.remove('collapsing'); element.removeEventListener(Util.Event.TRANSITION_END, onCollapsed); element.setAttribute('aria-expanded', true); element.style.height = 'auto'; }; if (!element.classList.contains('collapsing')) { element.classList.add('collapsing'); } element.addEventListener(Util.Event.TRANSITION_END, onCollapsed); var height = this.getHeight(); element.style.height = '0px'; setTimeout(function () { element.style.height = height + "px"; }, 20); return true; }; Collapse.prototype.hide = function () { var _this = this; var element = this.getElement(); if (element.classList.contains('collapsing')) { return false; } if (!element.classList.contains('show')) { return false; } this.triggerEvent(Util.Event.HIDE); var onCollapsed = function () { _this.triggerEvent(Util.Event.HIDDEN); element.classList.remove('collapsing'); element.style.height = 'auto'; element.removeEventListener(Util.Event.TRANSITION_END, onCollapsed); element.setAttribute('aria-expanded', false); }; element.style.height = element.offsetHeight + "px"; setTimeout(function () { element.style.height = '0px'; }, 20); element.addEventListener(Util.Event.TRANSITION_END, onCollapsed); if (!element.classList.contains('collapsing')) { element.classList.add('collapsing'); } element.classList.remove('show'); return true; }; Collapse.prototype.isVisible = function () { return this.getElement().classList.contains('show'); }; return Collapse; }(Component)); Collapse.attachDOM(); var Accordion = (function (_super) { __extends(Accordion, _super); function Accordion(props) { var _this = _super.call(this, 'accordion', { multiple: false }, props) || this; _this.collapses = []; var element = _this.getElement(); var toggles = Array .from(element.querySelectorAll('[data-toggle="accordion"]') || []); toggles.forEach(function (toggle) { var collapseId = toggle.getAttribute('href') || toggle.getAttribute('data-target'); if (collapseId === null) { throw new Error('Accordion: collapse is missing href or data-target attribute'); } var collapse = document.querySelector(collapseId); if (collapse) { _this.addCollapse(collapse); } }); _this.registerElement({ target: element, event: Util.Event.CLICK }); return _this; } Accordion.attachDOM = function () { Util.Observer.subscribe({ componentClass: 'accordion', onAdded: function (element, create) { create(new Accordion({ element: element })); }, onRemoved: function (element, remove) { remove('Accordion', element); }, }); }; Accordion.prototype.addCollapse = function (element) { var collapse = new Collapse({ element: element, }); this.collapses.push(collapse); return collapse; }; Accordion.prototype.getCollapse = function (element) { var el = this.getElement(); var collapse = this.collapses.find(function (c) { return el.getAttribute('id') === element.getAttribute('id'); }); if (!collapse) { collapse = this.addCollapse(element); } return collapse; }; Accordion.prototype.getCollapses = function () { return this.collapses; }; Accordion.prototype.setCollapses = function (showCollapse) { var _this = this; var element = this.getElement(); var collapse = this.getCollapse(showCollapse); var multipleOpen = this.getProp('multiple'); if (!multipleOpen) { this.collapses.filter(function (c) { return c.getElement() !== collapse.getElement(); }).forEach(function (c) { _this.toggleIcon(c.getElement(), 'icon-minus', 'icon-plus'); c.hide(); }); } var v = collapse.isVisible(); this.toggleIcon(collapse.getElement(), v ? 'icon-minus' : 'icon-plus', v ? 'icon-plus' : 'icon-minus'); collapse.toggle(); }; Accordion.prototype.onElementEvent = function (event) { var target = event.target; var toggleEl = Util.Selector.closest(target, '[data-toggle="accordion"]'); if (!toggleEl) { return; } var collapseId = toggleEl.getAttribute('data-target') || toggleEl.getAttribute('href'); if (!collapseId) { return; } var collapseEl = document.querySelector(collapseId); var accordion = Util.Selector.closest(toggleEl, '.accordion'); if (!accordion || !collapseEl) { return; } event.preventDefault(); this.show(collapseEl); }; Accordion.prototype.toggleIcon = function (collapse, remove, add) { var id = collapse.getAttribute('id'); var selector = "[data-toggle=\"accordion\"][href=\"#" + id + "\"] .collapse-toggle"; var iconEl = document.querySelector(selector); if (!iconEl) { return; } if (iconEl.classList.contains(remove)) { iconEl.classList.remove(remove); iconEl.classList.add(add); } }; Accordion.prototype.show = function (collapseEl) { var collapse = collapseEl; if (typeof collapseEl === 'string') { collapse = document.querySelector(collapseEl); } if (!collapse) { throw new Error("The collapsible " + collapseEl + " is an invalid HTMLElement."); } this.setCollapses(collapse); return true; }; Accordion.prototype.hide = function (collapseEl) { var collapse = collapseEl; if (typeof collapseEl === 'string') { collapse = document.querySelector(collapseEl); } if (!collapse) { throw new Error("The collapsible " + collapseEl + " is an invalid HTMLElement."); } var collapseObj = this.getCollapse(collapse); return collapseObj.hide(); }; return Accordion; }(Component)); Accordion.attachDOM(); module.exports = Accordion; //# sourceMappingURL=accordion.js.map