first commit

This commit is contained in:
2025-11-25 01:21:34 +02:00
commit 4af0db8263
84 changed files with 18906 additions and 0 deletions
+181
View File
@@ -0,0 +1,181 @@
import './dropdown.css';
import { Ut } from '../../utils/Ut';
import { El } from '../../utils/dom';
////////////////////
// DopDown Menu
////////////////////
export class Dropdown {
/**
* Dropdown Constructor
*/
constructor(target, opts) {
this.target = target;
if (this.target.dxData('dropdown')) {
return;
}
this.target.dxData('dropdown', this);
this.opts = { ... { items: [] }, ... opts };
this.isOpened = false;
this.isBusy = false;
this.create();
this.setEvents();
}
/**
* Dropdown, Create UI
*/
create() {
this.ui = El('div', { class: 'sp-dropdown hide' });
if (this.opts.cls) {
this.ui.classList.add(this.opts.cls);
}
const list = El('ul');
if (this.opts.items.length) {
this.ui.append(list);
}
this.items = [];
this.opts.items.forEach(item => {
this.items.push(
list.appendChild( El('li', { class: 'color-'+ (item.color || 'black'), 'data-id': item.id },
(item.icon ? El('i', { class: 'fa fa-'+ item.icon }) : null),
item.name
))
);
});
this.target.after(this.ui);
Ut.trigger(this.opts.onInit, this);
}
/**
* Dropdown, Set UI Position
*/
setPosition() {
let left = Math.round(this.target.offsetLeft);
if ((this.ui.clientWidth + left) > window.innerWidth) {
left = 0;
}
this.ui.style.top = (Math.round(this.target.offsetTop) + this.target.clientHeight + 2) + 'px';
this.ui.style.left = left + 'px';
}
/**
* Dropdown, Show UI
*/
show() {
if (this.isBusy || this.isOpened) {
return;
}
Ut.trigger(this.opts.onShow, this);
this.setPosition();
this.ui.classList.remove('hide');
this.ui.classList.add('opened');
this.target.classList.add('dropdown-opened');
this.isOpened = true;
}
/**
* Dropdown, Hide UI
*/
hide() {
if (!this.isOpened) {
return;
}
Ut.trigger(this.opts.onHide, this);
let that = this;
this.ui.addEventListener('transitionend', _ => !this.ui.classList.contains('opened') && this.ui.classList.add('hide'), { once: true });
this.ui.classList.remove('opened');
this.target.classList.remove('dropdown-opened');
this.isOpened = false;
};
/**
* Dropdown, Set Evensts
*/
setEvents() {
let that = this;
document.body.dxOn('click.dropdown', _ => that.hide());
this.target.dxOn('click', e => {
e.stopPropagation();
if (!that.ui.classList.contains('opened')) {
that.show();
}
else {
that.hide();
}
});
this.ui.dxOn('click', 'li', (_, t) => {
Ut.trigger(that.opts.items[ t.dxIndex(that.items) ].handler);
Ut.trigger(that.opts.onChange, t.dataset.id, this);
});
let tm = null;
window.dxOn('resize.dropdown' + this.ekey + ' orientationchange.dropdown' + this.ekey, _ => {
if (tm) {
clearTimeout(tm);
tm = null;
}
tm = setTimeout(_ => that.setPosition(), 100);
});
}
/**
* Dropdown, Destroy
*/
destroy() {
this.ui.remove();
document.body.dxOff('click.dropdown');
window.dxOff('resize.dropdown' + this.ekey + ' orientationchange.dropdown' + this.ekey);
this.target.dxRemoveData('dropdown');
Ut.trigger(this.events.destroy, this);
return this.target;
}
}
//Ut.extendNodeUx(Dropdown);