@n8d/htwoo-core
Version:
hTWOo is a Fluent Design Framework purely in HTML and CSS
142 lines • 5.17 kB
JavaScript
/**
* Array to store overflow items for each container
*/
const overflowItems = [];
/**
* Default offset for overflow width calculations
*/
const defaultOffset = 40;
/**
* Handle overflow items based on available container width
* @param targetWidth - Width of the overflow container
* @param children - Child elements inside the overflow container
* @param curContainer - Current overflow container
* @param itemIndex - Index of the current container
*/
const getOverflowItems = (targetWidth, children, curContainer, itemIndex) => {
// Filter items that should go into overflow
let curOverFlowItems = overflowItems[itemIndex].filter(item => {
return item.overallWidth > targetWidth - defaultOffset;
});
// Filter items that can fit in the container
let curItems = overflowItems[itemIndex].filter(item => {
return item.overallWidth < targetWidth - defaultOffset;
});
// Flyout Button ellipses
const overflowControl = curContainer.querySelector('.hoo-buttonicon-overflow .hoo-buttonflyout');
if (!overflowControl)
return;
// Add items to overflow menu
if (overflowControl && overflowControl.children.length < curOverFlowItems.length) {
for (let i = 0; i < curOverFlowItems.length; i++) {
const itemRef = curOverFlowItems[i].ref;
const element = curContainer.querySelector(`[data-ref="${itemRef}"]`);
if (element) {
let listItem = document.createElement('li');
// Moves the Element into a new list item with all Events attached
listItem.appendChild(element);
// Append list item
overflowControl.appendChild(listItem);
}
}
}
// Toggle overflow button visibility
if (overflowControl.children.length !== 0) {
const buttonEnabled = overflowControl.closest('.hoo-buttonicon-overflow');
if (buttonEnabled) {
buttonEnabled.classList.add('is-active');
}
}
else {
const buttonEnabled = overflowControl.closest('.hoo-buttonicon-overflow');
if (buttonEnabled) {
buttonEnabled.classList.remove('is-active');
}
}
// Move items back from overflow if there's room
if (overflowControl && overflowControl.children.length > curOverFlowItems.length) {
for (let i = 0; i < curItems.length; i++) {
const itemRef = curItems[i].ref;
const overflowElement = overflowControl.querySelector(`[data-ref="${itemRef}"]`);
if (overflowElement) {
// Move elements back from overflow menu
curContainer.appendChild(overflowElement);
}
}
}
/**
* Cleanup empty <li> elements
*/
for (let i = 0; i < overflowControl.children.length; i++) {
if (overflowControl.children[i].children.length === 0) {
overflowControl.children[i].remove();
}
}
};
/**
* Handle all entries in the overflow menu
* @param entry - ResizeObserver entry
* @param index - Index of the entry
*/
const entryHandler = (entry, index) => {
const parent = entry.target.parentElement;
if (!parent)
return;
const childButtons = Array.from(parent.querySelectorAll('.hoo-overflow > *'));
if (childButtons.length > 0) {
getOverflowItems(parent.clientWidth, childButtons, entry.target, index);
}
};
/**
* Handle the overflow behavior for all '.hoo.overflow' containers
* @param entries - ResizeObserver entries
*/
const overflow = (entries) => {
// Handle the overflow behaviour for all '.hoo.overflow' containers
entries.forEach((item, index) => {
if (item.target.children) {
initOverflowElements(item.target.children, index);
// Handle the resizing
entryHandler(item, index);
}
});
};
/**
* Initialize overflow elements data
* @param children - Collection of child elements
* @param index - Container index
*/
const initOverflowElements = (children, index) => {
let overallWidth = 0;
if (overflowItems.length <= index) {
overflowItems[index] = [];
for (let i = 0; i < children.length; i++) {
const child = children[i];
overallWidth += child.clientWidth;
if (!child.classList.contains("hoo-buttonicon-overflow")) {
const currentItem = {
chlld: child,
ref: "ref-" + index + "-" + i,
width: child.clientWidth,
overallWidth: overallWidth
};
child.dataset.ref = currentItem.ref;
overflowItems[index].push(currentItem);
}
}
}
};
/**
* Initialize overflow functionality by setting up ResizeObserver
* for all overflow containers
*/
export const init = () => {
const items = document.querySelectorAll('.hoo-overflow');
if (items.length !== 0) {
const ofObserver = new ResizeObserver(overflow);
items.forEach(item => {
ofObserver.observe(item);
});
}
};
//# sourceMappingURL=overflow.js.map