maverick-wave 4.28.0 → 5.1.0
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/.claude/settings.local.json +29 -1
- package/.claude/skills/mw-maverick-wave/SKILL.md +39 -24
- package/.claude/skills/mw-maverick-wave/examples/angular-services.md +16 -4
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +13 -4
- package/.claude/skills/mw-maverick-wave/references/components.md +42 -5
- package/.claude/skills/mw-maverick-wave/references/forms.md +14 -2
- package/.claude/skills/mw-maverick-wave/references/javascript.md +17 -4
- package/.claude/skills/mw-maverick-wave/references/layout.md +53 -19
- package/.claude/skills/mw-maverick-wave/references/theming.md +38 -1
- package/.impeccable/config.local.json +5 -0
- package/.impeccable/hook.cache.json +75 -0
- package/CHANGELOG.md +17 -0
- package/CLAUDE.md +5 -5
- package/README.md +48 -4
- package/index.html +19 -38
- package/maverick-wave.min.css +14 -12
- package/maverick-wave.min.js +1 -1
- package/package.json +2 -2
- package/scripts/verify.js +27 -2
- package/src/js/main.js +223 -83
- package/src/partials/accordions-container.html +6 -10
- package/src/partials/alerts-container.html +6 -6
- package/src/partials/announcement-container.html +5 -5
- package/src/partials/avatars-container.html +85 -17
- package/src/partials/badges-container.html +6 -6
- package/src/partials/blog-posts-container.html +11 -12
- package/src/partials/buttons-container.html +3 -3
- package/src/partials/cards-container.html +26 -9
- package/src/partials/code-container.html +5 -5
- package/src/partials/content-slider-container.html +5 -4
- package/src/partials/divider-container.html +7 -7
- package/src/partials/dropdown-container.html +2 -2
- package/src/partials/empty-state-container.html +5 -5
- package/src/partials/footer-container.html +21 -18
- package/src/partials/form-elements-container.html +14 -14
- package/src/partials/gallery-container.html +16 -8
- package/src/partials/get-started-container.html +4 -8
- package/src/partials/header-container.html +18 -7
- package/src/partials/home-container.html +10 -20
- package/src/partials/input-group-container.html +11 -2
- package/src/partials/kbd-container.html +1 -1
- package/src/partials/login-container.html +5 -1
- package/src/partials/media-container.html +2 -2
- package/src/partials/modals-container.html +22 -32
- package/src/partials/pricing-container.html +9 -9
- package/src/partials/skeleton-container.html +6 -6
- package/src/partials/stepper-container.html +2 -2
- package/src/partials/tables-container.html +12 -12
- package/src/partials/tabs-container.html +17 -27
- package/src/partials/tags-container.html +23 -17
- package/src/partials/techstack-bucket-container.html +13 -0
- package/src/partials/tiles-container.html +26 -9
- package/src/partials/typography-container.html +7 -6
- package/src/partials/utilities-container.html +35 -15
- package/src/scss/_layers.scss +10 -0
- package/src/scss/abstracts/_index.scss +6 -0
- package/src/scss/abstracts/_mixins.scss +61 -153
- package/src/scss/abstracts/_variables.scss +123 -319
- package/src/scss/base/_base.scss +170 -190
- package/src/scss/base/_reset.scss +106 -104
- package/src/scss/base/_typography.scss +153 -151
- package/src/scss/components/_accordions.scss +97 -97
- package/src/scss/components/_alerts.scss +71 -70
- package/src/scss/components/_announcement.scss +71 -70
- package/src/scss/components/_avatars.scss +130 -142
- package/src/scss/components/_badge.scss +131 -132
- package/src/scss/components/_blog-post.scss +223 -220
- package/src/scss/components/_breadcrumbs.scss +93 -92
- package/src/scss/components/_button-bar.scss +102 -110
- package/src/scss/components/_buttons.scss +319 -324
- package/src/scss/components/_calendar.scss +251 -252
- package/src/scss/components/_cards.scss +359 -386
- package/src/scss/components/_code.scss +190 -194
- package/src/scss/components/_coming-soon.scss +77 -75
- package/src/scss/components/_content-slider.scss +90 -89
- package/src/scss/components/_divider.scss +55 -53
- package/src/scss/components/_dropdown.scss +179 -185
- package/src/scss/components/_empty-state.scss +57 -57
- package/src/scss/components/_flag.scss +294 -278
- package/src/scss/components/_gallery.scss +131 -133
- package/src/scss/components/_info.scss +151 -167
- package/src/scss/components/_kanban.scss +332 -341
- package/src/scss/components/_kbd.scss +40 -38
- package/src/scss/components/_lang-switch.scss +89 -97
- package/src/scss/components/_links.scss +21 -28
- package/src/scss/components/_lists.scss +510 -514
- package/src/scss/components/_localhost-indicator.scss +26 -24
- package/src/scss/components/_media.scss +22 -20
- package/src/scss/components/_meta-info.scss +35 -33
- package/src/scss/components/_modals.scss +277 -186
- package/src/scss/components/_pagination.scss +81 -87
- package/src/scss/components/_panels.scss +99 -97
- package/src/scss/components/_pricing.scss +183 -241
- package/src/scss/components/_progress.scss +122 -89
- package/src/scss/components/_prose.scss +35 -33
- package/src/scss/components/_ratings.scss +40 -38
- package/src/scss/components/_segmented.scss +82 -84
- package/src/scss/components/_skeleton.scss +66 -72
- package/src/scss/components/_spinners.scss +155 -159
- package/src/scss/components/_stepper.scss +116 -116
- package/src/scss/components/_tables.scss +155 -148
- package/src/scss/components/_tabs.scss +232 -141
- package/src/scss/components/_tags.scss +109 -107
- package/src/scss/components/_techstack-bucket.scss +123 -122
- package/src/scss/components/_testimonial.scss +72 -70
- package/src/scss/components/_theme-toggle.scss +53 -51
- package/src/scss/components/_tiles.scss +174 -174
- package/src/scss/components/_timelines.scss +282 -280
- package/src/scss/components/_toasts.scss +66 -72
- package/src/scss/form-elements/_checkbox.scss +117 -132
- package/src/scss/form-elements/_form.scss +149 -115
- package/src/scss/form-elements/_input-group.scss +99 -103
- package/src/scss/form-elements/_input.scss +74 -74
- package/src/scss/form-elements/_login.scss +48 -48
- package/src/scss/form-elements/_prefilled.scss +53 -51
- package/src/scss/form-elements/_radio.scss +95 -107
- package/src/scss/form-elements/_select.scss +42 -42
- package/src/scss/form-elements/_slider.scss +117 -132
- package/src/scss/form-elements/_textarea.scss +68 -54
- package/src/scss/form-elements/_toggle.scss +127 -140
- package/src/scss/layout/_footer.scss +172 -171
- package/src/scss/layout/_grid.scss +268 -302
- package/src/scss/layout/_header.scss +426 -427
- package/src/scss/layout/_home.scss +28 -27
- package/src/scss/layout/_main.scss +275 -238
- package/src/scss/layout/_page-header.scss +38 -36
- package/src/scss/layout/_section.scss +150 -124
- package/src/scss/main.scss +1 -1
- package/src/scss/utilities/_accessibility.scss +46 -45
- package/src/scss/utilities/_aspect.scss +22 -20
- package/src/scss/utilities/_corner.scss +23 -5
- package/src/scss/utilities/_display.scss +76 -70
- package/src/scss/utilities/_elevation.scss +13 -11
- package/src/scss/utilities/_flex.scss +83 -85
- package/src/scss/utilities/_reveal.scss +40 -63
- package/src/scss/utilities/_spacing.scss +63 -64
- package/src/scss/utilities/_text.scss +139 -141
- package/src/scss/utilities/_touch-targets.scss +130 -147
package/maverick-wave.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(){"use strict";function e(e,t){e&&(e.classList.toggle("mw-active",t),t||e.classList.remove("active"))}function t(e){return!!e&&(e.classList.contains("mw-active")||e.classList.contains("active"))}function n(){document.querySelectorAll(".color-swatch").forEach(e=>{const t=function(e){if(!e||"transparent"===e)return"#000000";const t=e=>Math.max(0,Math.min(255,Math.round(e))).toString(16).padStart(2,"0"),n=e.match(/color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\)/);if(n){const e="#"+t(255*n[1])+t(255*n[2])+t(255*n[3]),a=void 0===n[4]?1:parseFloat(n[4]);return(a<1?`${e} / ${a}`:e).toUpperCase()}const a=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(!a)return e;const c="#"+t(a[1])+t(a[2])+t(a[3]),o=void 0===a[4]?1:parseFloat(a[4]);return(o<1?`${c} / ${o}`:c).toUpperCase()}(window.getComputedStyle(e).backgroundColor),n=e.parentElement.querySelector(".mw-text-muted");n&&(n.textContent=t)})}function a(e){const t=Array.from(e.querySelectorAll(".mw-kanban-column")),n=e.querySelector(".mw-kanban-composer"),a=e.querySelector(".mw-kanban-card-template"),c=e.dataset.kanbanPrefix||"MW",o=n.querySelector(".mw-kanban-composer-title"),r=n.querySelector(".mw-kanban-composer-text"),s=n.querySelector(".mw-kanban-composer-priority"),l=n.querySelector(".mw-kanban-composer-assignee");let i=null;function d(){t.forEach(function(e,n){const a=e.querySelectorAll(".mw-kanban-card"),c=e.querySelector(".mw-kanban-count");c&&(c.textContent=a.length),e.querySelectorAll("[data-kanban-move]").forEach(function(e){const a=n+parseInt(e.dataset.kanbanMove,10);e.disabled=a<0||a>=t.length})})}function u(e,t){const n=e.querySelector(t);return n?n.textContent.replace(/\s+/g," ").trim():""}function m(e,t){f(),i=t||null,o.value=t?u(t,".mw-kanban-card-title"):"",r.value=t?u(t,".mw-kanban-card-text"):"",s.value=t?function(e){const t=e.querySelector(".mw-card-ribbon");if(!t)return"";const n=Array.from(t.classList).find(function(e){return 0===e.indexOf("mw-card-addon-")});return n?n.replace("mw-card-addon-",""):""}(t):"",l.value=t?function(e){const t=e.querySelector(".mw-avatar-initials");return t?t.textContent.trim():""}(t):"",t?(t.classList.add("mw-kanban-editing"),t.before(n)):e.querySelector(".mw-kanban-column-body").prepend(n),n.classList.add("mw-active"),o.focus()}function f(){n.classList.remove("mw-active"),i&&i.classList.remove("mw-kanban-editing"),i=null}function w(){const t=o.value.trim();if(!t)return void o.focus();const u=i||a.content.firstElementChild.cloneNode(!0);if(u.querySelector(".mw-kanban-card-title").textContent=t,u.querySelector(".mw-kanban-card-text").textContent=r.value.trim(),function(e,t){const n=e.querySelector(".mw-card-ribbon");if(n&&n.remove(),!t||!t.value)return;const a=document.createElement("div");a.className="mw-card-ribbon mw-card-addon-"+t.value,a.textContent=t.textContent,e.prepend(a)}(u,s.selectedOptions[0]),function(e,t){const n=e.querySelector(".mw-kanban-card-actions"),a=n.querySelector(".mw-avatar");if(!t)return void(a&&a.remove());const c=a||document.createElement("div");c.className="mw-avatar mw-avatar-xs mw-avatar-initials",c.textContent=t,a||n.prepend(c)}(u,l.value),!i){const t=function(){const t=Array.from(e.querySelectorAll(".mw-kanban-card-id")).map(function(e){return parseInt(e.textContent.split("-").pop(),10)||0});return c+"-"+(Math.max(0,...t)+1)}();u.classList.add("mw-kanban-card-in"),u.querySelector(".mw-kanban-card-id").textContent=t,u.querySelectorAll("[aria-label]").forEach(function(e){e.setAttribute("aria-label",e.getAttribute("aria-label").replace(/[A-Z]+-\d+/,t))}),n.before(u)}f(),d()}const h=["mw-kanban-card-moved-forward","mw-kanban-card-moved-back"];e.addEventListener("click",function(e){const n=e.target.closest("[data-kanban-move]");if(n){if(function(e,n){const a=e.closest(".mw-kanban-column"),c=t[t.indexOf(a)+n];c&&(c.querySelector(".mw-kanban-column-body").appendChild(e),e.classList.remove.apply(e.classList,h),e.offsetWidth,e.classList.add(n>0?h[0]:h[1]),d())}(n.closest(".mw-kanban-card"),parseInt(n.dataset.kanbanMove,10)),n.disabled){const e=n.parentElement.querySelector("[data-kanban-move]:not(:disabled)");e&&e.focus()}return}const a=e.target.closest(".mw-kanban-edit");if(a){const e=a.closest(".mw-kanban-card");return void m(e.closest(".mw-kanban-column"),e)}const c=e.target.closest(".mw-kanban-delete");if(c){const e=c.closest(".mw-kanban-card");return e===i&&f(),e.remove(),void d()}const o=e.target.closest(".mw-kanban-add");o?m(o.closest(".mw-kanban-column"),null):e.target.closest(".mw-kanban-composer-cancel")&&f()}),n.addEventListener("submit",function(e){e.preventDefault(),w()}),n.addEventListener("keydown",function(e){"Escape"===e.key&&f()}),d()}function c(e){const t=e.querySelector(".mw-calendar-grid"),n=e.querySelector(".mw-calendar-title");if(!t)return;const a="week"===e.dataset.calendar,c=function(e){if(!e)return{};try{return JSON.parse(e)}catch(e){return{}}}(e.dataset.calendarMarkers),o=e.dataset.calendarLocale||document.documentElement.lang||void 0,r=new Date;r.setHours(0,0,0,0);let s=e.dataset.calendarDate?new Date(e.dataset.calendarDate+"T00:00:00"):new Date(r),l=e.dataset.calendarSelected||"";function i(e){const t=new Date(e);return t.setDate(t.getDate()-(t.getDay()+6)%7),t}function d(e){return e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0")}function u(){if(!a)return s.toLocaleDateString(o,{month:"long",year:"numeric"});const e=i(s),t=new Date(e);t.setDate(t.getDate()+6);const n=e.toLocaleDateString(o,{day:"numeric",month:e.getMonth()===t.getMonth()?void 0:"short"}),c=t.toLocaleDateString(o,{day:"numeric",month:"short",year:"numeric"});return"Week "+function(e){const t=i(e);t.setDate(t.getDate()+3);const n=i(new Date(t.getFullYear(),0,4));return n.setDate(n.getDate()+3),1+Math.round((t-n)/6048e5)}(e)+" · "+n+" - "+c}function m(e){const t=e.getDay();return 0===t||6===t}function f(e,t){const n=d(e),s=document.createElement("button");s.type="button",s.className="mw-calendar-day",s.tabIndex=-1,s.dataset.calendarDay=n,s.setAttribute("aria-pressed",n===l?"true":"false"),s.setAttribute("aria-label",e.toLocaleDateString(o,{weekday:"long",day:"numeric",month:"long",year:"numeric"})),m(e)&&s.classList.add("mw-calendar-weekend"),a||e.getMonth()===t||s.classList.add("mw-calendar-adjacent"),n===d(r)&&(s.classList.add("mw-calendar-today"),s.setAttribute("aria-current","date")),n===l&&s.classList.add("mw-selected");const i=document.createElement("span");i.className="mw-calendar-date",i.textContent=e.getDate(),s.appendChild(i);const u=[].concat(c[n]||[]);if(u.length){const e=document.createElement("span");e.className="mw-calendar-dots",u.forEach(function(t){const n=document.createElement("span");n.className=t?"mw-calendar-dot mw-calendar-dot-"+t:"mw-calendar-dot",e.appendChild(n)}),s.appendChild(e)}return s}function w(){const e=s.getMonth(),c=a?7:42,r=i(a?s:new Date(s.getFullYear(),e,1));t.innerHTML="",function(){const e=i(new Date);for(let n=0;n<7;n++){const n=document.createElement("div");n.className="mw-calendar-weekday",m(e)&&n.classList.add("mw-calendar-weekend"),n.setAttribute("aria-hidden","true"),n.textContent=e.toLocaleDateString(o,{weekday:"short"}),t.appendChild(n),e.setDate(e.getDate()+1)}}();for(let n=0;n<c;n++)t.appendChild(f(r,e)),r.setDate(r.getDate()+1);n&&(n.textContent=u()),function(){const e=t.querySelector(".mw-selected")||t.querySelector(".mw-calendar-today")||t.querySelector(".mw-calendar-day:not(.mw-calendar-adjacent)")||t.querySelector(".mw-calendar-day");e&&(e.tabIndex=0)}()}e.addEventListener("click",function(n){const c=n.target.closest("[data-calendar-nav]");if(c)return o=parseInt(c.dataset.calendarNav,10),a?s.setDate(s.getDate()+7*o):s=new Date(s.getFullYear(),s.getMonth()+o,1),void w();var o;const r=n.target.closest(".mw-calendar-day");var i;r&&!r.disabled&&(i=r.dataset.calendarDay,l=i===l?"":i,t.querySelectorAll(".mw-calendar-day").forEach(function(e){const t=e.dataset.calendarDay===l;e.classList.toggle("mw-selected",t),e.setAttribute("aria-pressed",t?"true":"false")}),e.dispatchEvent(new CustomEvent("mw-calendar-select",{bubbles:!0,detail:{date:l}})))}),t.addEventListener("keydown",function(e){const n={ArrowLeft:-1,ArrowRight:1,ArrowUp:-7,ArrowDown:7}[e.key];if(!n)return;const a=e.target.closest(".mw-calendar-day");if(!a)return;e.preventDefault();const c=new Date(a.dataset.calendarDay+"T00:00:00");c.setDate(c.getDate()+n),function(e){const n=d(e);let a=t.querySelector('[data-calendar-day="'+n+'"]');a||(s=new Date(e),w(),a=t.querySelector('[data-calendar-day="'+n+'"]')),a&&(t.querySelectorAll(".mw-calendar-day").forEach(function(e){e.tabIndex=-1}),a.tabIndex=0,a.focus())}(c)}),w()}document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll(".mw-gallery").forEach(e=>{const t=e.closest(".mw-gallery-container")||e.parentElement;t&&function(e,t){const n=t.querySelector(".mw-gallery-track");if(!n||!n.children.length)return;const a=n.children,c=e.querySelector(".mw-gallery-dots"),o=e.querySelector(".mw-gallery-desc"),r=t.querySelector(".mw-gallery-navi-prev"),s=t.querySelector(".mw-gallery-navi-next");let l=0;function i(e){const t=a.length;l=(e+t)%t,n.style.transform=`translateX(-${100*l}%)`,c&&c.querySelectorAll(".mw-gallery-dot").forEach((e,t)=>{e.classList.toggle("mw-active",t===l)}),o&&(o.textContent=a[l].dataset.desc||"")}if(c)for(let e=0;e<a.length;e++){const t=document.createElement("button");t.type="button",t.className="mw-gallery-dot"+(0===e?" mw-active":""),t.setAttribute("aria-label","Go to slide "+(e+1)),t.addEventListener("click",()=>i(e)),c.appendChild(t)}r&&r.addEventListener("click",()=>i(l-1)),s&&s.addEventListener("click",()=>i(l+1));let d=0;n.addEventListener("touchstart",e=>d=e.touches[0].clientX),n.addEventListener("touchend",e=>{const t=e.changedTouches[0].clientX-d;t>50&&i(l-1),t<-50&&i(l+1)}),i(0)}(t,e)}),function(){const t=document.querySelector(".mw-theme-toggle");if(!t)return;const a=document.body,c=t.querySelector(".mw-theme-toggle-slider i"),o=getComputedStyle(document.documentElement).getPropertyValue("--mw-internal-theme-mode").trim()||"switchable";if("switchable"!==o)return console.log(`Theme mode fixed to: ${o}. Disabling toggle.`),c&&(c.className="light"===o?"fas fa-sun":"fas fa-moon"),e(t,"light"===o),t.style.opacity="0.4",t.style.pointerEvents="none",t.style.cursor="default",t.setAttribute("aria-disabled","true"),localStorage.removeItem("mw-theme"),void("dark"===o&&a.classList.remove("mw-theme-light"));let r="light"===localStorage.getItem("mw-theme");const s=n=>{a.classList.toggle("mw-theme-light",n),e(t,n),c&&(c.className=n?"fas fa-sun":"fas fa-moon")};s(r),t.addEventListener("click",()=>{r=!r,s(r),localStorage.setItem("mw-theme",r?"light":"dark"),setTimeout(n,400)})}(),n(),document.querySelectorAll(".mw-accordion-header").forEach(n=>{const a="BUTTON"===n.tagName;a&&n.setAttribute("aria-expanded",String(t(n))),n.addEventListener("click",function(){const n=!t(this);e(this,n),e(this.nextElementSibling,n),a&&this.setAttribute("aria-expanded",String(n))})}),function(){const e=document.querySelector(".mw-menu-btn"),t=document.querySelector(".mw-navbar");if(!e||!t)return;function n(){e.classList.remove("open"),t.classList.remove("open")}function a(n){n.preventDefault(),n.stopPropagation(),e.classList.toggle("open"),t.classList.toggle("open")}e.addEventListener("click",a),e.addEventListener("touchstart",a,{passive:!1}),document.addEventListener("click",function(a){t.classList.contains("open")&&(t.contains(a.target)||e.contains(a.target)||n())}),document.addEventListener("keydown",function(e){"Escape"===e.key&&n()})}(),function(){const e=document.querySelectorAll(".mw-progress-fill");if(!e.length)return;const t=new IntersectionObserver((e,t)=>{e.forEach(e=>{if(!e.isIntersecting)return;const n=e.target,a=n.dataset.value||0;n.style.width=a+"%",t.unobserve(n)})},{root:null,threshold:.2});e.forEach(e=>t.observe(e))}(),document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(e){const t=this.getAttribute("href");if("#"===t)return;if(!document.querySelector(t))return;const n=document.querySelector(".mw-menu-btn"),a=document.querySelector(".mw-navbar");n&&a&&(n.classList.remove("open"),a.classList.remove("open"))})}),function(){const t=document.querySelectorAll("section[id]"),n=document.querySelectorAll(".mw-navbar-link");if(0===t.length||0===n.length)return;function a(){const e=parseFloat(getComputedStyle(document.documentElement).scrollPaddingTop);return(Number.isNaN(e)?0:e)+2}window.addEventListener("scroll",function(e,t){let n;return function(){const a=this,c=arguments;clearTimeout(n),n=setTimeout(()=>e.apply(a,c),t)}}(function(){let c="";const o=a();t.forEach(e=>{const t=e.offsetTop-o,n=e.clientHeight;scrollY>=t&&scrollY<t+n&&(c=e.getAttribute("id"))}),n.forEach(t=>{e(t,!1);const n=t.getAttribute("href");if(n){const a=n.indexOf("#");if(-1!==a){n.substring(a+1)===c&&e(t,!0)}}})},100))}(),document.querySelectorAll(".mw-tabs-nav-item").forEach(t=>{t.addEventListener("click",function(){const t=this.closest(".mw-tabs");if(!t)return;t.querySelectorAll(".mw-tabs-nav-item").forEach(t=>{e(t,!1)}),e(this,!0);const n=this.getAttribute("data-tab");n&&(t.querySelectorAll(".mw-tabs-panel").forEach(t=>{e(t,!1)}),e(document.getElementById(n),!0))})}),document.querySelectorAll(".mw-alert-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-alert");e&&(e.classList.add("mw-alert-closing"),setTimeout(()=>{e.classList.add("mw-alert-closed")},300))})}),function(){const e=document.querySelector(".mw-localhost-indicator-activated"),t=document.querySelector(".mw-header");if(e){if("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.includes("192.168.")){const e=document.createElement("div");e.className="mw-localhost-indicator-pulse",t.prepend(e)}}}(),document.querySelectorAll(".mw-slider-container").forEach(e=>{const t=e.querySelector(".mw-slider"),n=e.querySelector(".mw-slider-value");if(!t||!n)return;const a=()=>{const e=Number(t.value),a=Number(t.max)||100,c=Math.round(e/a*100);t.style.setProperty("--value",c+"%"),n.classList.contains("mw-slider-numeric")?n.setAttribute("data-value",e):n.setAttribute("data-value",c)};t.addEventListener("input",a),a()}),document.querySelectorAll(".mw-modal-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-modal-overlay");e&&e.classList.remove("mw-modal-open")})}),function(){const e=document.getElementById("login-button");e&&e.addEventListener("click",function(){const e=this.querySelector("i");e.classList.contains("fa-lock")?(e.classList.remove("fa-lock"),e.classList.add("fa-lock-open")):(e.classList.remove("fa-lock-open"),e.classList.add("fa-lock"))})}(),document.querySelectorAll(".mw-image-slider").forEach(t=>{const n=t.querySelectorAll(".mw-image-slider-overlay-image"),a=t.querySelectorAll("button[data-index]");if(!n.length||!a.length)return;let c=0;function o(){n.forEach(t=>{e(t,parseInt(t.dataset.index)===c)}),a.forEach(t=>{e(t,parseInt(t.dataset.index)===c)})}function r(e){c=e,o()}a.forEach(e=>{e.addEventListener("click",()=>{r(parseInt(e.dataset.index))})}),o()}),document.querySelectorAll(".mw-item-list-checkbox, .mw-item-list-checkbox-scroll").forEach(e=>{e.querySelectorAll("li").forEach(e=>{const t=e.querySelector('input[type="checkbox"]'),n=e.querySelector(".mw-checkbox");t&&n&&(t.checked&&e.classList.add("mw-selected"),e.addEventListener("click",function(e){e.target!==t&&e.target.closest(".mw-checkbox")!==n&&toggleCheckbox(this)}),t.addEventListener("change",function(){const e=this.closest("li");this.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:this.checked,item:e}}))}),n.addEventListener("click",function(e){setTimeout(()=>{const e=this.closest("li");this.querySelector('input[type="checkbox"]').checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected")},0)}))})}),document.addEventListener("checkboxToggle",function(e){console.log("Checkbox toggled:",e.detail.checked,e.detail.item)}),document.querySelectorAll(".mw-kanban").forEach(a),document.querySelectorAll("[data-calendar]").forEach(c),function(){function e(e){document.querySelectorAll(".mw-dropdown[open]").forEach(t=>{t!==e&&t.removeAttribute("open")})}document.addEventListener("click",function(t){const n=t.target.closest(".mw-dropdown");e(n),n&&t.target.closest(".mw-dropdown-item")&&n.removeAttribute("open")}),document.addEventListener("keydown",function(e){if("Escape"!==e.key)return;const t=document.querySelector(".mw-dropdown[open]");if(!t)return;t.removeAttribute("open");const n=t.querySelector("summary");n&&n.focus()})}(),document.querySelectorAll(".mw-lang-switch").forEach(t=>{const n=t.querySelectorAll("[data-mw-lang]"),a=t.querySelector("summary"),c=t.querySelector("summary .mw-flag"),o=t.querySelector("summary .mw-lang-switch-code");n.forEach(r=>{r.addEventListener("click",function(){const s=r.dataset.mwLang,l=r.querySelector(".mw-lang-switch-name"),i=l?l.textContent.trim():s;n.forEach(t=>{e(t,t===r),t===r?t.setAttribute("aria-current","true"):t.removeAttribute("aria-current")}),o&&(o.textContent=s);const d=r.querySelector(".mw-flag");c&&d&&(c.className=d.className),a&&a.setAttribute("aria-label","Language: "+i),t.dispatchEvent(new CustomEvent("mw-language-change",{bubbles:!0,detail:{lang:s,name:i}}))})})})}),window.toggleCheckbox=function(e){const t=e.querySelector('input[type="checkbox"]');if(!t)return;const n=t.checked;t.checked=!n,t.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:t.checked,item:e}}))}}();
|
|
1
|
+
!function(){"use strict";function e(e,t){e&&(e.classList.toggle("mw-active",t),t||e.classList.remove("active"))}function t(e){return!!e&&(e.classList.contains("mw-active")||e.classList.contains("active"))}function n(){const e=Array.from(document.querySelectorAll(".color-swatch")),t=e.map(e=>function(e){if(!e||"transparent"===e)return"#000000";const t=e=>Math.max(0,Math.min(255,Math.round(e))).toString(16).padStart(2,"0"),n=e.match(/color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\)/);if(n){const e="#"+t(255*n[1])+t(255*n[2])+t(255*n[3]),a=void 0===n[4]?1:parseFloat(n[4]);return(a<1?`${e} / ${a}`:e).toUpperCase()}const a=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(!a)return e;const o="#"+t(a[1])+t(a[2])+t(a[3]),r=void 0===a[4]?1:parseFloat(a[4]);return(r<1?`${o} / ${r}`:o).toUpperCase()}(window.getComputedStyle(e).backgroundColor));e.forEach((e,n)=>{const a=e.parentElement.querySelector(".mw-text-muted");a&&(a.textContent=t[n])})}function a(e){const t=e.querySelector(".mw-tabs-nav-item.mw-active, .mw-tabs-nav-item.active");t?(e.style.setProperty("--mw-tabs-marker-x",t.offsetLeft+"px"),e.style.setProperty("--mw-tabs-marker-w",t.offsetWidth),e.style.setProperty("--mw-tabs-marker-y",t.offsetTop+"px"),e.style.setProperty("--mw-tabs-marker-h",t.offsetHeight),e.setAttribute("data-mw-tabs-marker","")):e.removeAttribute("data-mw-tabs-marker")}function o(e){const t=e.getAttribute("data-tab");return t?document.getElementById(t):null}function r(e){const n=t(e);e.setAttribute("aria-selected",String(n)),e.tabIndex=n?0:-1}function c(t,n){t.forEach(t=>{const a=t===n;e(t,a),e(o(t),a),r(t)});const c=n.closest(".mw-tabs-nav");c&&a(c)}function s(e){e&&("DIALOG"===e.tagName?e.showModal():e.classList.add("mw-modal-open"))}function l(e){const t=Array.from(e.querySelectorAll(".mw-kanban-column")),n=e.querySelector(".mw-kanban-composer"),a=e.querySelector(".mw-kanban-card-template"),o=e.dataset.kanbanPrefix||"MW",r=n.querySelector(".mw-kanban-composer-title"),c=n.querySelector(".mw-kanban-composer-text"),s=n.querySelector(".mw-kanban-composer-priority"),l=n.querySelector(".mw-kanban-composer-assignee");let i=null;function d(){t.forEach(function(e,n){const a=e.querySelectorAll(".mw-kanban-card"),o=e.querySelector(".mw-kanban-count");o&&(o.textContent=a.length),e.querySelectorAll("[data-kanban-move]").forEach(function(e){const a=n+parseInt(e.dataset.kanbanMove,10);e.disabled=a<0||a>=t.length})})}function u(e,t){const n=e.querySelector(t);return n?n.textContent.replace(/\s+/g," ").trim():""}function m(e,t){w(),i=t||null,r.value=t?u(t,".mw-kanban-card-title"):"",c.value=t?u(t,".mw-kanban-card-text"):"",s.value=t?function(e){const t=e.querySelector(".mw-card-ribbon");if(!t)return"";const n=Array.from(t.classList).find(function(e){return 0===e.indexOf("mw-card-addon-")});return n?n.replace("mw-card-addon-",""):""}(t):"",l.value=t?function(e){const t=e.querySelector(".mw-avatar-initials");return t?t.textContent.trim():""}(t):"",t?(t.classList.add("mw-kanban-editing"),t.before(n)):e.querySelector(".mw-kanban-column-body").prepend(n),n.classList.add("mw-active"),r.focus()}function w(){n.classList.remove("mw-active"),i&&i.classList.remove("mw-kanban-editing"),i=null}function f(){const t=r.value.trim();if(!t)return void r.focus();const u=i||a.content.firstElementChild.cloneNode(!0);if(u.querySelector(".mw-kanban-card-title").textContent=t,u.querySelector(".mw-kanban-card-text").textContent=c.value.trim(),function(e,t){const n=e.querySelector(".mw-card-ribbon");if(n&&n.remove(),!t||!t.value)return;const a=document.createElement("div");a.className="mw-card-ribbon mw-card-addon-"+t.value,a.textContent=t.textContent,e.prepend(a)}(u,s.selectedOptions[0]),function(e,t){const n=e.querySelector(".mw-kanban-card-actions"),a=n.querySelector(".mw-avatar");if(!t)return void(a&&a.remove());const o=a||document.createElement("div");o.className="mw-avatar mw-avatar-xs mw-avatar-initials",o.textContent=t,a||n.prepend(o)}(u,l.value),!i){const t=function(){const t=Array.from(e.querySelectorAll(".mw-kanban-card-id")).map(function(e){return parseInt(e.textContent.split("-").pop(),10)||0});return o+"-"+(Math.max(0,...t)+1)}();u.classList.add("mw-kanban-card-in"),u.querySelector(".mw-kanban-card-id").textContent=t,u.querySelectorAll("[aria-label]").forEach(function(e){e.setAttribute("aria-label",e.getAttribute("aria-label").replace(/[A-Z]+-\d+/,t))}),n.before(u)}w(),d()}const g=["mw-kanban-card-moved-forward","mw-kanban-card-moved-back"];e.addEventListener("click",function(e){const n=e.target.closest("[data-kanban-move]");if(n){if(function(e,n){const a=e.closest(".mw-kanban-column"),o=t[t.indexOf(a)+n];o&&(o.querySelector(".mw-kanban-column-body").appendChild(e),e.classList.remove.apply(e.classList,g),e.offsetWidth,e.classList.add(n>0?g[0]:g[1]),d())}(n.closest(".mw-kanban-card"),parseInt(n.dataset.kanbanMove,10)),n.disabled){const e=n.parentElement.querySelector("[data-kanban-move]:not(:disabled)");e&&e.focus()}return}const a=e.target.closest(".mw-kanban-edit");if(a){const e=a.closest(".mw-kanban-card");return void m(e.closest(".mw-kanban-column"),e)}const o=e.target.closest(".mw-kanban-delete");if(o){const e=o.closest(".mw-kanban-card");return e===i&&w(),e.remove(),void d()}const r=e.target.closest(".mw-kanban-add");r?m(r.closest(".mw-kanban-column"),null):e.target.closest(".mw-kanban-composer-cancel")&&w()}),n.addEventListener("submit",function(e){e.preventDefault(),f()}),n.addEventListener("keydown",function(e){"Escape"===e.key&&w()}),d()}function i(e){const t=e.querySelector(".mw-calendar-grid"),n=e.querySelector(".mw-calendar-title");if(!t)return;const a="week"===e.dataset.calendar,o=function(e){if(!e)return{};try{return JSON.parse(e)}catch(e){return{}}}(e.dataset.calendarMarkers),r=e.dataset.calendarLocale||document.documentElement.lang||void 0,c=new Date;c.setHours(0,0,0,0);let s=e.dataset.calendarDate?new Date(e.dataset.calendarDate+"T00:00:00"):new Date(c),l=e.dataset.calendarSelected||"";function i(e){const t=new Date(e);return t.setDate(t.getDate()-(t.getDay()+6)%7),t}function d(e){return e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0")}function u(){if(!a)return s.toLocaleDateString(r,{month:"long",year:"numeric"});const e=i(s),t=new Date(e);t.setDate(t.getDate()+6);const n=e.toLocaleDateString(r,{day:"numeric",month:e.getMonth()===t.getMonth()?void 0:"short"}),o=t.toLocaleDateString(r,{day:"numeric",month:"short",year:"numeric"});return"Week "+function(e){const t=i(e);t.setDate(t.getDate()+3);const n=i(new Date(t.getFullYear(),0,4));return n.setDate(n.getDate()+3),1+Math.round((t-n)/6048e5)}(e)+" · "+n+" - "+o}function m(e){const t=e.getDay();return 0===t||6===t}function w(e,t){const n=d(e),s=document.createElement("button");s.type="button",s.className="mw-calendar-day",s.tabIndex=-1,s.dataset.calendarDay=n,s.setAttribute("aria-pressed",n===l?"true":"false"),s.setAttribute("aria-label",e.toLocaleDateString(r,{weekday:"long",day:"numeric",month:"long",year:"numeric"})),m(e)&&s.classList.add("mw-calendar-weekend"),a||e.getMonth()===t||s.classList.add("mw-calendar-adjacent"),n===d(c)&&(s.classList.add("mw-calendar-today"),s.setAttribute("aria-current","date")),n===l&&s.classList.add("mw-selected");const i=document.createElement("span");i.className="mw-calendar-date",i.textContent=e.getDate(),s.appendChild(i);const u=[].concat(o[n]||[]);if(u.length){const e=document.createElement("span");e.className="mw-calendar-dots",u.forEach(function(t){const n=document.createElement("span");n.className=t?"mw-calendar-dot mw-calendar-dot-"+t:"mw-calendar-dot",e.appendChild(n)}),s.appendChild(e)}return s}function f(){const e=s.getMonth(),o=a?7:42,c=i(a?s:new Date(s.getFullYear(),e,1));t.innerHTML="",function(){const e=i(new Date);for(let n=0;n<7;n++){const n=document.createElement("div");n.className="mw-calendar-weekday",m(e)&&n.classList.add("mw-calendar-weekend"),n.setAttribute("aria-hidden","true"),n.textContent=e.toLocaleDateString(r,{weekday:"short"}),t.appendChild(n),e.setDate(e.getDate()+1)}}();for(let n=0;n<o;n++)t.appendChild(w(c,e)),c.setDate(c.getDate()+1);n&&(n.textContent=u()),function(){const e=t.querySelector(".mw-selected")||t.querySelector(".mw-calendar-today")||t.querySelector(".mw-calendar-day:not(.mw-calendar-adjacent)")||t.querySelector(".mw-calendar-day");e&&(e.tabIndex=0)}()}e.addEventListener("click",function(n){const o=n.target.closest("[data-calendar-nav]");if(o)return r=parseInt(o.dataset.calendarNav,10),a?s.setDate(s.getDate()+7*r):s=new Date(s.getFullYear(),s.getMonth()+r,1),void f();var r;const c=n.target.closest(".mw-calendar-day");var i;c&&!c.disabled&&(i=c.dataset.calendarDay,l=i===l?"":i,t.querySelectorAll(".mw-calendar-day").forEach(function(e){const t=e.dataset.calendarDay===l;e.classList.toggle("mw-selected",t),e.setAttribute("aria-pressed",t?"true":"false")}),e.dispatchEvent(new CustomEvent("mw-calendar-select",{bubbles:!0,detail:{date:l}})))}),t.addEventListener("keydown",function(e){const n={ArrowLeft:-1,ArrowRight:1,ArrowUp:-7,ArrowDown:7}[e.key];if(!n)return;const a=e.target.closest(".mw-calendar-day");if(!a)return;e.preventDefault();const o=new Date(a.dataset.calendarDay+"T00:00:00");o.setDate(o.getDate()+n),function(e){const n=d(e);let a=t.querySelector('[data-calendar-day="'+n+'"]');a||(s=new Date(e),f(),a=t.querySelector('[data-calendar-day="'+n+'"]')),a&&(t.querySelectorAll(".mw-calendar-day").forEach(function(e){e.tabIndex=-1}),a.tabIndex=0,a.focus())}(o)}),f()}document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll(".mw-gallery").forEach(e=>{const t=e.closest(".mw-gallery-container")||e.parentElement;t&&function(e,t){const n=t.querySelector(".mw-gallery-track");if(!n||!n.children.length)return;const a=n.children,o=e.querySelector(".mw-gallery-dots"),r=e.querySelector(".mw-gallery-desc"),c=t.querySelector(".mw-gallery-navi-prev"),s=t.querySelector(".mw-gallery-navi-next");let l=0;function i(e){const t=a.length;l=(e+t)%t,n.style.transform=`translateX(-${100*l}%)`,o&&o.querySelectorAll(".mw-gallery-dot").forEach((e,t)=>{e.classList.toggle("mw-active",t===l)}),r&&(r.textContent=a[l].dataset.desc||"")}if(o)for(let e=0;e<a.length;e++){const t=document.createElement("button");t.type="button",t.className="mw-gallery-dot"+(0===e?" mw-active":""),t.setAttribute("aria-label","Go to slide "+(e+1)),t.addEventListener("click",()=>i(e)),o.appendChild(t)}c&&c.addEventListener("click",()=>i(l-1)),s&&s.addEventListener("click",()=>i(l+1));let d=0;n.addEventListener("touchstart",e=>d=e.touches[0].clientX),n.addEventListener("touchend",e=>{const t=e.changedTouches[0].clientX-d;t>50&&i(l-1),t<-50&&i(l+1)}),i(0)}(t,e)}),function(){const t=document.querySelector(".mw-theme-toggle");if(!t)return;const a=document.body,o=document.documentElement,r=t.querySelector(".mw-theme-toggle-slider i"),c=getComputedStyle(document.documentElement).getPropertyValue("--mw-internal-theme-mode").trim()||"switchable";if("switchable"!==c)return console.log(`Theme mode fixed to: ${c}. Disabling toggle.`),r&&(r.className="light"===c?"fas fa-sun":"fas fa-moon"),e(t,"light"===c),t.style.opacity="0.4",t.style.pointerEvents="none",t.style.cursor="default",t.setAttribute("aria-disabled","true"),localStorage.removeItem("mw-theme"),void("dark"===c&&a.classList.remove("mw-theme-light"));let s="light"===localStorage.getItem("mw-theme");const l=n=>{o.classList.add("mw-theme-switching"),a.classList.toggle("mw-theme-light",n),o.offsetHeight,o.classList.remove("mw-theme-switching"),e(t,n),r&&(r.className=n?"fas fa-sun":"fas fa-moon")};l(s),t.addEventListener("click",()=>{s=!s,l(s),localStorage.setItem("mw-theme",s?"light":"dark"),n()})}(),n(),document.querySelectorAll(".mw-accordion-header").forEach(n=>{const a="BUTTON"===n.tagName;a&&n.setAttribute("aria-expanded",String(t(n))),n.addEventListener("click",function(){const n=!t(this);e(this,n),e(this.nextElementSibling,n),a&&this.setAttribute("aria-expanded",String(n))})}),function(){const e=document.querySelector(".mw-menu-btn"),t=document.querySelector(".mw-navbar");if(!e||!t)return;const n="BUTTON"===e.tagName;function a(a){e.classList.toggle("open",a),t.classList.toggle("open",a),n&&e.setAttribute("aria-expanded",String(a))}function o(e){e.preventDefault(),e.stopPropagation(),a(!t.classList.contains("open"))}e.addEventListener("click",o),e.addEventListener("touchstart",o,{passive:!1}),document.addEventListener("click",function(n){t.classList.contains("open")&&(t.contains(n.target)||e.contains(n.target)||a(!1))}),document.addEventListener("keydown",function(n){"Escape"===n.key&&t.classList.contains("open")&&(a(!1),e.focus())})}(),function(){const e=document.querySelectorAll(".mw-progress-fill");if(!e.length)return;const t=CSS.supports("animation-timeline","view()"),n=e=>e.dataset.value?e.dataset.value+"%":e.style.width,a=[];if(e.forEach(e=>{const o=n(e);o&&(e.style.setProperty("--mw-progress-value",o),t?e.classList.add("mw-progress-driven"):a.push(e))}),t)return;const o=new IntersectionObserver((e,t)=>{e.forEach(e=>{e.isIntersecting&&(e.target.style.width=n(e.target),t.unobserve(e.target))})},{root:null,threshold:.2});a.forEach(e=>o.observe(e))}(),document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(e){const t=this.getAttribute("href");if("#"===t)return;if(!document.querySelector(t))return;const n=document.querySelector(".mw-menu-btn"),a=document.querySelector(".mw-navbar");n&&a&&(n.classList.remove("open"),a.classList.remove("open"))})}),function(){const t=document.querySelectorAll("section[id]"),n=document.querySelectorAll(".mw-navbar-link");if(0===t.length||0===n.length)return;function a(){const e=parseFloat(getComputedStyle(document.documentElement).scrollPaddingTop);return(Number.isNaN(e)?0:e)+2}window.addEventListener("scroll",function(e,t){let n;return function(){const a=this,o=arguments;clearTimeout(n),n=setTimeout(()=>e.apply(a,o),t)}}(function(){let o="";const r=a();t.forEach(e=>{const t=e.offsetTop-r,n=e.clientHeight;scrollY>=t&&scrollY<t+n&&(o=e.getAttribute("id"))}),n.forEach(t=>{e(t,!1);const n=t.getAttribute("href");if(n){const a=n.indexOf("#");if(-1!==a){n.substring(a+1)===o&&e(t,!0)}}})},100))}(),document.querySelectorAll(".mw-tabs-nav").forEach(e=>{const t=Array.from(e.querySelectorAll(".mw-tabs-nav-item"));if(!t.length)return;const n=!!e.closest(".mw-tabs-vertical");e.setAttribute("role","tablist"),n&&e.setAttribute("aria-orientation","vertical"),t.forEach((e,a)=>{const s=o(e);e.setAttribute("role","tab"),e.id||(e.id=(s?s.id:"mw-tab-"+a)+"-tab"),s&&(e.setAttribute("aria-controls",s.id),s.setAttribute("role","tabpanel"),s.setAttribute("aria-labelledby",e.id)),r(e),e.addEventListener("click",()=>c(t,e)),e.addEventListener("keydown",e=>{const o=function(e,t,n,a){const o=t?"ArrowUp":"ArrowLeft",r=t?"ArrowDown":"ArrowRight";return e.key===o?(a-1+n)%n:e.key===r?(a+1)%n:"Home"===e.key?0:"End"===e.key?n-1:null}(e,n,t.length,a);null!==o&&(e.preventDefault(),c(t,t[o]),t[o].focus())})}),a(e);const s=new ResizeObserver(()=>a(e));s.observe(e),t.forEach(e=>s.observe(e))}),document.querySelectorAll(".mw-alert-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-alert");e&&(e.classList.add("mw-alert-closing"),setTimeout(()=>{e.classList.add("mw-alert-closed")},300))})}),function(){const e=document.querySelector(".mw-localhost-indicator-activated"),t=document.querySelector(".mw-header");if(e){if("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.includes("192.168.")){const e=document.createElement("div");e.className="mw-localhost-indicator-pulse",t.prepend(e)}}}(),document.querySelectorAll(".mw-slider-container").forEach(e=>{const t=e.querySelector(".mw-slider"),n=e.querySelector(".mw-slider-value");if(!t||!n)return;const a=()=>{const e=Number(t.value),a=Number(t.max)||100,o=Math.round(e/a*100);t.style.setProperty("--value",o+"%"),n.classList.contains("mw-slider-numeric")?n.setAttribute("data-value",e):n.setAttribute("data-value",o)};t.addEventListener("input",a),a()}),document.addEventListener("click",e=>{const t=e.target.closest(".mw-modal-close");if(t){const e=t.closest("dialog.mw-modal");if(e)return void e.close();const n=t.closest(".mw-modal-overlay");return void(n&&n.classList.remove("mw-modal-open"))}const n=e.target.closest("[data-mw-modal]");var a;n?s(document.getElementById(n.dataset.mwModal)):e.target.matches("dialog.mw-modal[open]")&&(!("closedBy"in(a=e.target))||null===a.getAttribute("closedby"))&&e.target.close()}),function(){const e=document.getElementById("login-button");e&&e.addEventListener("click",function(){const e=this.querySelector("i");e.classList.contains("fa-lock")?(e.classList.remove("fa-lock"),e.classList.add("fa-lock-open")):(e.classList.remove("fa-lock-open"),e.classList.add("fa-lock"))})}(),document.querySelectorAll(".mw-image-slider").forEach(t=>{const n=t.querySelectorAll(".mw-image-slider-overlay-image"),a=t.querySelectorAll("button[data-index]");if(!n.length||!a.length)return;let o=0;function r(){n.forEach(t=>{e(t,parseInt(t.dataset.index)===o)}),a.forEach(t=>{e(t,parseInt(t.dataset.index)===o)})}function c(e){o=e,r()}a.forEach(e=>{e.addEventListener("click",()=>{c(parseInt(e.dataset.index))})}),r()}),document.querySelectorAll(".mw-item-list-checkbox, .mw-item-list-checkbox-scroll").forEach(e=>{e.querySelectorAll("li").forEach(e=>{const t=e.querySelector('input[type="checkbox"]'),n=e.querySelector(".mw-checkbox");t&&n&&(t.checked&&e.classList.add("mw-selected"),e.addEventListener("click",function(e){e.target!==t&&e.target.closest(".mw-checkbox")!==n&&toggleCheckbox(this)}),t.addEventListener("change",function(){const e=this.closest("li");this.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:this.checked,item:e}}))}),n.addEventListener("click",function(e){setTimeout(()=>{const e=this.closest("li");this.querySelector('input[type="checkbox"]').checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected")},0)}))})}),document.addEventListener("checkboxToggle",function(e){console.log("Checkbox toggled:",e.detail.checked,e.detail.item)}),document.querySelectorAll(".mw-kanban").forEach(l),document.querySelectorAll("[data-calendar]").forEach(i),function(){function e(e){document.querySelectorAll(".mw-dropdown[open]").forEach(t=>{t!==e&&t.removeAttribute("open")})}document.addEventListener("click",function(t){const n=t.target.closest(".mw-dropdown");e(n),n&&t.target.closest(".mw-dropdown-item")&&n.removeAttribute("open")}),document.addEventListener("keydown",function(e){if("Escape"!==e.key)return;const t=document.querySelector(".mw-dropdown[open]");if(!t)return;t.removeAttribute("open");const n=t.querySelector("summary");n&&n.focus()})}(),document.querySelectorAll(".mw-lang-switch").forEach(t=>{const n=t.querySelectorAll("[data-mw-lang]"),a=t.querySelector("summary"),o=t.querySelector("summary .mw-flag"),r=t.querySelector("summary .mw-lang-switch-code");n.forEach(c=>{c.addEventListener("click",function(){const s=c.dataset.mwLang,l=c.querySelector(".mw-lang-switch-name"),i=l?l.textContent.trim():s;n.forEach(t=>{e(t,t===c),t===c?t.setAttribute("aria-current","true"):t.removeAttribute("aria-current")}),r&&(r.textContent=s);const d=c.querySelector(".mw-flag");o&&d&&(o.className=d.className),a&&a.setAttribute("aria-label","Language: "+i),t.dispatchEvent(new CustomEvent("mw-language-change",{bubbles:!0,detail:{lang:s,name:i}}))})})})}),window.toggleCheckbox=function(e){const t=e.querySelector('input[type="checkbox"]');if(!t)return;const n=t.checked;t.checked=!n,t.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:t.checked,item:e}}))},window.mwOpenModal=e=>s(document.getElementById(e)),window.mwCloseModal=e=>{var t;(t=document.getElementById(e))&&("DIALOG"===t.tagName?t.close():t.classList.remove("mw-modal-open"))}}();
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maverick-wave",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"config": {
|
|
5
|
-
"version_short": "
|
|
5
|
+
"version_short": "5.1"
|
|
6
6
|
},
|
|
7
7
|
"description": "A lightweight, modern CSS framework for building responsive websites with elegance and speed.",
|
|
8
8
|
"main": "src/js/main.js",
|
package/scripts/verify.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* 2. every --mw-* definition is used somewhere
|
|
8
8
|
* 3. every mw-* class in the markup exists in the built CSS
|
|
9
9
|
* 4. the committed root release files exist and are not empty
|
|
10
|
+
* 5. the CDN version pinned in the docs matches package.json
|
|
10
11
|
*
|
|
11
12
|
* Sources are scanned rather than hard-coded so a new partial is covered
|
|
12
13
|
* automatically. Exits 1 on any error; warnings never fail the build.
|
|
@@ -72,9 +73,12 @@ const docs = DOCS.map(read).filter(Boolean).map(stripFrontmatter).join('\n');
|
|
|
72
73
|
// --- 1 + 2: custom properties ---------------------------------------------
|
|
73
74
|
|
|
74
75
|
const tokensDefined = new Set(all(css, /(--mw-[a-z0-9-]+)\s*:/g));
|
|
76
|
+
// `\s*` after the paren: a long declaration wrapped by Prettier keeps its
|
|
77
|
+
// newline inside var() all the way through the minifier, and a token used only
|
|
78
|
+
// there would otherwise read as unused.
|
|
75
79
|
const tokensUsed = new Set([
|
|
76
|
-
...all(css, /var\((--mw-[a-z0-9-]+)/g),
|
|
77
|
-
...all(html, /var\((--mw-[a-z0-9-]+)/g),
|
|
80
|
+
...all(css, /var\(\s*(--mw-[a-z0-9-]+)/g),
|
|
81
|
+
...all(html, /var\(\s*(--mw-[a-z0-9-]+)/g),
|
|
78
82
|
...all(js, /(--mw-[a-z0-9-]+)/g),
|
|
79
83
|
]);
|
|
80
84
|
|
|
@@ -136,6 +140,27 @@ for (const f of ['maverick-wave.min.css', 'maverick-wave.min.js']) {
|
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
|
|
143
|
+
// --- 5: pinned CDN version -------------------------------------------------
|
|
144
|
+
// Every jsDelivr snippet in the docs pins a version, which is the right advice
|
|
145
|
+
// and the reason it goes stale: 5.0.0 shipped with six snippets still on 4.28.0.
|
|
146
|
+
|
|
147
|
+
const { version } = require(path.join(ROOT, 'package.json'));
|
|
148
|
+
|
|
149
|
+
for (const p of [path.join(ROOT, 'README.md'), ...DOCS]) {
|
|
150
|
+
const md = read(p);
|
|
151
|
+
if (!md) continue;
|
|
152
|
+
const stale = new Set(
|
|
153
|
+
all(md, /maverick-wave@([0-9]+\.[0-9]+\.[0-9]+)/g).filter(
|
|
154
|
+
(v) => v !== version
|
|
155
|
+
)
|
|
156
|
+
);
|
|
157
|
+
for (const v of stale) {
|
|
158
|
+
errors.push(
|
|
159
|
+
`stale CDN pin in ${path.relative(ROOT, p)}: maverick-wave@${v} - package.json is ${version}`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
139
164
|
// Informational: framework classes the showcase never demonstrates
|
|
140
165
|
const undocumented = [...classesInCss].filter(
|
|
141
166
|
(c) => !classesInMarkup.has(c) && !classesInJs.has(c)
|
package/src/js/main.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// to clear both - otherwise a stale `active` from the HTML would keep a
|
|
7
|
-
// second tab lit.
|
|
4
|
+
// Both spellings are styled, so turning a state off has to clear both or a
|
|
5
|
+
// stale `active` in the HTML keeps a second tab lit
|
|
8
6
|
function setActive(el, on) {
|
|
9
7
|
if (!el) return;
|
|
10
8
|
el.classList.toggle('mw-active', on);
|
|
@@ -43,15 +41,8 @@
|
|
|
43
41
|
initLangSwitches();
|
|
44
42
|
});
|
|
45
43
|
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
// The menu is a <details>, so opening, closing, the keyboard and the state a
|
|
49
|
-
// screen reader reads out are all the browser's job already. Two things it
|
|
50
|
-
// does not do, because no markup can express them: close when the click lands
|
|
51
|
-
// somewhere else, and close on Escape.
|
|
52
|
-
//
|
|
53
|
-
// Delegated to the document rather than bound per dropdown, so a menu added
|
|
54
|
-
// to the page later works without being initialised.
|
|
44
|
+
// The menu is a <details>, so only two things are left: close on an outside
|
|
45
|
+
// click and close on Escape. Delegated, so a menu added later works too.
|
|
55
46
|
function initDropdowns() {
|
|
56
47
|
function closeAll(except) {
|
|
57
48
|
document.querySelectorAll('.mw-dropdown[open]').forEach((dropdown) => {
|
|
@@ -89,14 +80,8 @@
|
|
|
89
80
|
});
|
|
90
81
|
}
|
|
91
82
|
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
// The menu itself is a dropdown and needs nothing here. This only keeps the
|
|
95
|
-
// trigger in step with the choice and then announces it - which language is
|
|
96
|
-
// actually loaded is the application's business, not the framework's, and
|
|
97
|
-
// that decision usually lives in the URL or on the server rather than in
|
|
98
|
-
// localStorage. Listen for it:
|
|
99
|
-
//
|
|
83
|
+
// Keeps the trigger in step with the choice and announces it - which language
|
|
84
|
+
// actually loads is the application's business, usually the URL or the server:
|
|
100
85
|
// document.addEventListener('mw-language-change', (e) => e.detail.lang)
|
|
101
86
|
function initLangSwitches() {
|
|
102
87
|
document.querySelectorAll('.mw-lang-switch').forEach((languageSwitch) => {
|
|
@@ -320,6 +305,7 @@
|
|
|
320
305
|
if (!themeToggle) return;
|
|
321
306
|
|
|
322
307
|
const body = document.body;
|
|
308
|
+
const root = document.documentElement;
|
|
323
309
|
const icon = themeToggle.querySelector('.mw-theme-toggle-slider i');
|
|
324
310
|
|
|
325
311
|
const computedStyle = getComputedStyle(document.documentElement);
|
|
@@ -358,8 +344,12 @@
|
|
|
358
344
|
|
|
359
345
|
// Function to apply theme styles and icon
|
|
360
346
|
const applyTheme = (lightMode) => {
|
|
361
|
-
//
|
|
347
|
+
// The forced reflow is the point: the new colours land while transitions are off
|
|
348
|
+
root.classList.add('mw-theme-switching');
|
|
362
349
|
body.classList.toggle('mw-theme-light', lightMode);
|
|
350
|
+
void root.offsetHeight;
|
|
351
|
+
root.classList.remove('mw-theme-switching');
|
|
352
|
+
|
|
363
353
|
setActive(themeToggle, lightMode);
|
|
364
354
|
if (icon) {
|
|
365
355
|
icon.className = lightMode ? 'fas fa-sun' : 'fas fa-moon';
|
|
@@ -375,8 +365,8 @@
|
|
|
375
365
|
applyTheme(isLight);
|
|
376
366
|
localStorage.setItem('mw-theme', isLight ? 'light' : 'dark'); // Save
|
|
377
367
|
|
|
378
|
-
//
|
|
379
|
-
|
|
368
|
+
// No transition left to wait out, so the swatches can read the new values now
|
|
369
|
+
updateColorSwatchHexValues();
|
|
380
370
|
});
|
|
381
371
|
}
|
|
382
372
|
|
|
@@ -386,14 +376,20 @@
|
|
|
386
376
|
}
|
|
387
377
|
|
|
388
378
|
function updateColorSwatchHexValues() {
|
|
389
|
-
const colorSwatches =
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
379
|
+
const colorSwatches = Array.from(
|
|
380
|
+
document.querySelectorAll('.color-swatch')
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
// All reads before the first write - a write between two reads forces a recalc
|
|
384
|
+
const hexValues = colorSwatches.map((swatch) =>
|
|
385
|
+
rgbToHex(window.getComputedStyle(swatch).backgroundColor)
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
colorSwatches.forEach((swatch, index) => {
|
|
393
389
|
const hexTextElement =
|
|
394
390
|
swatch.parentElement.querySelector('.mw-text-muted');
|
|
395
391
|
if (hexTextElement) {
|
|
396
|
-
hexTextElement.textContent =
|
|
392
|
+
hexTextElement.textContent = hexValues[index];
|
|
397
393
|
}
|
|
398
394
|
});
|
|
399
395
|
}
|
|
@@ -457,16 +453,19 @@
|
|
|
457
453
|
|
|
458
454
|
if (!menuBtn || !navbar) return;
|
|
459
455
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
456
|
+
// aria-expanded only on a real control - on a <div> it claims a state for nothing
|
|
457
|
+
const announces = menuBtn.tagName === 'BUTTON';
|
|
458
|
+
|
|
459
|
+
function setOpen(open) {
|
|
460
|
+
menuBtn.classList.toggle('open', open);
|
|
461
|
+
navbar.classList.toggle('open', open);
|
|
462
|
+
if (announces) menuBtn.setAttribute('aria-expanded', String(open));
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
function toggleMenu(e) {
|
|
466
466
|
e.preventDefault();
|
|
467
467
|
e.stopPropagation();
|
|
468
|
-
|
|
469
|
-
navbar.classList.toggle('open');
|
|
468
|
+
setOpen(!navbar.classList.contains('open'));
|
|
470
469
|
}
|
|
471
470
|
|
|
472
471
|
// Add multiple event listeners for better iOS compatibility
|
|
@@ -477,38 +476,58 @@
|
|
|
477
476
|
document.addEventListener('click', function (e) {
|
|
478
477
|
if (!navbar.classList.contains('open')) return;
|
|
479
478
|
if (navbar.contains(e.target) || menuBtn.contains(e.target)) return;
|
|
480
|
-
|
|
479
|
+
setOpen(false);
|
|
481
480
|
});
|
|
482
481
|
|
|
482
|
+
// Or Escape strands the keyboard user in a drawer that is no longer there
|
|
483
483
|
document.addEventListener('keydown', function (e) {
|
|
484
|
-
if (e.key
|
|
484
|
+
if (e.key !== 'Escape') return;
|
|
485
|
+
if (!navbar.classList.contains('open')) return;
|
|
486
|
+
setOpen(false);
|
|
487
|
+
menuBtn.focus();
|
|
485
488
|
});
|
|
486
489
|
}
|
|
487
490
|
|
|
488
491
|
// ===== Progress Bars =====
|
|
492
|
+
|
|
493
|
+
// The fill is driven from CSS where the browser can do it (_progress.scss), so
|
|
494
|
+
// this only hands the target width over and switches the animation on
|
|
489
495
|
function initProgressBars() {
|
|
490
496
|
const fills = document.querySelectorAll('.mw-progress-fill');
|
|
491
497
|
if (!fills.length) return;
|
|
492
498
|
|
|
499
|
+
const scrollDriven = CSS.supports('animation-timeline', 'view()');
|
|
500
|
+
|
|
501
|
+
// Two spellings in the wild: data-value="75" and style="width: 75%".
|
|
502
|
+
const targetWidth = (bar) =>
|
|
503
|
+
bar.dataset.value ? bar.dataset.value + '%' : bar.style.width;
|
|
504
|
+
|
|
505
|
+
const driven = [];
|
|
506
|
+
fills.forEach((bar) => {
|
|
507
|
+
const target = targetWidth(bar);
|
|
508
|
+
if (!target) return;
|
|
509
|
+
bar.style.setProperty('--mw-progress-value', target);
|
|
510
|
+
if (scrollDriven) bar.classList.add('mw-progress-driven');
|
|
511
|
+
else driven.push(bar);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
if (scrollDriven) return;
|
|
515
|
+
|
|
516
|
+
// Fallback: set the width once, when the bar comes into view, and let the
|
|
517
|
+
// transition in _progress.scss animate it. Only bars whose target is known -
|
|
518
|
+
// a bar already carrying its width in the markup is left alone.
|
|
493
519
|
const obs = new IntersectionObserver(
|
|
494
520
|
(entries, observer) => {
|
|
495
521
|
entries.forEach((entry) => {
|
|
496
522
|
if (!entry.isIntersecting) return;
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
// trigger the CSS transition
|
|
500
|
-
bar.style.width = pct + '%';
|
|
501
|
-
// stop observing this one
|
|
502
|
-
observer.unobserve(bar);
|
|
523
|
+
entry.target.style.width = targetWidth(entry.target);
|
|
524
|
+
observer.unobserve(entry.target);
|
|
503
525
|
});
|
|
504
526
|
},
|
|
505
|
-
{
|
|
506
|
-
root: null,
|
|
507
|
-
threshold: 0.2,
|
|
508
|
-
}
|
|
527
|
+
{ root: null, threshold: 0.2 }
|
|
509
528
|
);
|
|
510
529
|
|
|
511
|
-
|
|
530
|
+
driven.forEach((bar) => obs.observe(bar));
|
|
512
531
|
}
|
|
513
532
|
|
|
514
533
|
// ===== Smooth Scrolling =====
|
|
@@ -538,10 +557,8 @@
|
|
|
538
557
|
|
|
539
558
|
if (sections.length === 0 || navLinks.length === 0) return;
|
|
540
559
|
|
|
541
|
-
//
|
|
542
|
-
//
|
|
543
|
-
// target as soon as an announcement ribbon raises the padding. Read per
|
|
544
|
-
// run: the ribbon grows on small screens and can be dismissed at runtime.
|
|
560
|
+
// Measured against scroll-padding-top, the same value an anchor jump lands on,
|
|
561
|
+
// and read per run - the ribbon grows on small screens and can be dismissed
|
|
545
562
|
function scrollOffset() {
|
|
546
563
|
const padding = parseFloat(
|
|
547
564
|
getComputedStyle(document.documentElement).scrollPaddingTop
|
|
@@ -583,35 +600,109 @@
|
|
|
583
600
|
);
|
|
584
601
|
}
|
|
585
602
|
|
|
586
|
-
//
|
|
603
|
+
// The strip draws the marker, this only hands over position and length as custom
|
|
604
|
+
// properties. Both axes every time - which pair the bar uses is the stylesheet's
|
|
605
|
+
// decision, at a breakpoint this file knows nothing of. The attribute switches
|
|
606
|
+
// the bar on and is set after the first measurement, so a page without script
|
|
607
|
+
// keeps the plain border and still looks finished.
|
|
608
|
+
function measureTabsMarker(nav) {
|
|
609
|
+
const active = nav.querySelector(
|
|
610
|
+
'.mw-tabs-nav-item.mw-active, .mw-tabs-nav-item.active'
|
|
611
|
+
);
|
|
612
|
+
if (!active) {
|
|
613
|
+
nav.removeAttribute('data-mw-tabs-marker');
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// Unitless for the scale factors: the bar is 1px long and scaled up.
|
|
618
|
+
nav.style.setProperty('--mw-tabs-marker-x', active.offsetLeft + 'px');
|
|
619
|
+
nav.style.setProperty('--mw-tabs-marker-w', active.offsetWidth);
|
|
620
|
+
nav.style.setProperty('--mw-tabs-marker-y', active.offsetTop + 'px');
|
|
621
|
+
nav.style.setProperty('--mw-tabs-marker-h', active.offsetHeight);
|
|
622
|
+
nav.setAttribute('data-mw-tabs-marker', '');
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Set here and not in the markup, so a page that already ships .mw-tabs gets the
|
|
626
|
+
// tablist semantics by loading the script
|
|
587
627
|
function initTabs() {
|
|
588
|
-
|
|
628
|
+
document.querySelectorAll('.mw-tabs-nav').forEach((nav) => {
|
|
629
|
+
const items = Array.from(nav.querySelectorAll('.mw-tabs-nav-item'));
|
|
630
|
+
if (!items.length) return;
|
|
589
631
|
|
|
590
|
-
|
|
591
|
-
item.addEventListener('click', function () {
|
|
592
|
-
const tabsContainer = this.closest('.mw-tabs');
|
|
593
|
-
if (!tabsContainer) return;
|
|
632
|
+
const vertical = !!nav.closest('.mw-tabs-vertical');
|
|
594
633
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
.forEach((navItem) => {
|
|
598
|
-
setActive(navItem, false);
|
|
599
|
-
});
|
|
634
|
+
nav.setAttribute('role', 'tablist');
|
|
635
|
+
if (vertical) nav.setAttribute('aria-orientation', 'vertical');
|
|
600
636
|
|
|
601
|
-
|
|
637
|
+
items.forEach((item, index) => {
|
|
638
|
+
const panel = tabPanelOf(item);
|
|
602
639
|
|
|
603
|
-
|
|
604
|
-
if (!
|
|
640
|
+
item.setAttribute('role', 'tab');
|
|
641
|
+
if (!item.id) item.id = (panel ? panel.id : 'mw-tab-' + index) + '-tab';
|
|
605
642
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
643
|
+
if (panel) {
|
|
644
|
+
item.setAttribute('aria-controls', panel.id);
|
|
645
|
+
panel.setAttribute('role', 'tabpanel');
|
|
646
|
+
panel.setAttribute('aria-labelledby', item.id);
|
|
647
|
+
}
|
|
609
648
|
|
|
610
|
-
|
|
649
|
+
syncTabState(item);
|
|
650
|
+
|
|
651
|
+
item.addEventListener('click', () => selectTab(items, item));
|
|
652
|
+
|
|
653
|
+
item.addEventListener('keydown', (event) => {
|
|
654
|
+
const target = tabKeyTarget(event, vertical, items.length, index);
|
|
655
|
+
if (target === null) return;
|
|
656
|
+
event.preventDefault();
|
|
657
|
+
selectTab(items, items[target]);
|
|
658
|
+
items[target].focus();
|
|
659
|
+
});
|
|
611
660
|
});
|
|
661
|
+
|
|
662
|
+
measureTabsMarker(nav);
|
|
663
|
+
|
|
664
|
+
// The items are watched too: a web font arriving moves the label the bar is
|
|
665
|
+
// parked under without the strip itself changing size
|
|
666
|
+
const observer = new ResizeObserver(() => measureTabsMarker(nav));
|
|
667
|
+
observer.observe(nav);
|
|
668
|
+
items.forEach((item) => observer.observe(item));
|
|
612
669
|
});
|
|
613
670
|
}
|
|
614
671
|
|
|
672
|
+
function tabPanelOf(item) {
|
|
673
|
+
const id = item.getAttribute('data-tab');
|
|
674
|
+
return id ? document.getElementById(id) : null;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
function syncTabState(item) {
|
|
678
|
+
const on = isActive(item);
|
|
679
|
+
item.setAttribute('aria-selected', String(on));
|
|
680
|
+
item.tabIndex = on ? 0 : -1;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
function selectTab(items, item) {
|
|
684
|
+
items.forEach((other) => {
|
|
685
|
+
const on = other === item;
|
|
686
|
+
setActive(other, on);
|
|
687
|
+
setActive(tabPanelOf(other), on);
|
|
688
|
+
syncTabState(other);
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
const nav = item.closest('.mw-tabs-nav');
|
|
692
|
+
if (nav) measureTabsMarker(nav);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function tabKeyTarget(event, vertical, count, index) {
|
|
696
|
+
const back = vertical ? 'ArrowUp' : 'ArrowLeft';
|
|
697
|
+
const forward = vertical ? 'ArrowDown' : 'ArrowRight';
|
|
698
|
+
|
|
699
|
+
if (event.key === back) return (index - 1 + count) % count;
|
|
700
|
+
if (event.key === forward) return (index + 1) % count;
|
|
701
|
+
if (event.key === 'Home') return 0;
|
|
702
|
+
if (event.key === 'End') return count - 1;
|
|
703
|
+
return null;
|
|
704
|
+
}
|
|
705
|
+
|
|
615
706
|
// ===== Alerts =====
|
|
616
707
|
function initAlerts() {
|
|
617
708
|
const alertCloseButtons = document.querySelectorAll('.mw-alert-close');
|
|
@@ -691,17 +782,71 @@
|
|
|
691
782
|
}
|
|
692
783
|
|
|
693
784
|
// ===== Modals =====
|
|
785
|
+
|
|
786
|
+
// Two shapes: the older `mw-modal-overlay` div toggled by class, and `<dialog>`,
|
|
787
|
+
// where focus trap, Escape and the inert background are the browser's job.
|
|
788
|
+
// Delegated, so a modal added later works too.
|
|
694
789
|
function initModals() {
|
|
695
|
-
document.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
790
|
+
document.addEventListener('click', (e) => {
|
|
791
|
+
const closer = e.target.closest('.mw-modal-close');
|
|
792
|
+
if (closer) {
|
|
793
|
+
const dialog = closer.closest('dialog.mw-modal');
|
|
794
|
+
if (dialog) {
|
|
795
|
+
dialog.close();
|
|
796
|
+
return;
|
|
700
797
|
}
|
|
701
|
-
|
|
798
|
+
const overlay = closer.closest('.mw-modal-overlay');
|
|
799
|
+
if (overlay) overlay.classList.remove('mw-modal-open');
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
const opener = e.target.closest('[data-mw-modal]');
|
|
804
|
+
if (opener) {
|
|
805
|
+
openModal(document.getElementById(opener.dataset.mwModal));
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
// Light dismiss for a dialog the browser does not dismiss itself. A click
|
|
810
|
+
// that lands on the dialog element is a click on the backdrop - the
|
|
811
|
+
// content sits in .mw-modal-header/body/footer inside it.
|
|
812
|
+
if (
|
|
813
|
+
e.target.matches('dialog.mw-modal[open]') &&
|
|
814
|
+
!dismissesItself(e.target)
|
|
815
|
+
) {
|
|
816
|
+
e.target.close();
|
|
817
|
+
}
|
|
702
818
|
});
|
|
703
819
|
}
|
|
704
820
|
|
|
821
|
+
// True when `closedby` is on the element *and* understood, which is the only
|
|
822
|
+
// case where the browser closes the dialog on a backdrop click by itself.
|
|
823
|
+
function dismissesItself(dialog) {
|
|
824
|
+
return 'closedBy' in dialog && dialog.getAttribute('closedby') !== null;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// Opens either shape. Exposed, because which modal opens when is the
|
|
828
|
+
// application's decision and not something markup can express on its own.
|
|
829
|
+
function openModal(modal) {
|
|
830
|
+
if (!modal) return;
|
|
831
|
+
if (modal.tagName === 'DIALOG') {
|
|
832
|
+
modal.showModal();
|
|
833
|
+
} else {
|
|
834
|
+
modal.classList.add('mw-modal-open');
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
function closeModal(modal) {
|
|
839
|
+
if (!modal) return;
|
|
840
|
+
if (modal.tagName === 'DIALOG') {
|
|
841
|
+
modal.close();
|
|
842
|
+
} else {
|
|
843
|
+
modal.classList.remove('mw-modal-open');
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
window.mwOpenModal = (id) => openModal(document.getElementById(id));
|
|
848
|
+
window.mwCloseModal = (id) => closeModal(document.getElementById(id));
|
|
849
|
+
|
|
705
850
|
// ===== Login Button =====
|
|
706
851
|
function initHeaderLoginButton() {
|
|
707
852
|
const loginButton = document.getElementById('login-button');
|
|
@@ -926,14 +1071,9 @@
|
|
|
926
1071
|
|
|
927
1072
|
target.querySelector('.mw-kanban-column-body').appendChild(card);
|
|
928
1073
|
|
|
929
|
-
//
|
|
930
|
-
//
|
|
931
|
-
//
|
|
932
|
-
//
|
|
933
|
-
// Both classes come off first and the reflow is forced in between: an
|
|
934
|
-
// element that already carries the class it is being given again keeps
|
|
935
|
-
// the finished animation and plays nothing, so a second push in the same
|
|
936
|
-
// direction would be the silent one.
|
|
1074
|
+
// Re-parenting alone makes the card blink into the other column, so it comes
|
|
1075
|
+
// in from the side it was pushed from. Both classes come off first with a
|
|
1076
|
+
// forced reflow between, or a second push in the same direction is silent.
|
|
937
1077
|
card.classList.remove.apply(card.classList, MOVE_CLASSES);
|
|
938
1078
|
void card.offsetWidth;
|
|
939
1079
|
card.classList.add(offset > 0 ? MOVE_CLASSES[0] : MOVE_CLASSES[1]);
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
your project's needs:
|
|
46
46
|
</p>
|
|
47
47
|
|
|
48
|
-
<
|
|
48
|
+
<h4 class="mw-mt-4 mw-mb-2">
|
|
49
49
|
1. Using CSS Variables (Recommended for CDN/CSS Users)
|
|
50
|
-
</
|
|
50
|
+
</h4>
|
|
51
51
|
<p>
|
|
52
52
|
If you're using the pre-compiled CSS file (via CDN or download), you
|
|
53
53
|
can override MaverickWave's default styles by redefining its CSS
|
|
@@ -69,9 +69,9 @@
|
|
|
69
69
|
}</code></pre>
|
|
70
70
|
<p>This method is flexible and doesn't require a Sass build process.</p>
|
|
71
71
|
|
|
72
|
-
<
|
|
72
|
+
<h4 class="mw-mt-4 mw-mb-2">
|
|
73
73
|
2. Using SCSS Variables (Requires Sass Build Process)
|
|
74
|
-
</
|
|
74
|
+
</h4>
|
|
75
75
|
<p>
|
|
76
76
|
If you integrate MaverickWave's SCSS source files into your project,
|
|
77
77
|
pass your overrides through <code>@use ... with (...)</code>. A plain
|
|
@@ -91,13 +91,9 @@
|
|
|
91
91
|
<code>main</code> - see the "Get Started" section.
|
|
92
92
|
</p>
|
|
93
93
|
<p class="mw-mt-4">
|
|
94
|
-
<
|
|
95
|
-
type="button"
|
|
96
|
-
onclick="location.href = '#get-started'"
|
|
97
|
-
class="mw-link"
|
|
98
|
-
>
|
|
94
|
+
<a href="#get-started" class="mw-link">
|
|
99
95
|
See the "Get Started" section
|
|
100
|
-
</
|
|
96
|
+
</a>
|
|
101
97
|
for more detailed integration examples for both methods.
|
|
102
98
|
</p>
|
|
103
99
|
</div>
|