flash.moe/assets/makai.js/elems/sidelist.jsx

174 lines
5.2 KiB
React
Raw Permalink Normal View History

const MakaiSideListEmptyElement = function(element) {
if(!(element instanceof Element))
element = <div class="sidelist-empty">
<div class="sidelist-empty-icon"></div>
<div class="sidelist-empty-label">Nothing yet!</div>
</div>;
const iconElem = element.querySelector('.sidelist-empty-icon');
const labelElem = element.querySelector('.sidelist-empty-label');
return {
get element() { return element; },
get icon() { return iconElem.textContent; },
set icon(value) {
iconElem.textContent = value;
},
get label() { return labelElem.textContent; },
set label(value) {
labelElem.textContent = value;
},
};
};
const MakaiSideListItemElement = function(element, icon, link, click) {
const linkClass = 'sidelist-item-link';
if(!(element instanceof Element)) {
element = <a class="sidelist-item">
<div class="sidelist-item-icon">{icon ?? (Math.random() < 0.5 ? '☆' : '★')}</div>
<div class="sidelist-item-label">{element ?? ''}</div>
</a>;
if(typeof link === 'string') {
element.classList.add(linkClass);
element.href = link;
}
if(typeof click === 'function')
element.onclick = click;
}
const isLink = () => element.classList.contains(linkClass);
const iconElem = element.querySelector('.sidelist-item-icon');
const labelElem = element.querySelector('.sidelist-item-label');
return {
get element() { return element; },
get isLink() { return isLink(); },
get link() { return element.href ?? ''; },
set link(value) {
if(value === undefined)
value = null;
element.href = value;
element.classList.toggle(linkClass, typeof value === 'string' && value !== '');
},
get icon() { return iconElem.textContent; },
set icon(value) {
iconElem.textContent = value;
},
get label() { return labelElem.textContent; },
set label(value) {
labelElem.textContent = value;
},
};
};
const MakaiSideListElement = function(element) {
if(!(element instanceof Element))
element = <div class="sidelist">
<div class="sidelist-title">{element ?? ''}</div>
<div class="sidelist-body"/>
</div>;
const titleElem = element.querySelector('.sidelist-title');
const bodyElem = element.querySelector('.sidelist-body');
const emptyElem = new MakaiSideListEmptyElement(bodyElem.querySelector('.sidelist-empty'));
const getBodyChildren = () => {
const elems = [];
for(const elem of bodyElem.children) {
let item = elem;
if(item.classList.contains('sidelist-empty'))
item = new MakaiSideListEmptyElement(item);
else if(item.classList.contains('sidelist-item'))
item = new MakaiSideListItemElement(item);
elems.push(item);
}
return elems;
};
const insertEmptyElement = () => {
if(!bodyElem.contains(emptyElem.element) && bodyElem.childElementCount < 1)
bodyElem.appendChild(emptyElem.element);
};
const clearEmptyElement = () => {
if(bodyElem.contains(emptyElem.element))
bodyElem.removeChild(emptyElem.element);
};
const clearBody = insertEmpty => {
$rc(bodyElem);
insertEmptyElement();
};
const addItemCommon = (item, ...args) => {
if(typeof item === 'string')
item = new MakaiSideListItemElement(item, ...args);
else if(typeof item !== 'object' || item === null)
throw 'item must be a non-null object';
const elem = 'element' in item ? item.element : item;
if(bodyElem.contains(elem))
return;
clearEmptyElement();
return {
item: item,
elem: elem,
};
};
const appendItem = (...args) => {
const common = addItemCommon(...args);
if(common === undefined)
return;
bodyElem.appendChild(common.elem);
return common.item;
};
const prependItem = (...args) => {
const common = addItemCommon(...args);
if(common === undefined)
return;
bodyElem.insertBefore(common.elem, bodyElem.firstChild);
return common.item;
};
const removeItem = item => {
const elem = 'element' in item ? item.element : item;
if(bodyElem.contains(elem))
bodyElem.removeChild(elem);
insertEmptyElement();
return item;
};
if(bodyElem.childElementCount < 1)
insertEmptyElement();
return {
get element() { return element; },
get titleElem() { return titleElem; },
get bodyElem() { return bodyElem; },
get emptyElem() { return emptyElem; },
get children() { return getBodyChildren(); },
get title() { return titleElem.textContent; },
set title(value) {
titleElem.textContent = value;
},
appendItem: appendItem,
prependItem: prependItem,
removeItem: removeItem,
};
};