basecoat-cli 0.3.10-beta.2 → 0.3.10

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.
@@ -83,12 +83,10 @@
83
83
  </footer>
84
84
  {% endif %}
85
85
  {% if close_button %}
86
- <form method="dialog">
87
- <button aria-label="Close dialog">
88
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
86
+ <button type="button" aria-label="Close dialog" onclick="this.closest('dialog').close()">
87
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
89
88
  </button>
90
- </form>
91
89
  {% endif %}
92
90
  </div>
93
91
  </dialog>
94
- {% endmacro %}
92
+ {% endmacro %}
@@ -6,6 +6,7 @@
6
6
  @param name {string} [optional] - The name attribute for the hidden input storing the selected value.
7
7
  @param multiple {boolean} [optional] [default=false] - Enables multiple selection mode.
8
8
  @param placeholder {string} [optional] - Placeholder text shown when no options are selected (multiple mode only).
9
+ @param close_on_select {boolean} [optional] [default=false] - Closes the popover when selecting an option in multiple mode.
9
10
  @param main_attrs {object} [optional] - Additional HTML attributes for the main container div.
10
11
  @param trigger_attrs {object} [optional] - Additional HTML attributes for the trigger button.
11
12
  @param popover_attrs {object} [optional] - Additional HTML attributes for the popover content div.
@@ -21,6 +22,7 @@
21
22
  items=[],
22
23
  multiple=false,
23
24
  placeholder=None,
25
+ close_on_select=false,
24
26
  main_attrs={},
25
27
  trigger_attrs={},
26
28
  popover_attrs={},
@@ -76,6 +78,7 @@
76
78
  id="{{ id }}"
77
79
  class="select {{ main_attrs.class }}"
78
80
  {% if multiple and placeholder %}data-placeholder="{{ placeholder }}"{% endif %}
81
+ {% if multiple and close_on_select %}data-close-on-select="true"{% endif %}
79
82
  {% for key, value in main_attrs.items() %}
80
83
  {% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
81
84
  {% endfor %}
@@ -529,6 +529,7 @@
529
529
  const isMultiple = listbox.getAttribute('aria-multiselectable') === 'true';
530
530
  const selectedOptions = isMultiple ? new Set() : null;
531
531
  const placeholder = isMultiple ? (selectComponent.dataset.placeholder || '') : null;
532
+ const closeOnSelect = selectComponent.dataset.closeOnSelect === 'true';
532
533
 
533
534
  const getValue = (opt) => opt.dataset.value ?? opt.textContent.trim();
534
535
 
@@ -753,6 +754,9 @@
753
754
  const option = options[activeIndex];
754
755
  if (isMultiple) {
755
756
  toggleMultipleValue(option);
757
+ if (closeOnSelect) {
758
+ closePopover();
759
+ }
756
760
  } else {
757
761
  if (input.value !== getValue(option)) {
758
762
  updateValue(option);
@@ -863,11 +867,15 @@
863
867
 
864
868
  if (isMultiple) {
865
869
  toggleMultipleValue(option);
866
- setActiveOption(options.indexOf(option));
867
- if (filter) {
868
- filter.focus();
870
+ if (closeOnSelect) {
871
+ closePopover();
869
872
  } else {
870
- trigger.focus();
873
+ setActiveOption(options.indexOf(option));
874
+ if (filter) {
875
+ filter.focus();
876
+ } else {
877
+ trigger.focus();
878
+ }
871
879
  }
872
880
  } else {
873
881
  if (input.value !== getValue(option)) {
@@ -1 +1 @@
1
- (()=>{const e={};let t=null;const n=()=>{Object.entries(e).forEach((([e,{selector:t,init:n}])=>{document.querySelectorAll(t).forEach(n)}))},i=t=>{t.nodeType===Node.ELEMENT_NODE&&Object.entries(e).forEach((([e,{selector:n,init:i}])=>{t.matches(n)&&i(t),t.querySelectorAll(n).forEach(i)}))},a=()=>{t||(t=new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach(i)}))})),t.observe(document.body,{childList:!0,subtree:!0}))};window.basecoat={register:(t,n,i)=>{e[t]={selector:n,init:i}},init:t=>{const n=e[t];if(!n)return void console.warn(`Component '${t}' not found in registry`);const i=`data-${t}-initialized`;document.querySelectorAll(`[${i}]`).forEach((e=>{e.removeAttribute(i)})),document.querySelectorAll(n.selector).forEach(n.init)},initAll:()=>{Object.entries(e).forEach((([e,{selector:t}])=>{const n=`data-${e}-initialized`;document.querySelectorAll(`[${n}]`).forEach((e=>{e.removeAttribute(n)}))})),n()},start:a,stop:()=>{t&&(t.disconnect(),t=null)}},document.addEventListener("DOMContentLoaded",(()=>{n(),a()}))})(),(()=>{const e=e=>{const t=e.querySelector("header input"),n=e.querySelector('[role="menu"]');if(!t||!n){const i=[];return t||i.push("input"),n||i.push("menu"),void console.error(`Command component initialization failed. Missing element(s): ${i.join(", ")}`,e)}const i=Array.from(n.querySelectorAll('[role="menuitem"]')),a=i.filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled")));let r=[...a],o=-1;const s=e=>{if(o>-1&&a[o]&&a[o].classList.remove("active"),o=e,o>-1){const e=a[o];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")};t.addEventListener("input",(()=>{const e=t.value.trim().toLowerCase();s(-1),r=[],i.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(a.includes(t)&&r.push(t));const n=(t.dataset.filter||t.textContent).trim().toLowerCase(),i=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),o=n.includes(e)||i;t.setAttribute("aria-hidden",String(!o)),o&&a.includes(t)&&r.push(t)})),r.length>0&&(s(a.indexOf(r[0])),r[0].scrollIntoView({block:"nearest"}))}));n.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="menuitem"]');if(t&&r.includes(t)){const e=a.indexOf(t);e!==o&&s(e)}})),n.addEventListener("click",(t=>{const n=t.target.closest('[role="menuitem"]');if(n&&r.includes(n)){const t=e.closest("dialog.command-dialog");t&&!n.hasAttribute("data-keep-command-open")&&t.close()}})),t.addEventListener("keydown",(e=>{if(!["ArrowDown","ArrowUp","Enter","Home","End"].includes(e.key))return;if("Enter"===e.key)return e.preventDefault(),void(o>-1&&a[o]?.click());if(0===r.length)return;e.preventDefault();const t=o>-1?r.indexOf(a[o]):-1;let n=t;switch(e.key){case"ArrowDown":t<r.length-1&&(n=t+1);break;case"ArrowUp":t>0?n=t-1:-1===t&&(n=0);break;case"Home":n=0;break;case"End":n=r.length-1}if(n!==t){const e=r[n];s(a.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}})),r.length>0&&(s(a.indexOf(r[0])),r[0].scrollIntoView({block:"nearest"})),e.dataset.commandInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("command",".command:not([data-command-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=e.querySelector(":scope > [data-popover]"),i=n.querySelector('[role="menu"]');if(!t||!i||!n){const a=[];return t||a.push("trigger"),i||a.push("menu"),n||a.push("popover"),void console.error(`Dropdown menu initialisation failed. Missing element(s): ${a.join(", ")}`,e)}let a=[],r=-1;const o=(e=!0)=>{"false"!==t.getAttribute("aria-expanded")&&(t.setAttribute("aria-expanded","false"),t.removeAttribute("aria-activedescendant"),n.setAttribute("aria-hidden","true"),e&&t.focus(),d(-1))},s=(r=!1)=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),t.setAttribute("aria-expanded","true"),n.setAttribute("aria-hidden","false"),a=Array.from(i.querySelectorAll('[role^="menuitem"]')).filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled"))),a.length>0&&r&&("first"===r?d(0):"last"===r&&d(a.length-1))},d=e=>{if(r>-1&&a[r]&&a[r].classList.remove("active"),r=e,r>-1&&a[r]){const e=a[r];e.classList.add("active"),t.setAttribute("aria-activedescendant",e.id)}else t.removeAttribute("aria-activedescendant")};t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?o():s(!1)})),e.addEventListener("keydown",(e=>{const n="true"===t.getAttribute("aria-expanded");if("Escape"===e.key)return void(n&&o());if(!n)return void(["Enter"," "].includes(e.key)?(e.preventDefault(),s(!1)):"ArrowDown"===e.key?(e.preventDefault(),s("first")):"ArrowUp"===e.key&&(e.preventDefault(),s("last")));if(0===a.length)return;let i=r;switch(e.key){case"ArrowDown":e.preventDefault(),i=-1===r?0:Math.min(r+1,a.length-1);break;case"ArrowUp":e.preventDefault(),i=-1===r?a.length-1:Math.max(r-1,0);break;case"Home":e.preventDefault(),i=0;break;case"End":e.preventDefault(),i=a.length-1;break;case"Enter":case" ":return e.preventDefault(),a[r]?.click(),void o()}i!==r&&d(i)})),i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role^="menuitem"]');if(t&&a.includes(t)){const e=a.indexOf(t);e!==r&&d(e)}})),i.addEventListener("mouseleave",(()=>{d(-1)})),i.addEventListener("click",(e=>{e.target.closest('[role^="menuitem"]')&&o()})),document.addEventListener("click",(t=>{e.contains(t.target)||o()})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&o(!1)})),e.dataset.dropdownMenuInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("dropdown-menu",".dropdown-menu:not([data-dropdown-menu-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=e.querySelector(":scope > [data-popover]");if(!t||!n){const i=[];return t||i.push("trigger"),n||i.push("content"),void console.error(`Popover initialisation failed. Missing element(s): ${i.join(", ")}`,e)}const i=(e=!0)=>{"false"!==t.getAttribute("aria-expanded")&&(t.setAttribute("aria-expanded","false"),n.setAttribute("aria-hidden","true"),e&&t.focus())};t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?i():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}}));const i=n.querySelector("[autofocus]");i&&n.addEventListener("transitionend",(()=>{i.focus()}),{once:!0}),t.setAttribute("aria-expanded","true"),n.setAttribute("aria-hidden","false")})()})),e.addEventListener("keydown",(e=>{"Escape"===e.key&&i()})),document.addEventListener("click",(t=>{e.contains(t.target)||i()})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&i(!1)})),e.dataset.popoverInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("popover",".popover:not([data-popover-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=t.querySelector(":scope > span"),i=e.querySelector(":scope > [data-popover]"),a=i?i.querySelector('[role="listbox"]'):null,r=e.querySelector(':scope > input[type="hidden"]'),o=e.querySelector('header input[type="text"]');if(!(t&&i&&a&&r)){const n=[];return t||n.push("trigger"),i||n.push("popover"),a||n.push("listbox"),r||n.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${n.join(", ")}`,e)}const s=Array.from(a.querySelectorAll('[role="option"]')),d=s.filter((e=>"true"!==e.getAttribute("aria-disabled")));let c=[...d],l=-1;const u="true"===a.getAttribute("aria-multiselectable"),p=u?new Set:null,v=u?e.dataset.placeholder||"":null,h=e=>e.dataset.value??e.textContent.trim(),f=e=>{if(l>-1&&d[l]&&d[l].classList.remove("active"),l=e,l>-1){const e=d[l];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},m=()=>{const e=getComputedStyle(i);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},b=(t,i=!0)=>{let a;if(u){const e=Array.isArray(t)?t:[];p.clear(),e.forEach((e=>p.add(e)));const i=d.filter((e=>p.has(e)));0===i.length?(n.textContent=v,n.classList.add("text-muted-foreground")):(n.textContent=i.map((e=>e.dataset.label||e.textContent.trim())).join(", "),n.classList.remove("text-muted-foreground")),a=i.map(h),r.value=JSON.stringify(a)}else{const e=t;if(!e)return;n.innerHTML=e.innerHTML,a=h(e),r.value=a}d.forEach((e=>{(u?p.has(e):e===t)?e.setAttribute("aria-selected","true"):e.removeAttribute("aria-selected")})),i&&e.dispatchEvent(new CustomEvent("change",{detail:{value:a},bubbles:!0}))},w=(e=!0)=>{if("true"!==i.getAttribute("aria-hidden")){if(o){const e=()=>{o.value="",c=[...d],s.forEach((e=>e.setAttribute("aria-hidden","false")))};m()?i.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),i.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),f(-1)}},g=e=>{p.has(e)?p.delete(e):p.add(e),b(d.filter((e=>p.has(e))))},E=e=>{if(u){const t=d.find((t=>h(t)===e&&!p.has(t)));if(!t)return;p.add(t),b(d.filter((e=>p.has(e))))}else{const t=d.find((t=>h(t)===e));if(!t)return;r.value!==e&&b(t),w()}},A=e=>{if(!u)return;const t=d.find((t=>h(t)===e&&p.has(t)));t&&(p.delete(t),b(d.filter((e=>p.has(e)))))},y=e=>{if(!u)return;const t=d.find((t=>h(t)===e));t&&g(t)};if(o){const e=()=>{const e=o.value.trim().toLowerCase();f(-1),c=[],s.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(d.includes(t)&&c.push(t));const n=(t.dataset.filter||t.textContent).trim().toLowerCase(),i=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),a=n.includes(e)||i;t.setAttribute("aria-hidden",String(!a)),a&&d.includes(t)&&c.push(t)}))};o.addEventListener("input",e)}if(u){const e=d.filter((e=>"true"===e.getAttribute("aria-selected")));try{const t=JSON.parse(r.value||"[]"),n=new Set(d.map(h)),i=Array.isArray(t)?t.filter((e=>n.has(e))):[],a=[];i.length>0?i.forEach((e=>{const t=d.find((t=>h(t)===e&&!a.includes(t)));t&&a.push(t)})):a.push(...e),b(a,!1)}catch(t){b(e,!1)}}else{const e=d.find((e=>h(e)===r.value))||d[0];e&&b(e,!1)}const k=e=>{const n="false"===i.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!n)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void w();if("Enter"===e.key){if(l>-1){const e=d[l];u?g(e):(r.value!==h(e)&&b(e),w())}return}if(0===c.length)return;const a=l>-1?c.indexOf(d[l]):-1;let o=a;switch(e.key){case"ArrowDown":a<c.length-1&&(o=a+1);break;case"ArrowUp":a>0?o=a-1:-1===a&&(o=0);break;case"Home":o=0;break;case"End":o=c.length-1}if(o!==a){const e=c[o];f(d.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};a.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&c.includes(t)){const e=d.indexOf(t);e!==l&&f(e)}})),a.addEventListener("mouseleave",(()=>{const e=a.querySelector('[role="option"][aria-selected="true"]');f(e?d.indexOf(e):-1)})),t.addEventListener("keydown",k),o&&o.addEventListener("keydown",k);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?w():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),o&&(m()?i.addEventListener("transitionend",(()=>{o.focus()}),{once:!0}):o.focus()),i.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const n=a.querySelector('[role="option"][aria-selected="true"]');n&&(f(d.indexOf(n)),n.scrollIntoView({block:"nearest"}))})()})),a.addEventListener("click",(e=>{const n=e.target.closest('[role="option"]');if(!n)return;const i=d.find((e=>e===n));i&&(u?(g(i),f(d.indexOf(i)),o?o.focus():t.focus()):(r.value!==h(i)&&b(i),w()))})),document.addEventListener("click",(t=>{e.contains(t.target)||w(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&w(!1)})),i.setAttribute("aria-hidden","true"),Object.defineProperty(e,"value",{get:()=>u?d.filter((e=>p.has(e))).map(h):r.value,set:e=>{if(u){const t=Array.isArray(e)?e:null!=e?[e]:[],n=[];t.forEach((e=>{const t=d.find((t=>h(t)===e&&!n.includes(t)));t&&n.push(t)})),b(n)}else{const t=d.find((t=>h(t)===e));t&&(b(t),w())}}}),e.select=E,e.selectByValue=E,u&&(e.deselect=A,e.toggle=y,e.selectAll=()=>b(d),e.selectNone=()=>b([])),e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})(),(()=>{if(!window.history.__basecoatPatched){const e=window.history.pushState;window.history.pushState=function(...t){e.apply(this,t),window.dispatchEvent(new Event("basecoat:locationchange"))};const t=window.history.replaceState;window.history.replaceState=function(...e){t.apply(this,e),window.dispatchEvent(new Event("basecoat:locationchange"))},window.history.__basecoatPatched=!0}const e=e=>{const t="false"!==e.dataset.initialOpen,n="true"===e.dataset.initialMobileOpen,i=parseInt(e.dataset.breakpoint)||768;let a=i>0?window.innerWidth>=i?t:n:t;const r=()=>{const t=window.location.pathname.replace(/\/$/,"");e.querySelectorAll("a").forEach((e=>{if(e.hasAttribute("data-ignore-current"))return;new URL(e.href).pathname.replace(/\/$/,"")===t?e.setAttribute("aria-current","page"):e.removeAttribute("aria-current")}))},o=()=>{e.setAttribute("aria-hidden",!a),a?e.removeAttribute("inert"):e.setAttribute("inert","")},s=e=>{a=e,o()},d=e.id;document.addEventListener("basecoat:sidebar",(e=>{if(!e.detail?.id||e.detail.id===d)switch(e.detail?.action){case"open":s(!0);break;case"close":s(!1);break;default:s(!a)}})),e.addEventListener("click",(t=>{const n=t.target,a=e.querySelector("nav");if(window.innerWidth<i&&n.closest("a, button")&&!n.closest("[data-keep-mobile-sidebar-open]"))return document.activeElement&&document.activeElement.blur(),void s(!1);(n===e||a&&!a.contains(n))&&(document.activeElement&&document.activeElement.blur(),s(!1))})),window.addEventListener("popstate",r),window.addEventListener("basecoat:locationchange",r),o(),r(),e.dataset.sidebarInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("sidebar",".sidebar:not([data-sidebar-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector('[role="tablist"]');if(!t)return;const n=Array.from(t.querySelectorAll('[role="tab"]')),i=n.map((e=>document.getElementById(e.getAttribute("aria-controls")))).filter(Boolean),a=e=>{n.forEach(((e,t)=>{e.setAttribute("aria-selected","false"),e.setAttribute("tabindex","-1"),i[t]&&(i[t].hidden=!0)})),e.setAttribute("aria-selected","true"),e.setAttribute("tabindex","0");const t=document.getElementById(e.getAttribute("aria-controls"));t&&(t.hidden=!1)};t.addEventListener("click",(e=>{const t=e.target.closest('[role="tab"]');t&&a(t)})),t.addEventListener("keydown",(e=>{const t=e.target;if(!n.includes(t))return;let i;const r=n.indexOf(t);switch(e.key){case"ArrowRight":i=n[(r+1)%n.length];break;case"ArrowLeft":i=n[(r-1+n.length)%n.length];break;case"Home":i=n[0];break;case"End":i=n[n.length-1];break;default:return}e.preventDefault(),a(i),i.focus()})),e.dataset.tabsInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("tabs",".tabs:not([data-tabs-initialized])",e)})(),(()=>{let e;const t=new WeakMap;let n=!1;const i={success:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',error:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>',info:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',warning:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>'};function a(e){if(e.dataset.toastInitialized)return;const i=parseInt(e.dataset.duration),a=-1!==i?i||("error"===e.dataset.category?5e3:3e3):-1,r={remainingTime:a,timeoutId:null,startTime:null};-1!==a&&(n?r.timeoutId=null:(r.startTime=Date.now(),r.timeoutId=setTimeout((()=>s(e)),a))),t.set(e,r),e.dataset.toastInitialized="true"}function r(){n||(n=!0,e.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((e=>{if(!t.has(e))return;const n=t.get(e);n.timeoutId&&(clearTimeout(n.timeoutId),n.timeoutId=null,n.remainingTime-=Date.now()-n.startTime)})))}function o(){n&&(n=!1,e.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((e=>{if(!t.has(e))return;const n=t.get(e);-1===n.remainingTime||n.timeoutId||(n.remainingTime>0?(n.startTime=Date.now(),n.timeoutId=setTimeout((()=>s(e)),n.remainingTime)):s(e))})))}function s(e){if(!t.has(e))return;const n=t.get(e);clearTimeout(n.timeoutId),t.delete(e),e.contains(document.activeElement)&&document.activeElement.blur(),e.setAttribute("aria-hidden","true"),e.addEventListener("transitionend",(()=>e.remove()),{once:!0})}document.addEventListener("basecoat:toast",(t=>{if(!e)return void console.error("Cannot create toast: toaster container not found on page.");const n=function(e){const{category:t="info",title:n,description:a,action:r,cancel:o,duration:s,icon:d}=e,c=d||t&&i[t]||"",l=n?`<h2>${n}</h2>`:"",u=a?`<p>${a}</p>`:"",p=r?.href?`<a href="${r.href}" class="btn" data-toast-action>${r.label}</a>`:r?.onclick?`<button type="button" class="btn" data-toast-action onclick="${r.onclick}">${r.label}</button>`:"",v=o?`<button type="button" class="btn-outline h-6 text-xs px-2.5 rounded-sm" data-toast-cancel onclick="${o?.onclick}">${o.label}</button>`:"",h=`\n <div\n class="toast"\n role="${"error"===t?"alert":"status"}"\n aria-atomic="true"\n ${t?`data-category="${t}"`:""}\n ${void 0!==s?`data-duration="${s}"`:""}\n >\n <div class="toast-content">\n ${c}\n <section>\n ${l}\n ${u}\n </section>\n ${p||v?`<footer>${p}${v}</footer>`:""}\n </div>\n </div>\n </div>\n `,f=document.createElement("template");return f.innerHTML=h.trim(),f.content.firstChild}(t.detail?.config||{});e.appendChild(n)})),window.basecoat&&(window.basecoat.register("toaster","#toaster:not([data-toaster-initialized])",(function(t){t.dataset.toasterInitialized||(e=t,e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",o),e.addEventListener("click",(e=>{const t=e.target.closest(".toast footer a"),n=e.target.closest(".toast footer button");(t||n)&&s(e.target.closest(".toast"))})),e.querySelectorAll(".toast:not([data-toast-initialized])").forEach(a),e.dataset.toasterInitialized="true",e.dispatchEvent(new CustomEvent("basecoat:initialized")))})),window.basecoat.register("toast",".toast:not([data-toast-initialized])",a))})();
1
+ (()=>{const e={};let t=null;const n=()=>{Object.entries(e).forEach((([e,{selector:t,init:n}])=>{document.querySelectorAll(t).forEach(n)}))},i=t=>{t.nodeType===Node.ELEMENT_NODE&&Object.entries(e).forEach((([e,{selector:n,init:i}])=>{t.matches(n)&&i(t),t.querySelectorAll(n).forEach(i)}))},a=()=>{t||(t=new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach(i)}))})),t.observe(document.body,{childList:!0,subtree:!0}))};window.basecoat={register:(t,n,i)=>{e[t]={selector:n,init:i}},init:t=>{const n=e[t];if(!n)return void console.warn(`Component '${t}' not found in registry`);const i=`data-${t}-initialized`;document.querySelectorAll(`[${i}]`).forEach((e=>{e.removeAttribute(i)})),document.querySelectorAll(n.selector).forEach(n.init)},initAll:()=>{Object.entries(e).forEach((([e,{selector:t}])=>{const n=`data-${e}-initialized`;document.querySelectorAll(`[${n}]`).forEach((e=>{e.removeAttribute(n)}))})),n()},start:a,stop:()=>{t&&(t.disconnect(),t=null)}},document.addEventListener("DOMContentLoaded",(()=>{n(),a()}))})(),(()=>{const e=e=>{const t=e.querySelector("header input"),n=e.querySelector('[role="menu"]');if(!t||!n){const i=[];return t||i.push("input"),n||i.push("menu"),void console.error(`Command component initialization failed. Missing element(s): ${i.join(", ")}`,e)}const i=Array.from(n.querySelectorAll('[role="menuitem"]')),a=i.filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled")));let r=[...a],o=-1;const s=e=>{if(o>-1&&a[o]&&a[o].classList.remove("active"),o=e,o>-1){const e=a[o];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")};t.addEventListener("input",(()=>{const e=t.value.trim().toLowerCase();s(-1),r=[],i.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(a.includes(t)&&r.push(t));const n=(t.dataset.filter||t.textContent).trim().toLowerCase(),i=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),o=n.includes(e)||i;t.setAttribute("aria-hidden",String(!o)),o&&a.includes(t)&&r.push(t)})),r.length>0&&(s(a.indexOf(r[0])),r[0].scrollIntoView({block:"nearest"}))}));n.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="menuitem"]');if(t&&r.includes(t)){const e=a.indexOf(t);e!==o&&s(e)}})),n.addEventListener("click",(t=>{const n=t.target.closest('[role="menuitem"]');if(n&&r.includes(n)){const t=e.closest("dialog.command-dialog");t&&!n.hasAttribute("data-keep-command-open")&&t.close()}})),t.addEventListener("keydown",(e=>{if(!["ArrowDown","ArrowUp","Enter","Home","End"].includes(e.key))return;if("Enter"===e.key)return e.preventDefault(),void(o>-1&&a[o]?.click());if(0===r.length)return;e.preventDefault();const t=o>-1?r.indexOf(a[o]):-1;let n=t;switch(e.key){case"ArrowDown":t<r.length-1&&(n=t+1);break;case"ArrowUp":t>0?n=t-1:-1===t&&(n=0);break;case"Home":n=0;break;case"End":n=r.length-1}if(n!==t){const e=r[n];s(a.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}})),r.length>0&&(s(a.indexOf(r[0])),r[0].scrollIntoView({block:"nearest"})),e.dataset.commandInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("command",".command:not([data-command-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=e.querySelector(":scope > [data-popover]"),i=n.querySelector('[role="menu"]');if(!t||!i||!n){const a=[];return t||a.push("trigger"),i||a.push("menu"),n||a.push("popover"),void console.error(`Dropdown menu initialisation failed. Missing element(s): ${a.join(", ")}`,e)}let a=[],r=-1;const o=(e=!0)=>{"false"!==t.getAttribute("aria-expanded")&&(t.setAttribute("aria-expanded","false"),t.removeAttribute("aria-activedescendant"),n.setAttribute("aria-hidden","true"),e&&t.focus(),d(-1))},s=(r=!1)=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),t.setAttribute("aria-expanded","true"),n.setAttribute("aria-hidden","false"),a=Array.from(i.querySelectorAll('[role^="menuitem"]')).filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled"))),a.length>0&&r&&("first"===r?d(0):"last"===r&&d(a.length-1))},d=e=>{if(r>-1&&a[r]&&a[r].classList.remove("active"),r=e,r>-1&&a[r]){const e=a[r];e.classList.add("active"),t.setAttribute("aria-activedescendant",e.id)}else t.removeAttribute("aria-activedescendant")};t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?o():s(!1)})),e.addEventListener("keydown",(e=>{const n="true"===t.getAttribute("aria-expanded");if("Escape"===e.key)return void(n&&o());if(!n)return void(["Enter"," "].includes(e.key)?(e.preventDefault(),s(!1)):"ArrowDown"===e.key?(e.preventDefault(),s("first")):"ArrowUp"===e.key&&(e.preventDefault(),s("last")));if(0===a.length)return;let i=r;switch(e.key){case"ArrowDown":e.preventDefault(),i=-1===r?0:Math.min(r+1,a.length-1);break;case"ArrowUp":e.preventDefault(),i=-1===r?a.length-1:Math.max(r-1,0);break;case"Home":e.preventDefault(),i=0;break;case"End":e.preventDefault(),i=a.length-1;break;case"Enter":case" ":return e.preventDefault(),a[r]?.click(),void o()}i!==r&&d(i)})),i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role^="menuitem"]');if(t&&a.includes(t)){const e=a.indexOf(t);e!==r&&d(e)}})),i.addEventListener("mouseleave",(()=>{d(-1)})),i.addEventListener("click",(e=>{e.target.closest('[role^="menuitem"]')&&o()})),document.addEventListener("click",(t=>{e.contains(t.target)||o()})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&o(!1)})),e.dataset.dropdownMenuInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("dropdown-menu",".dropdown-menu:not([data-dropdown-menu-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=e.querySelector(":scope > [data-popover]");if(!t||!n){const i=[];return t||i.push("trigger"),n||i.push("content"),void console.error(`Popover initialisation failed. Missing element(s): ${i.join(", ")}`,e)}const i=(e=!0)=>{"false"!==t.getAttribute("aria-expanded")&&(t.setAttribute("aria-expanded","false"),n.setAttribute("aria-hidden","true"),e&&t.focus())};t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?i():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}}));const i=n.querySelector("[autofocus]");i&&n.addEventListener("transitionend",(()=>{i.focus()}),{once:!0}),t.setAttribute("aria-expanded","true"),n.setAttribute("aria-hidden","false")})()})),e.addEventListener("keydown",(e=>{"Escape"===e.key&&i()})),document.addEventListener("click",(t=>{e.contains(t.target)||i()})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&i(!1)})),e.dataset.popoverInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("popover",".popover:not([data-popover-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=t.querySelector(":scope > span"),i=e.querySelector(":scope > [data-popover]"),a=i?i.querySelector('[role="listbox"]'):null,r=e.querySelector(':scope > input[type="hidden"]'),o=e.querySelector('header input[type="text"]');if(!(t&&i&&a&&r)){const n=[];return t||n.push("trigger"),i||n.push("popover"),a||n.push("listbox"),r||n.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${n.join(", ")}`,e)}const s=Array.from(a.querySelectorAll('[role="option"]')),d=s.filter((e=>"true"!==e.getAttribute("aria-disabled")));let c=[...d],l=-1;const u="true"===a.getAttribute("aria-multiselectable"),p=u?new Set:null,v=u?e.dataset.placeholder||"":null,h="true"===e.dataset.closeOnSelect,f=e=>e.dataset.value??e.textContent.trim(),m=e=>{if(l>-1&&d[l]&&d[l].classList.remove("active"),l=e,l>-1){const e=d[l];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},b=()=>{const e=getComputedStyle(i);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},w=(t,i=!0)=>{let a;if(u){const e=Array.isArray(t)?t:[];p.clear(),e.forEach((e=>p.add(e)));const i=d.filter((e=>p.has(e)));0===i.length?(n.textContent=v,n.classList.add("text-muted-foreground")):(n.textContent=i.map((e=>e.dataset.label||e.textContent.trim())).join(", "),n.classList.remove("text-muted-foreground")),a=i.map(f),r.value=JSON.stringify(a)}else{const e=t;if(!e)return;n.innerHTML=e.innerHTML,a=f(e),r.value=a}d.forEach((e=>{(u?p.has(e):e===t)?e.setAttribute("aria-selected","true"):e.removeAttribute("aria-selected")})),i&&e.dispatchEvent(new CustomEvent("change",{detail:{value:a},bubbles:!0}))},g=(e=!0)=>{if("true"!==i.getAttribute("aria-hidden")){if(o){const e=()=>{o.value="",c=[...d],s.forEach((e=>e.setAttribute("aria-hidden","false")))};b()?i.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),i.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),m(-1)}},E=e=>{p.has(e)?p.delete(e):p.add(e),w(d.filter((e=>p.has(e))))},A=e=>{if(u){const t=d.find((t=>f(t)===e&&!p.has(t)));if(!t)return;p.add(t),w(d.filter((e=>p.has(e))))}else{const t=d.find((t=>f(t)===e));if(!t)return;r.value!==e&&w(t),g()}},y=e=>{if(!u)return;const t=d.find((t=>f(t)===e&&p.has(t)));t&&(p.delete(t),w(d.filter((e=>p.has(e)))))},k=e=>{if(!u)return;const t=d.find((t=>f(t)===e));t&&E(t)};if(o){const e=()=>{const e=o.value.trim().toLowerCase();m(-1),c=[],s.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(d.includes(t)&&c.push(t));const n=(t.dataset.filter||t.textContent).trim().toLowerCase(),i=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),a=n.includes(e)||i;t.setAttribute("aria-hidden",String(!a)),a&&d.includes(t)&&c.push(t)}))};o.addEventListener("input",e)}if(u){const e=d.filter((e=>"true"===e.getAttribute("aria-selected")));try{const t=JSON.parse(r.value||"[]"),n=new Set(d.map(f)),i=Array.isArray(t)?t.filter((e=>n.has(e))):[],a=[];i.length>0?i.forEach((e=>{const t=d.find((t=>f(t)===e&&!a.includes(t)));t&&a.push(t)})):a.push(...e),w(a,!1)}catch(t){w(e,!1)}}else{const e=d.find((e=>f(e)===r.value))||d[0];e&&w(e,!1)}const L=e=>{const n="false"===i.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!n)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void g();if("Enter"===e.key){if(l>-1){const e=d[l];u?(E(e),h&&g()):(r.value!==f(e)&&w(e),g())}return}if(0===c.length)return;const a=l>-1?c.indexOf(d[l]):-1;let o=a;switch(e.key){case"ArrowDown":a<c.length-1&&(o=a+1);break;case"ArrowUp":a>0?o=a-1:-1===a&&(o=0);break;case"Home":o=0;break;case"End":o=c.length-1}if(o!==a){const e=c[o];m(d.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};a.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&c.includes(t)){const e=d.indexOf(t);e!==l&&m(e)}})),a.addEventListener("mouseleave",(()=>{const e=a.querySelector('[role="option"][aria-selected="true"]');m(e?d.indexOf(e):-1)})),t.addEventListener("keydown",L),o&&o.addEventListener("keydown",L);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?g():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),o&&(b()?i.addEventListener("transitionend",(()=>{o.focus()}),{once:!0}):o.focus()),i.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const n=a.querySelector('[role="option"][aria-selected="true"]');n&&(m(d.indexOf(n)),n.scrollIntoView({block:"nearest"}))})()})),a.addEventListener("click",(e=>{const n=e.target.closest('[role="option"]');if(!n)return;const i=d.find((e=>e===n));i&&(u?(E(i),h?g():(m(d.indexOf(i)),o?o.focus():t.focus())):(r.value!==f(i)&&w(i),g()))})),document.addEventListener("click",(t=>{e.contains(t.target)||g(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&g(!1)})),i.setAttribute("aria-hidden","true"),Object.defineProperty(e,"value",{get:()=>u?d.filter((e=>p.has(e))).map(f):r.value,set:e=>{if(u){const t=Array.isArray(e)?e:null!=e?[e]:[],n=[];t.forEach((e=>{const t=d.find((t=>f(t)===e&&!n.includes(t)));t&&n.push(t)})),w(n)}else{const t=d.find((t=>f(t)===e));t&&(w(t),g())}}}),e.select=A,e.selectByValue=A,u&&(e.deselect=y,e.toggle=k,e.selectAll=()=>w(d),e.selectNone=()=>w([])),e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})(),(()=>{if(!window.history.__basecoatPatched){const e=window.history.pushState;window.history.pushState=function(...t){e.apply(this,t),window.dispatchEvent(new Event("basecoat:locationchange"))};const t=window.history.replaceState;window.history.replaceState=function(...e){t.apply(this,e),window.dispatchEvent(new Event("basecoat:locationchange"))},window.history.__basecoatPatched=!0}const e=e=>{const t="false"!==e.dataset.initialOpen,n="true"===e.dataset.initialMobileOpen,i=parseInt(e.dataset.breakpoint)||768;let a=i>0?window.innerWidth>=i?t:n:t;const r=()=>{const t=window.location.pathname.replace(/\/$/,"");e.querySelectorAll("a").forEach((e=>{if(e.hasAttribute("data-ignore-current"))return;new URL(e.href).pathname.replace(/\/$/,"")===t?e.setAttribute("aria-current","page"):e.removeAttribute("aria-current")}))},o=()=>{e.setAttribute("aria-hidden",!a),a?e.removeAttribute("inert"):e.setAttribute("inert","")},s=e=>{a=e,o()},d=e.id;document.addEventListener("basecoat:sidebar",(e=>{if(!e.detail?.id||e.detail.id===d)switch(e.detail?.action){case"open":s(!0);break;case"close":s(!1);break;default:s(!a)}})),e.addEventListener("click",(t=>{const n=t.target,a=e.querySelector("nav");if(window.innerWidth<i&&n.closest("a, button")&&!n.closest("[data-keep-mobile-sidebar-open]"))return document.activeElement&&document.activeElement.blur(),void s(!1);(n===e||a&&!a.contains(n))&&(document.activeElement&&document.activeElement.blur(),s(!1))})),window.addEventListener("popstate",r),window.addEventListener("basecoat:locationchange",r),o(),r(),e.dataset.sidebarInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("sidebar",".sidebar:not([data-sidebar-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector('[role="tablist"]');if(!t)return;const n=Array.from(t.querySelectorAll('[role="tab"]')),i=n.map((e=>document.getElementById(e.getAttribute("aria-controls")))).filter(Boolean),a=e=>{n.forEach(((e,t)=>{e.setAttribute("aria-selected","false"),e.setAttribute("tabindex","-1"),i[t]&&(i[t].hidden=!0)})),e.setAttribute("aria-selected","true"),e.setAttribute("tabindex","0");const t=document.getElementById(e.getAttribute("aria-controls"));t&&(t.hidden=!1)};t.addEventListener("click",(e=>{const t=e.target.closest('[role="tab"]');t&&a(t)})),t.addEventListener("keydown",(e=>{const t=e.target;if(!n.includes(t))return;let i;const r=n.indexOf(t);switch(e.key){case"ArrowRight":i=n[(r+1)%n.length];break;case"ArrowLeft":i=n[(r-1+n.length)%n.length];break;case"Home":i=n[0];break;case"End":i=n[n.length-1];break;default:return}e.preventDefault(),a(i),i.focus()})),e.dataset.tabsInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("tabs",".tabs:not([data-tabs-initialized])",e)})(),(()=>{let e;const t=new WeakMap;let n=!1;const i={success:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',error:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>',info:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',warning:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>'};function a(e){if(e.dataset.toastInitialized)return;const i=parseInt(e.dataset.duration),a=-1!==i?i||("error"===e.dataset.category?5e3:3e3):-1,r={remainingTime:a,timeoutId:null,startTime:null};-1!==a&&(n?r.timeoutId=null:(r.startTime=Date.now(),r.timeoutId=setTimeout((()=>s(e)),a))),t.set(e,r),e.dataset.toastInitialized="true"}function r(){n||(n=!0,e.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((e=>{if(!t.has(e))return;const n=t.get(e);n.timeoutId&&(clearTimeout(n.timeoutId),n.timeoutId=null,n.remainingTime-=Date.now()-n.startTime)})))}function o(){n&&(n=!1,e.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((e=>{if(!t.has(e))return;const n=t.get(e);-1===n.remainingTime||n.timeoutId||(n.remainingTime>0?(n.startTime=Date.now(),n.timeoutId=setTimeout((()=>s(e)),n.remainingTime)):s(e))})))}function s(e){if(!t.has(e))return;const n=t.get(e);clearTimeout(n.timeoutId),t.delete(e),e.contains(document.activeElement)&&document.activeElement.blur(),e.setAttribute("aria-hidden","true"),e.addEventListener("transitionend",(()=>e.remove()),{once:!0})}document.addEventListener("basecoat:toast",(t=>{if(!e)return void console.error("Cannot create toast: toaster container not found on page.");const n=function(e){const{category:t="info",title:n,description:a,action:r,cancel:o,duration:s,icon:d}=e,c=d||t&&i[t]||"",l=n?`<h2>${n}</h2>`:"",u=a?`<p>${a}</p>`:"",p=r?.href?`<a href="${r.href}" class="btn" data-toast-action>${r.label}</a>`:r?.onclick?`<button type="button" class="btn" data-toast-action onclick="${r.onclick}">${r.label}</button>`:"",v=o?`<button type="button" class="btn-outline h-6 text-xs px-2.5 rounded-sm" data-toast-cancel onclick="${o?.onclick}">${o.label}</button>`:"",h=`\n <div\n class="toast"\n role="${"error"===t?"alert":"status"}"\n aria-atomic="true"\n ${t?`data-category="${t}"`:""}\n ${void 0!==s?`data-duration="${s}"`:""}\n >\n <div class="toast-content">\n ${c}\n <section>\n ${l}\n ${u}\n </section>\n ${p||v?`<footer>${p}${v}</footer>`:""}\n </div>\n </div>\n </div>\n `,f=document.createElement("template");return f.innerHTML=h.trim(),f.content.firstChild}(t.detail?.config||{});e.appendChild(n)})),window.basecoat&&(window.basecoat.register("toaster","#toaster:not([data-toaster-initialized])",(function(t){t.dataset.toasterInitialized||(e=t,e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",o),e.addEventListener("click",(e=>{const t=e.target.closest(".toast footer a"),n=e.target.closest(".toast footer button");(t||n)&&s(e.target.closest(".toast"))})),e.querySelectorAll(".toast:not([data-toast-initialized])").forEach(a),e.dataset.toasterInitialized="true",e.dispatchEvent(new CustomEvent("basecoat:initialized")))})),window.basecoat.register("toast",".toast:not([data-toast-initialized])",a))})();
@@ -24,6 +24,7 @@
24
24
  const isMultiple = listbox.getAttribute('aria-multiselectable') === 'true';
25
25
  const selectedOptions = isMultiple ? new Set() : null;
26
26
  const placeholder = isMultiple ? (selectComponent.dataset.placeholder || '') : null;
27
+ const closeOnSelect = selectComponent.dataset.closeOnSelect === 'true';
27
28
 
28
29
  const getValue = (opt) => opt.dataset.value ?? opt.textContent.trim();
29
30
 
@@ -248,6 +249,9 @@
248
249
  const option = options[activeIndex];
249
250
  if (isMultiple) {
250
251
  toggleMultipleValue(option);
252
+ if (closeOnSelect) {
253
+ closePopover();
254
+ }
251
255
  } else {
252
256
  if (input.value !== getValue(option)) {
253
257
  updateValue(option);
@@ -358,11 +362,15 @@
358
362
 
359
363
  if (isMultiple) {
360
364
  toggleMultipleValue(option);
361
- setActiveOption(options.indexOf(option));
362
- if (filter) {
363
- filter.focus();
365
+ if (closeOnSelect) {
366
+ closePopover();
364
367
  } else {
365
- trigger.focus();
368
+ setActiveOption(options.indexOf(option));
369
+ if (filter) {
370
+ filter.focus();
371
+ } else {
372
+ trigger.focus();
373
+ }
366
374
  }
367
375
  } else {
368
376
  if (input.value !== getValue(option)) {
@@ -1 +1 @@
1
- (()=>{const e=e=>{const t=e.querySelector(":scope > button"),r=t.querySelector(":scope > span"),n=e.querySelector(":scope > [data-popover]"),i=n?n.querySelector('[role="listbox"]'):null,a=e.querySelector(':scope > input[type="hidden"]'),s=e.querySelector('header input[type="text"]');if(!(t&&n&&i&&a)){const r=[];return t||r.push("trigger"),n||r.push("popover"),i||r.push("listbox"),a||r.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${r.join(", ")}`,e)}const o=Array.from(i.querySelectorAll('[role="option"]')),c=o.filter((e=>"true"!==e.getAttribute("aria-disabled")));let l=[...c],d=-1;const u="true"===i.getAttribute("aria-multiselectable"),f=u?new Set:null,p=u?e.dataset.placeholder||"":null,v=e=>e.dataset.value??e.textContent.trim(),h=e=>{if(d>-1&&c[d]&&c[d].classList.remove("active"),d=e,d>-1){const e=c[d];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},b=()=>{const e=getComputedStyle(n);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},m=(t,n=!0)=>{let i;if(u){const e=Array.isArray(t)?t:[];f.clear(),e.forEach((e=>f.add(e)));const n=c.filter((e=>f.has(e)));0===n.length?(r.textContent=p,r.classList.add("text-muted-foreground")):(r.textContent=n.map((e=>e.dataset.label||e.textContent.trim())).join(", "),r.classList.remove("text-muted-foreground")),i=n.map(v),a.value=JSON.stringify(i)}else{const e=t;if(!e)return;r.innerHTML=e.innerHTML,i=v(e),a.value=i}c.forEach((e=>{(u?f.has(e):e===t)?e.setAttribute("aria-selected","true"):e.removeAttribute("aria-selected")})),n&&e.dispatchEvent(new CustomEvent("change",{detail:{value:i},bubbles:!0}))},y=(e=!0)=>{if("true"!==n.getAttribute("aria-hidden")){if(s){const e=()=>{s.value="",l=[...c],o.forEach((e=>e.setAttribute("aria-hidden","false")))};b()?n.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),n.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),h(-1)}},A=e=>{f.has(e)?f.delete(e):f.add(e),m(c.filter((e=>f.has(e))))},E=e=>{if(u){const t=c.find((t=>v(t)===e&&!f.has(t)));if(!t)return;f.add(t),m(c.filter((e=>f.has(e))))}else{const t=c.find((t=>v(t)===e));if(!t)return;a.value!==e&&m(t),y()}},g=e=>{if(!u)return;const t=c.find((t=>v(t)===e&&f.has(t)));t&&(f.delete(t),m(c.filter((e=>f.has(e)))))},w=e=>{if(!u)return;const t=c.find((t=>v(t)===e));t&&A(t)};if(s){const e=()=>{const e=s.value.trim().toLowerCase();h(-1),l=[],o.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(c.includes(t)&&l.push(t));const r=(t.dataset.filter||t.textContent).trim().toLowerCase(),n=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),i=r.includes(e)||n;t.setAttribute("aria-hidden",String(!i)),i&&c.includes(t)&&l.push(t)}))};s.addEventListener("input",e)}if(u){const e=c.filter((e=>"true"===e.getAttribute("aria-selected")));try{const t=JSON.parse(a.value||"[]"),r=new Set(c.map(v)),n=Array.isArray(t)?t.filter((e=>r.has(e))):[],i=[];n.length>0?n.forEach((e=>{const t=c.find((t=>v(t)===e&&!i.includes(t)));t&&i.push(t)})):i.push(...e),m(i,!1)}catch(t){m(e,!1)}}else{const e=c.find((e=>v(e)===a.value))||c[0];e&&m(e,!1)}const L=e=>{const r="false"===n.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!r)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void y();if("Enter"===e.key){if(d>-1){const e=c[d];u?A(e):(a.value!==v(e)&&m(e),y())}return}if(0===l.length)return;const i=d>-1?l.indexOf(c[d]):-1;let s=i;switch(e.key){case"ArrowDown":i<l.length-1&&(s=i+1);break;case"ArrowUp":i>0?s=i-1:-1===i&&(s=0);break;case"Home":s=0;break;case"End":s=l.length-1}if(s!==i){const e=l[s];h(c.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&l.includes(t)){const e=c.indexOf(t);e!==d&&h(e)}})),i.addEventListener("mouseleave",(()=>{const e=i.querySelector('[role="option"][aria-selected="true"]');h(e?c.indexOf(e):-1)})),t.addEventListener("keydown",L),s&&s.addEventListener("keydown",L);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?y():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),s&&(b()?n.addEventListener("transitionend",(()=>{s.focus()}),{once:!0}):s.focus()),n.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const r=i.querySelector('[role="option"][aria-selected="true"]');r&&(h(c.indexOf(r)),r.scrollIntoView({block:"nearest"}))})()})),i.addEventListener("click",(e=>{const r=e.target.closest('[role="option"]');if(!r)return;const n=c.find((e=>e===r));n&&(u?(A(n),h(c.indexOf(n)),s?s.focus():t.focus()):(a.value!==v(n)&&m(n),y()))})),document.addEventListener("click",(t=>{e.contains(t.target)||y(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&y(!1)})),n.setAttribute("aria-hidden","true"),Object.defineProperty(e,"value",{get:()=>u?c.filter((e=>f.has(e))).map(v):a.value,set:e=>{if(u){const t=Array.isArray(e)?e:null!=e?[e]:[],r=[];t.forEach((e=>{const t=c.find((t=>v(t)===e&&!r.includes(t)));t&&r.push(t)})),m(r)}else{const t=c.find((t=>v(t)===e));t&&(m(t),y())}}}),e.select=E,e.selectByValue=E,u&&(e.deselect=g,e.toggle=w,e.selectAll=()=>m(c),e.selectNone=()=>m([])),e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})();
1
+ (()=>{const e=e=>{const t=e.querySelector(":scope > button"),r=t.querySelector(":scope > span"),n=e.querySelector(":scope > [data-popover]"),i=n?n.querySelector('[role="listbox"]'):null,a=e.querySelector(':scope > input[type="hidden"]'),s=e.querySelector('header input[type="text"]');if(!(t&&n&&i&&a)){const r=[];return t||r.push("trigger"),n||r.push("popover"),i||r.push("listbox"),a||r.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${r.join(", ")}`,e)}const o=Array.from(i.querySelectorAll('[role="option"]')),c=o.filter((e=>"true"!==e.getAttribute("aria-disabled")));let l=[...c],d=-1;const u="true"===i.getAttribute("aria-multiselectable"),f=u?new Set:null,p=u?e.dataset.placeholder||"":null,v="true"===e.dataset.closeOnSelect,h=e=>e.dataset.value??e.textContent.trim(),b=e=>{if(d>-1&&c[d]&&c[d].classList.remove("active"),d=e,d>-1){const e=c[d];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},m=()=>{const e=getComputedStyle(n);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},y=(t,n=!0)=>{let i;if(u){const e=Array.isArray(t)?t:[];f.clear(),e.forEach((e=>f.add(e)));const n=c.filter((e=>f.has(e)));0===n.length?(r.textContent=p,r.classList.add("text-muted-foreground")):(r.textContent=n.map((e=>e.dataset.label||e.textContent.trim())).join(", "),r.classList.remove("text-muted-foreground")),i=n.map(h),a.value=JSON.stringify(i)}else{const e=t;if(!e)return;r.innerHTML=e.innerHTML,i=h(e),a.value=i}c.forEach((e=>{(u?f.has(e):e===t)?e.setAttribute("aria-selected","true"):e.removeAttribute("aria-selected")})),n&&e.dispatchEvent(new CustomEvent("change",{detail:{value:i},bubbles:!0}))},A=(e=!0)=>{if("true"!==n.getAttribute("aria-hidden")){if(s){const e=()=>{s.value="",l=[...c],o.forEach((e=>e.setAttribute("aria-hidden","false")))};m()?n.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),n.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),b(-1)}},E=e=>{f.has(e)?f.delete(e):f.add(e),y(c.filter((e=>f.has(e))))},g=e=>{if(u){const t=c.find((t=>h(t)===e&&!f.has(t)));if(!t)return;f.add(t),y(c.filter((e=>f.has(e))))}else{const t=c.find((t=>h(t)===e));if(!t)return;a.value!==e&&y(t),A()}},w=e=>{if(!u)return;const t=c.find((t=>h(t)===e&&f.has(t)));t&&(f.delete(t),y(c.filter((e=>f.has(e)))))},L=e=>{if(!u)return;const t=c.find((t=>h(t)===e));t&&E(t)};if(s){const e=()=>{const e=s.value.trim().toLowerCase();b(-1),l=[],o.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(c.includes(t)&&l.push(t));const r=(t.dataset.filter||t.textContent).trim().toLowerCase(),n=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),i=r.includes(e)||n;t.setAttribute("aria-hidden",String(!i)),i&&c.includes(t)&&l.push(t)}))};s.addEventListener("input",e)}if(u){const e=c.filter((e=>"true"===e.getAttribute("aria-selected")));try{const t=JSON.parse(a.value||"[]"),r=new Set(c.map(h)),n=Array.isArray(t)?t.filter((e=>r.has(e))):[],i=[];n.length>0?n.forEach((e=>{const t=c.find((t=>h(t)===e&&!i.includes(t)));t&&i.push(t)})):i.push(...e),y(i,!1)}catch(t){y(e,!1)}}else{const e=c.find((e=>h(e)===a.value))||c[0];e&&y(e,!1)}const x=e=>{const r="false"===n.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!r)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void A();if("Enter"===e.key){if(d>-1){const e=c[d];u?(E(e),v&&A()):(a.value!==h(e)&&y(e),A())}return}if(0===l.length)return;const i=d>-1?l.indexOf(c[d]):-1;let s=i;switch(e.key){case"ArrowDown":i<l.length-1&&(s=i+1);break;case"ArrowUp":i>0?s=i-1:-1===i&&(s=0);break;case"Home":s=0;break;case"End":s=l.length-1}if(s!==i){const e=l[s];b(c.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&l.includes(t)){const e=c.indexOf(t);e!==d&&b(e)}})),i.addEventListener("mouseleave",(()=>{const e=i.querySelector('[role="option"][aria-selected="true"]');b(e?c.indexOf(e):-1)})),t.addEventListener("keydown",x),s&&s.addEventListener("keydown",x);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?A():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),s&&(m()?n.addEventListener("transitionend",(()=>{s.focus()}),{once:!0}):s.focus()),n.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const r=i.querySelector('[role="option"][aria-selected="true"]');r&&(b(c.indexOf(r)),r.scrollIntoView({block:"nearest"}))})()})),i.addEventListener("click",(e=>{const r=e.target.closest('[role="option"]');if(!r)return;const n=c.find((e=>e===r));n&&(u?(E(n),v?A():(b(c.indexOf(n)),s?s.focus():t.focus())):(a.value!==h(n)&&y(n),A()))})),document.addEventListener("click",(t=>{e.contains(t.target)||A(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&A(!1)})),n.setAttribute("aria-hidden","true"),Object.defineProperty(e,"value",{get:()=>u?c.filter((e=>f.has(e))).map(h):a.value,set:e=>{if(u){const t=Array.isArray(e)?e:null!=e?[e]:[],r=[];t.forEach((e=>{const t=c.find((t=>h(t)===e&&!r.includes(t)));t&&r.push(t)})),y(r)}else{const t=c.find((t=>h(t)===e));t&&(y(t),A())}}}),e.select=g,e.selectByValue=g,u&&(e.deselect=w,e.toggle=L,e.selectAll=()=>y(c),e.selectNone=()=>y([])),e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})();
@@ -6,6 +6,7 @@
6
6
  @param name {string} [optional] - The name attribute for the hidden input storing the selected value.
7
7
  @param multiple {boolean} [optional] [default=false] - Enables multiple selection mode.
8
8
  @param placeholder {string} [optional] - Placeholder text shown when no options are selected (multiple mode only).
9
+ @param close_on_select {boolean} [optional] [default=false] - Closes the popover when selecting an option in multiple mode.
9
10
  @param main_attrs {object} [optional] - Additional HTML attributes for the main container div.
10
11
  @param trigger_attrs {object} [optional] - Additional HTML attributes for the trigger button.
11
12
  @param popover_attrs {object} [optional] - Additional HTML attributes for the popover content div.
@@ -21,6 +22,7 @@
21
22
  items=None,
22
23
  multiple=false,
23
24
  placeholder=None,
25
+ close_on_select=false,
24
26
  main_attrs={},
25
27
  trigger_attrs={},
26
28
  popover_attrs={},
@@ -76,6 +78,7 @@
76
78
  id="{{ id }}"
77
79
  class="select {{ main_attrs.class }}"
78
80
  {% if multiple and placeholder %}data-placeholder="{{ placeholder }}"{% endif %}
81
+ {% if multiple and close_on_select %}data-close-on-select="true"{% endif %}
79
82
  {% for key, value in main_attrs %}
80
83
  {% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
81
84
  {% endfor %}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "basecoat-cli",
3
- "version": "0.3.10-beta.2",
3
+ "version": "0.3.10",
4
4
  "description": "Add Basecoat components to your project",
5
5
  "author": "hunvreus",
6
6
  "license": "MIT",