Skip to content

Commit

Permalink
Merge pull request #47 from viivue/2.1.7
Browse files Browse the repository at this point in the history
merge 2.1.7
  • Loading branch information
phucbm authored Aug 4, 2023
2 parents 91fa9f4 + 8f06351 commit 8d6694c
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 165 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ Add these attributes on the wrapper element.
| `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

Expand All @@ -229,6 +230,9 @@ const eta = ETA.get('my-eta');

// use methods
eta.update();
eta.on("open", () => {
// do something
});
```

## Deployment
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,8 @@
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.3.1",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"@phucbm/os-util": "^0.0.4"
}
}
139 changes: 42 additions & 97 deletions src/_index.js
Original file line number Diff line number Diff line change
@@ -1,101 +1,58 @@
import {slideDown, slideUp, destroySlide, updateSlide} from "./slide";
import {fadeIn, fadeOut, destroyFade, updateFade} from "./fade";
import {getHash, isValidHash, hashScroll, updateURL} from "./hash";
import {hashScroll, updateURL} from "./hash";
import {
validID,
getToggleState,
getIndexById,
getElements,
removeActiveClass, addActiveClass, getIdByIndex, defaultActiveSections, log, getOptions
removeActiveClass, addActiveClass, getIdByIndex, log
} from "./helpers";
import {debounce, uniqueId} from "./utils";
import {debounce} from "./utils";
import {initSetup, onLoad, onResize} from "./methods";
import {isLive, validBreakpoints} from "./responsive";
import {scrollIntoView} from "./animation";
import {CLASSES, ATTRS, DEFAULTS} from './configs';
import {EventsManager, getOptionsFromAttribute} from "@phucbm/os-util";

export class EasyTabAccordion{
constructor(options){
this._class = {
enabled: 'easy-tab-accordion-enabled',
active: 'active',
hasAssignedTriggerEvent: 'assigned-trigger-event'
};
this._attr = {
container: 'data-eta',
trigger: 'data-eta-trigger',
receiver: 'data-eta-receiver',
hash: 'data-eta-hash',
hashScroll: 'data-eta-hash-scroll',
animation: 'data-eta-animation',
};
this.defaultOptions = {
// selectors
el: document.querySelector(`[${this._attr.container}]`), // DOM element
id: uniqueId('eta-'),
trigger: `[${this._attr.trigger}]`, // string selector
triggerAttr: this._attr.trigger, // attribute name
receiver: `[${this._attr.receiver}]`, // string selector
receiverAttr: this._attr.receiver, // attribute name
activeClass: this._class.active,

// animation
animation: 'slide', // slide, fade
duration: 450,
scrollIntoView: false, // scroll panel into view when open

// hash
hash: false, // update hash URL
hashScroll: false, // scroll into view when page loaded with a valid hash

// responsive
liveBreakpoint: [], // [1920, 1024] => destroy if window.width if bigger than 1920 or less than 1024

// avoid double click
avoidDoubleClick: true,

// dev mode => enable console.log
dev: false,

// open/close
activeSection: 0, // default opening sections, will be ignored if there's a valid hash, allow array of index [0,1,2] for slide animation only
allowCollapseAll: false, // for slide animation only
allowExpandAll: false, // for slide animation only

// prevent default when click to trigger element
isPreventDefault: true,

// events
onBeforeInit: (data) => {
},
onAfterInit: (data) => {
},
onBeforeOpen: (data, el) => {
},
onBeforeClose: (data, el) => {
},
onAfterOpen: (data, el) => {
},
onAfterClose: (data, el) => {
},
onDestroy: (data) => {
},
onUpdate: (data) => {
},
};
// init events manager
this.events = new EventsManager(this, {
names: ['onBeforeInit', 'onAfterInit', 'onBeforeOpen', 'onBeforeClose', 'onAfterOpen', 'onAfterClose', 'onDestroy', 'onUpdate'],
})

// save options
this.originalOptions = options;

// get options init by data attribute (JSON format)
this.options
= getOptionsFromAttribute({
target: this.wrapper,
defaultOptions: {...DEFAULTS, ...options},
attributeName: ATTRS.container,
numericValues: ['duration', 'activeSection'],
dev: DEFAULTS.dev
});

// init
this.init();

// avoid double click
this.isAnimating = false;
}

init(){
// setup
this.options = {...this.defaultOptions, ...this.originalOptions};
/******************************
* EVENTS
******************************/
/**
* Assign late-events
*/
on(eventName, callback){
this.events.add(eventName, callback);
};

init(){
if(!this.options.el){
log(this, 'warn', 'ETA Error, target not found!');
return;
Expand All @@ -111,7 +68,7 @@ export class EasyTabAccordion{
this.count = this.wrapper.querySelectorAll(this.options.trigger).length;

// check if ETA has already initialized
if(this.wrapper.classList.contains(this._class.enabled)){
if(this.wrapper.classList.contains(CLASSES.enabled)){
log(this, 'ETA has initialized');
return;
}
Expand All @@ -120,17 +77,14 @@ export class EasyTabAccordion{
this.isFirst = true;

// update hash from attribute
this.options.hash = this.wrapper.hasAttribute(this._attr.hash) === true ? true : this.options.hash;
this.options.hashScroll = this.wrapper.hasAttribute(this._attr.hashScroll) === true ? true : this.options.hashScroll;
this.options.hash = this.wrapper.hasAttribute(ATTRS.hash) === true ? true : this.options.hash;
this.options.hashScroll = this.wrapper.hasAttribute(ATTRS.hashScroll) === true ? true : this.options.hashScroll;
// update animation from attribute
const animationValue = this.wrapper.getAttribute(this._attr.animation);
const animationValue = this.wrapper.getAttribute(ATTRS.animation);
this.options.animation = animationValue !== null ? animationValue : this.options.animation;

// get options init by data attribute (JSON format)
this.options = getOptions(this);

// assign id to wrapper
this.wrapper.setAttribute(this._attr.container, this.id);
this.wrapper.setAttribute(ATTRS.container, this.id);

if(this.count < 1){
log(this, 'warn', 'Quit init due to child panels not found', this);
Expand All @@ -141,23 +95,14 @@ export class EasyTabAccordion{
if(this.enabled && !this.hasInitialized) initSetup(this);
if(!this.enabled && this.hasInitialized) this.destroy();

// toggle via hash
if(this.enabled){
if(isValidHash(this)){
this.toggle(getHash().id, 'hash');
}else{
defaultActiveSections(this);
}
}

// watch for resize/load events
window.addEventListener('resize', debounce(e => onResize(this, e), 300));
window.addEventListener('load', e => onLoad(this, e));
}

destroy(){
this.hasInitialized = false;
this.wrapper.classList.remove(this._class.enabled);
this.wrapper.classList.remove(CLASSES.enabled);

// loop through triggers
this.wrapper.querySelectorAll(this.options.trigger).forEach(trigger => {
Expand All @@ -178,7 +123,7 @@ export class EasyTabAccordion{
}

// event: onDestroy
this.options.onDestroy(this);
this.events.fire('onDestroy');
}

update(){
Expand All @@ -192,7 +137,7 @@ export class EasyTabAccordion{
}

// event: onUpdate
this.options.onUpdate(this);
this.events.fire('onUpdate');
}

openPanel(id = this.current_id){
Expand All @@ -206,7 +151,7 @@ export class EasyTabAccordion{
updateURL(this, id);

// events
this.options.onBeforeOpen(this);
this.events.fire('onBeforeOpen');
};

// event: on Before Open
Expand All @@ -225,7 +170,7 @@ export class EasyTabAccordion{
this.isAnimating = false;
log(this, 'log', 'Stop animation.');

this.options.onAfterOpen(this, target);
this.events.fire('onAfterOpen', {target});

// log
log(this, 'log', 'after open', id);
Expand Down Expand Up @@ -262,12 +207,12 @@ export class EasyTabAccordion{
if(!validID(this, id)) return;

// event: on Before Close
this.options.onBeforeClose(this);
this.events.fire('onBeforeClose');

// event: on After Close
this.dataset[getIndexById(this, id)].active = false;
const afterClose = (target) => {
this.options.onAfterClose(this, target);
this.events.fire('onAfterClose', {target});

// toggle animating status
this.isAnimating = false;
Expand Down
60 changes: 60 additions & 0 deletions src/configs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {uniqueId} from './utils'

/**
* Classes
* */
export const CLASSES = {
enabled: 'easy-tab-accordion-enabled',
active: 'active',
hasAssignedTriggerEvent: 'assigned-trigger-event',
};
/**
* Attributes
* */
export const ATTRS = {
container: 'data-eta',
trigger: 'data-eta-trigger',
receiver: 'data-eta-receiver',
hash: 'data-eta-hash',
hashScroll: 'data-eta-hash-scroll',
animation: 'data-eta-animation',
};
/**
* Defaults
* */
export const DEFAULTS = {
// selectors
el: document.querySelector('[data-eta]'), // DOM element
id: uniqueId('eta-'),
trigger: '[data-eta-trigger]', // string selector
triggerAttr: 'data-eta-trigger', // attribute name
receiver: '[data-eta-receiver]', // string selector
receiverAttr: 'data-eta-receiver', // attribute name
activeClass: 'active',

// animation
animation: 'slide', // slide, fade
duration: 450,
scrollIntoView: false, // scroll panel into view when open

// hash
hash: false, // update hash URL
hashScroll: false, // scroll into view when page loaded with a valid hash

// responsive
liveBreakpoint: [], // [1920, 1024] => destroy if window.width if bigger than 1920 or less than 1024

// avoid double click
avoidDoubleClick: true,

// dev mode => enable console.log
dev: false,

// open/close
activeSection: 0, // default opening sections, will be ignored if there's a valid hash, allow array of index [0,1,2] for slide animation only
allowCollapseAll: false, // for slide animation only
allowExpandAll: false, // for slide animation only

// prevent default when click to trigger element
isPreventDefault: true,
};
Loading

0 comments on commit 8d6694c

Please sign in to comment.