platypicker 0.0.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.
@@ -0,0 +1 @@
1
+ @media (any-pointer:fine),(any-hover:hover){:has(>select.platypicker){anchor-scope:--platypicker;& select.platypicker{anchor-name:--platypicker;&:not([multiple]),&::picker(select){appearance:base-select!important}&::picker(select),&::picker-icon{display:none}&+.dropdown-menu[popover]{display:revert;position-anchor:--platypicker;min-width:anchor-size();max-height:30rem;top:calc(anchor(bottom) + .125rem)!important;left:anchor(left)!important;transform:none!important;& .input-group:not(:has(:not(.d-none))){display:none}& .input-group input:not(:has(~button:not(.d-none))){border-top-right-radius:var(--bs-border-radius);border-bottom-right-radius:var(--bs-border-radius)}& .input-group input.d-none{&~button{flex-grow:1;flex-basis:50%}&+button:not(.d-none),&+button.d-none+button:not(.d-none){border-top-left-radius:var(--bs-border-radius);border-bottom-left-radius:var(--bs-border-radius)}}& .input-group button:not(.d-none)+button:not(.d-none){border-left-width:0}& li:has(.dropdown-item.d-none)~li:has(.dropdown-divider){display:none}& li:has(.dropdown-item:not(.d-none))~li:has(.dropdown-divider){display:revert}& li:has(.dropdown-item.d-none),& li:has(.dropdown-header.d-none),& li:has(.dropdown-divider.d-none),& li:has(.dropdown-header):not(:has(~li .dropdown-item:not(.d-none))),& li:has(.dropdown-divider):not(:has(~li .dropdown-item:not(.d-none))){display:none}}}}.dropdown-item::highlight(platypicker-highlight),.dropdown-item small::highlight(platypicker-highlight){color:#000;background-color:#fee6b1}}
@@ -0,0 +1 @@
1
+ "use strict";export default class Platypicker{static#e=new Map;static#t;static maxHighlights=100;static languageMap={searchPlaceholder:"Type to filter...",selectAllButton:"Select all",selectNoneButton:"Select none"};#s;#o;#i;#n;#l;#r;#a;#c;#d;#h;#p;get#g(){return"true"===this.#s.dataset?.search?.trim()?.toLowerCase()}get#u(){return"true"===this.#s.dataset.controls?.trim()?.toLowerCase()}static get(e){return this.#e.get(e)}constructor(e){if(Platypicker.#e.has(e)||!window.matchMedia("(any-pointer: fine), (any-hover: hover)").matches)return;let t;e.mutationObserver||(e.mutationObserver=new MutationObserver(()=>{this.#n.classList.toggle("d-none",!this.#g);for(const e of this.#i.querySelectorAll("button"))e.disabled=!this.#u}),e.mutationObserver.observe(e,{attributes:!0,attributeFilter:["data-toggle","data-search","data-controls"]})),this.#s=e,this.#v(),this.#s.popoverElement=this.#o,this.#o.selectElement=this.#s,this.#o.querySelector("ul").addEventListener("click",e=>{if(!this.#s.options?.length)return;let t=e.target.closest("li:not(:has(.dropdown-divider, .dropdown-header)) .dropdown-item:not(.disabled)");t&&(this.#s.multiple?t.option.selected=!t.option.selected:(this.#s.value=t.option.value,this.#m(),this.#o.hidePopover(),this.#l=void 0),t.scrollIntoView({block:"nearest"}),this.#s.multiple||this.#s.focus(),this.#s.dispatchEvent(new Event("change",{bubbles:!0})))}),this.#c=async()=>{this.#s.options?.length&&(await new Promise(e=>requestAnimationFrame(e)),this.#m())},this.#s.addEventListener("change",this.#c),this.#n.form.addEventListener("submit",e=>e.preventDefault()),this.#n.addEventListener("input",e=>this.#L(e.target.value)),this.#n.addEventListener("keydown",e=>{"Escape"===e.code&&this.#s.click()}),this.#a=()=>{this.#l=this.#o.togglePopover(!this.#l),this.#l?this.#o.querySelector("input:not(.d-none), .dropdown-item:not(.disabled, .d-none)")?.focus():this.#s.focus()},this.#s.addEventListener("click",this.#a),this.#h=e=>{this.#o.contains(e.target)||this.#s.contains(e.target)||(this.#o.hidePopover(),this.#l=void 0)},document.addEventListener("click",this.#h),this.#p=e=>{"Escape"===e.code&&(this.#o.hidePopover(),this.#l=void 0)},document.addEventListener("keydown",this.#p),this.#d=e=>{"Enter"!==e.code&&"Space"!==e.code&&"ArrowDown"!==e.code||(this.#l=this.#o.togglePopover(!this.#l))},this.#s.addEventListener("keydown",this.#d,!0);let s="";this.#o.addEventListener("keydown",e=>{if(this.#n.contains(e.target))return;let o=e.key.toLowerCase().charCodeAt(0);if(e.ctrlKey||e.altKey||e.metaKey||e.key.length>1||o<48||o>57&&o<97||o>122)return;s+=e.key.toLowerCase();let i=[...this.#s.options].find(e=>e!==this.#s.selectedOptions[0]&&e.textContent.toLowerCase().trim().startsWith(s)&&!e.disabled&&!e.closest("optgroup")?.disabled&&!e.popoverItem.classList.contains("d-none"));i||(i=!this.#s.selectedOptions[0].textContent.toLowerCase().trim().startsWith(s)||this.#s.selectedOptions[0].disabled||this.#s.selectedOptions[0].closest("optgroup")?.disabled||this.#s.selectedOptions[0].popoverItem.classList.contains("d-none")?void 0:this.#s.selectedOptions[0]),i?(this.#s.multiple?(this.#s.selectedIndex=-1,i.selected=!0,this.#s.dispatchEvent(new Event("change",{bubbles:!0}))):i.popoverItem.focus(),requestAnimationFrame(()=>i.popoverItem?.scrollIntoView({block:"nearest"})),t?t():t=Platypicker.#b(()=>s="",350)):s=""}),this.#o.querySelector("ul").addEventListener("keydown",e=>{"Escape"===e.code&&(this.#l=this.#o.togglePopover(!1),this.#s.focus())},!0),this.#r=new MutationObserver(()=>{(this.#s.options.length!==this.#s.length||[...this.#s.options].some(e=>!e.option))&&this.#w()}),this.#r.observe(e,{childList:!0}),Platypicker.#e.set(this.#s,this)}#v(){this.#o=document.createElement("div"),this.#o.classList.add("dropdown-menu","rounded-3","shadow","p-0"),this.#o.popover="manual",this.#s.parentElement.classList.add("dropdown"),this.#s.classList.add("platypicker"),this.#s.dataset.bsToggle="dropdown",this.#s.insertAdjacentElement("afterend",this.#o),this.#i=document.createElement("form"),this.#i.classList.add("input-group","p-2","bg-body-tertiary","border-bottom","sticky-top"),this.#o.append(this.#i),this.#n=document.createElement("input"),this.#n.classList.add("form-control"),this.#n.type="search",this.#n.name="platypicker-search",this.#n.placeholder=Platypicker.languageMap.searchPlaceholder,this.#n.autofocus=!0,this.#g||this.#n.classList.add("d-none"),this.#i.append(this.#n);const e=document.createElement("button");e.classList.add("btn","btn-outline-secondary"),e.type="button",e.textContent=Platypicker.languageMap.selectAllButton,e.addEventListener("click",()=>{for(const e of[...this.#s.options].filter(e=>!e.disabled&&!e.popoverItem.classList.contains("d-none")&&!e.closest("optgroup")?.disabled))e.selected=!0;this.#s.dispatchEvent(new Event("change",{bubbles:!0}))}),this.#s.multiple&&this.#u||e.classList.add("d-none"),this.#i.append(e);const t=document.createElement("button");t.classList.add("btn","btn-outline-secondary"),t.type="button",t.textContent=Platypicker.languageMap.selectNoneButton,t.addEventListener("click",()=>{this.#s.selectedIndex=-1,this.#s.dispatchEvent(new Event("change",{bubbles:!0}))}),this.#u||t.classList.add("d-none"),this.#i.append(t),this.#w()}#w(){let e=this.#o.querySelector("ul");e?e.innerHTML="":(e=document.createElement("ul"),e.classList.add("list-unstyled","d-grid","gap-1","p-2","mb-0"),this.#o.append(e));for(const t of this.#s.children)if(t instanceof HTMLOptionElement)this.#y(e,t);else if(t instanceof HTMLOptGroupElement){const s=document.createElement("li");e.append(s);const o=document.createElement("h6");o.classList.add("dropdown-header"),o.textContent=t.label,s.append(o),o.optgroup=t,t.header=o;for(const s of t.children)this.#y(e,s);if(t.nextElementSibling instanceof HTMLOptionElement){const s=document.createElement("li");e.append(s);const o=document.createElement("hr");o.classList.add("dropdown-divider"),s.append(o),o.optgroup=t,t.divider=o}}else if(t instanceof HTMLHRElement){const t=document.createElement("li");e.append(t);const s=document.createElement("hr");s.classList.add("dropdown-divider"),t.append(s)}}#y(e,t){const s=document.createElement("li");e.append(s);const o=document.createElement("button");o.classList.add("dropdown-item","rounded-2"),o.type="button",o.textContent=t.textContent,t.title&&(o.title=t.title),s.append(o);const i=document.createElement("small");i.textContent=t.dataset.subtext,t.selected&&!t.disabled&&o.classList.add("active"),(t.disabled||t.closest("optgroup")?.disabled)&&o.classList.add("disabled"),o.append(i),o.option=t,t.popoverItem=o;const n=this.#n.value.trim().toLowerCase();n&&this.#f(o,n)}#m(){const e=this.#n.value.trim().toLowerCase();for(const t of this.#o.querySelectorAll("li:not(:has(.dropdown-divider, .dropdown-header)) .dropdown-item")){let s=!1;t.childNodes[0].textContent!==t.option.textContent&&(t.childNodes[0].textContent=t.option.textContent,s=!0);let o=t.querySelector("small");t.option.dataset.subtext&&o.textContent!==t.option.dataset.subtext&&(o.textContent=t.option.dataset.subtext,s=!0),t.classList.remove("active"),s&&e&&this.#f(t,e)}for(const e of this.#s.selectedOptions)e.popoverItem.classList.add("active");this.#s.selectedOptions.length||(this.#s.querySelector("selectedcontent").textContent="0 selected")}#f(e,t){t=t.trim().toLowerCase();const s=e.option.textContent.trim().toLowerCase();let o=s.indexOf(t);o>=0&&Platypicker.#t.size<Platypicker.maxHighlights?(e.textHighlightRange||(e.textHighlightRange=new Range),e.textHighlightRange.setStart(e.childNodes[0],o),e.textHighlightRange.setEnd(e.childNodes[0],o+t.length),Platypicker.#t.add(e.textHighlightRange)):e.textHighlightRange&&(Platypicker.#t.delete(e.textHighlightRange),delete e.textHighlightRange);const i=e.option.dataset.subtext?.trim().toLowerCase();if(i&&i!==s)if(o=i.indexOf(t),o>=0&&Platypicker.#t.size<Platypicker.maxHighlights){e.subtextHighlightRange||(e.subtextHighlightRange=new Range);const s=e.querySelector("small").childNodes[0];e.subtextHighlightRange.setStart(s,o),e.subtextHighlightRange.setEnd(s,o+t.length),Platypicker.#t.add(e.subtextHighlightRange)}else e.subtextHighlightRange&&(Platypicker.#t.delete(e.subtextHighlightRange),delete e.subtextHighlightRange)}#L(e,t=!0){const s=e.trim().toLowerCase();if(!s){for(const e of this.#o.querySelectorAll("li .dropdown-item.d-none, li .dropdown-divider.d-none, li .dropdown-header.d-none"))e.classList.remove("d-none");return void(t&&Platypicker.#t?.clear())}t&&Platypicker.#t?.clear();let o=!1,i=null;for(const e of this.#o.querySelectorAll("li:not(:has(.dropdown-divider, .dropdown-header)) .dropdown-item")){const t=e.option.textContent.toLowerCase().trim(),n=e.option.dataset.subtext?.toLowerCase().trim()??"";e.option.closest("optgroup")&&e.option.closest("optgroup")===i||(o=!1),i=e.option.closest("optgroup"),t===s||n===s||t.includes(s)||n.includes(s)?(e.classList.remove("d-none"),i&&(o=!0,i.header.classList.remove("d-none"),i.divider?.classList.remove("d-none")),this.#f(e,s)):(e.classList.add("d-none"),i&&!o&&(o=!0,i.header.classList.add("d-none"),i.divider?.classList.add("d-none")),this.#f(e,s))}}static init(){this.#t=new Highlight,CSS.highlights.set("platypicker-highlight",this.#t);for(const e of document.querySelectorAll("select[data-toggle=platypicker]"))new Platypicker(e);new MutationObserver(e=>{for(const t of e){for(const e of t.addedNodes){if(!(e instanceof HTMLElement))continue;let t=[];"platypicker"===e.dataset?.toggle&&t.push(e),t.push(...e.querySelectorAll("[data-toggle=platypicker]"));for(const e of t)this.#e.has(e)||new Platypicker(e)}for(const e of t.removedNodes){if(!(e instanceof HTMLElement))continue;let t=[];"platypicker"===e.dataset?.toggle&&t.push(e),t.push(...e.querySelectorAll("[data-toggle=platypicker]"));for(const e of t)Platypicker.get(e)?.#E()}}}).observe(document,{childList:!0,subtree:!0})}#E(){Platypicker.#e.has(this.#s)&&(this.#s.removeEventListener("change",this.#c),this.#s.removeEventListener("click",this.#a),this.#s.removeEventListener("keydown",this.#d),document.removeEventListener("click",this.#h),document.removeEventListener("click",this.#p),this.#r.disconnect(),this.#s.classList.remove("platypicker"),this.#s.parentElement.classList.remove("dropdown"),this.#s.removeAttribute("data-bs-toggle"),this.#o.remove(),Platypicker.#e.delete(this.#s),this.#s=null,this.#o=null,this.#i=null,this.#n=null,this.#l=null,this.#r=null,this.#h=null,this.#p=null)}static#b(e,t=50,s){let o;return function(){const i=this,n=arguments,l=s&&!o;clearTimeout(o),o=window.setTimeout(function(){o=null,s||e.apply(i,n)},t),l&&e.apply(i,n)}}}Platypicker.init();
package/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "platypicker",
3
+ "version": "0.0.0",
4
+ "private": false,
5
+ "main": "dist/platypicker.min.js",
6
+ "files": ["dist"],
7
+ "repository": "https://github.com/Emberfire/UIComponents.git",
8
+ "exports": {
9
+ ".": "./dist/platypicker.min.js"
10
+ }
11
+ }