interface NeuHTMLElement extends HTMLElement { toggleRef: any; neuCurrentClass: string; neuActive: boolean; } let neuClickElements: NodeListOf, neuFocusElements: NodeListOf, neuClickedElements: NodeListOf, neuHoverElements: NodeListOf; const stateList = ['neu-bordered', 'neu-flat', 'neu-pressed', 'neu-concave', 'neu-convex']; const toggle = (el: NeuHTMLElement, datasetName: string, e: Event) => { if (el.dataset[datasetName] && !stateList.includes(el.dataset[datasetName])) { console.error('[Neu-Axentix] Error: invalid classname on', el); return; } if (datasetName === 'neuClick') { if (el.neuActive) { if (e.type === 'mousedown' || e.type === 'touchstart') return; el.neuActive = false; } else { if ( e.type === 'mouseup' || e.type === 'mouseleave' || e.type === 'touchend' || e.type === 'touchmove' ) { return; } el.neuActive = true; } } if (datasetName === 'neuHover') { if (!el.neuActive && e.type === 'mouseenter') { el.neuActive = true; } else if (!el.neuActive && e.type === 'mouseleave') { return; } else if (el.neuActive && e.type === 'mouseleave') { el.neuActive = false; } } const nextClass = el.dataset[datasetName]; if (el.neuCurrentClass) { el.classList.remove(el.neuCurrentClass); el.dataset[datasetName] = el.neuCurrentClass; } else { el.dataset[datasetName] = ''; } if (nextClass) { el.classList.add(nextClass); el.neuCurrentClass = nextClass; } else { el.neuCurrentClass = ''; } }; const setupClasses = (el: NeuHTMLElement) => { const classList = el.className.split(' '); const neumorphClasses = classList.filter((className) => stateList.includes(className)); if (neumorphClasses.length >= 2) { const newClasses = classList.filter((className) => !neumorphClasses.includes(className)); newClasses.push(neumorphClasses[0]); el.className = newClasses.join(' '); } el.neuCurrentClass = neumorphClasses[0] || ''; }; const setup = () => { neuClickElements = document.querySelectorAll('[data-neu-click]'); neuFocusElements = document.querySelectorAll('[data-neu-focus]'); neuClickedElements = document.querySelectorAll('[data-neu-clicked]'); neuHoverElements = document.querySelectorAll('[data-neu-hover]'); neuClickedElements.forEach((el) => { setupClasses(el); el.toggleRef = toggle.bind(null, el, 'neuClicked'); el.addEventListener('click', el.toggleRef); }); neuClickElements.forEach((el) => { setupClasses(el); el.toggleRef = toggle.bind(null, el, 'neuClick'); el.addEventListener('mousedown', el.toggleRef); el.addEventListener('mouseleave', el.toggleRef); el.addEventListener('mouseup', el.toggleRef); if ('ontouchstart' in document.documentElement) { el.addEventListener('touchstart', el.toggleRef); el.addEventListener('touchend', el.toggleRef); } }); neuFocusElements.forEach((el) => { setupClasses(el); el.toggleRef = toggle.bind(null, el, 'neuFocus'); el.addEventListener('focus', el.toggleRef); el.addEventListener('blur', el.toggleRef); }); neuHoverElements.forEach((el) => { setupClasses(el); el.toggleRef = toggle.bind(null, el, 'neuHover'); el.addEventListener('mouseenter', el.toggleRef); el.addEventListener('mouseleave', el.toggleRef); }); }; export const reset = () => { if (neuClickedElements) { neuClickedElements.forEach((el) => { el.removeEventListener('click', el.toggleRef); el.toggleRef = undefined; }); } if (neuClickElements) { neuClickElements.forEach((el) => { el.removeEventListener('mousedown', el.toggleRef); el.removeEventListener('mouseleave', el.toggleRef); el.removeEventListener('mouseup', el.toggleRef); if ('ontouchstart' in document.documentElement) { el.removeEventListener('touchstart', el.toggleRef); el.removeEventListener('touchend', el.toggleRef); } el.toggleRef = undefined; }); } if (neuFocusElements) { neuFocusElements.forEach((el) => { el.removeEventListener('focus', el.toggleRef); el.removeEventListener('blur', el.toggleRef); el.toggleRef = undefined; }); } if (neuHoverElements) { neuHoverElements.forEach((el) => { el.removeEventListener('mouseenter', el.toggleRef); el.removeEventListener('mouseleave', el.toggleRef); el.toggleRef = undefined; }); } setup(); }; document.addEventListener('DOMContentLoaded', setup);