natura11y 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/natura11y.css +1 -1
- package/dist/natura11y.js +1 -1
- package/package.json +1 -1
- package/src/js/lightbox.js +91 -60
- package/src/js/utilities/focus.js +4 -2
- package/src/js/utilities/overlay.js +3 -1
- package/src/scss/_accordion.scss +2 -0
- package/src/scss/_alert.scss +1 -0
- package/src/scss/_button.scss +12 -12
- package/src/scss/_card.scss +1 -0
- package/src/scss/_container.scss +1 -0
- package/src/scss/_form.scss +7 -0
- package/src/scss/_grid.scss +1 -0
- package/src/scss/_icon.scss +1 -0
- package/src/scss/_lightbox.scss +25 -12
- package/src/scss/_modal.scss +6 -6
- package/src/scss/_navigation.scss +2 -0
- package/src/scss/_shadow.scss +9 -0
- package/src/scss/_tab.scss +7 -0
- package/src/scss/_table.scss +1 -0
package/dist/natura11y.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(){"use strict";let t,e=0,i=document.querySelector("html");const s=s=>{t=document.activeElement,e=window.scrollY,i.style.setProperty("--scroll-position",`-${e}px`),i.classList.add("has-overlay"),s&&"true"===s.getAttribute("aria-hidden")&&s.setAttribute("aria-hidden",!1),o(s)},a=s=>{i.removeAttribute("style"),i.classList.remove("has-overlay"),i.classList.length||i.removeAttribute("class"),s&&"false"===s.getAttribute("aria-hidden")&&s.setAttribute("aria-hidden",!0),window.scrollTo({top:e,behavior:"instant"}),t.focus()},n=function(){return[...(arguments.length>0&&void 0!==arguments[0]?arguments[0]:document).querySelectorAll(["a[href]","area","button","details","frame","iframe","input","object","summary","textarea","select",'[tabindex]:not([tabindex="-1"])'])].filter((t=>!t.hasAttribute("disabled")&&!t.getAttribute("aria-hidden")))},o=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,i=n(t),s=i[0],o=i[i.length-1];e.setAttribute("tabindex","-1"),e.focus(),t.addEventListener("keydown",(e=>{switch(e.code){case"Tab":document.activeElement===o&&(e.shiftKey||(e.preventDefault(),s.focus())),document.activeElement===s&&e.shiftKey&&(e.preventDefault(),o.focus());break;case"Escape":a(t)}}))};class l{#t=document.querySelectorAll(".accordion");#e(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];n(t).forEach((t=>{t.setAttribute("tabindex",e?0:-1)}))}#i=(t,e,i)=>s=>{s.preventDefault(),s.stopPropagation();for(const t of i)t.classList.remove("show"),t!==e&&(t.classList.remove("shown"),t.style.maxHeight=null,t.previousElementSibling.setAttribute("aria-expanded",!1),t.setAttribute("aria-hidden",!0),this.#e(t,!1));e.classList.toggle("shown");let a=t.getAttribute("aria-expanded");"true"===a?(t.setAttribute("aria-expanded",!1),e.setAttribute("aria-hidden",!0),this.#e(e,!1)):"false"===a&&(t.setAttribute("aria-expanded",!0),e.setAttribute("aria-hidden",!1),this.#e(e,!0)),e.style.maxHeight?e.style.maxHeight=null:(e.style.maxHeight=e.scrollHeight+"px",e.setAttribute("aria-hidden",!1));let n=new Event("accTrigger",{bubbles:!0});document.dispatchEvent(n)};#s=(t,e,i)=>t=>{const s=s=>{t.preventDefault();let a=i+s;-1===s&&a<0?e[e.length-1].focus():1===s&&a>=e.length?e[0].focus():e[a].focus()};switch(t.code){case"ArrowLeft":case"ArrowUp":s(-1);break;case"ArrowRight":case"ArrowDown":s(1)}};#a=(t,e,i)=>s=>{"Enter"===s.code&&"BUTTON"!==s.target.tagName&&this.#i(t,e,i)(s)};init(){this.#t.forEach((t=>{const e=Array.from(t.querySelectorAll(':scope > [data-accordion="button"]')),i=t.querySelectorAll(':scope > [data-accordion="panel"]');t.addEventListener("click",(t=>{const s=t.target.closest('[data-accordion="button"]');if(!s)return;if(-1===e.indexOf(s))return;const a=s.nextElementSibling;this.#i(s,a,i)(t)})),t.addEventListener("keydown",(t=>{const i=t.target.closest('[data-accordion="button"]');if(!i)return;const s=e.indexOf(i);-1!==s&&this.#s(i,e,s)(t)})),t.addEventListener("keyup",(t=>{const s=t.target.closest('[data-accordion="button"]');if(!s)return;e.indexOf(s);const a=s.nextElementSibling;this.#a(s,a,i)(t)})),e.forEach(((t,e)=>{const i=t.nextElementSibling;let s=t.getAttribute("aria-expanded");t.setAttribute("tabindex",0),"true"===s?(i.style.maxHeight=i.scrollHeight+"px",i.classList.add("show"),this.#e(i,!0)):(t.setAttribute("aria-expanded",!1),i.style.maxHeight=null,i.setAttribute("aria-hidden",!0),this.#e(i,!1))}))}))}}class r{#n=document.querySelectorAll(".alert--dismissable");#o='\n <button class="button button--icon-only">\n <span class="icon icon-close" aria-label="Close" aria-hidden="true">\n </button>\n ';#l=t=>e=>{e.preventDefault(),t.classList.add("dismissed"),document.querySelector(".dismissed").addEventListener("animationend",(()=>{t.remove()}))};init(){this.#n.forEach((t=>{t.insertAdjacentHTML("afterbegin",this.#o),t.querySelector("button").addEventListener("click",this.#l(t))}))}}class d{#r=document.querySelectorAll(".button--icon-only");#d=t=>e=>setTimeout((()=>{t.forEach((t=>{t.classList.remove("tooltip-show")})),e.target.classList.add("tooltip-show")}),300);#c=()=>(t,e)=>{clearTimeout(e),t.target.classList.remove("tooltip-show")};#h(t,e){const i=e.offsetWidth/2,s=t.offsetLeft,a=window.innerWidth-(t.offsetLeft+t.offsetWidth);i>s&&e.classList.add("left"),i>a&&e.classList.add("right")}#u=(t,e)=>{const i=`\n <span class="button__tooltip">\n ${e}\n </span>\n `;if(e){t.insertAdjacentHTML("beforeend",i);const e=t.querySelector(".button__tooltip");let s;this.#h(t,e),window.addEventListener("resize",(()=>this.#h(t,e))),t.addEventListener("mouseenter",(t=>{s=this.#d(this.#r)(t)})),t.addEventListener("focusin",(t=>{s=this.#d(this.#r)(t)})),t.addEventListener("mouseleave",(t=>{this.#c()(t,s)})),t.addEventListener("focusout",(t=>{this.#c()(t,s)}))}};init(){this.#r.forEach((t=>{const e=t.getAttribute("aria-label");this.#u(t,e)}))}}class c{#b=document.querySelectorAll("[data-target-toggle]");#g(t,e){t.setAttribute("aria-expanded",!1),e.classList.remove("shown")}#p(t,e,i){t.setAttribute("aria-expanded",!0),e.classList.add("shown"),i&&i.focus()}#s(t,e,i){return s=>{switch(s.code){case"Tab":document.activeElement===i&&s.shiftKey&&(s.preventDefault(),t.focus());break;case"Escape":this.#g(t,e)}}}#m(t,e){const i=t.target.getAttribute("data-target-toggle").replace(/#/,""),s=document.getElementById(i),a=n(s)[0],o=e.getAttribute("aria-expanded");"true"===o?this.#g(e,s):"false"===o&&this.#p(e,s,s.hasAttribute("data-focus-first")?a:null),s.addEventListener("keydown",this.#s(e,s,a))}init(){this.#b.forEach((t=>{t.setAttribute("aria-expanded",!1),t.addEventListener("click",(e=>{if(this.#m(e,t),t.hasAttribute("data-target-close")){const t=e.target.getAttribute("data-target-close").replace(/#/,""),i=document.getElementById(t),s=document.querySelector(`[data-target-toggle="#${t}"]`);this.#g(s,i)}}))}))}}class h{#f=document.querySelectorAll(".form-entry");#L=["is-invalid"];#v=!1;#y(){return""===(arguments.length>0&&void 0!==arguments[0]?arguments[0]:null)}#x(t){t.closest(".form-entry").classList.add(...this.#L)}#E(t){t.closest(".form-entry").classList.remove(...this.#L)}#A(t){return this.#y(t.value)?(this.#x(t),!0):(this.#E(t),!1)}#w(t){return e=>{e.target.closest(t).classList.add("active")}}#S(t){return e=>{e.target.closest(t).classList.remove("active")}}#C(t,e){this.#v&&e&&this.#A(t),""!==t.value?t.closest(".form-entry").classList.add("has-value"):t.closest(".form-entry").classList.remove("has-value")}#_(t){const e=t.querySelectorAll(["email","input","select","tel","textarea"]);let i=t.hasAttribute("data-required");e.forEach((t=>this.#q(t,i)))}#q(t,e){const i=t.closest(".form-entry").querySelector(".form-entry__field__input");let s=".form-entry";if("INPUT"===t.tagName){const e=t.getAttribute("type");"radio"!==e&&"checkbox"!==e||t.disabled&&t.closest("label").classList.add("disabled")}t.addEventListener("focusin",this.#w(s)),t.addEventListener("focusout",this.#S(s)),e&&(t.setAttribute("required","true"),t.setAttribute("aria-required",!0)),t.addEventListener("change",(()=>this.#C(t,e))),i&&i.addEventListener("click",this.handleClickOnInputText)}handleClickOnInputText(t){let e=t.target.tagName,i=t.target.closest(".form-entry__field__input").querySelector("input");"SPAN"===e&&i.focus()}init(){this.#f.forEach((t=>this.#_(t)))}}class u{#T=document.querySelectorAll("form[novalidate]");#L=["is-invalid"];#v=!1;#y(){return""===(arguments.length>0&&void 0!==arguments[0]?arguments[0]:null)}#x(t){t.closest(".form-entry").classList.add(...this.#L)}#E(t){t.closest(".form-entry").classList.remove(...this.#L)}#A(t){return this.#y(t.value)?(this.#x(t),!0):(this.#E(t),!1)}#k(t,e){return null===t&&(t="This field is Required"),`\n <small class="form-entry__feedback">\n <span class="icon icon-warn" aria-hidden="true"></span>\n <span class="message">\n <strong>${t}</strong> ${void 0!==e?e:""}\n </span>\n </small>\n `}#H(t,e){t.forEach((t=>{let i=t.closest(".form-entry"),s=i.querySelector(".form-entry__field__label");i.classList.add("is-invalid");const a=i.querySelector(".form-entry__feedback"),n=i.querySelector(".form-entry__help");let o;n&&(o=n.innerHTML.toString());let l=i.getAttribute("data-error-message"),r=[l,o];e.push(r),null===a&&s.insertAdjacentHTML("afterend",this.#k(l,o))}))}#I(t){let e=t.querySelector('[class*="alert"], [class*="invalid"]');if(e){e.hasAttribute("data-alert")&&(e.style.display="block");let t=e.offsetTop-16;window.scrollTo({top:t,behavior:"smooth"})}}#M(t){t.addEventListener("submit",(e=>{e.preventDefault(),this.#v=!0;let i=[],s=t.querySelectorAll("input, select, textarea");s.forEach((t=>{t.addEventListener("input",(()=>this.#A(t)))})),s.forEach((t=>{this.#A(t)}));let a=t.querySelectorAll(":invalid");this.#H(a,i),i.length>0&&e.preventDefault(),this.#I(t)}))}init(){this.#T.forEach((t=>this.#M(t)))}}class b{#D=document.querySelectorAll(".file-upload");#F(t){return function(e){const[i]=e.target.files,{name:s,size:a}=i,n=`\n <span class="file-upload__data">\n <span class="file-name">${s}</span>\n <span class="file-size">${(a/1e3).toFixed(2)} kb</span>\n </span>\n `,o=t.querySelector(".file-upload__data");o&&o.remove(),t.insertAdjacentHTML("beforeend",n)}}dragOver(t){t.target.closest(".form-entry").classList.add("active")}dragOff(t){t.target.closest(".form-entry").classList.remove("active")}dropped(t){t.target.closest(".form-entry").classList.remove("active")}#O(t){t.querySelector('input[type="file"]').addEventListener("change",this.#F(t)),t.addEventListener("dragenter",this.dragOver.bind(this)),t.addEventListener("dragleave",this.dragOff.bind(this)),t.addEventListener("dragend",this.dragOff.bind(this)),t.addEventListener("drop",this.dropped.bind(this))}init(){this.#D.forEach((t=>this.#O(t)))}}class g{#B=document.querySelectorAll("[data-lightbox]");#U='\n\t\t<div class="lightbox__buttons button-group">\n\t\t<button class="button button--icon-only" data-lightbox-previous>\n\t\t\t<span class="icon icon-arrow-left" aria-label="Previous" aria-hidden="true"></span>\n\t\t</button>\n\t\t<button class="button button--icon-only" data-lightbox-next>\n\t\t\t<span class="icon icon-arrow-right" aria-label="Next" aria-hidden="true"></span>\n\t\t</button>\n\t\t<button class="button button--icon-only" data-lightbox-close>\n\t\t\t<span class="icon icon-close" aria-label="Close" aria-hidden="true"></span>\n\t\t</button>\n\t\t</div>\n\t\t<figure class="lightbox__container" aria-live="polite" aria-atomic="true">\n\t\t<div class="lightbox__media"></div> \n\t\t<figcaption class="lightbox__caption"></figcaption>\n\t\t</figure>\n \t';#N='\n\t\t<video controls>\n\t\t<source type="video/mp4">\n\t\t</video>\n\t';#P='\n\t\t<iframe\n\t\t\tframeborder="0"\n\t\t\tallow="autoplay; fullscreen;"\n\t\t\tallowfullscreen\n\t\t></iframe>\n\t';#$='\n\t\t<div class="lightbox__media__loader">\n\t\t\t<span class="icon icon-loading icon--rotate" aria-hidden="true"></span>\n\t\t</div>\n\t\t<div class="lightbox__media__error" style="display: none;">\n\t\t\t<span class="icon icon-warn" aria-hidden="true"></span>\n\t\t\t<p>Failed to load content. Please try again later.</p>\n\t\t</div>\n\t';#K='<img src="https://source.unsplash.com/1600x900" />';#V=[];#R=t=>e=>{document.querySelector(".lightbox")||(e.preventDefault(),this.lightbox=this.#W(),this.currentLB=t,s(this.lightbox),this.#z(t))};#j=t=>{t.stopPropagation(),t.target!==t.currentTarget&&"click"===t.type||(a(this.lightbox),this.lightbox.parentElement.removeChild(this.lightbox),window.removeEventListener("keyup",this.#Y))};#G=(()=>{var t=this;return function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];t.lightbox.querySelector(".lightbox__caption").style.display=e?"block":"none"}})();#J=t=>{if(t.preventDefault(),t.target.hasAttribute("data-lightbox-previous"))this.#Q(-1);else{if(!t.target.hasAttribute("data-lightbox-next"))return;this.#Q(1)}};#Y=t=>{if(t.preventDefault(),!(this.#V.length<=1)||"ArrowLeft"!==t.code&&"ArrowRight"!==t.code)switch(t.code){case"ArrowLeft":this.#Q(-1),this.lightbox.querySelector("[data-lightbox-previous]").focus();break;case"ArrowRight":this.#Q(1),this.lightbox.querySelector("[data-lightbox-next]").focus();break;case"Escape":this.#j(t);break;default:return}};#Q(t){this.currentLB+=t,this.currentLB<0?this.currentLB=this.#V.length-1:this.currentLB>=this.#V.length&&(this.currentLB=0),this.#z(this.currentLB)}#z(t){const e=this.lightbox.querySelector(".lightbox__media"),i=this.lightbox.querySelector(".lightbox__caption");let s;e.innerHTML="";const{lbType:a,lbSrc:n,lbAlt:o,lbCaption:l}=this.#V[t],r=null!==l;switch(this.#G(r),a){case"image":s=this.#X(e,n,o);break;case"video":s=this.#Z(e,n)}r&&(i.innerHTML=l)}#X(t,e,i){t.hasAttribute("style")&&t.removeAttribute("style"),t.innerHTML=this.#K;const s=this.#tt();t.appendChild(s);const a=t.querySelector("img");return a.alt=i,a.src=e,this.#et(a,s),a}#Z(t,e){const i=/youtube/i.test(e),s=/vimeo/i.test(e);let a;if(i||s)t.innerHTML=this.#P,a=t.querySelector("iframe"),a.src=e;else{t.innerHTML=this.#N;const i=this.#tt();t.appendChild(i),a=t.querySelector("source");const s=t.querySelector("video");s.addEventListener("loadedmetadata",(()=>{let e=s.videoWidth,i=s.videoHeight;t.style.maxWidth=`${e}px`,t.style.aspectRatio=`${e} / ${i}`})),this.#et(a,i),a.src=e}return a}#W(){const t=document.createElement("div");t.classList.add("lightbox"),t.setAttribute("aria-hidden",!0),t.innerHTML=this.#U,document.body.appendChild(t);const e=t.querySelector("[data-lightbox-previous]"),i=t.querySelector("[data-lightbox-next]"),s=t.querySelector("[data-lightbox-close]");return this.#V.length<=1&&(e.setAttribute("disabled",!0),i.setAttribute("disabled",!0),e.style.display="none",i.style.display="none"),t.addEventListener("click",this.#j),s.addEventListener("click",this.#j),e.addEventListener("click",this.#J),i.addEventListener("click",this.#J),window.addEventListener("keyup",this.#Y),t}#it(t){let e=null,i="";return null!==t.querySelector("img")&&(e=t.querySelector("img").src||null,i=t.querySelector("img").alt||""),{lbType:t.getAttribute("data-lightbox")||"image",lbSrc:t.getAttribute("data-lightbox-src")||e,lbCaption:t.getAttribute("data-lightbox-caption")||null,lbAlt:t.getAttribute("data-lightbox-alt")||i}}#st(){this.#B.forEach((t=>{this.#V.push(this.#it(t))}))}#tt=()=>{const t=document.createElement("div");return t.className="lightbox__media__loader",t.innerHTML=this.#$,t};#et=(t,e)=>{const i="SOURCE"===t.nodeName?"loadeddata":"load";t.closest("SOURCE"===t.nodeName?"video":"img").addEventListener(i,(()=>{e&&e.parentNode&&e.parentNode.removeChild(e),null!==this.#V[this.currentLB].lbCaption&&this.#G(!0)})),t.onerror=()=>{const i=e.querySelector(".lightbox__media__loader"),s=e.querySelector(".lightbox__media__error");t.style.display="none",this.#G(!1),i.style.display="none",s.style.display="block"}};#at(){const t=new IntersectionObserver(((t,e)=>{t.forEach((t=>{if(t.isIntersecting){const i=t.target,s=i.dataset.lightboxSrc||i.src;if(!s)return;e.unobserve(i);const a=new Image;a.onload=()=>{document.body.appendChild(a)},a.onerror=()=>{console.error(`Failed to load image: ${s}`)},a.src=s,a.style.display="none",this.#V[Number(i.dataset.index)].hiddenImage=a}}))}),{root:null,rootMargin:"0px",threshold:.1});Array.from(this.#B).filter((t=>"image"===t.getAttribute("data-lightbox"))).forEach(((e,i)=>{const s=e.querySelector("img");s&&(s.dataset.index=i,t.observe(s))}))}#nt(){this.#B.forEach(((t,e)=>{t.addEventListener("click",this.#R(e))}))}init(){this.#st(),this.#nt(),this.#at()}}class p{#ot=document.querySelectorAll(".modal");#lt=document.querySelectorAll("[data-modal-open]");#rt=new Map;#dt(t,e){window.addEventListener("click",e),this.#rt.set(t,e)}#ct(t){const e=this.#rt.get(t);e&&(window.removeEventListener("click",e),this.#rt.delete(t))}openModal(t){if(!t)return void console.warn("Modal target not found.");s(t);const e=t.querySelector(".modal__content");if(!e)return void console.warn("Modal content not found.");t.classList.contains("modal--scroll-all")&&(t.scrollTop=0);t.querySelectorAll("[data-modal-close]").forEach((e=>{e.addEventListener("click",(()=>{a(t),this.#ct(t)})),e.setAttribute("aria-label","Close Modal Window")})),"true"===t.dataset.modalCloseOutside&&this.#dt(t,(i=>{e.contains(i.target)||(a(t),this.#ct(t))}))}init(){this.#ot.forEach((t=>{const e=t.querySelector(".modal__content");e.setAttribute("role","dialog"),e.setAttribute("aria-modal",!0),t.setAttribute("aria-hidden",!0)})),this.#lt.forEach((t=>{t.addEventListener("click",(t=>{const e=t.target.getAttribute("data-modal-open").replace(/#/,""),i=document.getElementById(e);this.openModal(i),t.stopPropagation()}))}))}}class m{#ht=document.querySelectorAll('[data-toggle="dropdown"]');#ut(t,e){e.classList.toggle("shown"),t.setAttribute("aria-expanded","true"===t.getAttribute("aria-expanded")?"false":"true")}#bt(t,e){e.classList.remove("shown"),t.setAttribute("aria-expanded","false")}init(){window.addEventListener("click",(t=>{this.#ht.forEach((e=>{let i=e.closest("li"),s=e.nextElementSibling;i.contains(t.target)||this.#bt(e,s)}))})),this.#ht.forEach((t=>{let e=t.nextElementSibling;e?(t.setAttribute("aria-expanded","false"),t.setAttribute("aria-haspopup","true"),t.addEventListener("click",(i=>{i.preventDefault(),this.#ut(t,e)}))):console.warn(`No dropdown menu found for dropdown button ${t}`)}))}}class f{#gt=document.querySelectorAll('[class*="table--stack"]');#pt=document.querySelectorAll(".table-scroll");#mt(t){const e=t.querySelectorAll("thead th"),i=t.querySelectorAll("tbody tr");let s=[];e.forEach((t=>{if(""!==t.textContent){const e=t.textContent.trim();s.push(e)}})),i.forEach((t=>{t.querySelectorAll("td").forEach(((t,e)=>{t.innerHTML=this.#ft(t.innerHTML),t.setAttribute("data-header",s[e])}))}))}#ft(t){return`\n\t\t\t<div class="td-content">\n\t\t\t\t${t}\n\t\t\t</div>\n\t\t`}#Lt(){this.#pt.forEach((t=>{let e=t.querySelector(".table-scroll__container"),i=t.offsetWidth;e.scrollWidth>i?t.setAttribute("data-scroll",!0):t.setAttribute("data-scroll",!1),e.addEventListener("scroll",(()=>{e.scrollLeft>1?e.setAttribute("data-scrolling",!0):e.setAttribute("data-scrolling",!1)}),{passive:!0})}))}init(){this.#gt.forEach((t=>{this.#mt(t)})),this.#Lt(),window.addEventListener("resize",this.#Lt.bind(this))}}class L{#vt=document.querySelectorAll(".tabs");#yt(t,e,i,s){t.preventDefault();let a=e+s;-1===s&&a<0?i[i.length-1].focus():1===s&&a>=i.length?i[0].focus():i[a].focus()}#xt(t,e){t.forEach((t=>{t.setAttribute("aria-selected","false")})),e.forEach((t=>{t.classList.remove("shown"),t.setAttribute("hidden","")}))}activateTab(t,e,i){this.#xt(e,i),t.setAttribute("aria-selected","true");let s=t.getAttribute("aria-controls"),a=document.getElementById(s);a.classList.add("shown"),a.removeAttribute("hidden")}init(){this.#vt.forEach((t=>{const e=t.querySelectorAll('[role="tab"]'),i=t.querySelectorAll('[role="tabpanel"]');e.forEach(((t,s)=>{t.addEventListener("click",(t=>{let s=t.target;this.activateTab(s,e,i)})),t.addEventListener("keydown",(t=>{switch(t.code){case"Home":t.preventDefault(),e[0].focus();break;case"End":t.preventDefault(),e[e.length-1].focus();break;case"ArrowLeft":this.#yt(t,s,e,-1);break;case"ArrowRight":this.#yt(t,s,e,1)}}))}))}))}}document.addEventListener("DOMContentLoaded",(()=>{(new l).init(),(new r).init(),(new d).init(),(new c).init(),(new h).init(),(new u).init(),(new b).init(),(new g).init(),(new p).init(),(new m).init(),(new f).init(),(new L).init()}))}();
|
|
1
|
+
!function(){"use strict";let t,e=0,i=document.querySelector("html");const s=s=>{t=document.activeElement,e=window.scrollY,i.style.setProperty("--scroll-position",`-${e}px`),i.classList.add("has-overlay"),s&&"true"===s.getAttribute("aria-hidden")&&s.setAttribute("aria-hidden",!1),n(s)},a=s=>{i.removeAttribute("style"),i.classList.remove("has-overlay"),i.classList.length||i.removeAttribute("class"),s&&"false"===s.getAttribute("aria-hidden")&&s.setAttribute("aria-hidden",!0),window.scrollTo({top:e,behavior:"instant"}),t&&t.focus()},o=function(){return[...(arguments.length>0&&void 0!==arguments[0]?arguments[0]:document).querySelectorAll(["a[href]","area","button","details","frame","iframe","input","object","summary","textarea","select",'[tabindex]:not([tabindex="-1"])',"video","audio"])].filter((t=>!t.hasAttribute("disabled")))},n=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,i=o(t),s=i[0],n=i[i.length-1];e.setAttribute("tabindex","-1"),e.focus(),t.addEventListener("keydown",(e=>{switch(e.code){case"Tab":document.activeElement===n&&(e.shiftKey||(e.preventDefault(),s.focus())),document.activeElement===s&&e.shiftKey&&(e.preventDefault(),n.focus());break;case"Escape":a(t)}}))};class l{#t=document.querySelectorAll(".accordion");#e(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];o(t).forEach((t=>{t.setAttribute("tabindex",e?0:-1)}))}#i=(t,e,i)=>s=>{s.preventDefault(),s.stopPropagation();for(const t of i)t.classList.remove("show"),t!==e&&(t.classList.remove("shown"),t.style.maxHeight=null,t.previousElementSibling.setAttribute("aria-expanded",!1),t.setAttribute("aria-hidden",!0),this.#e(t,!1));e.classList.toggle("shown");let a=t.getAttribute("aria-expanded");"true"===a?(t.setAttribute("aria-expanded",!1),e.setAttribute("aria-hidden",!0),this.#e(e,!1)):"false"===a&&(t.setAttribute("aria-expanded",!0),e.setAttribute("aria-hidden",!1),this.#e(e,!0)),e.style.maxHeight?e.style.maxHeight=null:(e.style.maxHeight=e.scrollHeight+"px",e.setAttribute("aria-hidden",!1));let o=new Event("accTrigger",{bubbles:!0});document.dispatchEvent(o)};#s=(t,e,i)=>t=>{const s=s=>{t.preventDefault();let a=i+s;-1===s&&a<0?e[e.length-1].focus():1===s&&a>=e.length?e[0].focus():e[a].focus()};switch(t.code){case"ArrowLeft":case"ArrowUp":s(-1);break;case"ArrowRight":case"ArrowDown":s(1)}};#a=(t,e,i)=>s=>{"Enter"===s.code&&"BUTTON"!==s.target.tagName&&this.#i(t,e,i)(s)};init(){this.#t.forEach((t=>{const e=Array.from(t.querySelectorAll(':scope > [data-accordion="button"]')),i=t.querySelectorAll(':scope > [data-accordion="panel"]');t.addEventListener("click",(t=>{const s=t.target.closest('[data-accordion="button"]');if(!s)return;if(-1===e.indexOf(s))return;const a=s.nextElementSibling;this.#i(s,a,i)(t)})),t.addEventListener("keydown",(t=>{const i=t.target.closest('[data-accordion="button"]');if(!i)return;const s=e.indexOf(i);-1!==s&&this.#s(i,e,s)(t)})),t.addEventListener("keyup",(t=>{const s=t.target.closest('[data-accordion="button"]');if(!s)return;e.indexOf(s);const a=s.nextElementSibling;this.#a(s,a,i)(t)})),e.forEach(((t,e)=>{const i=t.nextElementSibling;let s=t.getAttribute("aria-expanded");t.setAttribute("tabindex",0),"true"===s?(i.style.maxHeight=i.scrollHeight+"px",i.classList.add("show"),this.#e(i,!0)):(t.setAttribute("aria-expanded",!1),i.style.maxHeight=null,i.setAttribute("aria-hidden",!0),this.#e(i,!1))}))}))}}class r{#o=document.querySelectorAll(".alert--dismissable");#n='\n <button class="button button--icon-only">\n <span class="icon icon-close" aria-label="Close" aria-hidden="true">\n </button>\n ';#l=t=>e=>{e.preventDefault(),t.classList.add("dismissed"),document.querySelector(".dismissed").addEventListener("animationend",(()=>{t.remove()}))};init(){this.#o.forEach((t=>{t.insertAdjacentHTML("afterbegin",this.#n),t.querySelector("button").addEventListener("click",this.#l(t))}))}}class d{#r=document.querySelectorAll(".button--icon-only");#d=t=>e=>setTimeout((()=>{t.forEach((t=>{t.classList.remove("tooltip-show")})),e.target.classList.add("tooltip-show")}),300);#c=()=>(t,e)=>{clearTimeout(e),t.target.classList.remove("tooltip-show")};#h(t,e){const i=e.offsetWidth/2,s=t.offsetLeft,a=window.innerWidth-(t.offsetLeft+t.offsetWidth);i>s&&e.classList.add("left"),i>a&&e.classList.add("right")}#u=(t,e)=>{const i=`\n <span class="button__tooltip">\n ${e}\n </span>\n `;if(e){t.insertAdjacentHTML("beforeend",i);const e=t.querySelector(".button__tooltip");let s;this.#h(t,e),window.addEventListener("resize",(()=>this.#h(t,e))),t.addEventListener("mouseenter",(t=>{s=this.#d(this.#r)(t)})),t.addEventListener("focusin",(t=>{s=this.#d(this.#r)(t)})),t.addEventListener("mouseleave",(t=>{this.#c()(t,s)})),t.addEventListener("focusout",(t=>{this.#c()(t,s)}))}};init(){this.#r.forEach((t=>{const e=t.getAttribute("aria-label");this.#u(t,e)}))}}class c{#b=document.querySelectorAll("[data-target-toggle]");#g(t,e){t.setAttribute("aria-expanded",!1),e.classList.remove("shown")}#p(t,e,i){t.setAttribute("aria-expanded",!0),e.classList.add("shown"),i&&i.focus()}#s(t,e,i){return s=>{switch(s.code){case"Tab":document.activeElement===i&&s.shiftKey&&(s.preventDefault(),t.focus());break;case"Escape":this.#g(t,e)}}}#m(t,e){const i=t.target.getAttribute("data-target-toggle").replace(/#/,""),s=document.getElementById(i),a=o(s)[0],n=e.getAttribute("aria-expanded");"true"===n?this.#g(e,s):"false"===n&&this.#p(e,s,s.hasAttribute("data-focus-first")?a:null),s.addEventListener("keydown",this.#s(e,s,a))}init(){this.#b.forEach((t=>{t.setAttribute("aria-expanded",!1),t.addEventListener("click",(e=>{if(this.#m(e,t),t.hasAttribute("data-target-close")){const t=e.target.getAttribute("data-target-close").replace(/#/,""),i=document.getElementById(t),s=document.querySelector(`[data-target-toggle="#${t}"]`);this.#g(s,i)}}))}))}}class h{#f=document.querySelectorAll(".form-entry");#L=["is-invalid"];#v=!1;#y(){return""===(arguments.length>0&&void 0!==arguments[0]?arguments[0]:null)}#x(t){t.closest(".form-entry").classList.add(...this.#L)}#E(t){t.closest(".form-entry").classList.remove(...this.#L)}#A(t){return this.#y(t.value)?(this.#x(t),!0):(this.#E(t),!1)}#w(t){return e=>{e.target.closest(t).classList.add("active")}}#S(t){return e=>{e.target.closest(t).classList.remove("active")}}#C(t,e){this.#v&&e&&this.#A(t),""!==t.value?t.closest(".form-entry").classList.add("has-value"):t.closest(".form-entry").classList.remove("has-value")}#_(t){const e=t.querySelectorAll(["email","input","select","tel","textarea"]);let i=t.hasAttribute("data-required");e.forEach((t=>this.#q(t,i)))}#q(t,e){const i=t.closest(".form-entry").querySelector(".form-entry__field__input");let s=".form-entry";if("INPUT"===t.tagName){const e=t.getAttribute("type");"radio"!==e&&"checkbox"!==e||t.disabled&&t.closest("label").classList.add("disabled")}t.addEventListener("focusin",this.#w(s)),t.addEventListener("focusout",this.#S(s)),e&&(t.setAttribute("required","true"),t.setAttribute("aria-required",!0)),t.addEventListener("change",(()=>this.#C(t,e))),i&&i.addEventListener("click",this.handleClickOnInputText)}handleClickOnInputText(t){let e=t.target.tagName,i=t.target.closest(".form-entry__field__input").querySelector("input");"SPAN"===e&&i.focus()}init(){this.#f.forEach((t=>this.#_(t)))}}class u{#T=document.querySelectorAll("form[novalidate]");#L=["is-invalid"];#v=!1;#y(){return""===(arguments.length>0&&void 0!==arguments[0]?arguments[0]:null)}#x(t){t.closest(".form-entry").classList.add(...this.#L)}#E(t){t.closest(".form-entry").classList.remove(...this.#L)}#A(t){return this.#y(t.value)?(this.#x(t),!0):(this.#E(t),!1)}#k(t,e){return null===t&&(t="This field is Required"),`\n <small class="form-entry__feedback">\n <span class="icon icon-warn" aria-hidden="true"></span>\n <span class="message">\n <strong>${t}</strong> ${void 0!==e?e:""}\n </span>\n </small>\n `}#H(t,e){t.forEach((t=>{let i=t.closest(".form-entry"),s=i.querySelector(".form-entry__field__label");i.classList.add("is-invalid");const a=i.querySelector(".form-entry__feedback"),o=i.querySelector(".form-entry__help");let n;o&&(n=o.innerHTML.toString());let l=i.getAttribute("data-error-message"),r=[l,n];e.push(r),null===a&&s.insertAdjacentHTML("afterend",this.#k(l,n))}))}#D(t){let e=t.querySelector('[class*="alert"], [class*="invalid"]');if(e){e.hasAttribute("data-alert")&&(e.style.display="block");let t=e.offsetTop-16;window.scrollTo({top:t,behavior:"smooth"})}}#I(t){t.addEventListener("submit",(e=>{e.preventDefault(),this.#v=!0;let i=[],s=t.querySelectorAll("input, select, textarea");s.forEach((t=>{t.addEventListener("input",(()=>this.#A(t)))})),s.forEach((t=>{this.#A(t)}));let a=t.querySelectorAll(":invalid");this.#H(a,i),i.length>0&&e.preventDefault(),this.#D(t)}))}init(){this.#T.forEach((t=>this.#I(t)))}}class b{#M=document.querySelectorAll(".file-upload");#F(t){return function(e){const[i]=e.target.files,{name:s,size:a}=i,o=`\n <span class="file-upload__data">\n <span class="file-name">${s}</span>\n <span class="file-size">${(a/1e3).toFixed(2)} kb</span>\n </span>\n `,n=t.querySelector(".file-upload__data");n&&n.remove(),t.insertAdjacentHTML("beforeend",o)}}dragOver(t){t.target.closest(".form-entry").classList.add("active")}dragOff(t){t.target.closest(".form-entry").classList.remove("active")}dropped(t){t.target.closest(".form-entry").classList.remove("active")}#O(t){t.querySelector('input[type="file"]').addEventListener("change",this.#F(t)),t.addEventListener("dragenter",this.dragOver.bind(this)),t.addEventListener("dragleave",this.dragOff.bind(this)),t.addEventListener("dragend",this.dragOff.bind(this)),t.addEventListener("drop",this.dropped.bind(this))}init(){this.#M.forEach((t=>this.#O(t)))}}class g{#B=document.querySelectorAll("[data-lightbox]");#N='\n\t\t<figure class="lightbox__container" aria-live="polite" aria-atomic="true">\n\t\t\t<div class="lightbox__media"></div> \n\t\t\t<figcaption class="lightbox__caption"></figcaption>\n\t\t</figure>\n\t\t<div class="lightbox__controls">\n\t\t\t<button class="button button--icon-only" data-lightbox-previous>\n\t\t\t\t<span class="icon icon-arrow-left" aria-label="Previous" aria-hidden="true"></span>\n\t\t\t</button>\n\t\t\t<button class="button button--icon-only" data-lightbox-next>\n\t\t\t\t<span class="icon icon-arrow-right" aria-label="Next" aria-hidden="true"></span>\n\t\t\t</button>\n\t\t\t<button class="button button--icon-only" data-lightbox-close>\n\t\t\t\t<span class="icon icon-close" aria-label="Close" aria-hidden="true"></span>\n\t\t\t</button>\n\t\t</div>\n \t';#U='\n\t\t<video controls tabindex="0">\n\t\t\t<source type="video/mp4">\n\t\t</video>\n\t';#P='\n\t\t<iframe\n\t\t\tframeborder="0"\n\t\t\tallow="autoplay; fullscreen;"\n\t\t\tallowfullscreen\n\t\t\tcontrols\n\t\t\ttabindex="0"\n\t\t></iframe>\n\t';#$='\n\t\t<div class="lightbox__media__loader">\n\t\t\t<span class="icon icon-loading icon--rotate" aria-hidden="true"></span>\n\t\t</div>\n\t\t<div class="lightbox__media__error" style="display: none;">\n\t\t\t<span class="icon icon-warn" aria-hidden="true"></span>\n\t\t\t<p>Failed to load content. Please try again later.</p>\n\t\t</div>\n\t';#K='<img src="https://source.unsplash.com/1600x900" />';#V=[];#R=t=>e=>{document.querySelector(".lightbox")||(e.preventDefault(),this.lightbox=this.#W(),this.currentLB=t,this.#z(t),s(this.lightbox))};#j=t=>{t.stopPropagation(),t.target!==t.currentTarget&&"click"===t.type||(a(this.lightbox),this.lightbox.parentElement.removeChild(this.lightbox),window.removeEventListener("keyup",this.#Y))};#G=(()=>{var t=this;return function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];t.lightbox.querySelector(".lightbox__caption").style.display=e?"block":"none"}})();#J=t=>{if(t.preventDefault(),t.target.hasAttribute("data-lightbox-previous"))this.#Q(-1);else{if(!t.target.hasAttribute("data-lightbox-next"))return;this.#Q(1)}};#Y=t=>{if(t.preventDefault(),!(this.#V.length<=1)||"ArrowLeft"!==t.code&&"ArrowRight"!==t.code)switch(t.code){case"ArrowLeft":this.#Q(-1),this.lightbox.querySelector("[data-lightbox-previous]").focus();break;case"ArrowRight":this.#Q(1),this.lightbox.querySelector("[data-lightbox-next]").focus();break;case"Escape":this.#j(t);break;default:return}};#X=t=>{t.setAttribute("tabindex",0),t.addEventListener("focus",(e=>{e.preventDefault(),t.children[0].focus(),o(t.children[0])}))};#Q(t){this.currentLB+=t,this.currentLB<0?this.currentLB=this.#V.length-1:this.currentLB>=this.#V.length&&(this.currentLB=0),this.#z(this.currentLB)}#z(t){const e=this.lightbox.querySelector(".lightbox__media"),i=this.lightbox.querySelector(".lightbox__caption");let s;e.innerHTML="";const{lbType:a,lbSrc:o,lbAlt:l,lbCaption:r}=this.#V[t],d=null!==r;switch(this.#G(d),a){case"image":s=this.#Z(e,o,l);break;case"video":s=this.#tt(e,o)}this.#X(e),d&&(i.innerHTML=r),n(this.lightbox)}#Z(t,e,i){t.hasAttribute("style")&&t.removeAttribute("style"),t.innerHTML=this.#K;const s=this.#et();t.appendChild(s);const a=t.querySelector("img");return a.alt=i,a.src=e,this.#it(a,s),a}#tt(t,e){const i=/youtube/i.test(e),s=/vimeo/i.test(e);let a;if(i||s)t.innerHTML=this.#P,a=t.querySelector("iframe"),a.src=e;else{t.innerHTML=this.#U;const i=this.#et();t.appendChild(i),a=t.querySelector("source");const s=t.querySelector("video");s.addEventListener("loadedmetadata",(()=>{let e=s.videoWidth,i=s.videoHeight;t.style.maxWidth=`${e}px`,t.style.aspectRatio=`${e} / ${i}`})),this.#it(a,i),a.src=e}return a}#W(){const t=document.createElement("div");t.classList.add("lightbox"),t.setAttribute("aria-hidden",!0),t.setAttribute("aria-live","polite"),t.innerHTML=this.#N,document.body.appendChild(t);const e=t.querySelector("[data-lightbox-previous]"),i=t.querySelector("[data-lightbox-next]"),s=t.querySelector("[data-lightbox-close]");return this.#V.length<=1&&(e.setAttribute("disabled",!0),i.setAttribute("disabled",!0),e.style.display="none",i.style.display="none"),t.addEventListener("click",this.#j),s.addEventListener("click",this.#j),e.addEventListener("click",this.#J),i.addEventListener("click",this.#J),window.addEventListener("keyup",this.#Y),t}#st(t){if(!t)return void console.error("No lightbox button provided");let e=null,i="";if(null!==t.querySelector("img")){const s=t.querySelector("img");e=s.src||null,i=s.alt||""}const s=t.getAttribute("data-lightbox")||"image",a=t.getAttribute("data-lightbox-src")||e,o=t.getAttribute("data-lightbox-caption")||null,n=t.getAttribute("data-lightbox-alt")||i;if(null!==a)return{lbType:s,lbSrc:a,lbCaption:o,lbAlt:n};console.error("No source provided for lightbox")}#at(){this.#B.forEach((t=>{this.#V.push(this.#st(t))}))}#et=()=>{const t=document.createElement("div");return t.className="lightbox__media__loader",t.innerHTML=this.#$,t};#it=(t,e)=>{const i="SOURCE"===t.nodeName?"loadeddata":"load";t.closest("SOURCE"===t.nodeName?"video":"img").addEventListener(i,(()=>{e&&e.parentNode&&e.parentNode.removeChild(e),null!==this.#V[this.currentLB].lbCaption&&this.#G(!0)})),t.onerror=()=>{const i=e.querySelector(".lightbox__media__loader"),s=e.querySelector(".lightbox__media__error");t.style.display="none",this.#G(!1),i.style.display="none",s.style.display="block"}};#ot(){const t=new IntersectionObserver(((t,e)=>{t.forEach((t=>{if(t.isIntersecting){const i=t.target,s=i.dataset.lightboxSrc||i.src;if(!s)return;e.unobserve(i);const a=new Image;a.onload=()=>{document.body.appendChild(a)},a.onerror=()=>{console.error(`Failed to load image: ${s}`)},a.src=s,a.style.display="none",this.#V[Number(i.dataset.index)].hiddenImage=a}}))}),{root:null,rootMargin:"0px",threshold:.1});Array.from(this.#B).filter((t=>"image"===t.getAttribute("data-lightbox"))).forEach(((e,i)=>{const s=e.querySelector("img");s&&(s.dataset.index=i,t.observe(s))}))}#nt(){this.#B.forEach(((t,e)=>{t.addEventListener("click",this.#R(e))}))}init(){this.#at(),this.#nt(),this.#ot()}}class p{#lt=document.querySelectorAll(".modal");#rt=document.querySelectorAll("[data-modal-open]");#dt=new Map;#ct(t,e){window.addEventListener("click",e),this.#dt.set(t,e)}#ht(t){const e=this.#dt.get(t);e&&(window.removeEventListener("click",e),this.#dt.delete(t))}openModal(t){if(!t)return void console.warn("Modal target not found.");s(t);const e=t.querySelector(".modal__content");if(!e)return void console.warn("Modal content not found.");t.classList.contains("modal--scroll-all")&&(t.scrollTop=0);t.querySelectorAll("[data-modal-close]").forEach((e=>{e.addEventListener("click",(()=>{a(t),this.#ht(t)})),e.setAttribute("aria-label","Close Modal Window")})),"true"===t.dataset.modalCloseOutside&&this.#ct(t,(i=>{e.contains(i.target)||(a(t),this.#ht(t))}))}init(){this.#lt.forEach((t=>{const e=t.querySelector(".modal__content");e.setAttribute("role","dialog"),e.setAttribute("aria-modal",!0),t.setAttribute("aria-hidden",!0)})),this.#rt.forEach((t=>{t.addEventListener("click",(t=>{const e=t.target.getAttribute("data-modal-open").replace(/#/,""),i=document.getElementById(e);this.openModal(i),t.stopPropagation()}))}))}}class m{#ut=document.querySelectorAll('[data-toggle="dropdown"]');#bt(t,e){e.classList.toggle("shown"),t.setAttribute("aria-expanded","true"===t.getAttribute("aria-expanded")?"false":"true")}#gt(t,e){e.classList.remove("shown"),t.setAttribute("aria-expanded","false")}init(){window.addEventListener("click",(t=>{this.#ut.forEach((e=>{let i=e.closest("li"),s=e.nextElementSibling;i.contains(t.target)||this.#gt(e,s)}))})),this.#ut.forEach((t=>{let e=t.nextElementSibling;e?(t.setAttribute("aria-expanded","false"),t.setAttribute("aria-haspopup","true"),t.addEventListener("click",(i=>{i.preventDefault(),this.#bt(t,e)}))):console.warn(`No dropdown menu found for dropdown button ${t}`)}))}}class f{#pt=document.querySelectorAll('[class*="table--stack"]');#mt=document.querySelectorAll(".table-scroll");#ft(t){const e=t.querySelectorAll("thead th"),i=t.querySelectorAll("tbody tr");let s=[];e.forEach((t=>{if(""!==t.textContent){const e=t.textContent.trim();s.push(e)}})),i.forEach((t=>{t.querySelectorAll("td").forEach(((t,e)=>{t.innerHTML=this.#Lt(t.innerHTML),t.setAttribute("data-header",s[e])}))}))}#Lt(t){return`\n\t\t\t<div class="td-content">\n\t\t\t\t${t}\n\t\t\t</div>\n\t\t`}#vt(){this.#mt.forEach((t=>{let e=t.querySelector(".table-scroll__container"),i=t.offsetWidth;e.scrollWidth>i?t.setAttribute("data-scroll",!0):t.setAttribute("data-scroll",!1),e.addEventListener("scroll",(()=>{e.scrollLeft>1?e.setAttribute("data-scrolling",!0):e.setAttribute("data-scrolling",!1)}),{passive:!0})}))}init(){this.#pt.forEach((t=>{this.#ft(t)})),this.#vt(),window.addEventListener("resize",this.#vt.bind(this))}}class L{#yt=document.querySelectorAll(".tabs");#xt(t,e,i,s){t.preventDefault();let a=e+s;-1===s&&a<0?i[i.length-1].focus():1===s&&a>=i.length?i[0].focus():i[a].focus()}#Et(t,e){t.forEach((t=>{t.setAttribute("aria-selected","false")})),e.forEach((t=>{t.classList.remove("shown"),t.setAttribute("hidden","")}))}activateTab(t,e,i){this.#Et(e,i),t.setAttribute("aria-selected","true");let s=t.getAttribute("aria-controls"),a=document.getElementById(s);a.classList.add("shown"),a.removeAttribute("hidden")}init(){this.#yt.forEach((t=>{const e=t.querySelectorAll('[role="tab"]'),i=t.querySelectorAll('[role="tabpanel"]');e.forEach(((t,s)=>{t.addEventListener("click",(t=>{let s=t.target;this.activateTab(s,e,i)})),t.addEventListener("keydown",(t=>{switch(t.code){case"Home":t.preventDefault(),e[0].focus();break;case"End":t.preventDefault(),e[e.length-1].focus();break;case"ArrowLeft":this.#xt(t,s,e,-1);break;case"ArrowRight":this.#xt(t,s,e,1)}}))}))}))}}document.addEventListener("DOMContentLoaded",(()=>{(new l).init(),(new r).init(),(new d).init(),(new c).init(),(new h).init(),(new u).init(),(new b).init(),(new g).init(),(new p).init(),(new m).init(),(new f).init(),(new L).init()}))}();
|
package/package.json
CHANGED
package/src/js/lightbox.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { handleOverlayOpen, handleOverlayClose } from './utilities/overlay';
|
|
2
2
|
|
|
3
|
+
import { focusTrap, getFocusableElements } from './utilities/focus';
|
|
4
|
+
|
|
3
5
|
export default class Lightbox {
|
|
4
6
|
|
|
5
7
|
// Private properties
|
|
@@ -7,26 +9,26 @@ export default class Lightbox {
|
|
|
7
9
|
#lightboxTargetList = document.querySelectorAll('[data-lightbox]');
|
|
8
10
|
|
|
9
11
|
#lightboxHTML = `
|
|
10
|
-
<div class="lightbox__buttons button-group">
|
|
11
|
-
<button class="button button--icon-only" data-lightbox-previous>
|
|
12
|
-
<span class="icon icon-arrow-left" aria-label="Previous" aria-hidden="true"></span>
|
|
13
|
-
</button>
|
|
14
|
-
<button class="button button--icon-only" data-lightbox-next>
|
|
15
|
-
<span class="icon icon-arrow-right" aria-label="Next" aria-hidden="true"></span>
|
|
16
|
-
</button>
|
|
17
|
-
<button class="button button--icon-only" data-lightbox-close>
|
|
18
|
-
<span class="icon icon-close" aria-label="Close" aria-hidden="true"></span>
|
|
19
|
-
</button>
|
|
20
|
-
</div>
|
|
21
12
|
<figure class="lightbox__container" aria-live="polite" aria-atomic="true">
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
<div class="lightbox__media"></div>
|
|
14
|
+
<figcaption class="lightbox__caption"></figcaption>
|
|
24
15
|
</figure>
|
|
16
|
+
<div class="lightbox__controls">
|
|
17
|
+
<button class="button button--icon-only" data-lightbox-previous>
|
|
18
|
+
<span class="icon icon-arrow-left" aria-label="Previous" aria-hidden="true"></span>
|
|
19
|
+
</button>
|
|
20
|
+
<button class="button button--icon-only" data-lightbox-next>
|
|
21
|
+
<span class="icon icon-arrow-right" aria-label="Next" aria-hidden="true"></span>
|
|
22
|
+
</button>
|
|
23
|
+
<button class="button button--icon-only" data-lightbox-close>
|
|
24
|
+
<span class="icon icon-close" aria-label="Close" aria-hidden="true"></span>
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
25
27
|
`;
|
|
26
28
|
|
|
27
29
|
#lightboxVideoHTML = `
|
|
28
|
-
<video controls>
|
|
29
|
-
|
|
30
|
+
<video controls tabindex="0">
|
|
31
|
+
<source type="video/mp4">
|
|
30
32
|
</video>
|
|
31
33
|
`;
|
|
32
34
|
|
|
@@ -35,6 +37,8 @@ export default class Lightbox {
|
|
|
35
37
|
frameborder="0"
|
|
36
38
|
allow="autoplay; fullscreen;"
|
|
37
39
|
allowfullscreen
|
|
40
|
+
controls
|
|
41
|
+
tabindex="0"
|
|
38
42
|
></iframe>
|
|
39
43
|
`;
|
|
40
44
|
|
|
@@ -65,9 +69,8 @@ export default class Lightbox {
|
|
|
65
69
|
|
|
66
70
|
this.currentLB = index;
|
|
67
71
|
|
|
68
|
-
handleOverlayOpen(this.lightbox);
|
|
69
|
-
|
|
70
72
|
this.#updateLightbox(index);
|
|
73
|
+
handleOverlayOpen(this.lightbox);
|
|
71
74
|
};
|
|
72
75
|
|
|
73
76
|
#handleLightboxClose = (e) => {
|
|
@@ -126,6 +129,18 @@ export default class Lightbox {
|
|
|
126
129
|
}
|
|
127
130
|
};
|
|
128
131
|
|
|
132
|
+
// Add this private method in your class
|
|
133
|
+
#handleVideoFocus = (lightboxElement) => {
|
|
134
|
+
const handleFocusEvent = (event) => {
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
lightboxElement.children[0].focus();
|
|
137
|
+
getFocusableElements(lightboxElement.children[0]);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
lightboxElement.setAttribute('tabindex', 0);
|
|
141
|
+
lightboxElement.addEventListener('focus', handleFocusEvent);
|
|
142
|
+
};
|
|
143
|
+
|
|
129
144
|
#updateDirection(dir) {
|
|
130
145
|
this.currentLB += dir;
|
|
131
146
|
|
|
@@ -144,6 +159,7 @@ export default class Lightbox {
|
|
|
144
159
|
|
|
145
160
|
// Clear the previous lightbox content before inserting a new one
|
|
146
161
|
lightboxElement.innerHTML = '';
|
|
162
|
+
|
|
147
163
|
|
|
148
164
|
let lightboxElementTarget;
|
|
149
165
|
|
|
@@ -170,15 +186,21 @@ export default class Lightbox {
|
|
|
170
186
|
lightboxElement,
|
|
171
187
|
lbSrc
|
|
172
188
|
);
|
|
189
|
+
|
|
173
190
|
break;
|
|
174
191
|
|
|
175
192
|
default:
|
|
176
193
|
break;
|
|
177
194
|
}
|
|
178
195
|
|
|
196
|
+
// Handle video focus
|
|
197
|
+
this.#handleVideoFocus(lightboxElement);
|
|
198
|
+
|
|
179
199
|
if (shouldDisplayCaption) {
|
|
180
200
|
lightboxCaption.innerHTML = lbCaption;
|
|
181
201
|
}
|
|
202
|
+
|
|
203
|
+
focusTrap(this.lightbox);
|
|
182
204
|
}
|
|
183
205
|
|
|
184
206
|
#updateLightboxImage(lightboxElement, lbSrc, lbAlt) {
|
|
@@ -202,56 +224,57 @@ export default class Lightbox {
|
|
|
202
224
|
}
|
|
203
225
|
|
|
204
226
|
#updateLightboxVideo(lightboxElement, lbSrc) {
|
|
205
|
-
|
|
206
|
-
|
|
227
|
+
// Check if the string contains 'youtube' (case-insensitive)
|
|
228
|
+
const hasYouTube = /youtube/i.test(lbSrc);
|
|
207
229
|
|
|
208
|
-
|
|
209
|
-
|
|
230
|
+
// Check if the string contains 'vimeo' (case-insensitive)
|
|
231
|
+
const hasVimeo = /vimeo/i.test(lbSrc);
|
|
210
232
|
|
|
211
|
-
|
|
233
|
+
let lightboxElementTarget;
|
|
212
234
|
|
|
213
|
-
|
|
235
|
+
if (hasYouTube || hasVimeo) {
|
|
214
236
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
237
|
+
// If the video is from YouTube or Vimeo, use an iframe
|
|
238
|
+
lightboxElement.innerHTML = this.#lightboxVideoIframeHTML;
|
|
239
|
+
lightboxElementTarget = lightboxElement.querySelector('iframe');
|
|
240
|
+
lightboxElementTarget.src = lbSrc;
|
|
241
|
+
|
|
242
|
+
} else {
|
|
221
243
|
|
|
222
|
-
|
|
223
|
-
|
|
244
|
+
// If the video is not from YouTube or Vimeo, use a video element
|
|
245
|
+
lightboxElement.innerHTML = this.#lightboxVideoHTML;
|
|
224
246
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
247
|
+
const loader = this.#createLoader();
|
|
248
|
+
lightboxElement.appendChild(loader);
|
|
249
|
+
|
|
250
|
+
lightboxElementTarget = lightboxElement.querySelector('source');
|
|
251
|
+
|
|
252
|
+
const video = lightboxElement.querySelector('video');
|
|
231
253
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
254
|
+
video.addEventListener('loadedmetadata', () => {
|
|
255
|
+
// The intrinsic width and height of the video
|
|
256
|
+
let intrinsicWidth = video.videoWidth;
|
|
257
|
+
let intrinsicHeight = video.videoHeight;
|
|
236
258
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
259
|
+
// The aspect ratio of the video
|
|
260
|
+
lightboxElement.style.maxWidth = `${intrinsicWidth}px`;
|
|
261
|
+
lightboxElement.style.aspectRatio = `${intrinsicWidth} / ${intrinsicHeight}`;
|
|
262
|
+
});
|
|
241
263
|
|
|
242
|
-
|
|
264
|
+
this.#handleMediaLoading(lightboxElementTarget, loader);
|
|
243
265
|
|
|
244
|
-
|
|
245
|
-
|
|
266
|
+
lightboxElementTarget.src = lbSrc;
|
|
267
|
+
}
|
|
246
268
|
|
|
247
|
-
|
|
248
|
-
|
|
269
|
+
return lightboxElementTarget;
|
|
270
|
+
}
|
|
249
271
|
|
|
250
272
|
#createLightbox() {
|
|
251
273
|
const lightbox = document.createElement('div');
|
|
252
274
|
|
|
253
275
|
lightbox.classList.add('lightbox');
|
|
254
276
|
lightbox.setAttribute('aria-hidden', true);
|
|
277
|
+
lightbox.setAttribute('aria-live', 'polite');
|
|
255
278
|
lightbox.innerHTML = this.#lightboxHTML;
|
|
256
279
|
|
|
257
280
|
document.body.appendChild(lightbox);
|
|
@@ -279,23 +302,32 @@ export default class Lightbox {
|
|
|
279
302
|
}
|
|
280
303
|
|
|
281
304
|
#setLightboxProperties(lightboxButton) {
|
|
305
|
+
|
|
306
|
+
if (!lightboxButton) {
|
|
307
|
+
console.error("No lightbox button provided");
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
|
|
282
311
|
let defaultSrc = null;
|
|
283
312
|
let defaultAlt = '';
|
|
284
313
|
|
|
285
314
|
const hasImage = lightboxButton.querySelector('img') !== null;
|
|
286
315
|
|
|
287
316
|
if (hasImage) {
|
|
288
|
-
|
|
289
|
-
|
|
317
|
+
const img = lightboxButton.querySelector('img');
|
|
318
|
+
defaultSrc = img.src || null;
|
|
319
|
+
defaultAlt = img.alt || '';
|
|
290
320
|
}
|
|
291
321
|
|
|
292
322
|
const lbType = lightboxButton.getAttribute('data-lightbox') || 'image';
|
|
293
|
-
const lbSrc =
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
323
|
+
const lbSrc = lightboxButton.getAttribute('data-lightbox-src') || defaultSrc;
|
|
324
|
+
const lbCaption = lightboxButton.getAttribute('data-lightbox-caption') || null;
|
|
325
|
+
const lbAlt = lightboxButton.getAttribute('data-lightbox-alt') || defaultAlt;
|
|
326
|
+
|
|
327
|
+
if (lbSrc === null) {
|
|
328
|
+
console.error("No source provided for lightbox");
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
299
331
|
|
|
300
332
|
return {
|
|
301
333
|
lbType: lbType,
|
|
@@ -380,8 +412,7 @@ export default class Lightbox {
|
|
|
380
412
|
hiddenLargeImage.src = src;
|
|
381
413
|
hiddenLargeImage.style.display = 'none';
|
|
382
414
|
|
|
383
|
-
this.#lightboxes[Number(lazyImage.dataset.index)].hiddenImage =
|
|
384
|
-
hiddenLargeImage;
|
|
415
|
+
this.#lightboxes[Number(lazyImage.dataset.index)].hiddenImage = hiddenLargeImage;
|
|
385
416
|
}
|
|
386
417
|
});
|
|
387
418
|
}, options);
|
|
@@ -28,11 +28,12 @@ export const getFocusableElements = (element = document) => {
|
|
|
28
28
|
'textarea',
|
|
29
29
|
'select',
|
|
30
30
|
'[tabindex]:not([tabindex="-1"])',
|
|
31
|
+
'video',
|
|
32
|
+
'audio'
|
|
31
33
|
];
|
|
32
34
|
|
|
33
35
|
return [...element.querySelectorAll(els)].filter((el) => {
|
|
34
|
-
return !el.hasAttribute('disabled')
|
|
35
|
-
!el.getAttribute('aria-hidden');
|
|
36
|
+
return !el.hasAttribute('disabled');
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
|
|
@@ -42,6 +43,7 @@ export const getFocusableElements = (element = document) => {
|
|
|
42
43
|
|
|
43
44
|
export const focusTrap = (element, firstFocusTarget = element) => {
|
|
44
45
|
let focusableElements = getFocusableElements(element);
|
|
46
|
+
|
|
45
47
|
let firstFocusableElement = focusableElements[0];
|
|
46
48
|
let lastFocusableElement = focusableElements[focusableElements.length - 1];
|
|
47
49
|
|
package/src/scss/_accordion.scss
CHANGED
|
@@ -20,9 +20,11 @@ In this file:
|
|
|
20
20
|
|
|
21
21
|
:root {
|
|
22
22
|
--accordion-button-padding-x: var(--spacer-3);
|
|
23
|
+
|
|
23
24
|
--accordion-button-padding-y: var(--button-padding-y);
|
|
24
25
|
|
|
25
26
|
--accordion-panel-padding-x: var(--spacer-3);
|
|
27
|
+
|
|
26
28
|
--accordion-panel-padding-y: var(--spacer-3);
|
|
27
29
|
|
|
28
30
|
--accordion-active-color: currentColor;
|
package/src/scss/_alert.scss
CHANGED
package/src/scss/_button.scss
CHANGED
|
@@ -20,6 +20,7 @@ In this file:
|
|
|
20
20
|
|
|
21
21
|
:root {
|
|
22
22
|
--button-padding-x: 1em;
|
|
23
|
+
|
|
23
24
|
--button-padding-y: 0.75em;
|
|
24
25
|
|
|
25
26
|
--button-font-weight: var(--body-font-weight-bold);
|
|
@@ -34,9 +35,12 @@ In this file:
|
|
|
34
35
|
|
|
35
36
|
--button-icon-only-size: 2.5em;
|
|
36
37
|
|
|
37
|
-
--button-icon-over-text-width:
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
--button-icon-over-text-width: 4em;
|
|
39
|
+
|
|
40
|
+
--button-icon-over-text-border-radius: var(--button-border-radius);
|
|
41
|
+
|
|
42
|
+
--button-icon-over-text-font-size: 0.675em;
|
|
43
|
+
|
|
40
44
|
--button-group-gap: 0.5em;
|
|
41
45
|
}
|
|
42
46
|
|
|
@@ -70,8 +74,7 @@ In this file:
|
|
|
70
74
|
@layer component {
|
|
71
75
|
|
|
72
76
|
.button {
|
|
73
|
-
--button-opacity-hover: 0.75;
|
|
74
|
-
|
|
77
|
+
--button-opacity-hover: 0.75;
|
|
75
78
|
--subtle-fill-opacity: 0.05;
|
|
76
79
|
|
|
77
80
|
position: relative;
|
|
@@ -245,10 +248,10 @@ In this file:
|
|
|
245
248
|
|
|
246
249
|
display: flex;
|
|
247
250
|
flex-direction: column;
|
|
248
|
-
|
|
251
|
+
|
|
249
252
|
text-align: center;
|
|
250
253
|
|
|
251
|
-
gap: 0.
|
|
254
|
+
gap: 0.375em;
|
|
252
255
|
|
|
253
256
|
width: var(--button-icon-over-text-width);
|
|
254
257
|
|
|
@@ -272,13 +275,12 @@ In this file:
|
|
|
272
275
|
[class*="__text"] {
|
|
273
276
|
min-width: 100%;
|
|
274
277
|
|
|
275
|
-
font-size: var(--font-size
|
|
278
|
+
font-size: var(--button-icon-over-text-font-size);
|
|
276
279
|
|
|
277
280
|
font-weight: var(--body-font-weight-bold);
|
|
278
281
|
}
|
|
279
282
|
|
|
280
283
|
&:focus-visible {
|
|
281
|
-
|
|
282
284
|
outline: unset;
|
|
283
285
|
|
|
284
286
|
> [class*="icon"] {
|
|
@@ -286,7 +288,6 @@ In this file:
|
|
|
286
288
|
outline-offset: var(--focus-outline-offset);
|
|
287
289
|
}
|
|
288
290
|
}
|
|
289
|
-
|
|
290
291
|
}
|
|
291
292
|
|
|
292
293
|
// Button Group
|
|
@@ -303,9 +304,8 @@ In this file:
|
|
|
303
304
|
> [class*="button"]:not(.button--icon-only) {
|
|
304
305
|
--button-padding-y: 0;
|
|
305
306
|
|
|
306
|
-
align-self: stretch;
|
|
307
|
-
|
|
308
307
|
display: flex;
|
|
308
|
+
align-self: stretch;
|
|
309
309
|
align-items: center;
|
|
310
310
|
flex-shrink: 0;
|
|
311
311
|
|
package/src/scss/_card.scss
CHANGED
package/src/scss/_container.scss
CHANGED
package/src/scss/_form.scss
CHANGED
|
@@ -24,18 +24,25 @@ In this file:
|
|
|
24
24
|
|
|
25
25
|
:root {
|
|
26
26
|
--form-field-padding-x: var(--spacer-3);
|
|
27
|
+
|
|
27
28
|
--form-field-padding-y: var(--button-padding-y);
|
|
28
29
|
|
|
29
30
|
--form-field-border-radius: 0.25em;
|
|
31
|
+
|
|
30
32
|
--form-field-border-color: currentColor;
|
|
31
33
|
|
|
32
34
|
// Icons
|
|
33
35
|
|
|
34
36
|
--icon-required: "\f14a";
|
|
37
|
+
|
|
35
38
|
--icon-checkbox-unchecked: "\f10d";
|
|
39
|
+
|
|
36
40
|
--icon-checkbox-checked: "\f10c";
|
|
41
|
+
|
|
37
42
|
--icon-radio-unchecked: "\f138";
|
|
43
|
+
|
|
38
44
|
--icon-radio-checked: "\f137";
|
|
45
|
+
|
|
39
46
|
--icon-disabled: "\f115";
|
|
40
47
|
}
|
|
41
48
|
|
package/src/scss/_grid.scss
CHANGED