UNPKG

12.1 kBJavaScriptView Raw
1/*!
2 * Collapse v2.0.0-alpha.1 (https://github.com/quark-dev/Phonon-Framework)
3 * Copyright 2015-2019 qathom
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 */
6'use strict';
7
8function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
9
10var Util = _interopDefault(require('../util.js'));
11
12/*! *****************************************************************************
13Copyright (c) Microsoft Corporation. All rights reserved.
14Licensed under the Apache License, Version 2.0 (the "License"); you may not use
15this file except in compliance with the License. You may obtain a copy of the
16License at http://www.apache.org/licenses/LICENSE-2.0
17
18THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
20WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
21MERCHANTABLITY OR NON-INFRINGEMENT.
22
23See the Apache Version 2.0 License for specific language governing permissions
24and limitations under the License.
25***************************************************************************** */
26/* global Reflect, Promise */
27
28var extendStatics = function(d, b) {
29 extendStatics = Object.setPrototypeOf ||
30 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
32 return extendStatics(d, b);
33};
34
35function __extends(d, b) {
36 extendStatics(d, b);
37 function __() { this.constructor = d; }
38 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
39}
40
41var Component = (function () {
42 function Component(name, defaultProps, props) {
43 var _this = this;
44 this.template = '';
45 this.id = null;
46 this.eventHandlers = [];
47 this.registeredElements = [];
48 this.name = name;
49 var element = typeof props.element === 'string'
50 ? document.querySelector(props.element) : props.element;
51 var config = {};
52 if (element) {
53 var dataConfig = Util.Selector.attrConfig(element);
54 if (dataConfig) {
55 config = dataConfig;
56 }
57 }
58 this.defaultProps = defaultProps;
59 this.props = Object.assign(defaultProps, config, props, { element: element });
60 this.id = this.uid();
61 this.elementListener = function (event) { return _this.onBeforeElementEvent(event); };
62 this.setEventsHandler();
63 }
64 Component.prototype.setTemplate = function (template) {
65 this.template = template;
66 };
67 Component.prototype.getTemplate = function () {
68 return this.template;
69 };
70 Component.prototype.getElement = function () {
71 return this.getProp('element') || null;
72 };
73 Component.prototype.setElement = function (element) {
74 this.props.element = element;
75 };
76 Component.prototype.getId = function () {
77 return this.id;
78 };
79 Component.prototype.uid = function () {
80 return Math.random().toString(36).substr(2, 10);
81 };
82 Component.prototype.getName = function () {
83 return this.name;
84 };
85 Component.prototype.getProps = function () {
86 return this.props;
87 };
88 Component.prototype.getProp = function (name) {
89 var defaultValue = this.defaultProps[name];
90 return typeof this.props[name] !== 'undefined' ? this.props[name] : defaultValue;
91 };
92 Component.prototype.setProps = function (props) {
93 var componentProps = Object.assign({}, props);
94 this.props = Object.assign(this.props, componentProps);
95 };
96 Component.prototype.setProp = function (name, value) {
97 if (typeof this.props[name] === 'undefined') {
98 throw new Error('Cannot set an invalid prop');
99 }
100 this.props[name] = value;
101 };
102 Component.prototype.registerElements = function (elements) {
103 var _this = this;
104 elements.forEach(function (element) { return _this.registerElement(element); });
105 };
106 Component.prototype.registerElement = function (element) {
107 element.target.addEventListener(element.event, this.elementListener);
108 this.registeredElements.push(element);
109 };
110 Component.prototype.unregisterElements = function () {
111 var _this = this;
112 this.registeredElements.forEach(function (element) {
113 _this.unregisterElement(element);
114 });
115 };
116 Component.prototype.unregisterElement = function (element) {
117 var registeredElementIndex = this.registeredElements
118 .findIndex(function (el) { return el.target === element.target && el.event === element.event; });
119 if (registeredElementIndex > -1) {
120 element.target.removeEventListener(element.event, this.elementListener);
121 this.registeredElements.splice(registeredElementIndex, 1);
122 }
123 else {
124 console.error('Warning! Could not remove element:'
125 + ' ' + (element.target + " with event: " + element.event + "."));
126 }
127 };
128 Component.prototype.triggerEvent = function (eventName, detail, objectEventOnly) {
129 var _this = this;
130 if (detail === void 0) { detail = {}; }
131 if (objectEventOnly === void 0) { objectEventOnly = false; }
132 var eventNameObject = eventName.split('.').reduce(function (acc, current, index) {
133 if (index === 0) {
134 return current;
135 }
136 return acc + current.charAt(0).toUpperCase() + current.slice(1);
137 });
138 var eventNameAlias = "on" + eventNameObject
139 .charAt(0).toUpperCase() + eventNameObject.slice(1);
140 var props = this.getProps();
141 this.eventHandlers.forEach(function (scope) {
142 if (typeof scope[eventNameObject] === 'function') {
143 scope[eventNameObject].apply(_this, [detail]);
144 }
145 if (typeof scope[eventNameAlias] === 'function') {
146 props[eventNameAlias].apply(_this, [detail]);
147 }
148 });
149 if (objectEventOnly) {
150 return;
151 }
152 var element = this.getElement();
153 if (element) {
154 Util.Dispatch.elementEvent(element, eventName, this.name, detail);
155 }
156 else {
157 Util.Dispatch.winDocEvent(eventName, this.name, detail);
158 }
159 };
160 Component.prototype.preventClosable = function () {
161 return false;
162 };
163 Component.prototype.destroy = function () {
164 this.unregisterElements();
165 };
166 Component.prototype.onElementEvent = function (event) {
167 };
168 Component.prototype.setEventsHandler = function () {
169 var props = this.getProps();
170 var scope = Object.keys(props).reduce(function (cur, key) {
171 if (typeof props[key] === 'function') {
172 cur[key] = props[key];
173 }
174 return cur;
175 }, {});
176 if (Object.keys(scope).length > 0) {
177 this.eventHandlers.push(scope);
178 }
179 };
180 Component.prototype.onBeforeElementEvent = function (event) {
181 if (this.preventClosable()) {
182 return;
183 }
184 this.onElementEvent(event);
185 };
186 return Component;
187}());
188
189var Collapse = (function (_super) {
190 __extends(Collapse, _super);
191 function Collapse(props) {
192 if (props === void 0) { props = { toggle: false }; }
193 var _this = _super.call(this, 'collapse', { toggle: false }, props) || this;
194 var toggle = _this.getProp('toggle');
195 if (toggle) {
196 _this.toggle();
197 }
198 return _this;
199 }
200 Collapse.attachDOM = function () {
201 var className = 'collapse';
202 Util.Observer.subscribe({
203 componentClass: className,
204 onAdded: function (element, create) {
205 create(new Collapse({ element: element }));
206 },
207 onRemoved: function (element, remove) {
208 remove('Collapse', element);
209 },
210 });
211 document.addEventListener(Util.Event.CLICK, function (event) {
212 if (!event.target) {
213 return;
214 }
215 var target = Util.Selector.closest(event.target, '[data-toggle]');
216 if (!target) {
217 return;
218 }
219 var dataToggleAttr = target.getAttribute('data-toggle');
220 if (dataToggleAttr && dataToggleAttr === className) {
221 var id = target.getAttribute('data-target') || target.getAttribute('href');
222 if (!id) {
223 return;
224 }
225 event.preventDefault();
226 var collapse = document.querySelector(id);
227 if (!collapse) {
228 return;
229 }
230 var collapseComponent = Util.Observer.getComponent(className, { element: collapse });
231 if (!collapseComponent) {
232 return;
233 }
234 collapseComponent.toggle({ element: collapse, toggle: true });
235 }
236 });
237 };
238 Collapse.prototype.getHeight = function () {
239 return this.getElement().getBoundingClientRect(this.getElement()).height;
240 };
241 Collapse.prototype.toggle = function () {
242 if (this.isVisible()) {
243 return this.hide();
244 }
245 return this.show();
246 };
247 Collapse.prototype.show = function () {
248 var _this = this;
249 var element = this.getElement();
250 if (element.classList.contains('collapsing') || this.isVisible()) {
251 return false;
252 }
253 this.triggerEvent(Util.Event.SHOW);
254 var onCollapsed = function () {
255 _this.triggerEvent(Util.Event.SHOWN);
256 element.classList.add('show');
257 element.classList.remove('collapsing');
258 element.removeEventListener(Util.Event.TRANSITION_END, onCollapsed);
259 element.setAttribute('aria-expanded', true);
260 element.style.height = 'auto';
261 };
262 if (!element.classList.contains('collapsing')) {
263 element.classList.add('collapsing');
264 }
265 element.addEventListener(Util.Event.TRANSITION_END, onCollapsed);
266 var height = this.getHeight();
267 element.style.height = '0px';
268 setTimeout(function () {
269 element.style.height = height + "px";
270 }, 20);
271 return true;
272 };
273 Collapse.prototype.hide = function () {
274 var _this = this;
275 var element = this.getElement();
276 if (element.classList.contains('collapsing')) {
277 return false;
278 }
279 if (!element.classList.contains('show')) {
280 return false;
281 }
282 this.triggerEvent(Util.Event.HIDE);
283 var onCollapsed = function () {
284 _this.triggerEvent(Util.Event.HIDDEN);
285 element.classList.remove('collapsing');
286 element.style.height = 'auto';
287 element.removeEventListener(Util.Event.TRANSITION_END, onCollapsed);
288 element.setAttribute('aria-expanded', false);
289 };
290 element.style.height = element.offsetHeight + "px";
291 setTimeout(function () {
292 element.style.height = '0px';
293 }, 20);
294 element.addEventListener(Util.Event.TRANSITION_END, onCollapsed);
295 if (!element.classList.contains('collapsing')) {
296 element.classList.add('collapsing');
297 }
298 element.classList.remove('show');
299 return true;
300 };
301 Collapse.prototype.isVisible = function () {
302 return this.getElement().classList.contains('show');
303 };
304 return Collapse;
305}(Component));
306Collapse.attachDOM();
307
308module.exports = Collapse;
309//# sourceMappingURL=collapse.js.map