@crowdstrike/glide-core 0.10.0 → 0.12.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.
Files changed (62) hide show
  1. package/dist/checkbox-group.d.ts +3 -0
  2. package/dist/checkbox-group.js +43 -1
  3. package/dist/checkbox-group.styles.js +12 -0
  4. package/dist/checkbox-group.test.validity.js +69 -0
  5. package/dist/checkbox.d.ts +3 -1
  6. package/dist/checkbox.js +135 -1
  7. package/dist/checkbox.styles.js +12 -0
  8. package/dist/checkbox.test.events.js +9 -0
  9. package/dist/checkbox.test.validity.js +77 -1
  10. package/dist/dropdown.d.ts +3 -0
  11. package/dist/dropdown.js +195 -1
  12. package/dist/dropdown.option.d.ts +1 -0
  13. package/dist/dropdown.option.js +1 -1
  14. package/dist/dropdown.option.test.events.js +9 -1
  15. package/dist/dropdown.option.test.interactions.single.js +2 -2
  16. package/dist/dropdown.styles.js +18 -6
  17. package/dist/dropdown.test.basics.d.ts +1 -1
  18. package/dist/dropdown.test.basics.js +19 -1
  19. package/dist/dropdown.test.basics.multiple.js +2 -1
  20. package/dist/dropdown.test.events.filterable.js +13 -2
  21. package/dist/dropdown.test.events.single.js +19 -0
  22. package/dist/dropdown.test.form.multiple.js +3 -2
  23. package/dist/dropdown.test.interactions.filterable.js +20 -0
  24. package/dist/dropdown.test.interactions.js +20 -14
  25. package/dist/dropdown.test.interactions.multiple.js +24 -10
  26. package/dist/dropdown.test.interactions.single.js +32 -0
  27. package/dist/dropdown.test.validity.js +172 -1
  28. package/dist/input.d.ts +4 -0
  29. package/dist/input.js +155 -1
  30. package/dist/input.styles.js +8 -0
  31. package/dist/input.test.validity.js +140 -62
  32. package/dist/menu.d.ts +2 -0
  33. package/dist/menu.js +1 -1
  34. package/dist/menu.test.basics.d.ts +1 -1
  35. package/dist/menu.test.basics.js +12 -27
  36. package/dist/menu.test.interactions.js +90 -0
  37. package/dist/radio-group.d.ts +3 -0
  38. package/dist/radio-group.js +45 -1
  39. package/dist/radio-group.styles.js +12 -0
  40. package/dist/radio-group.test.validity.js +82 -0
  41. package/dist/styles/variables.css +1 -1
  42. package/dist/tab.group.d.ts +1 -0
  43. package/dist/tab.group.js +1 -1
  44. package/dist/tab.group.styles.js +6 -0
  45. package/dist/tag.d.ts +1 -2
  46. package/dist/tag.js +1 -1
  47. package/dist/tag.styles.js +12 -3
  48. package/dist/tag.test.basics.js +1 -0
  49. package/dist/tag.test.interactions.js +8 -6
  50. package/dist/textarea.d.ts +3 -0
  51. package/dist/textarea.js +58 -2
  52. package/dist/textarea.styles.js +8 -0
  53. package/dist/textarea.test.events.js +0 -114
  54. package/dist/textarea.test.validity.js +64 -72
  55. package/dist/tooltip.d.ts +2 -1
  56. package/dist/tooltip.js +1 -1
  57. package/dist/tooltip.styles.js +2 -1
  58. package/dist/tree.item.menu.d.ts +1 -0
  59. package/dist/tree.item.menu.js +1 -1
  60. package/dist/tree.item.menu.test.basics.js +22 -1
  61. package/dist/tree.item.styles.js +3 -6
  62. package/package.json +1 -1
package/dist/dropdown.js CHANGED
@@ -1 +1,195 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,l){var s,o=arguments.length,n=o<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,i):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,l);else for(var a=e.length-1;a>=0;a--)(s=e[a])&&(n=(o<3?s(n):o>3?s(t,i,n):s(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n};import"./checkbox.js";import"./dropdown.option.js";import"./label.js";import"./tooltip.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.js";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{repeat}from"lit/directives/repeat.js";import{when}from"lit/directives/when.js";import GlideCoreDropdownOption from"./dropdown.option.js";import GlideCoreTag from"./tag.js";import magnifyingGlassIcon from"./icons/magnifying-glass.js";import ow,{owSlotType}from"./library/ow.js";import styles from"./dropdown.styles.js";let GlideCoreDropdown=class GlideCoreDropdown extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get disabled(){return this.#e}set disabled(e){this.#e=e,this.open&&e?this.#t():this.open&&this.#i()}get filterable(){return this.#l}set filterable(e){this.#l!==e&&e&&!this.multiple?setTimeout((()=>{this.updateComplete.then((()=>{this.#s.value&&this.selectedOptions.length>0&&(this.#s.value.value=this.#s.value.value=this.selectedOptions[0].label)}))})):this.#l!==e&&this.#o(),this.#l=e}get open(){return this.#n}set open(e){this.#n=e,e&&!this.disabled?this.#i():!this.multiple&&this.#s.value&&this.selectedOptions.length>0?(this.#s.value.value=this.selectedOptions[0].label,this.isFiltering=!1,this.isShowSingleSelectIcon=!this.multiple&&this.selectedOptions.length>0&&Boolean(this.selectedOptions.at(0)?.value),this.#t()):this.#t()}get size(){return this.#a}set size(e){if(this.#a=e,this.#r)for(const t of this.#r)t.privateSize=e}get multiple(){return this.#d}set multiple(e){const t=this.#d&&!e,i=!this.#d&&e;this.#d=e,this.isShowSingleSelectIcon=!1;for(const i of this.#p)i.privateMultiple=e,t&&i!==this.lastSelectedOption&&(i.selected=!1);t&&this.lastSelectedOption?.value?this.value=[this.lastSelectedOption.value]:i&&this.lastSelectedOption&&(this.lastSelectedOption.privateUpdateCheckbox(),this.#h())}get value(){return this.#c}set value(e){this.#c=e,ow(this.multiple||!this.multiple&&e.length<=1,ow.boolean.true.message("Only one value is allowed when not `multiple`."));for(const t of this.#p)t.selected=e.some((e=>e&&e===t.value))}get activeOption(){return this.#r?.find((({privateActive:e})=>e))}checkValidity(){this.isCheckingValidity=!0;const e=this.#u.checkValidity();return this.isCheckingValidity=!1,e}click(){this.#s.value?(this.#s.value.click(),this.#s.value.select()):this.#m.value?.click()}get selectedOptions(){return this.#p.filter((e=>e instanceof GlideCoreDropdownOption&&e.selected))}get lastSelectedOption(){return this.#p.findLast((e=>e.selected))}get isAllSelected(){return this.#p.filter((({selected:e})=>e)).length===this.#p.length}get isSomeSelected(){return this.#p.some((({selected:e})=>e))}get internalLabel(){const e=this.filterable||this.isFilterable;return e||0!==this.selectedOptions.length?this.multiple||e||!this.selectedOptions.at(-1)?.label?"":this.selectedOptions.at(-1)?.label:this.placeholder}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#f,{capture:!0})}createRenderRoot(){return this.#v=super.createRenderRoot(),this.#v}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#g),document.removeEventListener("click",this.#f,{capture:!0})}firstUpdated(){owSlotType(this.#w.value,[GlideCoreDropdownOption,Text]),this.#b.value&&(this.#b.value.popover="manual"),this.open&&!this.disabled&&this.#i();const e=new ResizeObserver((()=>{this.#h()}));this.#E.value&&(e.observe(this.#E.value),this.#E.value.addEventListener("mouseup",(()=>{this.#O=!0})))}focus(e){this.filterable||this.isFilterable?this.#s.value?.focus(e):this.#m.value?.focus(e)}get form(){return this.#u.form}get validity(){return this.required&&0===this.selectedOptions.length?this.#u.setValidity({valueMissing:!0}," ",this.#s.value):this.#u.setValidity({}),this.#u.validity}get willValidate(){return this.#u.willValidate}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#g)}formResetCallback(){for(const e of this.#p){e.hasAttribute("selected")||(e.selected=!1)}const e=this.#p.filter((e=>e.hasAttribute("selected"))),t=e.at(-1)?.value;this.#c=this.multiple&&e.length>0?e.map((({value:e})=>e)):!this.multiple&&t?[t]:[]}render(){return html`<div class="${classMap({component:!0,horizontal:"horizontal"===this.orientation,vertical:"vertical"===this.orientation})}" @blur="${this.#y}" ${ref(this.#E)}><glide-core-private-label orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?error="${this.#R}" ?hide="${this.hideLabel}" ?required="${this.required}" @blur="${this.#y}"><label id="label">${this.label}</label><slot name="tooltip" slot="tooltip"></slot><div class="dropdown-and-options" slot="control" @focusout="${this.#S}" @keydown="${this.#A}"><div class="${classMap({dropdown:!0,quiet:"quiet"===this.variant,disabled:this.disabled,error:this.#R,readonly:this.readonly,multiple:this.multiple})}" @click="${this.#C}" @mousedown="${this.#D}" ${ref(this.#$)}><span class="selected-option-labels" id="selected-option-labels">${this.selectedOptions.filter((({label:e})=>"string"==typeof e)).map((({label:e})=>html`<span data-test="selected-option-label">${e},</span>`))} </span>${when(this.multiple&&this.selectedOptions.length>0,(()=>html`<ul aria-describedby="tag-overflow-text" class="tags" ${ref(this.#k)}>${repeat(this.selectedOptions,(({id:e})=>e),(({id:e,label:t,value:i},l)=>html`<li class="${classMap({"tag-container":!0,hidden:l>this.tagOverflowLimit-1})}" data-test="tag-container" data-test-hidden="${l>this.tagOverflowLimit-1}"><glide-core-tag data-test="tag" data-id="${e}" label="${t}" removable size="${this.size}" @remove="${this.#_.bind(this,e)}">${when(i,(()=>html`<slot data-test="multiselect-icon-slot" name="icon:${i}" slot="icon"></slot>`))}</glide-core-tag></li>`))}</ul>`))} ${when(this.isShowSingleSelectIcon,(()=>html`<slot class="${classMap({"single-select-icon-slot":!0,quiet:"quiet"===this.variant})}" data-test="single-select-icon-slot" name="icon:${this.selectedOptions.at(0)?.value}"></slot>`))} ${when(this.filterable||this.isFilterable,(()=>html`<input aria-activedescendant="${this.ariaActivedescendant}" aria-controls="options" aria-describedby="description" aria-expanded="${this.open}" aria-labelledby="selected-option-labels label" autocapitalize="off" autocomplete="off" class="input" data-test="input" id="input" placeholder="${this.multiple||!this.selectedOptions.at(-1)?.label?this.placeholder??"":""}" role="combobox" spellcheck="false" tabindex="${this.disabled?"-1":"0"}" ?disabled="${this.disabled}" ?readonly="${this.readonly}" @focusin="${this.#F}" @input="${this.#G}" @keydown="${this.#L}" ${ref(this.#s)}>`))} ${when(this.internalLabel,(()=>html`<div class="internal-label" data-test="internal-label">${when(this.internalLabel===this.placeholder,(()=>html`<span class="${classMap({placeholder:!0,disabled:this.disabled,quiet:"quiet"===this.variant})}">${this.internalLabel}</span>`),(()=>this.internalLabel))}</div>`))}<div class="tag-overflow-text-and-button">${when(this.multiple&&this.selectedOptions.length>this.tagOverflowLimit,(()=>html`<div aria-hidden="true" class="tag-overflow-text" id="tag-overflow-text" data-test="tag-overflow-text">+ <span data-test="tag-overflow-count">${this.selectedOptions.length-this.tagOverflowLimit} </span>more</div>`))} <button aria-expanded="${this.open}" aria-haspopup="listbox" aria-hidden="${this.filterable||this.isFilterable}" aria-labelledby="selected-option-labels label" aria-describedby="description" aria-controls="options" class="button" data-test="button" id="button" tabindex="${this.filterable||this.isFilterable||this.disabled?"-1":"0"}" type="button" ${ref(this.#m)}>${when(this.isFiltering,(()=>html`<div data-test="magnifying-glass-icon">${magnifyingGlassIcon}</div>`),(()=>html`<svg aria-label="${this.#I.term("open")}" width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`))}</button></div></div><div aria-labelledby="${this.filterable||this.isFilterable?"input":"button"}" class="${classMap({options:!0,hidden:this.isOptionsHidden,[this.size]:!0})}" data-test="options" id="options" role="listbox" @click="${this.#T}" @input="${this.#V}" @focusin="${this.#z}" @mousedown="${this.#x}" @mouseover="${this.#N}" @private-selected-change="${this.#H}" @private-value-change="${this.#M}" ${ref(this.#b)}><glide-core-dropdown-option class="select-all" data-test="select-all" label="${this.#I.term("selectAll")}" private-size="${this.size}" private-multiple ?hidden="${!this.selectAll||!this.multiple||this.isFiltering}" ?private-indeterminate="${this.isSomeSelected&&!this.isAllSelected}" ${ref(this.#j)}></glide-core-dropdown-option><slot @slotchange="${this.#B}" ${ref(this.#w)}></slot></div></div><slot id="description" name="description" slot="description"></slot></glide-core-private-label></div>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#u.reportValidity();return this.requestUpdate(),e}constructor(){super(),this.hideLabel=!1,this.name="",this.orientation="horizontal",this.readonly=!1,this.selectAll=!1,this.required=!1,this.ariaActivedescendant="",this.isBlurring=!1,this.isCheckingValidity=!1,this.isFilterable=!1,this.isFiltering=!1,this.isOptionsHidden=!1,this.isReportValidityOrSubmit=!1,this.isShowSingleSelectIcon=!1,this.tagOverflowLimit=0,this.#m=createRef(),this.#E=createRef(),this.#w=createRef(),this.#$=createRef(),this.#s=createRef(),this.#O=!1,this.#e=!1,this.#l=!1,this.#d=!1,this.#n=!1,this.#U=!1,this.#q=!1,this.#P=!1,this.#K=!1,this.#I=new LocalizeController(this),this.#b=createRef(),this.#j=createRef(),this.#a="large",this.#k=createRef(),this.#c=[],this.#f=()=>{this.#O?setTimeout((()=>{this.#O=!1})):this.open=!1},this.#g=({formData:e})=>{this.name&&this.value.length>0&&!this.disabled&&e.append(this.name,JSON.stringify(this.value))},this.#u=this.attachInternals(),this.addEventListener("invalid",(e=>{if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#m;#W;#E;#w;#$;#s;#u;#O;#e;#l;#d;#n;#U;#q;#P;#K;#I;#b;#j;#v;#a;#k;#c;#f;#g;#J(){if(this.#r)for(const e of this.#r)e.privateActive=!1}#t(){this.#W?.(),this.#b.value?.hidePopover(),this.ariaActivedescendant=""}get#R(){return this.required&&!this.disabled&&!this.validity.valid&&this.isReportValidityOrSubmit}#y(){this.isBlurring=!0,this.reportValidity(),this.isBlurring=!1}#B(){owSlotType(this.#w.value,[GlideCoreDropdownOption,Text]),this.isFilterable=this.#p.length>10,this.tagOverflowLimit=this.selectedOptions.length;for(const e of this.#p)e.privateSize=this.size,e.privateMultiple=this.multiple;const e=this.#Q?.at(0);this.lastSelectedOption?(this.#J(),this.lastSelectedOption.privateActive=!0,this.ariaActivedescendant=this.open?this.lastSelectedOption.id:""):e&&(this.#J(),e.privateActive=!0,this.ariaActivedescendant=this.open?e.id:""),this.#j.value&&(this.#j.value.selected=this.isAllSelected),this.multiple?this.#c=this.selectedOptions.filter((e=>Boolean(e.value))).map((({value:e})=>e)):this.lastSelectedOption?.value&&(this.#c=[this.lastSelectedOption.value]),this.requestUpdate(),this.updateComplete.then((()=>{!this.multiple&&this.#s.value&&this.lastSelectedOption?.value&&(this.#s.value.value=this.lastSelectedOption.label)}))}#S(e){(null===e.relatedTarget||e.relatedTarget instanceof Node&&!this.#v?.contains(e.relatedTarget)&&!this.contains(e.relatedTarget))&&!this.#q&&(this.open=!1),this.#y()}#A(e){if(this.disabled||this.readonly)return;if(!this.open&&"Enter"===e.key)return void this.form?.requestSubmit();if("Escape"===e.key)return this.open=!1,void this.focus();const t=e.target===this.#m.value||e.target===this.#s.value||e.target instanceof GlideCoreDropdownOption;if(!this.multiple||t){if(!this.open&&[" ","ArrowUp","ArrowDown"].includes(e.key)&&this.activeOption)return e.preventDefault(),void(this.open=!0);if(this.activeOption&&this.open){if(("Enter"===e.key||" "===e.key)&&(this.#K=!0,"Enter"===e.key&&this.#X&&this.#X.length>0||" "===e.key&&!this.filterable&&!this.isFilterable))return e.preventDefault(),this.isFiltering=!1,this.activeOption.selected=!this.multiple||!this.activeOption.selected,this.activeOption===this.#j.value&&this.#Y(),this.#o(),this.multiple||(this.open=!1),this.dispatchEvent(new Event("change",{bubbles:!0})),void this.dispatchEvent(new Event("input",{bubbles:!0}));const t=this.#Q?.indexOf(this.activeOption);if("ArrowUp"===e.key&&!e.metaKey&&this.#Q&&"number"==typeof t){e.preventDefault();const i=this.#Q.at(t-1);return void(i&&0!==t&&(this.#J(),i.privateActive=!0,i.scrollIntoView({block:"center"}),this.ariaActivedescendant=i.id))}if("ArrowDown"===e.key&&!e.metaKey&&this.#Q&&"number"==typeof t){e.preventDefault();const i=this.#Q.at(t+1);return void(i&&(this.#J(),i.privateActive=!0,i.scrollIntoView({block:"center"}),this.ariaActivedescendant=i.id))}if(("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key)&&this.#Q){e.preventDefault();const t=this.#Q.at(0);return void(t&&(this.#J(),t.privateActive=!0,t.scrollIntoView({block:"end"}),this.ariaActivedescendant=t.id))}if(("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key)&&this.#Q){e.preventDefault();const t=this.#Q.at(-1);return void(t&&(this.#J(),t.privateActive=!0,t.scrollIntoView(),this.ariaActivedescendant=t.id))}}}}#C(e){this.disabled||this.readonly||(this.#q?this.#q=!1:e.target instanceof Node&&this.#m.value?.contains(e.target)&&!this.#K&&this.open?this.open=!1:0!==e.detail&&(this.open=!0,this.focus()))}#D(e){const t=this.filterable||this.isFilterable,i=e.target instanceof GlideCoreTag;t&&!i?e.target!==this.#s.value&&(e.preventDefault(),this.focus()):i||e.preventDefault()}get#p(){return this.#w.value?.assignedElements().filter((e=>e instanceof GlideCoreDropdownOption))??[]}get#r(){const e=this.#w.value?.assignedElements().filter((e=>e instanceof GlideCoreDropdownOption));if(e&&this.#j.value)return[this.#j.value,...e]}get#X(){return this.#w.value?.assignedElements().filter((e=>e instanceof GlideCoreDropdownOption&&!e.hidden))}get#Q(){const e=this.#w.value?.assignedElements().filter((e=>e instanceof GlideCoreDropdownOption&&!e.hidden));return this.#j.value&&!this.#j.value.hidden&&e?[this.#j.value,...e]:e}#F(){this.#s.value?.select()}#G(e){if(ow(this.#s.value,ow.object.instanceOf(HTMLInputElement)),e.stopPropagation(),this.multiple&&""!==this.#s.value.value?this.isFiltering=!0:this.multiple?this.isFiltering=!1:""!==this.#s.value.value&&this.#s.value.value!==this.selectedOptions.at(0)?.label?this.isFiltering=!0:this.isFiltering=!1,this.isShowSingleSelectIcon=!1,this.activeOption){this.ariaActivedescendant=this.activeOption.id;for(const e of this.#p)e.hidden=!e.label?.toLowerCase().includes(this.#s.value?.value.toLowerCase().trim());const e=this.#X?.at(0);e&&this.activeOption?.hidden&&(this.#J(),e.privateActive=!0),this.open=!0,this.isOptionsHidden=!this.#X||0===this.#X.length}}#L(e){const t=this.selectedOptions.filter(((e,t)=>t<=this.tagOverflowLimit-1)).at(-1);if(t&&"Backspace"===e.key&&!e.metaKey&&this.multiple&&this.#s.value&&0===this.#s.value.selectionStart)return void(t.selected=!1);const i=this.selectedOptions.filter(((e,t)=>t<=this.tagOverflowLimit-1));if(t&&"Backspace"===e.key&&e.metaKey&&this.multiple&&this.#s.value&&0===this.#s.value.selectionStart)for(const e of i)e.selected=!1;else;}#T(e){if(e.target instanceof Element){const t=e.target.closest("glide-core-dropdown-option");t instanceof GlideCoreDropdownOption&&!t.selected&&(t.selected=!0,this.#o(),this.multiple||this.#t(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new Event("input",{bubbles:!0})))}}#z(e){e.target instanceof GlideCoreDropdownOption&&(this.#J(),e.target.privateActive=!0)}#V(e){e.stopPropagation(),e.target instanceof GlideCoreDropdownOption&&(e.target.selected=!e.target.selected),e.target===this.#j.value&&this.#Y(),this.#o(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new Event("input",{bubbles:!0}))}#x(e){(this.filterable||this.isFilterable)&&e.preventDefault()}#N(e){if(e.target instanceof GlideCoreDropdownOption&&this.#Q){this.#J(),e.target.privateActive=!0;for(const e of this.#Q)e.privateActive&&(this.ariaActivedescendant=e.id)}}#H(e){e.target!==this.#j.value&&!this.#P&&this.#j.value&&(this.#j.value.selected=this.isAllSelected),this.isFiltering=!1,this.isShowSingleSelectIcon=!this.multiple&&this.selectedOptions.length>0&&Boolean(this.selectedOptions.at(0)?.value),e.target instanceof GlideCoreDropdownOption&&(this.multiple?(this.#c=e.target.selected&&e.target.value?[...this.value,e.target.value]:this.value.filter((t=>e.target instanceof GlideCoreDropdownOption&&t!==e.target.value)),this.#s.value&&(this.#s.value.value=""),this.#h()):!this.multiple&&e.target.selected&&(this.#c=e.target.value?[e.target.value]:[],this.#s.value&&(this.#s.value.value=e.target.label))),this.requestUpdate()}#M(e){e.target instanceof GlideCoreDropdownOption&&this.multiple&&e.target.selected&&e.detail.new?this.#c=this.value.map((t=>t===e.detail.old?e.detail.new:t)):e.target instanceof GlideCoreDropdownOption&&this.multiple?this.#c=this.value.filter((t=>t!==e.detail.old)):e.target instanceof GlideCoreDropdownOption&&(this.#c=e.detail.new?[e.detail.new]:[])}async#_(e){this.#q=!0;for(const t of this.#p)t.id===e&&(t.selected=!1,this.#c=this.value.filter((e=>e!==t.value)));const t=this.#k.value?.querySelectorAll("glide-core-tag");if(t&&this.value.length>0){const i=[...t].findIndex((t=>t.dataset.id===e));await this.updateComplete,t[i<t.length-1?i+1:i-1]?.focus()}else this.focus();this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new Event("input",{bubbles:!0}))}#Y(){ow(this.#j.value,ow.object.instanceOf(GlideCoreDropdownOption)),this.#P=!0;for(const e of this.#p)e.selected=this.#j.value.selected;this.#P=!1}async#h(){if(this.#E.value){const e=this.#E.value.scrollWidth>this.#E.value.clientWidth;e&&this.tagOverflowLimit>1?(this.tagOverflowLimit=this.tagOverflowLimit-1,await this.updateComplete,this.#h()):!e&&!this.#U&&this.tagOverflowLimit<this.selectedOptions.length?(this.tagOverflowLimit=this.tagOverflowLimit+1,this.#U=!0,await this.updateComplete,this.#h()):this.#U=!1}}#i(){this.#W?.(),this.#$.value&&this.#b.value&&(this.#W=autoUpdate(this.#$.value,this.#b.value,(()=>{(async()=>{if(this.#$.value&&this.#b.value){const{x:e,y:t,placement:i}=await computePosition(this.#$.value,this.#b.value,{placement:"bottom-start",middleware:[offset({mainAxis:Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}),flip()]});this.#b.value.dataset.placement=i,Object.assign(this.#b.value.style,{left:`${e}px`,top:`${t}px`}),this.#b.value?.showPopover(),this.activeOption&&(this.ariaActivedescendant=this.activeOption.id)}})()})))}#o(){if((this.filterable||this.isFilterable)&&this.#s.value){this.isFiltering=!1;for(const e of this.#p)e.hidden=!1}}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"disabled",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"filterable",null),__decorate([property({attribute:"hide-label",reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"name",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"orientation",void 0),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"placeholder",void 0),__decorate([property()],GlideCoreDropdown.prototype,"privateSplit",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"readonly",void 0),__decorate([property({attribute:"select-all",reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"selectAll",void 0),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"size",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"multiple",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"required",void 0),__decorate([property({type:Array})],GlideCoreDropdown.prototype,"value",null),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"variant",void 0),__decorate([state()],GlideCoreDropdown.prototype,"ariaActivedescendant",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isFilterable",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isFiltering",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isOptionsHidden",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isReportValidityOrSubmit",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isShowSingleSelectIcon",void 0),__decorate([state()],GlideCoreDropdown.prototype,"tagOverflowLimit",void 0),GlideCoreDropdown=__decorate([customElement("glide-core-dropdown")],GlideCoreDropdown);export default GlideCoreDropdown;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,l){var s,o=arguments.length,n=o<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,i):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,l);else for(var a=e.length-1;a>=0;a--)(s=e[a])&&(n=(o<3?s(n):o>3?s(t,i,n):s(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n};import"./checkbox.js";import"./dropdown.option.js";import"./label.js";import"./tooltip.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.js";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{repeat}from"lit/directives/repeat.js";import{unsafeHTML}from"lit/directives/unsafe-html.js";import{when}from"lit/directives/when.js";import GlideCoreDropdownOption from"./dropdown.option.js";import GlideCoreTag from"./tag.js";import magnifyingGlassIcon from"./icons/magnifying-glass.js";import ow,{owSlotType}from"./library/ow.js";import styles from"./dropdown.styles.js";let GlideCoreDropdown=class GlideCoreDropdown extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get disabled(){return this.#e}set disabled(e){this.#e=e,this.open&&e?this.#t():this.open&&this.#i()}get filterable(){return this.#l}set filterable(e){this.#l!==e&&e&&!this.multiple?setTimeout((()=>{this.updateComplete.then((()=>{this.#s.value&&this.selectedOptions.length>0&&(this.#s.value.value=this.selectedOptions[0].label)}))})):this.#l!==e&&this.#o(),this.#l=e}get open(){return this.#n}set open(e){this.#n=e,!e||this.disabled?(!this.multiple&&this.#s.value&&this.selectedOptions.length>0&&(this.#s.value.value=this.selectedOptions[0].label,this.isFiltering=!1,this.isShowSingleSelectIcon=!this.multiple&&this.selectedOptions.length>0&&Boolean(this.selectedOptions.at(0)?.value)),this.#t(),this.activeOption&&(this.activeOption.privateIsOpenTooltip=!1)):this.#i()}get size(){return this.#a}set size(e){if(this.#a=e,this.#r)for(const t of this.#r)t.privateSize=e}get multiple(){return this.#d}set multiple(e){const t=this.#d&&!e,i=!this.#d&&e;this.#d=e,this.isShowSingleSelectIcon=!1;for(const i of this.#p)i.privateMultiple=e,t&&i!==this.lastSelectedOption&&(i.selected=!1);t&&this.lastSelectedOption?.value?this.value=[this.lastSelectedOption.value]:i&&this.lastSelectedOption&&(this.lastSelectedOption.privateUpdateCheckbox(),this.#h())}get value(){return this.#c}set value(e){this.#c=e,ow(this.multiple||!this.multiple&&e.length<=1,ow.boolean.true.message("Only one value is allowed when not `multiple`."));for(const t of this.#p)t.selected=e.some((e=>e&&e===t.value))}get activeOption(){return this.#r?.find((({privateActive:e})=>e))}checkValidity(){this.isCheckingValidity=!0;const e=this.#u.checkValidity();return this.isCheckingValidity=!1,e}click(){this.#s.value?(this.#s.value.click(),this.#s.value.select()):this.#v.value?.click()}get selectedOptions(){return this.#p.filter((e=>e instanceof GlideCoreDropdownOption&&e.selected))}get lastSelectedOption(){return this.#p.findLast((e=>e.selected))}get isAllSelected(){return this.#p.filter((({selected:e})=>e)).length===this.#p.length}get isSomeSelected(){return this.#p.some((({selected:e})=>e))}get internalLabel(){const e=this.filterable||this.isFilterable;return e||0!==this.selectedOptions.length?this.multiple||e||!this.selectedOptions.at(-1)?.label?"":this.selectedOptions.at(-1)?.label:this.placeholder}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#m,{capture:!0})}createRenderRoot(){return this.#f=super.createRenderRoot(),this.#f}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#g),document.removeEventListener("click",this.#m,{capture:!0})}firstUpdated(){owSlotType(this.#b.value,[GlideCoreDropdownOption,Text]),this.#w.value&&(this.#w.value.popover="manual"),this.open&&!this.disabled&&this.#i();const e=new ResizeObserver((()=>{this.#h()}));this.#E.value&&(e.observe(this.#E.value),this.#E.value.addEventListener("mouseup",(()=>{this.#O=!0})))}focus(e){this.filterable||this.isFilterable?this.#s.value?.focus(e):this.#v.value?.focus(e)}get form(){return this.#u.form}get validity(){return this.required&&0===this.selectedOptions.length?(this.#u.setValidity({customError:Boolean(this.validityMessage),valueMissing:!0}," ",this.filterable||this.isFilterable?this.#s.value:this.#v.value),this.#u.validity):this.required&&this.#u.validity.valueMissing&&this.selectedOptions.length>0?(this.#u.setValidity({}),this.#u.validity):this.#u.validity}get willValidate(){return this.#u.willValidate}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#g)}formResetCallback(){for(const e of this.#p){e.hasAttribute("selected")||(e.selected=!1)}const e=this.#p.filter((e=>e.hasAttribute("selected"))),t=e.at(-1)?.value;this.#c=this.multiple&&e.length>0?e.map((({value:e})=>e)):!this.multiple&&t?[t]:[]}render(){return html`<div
2
+ class=${classMap({component:!0,horizontal:"horizontal"===this.orientation,vertical:"vertical"===this.orientation})}
3
+ @blur=${this.#y}
4
+ ${ref(this.#E)}
5
+ >
6
+ <glide-core-private-label
7
+ orientation=${this.orientation}
8
+ split=${ifDefined(this.privateSplit??void 0)}
9
+ ?disabled=${this.disabled}
10
+ ?error=${this.#R}
11
+ ?hide=${this.hideLabel}
12
+ ?required=${this.required}
13
+ @blur=${this.#y}
14
+ >
15
+ <label id="label"> ${this.label} </label>
16
+ <slot name="tooltip" slot="tooltip"></slot>
17
+
18
+ <div
19
+ class="dropdown-and-options"
20
+ slot="control"
21
+ @focusout=${this.#S}
22
+ @keydown=${this.#C}
23
+ >
24
+ <div
25
+ class=${classMap({dropdown:!0,quiet:"quiet"===this.variant,disabled:this.disabled,error:this.#R,readonly:this.readonly,multiple:this.multiple})}
26
+ @click=${this.#A}
27
+ @mousedown=${this.#D}
28
+ ${ref(this.#$)}
29
+ >
30
+ <span class="selected-option-labels" id="selected-option-labels">
31
+ ${this.selectedOptions.filter((({label:e})=>"string"==typeof e)).map((({label:e})=>html`<span data-test="selected-option-label">
32
+ ${e},
33
+ </span>`))}
34
+ </span>
35
+
36
+ ${when(this.multiple&&this.selectedOptions.length>0,(()=>html`<ul
37
+ aria-describedby="tag-overflow-text"
38
+ class="tags"
39
+ ${ref(this.#k)}
40
+ >
41
+ ${repeat(this.selectedOptions,(({id:e})=>e),(({id:e,label:t,value:i},l)=>html`<li
42
+ class=${classMap({"tag-container":!0,hidden:l>this.tagOverflowLimit-1})}
43
+ data-test="tag-container"
44
+ data-test-hidden=${l>this.tagOverflowLimit-1}
45
+ >
46
+ <glide-core-tag
47
+ data-test="tag"
48
+ data-id=${e}
49
+ label=${t}
50
+ removable
51
+ size=${this.size}
52
+ @remove=${this.#F.bind(this,e)}
53
+ >
54
+ ${when(i,(()=>html`
55
+ <slot
56
+ data-test="multiselect-icon-slot"
57
+ name="icon:${i}"
58
+ slot="icon"
59
+ ></slot>
60
+ `))}
61
+ </glide-core-tag>
62
+ </li>`))}
63
+ </ul>`))}
64
+ ${when(this.isShowSingleSelectIcon,(()=>html`<slot
65
+ class=${classMap({"single-select-icon-slot":!0,quiet:"quiet"===this.variant})}
66
+ data-test="single-select-icon-slot"
67
+ name="icon:${this.selectedOptions.at(0)?.value}"
68
+ ></slot>`))}
69
+ ${when(this.filterable||this.isFilterable,(()=>html`<input
70
+ aria-activedescendant=${this.ariaActivedescendant}
71
+ aria-controls="options"
72
+ aria-describedby="description"
73
+ aria-expanded=${this.open}
74
+ aria-labelledby="selected-option-labels label"
75
+ autocapitalize="off"
76
+ autocomplete="off"
77
+ class="input"
78
+ data-test="input"
79
+ id="input"
80
+ placeholder=${this.multiple||!this.selectedOptions.at(-1)?.label?this.placeholder??"":""}
81
+ role="combobox"
82
+ spellcheck="false"
83
+ tabindex=${this.disabled?"-1":"0"}
84
+ ?disabled=${this.disabled}
85
+ ?readonly=${this.readonly}
86
+ @focusin=${this.#_}
87
+ @input=${this.#I}
88
+ @keydown=${this.#G}
89
+ ${ref(this.#s)}
90
+ />`))}
91
+ ${when(this.internalLabel,(()=>html`<div
92
+ class="internal-label"
93
+ data-test="internal-label"
94
+ >
95
+ ${when(this.internalLabel===this.placeholder,(()=>html`<span
96
+ class=${classMap({placeholder:!0,disabled:this.disabled,quiet:"quiet"===this.variant})}
97
+ >
98
+ ${this.internalLabel}
99
+ </span>`),(()=>this.internalLabel))}
100
+ </div>`))}
101
+
102
+ <div class="tag-overflow-text-and-button">
103
+ ${when(this.multiple&&this.selectedOptions.length>this.tagOverflowLimit,(()=>html`<div
104
+ aria-hidden="true"
105
+ class="tag-overflow-text"
106
+ id="tag-overflow-text"
107
+ data-test="tag-overflow-text"
108
+ >
109
+ +
110
+ <span data-test="tag-overflow-count">
111
+ ${this.selectedOptions.length-this.tagOverflowLimit}
112
+ </span>
113
+ more
114
+ </div>`))}
115
+
116
+ <button
117
+ aria-expanded=${this.open}
118
+ aria-haspopup="listbox"
119
+ aria-hidden=${this.filterable||this.isFilterable}
120
+ aria-labelledby="selected-option-labels label"
121
+ aria-describedby="description"
122
+ aria-controls="options"
123
+ class="button"
124
+ data-test="button"
125
+ id="button"
126
+ tabindex=${this.filterable||this.isFilterable||this.disabled?"-1":"0"}
127
+ type="button"
128
+ ${ref(this.#v)}
129
+ >
130
+ ${when(this.isFiltering,(()=>html`<div data-test="magnifying-glass-icon">
131
+ ${magnifyingGlassIcon}
132
+ </div>`),(()=>html`<svg
133
+ aria-label=${this.#L.term("open")}
134
+ width="16"
135
+ height="16"
136
+ viewBox="0 0 24 24"
137
+ fill="none"
138
+ >
139
+ <path
140
+ d="M6 9L12 15L18 9"
141
+ stroke="currentColor"
142
+ stroke-width="2"
143
+ stroke-linecap="round"
144
+ stroke-linejoin="round"
145
+ />
146
+ </svg>`))}
147
+ </button>
148
+ </div>
149
+ </div>
150
+
151
+ <div
152
+ aria-labelledby=${this.filterable||this.isFilterable?"input":"button"}
153
+ class=${classMap({options:!0,hidden:this.isOptionsHidden,[this.size]:!0})}
154
+ data-test="options"
155
+ id="options"
156
+ role="listbox"
157
+ @click=${this.#T}
158
+ @input=${this.#V}
159
+ @focusin=${this.#M}
160
+ @mousedown=${this.#z}
161
+ @mouseover=${this.#x}
162
+ @private-label-change=${this.#H}
163
+ @private-selected-change=${this.#N}
164
+ @private-value-change=${this.#B}
165
+ ${ref(this.#w)}
166
+ >
167
+ <glide-core-dropdown-option
168
+ class="select-all"
169
+ data-test="select-all"
170
+ label=${this.#L.term("selectAll")}
171
+ private-size=${this.size}
172
+ private-multiple
173
+ ?hidden=${!this.selectAll||!this.multiple||this.isFiltering}
174
+ ?private-indeterminate=${this.isSomeSelected&&!this.isAllSelected}
175
+ ${ref(this.#j)}
176
+ ></glide-core-dropdown-option>
177
+
178
+ <slot
179
+ @slotchange=${this.#U}
180
+ ${ref(this.#b)}
181
+ ></slot>
182
+ </div>
183
+ </div>
184
+
185
+ <div id="description" slot="description">
186
+ <slot
187
+ class=${classMap({description:!0,hidden:Boolean(this.#R&&this.validityMessage)})}
188
+ name="description"
189
+ ></slot>
190
+ ${when(this.#R&&this.validityMessage,(()=>html`<span class="validity-message" data-test="validity-message"
191
+ >${unsafeHTML(this.validityMessage)}</span
192
+ >`))}
193
+ </div>
194
+ </glide-core-private-label>
195
+ </div>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#u.reportValidity();return this.requestUpdate(),e}setCustomValidity(e){this.validityMessage=e,""===e?this.#u.setValidity({customError:!1},"",this.filterable||this.isFilterable?this.#s.value:this.#v.value):this.#u.setValidity({customError:!0,valueMissing:this.#u.validity.valueMissing}," ",this.filterable||this.isFilterable?this.#s.value:this.#v.value)}setValidity(e,t){this.validityMessage=t,this.#u.setValidity(e," ",this.filterable||this.isFilterable?this.#s.value:this.#v.value)}constructor(){super(),this.hideLabel=!1,this.name="",this.orientation="horizontal",this.readonly=!1,this.selectAll=!1,this.required=!1,this.ariaActivedescendant="",this.isBlurring=!1,this.isCheckingValidity=!1,this.isFilterable=!1,this.isFiltering=!1,this.isOptionsHidden=!1,this.isReportValidityOrSubmit=!1,this.isShowSingleSelectIcon=!1,this.tagOverflowLimit=0,this.#v=createRef(),this.#E=createRef(),this.#b=createRef(),this.#$=createRef(),this.#s=createRef(),this.#O=!1,this.#e=!1,this.#l=!1,this.#d=!1,this.#n=!1,this.#q=!1,this.#P=!1,this.#K=!1,this.#W=!1,this.#L=new LocalizeController(this),this.#w=createRef(),this.#j=createRef(),this.#a="large",this.#k=createRef(),this.#c=[],this.#m=()=>{this.#O?setTimeout((()=>{this.#O=!1})):this.open=!1},this.#g=({formData:e})=>{this.name&&this.value.length>0&&!this.disabled&&e.append(this.name,JSON.stringify(this.value))},this.#u=this.attachInternals(),this.addEventListener("invalid",(e=>{if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#v;#J;#E;#b;#$;#s;#u;#O;#e;#l;#d;#n;#q;#P;#K;#W;#L;#w;#j;#f;#a;#k;#c;#m;#g;#t(){this.#J?.(),this.#w.value?.hidePopover(),this.ariaActivedescendant=""}get#R(){return!this.disabled&&!this.validity.valid&&this.isReportValidityOrSubmit}#y(){this.isBlurring=!0,this.reportValidity(),this.isBlurring=!1}#U(){owSlotType(this.#b.value,[GlideCoreDropdownOption,Text]),this.isFilterable=this.#p.length>10,this.tagOverflowLimit=this.selectedOptions.length;for(const e of this.#p)e.privateSize=this.size,e.privateMultiple=this.multiple;const e=this.#Q?.at(0);!this.activeOption&&this.lastSelectedOption?(this.lastSelectedOption.privateActive=!0,this.ariaActivedescendant=this.open?this.lastSelectedOption.id:""):!this.activeOption&&e&&(e.privateActive=!0,this.ariaActivedescendant=this.open?e.id:""),this.#j.value&&(this.#j.value.selected=this.isAllSelected),this.multiple?this.#c=this.selectedOptions.filter((e=>Boolean(e.value))).map((({value:e})=>e)):this.lastSelectedOption?.value&&(this.#c=[this.lastSelectedOption.value]),this.requestUpdate(),this.updateComplete.then((()=>{!this.multiple&&this.#s.value&&this.lastSelectedOption?.value&&(this.#s.value.value=this.lastSelectedOption.label)}))}#S(e){(null===e.relatedTarget||e.relatedTarget instanceof Node&&!this.#f?.contains(e.relatedTarget)&&!this.contains(e.relatedTarget))&&!this.#P&&(this.open=!1),this.#y()}#C(e){if(this.disabled||this.readonly)return;if(!this.open&&"Enter"===e.key)return void this.form?.requestSubmit();if("Escape"===e.key)return this.open=!1,void this.focus();const t=e.target===this.#v.value||e.target===this.#s.value||e.target instanceof GlideCoreDropdownOption;if(!this.multiple||t){if(!this.open&&[" ","ArrowUp","ArrowDown"].includes(e.key)&&this.activeOption)return e.preventDefault(),this.open=!0,void(this.activeOption.privateIsOpenTooltip=!0);if(this.activeOption&&this.open){if(("Enter"===e.key||" "===e.key)&&(this.#W=!0,"Enter"===e.key&&this.#X&&this.#X.length>0||" "===e.key&&!this.filterable&&!this.isFilterable))return e.preventDefault(),this.isFiltering=!1,this.activeOption.selected=!this.multiple||!this.activeOption.selected,this.activeOption===this.#j.value&&this.#Y(),this.#o(),this.multiple||(this.open=!1),this.dispatchEvent(new Event("change",{bubbles:!0})),void this.dispatchEvent(new Event("input",{bubbles:!0}));const t=this.#Q?.indexOf(this.activeOption);if("ArrowUp"===e.key&&!e.metaKey&&this.#Q&&"number"==typeof t){e.preventDefault();const i=this.#Q.at(t-1);return void(i&&0!==t&&(this.activeOption.privateIsOpenTooltip=!1,this.activeOption.privateActive=!1,this.ariaActivedescendant=i.id,i.privateActive=!0,i.privateIsOpenTooltip=!0,i.scrollIntoView({block:"center"})))}if("ArrowDown"===e.key&&!e.metaKey&&this.#Q&&"number"==typeof t){e.preventDefault();const i=this.#Q.at(t+1);return void(i&&(this.activeOption.privateIsOpenTooltip=!1,this.activeOption.privateActive=!1,this.ariaActivedescendant=i.id,i.privateActive=!0,i.privateIsOpenTooltip=!0,i.scrollIntoView({block:"center"})))}if(("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key)&&this.#Q){e.preventDefault();const t=this.#Q.at(0);return void(t&&(this.activeOption.privateIsOpenTooltip=!1,this.activeOption.privateActive=!1,this.ariaActivedescendant=t.id,t.privateActive=!0,t.privateIsOpenTooltip=!0,t.scrollIntoView({block:"end"})))}if(("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key)&&this.#Q){e.preventDefault();const t=this.#Q.at(-1);return void(t&&this.activeOption&&(this.activeOption.privateIsOpenTooltip=!1,this.activeOption.privateActive=!1,this.ariaActivedescendant=t.id,t.privateActive=!0,t.privateIsOpenTooltip=!0,t.scrollIntoView()))}}}}#A(e){this.disabled||this.readonly||(this.#P?this.#P=!1:!this.#W&&this.open?this.open=!1:0!==e.detail&&(this.open=!0,this.focus()))}#D(e){const t=this.filterable||this.isFilterable,i=e.target instanceof GlideCoreTag;t&&!i?e.target!==this.#s.value&&(e.preventDefault(),this.focus()):i||e.preventDefault()}get#p(){return this.#b.value?.assignedElements().filter((e=>e instanceof GlideCoreDropdownOption))??[]}get#r(){const e=this.#b.value?.assignedElements().filter((e=>e instanceof GlideCoreDropdownOption));if(e&&this.#j.value)return[this.#j.value,...e]}get#X(){return this.#b.value?.assignedElements().filter((e=>e instanceof GlideCoreDropdownOption&&!e.hidden))}get#Q(){const e=this.#b.value?.assignedElements().filter((e=>e instanceof GlideCoreDropdownOption&&!e.hidden));return this.#j.value&&!this.#j.value.hidden&&e?[this.#j.value,...e]:e}#_(){this.#s.value?.select()}#I(e){if(ow(this.#s.value,ow.object.instanceOf(HTMLInputElement)),e.stopPropagation(),this.multiple&&""!==this.#s.value.value?this.isFiltering=!0:this.multiple?this.isFiltering=!1:""!==this.#s.value.value&&this.#s.value.value!==this.selectedOptions.at(0)?.label?this.isFiltering=!0:this.isFiltering=!1,this.isShowSingleSelectIcon=!1,this.activeOption){this.ariaActivedescendant=this.activeOption.id;for(const e of this.#p)e.hidden=!e.label?.toLowerCase().includes(this.#s.value?.value.toLowerCase().trim());const e=this.#X?.at(0);e&&this.activeOption?.hidden&&(this.activeOption.privateActive=!1,e.privateActive=!0),this.open=!0,this.isOptionsHidden=!this.#X||0===this.#X.length}this.dispatchEvent(new CustomEvent("filter",{bubbles:!0,detail:this.#s.value.value}))}#G(e){const t=this.selectedOptions.filter(((e,t)=>t<=this.tagOverflowLimit-1)).at(-1);if(t&&"Backspace"===e.key&&!e.metaKey&&this.multiple&&this.#s.value&&0===this.#s.value.selectionStart)return void(t.selected=!1);const i=this.selectedOptions.filter(((e,t)=>t<=this.tagOverflowLimit-1));if(t&&"Backspace"===e.key&&e.metaKey&&this.multiple&&this.#s.value&&0===this.#s.value.selectionStart)for(const e of i)e.selected=!1;else;}#T(e){if(e.target instanceof Element){const t=e.target.closest("glide-core-dropdown-option");if(t&&!t.selected)return t.selected=!0,this.#o(),this.multiple||(this.open=!1),this.dispatchEvent(new Event("change",{bubbles:!0})),void this.dispatchEvent(new Event("input",{bubbles:!0}));if(t?.selected&&!this.multiple)return void(this.open=!1)}}#M(e){e.target instanceof GlideCoreDropdownOption&&(this.activeOption&&(this.activeOption.privateActive=!1),e.target.privateActive=!0)}#V(e){e.stopPropagation(),e.target instanceof GlideCoreDropdownOption&&(e.target.selected=!e.target.selected),e.target===this.#j.value&&this.#Y(),this.#o(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new Event("input",{bubbles:!0}))}#H(){this.selectedOptions.length>0&&(this.multiple?(this.requestUpdate(),this.updateComplete.then((()=>{this.#h()}))):this.#s.value?this.#s.value.value=this.selectedOptions[0].label:this.requestUpdate())}#z(e){(this.filterable||this.isFilterable)&&e.preventDefault()}#x(e){if(e.target instanceof GlideCoreDropdownOption&&this.#Q&&this.activeOption){this.activeOption.privateIsOpenTooltip=!1,this.activeOption.privateActive=!1,e.target.privateActive=!0;for(const e of this.#Q)e.privateActive&&(this.ariaActivedescendant=e.id)}}#N(e){e.target!==this.#j.value&&!this.#K&&this.#j.value&&(this.#j.value.selected=this.isAllSelected),this.isFiltering=!1,this.isShowSingleSelectIcon=!this.multiple&&this.selectedOptions.length>0&&Boolean(this.selectedOptions.at(0)?.value),e.target instanceof GlideCoreDropdownOption&&(this.multiple?(this.#c=e.target.selected&&e.target.value?[...this.value,e.target.value]:this.value.filter((t=>e.target instanceof GlideCoreDropdownOption&&t!==e.target.value)),this.#s.value&&(this.#s.value.value=""),this.#h()):!this.multiple&&e.target.selected&&(this.#c=e.target.value?[e.target.value]:[],this.#s.value&&(this.#s.value.value=e.target.label))),this.requestUpdate()}#B(e){e.target instanceof GlideCoreDropdownOption&&this.multiple&&e.target.selected&&e.detail.new?this.#c=this.value.map((t=>t===e.detail.old?e.detail.new:t)):e.target instanceof GlideCoreDropdownOption&&this.multiple?this.#c=this.value.filter((t=>t!==e.detail.old)):e.target instanceof GlideCoreDropdownOption&&(this.#c=e.detail.new?[e.detail.new]:[])}async#F(e){this.#P=!0;for(const t of this.#p)t.id===e&&(t.selected=!1,this.#c=this.value.filter((e=>e!==t.value)));const t=this.#k.value?.querySelectorAll("glide-core-tag");if(t&&this.value.length>0){const i=[...t].findIndex((t=>t.dataset.id===e));await this.updateComplete,t[i<t.length-1?i+1:i-1]?.focus()}else this.focus();this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new Event("input",{bubbles:!0}))}#Y(){ow(this.#j.value,ow.object.instanceOf(GlideCoreDropdownOption)),this.#K=!0;for(const e of this.#p)e.selected=this.#j.value.selected;this.#K=!1}async#h(){if(this.#E.value){const e=this.#E.value.scrollWidth>this.#E.value.clientWidth;e&&this.tagOverflowLimit>1?(this.tagOverflowLimit=this.tagOverflowLimit-1,await this.updateComplete,this.#h()):!e&&!this.#q&&this.tagOverflowLimit<this.selectedOptions.length?(this.tagOverflowLimit=this.tagOverflowLimit+1,this.#q=!0,await this.updateComplete,this.#h()):this.#q=!1}}#i(){this.#J?.(),this.#$.value&&this.#w.value&&(this.#J=autoUpdate(this.#$.value,this.#w.value,(()=>{(async()=>{if(this.#$.value&&this.#w.value){const{x:e,y:t,placement:i}=await computePosition(this.#$.value,this.#w.value,{placement:"bottom-start",middleware:[offset({mainAxis:Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}),flip()]});this.#w.value.dataset.placement=i,Object.assign(this.#w.value.style,{left:`${e}px`,top:`${t}px`}),this.#w.value?.showPopover(),this.activeOption&&(this.ariaActivedescendant=this.activeOption.id)}})()})))}#o(){if((this.filterable||this.isFilterable)&&this.#s.value){this.isFiltering=!1;for(const e of this.#p)e.hidden=!1}}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"disabled",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"filterable",null),__decorate([property({attribute:"hide-label",reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"name",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"orientation",void 0),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"placeholder",void 0),__decorate([property()],GlideCoreDropdown.prototype,"privateSplit",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"readonly",void 0),__decorate([property({attribute:"select-all",reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"selectAll",void 0),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"size",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"multiple",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdown.prototype,"required",void 0),__decorate([property({type:Array})],GlideCoreDropdown.prototype,"value",null),__decorate([property({reflect:!0})],GlideCoreDropdown.prototype,"variant",void 0),__decorate([state()],GlideCoreDropdown.prototype,"ariaActivedescendant",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isFilterable",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isFiltering",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isOptionsHidden",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isReportValidityOrSubmit",void 0),__decorate([state()],GlideCoreDropdown.prototype,"isShowSingleSelectIcon",void 0),__decorate([state()],GlideCoreDropdown.prototype,"tagOverflowLimit",void 0),__decorate([state()],GlideCoreDropdown.prototype,"validityMessage",void 0),GlideCoreDropdown=__decorate([customElement("glide-core-dropdown")],GlideCoreDropdown);export default GlideCoreDropdown;
@@ -22,6 +22,7 @@ export default class GlideCoreDropdownOption extends LitElement {
22
22
  privateSize: 'small' | 'large';
23
23
  privateActive: boolean;
24
24
  private get isMultiple();
25
+ privateIsOpenTooltip: boolean;
25
26
  click(): void;
26
27
  connectedCallback(): void;
27
28
  disconnectedCallback(): void;
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,o){var l,s=arguments.length,r=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(l=e[a])&&(r=(s<3?l(r):s>3?l(t,i,r):l(t,i))||r);return s>3&&r&&Object.defineProperty(t,i,r),r};import"./checkbox.js";import"./tooltip.js";import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{nanoid}from"nanoid";import{when}from"lit/directives/when.js";import checkedIcon from"./icons/checked.js";import styles from"./dropdown.option.styles.js";let GlideCoreDropdownOption=class GlideCoreDropdownOption extends LitElement{constructor(){super(...arguments),this.privateIndeterminate=!1,this.privateMultiple=!1,this.privateSize="large",this.privateActive=!1,this.isLabelOverflow=!1,this.#e=createRef(),this.#t=createRef(),this.#i=nanoid(),this.#o="",this.#l=createRef(),this.#s=!1,this.#r=""}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get label(){return this.#o}set label(e){this.#o=e,setTimeout((()=>{this.#a()}))}get selected(){return this.#s}set selected(e){if(this.#s=e,this.ariaSelected=e.toString(),this.isMultiple)this.#e.value&&(this.#e.value.checked=e);else for(const e of this.#c)e!==this&&this.selected&&e.selected&&(e.selected=!1);this.dispatchEvent(new Event("private-selected-change",{bubbles:!0}))}get isMultiple(){return this.privateMultiple||this.closest("glide-core-dropdown")?.multiple}click(){this.privateMultiple?this.#e.value?.click():this.#t.value?.click()}connectedCallback(){super.connectedCallback(),this.id=this.#i,this.ariaSelected=this.selected.toString(),this.role="option",this.tabIndex=-1,this.#n=new IntersectionObserver((()=>{this.checkVisibility()&&this.#a()})),this.#n.observe(this)}disconnectedCallback(){super.disconnectedCallback(),this.#n?.disconnect()}firstUpdated(){this.#e.value&&(this.#e.value.checked=this.selected)}get value(){return this.#r}set value(e){this.dispatchEvent(new CustomEvent("private-value-change",{bubbles:!0,detail:{old:this.value,new:e}})),this.#r=e}async privateUpdateCheckbox(){await this.updateComplete,this.#e.value&&(this.#e.value.checked=this.selected)}render(){return html`<div class="${classMap({component:!0,active:this.privateActive,[this.privateSize]:!0})}" data-test="component" ${ref(this.#t)}>${when(this.isMultiple,(()=>html`<glide-core-checkbox class="${classMap({checkbox:!0,[this.privateSize]:!0})}" data-test="checkbox" label="${this.label??""}" tabindex="-1" private-label-tooltip-offset="${12}" private-size="${this.privateSize}" private-variant="minimal" value="${this.value}" internally-inert @click="${this.#p}" ?indeterminate="${this.privateIndeterminate}" ?private-show-label-tooltip="${this.privateActive}" ${ref(this.#e)}><slot class="icon-slot" data-test="icon-slot" name="icon" slot="private-icon"></slot></glide-core-checkbox>`),(()=>html`<div class="${classMap({option:!0,[this.privateSize]:!0})}"><slot class="icon-slot" name="icon"></slot><glide-core-tooltip class="tooltip" offset="${10}" ?disabled="${!this.isLabelOverflow}" ?open="${this.privateActive}"><div aria-hidden="true" data-test="tooltip">${this.label}</div><div class="label" data-test="label" slot="target" ${ref(this.#l)}>${this.label}</div></glide-core-tooltip><div class="${classMap({"checked-icon":!0,visible:this.selected})}">${checkedIcon}</div></div>`))}</div>`}#e;#t;#i;#n;#o;#l;#s;#r;get#c(){return[...this.closest("glide-core-dropdown")?.querySelectorAll("glide-core-dropdown-option")??[]]}#p(e){e.stopPropagation()}#a(){this.#l.value&&(this.isLabelOverflow=this.#l.value.scrollWidth>this.#l.value.clientWidth)}};__decorate([property({reflect:!0})],GlideCoreDropdownOption.prototype,"label",null),__decorate([property({attribute:"private-indeterminate",type:Boolean})],GlideCoreDropdownOption.prototype,"privateIndeterminate",void 0),__decorate([property({attribute:"private-multiple",type:Boolean})],GlideCoreDropdownOption.prototype,"privateMultiple",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdownOption.prototype,"selected",null),__decorate([property({attribute:"private-size",reflect:!0})],GlideCoreDropdownOption.prototype,"privateSize",void 0),__decorate([state()],GlideCoreDropdownOption.prototype,"privateActive",void 0),__decorate([state()],GlideCoreDropdownOption.prototype,"isMultiple",null),__decorate([property({reflect:!0})],GlideCoreDropdownOption.prototype,"value",null),__decorate([state()],GlideCoreDropdownOption.prototype,"isLabelOverflow",void 0),GlideCoreDropdownOption=__decorate([customElement("glide-core-dropdown-option")],GlideCoreDropdownOption);export default GlideCoreDropdownOption;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var l,s=arguments.length,r=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(l=e[a])&&(r=(s<3?l(r):s>3?l(t,i,r):l(t,i))||r);return s>3&&r&&Object.defineProperty(t,i,r),r};import"./checkbox.js";import"./tooltip.js";import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{nanoid}from"nanoid";import{when}from"lit/directives/when.js";import checkedIcon from"./icons/checked.js";import styles from"./dropdown.option.styles.js";let GlideCoreDropdownOption=class GlideCoreDropdownOption extends LitElement{constructor(){super(...arguments),this.privateIndeterminate=!1,this.privateMultiple=!1,this.privateSize="large",this.privateActive=!1,this.privateIsOpenTooltip=!1,this.isLabelOverflow=!1,this.#e=createRef(),this.#t=createRef(),this.#i=nanoid(),this.#o="",this.#l=createRef(),this.#s=!1,this.#r=""}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get label(){return this.#o}set label(e){this.#o=e,setTimeout((()=>{this.#a()})),this.dispatchEvent(new Event("private-label-change",{bubbles:!0}))}get selected(){return this.#s}set selected(e){if(this.#s=e,this.ariaSelected=e.toString(),this.isMultiple)this.#e.value&&(this.#e.value.checked=e);else for(const e of this.#n)e!==this&&this.selected&&e.selected&&(e.selected=!1);this.dispatchEvent(new Event("private-selected-change",{bubbles:!0}))}get isMultiple(){return this.privateMultiple||this.closest("glide-core-dropdown")?.multiple}click(){this.privateMultiple?this.#e.value?.click():this.#t.value?.click()}connectedCallback(){super.connectedCallback(),this.id=this.#i,this.ariaSelected=this.selected.toString(),this.role="option",this.tabIndex=-1,this.#c=new IntersectionObserver((()=>{this.checkVisibility()&&this.#a()})),this.#c.observe(this)}disconnectedCallback(){super.disconnectedCallback(),this.#c?.disconnect()}firstUpdated(){this.#e.value&&(this.#e.value.checked=this.selected)}get value(){return this.#r}set value(e){this.dispatchEvent(new CustomEvent("private-value-change",{bubbles:!0,detail:{old:this.value,new:e}})),this.#r=e}async privateUpdateCheckbox(){await this.updateComplete,this.#e.value&&(this.#e.value.checked=this.selected)}render(){return html`<div class="${classMap({component:!0,active:this.privateActive,[this.privateSize]:!0})}" data-test="component" ${ref(this.#t)}>${when(this.isMultiple,(()=>html`<glide-core-checkbox class="${classMap({checkbox:!0,[this.privateSize]:!0})}" data-test="checkbox" label="${this.label??""}" tabindex="-1" private-label-tooltip-offset="${12}" private-size="${this.privateSize}" private-variant="minimal" value="${this.value}" internally-inert @click="${this.#p}" ?indeterminate="${this.privateIndeterminate}" ?private-show-label-tooltip="${this.privateIsOpenTooltip}" ${ref(this.#e)}><slot class="icon-slot" data-test="icon-slot" name="icon" slot="private-icon"></slot></glide-core-checkbox>`),(()=>html`<div class="${classMap({option:!0,[this.privateSize]:!0})}"><slot class="icon-slot" name="icon"></slot><glide-core-tooltip class="tooltip" offset="${10}" ?disabled="${!this.isLabelOverflow}" ?open="${this.privateIsOpenTooltip}"><div aria-hidden="true" data-test="tooltip">${this.label}</div><div class="label" data-test="label" slot="target" ${ref(this.#l)}>${this.label}</div></glide-core-tooltip><div class="${classMap({"checked-icon":!0,visible:this.selected})}">${checkedIcon}</div></div>`))}</div>`}#e;#t;#i;#c;#o;#l;#s;#r;get#n(){return[...this.closest("glide-core-dropdown")?.querySelectorAll("glide-core-dropdown-option")??[]]}#p(e){e.stopPropagation()}#a(){this.#l.value&&(this.isLabelOverflow=this.#l.value.scrollWidth>this.#l.value.clientWidth)}};__decorate([property({reflect:!0})],GlideCoreDropdownOption.prototype,"label",null),__decorate([property({attribute:"private-indeterminate",type:Boolean})],GlideCoreDropdownOption.prototype,"privateIndeterminate",void 0),__decorate([property({attribute:"private-multiple",type:Boolean})],GlideCoreDropdownOption.prototype,"privateMultiple",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreDropdownOption.prototype,"selected",null),__decorate([property({attribute:"private-size",reflect:!0})],GlideCoreDropdownOption.prototype,"privateSize",void 0),__decorate([state()],GlideCoreDropdownOption.prototype,"privateActive",void 0),__decorate([state()],GlideCoreDropdownOption.prototype,"isMultiple",null),__decorate([state()],GlideCoreDropdownOption.prototype,"privateIsOpenTooltip",void 0),__decorate([property({reflect:!0})],GlideCoreDropdownOption.prototype,"value",null),__decorate([state()],GlideCoreDropdownOption.prototype,"isLabelOverflow",void 0),GlideCoreDropdownOption=__decorate([customElement("glide-core-dropdown-option")],GlideCoreDropdownOption);export default GlideCoreDropdownOption;
@@ -2,10 +2,18 @@
2
2
  import { expect, fixture, html, oneEvent } from '@open-wc/testing';
3
3
  import GlideCoreDropdownOption from './dropdown.option.js';
4
4
  GlideCoreDropdownOption.shadowRootOptions.mode = 'open';
5
+ it('dispatches a "private-label-change" event', async () => {
6
+ const component = await fixture(html `<glide-core-dropdown-option label="One"></glide-core-dropdown-option>`);
7
+ setTimeout(() => {
8
+ component.label = 'Two';
9
+ });
10
+ const event = await oneEvent(component, 'private-label-change');
11
+ expect(event instanceof Event).to.be.true;
12
+ expect(event.bubbles).to.be.true;
13
+ });
5
14
  it('dispatches a "private-selected-change" event', async () => {
6
15
  const component = await fixture(html `<glide-core-dropdown-option
7
16
  label="Label"
8
- value="value"
9
17
  ></glide-core-dropdown-option>`);
10
18
  setTimeout(() => {
11
19
  component.selected = true;
@@ -18,7 +18,7 @@ it('has a tooltip when active and with a long label', async () => {
18
18
  label=${'.'.repeat(500)}
19
19
  value="value"
20
20
  ></glide-core-dropdown-option>`);
21
- component.privateActive = true;
21
+ component.privateIsOpenTooltip = true;
22
22
  // Wait for the tooltip.
23
23
  await aTimeout(0);
24
24
  const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
@@ -40,7 +40,7 @@ it('has a tooltip when active and with a long label set programmatically', async
40
40
  label="Label"
41
41
  value="value"
42
42
  ></glide-core-dropdown-option>`);
43
- component.privateActive = true;
43
+ component.privateIsOpenTooltip = true;
44
44
  // The period is arbitrary. 500 of them ensures we exceed the maximum
45
45
  // width even if it's increased.
46
46
  component.label = '.'.repeat(500);
@@ -198,9 +198,9 @@ import{css}from"lit";import opacityAndScaleAnimation from"./styles/opacity-and-s
198
198
  }
199
199
 
200
200
  .internal-label {
201
- /*
202
- 2px so the label is vertically aligned. "vertical-align: middle" has no
203
- effect on flex children.
201
+ /*
202
+ 2px so the label is vertically aligned. "vertical-align: middle" has no
203
+ effect on flex children.
204
204
  */
205
205
  padding-block-start: 0.125rem;
206
206
  }
@@ -229,9 +229,9 @@ import{css}from"lit";import opacityAndScaleAnimation from"./styles/opacity-and-s
229
229
  font-size: inherit;
230
230
  min-inline-size: var(--min-inline-size);
231
231
 
232
- /*
233
- 2px so the value is vertically aligned. "vertical-align: middle" has no
234
- effect flex children.
232
+ /*
233
+ 2px so the value is vertically aligned. "vertical-align: middle" has no
234
+ effect flex children.
235
235
  */
236
236
  padding-block: 0.125rem 0;
237
237
  padding-inline: 0;
@@ -244,4 +244,16 @@ import{css}from"lit";import opacityAndScaleAnimation from"./styles/opacity-and-s
244
244
  font-family: var(--glide-core-font-sans);
245
245
  }
246
246
  }
247
+
248
+ .description {
249
+ display: block;
250
+
251
+ &.hidden {
252
+ display: none;
253
+ }
254
+ }
255
+
256
+ .validity-message {
257
+ display: block;
258
+ }
247
259
  `];
@@ -1 +1 @@
1
- import './dropdown.option.js';
1
+ export {};
@@ -1,9 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
- import './dropdown.option.js';
3
2
  import { ArgumentError } from 'ow';
4
3
  import { aTimeout, assert, expect, fixture, html } from '@open-wc/testing';
5
4
  import { repeat } from 'lit/directives/repeat.js';
6
5
  import GlideCoreDropdown from './dropdown.js';
6
+ import GlideCoreDropdownOption from './dropdown.option.js';
7
7
  import expectArgumentError from './library/expect-argument-error.js';
8
8
  import sinon from 'sinon';
9
9
  // You'll notice quite a few duplicated tests among the "*.single.ts", "*.multiple.ts",
@@ -18,6 +18,7 @@ import sinon from 'sinon';
18
18
  // duplicating them in both `dropdown.test.interactions.single.ts` and
19
19
  // `dropdown.test.interactions.multiple.ts` would add a ton of test weight.
20
20
  GlideCoreDropdown.shadowRootOptions.mode = 'open';
21
+ GlideCoreDropdownOption.shadowRootOptions.mode = 'open';
21
22
  it('registers', async () => {
22
23
  expect(window.customElements.get('glide-core-dropdown')).to.equal(GlideCoreDropdown);
23
24
  });
@@ -381,3 +382,20 @@ it('does not throw if the default slot only contains whitespace', async () => {
381
382
  }
382
383
  expect(spy.callCount).to.equal(0);
383
384
  });
385
+ it('hides the tooltip of the active option when open', async () => {
386
+ // The period is arbitrary. 500 of them ensures we exceed the maximum
387
+ // width even if it's increased.
388
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
389
+ <glide-core-dropdown-option
390
+ label=${'.'.repeat(500)}
391
+ ></glide-core-dropdown-option>
392
+
393
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
394
+ </glide-core-dropdown>`);
395
+ // Wait for it to open.
396
+ await aTimeout(0);
397
+ const tooltip = component
398
+ .querySelector('glide-core-dropdown-option')
399
+ ?.shadowRoot?.querySelector('[data-test="tooltip"]');
400
+ expect(tooltip?.checkVisibility()).to.be.false;
401
+ });
@@ -2,6 +2,7 @@
2
2
  import './dropdown.option.js';
3
3
  import { aTimeout, expect, fixture, html } from '@open-wc/testing';
4
4
  import GlideCoreDropdown from './dropdown.js';
5
+ import GlideCoreTag from './tag.js';
5
6
  GlideCoreDropdown.shadowRootOptions.mode = 'open';
6
7
  it('is accessible', async () => {
7
8
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
@@ -73,7 +74,7 @@ it('has a tag when an option is initially selected', async () => {
73
74
  </glide-core-dropdown>`);
74
75
  const tag = component.shadowRoot?.querySelector('[data-test="tag"]');
75
76
  expect(tag?.checkVisibility()).to.be.true;
76
- expect(tag?.textContent?.trim()).to.equal('One');
77
+ expect(tag?.label).to.equal('One');
77
78
  });
78
79
  it('shows Select All', async () => {
79
80
  const component = await fixture(html `<glide-core-dropdown
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import * as sinon from 'sinon';
3
- import { expect, fixture, html } from '@open-wc/testing';
3
+ import { expect, fixture, html, oneEvent } from '@open-wc/testing';
4
4
  import { sendKeys } from '@web/test-runner-commands';
5
5
  import GlideCoreDropdown from './dropdown.js';
6
6
  import GlideCoreDropdownOption from './dropdown.option.js';
@@ -62,6 +62,17 @@ const defaultSlot = html `
62
62
  value="eleven"
63
63
  ></glide-core-dropdown-option>
64
64
  `;
65
+ it('dispatches a "filter" event on "input"', async () => {
66
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
67
+ ${defaultSlot}
68
+ </glide-core-dropdown>`);
69
+ component.focus();
70
+ sendKeys({ type: 'o' });
71
+ const event = await oneEvent(component, 'filter');
72
+ expect(event instanceof CustomEvent).to.be.true;
73
+ expect(event.bubbles).to.be.true;
74
+ expect(event.detail).to.equal('o');
75
+ });
65
76
  it('does not dispatch "input" events on input', async () => {
66
77
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
67
78
  ${defaultSlot}
@@ -69,6 +80,6 @@ it('does not dispatch "input" events on input', async () => {
69
80
  const spy = sinon.spy();
70
81
  component.addEventListener('input', spy);
71
82
  component.focus();
72
- await sendKeys({ type: ' one ' });
83
+ await sendKeys({ type: 'one' });
73
84
  expect(spy.callCount).to.equal(0);
74
85
  });
@@ -159,6 +159,25 @@ it('dispatches one "input" event when an option is selected via Space', async ()
159
159
  expect(event.bubbles).to.be.true;
160
160
  expect(spy.callCount).to.equal(1);
161
161
  });
162
+ it('does not dispatch a "change" event when an already selected option is clicked', async () => {
163
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
164
+ <glide-core-dropdown-option
165
+ label="One"
166
+ selected
167
+ ></glide-core-dropdown-option>
168
+
169
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
170
+ </glide-core-dropdown>`);
171
+ // Wait for it to open.
172
+ await aTimeout(0);
173
+ const spy = sinon.spy();
174
+ component.addEventListener('change', spy);
175
+ setTimeout(() => {
176
+ component.querySelector('glide-core-dropdown-option')?.click();
177
+ });
178
+ await aTimeout(0);
179
+ expect(spy.callCount).to.equal(0);
180
+ });
162
181
  it('does not dispatch a "change" event when `value` is changed programmatically', async () => {
163
182
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
164
183
  <glide-core-dropdown-option
@@ -3,6 +3,7 @@ import './dropdown.option.js';
3
3
  import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
4
4
  import GlideCoreDropdown from './dropdown.js';
5
5
  import GlideCoreDropdownOption from './dropdown.option.js';
6
+ import GlideCoreTag from './tag.js';
6
7
  GlideCoreDropdown.shadowRootOptions.mode = 'open';
7
8
  GlideCoreDropdownOption.shadowRootOptions.mode = 'open';
8
9
  it('can be reset', async () => {
@@ -62,8 +63,8 @@ it('can be reset to the initially selected options', async () => {
62
63
  form.reset();
63
64
  const tags = component.shadowRoot?.querySelectorAll('[data-test="tag"]');
64
65
  expect(tags?.length).to.equal(2);
65
- expect(tags?.[0].textContent?.trim()).to.equal('Two');
66
- expect(tags?.[1].textContent?.trim()).to.equal('Three');
66
+ expect(tags?.[0].label).to.equal('Two');
67
+ expect(tags?.[1].label).to.equal('Three');
67
68
  expect(component.value).to.deep.equal(['two', 'three']);
68
69
  });
69
70
  it('has `formData` value when options are selected', async () => {
@@ -275,6 +275,26 @@ it('sets the first unfiltered option as active when the previously active option
275
275
  expect(option?.privateActive).to.be.true;
276
276
  expect(input?.getAttribute('aria-activedescendant')).to.equal(option?.id);
277
277
  });
278
+ it('updates the `value` of its `<input>` when the `label` of a selected option is changed programmatically', async () => {
279
+ const component = await fixture(html `<glide-core-dropdown
280
+ label="Label"
281
+ placeholder="Placeholder"
282
+ filterable
283
+ >
284
+ <glide-core-dropdown-option
285
+ label="One"
286
+ selected
287
+ ></glide-core-dropdown-option>
288
+
289
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
290
+ </glide-core-dropdown>`);
291
+ const option = component.querySelector('glide-core-dropdown-option');
292
+ assert(option);
293
+ option.label = 'Three';
294
+ await elementUpdated(component);
295
+ const input = component.shadowRoot?.querySelector('[data-test="input"]');
296
+ expect(input?.value).to.equal('Three');
297
+ });
278
298
  it('updates `value` when an option `value` is changed programmatically', async () => {
279
299
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
280
300
  ${defaultSlot}
@@ -516,21 +516,27 @@ it('opens when something other than the button is clicked', async () => {
516
516
  });
517
517
  expect(component.open).to.be.true;
518
518
  });
519
- it('remains open when something other than the button is clicked', async () => {
520
- const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
519
+ it('hides the tooltip of the active option when opened via click', async () => {
520
+ // The period is arbitrary. 500 of them ensures we exceed the maximum
521
+ // width even if it's increased.
522
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
521
523
  <glide-core-dropdown-option
522
- label="Label"
523
- value="value"
524
+ label=${'.'.repeat(500)}
524
525
  ></glide-core-dropdown-option>
526
+
527
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
525
528
  </glide-core-dropdown>`);
526
- const internalLabel = component.shadowRoot?.querySelector('[data-test="internal-label"]');
527
- assert(internalLabel);
528
- const { x, y } = internalLabel.getBoundingClientRect();
529
- // A simple `option.click()` won't do because we need a "mousedown" so that
530
- // `#onDropdownMousedown` gets covered.
531
- await sendMouse({
532
- type: 'click',
533
- position: [Math.ceil(x), Math.ceil(y)],
534
- });
535
- expect(component.open).to.be.true;
529
+ // Calling `click()` would be sweet. The problem is it sets `event.detail` to `0`,
530
+ // which puts us in a guard in the event handler. `Event` has no `detail` property
531
+ // and would work. `CustomEvent` is used for completeness and to get us as close as
532
+ // possible to a real click. See the comment in the handler for more information.
533
+ component.shadowRoot
534
+ ?.querySelector('[data-test="button"]')
535
+ ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
536
+ // Wait for it to open.
537
+ await aTimeout(0);
538
+ const tooltip = component
539
+ .querySelector('glide-core-dropdown-option')
540
+ ?.shadowRoot?.querySelector('[data-test="tooltip"]');
541
+ expect(tooltip?.checkVisibility()).to.be.false;
536
542
  });