@evermade/menu-toolkit
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -81,2 +81,10 @@ function animate(options) { | ||
/** | ||
* Protect agains multiple initializations with checking data-menu="root" attribute. | ||
*/ | ||
const isInitialized = $ulRoot.getAttribute('data-menu') === 'root'; | ||
if (isInitialized) { | ||
console.log('menuFromHTML: Menu already initialized.', $ulRoot); | ||
return; | ||
} | ||
/** | ||
* Called before the component is initialized. | ||
@@ -83,0 +91,0 @@ */ |
@@ -1,2 +0,2 @@ | ||
/*! @evermade/menu-toolkit 1.0.1 */ | ||
function e(e){const{element:t,animationClass:n,onReady:o,maxExecutionTime:a}=e;t.classList.add(n);let s=!1;function u(){t.removeEventListener("animationend",u,!1),"function"==typeof o&&(s=!0,o(t,n))}t.addEventListener("animationend",u,!1),"function"==typeof o&&a&&setTimeout((()=>{s||(s=!0,o(t,n),t.removeEventListener("animationend",u,!1))}),a)}function t(t,n){const o=t;let a=[];if(!(t instanceof HTMLElement))throw new Error("Menu element must be an valid HTMLElement");const s=Object.assign(Object.assign({},{action:"click",subMenuAnchorSelector:".menu-item-has-children > a",subMenuListItemSelector:".menu-item-has-children",openSubMenuClass:"is-open",buttonClass:"",visuallyHiddenClass:"screen-reader-text",expandChildMenuText:"Sub menu",hoverTimeout:750,buttonIcon:'<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"></path></svg>',shouldWrapAnchorToButton:null,activeListItemSelector:".current-menu-item",openActiveSubMenuOnCreate:!1,closeSubMenuOnOutsideClick:!0,animateOpen:!1,animateClose:!1,animateOpenClass:"animate-open",animateCloseClass:"animate-close",animateOpenMaxExecutionTime:250,animateCloseMaxExecutionTime:250,onBeforeCreate:null,onAfterCreate:null,onBeforeOpenSubMenu:null,onAfterOpenSubMenu:null,onBeforeCloseSubMenu:null,onAfterCloseSubMenu:null}),n),u=Array.from(o.querySelectorAll(s.subMenuAnchorSelector)),l=Array.from(o.querySelectorAll(s.subMenuListItemSelector)),r=e=>{const t=e.target.closest('[data-menu="sub-toggle"]');if(!t)return;const n=o.querySelector(`#${t.getAttribute("aria-controls")}`);if(n)if(p(n))d(n,e);else{const t=h().filter((e=>e!==n&&!e.contains(n)));t.length&&t.forEach((e=>{d(e)})),m(n,e)}},i=e=>{e.target.closest('[data-menu="root"]')||g()},c=e=>{var t,n,o;const a=e.target,s=null===(n=null===(t=a.closest('[data-menu="sub-menu"]'))||void 0===t?void 0:t.parentElement)||void 0===n?void 0:n.querySelector('[data-menu="sub-toggle"]'),u=a.closest('[data-menu="sub-toggle"]');let l;l="sub-toggle"===a.getAttribute("data-menu")?a:s||u;const r=l?l.closest("li"):a.closest("li");if(!r)return;const i=C(r),c=i[i.length-1];if("Tab"===e.key&&!e.shiftKey&&e.target===c){const t=h().filter((t=>{const n=C(t);return!(n[n.length-1]!==e.target)||!t.contains(r)}));t.length&&t.forEach((e=>{d(e)}))}if(l&&"Tab"===e.key&&e.shiftKey&&e.target===l){const e=h().filter((e=>!e.contains(r)));e.length&&e.forEach((e=>{d(e)}))}if("Escape"===e.key){const e=null===(o=a.closest('[data-menu="sub-menu"]'))||void 0===o?void 0:o.closest("li");if(e){const t=C(e);t.length&&t[0].focus();const n=e.querySelector('[data-menu="sub-menu"]');n&&p(n)&&d(n)}}},m=(t,n)=>{if(p(t))return;"function"==typeof s.onBeforeOpenSubMenu&&s.onBeforeOpenSubMenu(t,n);const a=o.querySelector(`[aria-controls="${t.id}"]`);a&&a.setAttribute("aria-expanded","true"),s.animateCloseClass&&t.classList.remove(s.animateCloseClass),t.classList.add(s.openSubMenuClass);const u=()=>{s.animateOpenClass&&t.classList.remove(s.animateOpenClass),"function"==typeof s.onAfterOpenSubMenu&&s.onAfterOpenSubMenu(t,n)};s.animateOpen?e({element:t,animationClass:s.animateOpenClass,onReady:()=>{u()},maxExecutionTime:s.animateOpenMaxExecutionTime}):u()},d=(t,n)=>{if(!p(t))return;const a=o.querySelector(`[aria-controls="${t.id}"]`);a&&a.setAttribute("aria-expanded","false");const u=()=>{t.classList.remove(s.openSubMenuClass),s.animateCloseClass&&t.classList.remove(s.animateCloseClass),"function"==typeof s.onAfterCloseSubMenu&&s.onAfterCloseSubMenu(t,n)};s.animateClose?e({element:t,animationClass:s.animateCloseClass,onReady:()=>{u()},maxExecutionTime:s.animateCloseMaxExecutionTime}):u()},f=e=>{const t=e.currentTarget.querySelector('[data-menu="sub-menu"]');a=a.filter((e=>e.ul!==t&&!e.ul.contains(t)||(clearTimeout(e.id),!1)));h().filter((e=>e!==t&&!e.contains(t)&&!t.contains(e))).forEach((t=>{d(t,e)})),t&&m(t,e)},b=e=>{const t=e.currentTarget.querySelector('[data-menu="sub-menu"]');t&&(a=a.filter((e=>e.ul!==t||(clearTimeout(e.id),!1))),a.push({id:setTimeout((e=>{d(e)}),s.hoverTimeout,t),ul:t}))},p=e=>e.classList.contains(s.openSubMenuClass),h=()=>Array.from(o.querySelectorAll(`.${s.openSubMenuClass}[data-menu="sub-menu"]`)),C=e=>Array.from(e.querySelectorAll("\na[href]:not([hidden]),\narea[href],\ninput:not([disabled]),\nselect:not([disabled]),\ntextarea:not([disabled]),\nbutton:not([disabled])\n")).filter((e=>{const t=e.closest('[data-menu="sub-menu"]');return!t||p(t)})),g=()=>{const e=h();e.length&&e.forEach((e=>{d(e)}))},y=()=>{const e=o.querySelector(s.activeListItemSelector);if(e){let t=e.closest('[data-menu="sub-menu"]');if(t||(t=e.querySelector('[data-menu="sub-menu"]')),t){const e=[];let n=t.parentElement;for(;n&&n!==o;)"UL"===n.tagName&&e.push(n),n=n.parentElement;[...e,t].forEach((e=>{m(e)}))}}},S=(e,t)=>{const n=e.getAttribute("href");let o=!0;return n&&"#"!==n&&(o=!1),"boolean"==typeof s.shouldWrapAnchorToButton?o=s.shouldWrapAnchorToButton:"function"==typeof s.shouldWrapAnchorToButton&&(o=s.shouldWrapAnchorToButton(o,e,t)),o},A=(e,t)=>"function"==typeof s.buttonClass?s.buttonClass(o,e,t):s.buttonClass,v=(e,t)=>"function"==typeof s.buttonIcon?s.buttonIcon(o,e,t):s.buttonIcon;return(()=>{"function"==typeof s.onBeforeCreate&&s.onBeforeCreate(),o.setAttribute("data-menu","root");let e=1;u.forEach(((t,n)=>{var a;const u=document.createElement("button");u.setAttribute("data-menu","sub-toggle"),u.setAttribute("aria-expanded","false");let l=1,r=t.parentElement;for(;r&&r!==o;)"UL"===r.tagName&&l++,r=r.parentElement;for(u.setAttribute("data-menu-level",`${l}`);document.getElementById(`sub-menu-${e}-${n}`);)e++;u.setAttribute("aria-controls",`sub-menu-${e}-${n}`);const i=null===(a=t.closest("li"))||void 0===a?void 0:a.querySelector("ul");i&&(i.id=`sub-menu-${e}-${n}`,i.setAttribute("data-menu","sub-menu")),u.className=A(i,l),u.type="button";const c=v(i,l);if(S(t,l)){const e=document.createElement("span");for(;t.childNodes.length>0;)e.appendChild(t.childNodes[0]);u.appendChild(e),u.insertAdjacentHTML("beforeend",c),u.setAttribute("data-toggle-type","cover"),t.after(u),t.setAttribute("hidden","")}else u.innerHTML=`<span class="${s.visuallyHiddenClass}">${s.expandChildMenuText}</span>${c}`,u.setAttribute("data-toggle-type","icon"),t.after(u)})),s.openActiveSubMenuOnCreate&&y(),o.addEventListener("click",r,!1),o.addEventListener("keydown",c,!1),s.closeSubMenuOnOutsideClick&&document.addEventListener("click",i,!1),"hover"===s.action&&l.forEach((e=>{e.addEventListener("mouseenter",f,!1),e.addEventListener("mouseleave",b,!1)})),"function"==typeof s.onAfterCreate&&s.onAfterCreate(),o.classList.add("is-ready")})(),{openSubMenu:m,closeSubMenu:d,closeAllSubMenus:g,openActiveSubMenu:y,getOpenSubMenus:h,getButtonClass:A,getButtonIcon:v}}export{t as menuFromHTML}; | ||
/*! @evermade/menu-toolkit 1.0.2 */ | ||
function e(e){const{element:t,animationClass:n,onReady:o,maxExecutionTime:a}=e;t.classList.add(n);let s=!1;function u(){t.removeEventListener("animationend",u,!1),"function"==typeof o&&(s=!0,o(t,n))}t.addEventListener("animationend",u,!1),"function"==typeof o&&a&&setTimeout((()=>{s||(s=!0,o(t,n),t.removeEventListener("animationend",u,!1))}),a)}function t(t,n){const o=t;let a=[];if(!(t instanceof HTMLElement))throw new Error("Menu element must be an valid HTMLElement");const s=Object.assign(Object.assign({},{action:"click",subMenuAnchorSelector:".menu-item-has-children > a",subMenuListItemSelector:".menu-item-has-children",openSubMenuClass:"is-open",buttonClass:"",visuallyHiddenClass:"screen-reader-text",expandChildMenuText:"Sub menu",hoverTimeout:750,buttonIcon:'<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"></path></svg>',shouldWrapAnchorToButton:null,activeListItemSelector:".current-menu-item",openActiveSubMenuOnCreate:!1,closeSubMenuOnOutsideClick:!0,animateOpen:!1,animateClose:!1,animateOpenClass:"animate-open",animateCloseClass:"animate-close",animateOpenMaxExecutionTime:250,animateCloseMaxExecutionTime:250,onBeforeCreate:null,onAfterCreate:null,onBeforeOpenSubMenu:null,onAfterOpenSubMenu:null,onBeforeCloseSubMenu:null,onAfterCloseSubMenu:null}),n),u=Array.from(o.querySelectorAll(s.subMenuAnchorSelector)),l=Array.from(o.querySelectorAll(s.subMenuListItemSelector)),r=e=>{const t=e.target.closest('[data-menu="sub-toggle"]');if(!t)return;const n=o.querySelector(`#${t.getAttribute("aria-controls")}`);if(n)if(p(n))d(n,e);else{const t=h().filter((e=>e!==n&&!e.contains(n)));t.length&&t.forEach((e=>{d(e)})),m(n,e)}},i=e=>{e.target.closest('[data-menu="root"]')||g()},c=e=>{var t,n,o;const a=e.target,s=null===(n=null===(t=a.closest('[data-menu="sub-menu"]'))||void 0===t?void 0:t.parentElement)||void 0===n?void 0:n.querySelector('[data-menu="sub-toggle"]'),u=a.closest('[data-menu="sub-toggle"]');let l;l="sub-toggle"===a.getAttribute("data-menu")?a:s||u;const r=l?l.closest("li"):a.closest("li");if(!r)return;const i=C(r),c=i[i.length-1];if("Tab"===e.key&&!e.shiftKey&&e.target===c){const t=h().filter((t=>{const n=C(t);return!(n[n.length-1]!==e.target)||!t.contains(r)}));t.length&&t.forEach((e=>{d(e)}))}if(l&&"Tab"===e.key&&e.shiftKey&&e.target===l){const e=h().filter((e=>!e.contains(r)));e.length&&e.forEach((e=>{d(e)}))}if("Escape"===e.key){const e=null===(o=a.closest('[data-menu="sub-menu"]'))||void 0===o?void 0:o.closest("li");if(e){const t=C(e);t.length&&t[0].focus();const n=e.querySelector('[data-menu="sub-menu"]');n&&p(n)&&d(n)}}},m=(t,n)=>{if(p(t))return;"function"==typeof s.onBeforeOpenSubMenu&&s.onBeforeOpenSubMenu(t,n);const a=o.querySelector(`[aria-controls="${t.id}"]`);a&&a.setAttribute("aria-expanded","true"),s.animateCloseClass&&t.classList.remove(s.animateCloseClass),t.classList.add(s.openSubMenuClass);const u=()=>{s.animateOpenClass&&t.classList.remove(s.animateOpenClass),"function"==typeof s.onAfterOpenSubMenu&&s.onAfterOpenSubMenu(t,n)};s.animateOpen?e({element:t,animationClass:s.animateOpenClass,onReady:()=>{u()},maxExecutionTime:s.animateOpenMaxExecutionTime}):u()},d=(t,n)=>{if(!p(t))return;const a=o.querySelector(`[aria-controls="${t.id}"]`);a&&a.setAttribute("aria-expanded","false");const u=()=>{t.classList.remove(s.openSubMenuClass),s.animateCloseClass&&t.classList.remove(s.animateCloseClass),"function"==typeof s.onAfterCloseSubMenu&&s.onAfterCloseSubMenu(t,n)};s.animateClose?e({element:t,animationClass:s.animateCloseClass,onReady:()=>{u()},maxExecutionTime:s.animateCloseMaxExecutionTime}):u()},f=e=>{const t=e.currentTarget.querySelector('[data-menu="sub-menu"]');a=a.filter((e=>e.ul!==t&&!e.ul.contains(t)||(clearTimeout(e.id),!1)));h().filter((e=>e!==t&&!e.contains(t)&&!t.contains(e))).forEach((t=>{d(t,e)})),t&&m(t,e)},b=e=>{const t=e.currentTarget.querySelector('[data-menu="sub-menu"]');t&&(a=a.filter((e=>e.ul!==t||(clearTimeout(e.id),!1))),a.push({id:setTimeout((e=>{d(e)}),s.hoverTimeout,t),ul:t}))},p=e=>e.classList.contains(s.openSubMenuClass),h=()=>Array.from(o.querySelectorAll(`.${s.openSubMenuClass}[data-menu="sub-menu"]`)),C=e=>Array.from(e.querySelectorAll("\na[href]:not([hidden]),\narea[href],\ninput:not([disabled]),\nselect:not([disabled]),\ntextarea:not([disabled]),\nbutton:not([disabled])\n")).filter((e=>{const t=e.closest('[data-menu="sub-menu"]');return!t||p(t)})),g=()=>{const e=h();e.length&&e.forEach((e=>{d(e)}))},y=()=>{const e=o.querySelector(s.activeListItemSelector);if(e){let t=e.closest('[data-menu="sub-menu"]');if(t||(t=e.querySelector('[data-menu="sub-menu"]')),t){const e=[];let n=t.parentElement;for(;n&&n!==o;)"UL"===n.tagName&&e.push(n),n=n.parentElement;[...e,t].forEach((e=>{m(e)}))}}},S=(e,t)=>{const n=e.getAttribute("href");let o=!0;return n&&"#"!==n&&(o=!1),"boolean"==typeof s.shouldWrapAnchorToButton?o=s.shouldWrapAnchorToButton:"function"==typeof s.shouldWrapAnchorToButton&&(o=s.shouldWrapAnchorToButton(o,e,t)),o},A=(e,t)=>"function"==typeof s.buttonClass?s.buttonClass(o,e,t):s.buttonClass,v=(e,t)=>"function"==typeof s.buttonIcon?s.buttonIcon(o,e,t):s.buttonIcon;return(()=>{if("root"===o.getAttribute("data-menu"))return void console.log("menuFromHTML: Menu already initialized.",o);"function"==typeof s.onBeforeCreate&&s.onBeforeCreate(),o.setAttribute("data-menu","root");let e=1;u.forEach(((t,n)=>{var a;const u=document.createElement("button");u.setAttribute("data-menu","sub-toggle"),u.setAttribute("aria-expanded","false");let l=1,r=t.parentElement;for(;r&&r!==o;)"UL"===r.tagName&&l++,r=r.parentElement;for(u.setAttribute("data-menu-level",`${l}`);document.getElementById(`sub-menu-${e}-${n}`);)e++;u.setAttribute("aria-controls",`sub-menu-${e}-${n}`);const i=null===(a=t.closest("li"))||void 0===a?void 0:a.querySelector("ul");i&&(i.id=`sub-menu-${e}-${n}`,i.setAttribute("data-menu","sub-menu")),u.className=A(i,l),u.type="button";const c=v(i,l);if(S(t,l)){const e=document.createElement("span");for(;t.childNodes.length>0;)e.appendChild(t.childNodes[0]);u.appendChild(e),u.insertAdjacentHTML("beforeend",c),u.setAttribute("data-toggle-type","cover"),t.after(u),t.setAttribute("hidden","")}else u.innerHTML=`<span class="${s.visuallyHiddenClass}">${s.expandChildMenuText}</span>${c}`,u.setAttribute("data-toggle-type","icon"),t.after(u)})),s.openActiveSubMenuOnCreate&&y(),o.addEventListener("click",r,!1),o.addEventListener("keydown",c,!1),s.closeSubMenuOnOutsideClick&&document.addEventListener("click",i,!1),"hover"===s.action&&l.forEach((e=>{e.addEventListener("mouseenter",f,!1),e.addEventListener("mouseleave",b,!1)})),"function"==typeof s.onAfterCreate&&s.onAfterCreate(),o.classList.add("is-ready")})(),{openSubMenu:m,closeSubMenu:d,closeAllSubMenus:g,openActiveSubMenu:y,getOpenSubMenus:h,getButtonClass:A,getButtonIcon:v}}export{t as menuFromHTML}; |
@@ -87,2 +87,10 @@ (function (global, factory) { | ||
/** | ||
* Protect agains multiple initializations with checking data-menu="root" attribute. | ||
*/ | ||
const isInitialized = $ulRoot.getAttribute('data-menu') === 'root'; | ||
if (isInitialized) { | ||
console.log('menuFromHTML: Menu already initialized.', $ulRoot); | ||
return; | ||
} | ||
/** | ||
* Called before the component is initialized. | ||
@@ -89,0 +97,0 @@ */ |
@@ -1,2 +0,2 @@ | ||
/*! @evermade/menu-toolkit 1.0.1 */ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Menu={})}(this,(function(e){"use strict";function t(e){const{element:t,animationClass:n,onReady:o,maxExecutionTime:a}=e;t.classList.add(n);let s=!1;function u(){t.removeEventListener("animationend",u,!1),"function"==typeof o&&(s=!0,o(t,n))}t.addEventListener("animationend",u,!1),"function"==typeof o&&a&&setTimeout((()=>{s||(s=!0,o(t,n),t.removeEventListener("animationend",u,!1))}),a)}e.menuFromHTML=function(e,n){const o=e;let a=[];if(!(e instanceof HTMLElement))throw new Error("Menu element must be an valid HTMLElement");const s=Object.assign(Object.assign({},{action:"click",subMenuAnchorSelector:".menu-item-has-children > a",subMenuListItemSelector:".menu-item-has-children",openSubMenuClass:"is-open",buttonClass:"",visuallyHiddenClass:"screen-reader-text",expandChildMenuText:"Sub menu",hoverTimeout:750,buttonIcon:'<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"></path></svg>',shouldWrapAnchorToButton:null,activeListItemSelector:".current-menu-item",openActiveSubMenuOnCreate:!1,closeSubMenuOnOutsideClick:!0,animateOpen:!1,animateClose:!1,animateOpenClass:"animate-open",animateCloseClass:"animate-close",animateOpenMaxExecutionTime:250,animateCloseMaxExecutionTime:250,onBeforeCreate:null,onAfterCreate:null,onBeforeOpenSubMenu:null,onAfterOpenSubMenu:null,onBeforeCloseSubMenu:null,onAfterCloseSubMenu:null}),n),u=Array.from(o.querySelectorAll(s.subMenuAnchorSelector)),l=Array.from(o.querySelectorAll(s.subMenuListItemSelector)),r=e=>{const t=e.target.closest('[data-menu="sub-toggle"]');if(!t)return;const n=o.querySelector(`#${t.getAttribute("aria-controls")}`);if(n)if(p(n))m(n,e);else{const t=h().filter((e=>e!==n&&!e.contains(n)));t.length&&t.forEach((e=>{m(e)})),d(n,e)}},i=e=>{e.target.closest('[data-menu="root"]')||y()},c=e=>{var t,n,o;const a=e.target,s=null===(n=null===(t=a.closest('[data-menu="sub-menu"]'))||void 0===t?void 0:t.parentElement)||void 0===n?void 0:n.querySelector('[data-menu="sub-toggle"]'),u=a.closest('[data-menu="sub-toggle"]');let l;l="sub-toggle"===a.getAttribute("data-menu")?a:s||u;const r=l?l.closest("li"):a.closest("li");if(!r)return;const i=C(r),c=i[i.length-1];if("Tab"===e.key&&!e.shiftKey&&e.target===c){const t=h().filter((t=>{const n=C(t);return!(n[n.length-1]!==e.target)||!t.contains(r)}));t.length&&t.forEach((e=>{m(e)}))}if(l&&"Tab"===e.key&&e.shiftKey&&e.target===l){const e=h().filter((e=>!e.contains(r)));e.length&&e.forEach((e=>{m(e)}))}if("Escape"===e.key){const e=null===(o=a.closest('[data-menu="sub-menu"]'))||void 0===o?void 0:o.closest("li");if(e){const t=C(e);t.length&&t[0].focus();const n=e.querySelector('[data-menu="sub-menu"]');n&&p(n)&&m(n)}}},d=(e,n)=>{if(p(e))return;"function"==typeof s.onBeforeOpenSubMenu&&s.onBeforeOpenSubMenu(e,n);const a=o.querySelector(`[aria-controls="${e.id}"]`);a&&a.setAttribute("aria-expanded","true"),s.animateCloseClass&&e.classList.remove(s.animateCloseClass),e.classList.add(s.openSubMenuClass);const u=()=>{s.animateOpenClass&&e.classList.remove(s.animateOpenClass),"function"==typeof s.onAfterOpenSubMenu&&s.onAfterOpenSubMenu(e,n)};s.animateOpen?t({element:e,animationClass:s.animateOpenClass,onReady:()=>{u()},maxExecutionTime:s.animateOpenMaxExecutionTime}):u()},m=(e,n)=>{if(!p(e))return;const a=o.querySelector(`[aria-controls="${e.id}"]`);a&&a.setAttribute("aria-expanded","false");const u=()=>{e.classList.remove(s.openSubMenuClass),s.animateCloseClass&&e.classList.remove(s.animateCloseClass),"function"==typeof s.onAfterCloseSubMenu&&s.onAfterCloseSubMenu(e,n)};s.animateClose?t({element:e,animationClass:s.animateCloseClass,onReady:()=>{u()},maxExecutionTime:s.animateCloseMaxExecutionTime}):u()},f=e=>{const t=e.currentTarget.querySelector('[data-menu="sub-menu"]');a=a.filter((e=>e.ul!==t&&!e.ul.contains(t)||(clearTimeout(e.id),!1)));h().filter((e=>e!==t&&!e.contains(t)&&!t.contains(e))).forEach((t=>{m(t,e)})),t&&d(t,e)},b=e=>{const t=e.currentTarget.querySelector('[data-menu="sub-menu"]');t&&(a=a.filter((e=>e.ul!==t||(clearTimeout(e.id),!1))),a.push({id:setTimeout((e=>{m(e)}),s.hoverTimeout,t),ul:t}))},p=e=>e.classList.contains(s.openSubMenuClass),h=()=>Array.from(o.querySelectorAll(`.${s.openSubMenuClass}[data-menu="sub-menu"]`)),C=e=>Array.from(e.querySelectorAll("\na[href]:not([hidden]),\narea[href],\ninput:not([disabled]),\nselect:not([disabled]),\ntextarea:not([disabled]),\nbutton:not([disabled])\n")).filter((e=>{const t=e.closest('[data-menu="sub-menu"]');return!t||p(t)})),y=()=>{const e=h();e.length&&e.forEach((e=>{m(e)}))},g=()=>{const e=o.querySelector(s.activeListItemSelector);if(e){let t=e.closest('[data-menu="sub-menu"]');if(t||(t=e.querySelector('[data-menu="sub-menu"]')),t){const e=[];let n=t.parentElement;for(;n&&n!==o;)"UL"===n.tagName&&e.push(n),n=n.parentElement;[...e,t].forEach((e=>{d(e)}))}}},S=(e,t)=>{const n=e.getAttribute("href");let o=!0;return n&&"#"!==n&&(o=!1),"boolean"==typeof s.shouldWrapAnchorToButton?o=s.shouldWrapAnchorToButton:"function"==typeof s.shouldWrapAnchorToButton&&(o=s.shouldWrapAnchorToButton(o,e,t)),o},v=(e,t)=>"function"==typeof s.buttonClass?s.buttonClass(o,e,t):s.buttonClass,A=(e,t)=>"function"==typeof s.buttonIcon?s.buttonIcon(o,e,t):s.buttonIcon;return(()=>{"function"==typeof s.onBeforeCreate&&s.onBeforeCreate(),o.setAttribute("data-menu","root");let e=1;u.forEach(((t,n)=>{var a;const u=document.createElement("button");u.setAttribute("data-menu","sub-toggle"),u.setAttribute("aria-expanded","false");let l=1,r=t.parentElement;for(;r&&r!==o;)"UL"===r.tagName&&l++,r=r.parentElement;for(u.setAttribute("data-menu-level",`${l}`);document.getElementById(`sub-menu-${e}-${n}`);)e++;u.setAttribute("aria-controls",`sub-menu-${e}-${n}`);const i=null===(a=t.closest("li"))||void 0===a?void 0:a.querySelector("ul");i&&(i.id=`sub-menu-${e}-${n}`,i.setAttribute("data-menu","sub-menu")),u.className=v(i,l),u.type="button";const c=A(i,l);if(S(t,l)){const e=document.createElement("span");for(;t.childNodes.length>0;)e.appendChild(t.childNodes[0]);u.appendChild(e),u.insertAdjacentHTML("beforeend",c),u.setAttribute("data-toggle-type","cover"),t.after(u),t.setAttribute("hidden","")}else u.innerHTML=`<span class="${s.visuallyHiddenClass}">${s.expandChildMenuText}</span>${c}`,u.setAttribute("data-toggle-type","icon"),t.after(u)})),s.openActiveSubMenuOnCreate&&g(),o.addEventListener("click",r,!1),o.addEventListener("keydown",c,!1),s.closeSubMenuOnOutsideClick&&document.addEventListener("click",i,!1),"hover"===s.action&&l.forEach((e=>{e.addEventListener("mouseenter",f,!1),e.addEventListener("mouseleave",b,!1)})),"function"==typeof s.onAfterCreate&&s.onAfterCreate(),o.classList.add("is-ready")})(),{openSubMenu:d,closeSubMenu:m,closeAllSubMenus:y,openActiveSubMenu:g,getOpenSubMenus:h,getButtonClass:v,getButtonIcon:A}},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
/*! @evermade/menu-toolkit 1.0.2 */ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Menu={})}(this,(function(e){"use strict";function t(e){const{element:t,animationClass:n,onReady:o,maxExecutionTime:a}=e;t.classList.add(n);let s=!1;function u(){t.removeEventListener("animationend",u,!1),"function"==typeof o&&(s=!0,o(t,n))}t.addEventListener("animationend",u,!1),"function"==typeof o&&a&&setTimeout((()=>{s||(s=!0,o(t,n),t.removeEventListener("animationend",u,!1))}),a)}e.menuFromHTML=function(e,n){const o=e;let a=[];if(!(e instanceof HTMLElement))throw new Error("Menu element must be an valid HTMLElement");const s=Object.assign(Object.assign({},{action:"click",subMenuAnchorSelector:".menu-item-has-children > a",subMenuListItemSelector:".menu-item-has-children",openSubMenuClass:"is-open",buttonClass:"",visuallyHiddenClass:"screen-reader-text",expandChildMenuText:"Sub menu",hoverTimeout:750,buttonIcon:'<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"></path></svg>',shouldWrapAnchorToButton:null,activeListItemSelector:".current-menu-item",openActiveSubMenuOnCreate:!1,closeSubMenuOnOutsideClick:!0,animateOpen:!1,animateClose:!1,animateOpenClass:"animate-open",animateCloseClass:"animate-close",animateOpenMaxExecutionTime:250,animateCloseMaxExecutionTime:250,onBeforeCreate:null,onAfterCreate:null,onBeforeOpenSubMenu:null,onAfterOpenSubMenu:null,onBeforeCloseSubMenu:null,onAfterCloseSubMenu:null}),n),u=Array.from(o.querySelectorAll(s.subMenuAnchorSelector)),l=Array.from(o.querySelectorAll(s.subMenuListItemSelector)),r=e=>{const t=e.target.closest('[data-menu="sub-toggle"]');if(!t)return;const n=o.querySelector(`#${t.getAttribute("aria-controls")}`);if(n)if(p(n))m(n,e);else{const t=h().filter((e=>e!==n&&!e.contains(n)));t.length&&t.forEach((e=>{m(e)})),d(n,e)}},i=e=>{e.target.closest('[data-menu="root"]')||y()},c=e=>{var t,n,o;const a=e.target,s=null===(n=null===(t=a.closest('[data-menu="sub-menu"]'))||void 0===t?void 0:t.parentElement)||void 0===n?void 0:n.querySelector('[data-menu="sub-toggle"]'),u=a.closest('[data-menu="sub-toggle"]');let l;l="sub-toggle"===a.getAttribute("data-menu")?a:s||u;const r=l?l.closest("li"):a.closest("li");if(!r)return;const i=C(r),c=i[i.length-1];if("Tab"===e.key&&!e.shiftKey&&e.target===c){const t=h().filter((t=>{const n=C(t);return!(n[n.length-1]!==e.target)||!t.contains(r)}));t.length&&t.forEach((e=>{m(e)}))}if(l&&"Tab"===e.key&&e.shiftKey&&e.target===l){const e=h().filter((e=>!e.contains(r)));e.length&&e.forEach((e=>{m(e)}))}if("Escape"===e.key){const e=null===(o=a.closest('[data-menu="sub-menu"]'))||void 0===o?void 0:o.closest("li");if(e){const t=C(e);t.length&&t[0].focus();const n=e.querySelector('[data-menu="sub-menu"]');n&&p(n)&&m(n)}}},d=(e,n)=>{if(p(e))return;"function"==typeof s.onBeforeOpenSubMenu&&s.onBeforeOpenSubMenu(e,n);const a=o.querySelector(`[aria-controls="${e.id}"]`);a&&a.setAttribute("aria-expanded","true"),s.animateCloseClass&&e.classList.remove(s.animateCloseClass),e.classList.add(s.openSubMenuClass);const u=()=>{s.animateOpenClass&&e.classList.remove(s.animateOpenClass),"function"==typeof s.onAfterOpenSubMenu&&s.onAfterOpenSubMenu(e,n)};s.animateOpen?t({element:e,animationClass:s.animateOpenClass,onReady:()=>{u()},maxExecutionTime:s.animateOpenMaxExecutionTime}):u()},m=(e,n)=>{if(!p(e))return;const a=o.querySelector(`[aria-controls="${e.id}"]`);a&&a.setAttribute("aria-expanded","false");const u=()=>{e.classList.remove(s.openSubMenuClass),s.animateCloseClass&&e.classList.remove(s.animateCloseClass),"function"==typeof s.onAfterCloseSubMenu&&s.onAfterCloseSubMenu(e,n)};s.animateClose?t({element:e,animationClass:s.animateCloseClass,onReady:()=>{u()},maxExecutionTime:s.animateCloseMaxExecutionTime}):u()},f=e=>{const t=e.currentTarget.querySelector('[data-menu="sub-menu"]');a=a.filter((e=>e.ul!==t&&!e.ul.contains(t)||(clearTimeout(e.id),!1)));h().filter((e=>e!==t&&!e.contains(t)&&!t.contains(e))).forEach((t=>{m(t,e)})),t&&d(t,e)},b=e=>{const t=e.currentTarget.querySelector('[data-menu="sub-menu"]');t&&(a=a.filter((e=>e.ul!==t||(clearTimeout(e.id),!1))),a.push({id:setTimeout((e=>{m(e)}),s.hoverTimeout,t),ul:t}))},p=e=>e.classList.contains(s.openSubMenuClass),h=()=>Array.from(o.querySelectorAll(`.${s.openSubMenuClass}[data-menu="sub-menu"]`)),C=e=>Array.from(e.querySelectorAll("\na[href]:not([hidden]),\narea[href],\ninput:not([disabled]),\nselect:not([disabled]),\ntextarea:not([disabled]),\nbutton:not([disabled])\n")).filter((e=>{const t=e.closest('[data-menu="sub-menu"]');return!t||p(t)})),y=()=>{const e=h();e.length&&e.forEach((e=>{m(e)}))},g=()=>{const e=o.querySelector(s.activeListItemSelector);if(e){let t=e.closest('[data-menu="sub-menu"]');if(t||(t=e.querySelector('[data-menu="sub-menu"]')),t){const e=[];let n=t.parentElement;for(;n&&n!==o;)"UL"===n.tagName&&e.push(n),n=n.parentElement;[...e,t].forEach((e=>{d(e)}))}}},M=(e,t)=>{const n=e.getAttribute("href");let o=!0;return n&&"#"!==n&&(o=!1),"boolean"==typeof s.shouldWrapAnchorToButton?o=s.shouldWrapAnchorToButton:"function"==typeof s.shouldWrapAnchorToButton&&(o=s.shouldWrapAnchorToButton(o,e,t)),o},S=(e,t)=>"function"==typeof s.buttonClass?s.buttonClass(o,e,t):s.buttonClass,v=(e,t)=>"function"==typeof s.buttonIcon?s.buttonIcon(o,e,t):s.buttonIcon;return(()=>{if("root"===o.getAttribute("data-menu"))return void console.log("menuFromHTML: Menu already initialized.",o);"function"==typeof s.onBeforeCreate&&s.onBeforeCreate(),o.setAttribute("data-menu","root");let e=1;u.forEach(((t,n)=>{var a;const u=document.createElement("button");u.setAttribute("data-menu","sub-toggle"),u.setAttribute("aria-expanded","false");let l=1,r=t.parentElement;for(;r&&r!==o;)"UL"===r.tagName&&l++,r=r.parentElement;for(u.setAttribute("data-menu-level",`${l}`);document.getElementById(`sub-menu-${e}-${n}`);)e++;u.setAttribute("aria-controls",`sub-menu-${e}-${n}`);const i=null===(a=t.closest("li"))||void 0===a?void 0:a.querySelector("ul");i&&(i.id=`sub-menu-${e}-${n}`,i.setAttribute("data-menu","sub-menu")),u.className=S(i,l),u.type="button";const c=v(i,l);if(M(t,l)){const e=document.createElement("span");for(;t.childNodes.length>0;)e.appendChild(t.childNodes[0]);u.appendChild(e),u.insertAdjacentHTML("beforeend",c),u.setAttribute("data-toggle-type","cover"),t.after(u),t.setAttribute("hidden","")}else u.innerHTML=`<span class="${s.visuallyHiddenClass}">${s.expandChildMenuText}</span>${c}`,u.setAttribute("data-toggle-type","icon"),t.after(u)})),s.openActiveSubMenuOnCreate&&g(),o.addEventListener("click",r,!1),o.addEventListener("keydown",c,!1),s.closeSubMenuOnOutsideClick&&document.addEventListener("click",i,!1),"hover"===s.action&&l.forEach((e=>{e.addEventListener("mouseenter",f,!1),e.addEventListener("mouseleave",b,!1)})),"function"==typeof s.onAfterCreate&&s.onAfterCreate(),o.classList.add("is-ready")})(),{openSubMenu:d,closeSubMenu:m,closeAllSubMenus:y,openActiveSubMenu:g,getOpenSubMenus:h,getButtonClass:S,getButtonIcon:v}},Object.defineProperty(e,"__esModule",{value:!0})})); |
@@ -81,2 +81,10 @@ function animate(options) { | ||
/** | ||
* Protect agains multiple initializations with checking data-menu="root" attribute. | ||
*/ | ||
const isInitialized = $ulRoot.getAttribute('data-menu') === 'root'; | ||
if (isInitialized) { | ||
console.log('menuFromHTML: Menu already initialized.', $ulRoot); | ||
return; | ||
} | ||
/** | ||
* Called before the component is initialized. | ||
@@ -83,0 +91,0 @@ */ |
{ | ||
"name": "@evermade/menu-toolkit", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "Toolkit for developing accessible menus.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -401,2 +401,12 @@ # Menu Toolkit | ||
## Change log | ||
### 1.0.2 | ||
Prevent double initialization of menu. This could happen by human error or by some cookie consent scripts that re-run scripts after consent is given. | ||
### 1.0.1 | ||
Fix issue of shouldWrapAnchorToButton copying links content with textContent and in case link actually has some inner HTML elements those would not be copied. This is now changed so that all inner HTML elements are moved which is the appropriate thing to do. | ||
## Development | ||
@@ -403,0 +413,0 @@ |
@@ -110,2 +110,11 @@ import animate from './utils/animate'; | ||
/** | ||
* Protect agains multiple initializations with checking data-menu="root" attribute. | ||
*/ | ||
const isInitialized = $ulRoot.getAttribute('data-menu') === 'root'; | ||
if (isInitialized) { | ||
console.log('menuFromHTML: Menu already initialized.', $ulRoot); | ||
return; | ||
} | ||
/** | ||
* Called before the component is initialized. | ||
@@ -112,0 +121,0 @@ */ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
155826
3426
422