diff --git a/README.md b/README.md index 04123f0..66a2ed2 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ import "@viivue/easy-tab-accordion"; ```html - + ``` ## Initialize @@ -197,27 +197,29 @@ Add these attributes on the wrapper element. ## Events -| Name | Description | -|----------------------------------|-------------| -| `onBeforeInit: (data) => {}` | | -| `onAfterInit: (data) => {}` | | -| `onBeforeOpen: (data,el) => {}` | | -| `onBeforeClose: (data,el) => {}` | | -| `onAfterOpen: (data,el) => {}` | | -| `onAfterClose: (data,el) => {}` | | -| `onDestroy: (data) => {}` | | -| `onUpdate: (data) => {}` | | +| Name | Description | +|-------------------------------|-------------| +| `onBeforeInit: (data) => {}` | | +| `onAfterInit: (data) => {}` | | +| `onBeforeOpen: (data) => {}` | | +| `onBeforeClose: (data) => {}` | | +| `onAfterOpen: (data) => {}` | | +| `onAfterClose: (data) => {}` | | +| `onDestroy: (data) => {}` | | +| `onUpdate: (data) => {}` | | ## Methods -| Name | Usage | Description | -|-----------------|----------------------------|-----------------------------| -| `toggle` | `eta.toggle(id)` | Toggle a section by ID | -| `toggleByIndex` | `eta.toggleByIndex(index)` | Toggle a section by index | -| `destroy` | `eta.destroy()` | Remove all style and events | -| `init` | `eta.init()` | Could be use after destroy | -| `update` | `eta.update()` | Update styling | -| `on` | `eta.on()` | Assign events | +| Name | Usage | Description | +|-----------------|-------------------------------------------|-----------------------------------------------------------------------| +| `toggle` | `eta.toggle(panelId)` | Toggle a panel | +| `openPanel` | `eta.openPanel(panelId, isStrict=false)` | Open a panel. Turn `isStrict` on to only open is currently closing. | +| `closePanel` | `eta.closePanel(panelId, isStrict=false)` | Close a panel. Turn `isStrict` on to only close is currently opening. | +| `toggleByIndex` | `eta.toggleByIndex(index)` | Toggle a section by index | +| `destroy` | `eta.destroy()` | Remove all style and events | +| `init` | `eta.init()` | Could be use after destroy | +| `update` | `eta.update()` | Update styling | +| `on` | `eta.on()` | Assign events | Get the instance with JS init @@ -246,6 +248,9 @@ npm run prod # Build dev site (for Netlify only) npm run build + +# Research replace to set new version +npm publish ``` ## License diff --git a/dev/index.html b/dev/index.html index dbdd372..e082290 100644 --- a/dev/index.html +++ b/dev/index.html @@ -171,7 +171,7 @@

Tab

Accordion initialize with JSON format

-
+
Section 1 diff --git a/dist/easy-tab-accordion.min.js b/dist/easy-tab-accordion.min.js index 7500205..662c371 100644 --- a/dist/easy-tab-accordion.min.js +++ b/dist/easy-tab-accordion.min.js @@ -1,7 +1,7 @@ /**! - * Easy Tabs & Accordion v2.2.0 + * Easy Tabs & Accordion v2.3.0 * @author phucbm * @homepage https://github.com/viivue/easy-tab-accordion * @license MIT 2023 */ -!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i=e();for(var n in i)("object"==typeof exports?exports:t)[n]=i[n]}}(this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};function i({context:t,target:e}){"auto"!==t.type&&("fade"===t.options.animation&&(e=t.wrapper),e||(e=t.wrapper),e.scrollIntoView({behavior:"smooth"}))}function n(t){const e=getComputedStyle(t);return parseInt(e.getPropertyValue("margin-top")+e.getPropertyValue("margin-bottom"),10)}function o(t){return t.scrollHeight+n(t)+"px"}function r(t,e){Object.assign(t.style,e)}function s(t,e){r(t,{transitionProperty:"height, margin, padding, opacity",transitionDuration:e+"ms",overflow:"hidden"})}function a(t){r(t,{boxSizing:"",paddingTop:"",paddingBottom:"",marginTop:"",marginBottom:""})}t.r(e),t.d(e,{EasyTabAccordion:()=>I});const c="easy-tab-accordion-enabled",l="active",h="assigned-trigger-event",d="data-eta",p="data-eta-hash",u="data-eta-hash-scroll",f="data-eta-animation",g={el:document.querySelector("[data-eta]"),id:function(t=""){return t+(+new Date).toString(16)+(1e8*Math.random()|0).toString(16)}("eta-"),trigger:"[data-eta-trigger]",triggerAttr:"data-eta-trigger",receiver:"[data-eta-receiver]",receiverAttr:"data-eta-receiver",activeClass:"active",animation:"slide",duration:450,scrollIntoView:!1,hash:!1,hashScroll:!1,liveBreakpoint:[],avoidDoubleClick:!0,dev:!1,activeSection:0,allowCollapseAll:!1,allowExpandAll:!1,isPreventDefault:!0};function v(t,e){return!!t.dataset.filter((t=>t.id===e)).length}function m(t,e){return e>=0&&ee?t.options.receiver:t.options.trigger,n=e=>e?t.options.receiverAttr:t.options.triggerAttr;if(e){return{previous:t.wrapper.querySelectorAll(`${i(!0)}:not([${n(!0)}="${e}"])`),current:t.wrapper.querySelectorAll(`[${n(!0)}="${e}"]`),previousTrigger:t.wrapper.querySelectorAll(`${i(!1)}:not([${n(!1)}="${e}"])`),currentTrigger:t.wrapper.querySelectorAll(`[${n(!1)}="${e}"]`)}}return{current:t.wrapper.querySelectorAll(`[${n(!0)}]`),currentTrigger:t.wrapper.querySelectorAll(`[${n(!1)}]`)}}function w(t,e){return t.dataset.findIndex((t=>t.id===e))}function b(t,e){return t.dataset[e].id}function A(t,e){const{current:i,currentTrigger:n}=y(t,e);i.forEach((t=>t.classList.remove(l))),n.forEach((t=>t.classList.remove(l)))}function E(t,e,...i){t.options.dev&&console?.[e](...i)}function S(t,e=500,i){r(t,{opacity:"0",visibility:"hidden"}),setTimeout((()=>{a(t),"function"==typeof i&&i()}),e)}function T(t,e=500,i){s(t.parentElement,e),r(t,{opacity:"1",visibility:"visible"}),r(t.parentElement,{height:`${t.scrollHeight+n(t)}px`}),setTimeout((()=>{a(t),a(t.parentElement),"function"==typeof i&&i()}),e)}function x(t=document.location){const e=new URL(t),i=e.hash.indexOf("?"),n=i>-1?e.hash.slice(0,i):e.hash;return{data:e,hash:n,id:n.slice(1)}}function _(t,e){k(t)&&L(t)!==t.enabled&&(t.enabled=L(t),t.enabled?t.init():t.destroy())}function L(t){return window.innerWidth<=t.options.liveBreakpoint[0]&&window.innerWidth>=t.options.liveBreakpoint[1]&&k(t)}function k(t){let e=function(t,e=!0){return t.sort((function(t,i){return e?t-i:i-t}))}(t.options.liveBreakpoint,!1);return e=e.slice(0,2),2===e.length}function C(t){t.events.fire("onBeforeInit"),t.wrapper.classList.add(c),t.wrapper.querySelectorAll(t.options.trigger).forEach((e=>{e.addEventListener("click",(e=>function(t,e){t.options.isPreventDefault&&e.preventDefault();e.stopPropagation();const i=e.target.getAttribute(t.options.triggerAttr)||e.target.closest(t.options.trigger).getAttribute(t.options.triggerAttr);t.toggle(i,"manual")}(t,e))),e.classList.add(h)})),t.dataset=[],t.wrapper.querySelectorAll(t.options.receiver).forEach((e=>{const i=e.getAttribute(t.options.receiverAttr);if(t.dataset.push({id:i,el:e,active:!1}),"fade"===t.options.animation){r(e.parentElement,{overflow:"hidden",position:"relative"!==getComputedStyle(e).position?"relative":""});const t={position:(()=>"absolute"!==getComputedStyle(e).position?"absolute":"")(),inset:"0 0 auto"};setTimeout((()=>{r(e,t)}),1)}s(e,t.options.duration)})),function(t){document.querySelectorAll('a[href^="#"]').forEach((e=>{const i=e.getAttribute("href"),n="#"===i[0]?i.slice(1):x(i).id;n&&t.dataset.forEach((i=>{if(i.id===n){if(e.classList.contains(h))return;e.addEventListener("click",(e=>{t.options.isPreventDefault&&e.preventDefault(),t.toggle(n,"manual")}))}}))}))}(t),t.enabled&&(function(t){const e=x(),i=e.hash,n=e.id;return t.options.hash&&i.length&&t.dataset.filter((t=>t.id===n)).length}(t)?t.toggle(x().id,"hash"):function(t){let e=[];const i=t.options.activeSection;switch(t.options.animation){case"slide":switch(typeof i){case"number":e.push(i);break;case"object":t.options.allowExpandAll&&"slide"===t.options.animation?e=i.filter((function(t,e,i){return i.indexOf(t)===e})):e.push(i[0])}break;case"fade":switch(typeof i){case"number":e.push(m(t,i)?i:0);break;case"object":const n=i[0];e.push(m(t,n)?n:0)}}e.forEach((e=>{m(t,e)&&t.toggle(b(t,e),"auto")})),t.dataset.filter((t=>!t.active)).forEach((e=>t.closePanel(e.id)))}(t)),t.hasInitialized=!0,t.events.fire("onAfterInit")}class O{constructor(t,e){t&&(this.context=t,this.options={names:[],...e},this.eventNames=this.options.names,this.eventsList=[])}fire(t,e={}){if(!this.eventNames.includes(t))return void console.warn(`Cannot fire unrecognized event "${t}"`,this,e);const i={instance:this.context,eventName:t,...e},n=(this.context.config?this.context.config:this.context.options)[t];"function"==typeof n&&n(i);const o=this.eventsList[t];o?.length&&o.forEach((t=>{"function"==typeof t&&t(i)}))}add(t,e){t=function(t){let e=t;"on"!==t.slice(0,2)&&(e=e.charAt(0).toUpperCase()+e.slice(1),e="on"+e);return e}(t);this.eventNames.includes(t)?(void 0===this.eventsList[t]&&(this.eventsList[t]=[]),this.eventsList[t].push(e)):console.warn(`Cannot add unrecognized event "${t}"`)}}function B({target:t,attributeName:e="",defaultOptions:i={},numericValues:n=[],onIsString:o,dev:r=!1}){if(!t)return r&&console.warn("Target not found!",t),i;if(!t.hasAttribute(e))return r&&console.warn("Attribute not found from target",e),i;const s=t.getAttribute(e);if(!s.length)return i;if(!function(t){try{return JSON.parse(t)&&!!t}catch(t){return!1}}(s))return"function"==typeof o?o(s):console.warn("Not a JSON string",s),i;let a=JSON.parse(s);for(const[t,e]of Object.entries(a))"false"===e?a[t]=!1:"true"===e?a[t]=!0:n.includes(t)&&"string"==typeof e&&e.length>0?a[t]=parseFloat(e):a[t]=e;return{...i,...a}}class I{constructor(t){this.events=new O(this,{names:["onBeforeInit","onAfterInit","onBeforeOpen","onBeforeClose","onAfterOpen","onAfterClose","onDestroy","onUpdate"]}),this.originalOptions=t,this.options=B({target:this.wrapper,defaultOptions:{...g,...t},attributeName:d,numericValues:["duration","activeSection"],dev:g.dev}),this.init(),this.isAnimating=!1}on(t,e){this.events.add(t,e)}init(){if(!this.options.el)return void E(this,"warn","ETA Error, target not found!");if(this.wrapper=this.options.el,this.id="",this.current_id="",this.previous_id="",this.type="",this.hasInitialized=!1,this.enabled=!k(this)||L(this),this.count=this.wrapper.querySelectorAll(this.options.trigger).length,this.wrapper.classList.contains(c))return void E(this,"ETA has initialized");this.isFirst=!0,this.options.hash=!0===this.wrapper.hasAttribute(p)||this.options.hash,this.options.hashScroll=!0===this.wrapper.hasAttribute(u)||this.options.hashScroll;const t=this.wrapper.getAttribute(f);this.options.animation=null!==t?t:this.options.animation,this.wrapper.setAttribute(d,this.id),this.count<1?E(this,"warn","Quit init due to child panels not found",this):(this.enabled&&!this.hasInitialized&&C(this),!this.enabled&&this.hasInitialized&&this.destroy(),window.addEventListener("resize",function(t,e=150){let i;return(...n)=>{clearTimeout(i),i=setTimeout((()=>{t.apply(this,n)}),e)}}((t=>{return(e=this).update(),void _(e);var e}),300)),window.addEventListener("load",(t=>{return(e=this).update(),void _(e);var e})))}destroy(){switch(this.hasInitialized=!1,this.wrapper.classList.remove(c),this.wrapper.querySelectorAll(this.options.trigger).forEach((t=>{t.outerHTML=`${t.outerHTML}`})),this.dataset=[],this.options.animation){case"slide":(t=this).wrapper.querySelectorAll(t.options.receiver).forEach((t=>{r(t,{display:"",height:""}),a(t)})),A(t);break;case"fade":!function(t){t.wrapper.querySelectorAll(t.options.receiver).forEach((t=>{r(t,{opacity:"",visibility:"",position:"",inset:""}),r(t.parentElement,{height:"",position:""}),a(t),a(t.parentElement)})),A(t)}(this)}var t;this.events.fire("onDestroy")}update(){switch(this.options.animation){case"slide":break;case"fade":(t=this).dataset.forEach((e=>{const i=e.el,n=t.options.duration;e.active&&T(i,n),e.active||S(i,n)}))}var t;this.events.fire("onUpdate")}openPanel(t=this.current_id){if(!v(this,t))return;(()=>{this.dataset[w(this,t)].active=!0,function(t,e){if(!t.options.hash||"manual"!==t.type)return;const i=document.location.origin+document.location.pathname;document.location=i+"#"+e}(this,t),this.events.fire("onBeforeOpen",{type:this.type,current_id:this.current_id,previous_id:this.previous_id})})();const e=e=>{var n;"hash"===(n=this).type&&n.options.hashScroll&&window.addEventListener("load",(()=>setTimeout((()=>i({context:n})),100))),this.options.scrollIntoView&&i({context:this,target:e}),this.isAnimating=!1,E(this,"log","Stop animation."),this.events.fire("onAfterOpen",{target:e,type:this.type,current_id:this.current_id,previous_id:this.previous_id}),E(this,"log","after open",t)},{current:n}=y(this,t);switch(this.options.animation){case"slide":n.forEach((t=>function(t,e=500,i){0!==parseInt(o(t))&&"none"!==t.style.display.trim()||r(t,{boxSizing:"border-box",height:"0px",display:"block"}),setTimeout((()=>{r(t,{height:o(t),marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""})}),10),setTimeout((()=>{a(t),r(t,{height:""}),"function"==typeof i&&i()}),e+10)}(t,this.options.duration,(()=>e(t)))));break;case"fade":n.forEach((t=>T(t,this.options.duration,(()=>e(t)))))}!function(t,e){const{current:i,currentTrigger:n}=y(t,e||t.current_id);i&&i.forEach((t=>t.classList.add(l))),n&&n.forEach((t=>t.classList.add(l)))}(this,t);("fade"===this.options.animation||"slide"===this.options.animation&&!this.options.allowExpandAll)&&this.dataset.filter((e=>e.id!==t)).forEach((t=>{(t.active||this.isFirst)&&this.closePanel(t.id)})),this.isFirst&&(n[0].style.display="block",this.isFirst=!1)}closePanel(t=this.current_id){if(!v(this,t))return;this.events.fire("onBeforeClose",{type:this.type,current_id:this.current_id,previous_id:this.previous_id}),this.dataset[w(this,t)].active=!1;const e=e=>{this.events.fire("onAfterClose",{target:e}),this.isAnimating=!1,E(this,"log","Stop animation."),E(this,"log","after close",t)},{current:i}=y(this,t);switch(this.options.animation){case"slide":i.forEach((t=>function(t,e=500,i){const n=o(t);"0px"!==n?(r(t,{boxSizing:"border-box",height:n}),setTimeout((()=>{r(t,{height:"0px",marginTop:"0px",marginBottom:"0px",paddingTop:"0px",paddingBottom:"0px"})}),10),setTimeout((()=>{r(t,{display:"none",height:""}),a(t),"function"==typeof i&&i()}),e+10)):"function"==typeof i&&i()}(t,this.options.duration,(()=>e(t)))));break;case"fade":i.forEach((t=>S(t,this.options.duration,(()=>e(t)))))}A(this,t)}toggle(t,e="undefined",i=!1){if(!v(this,t))return void E(this,"warn","invalid id");const n=function(t,e){if(!v(t,e))return!1;if(t.hasInitialized&&t.options.avoidDoubleClick&&t.isAnimating)return E(t,"warn",`Block [${e}] to avoid double click on animating item.`),0;const i=t.dataset[w(t,e)].active,n="slide"===t.options.animation&&t.options.allowCollapseAll;return i&&n?-1:i&&!n?0:!i&&n?1:i||n?i?1:-1:1}(this,t);0!==n&&(this.isAnimating=!0,E(this,"log","Start animation."),this.type=e,this.previous_id=this.current_id?this.current_id:b(this,0),1===n?(this.current_id=t,this.openPanel(this.current_id)):this.closePanel(t))}toggleByIndex(t){this.toggle(b(this,t))}}return window.ETAController=new class{constructor(){this.instances=[]}add(t){this.instances.push(t)}get(t){return this.instances.filter((e=>e.id===t))[0]}},window.ETA={init:t=>{void 0===t&&document.querySelectorAll("[data-eta]").forEach((e=>{window.ETAController.add(new I({el:e,...t}))})),window.ETAController.add(new I(t))},get:t=>window.ETAController.get(t)},window.ETA.init(),e})())); \ No newline at end of file +!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i=e();for(var n in i)("object"==typeof exports?exports:t)[n]=i[n]}}(this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};function i({context:t,target:e}){"auto"!==t.type&&("fade"===t.options.animation&&(e=t.wrapper),e||(e=t.wrapper),e.scrollIntoView({behavior:"smooth"}))}function n(t){const e=getComputedStyle(t);return parseInt(e.getPropertyValue("margin-top")+e.getPropertyValue("margin-bottom"),10)}function o(t){return t.scrollHeight+n(t)+"px"}function s(t,e){Object.assign(t.style,e)}function r(t,e){s(t,{transitionProperty:"height, margin, padding, opacity",transitionDuration:e+"ms",overflow:"hidden"})}function a(t){s(t,{boxSizing:"",paddingTop:"",paddingBottom:"",marginTop:"",marginBottom:""})}function c(t=""){return t+(+new Date).toString(16)+(1e8*Math.random()|0).toString(16)}function l(t,e){return!!t.dataset.filter((t=>t.id===e)).length}function h(t,e){return e>=0&&ee?t.options.receiver:t.options.trigger,n=e=>e?t.options.receiverAttr:t.options.triggerAttr;if(e){return{previous:t.wrapper.querySelectorAll(`${i(!0)}:not([${n(!0)}="${e}"])`),current:t.wrapper.querySelectorAll(`[${n(!0)}="${e}"]`),previousTrigger:t.wrapper.querySelectorAll(`${i(!1)}:not([${n(!1)}="${e}"])`),currentTrigger:t.wrapper.querySelectorAll(`[${n(!1)}="${e}"]`)}}return{current:t.wrapper.querySelectorAll(`[${n(!0)}]`),currentTrigger:t.wrapper.querySelectorAll(`[${n(!1)}]`)}}function p(t,e){return t.dataset.findIndex((t=>t.id===e))}function u(t,e){return t.dataset[e].id}function f(t,e){const{current:i,currentTrigger:n}=d(t,e);i.forEach((e=>e.classList.remove(t.options.activeClass))),n.forEach((e=>e.classList.remove(t.options.activeClass)))}function g(t,e,...i){t.options.dev&&console?.[e](...i)}function v(t,e=500,i){s(t,{opacity:"0",visibility:"hidden"}),setTimeout((()=>{a(t),"function"==typeof i&&i()}),e)}function m(t,e=500,i){r(t.parentElement,e),s(t,{opacity:"1",visibility:"visible"}),s(t.parentElement,{height:`${t.scrollHeight+n(t)}px`}),setTimeout((()=>{a(t),a(t.parentElement),"function"==typeof i&&i()}),e)}function y(t=document.location){const e=new URL(t),i=e.hash.indexOf("?"),n=i>-1?e.hash.slice(0,i):e.hash;return{data:e,hash:n,id:n.slice(1)}}function w(t,e){A(t)&&b(t)!==t.enabled&&(t.enabled=b(t),t.enabled?t.init():t.destroy())}function b(t){return window.innerWidth<=t.options.liveBreakpoint[0]&&window.innerWidth>=t.options.liveBreakpoint[1]&&A(t)}function A(t){let e=function(t,e=!0){return t.sort((function(t,i){return e?t-i:i-t}))}(t.options.liveBreakpoint,!1);return e=e.slice(0,2),2===e.length}t.r(e),t.d(e,{EasyTabAccordion:()=>k});const E="easy-tab-accordion-enabled",S="assigned-trigger-event",T="data-eta",x="data-eta-hash",P="data-eta-hash-scroll",_="data-eta-animation",B={el:void 0,id:void 0,trigger:"[data-eta-trigger]",triggerAttr:"data-eta-trigger",receiver:"[data-eta-receiver]",receiverAttr:"data-eta-receiver",activeClass:"active",animation:"slide",duration:450,scrollIntoView:!1,hash:!1,hashScroll:!1,liveBreakpoint:[],avoidDoubleClick:!0,dev:!1,activeSection:0,allowCollapseAll:!1,allowExpandAll:!1,isPreventDefault:!0};function C(t){t.events.fire("onBeforeInit"),t.wrapper.classList.add(E),t.wrapper.querySelectorAll(t.options.trigger).forEach((e=>{e.addEventListener("click",(e=>function(t,e){t.options.isPreventDefault&&e.preventDefault();e.stopPropagation();const i=e.target.getAttribute(t.options.triggerAttr)||e.target.closest(t.options.trigger).getAttribute(t.options.triggerAttr);t.toggle(i,"manual")}(t,e))),e.classList.add(S)})),t.dataset=[],t.wrapper.querySelectorAll(t.options.receiver).forEach((e=>{const i=e.getAttribute(t.options.receiverAttr);if(t.dataset.push({id:i,el:e,active:!1}),"fade"===t.options.animation){s(e.parentElement,{overflow:"hidden",position:"relative"!==getComputedStyle(e).position?"relative":""});const t={position:(()=>"absolute"!==getComputedStyle(e).position?"absolute":"")(),inset:"0 0 auto"};setTimeout((()=>{s(e,t)}),1)}r(e,t.options.duration)})),function(t){document.querySelectorAll('a[href^="#"]').forEach((e=>{const i=e.getAttribute("href"),n="#"===i[0]?i.slice(1):y(i).id;n&&t.dataset.forEach((i=>{if(i.id===n){if(e.classList.contains(S))return;e.addEventListener("click",(e=>{t.options.isPreventDefault&&e.preventDefault(),t.toggle(n,"manual")}))}}))}))}(t),t.enabled&&(function(t){const e=y(),i=e.hash,n=e.id;return t.options.hash&&i.length&&t.dataset.filter((t=>t.id===n)).length}(t)?t.toggle(y().id,"hash"):function(t){let e=[];const i=t.options.activeSection;switch(t.options.animation){case"slide":switch(typeof i){case"number":e.push(i);break;case"object":t.options.allowExpandAll&&"slide"===t.options.animation?e=i.filter((function(t,e,i){return i.indexOf(t)===e})):e.push(i[0])}break;case"fade":switch(typeof i){case"number":e.push(h(t,i)?i:0);break;case"object":const n=i[0];e.push(h(t,n)?n:0)}}e.forEach((e=>{h(t,e)&&t.toggle(u(t,e),"auto")})),t.dataset.filter((t=>!t.active)).forEach((e=>t.closePanel(e.id)))}(t)),t.hasInitialized=!0,t.events.fire("onAfterInit")}function I({target:t,attributeName:e="",defaultOptions:i={},numericValues:n=[],onIsString:o,dev:s=!1}){if(!t)return s&&console.warn("Target not found!",t),i;if(!t.hasAttribute(e))return s&&console.warn("Attribute not found from target",e),i;const r=t.getAttribute(e);if(!r.length)return i;if(!function(t){try{return JSON.parse(t)&&!!t}catch(t){return!1}}(r))return"function"==typeof o?o(r):console.warn("Not a JSON string",r),i;let a=JSON.parse(r);for(const[t,e]of Object.entries(a))"false"===e?a[t]=!1:"true"===e?a[t]=!0:n.includes(t)&&"string"==typeof e&&e.length>0?a[t]=parseFloat(e):a[t]=e;return{...i,...a}}class L{constructor(t,e){t&&(this.context=t,this.options={names:[],...e},this.eventNames=this.options.names,this.eventsList=[])}fire(t,e={}){if(!this.eventNames.includes(t))return void console.warn(`Cannot fire unrecognized event "${t}"`,this,e);const i={instance:this.context,eventName:t,...e},n=(this.context.config?this.context.config:this.context.options)[t];"function"==typeof n&&n(i);const o=this.eventsList[t];o?.length&&o.forEach((t=>{"function"==typeof t&&t(i)}))}add(t,e){t=function(t){let e=t;"on"!==t.slice(0,2)&&(e=e.charAt(0).toUpperCase()+e.slice(1),e="on"+e);return e}(t);this.eventNames.includes(t)?(void 0===this.eventsList[t]&&(this.eventsList[t]=[]),this.eventsList[t].push(e)):console.warn(`Cannot add unrecognized event "${t}"`)}}class k{constructor(t){this.options={...B,id:c("eta-"),...t},this.options.el?(this.options=I({target:this.options.el,defaultOptions:this.options,attributeName:T,numericValues:["duration","activeSection"],dev:B.dev}),this.events=new L(this,{names:["onBeforeInit","onAfterInit","onBeforeOpen","onBeforeClose","onAfterOpen","onAfterClose","onDestroy","onUpdate"]}),this.init(),this.isAnimating=!1):g(this,"warn","ETA Error, target not found!")}on(t,e){this.events.add(t,e)}init(){if(this.wrapper=this.options.el,this.id=this.options.id,this.current_id="",this.previous_id="",this.type="",this.hasInitialized=!1,this.enabled=!A(this)||b(this),this.count=this.wrapper.querySelectorAll(this.options.trigger).length,this.wrapper.classList.contains(E))return void g(this,"ETA has initialized");this.isFirst=!0,this.options.hash=!0===this.wrapper.hasAttribute(x)||this.options.hash,this.options.hashScroll=!0===this.wrapper.hasAttribute(P)||this.options.hashScroll;const t=this.wrapper.getAttribute(_);this.options.animation=null!==t?t:this.options.animation,this.wrapper.setAttribute(T,this.id),this.count<1?g(this,"warn","Quit init due to child panels not found",this):(this.enabled&&!this.hasInitialized&&C(this),!this.enabled&&this.hasInitialized&&this.destroy(),window.addEventListener("resize",function(t,e=150){let i;return(...n)=>{clearTimeout(i),i=setTimeout((()=>{t.apply(this,n)}),e)}}((t=>{return(e=this).update(),void w(e);var e}),300)),window.addEventListener("load",(t=>{return(e=this).update(),void w(e);var e})))}destroy(){switch(this.hasInitialized=!1,this.wrapper.classList.remove(E),this.wrapper.querySelectorAll(this.options.trigger).forEach((t=>{t.outerHTML=`${t.outerHTML}`})),this.dataset=[],this.options.animation){case"slide":(t=this).wrapper.querySelectorAll(t.options.receiver).forEach((t=>{s(t,{display:"",height:""}),a(t)})),f(t);break;case"fade":!function(t){t.wrapper.querySelectorAll(t.options.receiver).forEach((t=>{s(t,{opacity:"",visibility:"",position:"",inset:""}),s(t.parentElement,{height:"",position:""}),a(t),a(t.parentElement)})),f(t)}(this)}var t;this.events.fire("onDestroy")}update(){switch(this.options.animation){case"slide":break;case"fade":(t=this).dataset.forEach((e=>{const i=e.el,n=t.options.duration;e.active&&m(i,n),e.active||v(i,n)}))}var t;this.events.fire("onUpdate")}openPanel(t=this.current_id,e=!1){if(!l(this,t))return;const n=this.getPanelByID(t);if(e&&n.active)return void g(this,"warn",`openPanel(${t}) does not run as the panel is already opened!`);(()=>{this.getPanelByID(t).active=!0,function(t,e){if(!t.options.hash||"manual"!==t.type)return;const i=document.location.origin+document.location.pathname;document.location=i+"#"+e}(this,t),this.events.fire("onBeforeOpen",{type:this.type,current_id:this.current_id,previous_id:this.previous_id})})();const r=e=>{var n;"hash"===(n=this).type&&n.options.hashScroll&&window.addEventListener("load",(()=>setTimeout((()=>i({context:n})),100))),this.options.scrollIntoView&&i({context:this,target:e}),this.isAnimating=!1,g(this,"log","Stop animation."),this.events.fire("onAfterOpen",{target:e,type:this.type,current_id:this.current_id,previous_id:this.previous_id}),g(this,"log","after open",t)},{current:c}=d(this,t);switch(this.options.animation){case"slide":c.forEach((t=>function(t,e=500,i){0!==parseInt(o(t))&&"none"!==t.style.display.trim()||s(t,{boxSizing:"border-box",height:"0px",display:"block"}),setTimeout((()=>{s(t,{height:o(t),marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""})}),10),setTimeout((()=>{a(t),s(t,{height:""}),"function"==typeof i&&i()}),e+10)}(t,this.options.duration,(()=>r(t)))));break;case"fade":c.forEach((t=>m(t,this.options.duration,(()=>r(t)))))}!function(t,e){const{current:i,currentTrigger:n}=d(t,e||t.current_id);i&&i.forEach((e=>e.classList.add(t.options.activeClass))),n&&n.forEach((e=>e.classList.add(t.options.activeClass)))}(this,t);("fade"===this.options.animation||"slide"===this.options.animation&&!this.options.allowExpandAll)&&this.dataset.filter((e=>e.id!==t)).forEach((t=>{(t.active||this.isFirst)&&this.closePanel(t.id)})),this.isFirst&&(c[0].style.display="block",this.isFirst=!1)}closePanel(t=this.current_id,e=!1){if(!l(this,t))return;const i=this.getPanelByID(t);if(e&&!i.active)return void console.warn(`closePanel(${t}) does not run as the panel is already closed!`);this.events.fire("onBeforeClose",{type:this.type,current_id:this.current_id,previous_id:this.previous_id}),this.getPanelByID(t).active=!1;const n=e=>{this.events.fire("onAfterClose",{target:e}),this.isAnimating=!1,g(this,"log","Stop animation."),g(this,"log","after close",t)},{current:r}=d(this,t);switch(this.options.animation){case"slide":r.forEach((t=>function(t,e=500,i){const n=o(t);"0px"!==n?(s(t,{boxSizing:"border-box",height:n}),setTimeout((()=>{s(t,{height:"0px",marginTop:"0px",marginBottom:"0px",paddingTop:"0px",paddingBottom:"0px"})}),10),setTimeout((()=>{s(t,{display:"none",height:""}),a(t),"function"==typeof i&&i()}),e+10)):"function"==typeof i&&i()}(t,this.options.duration,(()=>n(t)))));break;case"fade":r.forEach((t=>v(t,this.options.duration,(()=>n(t)))))}f(this,t)}getPanelByID(t){return this.dataset[p(this,t)]}toggle(t,e="undefined",i=!1){if(!l(this,t))return void g(this,"warn","invalid id");const n=function(t,e){if(!l(t,e))return!1;if(t.hasInitialized&&t.options.avoidDoubleClick&&t.isAnimating)return g(t,"warn",`Block [${e}] to avoid double click on animating item.`),0;const i=t.dataset[p(t,e)].active,n="slide"===t.options.animation&&t.options.allowCollapseAll;return i&&n?-1:i&&!n?0:!i&&n?1:i||n?i?1:-1:1}(this,t);0!==n&&(this.isAnimating=!0,g(this,"log","Start animation."),this.type=e,this.previous_id=this.current_id?this.current_id:u(this,0),1===n?(this.current_id=t,this.openPanel(this.current_id)):this.closePanel(t))}toggleByIndex(t){this.toggle(u(this,t))}}return window.ETAController=new class{constructor(){this.instances=[]}add(t){this.instances.push(t)}get(t){return this.instances.filter((e=>e.id===t))[0]}},window.ETA={init:t=>{void 0===t&&document.querySelectorAll("[data-eta]").forEach((e=>{window.ETAController.add(new k({el:e,...t}))})),window.ETAController.add(new k(t))},get:t=>window.ETAController.get(t)},window.ETA.init(),e})())); \ No newline at end of file diff --git a/dist/easy-tab-accordion.module.js b/dist/easy-tab-accordion.module.js index 2ac46e7..4e0523d 100644 --- a/dist/easy-tab-accordion.module.js +++ b/dist/easy-tab-accordion.module.js @@ -1,6 +1,6 @@ /**! - * Easy Tabs & Accordion v2.2.0 + * Easy Tabs & Accordion v2.3.0 * @author phucbm * @homepage https://github.com/viivue/easy-tab-accordion * @license MIT 2023 - */var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};function i({context:t,target:e}){"auto"!==t.type&&("fade"===t.options.animation&&(e=t.wrapper),e||(e=t.wrapper),e.scrollIntoView({behavior:"smooth"}))}function n(t){const e=getComputedStyle(t);return parseInt(e.getPropertyValue("margin-top")+e.getPropertyValue("margin-bottom"),10)}function o(t){return t.scrollHeight+n(t)+"px"}function r(t,e){Object.assign(t.style,e)}function s(t,e){r(t,{transitionProperty:"height, margin, padding, opacity",transitionDuration:e+"ms",overflow:"hidden"})}function a(t){r(t,{boxSizing:"",paddingTop:"",paddingBottom:"",marginTop:"",marginBottom:""})}t.d(e,{v:()=>O});const c="easy-tab-accordion-enabled",l="active",h="assigned-trigger-event",d="data-eta",p="data-eta-hash",u="data-eta-hash-scroll",f="data-eta-animation",g={el:document.querySelector("[data-eta]"),id:function(t=""){return t+(+new Date).toString(16)+(1e8*Math.random()|0).toString(16)}("eta-"),trigger:"[data-eta-trigger]",triggerAttr:"data-eta-trigger",receiver:"[data-eta-receiver]",receiverAttr:"data-eta-receiver",activeClass:"active",animation:"slide",duration:450,scrollIntoView:!1,hash:!1,hashScroll:!1,liveBreakpoint:[],avoidDoubleClick:!0,dev:!1,activeSection:0,allowCollapseAll:!1,allowExpandAll:!1,isPreventDefault:!0};function v(t,e){return!!t.dataset.filter((t=>t.id===e)).length}function m(t,e){return e>=0&&ee?t.options.receiver:t.options.trigger,n=e=>e?t.options.receiverAttr:t.options.triggerAttr;if(e){return{previous:t.wrapper.querySelectorAll(`${i(!0)}:not([${n(!0)}="${e}"])`),current:t.wrapper.querySelectorAll(`[${n(!0)}="${e}"]`),previousTrigger:t.wrapper.querySelectorAll(`${i(!1)}:not([${n(!1)}="${e}"])`),currentTrigger:t.wrapper.querySelectorAll(`[${n(!1)}="${e}"]`)}}return{current:t.wrapper.querySelectorAll(`[${n(!0)}]`),currentTrigger:t.wrapper.querySelectorAll(`[${n(!1)}]`)}}function y(t,e){return t.dataset.findIndex((t=>t.id===e))}function b(t,e){return t.dataset[e].id}function A(t,e){const{current:i,currentTrigger:n}=w(t,e);i.forEach((t=>t.classList.remove(l))),n.forEach((t=>t.classList.remove(l)))}function E(t,e,...i){t.options.dev&&console?.[e](...i)}function S(t,e=500,i){r(t,{opacity:"0",visibility:"hidden"}),setTimeout((()=>{a(t),"function"==typeof i&&i()}),e)}function T(t,e=500,i){s(t.parentElement,e),r(t,{opacity:"1",visibility:"visible"}),r(t.parentElement,{height:`${t.scrollHeight+n(t)}px`}),setTimeout((()=>{a(t),a(t.parentElement),"function"==typeof i&&i()}),e)}function x(t=document.location){const e=new URL(t),i=e.hash.indexOf("?"),n=i>-1?e.hash.slice(0,i):e.hash;return{data:e,hash:n,id:n.slice(1)}}function L(t,e){k(t)&&_(t)!==t.enabled&&(t.enabled=_(t),t.enabled?t.init():t.destroy())}function _(t){return window.innerWidth<=t.options.liveBreakpoint[0]&&window.innerWidth>=t.options.liveBreakpoint[1]&&k(t)}function k(t){let e=function(t,e=!0){return t.sort((function(t,i){return e?t-i:i-t}))}(t.options.liveBreakpoint,!1);return e=e.slice(0,2),2===e.length}function C(t){t.events.fire("onBeforeInit"),t.wrapper.classList.add(c),t.wrapper.querySelectorAll(t.options.trigger).forEach((e=>{e.addEventListener("click",(e=>function(t,e){t.options.isPreventDefault&&e.preventDefault();e.stopPropagation();const i=e.target.getAttribute(t.options.triggerAttr)||e.target.closest(t.options.trigger).getAttribute(t.options.triggerAttr);t.toggle(i,"manual")}(t,e))),e.classList.add(h)})),t.dataset=[],t.wrapper.querySelectorAll(t.options.receiver).forEach((e=>{const i=e.getAttribute(t.options.receiverAttr);if(t.dataset.push({id:i,el:e,active:!1}),"fade"===t.options.animation){r(e.parentElement,{overflow:"hidden",position:"relative"!==getComputedStyle(e).position?"relative":""});const t={position:(()=>"absolute"!==getComputedStyle(e).position?"absolute":"")(),inset:"0 0 auto"};setTimeout((()=>{r(e,t)}),1)}s(e,t.options.duration)})),function(t){document.querySelectorAll('a[href^="#"]').forEach((e=>{const i=e.getAttribute("href"),n="#"===i[0]?i.slice(1):x(i).id;n&&t.dataset.forEach((i=>{if(i.id===n){if(e.classList.contains(h))return;e.addEventListener("click",(e=>{t.options.isPreventDefault&&e.preventDefault(),t.toggle(n,"manual")}))}}))}))}(t),t.enabled&&(function(t){const e=x(),i=e.hash,n=e.id;return t.options.hash&&i.length&&t.dataset.filter((t=>t.id===n)).length}(t)?t.toggle(x().id,"hash"):function(t){let e=[];const i=t.options.activeSection;switch(t.options.animation){case"slide":switch(typeof i){case"number":e.push(i);break;case"object":t.options.allowExpandAll&&"slide"===t.options.animation?e=i.filter((function(t,e,i){return i.indexOf(t)===e})):e.push(i[0])}break;case"fade":switch(typeof i){case"number":e.push(m(t,i)?i:0);break;case"object":const n=i[0];e.push(m(t,n)?n:0)}}e.forEach((e=>{m(t,e)&&t.toggle(b(t,e),"auto")})),t.dataset.filter((t=>!t.active)).forEach((e=>t.closePanel(e.id)))}(t)),t.hasInitialized=!0,t.events.fire("onAfterInit")}class B{constructor(t,e){t&&(this.context=t,this.options={names:[],...e},this.eventNames=this.options.names,this.eventsList=[])}fire(t,e={}){if(!this.eventNames.includes(t))return void console.warn(`Cannot fire unrecognized event "${t}"`,this,e);const i={instance:this.context,eventName:t,...e},n=(this.context.config?this.context.config:this.context.options)[t];"function"==typeof n&&n(i);const o=this.eventsList[t];o?.length&&o.forEach((t=>{"function"==typeof t&&t(i)}))}add(t,e){t=function(t){let e=t;"on"!==t.slice(0,2)&&(e=e.charAt(0).toUpperCase()+e.slice(1),e="on"+e);return e}(t);this.eventNames.includes(t)?(void 0===this.eventsList[t]&&(this.eventsList[t]=[]),this.eventsList[t].push(e)):console.warn(`Cannot add unrecognized event "${t}"`)}}function I({target:t,attributeName:e="",defaultOptions:i={},numericValues:n=[],onIsString:o,dev:r=!1}){if(!t)return r&&console.warn("Target not found!",t),i;if(!t.hasAttribute(e))return r&&console.warn("Attribute not found from target",e),i;const s=t.getAttribute(e);if(!s.length)return i;if(!function(t){try{return JSON.parse(t)&&!!t}catch(t){return!1}}(s))return"function"==typeof o?o(s):console.warn("Not a JSON string",s),i;let a=JSON.parse(s);for(const[t,e]of Object.entries(a))"false"===e?a[t]=!1:"true"===e?a[t]=!0:n.includes(t)&&"string"==typeof e&&e.length>0?a[t]=parseFloat(e):a[t]=e;return{...i,...a}}class O{constructor(t){this.events=new B(this,{names:["onBeforeInit","onAfterInit","onBeforeOpen","onBeforeClose","onAfterOpen","onAfterClose","onDestroy","onUpdate"]}),this.originalOptions=t,this.options=I({target:this.wrapper,defaultOptions:{...g,...t},attributeName:d,numericValues:["duration","activeSection"],dev:g.dev}),this.init(),this.isAnimating=!1}on(t,e){this.events.add(t,e)}init(){if(!this.options.el)return void E(this,"warn","ETA Error, target not found!");if(this.wrapper=this.options.el,this.id="",this.current_id="",this.previous_id="",this.type="",this.hasInitialized=!1,this.enabled=!k(this)||_(this),this.count=this.wrapper.querySelectorAll(this.options.trigger).length,this.wrapper.classList.contains(c))return void E(this,"ETA has initialized");this.isFirst=!0,this.options.hash=!0===this.wrapper.hasAttribute(p)||this.options.hash,this.options.hashScroll=!0===this.wrapper.hasAttribute(u)||this.options.hashScroll;const t=this.wrapper.getAttribute(f);this.options.animation=null!==t?t:this.options.animation,this.wrapper.setAttribute(d,this.id),this.count<1?E(this,"warn","Quit init due to child panels not found",this):(this.enabled&&!this.hasInitialized&&C(this),!this.enabled&&this.hasInitialized&&this.destroy(),window.addEventListener("resize",function(t,e=150){let i;return(...n)=>{clearTimeout(i),i=setTimeout((()=>{t.apply(this,n)}),e)}}((t=>{return(e=this).update(),void L(e);var e}),300)),window.addEventListener("load",(t=>{return(e=this).update(),void L(e);var e})))}destroy(){switch(this.hasInitialized=!1,this.wrapper.classList.remove(c),this.wrapper.querySelectorAll(this.options.trigger).forEach((t=>{t.outerHTML=`${t.outerHTML}`})),this.dataset=[],this.options.animation){case"slide":(t=this).wrapper.querySelectorAll(t.options.receiver).forEach((t=>{r(t,{display:"",height:""}),a(t)})),A(t);break;case"fade":!function(t){t.wrapper.querySelectorAll(t.options.receiver).forEach((t=>{r(t,{opacity:"",visibility:"",position:"",inset:""}),r(t.parentElement,{height:"",position:""}),a(t),a(t.parentElement)})),A(t)}(this)}var t;this.events.fire("onDestroy")}update(){switch(this.options.animation){case"slide":break;case"fade":(t=this).dataset.forEach((e=>{const i=e.el,n=t.options.duration;e.active&&T(i,n),e.active||S(i,n)}))}var t;this.events.fire("onUpdate")}openPanel(t=this.current_id){if(!v(this,t))return;(()=>{this.dataset[y(this,t)].active=!0,function(t,e){if(!t.options.hash||"manual"!==t.type)return;const i=document.location.origin+document.location.pathname;document.location=i+"#"+e}(this,t),this.events.fire("onBeforeOpen",{type:this.type,current_id:this.current_id,previous_id:this.previous_id})})();const e=e=>{var n;"hash"===(n=this).type&&n.options.hashScroll&&window.addEventListener("load",(()=>setTimeout((()=>i({context:n})),100))),this.options.scrollIntoView&&i({context:this,target:e}),this.isAnimating=!1,E(this,"log","Stop animation."),this.events.fire("onAfterOpen",{target:e,type:this.type,current_id:this.current_id,previous_id:this.previous_id}),E(this,"log","after open",t)},{current:n}=w(this,t);switch(this.options.animation){case"slide":n.forEach((t=>function(t,e=500,i){0!==parseInt(o(t))&&"none"!==t.style.display.trim()||r(t,{boxSizing:"border-box",height:"0px",display:"block"}),setTimeout((()=>{r(t,{height:o(t),marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""})}),10),setTimeout((()=>{a(t),r(t,{height:""}),"function"==typeof i&&i()}),e+10)}(t,this.options.duration,(()=>e(t)))));break;case"fade":n.forEach((t=>T(t,this.options.duration,(()=>e(t)))))}!function(t,e){const{current:i,currentTrigger:n}=w(t,e||t.current_id);i&&i.forEach((t=>t.classList.add(l))),n&&n.forEach((t=>t.classList.add(l)))}(this,t);("fade"===this.options.animation||"slide"===this.options.animation&&!this.options.allowExpandAll)&&this.dataset.filter((e=>e.id!==t)).forEach((t=>{(t.active||this.isFirst)&&this.closePanel(t.id)})),this.isFirst&&(n[0].style.display="block",this.isFirst=!1)}closePanel(t=this.current_id){if(!v(this,t))return;this.events.fire("onBeforeClose",{type:this.type,current_id:this.current_id,previous_id:this.previous_id}),this.dataset[y(this,t)].active=!1;const e=e=>{this.events.fire("onAfterClose",{target:e}),this.isAnimating=!1,E(this,"log","Stop animation."),E(this,"log","after close",t)},{current:i}=w(this,t);switch(this.options.animation){case"slide":i.forEach((t=>function(t,e=500,i){const n=o(t);"0px"!==n?(r(t,{boxSizing:"border-box",height:n}),setTimeout((()=>{r(t,{height:"0px",marginTop:"0px",marginBottom:"0px",paddingTop:"0px",paddingBottom:"0px"})}),10),setTimeout((()=>{r(t,{display:"none",height:""}),a(t),"function"==typeof i&&i()}),e+10)):"function"==typeof i&&i()}(t,this.options.duration,(()=>e(t)))));break;case"fade":i.forEach((t=>S(t,this.options.duration,(()=>e(t)))))}A(this,t)}toggle(t,e="undefined",i=!1){if(!v(this,t))return void E(this,"warn","invalid id");const n=function(t,e){if(!v(t,e))return!1;if(t.hasInitialized&&t.options.avoidDoubleClick&&t.isAnimating)return E(t,"warn",`Block [${e}] to avoid double click on animating item.`),0;const i=t.dataset[y(t,e)].active,n="slide"===t.options.animation&&t.options.allowCollapseAll;return i&&n?-1:i&&!n?0:!i&&n?1:i||n?i?1:-1:1}(this,t);0!==n&&(this.isAnimating=!0,E(this,"log","Start animation."),this.type=e,this.previous_id=this.current_id?this.current_id:b(this,0),1===n?(this.current_id=t,this.openPanel(this.current_id)):this.closePanel(t))}toggleByIndex(t){this.toggle(b(this,t))}}window.ETAController=new class{constructor(){this.instances=[]}add(t){this.instances.push(t)}get(t){return this.instances.filter((e=>e.id===t))[0]}},window.ETA={init:t=>{void 0===t&&document.querySelectorAll("[data-eta]").forEach((e=>{window.ETAController.add(new O({el:e,...t}))})),window.ETAController.add(new O(t))},get:t=>window.ETAController.get(t)},window.ETA.init();var $=e.v;export{$ as EasyTabAccordion}; \ No newline at end of file + */var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};function i({context:t,target:e}){"auto"!==t.type&&("fade"===t.options.animation&&(e=t.wrapper),e||(e=t.wrapper),e.scrollIntoView({behavior:"smooth"}))}function n(t){const e=getComputedStyle(t);return parseInt(e.getPropertyValue("margin-top")+e.getPropertyValue("margin-bottom"),10)}function o(t){return t.scrollHeight+n(t)+"px"}function s(t,e){Object.assign(t.style,e)}function r(t,e){s(t,{transitionProperty:"height, margin, padding, opacity",transitionDuration:e+"ms",overflow:"hidden"})}function a(t){s(t,{boxSizing:"",paddingTop:"",paddingBottom:"",marginTop:"",marginBottom:""})}function c(t=""){return t+(+new Date).toString(16)+(1e8*Math.random()|0).toString(16)}function l(t,e){return!!t.dataset.filter((t=>t.id===e)).length}function h(t,e){return e>=0&&ee?t.options.receiver:t.options.trigger,n=e=>e?t.options.receiverAttr:t.options.triggerAttr;if(e){return{previous:t.wrapper.querySelectorAll(`${i(!0)}:not([${n(!0)}="${e}"])`),current:t.wrapper.querySelectorAll(`[${n(!0)}="${e}"]`),previousTrigger:t.wrapper.querySelectorAll(`${i(!1)}:not([${n(!1)}="${e}"])`),currentTrigger:t.wrapper.querySelectorAll(`[${n(!1)}="${e}"]`)}}return{current:t.wrapper.querySelectorAll(`[${n(!0)}]`),currentTrigger:t.wrapper.querySelectorAll(`[${n(!1)}]`)}}function p(t,e){return t.dataset.findIndex((t=>t.id===e))}function u(t,e){return t.dataset[e].id}function f(t,e){const{current:i,currentTrigger:n}=d(t,e);i.forEach((e=>e.classList.remove(t.options.activeClass))),n.forEach((e=>e.classList.remove(t.options.activeClass)))}function g(t,e,...i){t.options.dev&&console?.[e](...i)}function v(t,e=500,i){s(t,{opacity:"0",visibility:"hidden"}),setTimeout((()=>{a(t),"function"==typeof i&&i()}),e)}function m(t,e=500,i){r(t.parentElement,e),s(t,{opacity:"1",visibility:"visible"}),s(t.parentElement,{height:`${t.scrollHeight+n(t)}px`}),setTimeout((()=>{a(t),a(t.parentElement),"function"==typeof i&&i()}),e)}function w(t=document.location){const e=new URL(t),i=e.hash.indexOf("?"),n=i>-1?e.hash.slice(0,i):e.hash;return{data:e,hash:n,id:n.slice(1)}}function y(t,e){A(t)&&b(t)!==t.enabled&&(t.enabled=b(t),t.enabled?t.init():t.destroy())}function b(t){return window.innerWidth<=t.options.liveBreakpoint[0]&&window.innerWidth>=t.options.liveBreakpoint[1]&&A(t)}function A(t){let e=function(t,e=!0){return t.sort((function(t,i){return e?t-i:i-t}))}(t.options.liveBreakpoint,!1);return e=e.slice(0,2),2===e.length}t.d(e,{v:()=>k});const E="easy-tab-accordion-enabled",S="assigned-trigger-event",T="data-eta",x="data-eta-hash",B="data-eta-hash-scroll",C="data-eta-animation",I={el:void 0,id:void 0,trigger:"[data-eta-trigger]",triggerAttr:"data-eta-trigger",receiver:"[data-eta-receiver]",receiverAttr:"data-eta-receiver",activeClass:"active",animation:"slide",duration:450,scrollIntoView:!1,hash:!1,hashScroll:!1,liveBreakpoint:[],avoidDoubleClick:!0,dev:!1,activeSection:0,allowCollapseAll:!1,allowExpandAll:!1,isPreventDefault:!0};function L(t){t.events.fire("onBeforeInit"),t.wrapper.classList.add(E),t.wrapper.querySelectorAll(t.options.trigger).forEach((e=>{e.addEventListener("click",(e=>function(t,e){t.options.isPreventDefault&&e.preventDefault();e.stopPropagation();const i=e.target.getAttribute(t.options.triggerAttr)||e.target.closest(t.options.trigger).getAttribute(t.options.triggerAttr);t.toggle(i,"manual")}(t,e))),e.classList.add(S)})),t.dataset=[],t.wrapper.querySelectorAll(t.options.receiver).forEach((e=>{const i=e.getAttribute(t.options.receiverAttr);if(t.dataset.push({id:i,el:e,active:!1}),"fade"===t.options.animation){s(e.parentElement,{overflow:"hidden",position:"relative"!==getComputedStyle(e).position?"relative":""});const t={position:(()=>"absolute"!==getComputedStyle(e).position?"absolute":"")(),inset:"0 0 auto"};setTimeout((()=>{s(e,t)}),1)}r(e,t.options.duration)})),function(t){document.querySelectorAll('a[href^="#"]').forEach((e=>{const i=e.getAttribute("href"),n="#"===i[0]?i.slice(1):w(i).id;n&&t.dataset.forEach((i=>{if(i.id===n){if(e.classList.contains(S))return;e.addEventListener("click",(e=>{t.options.isPreventDefault&&e.preventDefault(),t.toggle(n,"manual")}))}}))}))}(t),t.enabled&&(function(t){const e=w(),i=e.hash,n=e.id;return t.options.hash&&i.length&&t.dataset.filter((t=>t.id===n)).length}(t)?t.toggle(w().id,"hash"):function(t){let e=[];const i=t.options.activeSection;switch(t.options.animation){case"slide":switch(typeof i){case"number":e.push(i);break;case"object":t.options.allowExpandAll&&"slide"===t.options.animation?e=i.filter((function(t,e,i){return i.indexOf(t)===e})):e.push(i[0])}break;case"fade":switch(typeof i){case"number":e.push(h(t,i)?i:0);break;case"object":const n=i[0];e.push(h(t,n)?n:0)}}e.forEach((e=>{h(t,e)&&t.toggle(u(t,e),"auto")})),t.dataset.filter((t=>!t.active)).forEach((e=>t.closePanel(e.id)))}(t)),t.hasInitialized=!0,t.events.fire("onAfterInit")}function P({target:t,attributeName:e="",defaultOptions:i={},numericValues:n=[],onIsString:o,dev:s=!1}){if(!t)return s&&console.warn("Target not found!",t),i;if(!t.hasAttribute(e))return s&&console.warn("Attribute not found from target",e),i;const r=t.getAttribute(e);if(!r.length)return i;if(!function(t){try{return JSON.parse(t)&&!!t}catch(t){return!1}}(r))return"function"==typeof o?o(r):console.warn("Not a JSON string",r),i;let a=JSON.parse(r);for(const[t,e]of Object.entries(a))"false"===e?a[t]=!1:"true"===e?a[t]=!0:n.includes(t)&&"string"==typeof e&&e.length>0?a[t]=parseFloat(e):a[t]=e;return{...i,...a}}class _{constructor(t,e){t&&(this.context=t,this.options={names:[],...e},this.eventNames=this.options.names,this.eventsList=[])}fire(t,e={}){if(!this.eventNames.includes(t))return void console.warn(`Cannot fire unrecognized event "${t}"`,this,e);const i={instance:this.context,eventName:t,...e},n=(this.context.config?this.context.config:this.context.options)[t];"function"==typeof n&&n(i);const o=this.eventsList[t];o?.length&&o.forEach((t=>{"function"==typeof t&&t(i)}))}add(t,e){t=function(t){let e=t;"on"!==t.slice(0,2)&&(e=e.charAt(0).toUpperCase()+e.slice(1),e="on"+e);return e}(t);this.eventNames.includes(t)?(void 0===this.eventsList[t]&&(this.eventsList[t]=[]),this.eventsList[t].push(e)):console.warn(`Cannot add unrecognized event "${t}"`)}}class k{constructor(t){this.options={...I,id:c("eta-"),...t},this.options.el?(this.options=P({target:this.options.el,defaultOptions:this.options,attributeName:T,numericValues:["duration","activeSection"],dev:I.dev}),this.events=new _(this,{names:["onBeforeInit","onAfterInit","onBeforeOpen","onBeforeClose","onAfterOpen","onAfterClose","onDestroy","onUpdate"]}),this.init(),this.isAnimating=!1):g(this,"warn","ETA Error, target not found!")}on(t,e){this.events.add(t,e)}init(){if(this.wrapper=this.options.el,this.id=this.options.id,this.current_id="",this.previous_id="",this.type="",this.hasInitialized=!1,this.enabled=!A(this)||b(this),this.count=this.wrapper.querySelectorAll(this.options.trigger).length,this.wrapper.classList.contains(E))return void g(this,"ETA has initialized");this.isFirst=!0,this.options.hash=!0===this.wrapper.hasAttribute(x)||this.options.hash,this.options.hashScroll=!0===this.wrapper.hasAttribute(B)||this.options.hashScroll;const t=this.wrapper.getAttribute(C);this.options.animation=null!==t?t:this.options.animation,this.wrapper.setAttribute(T,this.id),this.count<1?g(this,"warn","Quit init due to child panels not found",this):(this.enabled&&!this.hasInitialized&&L(this),!this.enabled&&this.hasInitialized&&this.destroy(),window.addEventListener("resize",function(t,e=150){let i;return(...n)=>{clearTimeout(i),i=setTimeout((()=>{t.apply(this,n)}),e)}}((t=>{return(e=this).update(),void y(e);var e}),300)),window.addEventListener("load",(t=>{return(e=this).update(),void y(e);var e})))}destroy(){switch(this.hasInitialized=!1,this.wrapper.classList.remove(E),this.wrapper.querySelectorAll(this.options.trigger).forEach((t=>{t.outerHTML=`${t.outerHTML}`})),this.dataset=[],this.options.animation){case"slide":(t=this).wrapper.querySelectorAll(t.options.receiver).forEach((t=>{s(t,{display:"",height:""}),a(t)})),f(t);break;case"fade":!function(t){t.wrapper.querySelectorAll(t.options.receiver).forEach((t=>{s(t,{opacity:"",visibility:"",position:"",inset:""}),s(t.parentElement,{height:"",position:""}),a(t),a(t.parentElement)})),f(t)}(this)}var t;this.events.fire("onDestroy")}update(){switch(this.options.animation){case"slide":break;case"fade":(t=this).dataset.forEach((e=>{const i=e.el,n=t.options.duration;e.active&&m(i,n),e.active||v(i,n)}))}var t;this.events.fire("onUpdate")}openPanel(t=this.current_id,e=!1){if(!l(this,t))return;const n=this.getPanelByID(t);if(e&&n.active)return void g(this,"warn",`openPanel(${t}) does not run as the panel is already opened!`);(()=>{this.getPanelByID(t).active=!0,function(t,e){if(!t.options.hash||"manual"!==t.type)return;const i=document.location.origin+document.location.pathname;document.location=i+"#"+e}(this,t),this.events.fire("onBeforeOpen",{type:this.type,current_id:this.current_id,previous_id:this.previous_id})})();const r=e=>{var n;"hash"===(n=this).type&&n.options.hashScroll&&window.addEventListener("load",(()=>setTimeout((()=>i({context:n})),100))),this.options.scrollIntoView&&i({context:this,target:e}),this.isAnimating=!1,g(this,"log","Stop animation."),this.events.fire("onAfterOpen",{target:e,type:this.type,current_id:this.current_id,previous_id:this.previous_id}),g(this,"log","after open",t)},{current:c}=d(this,t);switch(this.options.animation){case"slide":c.forEach((t=>function(t,e=500,i){0!==parseInt(o(t))&&"none"!==t.style.display.trim()||s(t,{boxSizing:"border-box",height:"0px",display:"block"}),setTimeout((()=>{s(t,{height:o(t),marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""})}),10),setTimeout((()=>{a(t),s(t,{height:""}),"function"==typeof i&&i()}),e+10)}(t,this.options.duration,(()=>r(t)))));break;case"fade":c.forEach((t=>m(t,this.options.duration,(()=>r(t)))))}!function(t,e){const{current:i,currentTrigger:n}=d(t,e||t.current_id);i&&i.forEach((e=>e.classList.add(t.options.activeClass))),n&&n.forEach((e=>e.classList.add(t.options.activeClass)))}(this,t);("fade"===this.options.animation||"slide"===this.options.animation&&!this.options.allowExpandAll)&&this.dataset.filter((e=>e.id!==t)).forEach((t=>{(t.active||this.isFirst)&&this.closePanel(t.id)})),this.isFirst&&(c[0].style.display="block",this.isFirst=!1)}closePanel(t=this.current_id,e=!1){if(!l(this,t))return;const i=this.getPanelByID(t);if(e&&!i.active)return void console.warn(`closePanel(${t}) does not run as the panel is already closed!`);this.events.fire("onBeforeClose",{type:this.type,current_id:this.current_id,previous_id:this.previous_id}),this.getPanelByID(t).active=!1;const n=e=>{this.events.fire("onAfterClose",{target:e}),this.isAnimating=!1,g(this,"log","Stop animation."),g(this,"log","after close",t)},{current:r}=d(this,t);switch(this.options.animation){case"slide":r.forEach((t=>function(t,e=500,i){const n=o(t);"0px"!==n?(s(t,{boxSizing:"border-box",height:n}),setTimeout((()=>{s(t,{height:"0px",marginTop:"0px",marginBottom:"0px",paddingTop:"0px",paddingBottom:"0px"})}),10),setTimeout((()=>{s(t,{display:"none",height:""}),a(t),"function"==typeof i&&i()}),e+10)):"function"==typeof i&&i()}(t,this.options.duration,(()=>n(t)))));break;case"fade":r.forEach((t=>v(t,this.options.duration,(()=>n(t)))))}f(this,t)}getPanelByID(t){return this.dataset[p(this,t)]}toggle(t,e="undefined",i=!1){if(!l(this,t))return void g(this,"warn","invalid id");const n=function(t,e){if(!l(t,e))return!1;if(t.hasInitialized&&t.options.avoidDoubleClick&&t.isAnimating)return g(t,"warn",`Block [${e}] to avoid double click on animating item.`),0;const i=t.dataset[p(t,e)].active,n="slide"===t.options.animation&&t.options.allowCollapseAll;return i&&n?-1:i&&!n?0:!i&&n?1:i||n?i?1:-1:1}(this,t);0!==n&&(this.isAnimating=!0,g(this,"log","Start animation."),this.type=e,this.previous_id=this.current_id?this.current_id:u(this,0),1===n?(this.current_id=t,this.openPanel(this.current_id)):this.closePanel(t))}toggleByIndex(t){this.toggle(u(this,t))}}window.ETAController=new class{constructor(){this.instances=[]}add(t){this.instances.push(t)}get(t){return this.instances.filter((e=>e.id===t))[0]}},window.ETA={init:t=>{void 0===t&&document.querySelectorAll("[data-eta]").forEach((e=>{window.ETAController.add(new k({el:e,...t}))})),window.ETAController.add(new k(t))},get:t=>window.ETAController.get(t)},window.ETA.init();var $=e.v;export{$ as EasyTabAccordion}; \ No newline at end of file diff --git a/package.json b/package.json index 95b1b52..fb78a10 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@viivue/easy-tab-accordion", "filename": "easy-tab-accordion", "prettyName": "Easy Tabs & Accordion", - "version": "2.2.0", + "version": "2.3.0", "description": "Javascript library to create tabs or accordion.", "homepage": "https://github.com/viivue/easy-tab-accordion", "repository": { diff --git a/src/_index.js b/src/_index.js index 4eefa7a..3710d9f 100644 --- a/src/_index.js +++ b/src/_index.js @@ -4,11 +4,11 @@ import {hashScroll, updateURL} from "./hash"; import { validID, getToggleState, - getIndexById, + getPanelIndexById, getElements, removeActiveClass, addActiveClass, getIdByIndex, log } from "./helpers"; -import {debounce} from "./utils"; +import {debounce, uniqueId} from "./utils"; import {initSetup, onLoad, onResize} from "./methods"; import {isLive, validBreakpoints} from "./responsive"; import {scrollIntoView} from "./animation"; @@ -17,24 +17,27 @@ import {EventsManager, getOptionsFromAttribute} from "@phucbm/os-util"; export class EasyTabAccordion{ constructor(options){ - // init events manager - this.events = new EventsManager(this, { - names: ['onBeforeInit', 'onAfterInit', 'onBeforeOpen', 'onBeforeClose', 'onAfterOpen', 'onAfterClose', 'onDestroy', 'onUpdate'], - }) - - // save options - this.originalOptions = options; + // update options + this.options = {...DEFAULTS, id: uniqueId('eta-'), ...options}; + if(!this.options.el){ + log(this, 'warn', 'ETA Error, target not found!'); + return; + } // get options init by data attribute (JSON format) - this.options - = getOptionsFromAttribute({ - target: this.wrapper, - defaultOptions: {...DEFAULTS, ...options}, + this.options = getOptionsFromAttribute({ + target: this.options.el, + defaultOptions: this.options, attributeName: ATTRS.container, numericValues: ['duration', 'activeSection'], dev: DEFAULTS.dev }); + // init events manager + this.events = new EventsManager(this, { + names: ['onBeforeInit', 'onAfterInit', 'onBeforeOpen', 'onBeforeClose', 'onAfterOpen', 'onAfterClose', 'onDestroy', 'onUpdate'], + }); + // init this.init(); @@ -53,13 +56,8 @@ export class EasyTabAccordion{ }; init(){ - if(!this.options.el){ - log(this, 'warn', 'ETA Error, target not found!'); - return; - } - this.wrapper = this.options.el; - this.id = ''; + this.id = this.options.id; this.current_id = ''; this.previous_id = ''; this.type = ''; @@ -100,6 +98,9 @@ export class EasyTabAccordion{ window.addEventListener('load', e => onLoad(this, e)); } + /****************************** + * Methods: ETA + ******************************/ destroy(){ this.hasInitialized = false; this.wrapper.classList.remove(CLASSES.enabled); @@ -140,15 +141,27 @@ export class EasyTabAccordion{ this.events.fire('onUpdate'); } - openPanel(id = this.current_id){ - if(!validID(this, id)) return; + + /****************************** + * Methods: Panel + ******************************/ + openPanel(panelId = this.current_id, isStrict = false){ + if(!validID(this, panelId)) return; + const panel = this.getPanelByID(panelId); + + // only open when is currently closing + if(isStrict && panel.active){ + log(this, 'warn', `openPanel(${panelId}) does not run as the panel is already opened!`); + return; + } const beforeOpen = () => { // update section status - this.dataset[getIndexById(this, id)].active = true; + //this.dataset[getPanelIndexById(this, id)].active = true; + this.getPanelByID(panelId).active = true; // update URL - updateURL(this, id); + updateURL(this, panelId); // events this.events.fire('onBeforeOpen', { @@ -182,11 +195,11 @@ export class EasyTabAccordion{ }); // log - log(this, 'log', 'after open', id); + log(this, 'log', 'after open', panelId); }; // open - const {current} = getElements(this, id); + const {current} = getElements(this, panelId); switch(this.options.animation){ case 'slide': current.forEach(el => slideDown(el, this.options.duration, () => afterOpen(el))); @@ -197,11 +210,11 @@ export class EasyTabAccordion{ } // update classes - addActiveClass(this, id); + addActiveClass(this, panelId); // close all others const closeAllOthers = this.options.animation === 'fade' || this.options.animation === 'slide' && !this.options.allowExpandAll; - if(closeAllOthers) this.dataset.filter(x => x.id !== id).forEach(item => { + if(closeAllOthers) this.dataset.filter(x => x.id !== panelId).forEach(item => { if(item.active || this.isFirst){ this.closePanel(item.id); } @@ -212,8 +225,15 @@ export class EasyTabAccordion{ } } - closePanel(id = this.current_id){ - if(!validID(this, id)) return; + closePanel(panelId = this.current_id, isStrict = false){ + if(!validID(this, panelId)) return; + const panel = this.getPanelByID(panelId); + + // only open when is currently closing + if(isStrict && !panel.active){ + console.warn(`closePanel(${panelId}) does not run as the panel is already closed!`); + return; + } // event: on Before Close this.events.fire('onBeforeClose', { @@ -223,7 +243,8 @@ export class EasyTabAccordion{ }); // event: on After Close - this.dataset[getIndexById(this, id)].active = false; + //this.dataset[getPanelIndexById(this, id)].active = false; + this.getPanelByID(panelId).active = false; const afterClose = (target) => { this.events.fire('onAfterClose', {target}); @@ -232,11 +253,11 @@ export class EasyTabAccordion{ log(this, 'log', 'Stop animation.'); // log - log(this, 'log', 'after close', id); + log(this, 'log', 'after close', panelId); }; // close animation - const {current} = getElements(this, id); + const {current} = getElements(this, panelId); switch(this.options.animation){ case 'slide': current.forEach(el => slideUp(el, this.options.duration, () => afterClose(el))); @@ -247,7 +268,11 @@ export class EasyTabAccordion{ } // update classes - removeActiveClass(this, id); + removeActiveClass(this, panelId); + } + + getPanelByID(panelId){ + return this.dataset[getPanelIndexById(this, panelId)]; } toggle(id, type = 'undefined', force = false){ diff --git a/src/configs.js b/src/configs.js index c4bda38..f9c2d67 100644 --- a/src/configs.js +++ b/src/configs.js @@ -1,11 +1,8 @@ -import {uniqueId} from './utils' - /** * Classes * */ export const CLASSES = { enabled: 'easy-tab-accordion-enabled', - active: 'active', hasAssignedTriggerEvent: 'assigned-trigger-event', }; /** @@ -24,8 +21,8 @@ export const ATTRS = { * */ export const DEFAULTS = { // selectors - el: document.querySelector('[data-eta]'), // DOM element - id: uniqueId('eta-'), + el: undefined, // DOM element + id: undefined, trigger: '[data-eta-trigger]', // string selector triggerAttr: 'data-eta-trigger', // attribute name receiver: '[data-eta-receiver]', // string selector diff --git a/src/helpers.js b/src/helpers.js index 948bd19..2ae2603 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,5 +1,4 @@ import {arrayUnique} from "./utils"; -import {CLASSES, ATTRS} from './configs' /** * Has valid id @@ -36,7 +35,7 @@ export function getToggleState(context, id){ } } - const open = context.dataset[getIndexById(context, id)].active; + const open = context.dataset[getPanelIndexById(context, id)].active; const allowCollapseAll = context.options.animation === 'slide' ? context.options.allowCollapseAll : false; // is open and allow collapse all => close @@ -133,19 +132,19 @@ export function getElements(context, id){ /** - * Get index by ID + * Get panel index by panel ID * @param context - * @param id + * @param panelId * @returns {number} * @since 2.0.0 */ -export function getIndexById(context, id){ - return context.dataset.findIndex(x => x.id === id); +export function getPanelIndexById(context, panelId){ + return context.dataset.findIndex(x => x.id === panelId); } /** - * Get ID by index + * Get panel ID by panel index * @param context * @param index * @returns {*} @@ -166,8 +165,8 @@ export function removeActiveClass(context, id){ const {current, currentTrigger} = getElements(context, id); // update classes - current.forEach(item => item.classList.remove(CLASSES.active)); - currentTrigger.forEach(item => item.classList.remove(CLASSES.active)); + current.forEach(item => item.classList.remove(context.options.activeClass)); + currentTrigger.forEach(item => item.classList.remove(context.options.activeClass)); } @@ -181,8 +180,8 @@ export function addActiveClass(context, id){ const {current, currentTrigger} = getElements(context, id ? id : context.current_id); // update classes - if(current) current.forEach(item => item.classList.add(CLASSES.active)); - if(currentTrigger) currentTrigger.forEach(item => item.classList.add(CLASSES.active)); + if(current) current.forEach(item => item.classList.add(context.options.activeClass)); + if(currentTrigger) currentTrigger.forEach(item => item.classList.add(context.options.activeClass)); } export function log(context, status, ...message){