@taprootio/espalier 2.14.0 → 2.15.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 (38) hide show
  1. package/custom-elements.json +3744 -2306
  2. package/dist/date-picker/esp-date-picker.js +22 -22
  3. package/dist/flyout/esp-flyout.js +4 -4
  4. package/dist/font-picker/esp-font-picker.js +3 -3
  5. package/dist/form/esp-form.js +1 -1
  6. package/dist/grid/esp-grid.d.ts +4 -12
  7. package/dist/grid/esp-grid.js +5 -5
  8. package/dist/header/esp-header.js +7 -7
  9. package/dist/lightbox/esp-lightbox.js +16 -16
  10. package/dist/page/esp-page.js +26 -26
  11. package/dist/page/workspace-width.js +1 -0
  12. package/dist/pickers/esp-pick-one.d.ts +9 -30
  13. package/dist/pickers/esp-pick-one.js +18 -50
  14. package/dist/pickers/esp-pick-some.d.ts +4 -29
  15. package/dist/pickers/esp-pick-some.js +15 -42
  16. package/dist/pickers/esp-picker-base.d.ts +95 -0
  17. package/dist/pickers/esp-picker-base.js +33 -1
  18. package/dist/pickers/esp-picker-menu.d.ts +0 -2
  19. package/dist/pickers/esp-picker-menu.js +6 -6
  20. package/dist/pickers/pick-one-selection.js +1 -0
  21. package/dist/popover/esp-popover.js +6 -6
  22. package/dist/repeater/esp-repeater.d.ts +11 -8
  23. package/dist/repeater/esp-repeater.js +4 -4
  24. package/dist/shared/color-engine.js +1 -1
  25. package/dist/shared/cursor-pagination.d.ts +76 -0
  26. package/dist/shared/cursor-pagination.js +1 -0
  27. package/dist/shared/intent-values.d.ts +13 -2
  28. package/dist/shared/intent-values.js +1 -1
  29. package/dist/shared/popover-controller.js +1 -1
  30. package/dist/shared/raf-throttle.js +1 -0
  31. package/dist/shared/utilities.d.ts +27 -27
  32. package/dist/shared/utilities.js +1 -1
  33. package/dist/shared/viewport.d.ts +89 -0
  34. package/dist/shared/viewport.js +1 -0
  35. package/package.json +9 -1
  36. package/dist/header/esp-menu-group.js +0 -1
  37. package/dist/header/esp-menu-item.js +0 -1
  38. package/dist/header/esp-menu.js +0 -1
@@ -1,24 +1,24 @@
1
- var o=function(p,t,s,e){var i=arguments.length,a=i<3?t:e===null?e=Object.getOwnPropertyDescriptor(t,s):e,h;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(p,t,s,e);else for(var l=p.length-1;l>=0;l--)(h=p[l])&&(a=(i<3?h(a):i>3?h(t,s,a):h(t,s))||a);return i>3&&a&&Object.defineProperty(t,s,a),a};import{css as y,html as m}from"lit";import{customElement as v,property as n,state as d}from"lit/decorators.js";import{classMap as I}from"lit/directives/class-map.js";import{ifDefined as w}from"lit/directives/if-defined.js";import{ref as u}from"lit/directives/ref.js";import"./esp-picker-item.js";import"./esp-picker-menu.js";import{EspalierElementBase as k}from"../shared/esp-element-base.js";import{caretUpDown as g}from"../shared/svgs/caret-up-down.js";import{filter as b}from"../shared/svgs/filter.js";import{plus as O}from"../shared/svgs/plus.js";import{EspalierPickerBase as $}from"./esp-picker-base.js";import{arrayKeysMatch as f}from"../shared/utilities.js";import{TypeaheadController as C}from"./typeahead-controller.js";let r=class extends ${constructor(){super(...arguments),this.selectedItems=[],this.initialSyncDone=!1,this.typeaheadLoading=!1,this.filteredItems=[],this.inputFocused=!1,this.typeaheadCtrl=new C({host:this,onFilteredItemsChanged:t=>{const s=new Set(this.selectedItems.map(e=>e.value));this.filteredItems=t.map(e=>({...e,selected:s.has(e.value)}))},onLoadingChanged:t=>{this.typeaheadLoading=t}}),this.typeahead=!1,this.fetchItems=null,this.debounceMs=void 0,this.addNewValue=null}get values(){return this.selectedItems.map(t=>t.value)}getPickerFormValue(){const t=this.values;return t.length>0?t.join(","):null}getPickerValidity(){return this.required&&this.selectedItems.length===0?{flags:{valueMissing:!0},message:this.requiredMessage||"Please select at least one option."}:null}handlePickerReset(){this.selectedItems=[],this.pickerItems=this.pickerItems.map(t=>({...t,selected:!1}))}handlePickerRestore(t){const s=t.split(",");this.pickerItems=this.pickerItems.map(e=>({...e,selected:s.includes(e.value)})),this.selectedItems=this.pickerItems.filter(e=>e.selected)}set showOptions(t){const s=this.showOptions;super.showOptions=t,t&&!s&&this.typeahead&&this.typeaheadCtrl.isRemote&&this.filteredItems.length===0&&this.typeaheadCtrl.fetchInitial()}get showOptions(){return super.showOptions}willUpdate(t){if(super.willUpdate(t),!this.initialSyncDone&&t.has("pickerItems")&&this.selectedItems.length===0){const s=this.pickerItems.filter(e=>e.selected);s.length>0&&(this.selectedItems=s,this.initialSyncDone=!0)}this.typeahead&&((t.has("pickerItems")||t.has("typeahead"))&&this.typeaheadCtrl.setAllItems(this.pickerItems),(t.has("fetchItems")||t.has("typeahead"))&&this.typeaheadCtrl.setFetchItems(this.fetchItems),(t.has("debounceMs")||t.has("typeahead"))&&this.debounceMs!==void 0&&this.typeaheadCtrl.setDebounceMs(this.debounceMs))}firstUpdated(t){if(super.firstUpdated(t),this.typeahead){const s=this.theInput.value;s&&(s.ariaAutoComplete="list")}}setSelectedItems(t){this.initialSyncDone=!0,this.selectedItems=t,this.pickerItems=this.pickerItems.map(s=>({...s,selected:this.selectedItems.some(e=>e.value===s.value)})),this.formCtrl.syncValue(),this.dispatchEvent(new CustomEvent("value-changed",{detail:this.selectedItems,bubbles:!0,composed:!0})),this.focus()}resetTypeaheadInput(){const t=this.theInput.value;t&&(t.value=""),this.typeaheadCtrl.isRemote?this.typeaheadCtrl.resetQuery():this.typeaheadCtrl.clearQuery()}get canAddNewValue(){if(!this.addNewValue||!this.typeahead)return!1;const t=this.theInput.value;if(!t||!t.value.trim())return!1;const s=t.value.trim().toLowerCase(),e=i=>i.text.toLowerCase()===s;return!(this.pickerItems.some(e)||this.typeaheadCtrl.isRemote&&this.filteredItems.some(e))}async handleAddNewValue(){if(!this.addNewValue)return;const t=this.theInput.value;if(!t||!t.value.trim())return;const s=t.value.trim();let e;try{e=await this.addNewValue(s)}catch{return}const i=this.pickerItems.find(a=>a.value===e.value);if(i){this.selectedItems.some(a=>a.value===i.value)||(i.selected=!0,this.setSelectedItems([...this.selectedItems,i])),this.resetTypeaheadInput();return}e.selected=!0,this.pickerItems=[...this.pickerItems,e],this.setSelectedItems([...this.selectedItems,e]),this.resetTypeaheadInput(),this.typeaheadCtrl.setAllItems(this.pickerItems),this.typeaheadCtrl.isRemote&&this.typeaheadCtrl.fetchInitial()}get iconSvg(){return this.canAddNewValue?O:this.typeahead&&this.inputFocused?b:g}render(){const{showOptions:t}=this;return m`
1
+ var c=function(o,t,s,e){var a=arguments.length,i=a<3?t:e===null?e=Object.getOwnPropertyDescriptor(t,s):e,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(o,t,s,e);else for(var l=o.length-1;l>=0;l--)(n=o[l])&&(i=(a<3?n(i):a>3?n(t,s,i):n(t,s))||i);return a>3&&i&&Object.defineProperty(t,s,i),i};import{css as I,html as p}from"lit";import{customElement as k,property as u,state as v}from"lit/decorators.js";import{classMap as y}from"lit/directives/class-map.js";import{ifDefined as g}from"lit/directives/if-defined.js";import{ref as d}from"lit/directives/ref.js";import"./esp-picker-item.js";import"./esp-picker-menu.js";import{EspalierElementBase as w}from"../shared/esp-element-base.js";import{caretUpDown as b}from"../shared/svgs/caret-up-down.js";import{filter as $}from"../shared/svgs/filter.js";import{plus as V}from"../shared/svgs/plus.js";import{EspalierPickerBase as m}from"./esp-picker-base.js";import{arrayKeysMatch as f}from"../shared/utilities.js";let r=class extends m{constructor(){super(...arguments),this.selectedItems=[],this.initialSyncDone=!1,this.addNewValue=null}decorateFilteredItems(t){const s=new Set(this.selectedItems.map(e=>e.value));return t.map(e=>({...e,selected:s.has(e.value)}))}get typeaheadRestoreText(){return""}get values(){return this.selectedItems.map(t=>t.value)}getPickerFormValue(){const t=this.values;return t.length>0?t.join(","):null}getPickerValidity(){return this.required&&this.selectedItems.length===0?{flags:{valueMissing:!0},message:this.requiredMessage||"Please select at least one option."}:null}handlePickerReset(){this.selectedItems=[],this.pickerItems=this.pickerItems.map(t=>({...t,selected:!1}))}handlePickerRestore(t){const s=t.split(",");this.pickerItems=this.pickerItems.map(e=>({...e,selected:s.includes(e.value)})),this.selectedItems=this.pickerItems.filter(e=>e.selected)}syncSelectionFromItems(t){if(this.initialSyncDone||!t.has("pickerItems")||this.selectedItems.length>0)return;const s=this.pickerItems.filter(e=>e.selected);s.length>0&&(this.selectedItems=s,this.initialSyncDone=!0)}setSelectedItems(t){this.initialSyncDone=!0,this.selectedItems=t,this.pickerItems=this.pickerItems.map(s=>({...s,selected:this.selectedItems.some(e=>e.value===s.value)})),this.formCtrl.syncValue(),this.emitValueChanged(this.selectedItems),this.focus()}get canAddNewValue(){if(!this.addNewValue||!this.typeahead)return!1;const t=this.theInput.value;if(!t||!t.value.trim())return!1;const s=t.value.trim().toLowerCase(),e=a=>a.text.toLowerCase()===s;return!(this.pickerItems.some(e)||this.typeaheadIsRemote&&this.filteredItems.some(e))}async handleAddNewValue(){if(!this.addNewValue)return;const t=this.theInput.value;if(!t||!t.value.trim())return;const s=t.value.trim();let e;try{e=await this.addNewValue(s)}catch{return}const a=this.pickerItems.find(i=>i.value===e.value);if(a){this.selectedItems.some(i=>i.value===a.value)||(a.selected=!0,this.setSelectedItems([...this.selectedItems,a])),this.resetTypeaheadInput();return}e.selected=!0,this.pickerItems=[...this.pickerItems,e],this.setSelectedItems([...this.selectedItems,e]),this.resetTypeaheadInput(),this.refreshTypeaheadItems(),this.typeaheadIsRemote&&this.fetchInitialTypeaheadItems()}get iconSvg(){return this.canAddNewValue?V:this.typeahead&&this.inputFocused?$:b}render(){const{showOptions:t}=this;return p`
2
2
  <div
3
3
  tabindex="-1"
4
- class=${I({"esp-field":!0,"show-options":t})}
4
+ class=${y({"esp-field":!0,"show-options":t})}
5
5
  @click=${e=>{this.theInput.value?.focus(),this.showOptions=!this.showOptions,e.stopPropagation()}}
6
6
  >
7
7
  <section>
8
- ${this.selectedItems.map(e=>m`<span
8
+ ${this.selectedItems.map(e=>p`<span
9
9
  class="selected-item"
10
- @click=${i=>{i.stopPropagation(),this.setSelectedItems(this.selectedItems.filter(a=>a.value!==e.value))}}
10
+ @click=${a=>{a.stopPropagation(),this.setSelectedItems(this.selectedItems.filter(i=>i.value!==e.value))}}
11
11
  >${e.text}</span
12
12
  >`)}
13
13
  <input
14
- ${u(this.theInput)}
14
+ ${d(this.theInput)}
15
15
  class="esp-input"
16
16
  placeholder=${this.placeholder}
17
17
  ?readonly=${!this.typeahead}
18
- @input=${e=>{if(!this.typeahead)return;const i=e.target;this.typeaheadCtrl.setQuery(i.value),this.showOptions||(this.showOptions=!0)}}
18
+ @input=${this.handleTypeaheadInput}
19
19
  @focus=${()=>{this.inputFocused=!0}}
20
- @blur=${e=>{this.inputFocused=!1;const i=e.relatedTarget;if(!(i&&(this.contains(i)||this.shadowRoot?.contains(i)))){if(!i&&this.showOptions){requestAnimationFrame(()=>{this.showOptions&&this.shadowRoot?.activeElement!==this.theInput.value&&(this.showOptions=!1,this.typeahead&&this.resetTypeaheadInput())});return}this.showOptions=!1,this.typeahead&&this.resetTypeaheadInput()}}}
21
- @keydown=${e=>{if(this.pickerMenu.value)switch(e.key){case" ":this.typeahead||(this.showOptions=!this.showOptions);break;case"ArrowDown":case"ArrowUp":case"Home":case"End":e.preventDefault(),this.showOptions?(this.pickerMenu.value.doKeyboardNav(e.key),this.updateActiveDescendant()):this.showOptions=!0;break;case"Enter":e.preventDefault(),this.showOptions?this.canAddNewValue?this.handleAddNewValue():(this.pickerMenu.value.doKeyboardNav("Enter"),this.updateActiveDescendant()):this.showOptions=!0;break;case"Tab":this.showOptions&&(this.showOptions=!1),this.typeahead&&this.resetTypeaheadInput();break;case"Backspace":this.typeahead&&this.selectedItems.length>0&&!e.target.value&&this.setSelectedItems(this.selectedItems.slice(0,-1));break;case"Escape":this.showOptions=!1,this.typeahead&&this.resetTypeaheadInput();break}}}
20
+ @blur=${this.handleInputBlur}
21
+ @keydown=${e=>{if(this.pickerMenu.value&&!this.handleSharedPickerKeydown(e))switch(e.key){case"ArrowDown":case"ArrowUp":case"Home":case"End":this.handleMenuNavigationKey(e.key,e);break;case"Enter":if(this.showOptions&&this.canAddNewValue){e.preventDefault(),this.handleAddNewValue();break}this.handleMenuNavigationKey("Enter",e);break;case"Backspace":this.typeahead&&this.selectedItems.length>0&&!e.target.value&&this.setSelectedItems(this.selectedItems.slice(0,-1));break}}}
22
22
  />
23
23
  </section>
24
24
  <label
@@ -27,39 +27,30 @@ var o=function(p,t,s,e){var i=arguments.length,a=i<3?t:e===null?e=Object.getOwnP
27
27
  class=${this.canAddNewValue?"add-new":""}
28
28
  tabindex=${this.canAddNewValue?"0":"-1"}
29
29
  role=${this.canAddNewValue?"button":"presentation"}
30
- aria-label=${w(this.canAddNewValue?"Add new value":void 0)}
30
+ aria-label=${g(this.canAddNewValue?"Add new value":void 0)}
31
31
  >${this.iconSvg}</label
32
32
  >
33
33
 
34
34
  <esp-picker-menu
35
- .pickerItems=${this.typeahead?this.filteredItems:this.pickerItems}
35
+ .pickerItems=${this.menuItems}
36
36
  .loading=${this.typeaheadLoading}
37
37
  .emptyMessage=${this.typeahead?"No matches":""}
38
38
  .label=${this.placeholder}
39
39
  tabindex="-1"
40
- ${u(this.pickerMenu)}
40
+ ${d(this.pickerMenu)}
41
41
  multi-select
42
- @selection-changed=${e=>{if(e.stopPropagation(),this.typeahead){const a=new Set(this.filteredItems.map(c=>c.value)),l=[...this.selectedItems.filter(c=>!a.has(c.value)),...e.detail];if(f(l,this.selectedItems,"value"))return;this.setSelectedItems(l),this.resetTypeaheadInput();return}f(e.detail,this.selectedItems,"value")||this.setSelectedItems(e.detail)}}
42
+ @selection-changed=${e=>{if(e.stopPropagation(),this.typeahead){const i=new Set(this.filteredItems.map(h=>h.value)),l=[...this.selectedItems.filter(h=>!i.has(h.value)),...e.detail];if(f(l,this.selectedItems,"value"))return;this.setSelectedItems(l),this.resetTypeaheadInput();return}f(e.detail,this.selectedItems,"value")||this.setSelectedItems(e.detail)}}
43
43
  >
44
44
  </esp-picker-menu>
45
45
  </div>
46
- <slot ${u(this.itemsSlot)}></slot>
47
- `}};r.styles=[...k.styles,y`
46
+ <slot ${d(this.itemsSlot)}></slot>
47
+ `}};r.styles=[...w.styles,m.pickerFieldStyles,I`
48
48
  :host {
49
49
  --_esp-pick-some-chip-hover-l: calc(var(--esp-l-raised-2) * 0.88);
50
50
  --_esp-pick-some-chip-focus-l: calc(var(--esp-l-raised-2) * 0.8);
51
51
  }
52
52
 
53
- :host([disabled]) {
54
- pointer-events: none;
55
- opacity: 0.5;
56
- }
57
-
58
53
  .esp-field {
59
- display: grid;
60
- grid-template-columns: auto min-content;
61
- position: relative;
62
-
63
54
  & input.esp-input {
64
55
  width: auto;
65
56
  flex-grow: 1;
@@ -67,9 +58,6 @@ var o=function(p,t,s,e){var i=arguments.length,a=i<3?t:e===null?e=Object.getOwnP
67
58
  }
68
59
 
69
60
  > section {
70
- cursor: pointer;
71
- display: flex;
72
- flex-wrap: wrap;
73
61
  padding: var(--esp-size-padding);
74
62
  gap: var(--esp-size-tiny);
75
63
 
@@ -107,23 +95,8 @@ var o=function(p,t,s,e){var i=arguments.length,a=i<3?t:e===null?e=Object.getOwnP
107
95
  }
108
96
  }
109
97
 
110
- > label {
111
- display: grid;
112
- place-content: center;
113
- cursor: pointer;
114
-
115
- > svg {
116
- height: var(--esp-size-normal-to-medium);
117
- width: var(--esp-size-normal-to-medium);
118
- }
119
- }
120
-
121
98
  > label.add-new {
122
99
  color: var(--esp-color-primary);
123
100
  }
124
101
  }
125
-
126
- :host([typeahead]) .esp-field > section {
127
- cursor: text;
128
- }
129
- `],o([d()],r.prototype,"selectedItems",void 0),o([d()],r.prototype,"typeaheadLoading",void 0),o([d()],r.prototype,"filteredItems",void 0),o([d()],r.prototype,"inputFocused",void 0),o([n({type:Array})],r.prototype,"values",null),o([n({type:Boolean,reflect:!0})],r.prototype,"typeahead",void 0),o([n({attribute:!1})],r.prototype,"fetchItems",void 0),o([n({type:Number,attribute:"debounce-ms"})],r.prototype,"debounceMs",void 0),o([n({attribute:!1})],r.prototype,"addNewValue",void 0),r=o([v("esp-pick-some")],r);export{r as EspalierPickSome};
102
+ `],c([v()],r.prototype,"selectedItems",void 0),c([u({type:Array})],r.prototype,"values",null),c([u({attribute:!1})],r.prototype,"addNewValue",void 0),r=c([k("esp-pick-some")],r);export{r as EspalierPickSome};
@@ -4,6 +4,9 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
4
4
  import { type PickerItem } from "./esp-picker-item.js";
5
5
  import { type PropertyValues } from "lit";
6
6
  import { FormFieldController } from "../shared/form-field-controller.js";
7
+ import type { TypeaheadFetchItems } from "./types.js";
8
+ /** Keys that drive the picker menu rather than the input's text. */
9
+ export type PickerNavigationKey = "ArrowDown" | "ArrowUp" | "Enter" | "Home" | "End";
7
10
  export declare abstract class EspalierPickerBase extends EspalierElementBase implements EspalierFormField {
8
11
  static formAssociated: boolean;
9
12
  protected internals: ElementInternals;
@@ -31,6 +34,79 @@ export declare abstract class EspalierPickerBase extends EspalierElementBase imp
31
34
  protected theInput: import("lit-html/directives/ref.js").Ref<HTMLInputElement>;
32
35
  protected get showOptions(): boolean;
33
36
  protected set showOptions(val: boolean);
37
+ protected typeaheadLoading: boolean;
38
+ protected filteredItems: PickerItem[];
39
+ protected inputFocused: boolean;
40
+ /**
41
+ * Copy the picker's current selection onto a freshly filtered item list so
42
+ * the menu renders the right checkmarks.
43
+ *
44
+ * Implementations **must not** mutate `items` — `pickerItems` carries
45
+ * `selected` flags that the update lifecycle reads, and the filtered list may
46
+ * alias it.
47
+ */
48
+ protected abstract decorateFilteredItems(items: PickerItem[]): PickerItem[];
49
+ /** Text the input reverts to when a typeahead query is discarded. */
50
+ protected abstract get typeaheadRestoreText(): string;
51
+ /**
52
+ * Whether discarding a query should keep the last remote result set instead
53
+ * of restoring the full canonical list. Multi-select overrides this so a user
54
+ * can keep picking from the same server results without retyping.
55
+ */
56
+ protected get preservesRemoteResultsOnReset(): boolean;
57
+ /** Whether typeahead is sourcing items from `fetchItems` rather than locally. */
58
+ protected get typeaheadIsRemote(): boolean;
59
+ /** Re-seed the typeahead controller with the current canonical items. */
60
+ protected refreshTypeaheadItems(): void;
61
+ /** Fetch the default remote result set. */
62
+ protected fetchInitialTypeaheadItems(): void;
63
+ /**
64
+ * When true, the picker input becomes a typeahead search field.
65
+ * The user types to filter the option list.
66
+ *
67
+ * @type {boolean}
68
+ */
69
+ typeahead: boolean;
70
+ /**
71
+ * Async callback for fetching items from a remote source.
72
+ * When set alongside `typeahead`, the picker delegates to this
73
+ * callback instead of filtering locally.
74
+ *
75
+ * The callback receives the current query string and an
76
+ * `AbortSignal` that the component will abort when a newer
77
+ * query arrives before the previous request completes.
78
+ */
79
+ fetchItems: TypeaheadFetchItems | null;
80
+ /**
81
+ * Debounce delay in milliseconds for typeahead input. Defaults
82
+ * to `0` for local filtering and `300` for remote fetching.
83
+ *
84
+ * @type {number}
85
+ */
86
+ debounceMs: number | undefined;
87
+ /** Revert the input text to the current selection and drop the query. */
88
+ protected resetTypeaheadInput(): void;
89
+ /** Feed typed text to the controller, opening the menu on first keystroke. */
90
+ protected handleTypeaheadInput: (ev: InputEvent) => void;
91
+ /**
92
+ * Close the menu when focus genuinely leaves the picker.
93
+ *
94
+ * A click on a menu item reports `relatedTarget: null`, because items in the
95
+ * top layer are not focusable. That is indistinguishable from focus leaving
96
+ * the document, so the close is deferred a frame: by then either the item's
97
+ * click has closed the menu itself, or focus really is gone.
98
+ */
99
+ protected handleInputBlur: (event: FocusEvent) => void;
100
+ /**
101
+ * Handle the keys both pickers treat identically.
102
+ *
103
+ * @returns `true` when the key was consumed and the caller should stop.
104
+ */
105
+ protected handleSharedPickerKeydown(ev: KeyboardEvent): boolean;
106
+ /** Open the menu, or forward a navigation key to the open menu. */
107
+ protected handleMenuNavigationKey(key: PickerNavigationKey, ev: KeyboardEvent): void;
108
+ /** Items the menu should render — the filtered set while typing ahead. */
109
+ protected get menuItems(): Array<PickerItem>;
34
110
  /**
35
111
  * The name used when the picker participates in a `<form>`.
36
112
  *
@@ -107,6 +183,25 @@ export declare abstract class EspalierPickerBase extends EspalierElementBase imp
107
183
  * Clear `ariaActiveDescendantElement` on the input.
108
184
  */
109
185
  protected clearActiveDescendant(): void;
186
+ /**
187
+ * Resolve this picker's own selection from `pickerItems`.
188
+ *
189
+ * Runs **before** the typeahead controller is re-seeded, because
190
+ * `setAllItems` synchronously re-emits the filtered list and
191
+ * {@link decorateFilteredItems} reads the selection to mark the menu copies.
192
+ * Reversing the order decorates them against a stale selection, which drops
193
+ * the checkmark for a `.value` set before the items arrived.
194
+ */
195
+ protected syncSelectionFromItems(_changedProperties: PropertyValues): void;
196
+ protected willUpdate(changedProperties: PropertyValues): void;
110
197
  protected updated(changedProperties: PropertyValues): void;
111
198
  protected firstUpdated(_changedProperties: PropertyValues): void;
199
+ /**
200
+ * The field shell shared by every picker: the trigger grid, the icon slot,
201
+ * the disabled treatment, and the typeahead text cursor.
202
+ *
203
+ * Subclasses spread this into their own `static styles` and add only what is
204
+ * genuinely theirs (`esp-pick-some`'s selection chips, for example).
205
+ */
206
+ static pickerFieldStyles: import("lit").CSSResult;
112
207
  }
@@ -1 +1,33 @@
1
- var a=function(c,t,e,s){var o=arguments.length,i=o<3?t:s===null?s=Object.getOwnPropertyDescriptor(t,e):s,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(c,t,e,s);else for(var l=c.length-1;l>=0;l--)(n=c[l])&&(i=(o<3?n(i):o>3?n(t,e,i):n(t,e))||i);return o>3&&i&&Object.defineProperty(t,e,i),i};import{createRef as u}from"lit/directives/ref.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";import{property as h,state as m}from"lit/decorators.js";import{EspalierPickerItem as f}from"./esp-picker-item.js";import{findContainingPopovers as g,PopoverController as v}from"../shared/popover-controller.js";import{FormFieldController as w}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as k}from"../shared/form-field-description-controller.js";class r extends d{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new w({host:this,internals:this.internals,getFormValue:()=>this.getPickerFormValue(),getValidity:()=>this.getPickerValidity(),onReset:()=>this.handlePickerReset(),onRestore:t=>this.handlePickerRestore(t),onDisabled:t=>{this.disabled=t}}),this.formItemDescription=new k({host:this,getTarget:()=>this.theInput.value}),this._showOptions=!1,this.itemsSlot=u(),this.pickerMenu=u(),this.theInput=u(),this._lastViewportHeight=0,this.popoverCtrl=new v({host:this,closeStrategy:"source-identity",isOpen:()=>this._showOptions,onShouldClose:()=>{this.showOptions=!1},onPositionUpdate:()=>{this.pickerMenu.value?.updatePosition(this);const t=window.innerHeight||document.documentElement.clientHeight;if(this._lastViewportHeight!==0&&t!==this._lastViewportHeight){const e=this._lastViewportHeight-t;e>=r.KEYBOARD_THRESHOLD?(this._scrollToContainPopover(),this._lastViewportHeight=t):e<0&&(this._lastViewportHeight=t)}},getInsideElements:()=>[this.pickerMenu.value??null],onOutsideClick:()=>{this.showOptions=!1}}),this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1,this.pickerItems=[],this.placeholder="Choose...",this.width="",this._slotExtractPending=!1}getPickerFormValue(){return null}getPickerValidity(){return null}handlePickerReset(){}handlePickerRestore(t){}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(t){this.formCtrl.handleFormStateRestore(t)}formDisabledCallback(t){this.formCtrl.handleFormDisabled(t)}get showOptions(){return this._showOptions}set showOptions(t){if(t&&this.disabled)return;this._showOptions=t;const e=this.theInput.value;e&&(e.ariaExpanded=String(t)),t&&this.pickerMenu.value?(this.popoverCtrl.publishCloseOthers(g(this)),this.pickerMenu.value.positionSelf(this),this._lastViewportHeight=window.innerHeight||document.documentElement.clientHeight,this.clearActiveDescendant(),this.popoverCtrl.startTracking(),this.popoverCtrl.startOutsideClick()):!t&&this.pickerMenu.value&&(this.popoverCtrl.stopTracking(),this.popoverCtrl.stopOutsideClick(),this.pickerMenu.value.hideMenu(),this.clearActiveDescendant(),this._lastViewportHeight=0)}focus(){this.theInput.value?.focus()}setFormItemDescription(t){this.formItemDescription.setDescription(t)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}updateActiveDescendant(){const t=this.theInput.value;if(!t||!this.pickerMenu.value)return;const e=this.pickerMenu.value.getHighlightedElement();t.ariaActiveDescendantElement=e}clearActiveDescendant(){const t=this.theInput.value;t&&(t.ariaActiveDescendantElement=null)}_scrollToContainPopover(){const t=this.pickerMenu.value;if(!t)return;const e=t.getBoundingClientRect(),s=this.getBoundingClientRect(),o=window.innerHeight||document.documentElement.clientHeight,i=Math.min(s.top,e.top),n=Math.max(s.bottom,e.bottom),l=window.matchMedia("(prefers-reduced-motion: reduce)").matches?"auto":"smooth";if(n>o){const p=n-o;window.scrollBy({top:p+8,behavior:l}),requestAnimationFrame(()=>{this.pickerMenu.value?.updatePosition(this)})}else i<0&&(window.scrollBy({top:i-8,behavior:l}),requestAnimationFrame(()=>{this.pickerMenu.value?.updatePosition(this)}))}updated(t){super.updated(t),t.has("width")&&(this.width?this.style.width=this.width:this.style.removeProperty("width"))}firstUpdated(t){super.firstUpdated(t);const e=this.theInput.value;if(e&&(e.role="combobox",e.ariaHasPopup="listbox",e.ariaExpanded="false",e.ariaAutoComplete="none",this.pickerMenu.value)){const o=e;o.ariaControlsElements=[this.pickerMenu.value]}const s=this.itemsSlot.value;s&&(this.extractSlotItems(s),s.addEventListener("slotchange",()=>this.extractSlotItems(s)))}extractSlotItems(t){this._slotExtractPending||(this._slotExtractPending=!0,queueMicrotask(()=>{this._slotExtractPending=!1;const e=t.assignedElements();if(e.length===0)return;const s=[];for(const o of e){if(!(o instanceof f))throw new Error(`Picker items must be of type esp-picker-item, but got <${o.tagName.toLowerCase()}>`);const i=o,n=Array.from(i.childNodes),l=n.length>0?n.map(p=>p.cloneNode(!0)):void 0;s.push({text:i.text||i.getAttribute("text")||i.textContent?.trim()||"",value:i.value||i.getAttribute("value")||"",selected:i.selected||i.hasAttribute("selected"),icon:i.icon||i.getAttribute("icon")||"",styles:i.styles,slotNodes:l})}this.pickerItems=s;for(const o of e)o.remove()}))}}r.formAssociated=!0,r.KEYBOARD_THRESHOLD=150,a([m()],r.prototype,"showOptions",null),a([h({type:String,reflect:!0})],r.prototype,"name",void 0),a([h({type:Boolean,reflect:!0})],r.prototype,"required",void 0),a([h({attribute:"required-message"})],r.prototype,"requiredMessage",void 0),a([h({type:Boolean,reflect:!0})],r.prototype,"disabled",void 0),a([h({type:Array})],r.prototype,"pickerItems",void 0),a([h({type:String})],r.prototype,"placeholder",void 0),a([h({type:String})],r.prototype,"width",void 0);export{r as EspalierPickerBase};
1
+ var r=function(d,e,t,o){var a=arguments.length,s=a<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(d,e,t,o);else for(var l=d.length-1;l>=0;l--)(n=d[l])&&(s=(a<3?n(s):a>3?n(e,t,s):n(e,t))||s);return a>3&&s&&Object.defineProperty(e,t,s),s};import{createRef as u}from"lit/directives/ref.js";import{EspalierElementBase as f}from"../shared/esp-element-base.js";import{property as h,state as p}from"lit/decorators.js";import{EspalierPickerItem as y}from"./esp-picker-item.js";import{css as v}from"lit";import{findContainingPopovers as g,PopoverController as w}from"../shared/popover-controller.js";import{scrollToContainAnchoredSurface as I,viewportSize as c}from"../shared/viewport.js";import{FormFieldController as C}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as k}from"../shared/form-field-description-controller.js";import{TypeaheadController as b}from"./typeahead-controller.js";class i extends f{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new C({host:this,internals:this.internals,getFormValue:()=>this.getPickerFormValue(),getValidity:()=>this.getPickerValidity(),onReset:()=>this.handlePickerReset(),onRestore:e=>this.handlePickerRestore(e),onDisabled:e=>{this.disabled=e}}),this.formItemDescription=new k({host:this,getTarget:()=>this.theInput.value}),this._showOptions=!1,this.itemsSlot=u(),this.pickerMenu=u(),this.theInput=u(),this._lastViewportHeight=0,this.popoverCtrl=new w({host:this,closeStrategy:"source-identity",isOpen:()=>this._showOptions,onShouldClose:()=>{this.showOptions=!1},onPositionUpdate:()=>{this.pickerMenu.value?.updatePosition(this);const{height:e}=c();if(this._lastViewportHeight!==0&&e!==this._lastViewportHeight){const t=this._lastViewportHeight-e;t>=i.KEYBOARD_THRESHOLD?(this._scrollToContainPopover(),this._lastViewportHeight=e):t<0&&(this._lastViewportHeight=e)}},getInsideElements:()=>[this.pickerMenu.value??null],onOutsideClick:()=>{this.showOptions=!1}}),this.typeaheadLoading=!1,this.filteredItems=[],this.inputFocused=!1,this.typeaheadCtrl=new b({host:this,onFilteredItemsChanged:e=>{this.filteredItems=this.decorateFilteredItems(e)},onLoadingChanged:e=>{this.typeaheadLoading=e}}),this.typeahead=!1,this.fetchItems=null,this.debounceMs=void 0,this.handleTypeaheadInput=e=>{this.typeahead&&(this.typeaheadCtrl.setQuery(e.target.value),this.showOptions||(this.showOptions=!0))},this.handleInputBlur=e=>{this.inputFocused=!1;const t=e.relatedTarget;if(!(t&&(this.contains(t)||this.shadowRoot?.contains(t)))){if(!t&&this.showOptions){requestAnimationFrame(()=>{this.showOptions&&this.shadowRoot?.activeElement!==this.theInput.value&&this.closeAndResetTypeahead()});return}this.closeAndResetTypeahead()}},this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1,this.pickerItems=[],this.placeholder="Choose...",this.width="",this._slotExtractPending=!1}getPickerFormValue(){return null}getPickerValidity(){return null}handlePickerReset(){}handlePickerRestore(e){}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}get showOptions(){return this._showOptions}set showOptions(e){if(e&&this.disabled)return;const t=this._showOptions;this._showOptions=e;const o=this.theInput.value;o&&(o.ariaExpanded=String(e)),e&&this.pickerMenu.value?(this.popoverCtrl.publishCloseOthers(g(this)),this.pickerMenu.value.positionSelf(this),this._lastViewportHeight=c().height,this.clearActiveDescendant(),this.popoverCtrl.startTracking(),this.popoverCtrl.startOutsideClick()):!e&&this.pickerMenu.value&&(this.popoverCtrl.stopTracking(),this.popoverCtrl.stopOutsideClick(),this.pickerMenu.value.hideMenu(),this.clearActiveDescendant(),this._lastViewportHeight=0),e&&!t&&this.typeahead&&this.typeaheadCtrl.isRemote&&this.filteredItems.length===0&&this.typeaheadCtrl.fetchInitial()}get preservesRemoteResultsOnReset(){return this.typeaheadIsRemote}get typeaheadIsRemote(){return this.typeaheadCtrl.isRemote}refreshTypeaheadItems(){this.typeaheadCtrl.setAllItems(this.pickerItems)}fetchInitialTypeaheadItems(){this.typeaheadCtrl.fetchInitial()}resetTypeaheadInput(){const e=this.theInput.value;e&&(e.value=this.typeaheadRestoreText),this.preservesRemoteResultsOnReset?this.typeaheadCtrl.resetQuery():this.typeaheadCtrl.clearQuery()}closeAndResetTypeahead(){this.showOptions=!1,this.typeahead&&this.resetTypeaheadInput()}handleSharedPickerKeydown(e){switch(e.key){case" ":return this.typeahead||(this.showOptions=!this.showOptions),!0;case"Tab":return this.showOptions&&(this.showOptions=!1),this.typeahead&&this.resetTypeaheadInput(),!0;case"Escape":return this.closeAndResetTypeahead(),!0;default:return!1}}handleMenuNavigationKey(e,t){if(t.preventDefault(),!this.showOptions){this.showOptions=!0;return}this.pickerMenu.value?.doKeyboardNav(e),this.updateActiveDescendant()}get menuItems(){return this.typeahead?this.filteredItems:this.pickerItems}focus(){this.theInput.value?.focus()}setFormItemDescription(e){this.formItemDescription.setDescription(e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}updateActiveDescendant(){const e=this.theInput.value;if(!e||!this.pickerMenu.value)return;const t=this.pickerMenu.value.getHighlightedElement();e.ariaActiveDescendantElement=t}clearActiveDescendant(){const e=this.theInput.value;e&&(e.ariaActiveDescendantElement=null)}_scrollToContainPopover(){const e=this.pickerMenu.value;e&&I(this,e,()=>{this.pickerMenu.value?.updatePosition(this)})}syncSelectionFromItems(e){}willUpdate(e){super.willUpdate(e),this.syncSelectionFromItems(e),this.typeahead&&((e.has("pickerItems")||e.has("typeahead"))&&this.typeaheadCtrl.setAllItems(this.pickerItems),(e.has("fetchItems")||e.has("typeahead"))&&this.typeaheadCtrl.setFetchItems(this.fetchItems),(e.has("debounceMs")||e.has("typeahead"))&&this.debounceMs!==void 0&&this.typeaheadCtrl.setDebounceMs(this.debounceMs))}updated(e){super.updated(e),e.has("width")&&(this.width?this.style.width=this.width:this.style.removeProperty("width"))}firstUpdated(e){super.firstUpdated(e);const t=this.theInput.value;if(t&&(t.role="combobox",t.ariaHasPopup="listbox",t.ariaExpanded="false",t.ariaAutoComplete=this.typeahead?"list":"none",this.pickerMenu.value)){const a=t;a.ariaControlsElements=[this.pickerMenu.value]}const o=this.itemsSlot.value;o&&(this.extractSlotItems(o),o.addEventListener("slotchange",()=>this.extractSlotItems(o)))}extractSlotItems(e){this._slotExtractPending||(this._slotExtractPending=!0,queueMicrotask(()=>{this._slotExtractPending=!1;const t=e.assignedElements();if(t.length===0)return;const o=[];for(const a of t){if(!(a instanceof y))throw new Error(`Picker items must be of type esp-picker-item, but got <${a.tagName.toLowerCase()}>`);const s=a,n=Array.from(s.childNodes),l=n.length>0?n.map(m=>m.cloneNode(!0)):void 0;o.push({text:s.text||s.getAttribute("text")||s.textContent?.trim()||"",value:s.value||s.getAttribute("value")||"",selected:s.selected||s.hasAttribute("selected"),icon:s.icon||s.getAttribute("icon")||"",styles:s.styles,slotNodes:l})}this.pickerItems=o;for(const a of t)a.remove()}))}}i.formAssociated=!0,i.KEYBOARD_THRESHOLD=150,i.pickerFieldStyles=v`
2
+ :host([disabled]) {
3
+ pointer-events: none;
4
+ opacity: 0.5;
5
+ }
6
+
7
+ .esp-field {
8
+ display: grid;
9
+ grid-template-columns: auto min-content;
10
+ position: relative;
11
+
12
+ > section {
13
+ cursor: pointer;
14
+ display: flex;
15
+ flex-wrap: wrap;
16
+ }
17
+
18
+ > label {
19
+ display: grid;
20
+ place-content: center;
21
+ cursor: pointer;
22
+
23
+ > svg {
24
+ height: var(--esp-size-normal-to-medium);
25
+ width: var(--esp-size-normal-to-medium);
26
+ }
27
+ }
28
+ }
29
+
30
+ :host([typeahead]) .esp-field > section {
31
+ cursor: text;
32
+ }
33
+ `,r([p()],i.prototype,"showOptions",null),r([p()],i.prototype,"typeaheadLoading",void 0),r([p()],i.prototype,"filteredItems",void 0),r([p()],i.prototype,"inputFocused",void 0),r([h({type:Boolean,reflect:!0})],i.prototype,"typeahead",void 0),r([h({attribute:!1})],i.prototype,"fetchItems",void 0),r([h({type:Number,attribute:"debounce-ms"})],i.prototype,"debounceMs",void 0),r([h({type:String,reflect:!0})],i.prototype,"name",void 0),r([h({type:Boolean,reflect:!0})],i.prototype,"required",void 0),r([h({attribute:"required-message"})],i.prototype,"requiredMessage",void 0),r([h({type:Boolean,reflect:!0})],i.prototype,"disabled",void 0),r([h({type:Array})],i.prototype,"pickerItems",void 0),r([h({type:String})],i.prototype,"placeholder",void 0),r([h({type:String})],i.prototype,"width",void 0);export{i as EspalierPickerBase};
@@ -106,8 +106,6 @@ export declare class EspalierPickerMenu extends LitElement {
106
106
  * Uses the Popover API to render in the top layer, escaping any
107
107
  * ancestor `overflow: hidden` clipping.
108
108
  *
109
- * //TODO: Show the menu full screen on mobile...
110
- *
111
109
  * @param relativeTo The element to place the picker above or below.
112
110
  */
113
111
  positionSelf(relativeTo: HTMLElement): void;
@@ -1,4 +1,4 @@
1
- var n=function(d,t,e,i){var l=arguments.length,s=l<3?t:i===null?i=Object.getOwnPropertyDescriptor(t,e):i,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(d,t,e,i);else for(var h=d.length-1;h>=0;h--)(o=d[h])&&(s=(l<3?o(s):l>3?o(t,e,s):o(t,e))||s);return l>3&&s&&Object.defineProperty(t,e,s),s};import{LitElement as u,css as f,html as p}from"lit";import{customElement as v,property as g,state as m}from"lit/decorators.js";import{createRef as y,ref as I}from"lit/directives/ref.js";import{styleMap as x}from"lit/directives/style-map.js";import"../shared/virtualizer/lit-virtualizer.js";const c="highlighted";let r=class extends u{constructor(){super(),this.internals=this.attachInternals(),this.virtualizerRef=y(),this.maxAvailableHeight=0,this.lastViewportHeight=0,this.label="",this.virtualizedItemsPool=[],this.highlightIndex=-1,this.multiSelect=!1,this.loading=!1,this.emptyMessage="",this.handleItemPointerDown=t=>{this.selectItemFromPointerEvent(t)},this.renderPickerItem=(t,e)=>{const i={display:"block",cursor:"pointer",width:"100%",...t.styles};return p`<esp-picker-item
1
+ var n=function(d,t,e,i){var l=arguments.length,s=l<3?t:i===null?i=Object.getOwnPropertyDescriptor(t,e):i,r;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(d,t,e,i);else for(var o=d.length-1;o>=0;o--)(r=d[o])&&(s=(l<3?r(s):l>3?r(t,e,s):r(t,e))||s);return l>3&&s&&Object.defineProperty(t,e,s),s};import{LitElement as v,css as y,html as p}from"lit";import{customElement as I,property as g,state as u}from"lit/decorators.js";import{createRef as x,ref as b}from"lit/directives/ref.js";import{styleMap as P}from"lit/directives/style-map.js";import"../shared/virtualizer/lit-virtualizer.js";import{spaceAroundRect as f,viewportSize as m}from"../shared/viewport.js";const c="highlighted";let h=class extends v{constructor(){super(),this.internals=this.attachInternals(),this.virtualizerRef=x(),this.maxAvailableHeight=0,this.lastViewportHeight=0,this.label="",this.virtualizedItemsPool=[],this.highlightIndex=-1,this.multiSelect=!1,this.loading=!1,this.emptyMessage="",this.handleItemPointerDown=t=>{this.selectItemFromPointerEvent(t)},this.renderPickerItem=(t,e)=>{const i={display:"block",cursor:"pointer",width:"100%",...t.styles};return p`<esp-picker-item
2
2
  class="picker-item"
3
3
  data-picker-index=${e}
4
4
  .text=${t.text}
@@ -6,17 +6,17 @@ var n=function(d,t,e,i){var l=arguments.length,s=l<3?t:i===null?i=Object.getOwnP
6
6
  .selected=${t.selected}
7
7
  .icon=${t.icon??""}
8
8
  .highlightRanges=${t.highlightRanges}
9
- style=${x(i)}
9
+ style=${P(i)}
10
10
  >
11
11
  ${t.slotNodes?.map(l=>l.cloneNode(!0))}
12
- </esp-picker-item>`},this.internals.role="listbox"}connectedCallback(){super.connectedCallback(),this.setAttribute("popover","manual")}updated(t){super.updated(t),t.has("multiSelect")&&(this.internals.ariaMultiSelectable=String(this.multiSelect)),t.has("label")&&(this.internals.ariaLabel=this.label),(t.has("virtualizedItemsPool")||t.has("loading"))&&this.maxAvailableHeight>0&&this.matches(":popover-open")&&this.resizeAndHighlight(t.has("virtualizedItemsPool"))}get pickerItems(){return this.virtualizedItemsPool}set pickerItems(t){const e=this.virtualizedItemsPool.filter(s=>s.selected).map(s=>s.value);this.virtualizedItemsPool=t;const i=t.filter(s=>s.selected),l=i.map(s=>s.value);(e.length!==l.length||e.some((s,o)=>s!==l[o]))&&this.dispatchEvent(new CustomEvent("selection-changed",{detail:i,bubbles:!0,composed:!0}))}setHighlight(t){const e=this.virtualizedItemsPool;if(e.length===0)return;(this.highlightIndex<0||this.highlightIndex>e.length-1)&&(this.highlightIndex=t);const i=this.virtualizerRef.value;i&&i.scrollToIndex(this.highlightIndex,"nearest"),this.applyHighlightClass()}async setHighlightAsync(t){const e=this.virtualizedItemsPool;if(e.length===0)return;(this.highlightIndex<0||this.highlightIndex>e.length-1)&&(this.highlightIndex=t);const i=this.virtualizerRef.value;i&&(i.scrollToIndex(this.highlightIndex,"nearest"),await i.layoutComplete),this.applyHighlightClass()}applyHighlightClass(){this.clearHighlight();const t=this.getHighlightedElement();t&&t.classList.add(c)}clearHighlight(){const t=this.virtualizerRef.value;if(t)for(const e of t.querySelectorAll(`esp-picker-item.${c}`))e.classList.remove(c)}resetHighlight(){this.clearHighlight();const t=this.virtualizedItemsPool.find(e=>e.selected);this.highlightIndex=t?this.virtualizedItemsPool.indexOf(t):-1}applyHighlightWithRetry(t){if(!this.isConnected||!this.matches(":popover-open"))return;this.clearHighlight();const e=this.getHighlightedElement();if(e){e.classList.add(c);return}t>0&&requestAnimationFrame(()=>this.applyHighlightWithRetry(t-1))}getHighlightedElement(){if(this.highlightIndex<0)return null;const t=this.virtualizerRef.value;if(!t)return null;const e=t.querySelectorAll("esp-picker-item");for(const i of e)if(this.virtualizedItemsPool.findIndex(s=>s.value===i.value&&s.text===i.text)===this.highlightIndex)return i;return null}pickItem(t){for(const i of this.pickerItems)i===t?i.selected=!i.selected:this.multiSelect||(i.selected=!1);const e=this.virtualizedItemsPool.indexOf(t);if(e!==-1){this.highlightIndex=e,this.clearHighlight();const i=this.getHighlightedElement();i&&i.classList.add(c)}this.pickerItems=[...this.pickerItems],this.dispatchEvent(new CustomEvent("selection-changed",{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0})),this.multiSelect||this.dispatchEvent(new CustomEvent("close-menu",{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0}))}selectItemByIndex(t){const e=Number.isInteger(t)?this.virtualizedItemsPool[t]:void 0;return e?(this.pickItem(e),!0):!1}getPickerItemElementAtPoint(t,e){const i=this.shadowRoot?.querySelectorAll("esp-picker-item[data-picker-index]");if(!i)return null;for(const l of i){const s=l.getBoundingClientRect();if(t>=s.left&&t<=s.right&&e>=s.top&&e<=s.bottom)return l}return null}selectPickerItemElement(t){return t?this.selectItemByIndex(Number(t.dataset.pickerIndex)):!1}selectItemAtPoint(t,e){return this.selectPickerItemElement(this.getPickerItemElementAtPoint(t,e))}selectItemFromPointerEvent(t){const e=t.composedPath().find(l=>l instanceof HTMLElement&&l.matches("esp-picker-item[data-picker-index]"));return this.selectPickerItemElement(e??this.getPickerItemElementAtPoint(t.clientX,t.clientY))?(t.preventDefault(),t.stopPropagation(),!0):!1}positionSelf(t){const e=t.getBoundingClientRect(),i=window.innerHeight||document.documentElement.clientHeight,l=e.top,s=i-e.bottom,o=Math.max(Math.max(l,s)-75,0);this.maxAvailableHeight=o,this.lastViewportHeight=i,this.style.setProperty("height",`${o}px`),this.style.setProperty("min-width",`${e.width}px`),this.style.setProperty("left",`${e.left}px`),this.style.removeProperty("top"),this.style.removeProperty("bottom"),l>s?this.style.setProperty("bottom",`${i-e.top}px`):this.style.setProperty("top",`${e.bottom}px`),this.classList.remove("visible"),this.matches(":popover-open")||this.showPopover();const h=this.pickerItems.find(a=>a.selected);this.highlightIndex=h?this.pickerItems.indexOf(h):0,this.setHighlightAsync(0).then(()=>{requestAnimationFrame(()=>{this.shrinkToFit(o),this.widenToFitContent(e),this.classList.add("visible")})})}async resizeAndHighlight(t){try{await this.updateComplete}catch{return}if(!this.isConnected||!this.matches(":popover-open"))return;const e=this.virtualizerRef.value;if(!e){requestAnimationFrame(()=>{if(!this.isConnected)return;const s=this.shadowRoot?.querySelector(".status-message");if(s){const o=Math.min(s.scrollHeight,this.maxAvailableHeight);this.style.setProperty("height",`${o}px`)}});return}try{const s=e.layoutComplete;s&&await s}catch{return}if(!this.isConnected||!this.matches(":popover-open")||(e.scrollTop=0,this.sizeToContent(this.maxAvailableHeight),!t))return;try{const s=e.layoutComplete;s&&await s}catch{return}if(!this.isConnected||!this.matches(":popover-open"))return;const i=this.virtualizedItemsPool;if(i.length===0)return;const l=i.findIndex(s=>s.selected);l>=0?this.highlightIndex=l:this.highlightIndex>=i.length?this.highlightIndex=i.length-1:this.highlightIndex<0&&(this.highlightIndex=0);try{e.scrollToIndex(this.highlightIndex,"nearest")}catch{}try{const s=e.layoutComplete;s&&await s}catch{return}!this.isConnected||!this.matches(":popover-open")||this.applyHighlightWithRetry(3)}sizeToContent(t){const e=this.measureContentHeight();e>0&&this.style.setProperty("height",`${Math.min(e,t)}px`)}shrinkToFit(t){const e=this.measureContentHeight();e>2&&e<t&&this.style.setProperty("height",`${e}px`)}measureContentHeight(){const t=this.virtualizerRef.value;if(!t)return 0;const e=t.querySelectorAll("esp-picker-item");if(e.length===0)return 0;const i=getComputedStyle(this),l=(parseFloat(i.borderTopWidth)||0)+(parseFloat(i.borderBottomWidth)||0),s=this.virtualizedItemsPool.length;if(e.length<s)return t.scrollHeight+l;t.scrollTop=0;const o=t.getBoundingClientRect();return e[e.length-1].getBoundingClientRect().bottom-o.top+l}widenToFitContent(t){const e=this.virtualizerRef.value;if(!e)return;const i=e.querySelectorAll("esp-picker-item");let l=t.width;for(const s of i)l=Math.max(l,s.scrollWidth);if(l+=2,l>t.width){const s=window.innerWidth||document.documentElement.clientWidth,o=Math.min(l,s-t.left);this.style.setProperty("width",`${o}px`)}}updatePosition(t){const e=t.getBoundingClientRect(),i=window.innerHeight||document.documentElement.clientHeight;if(i!==this.lastViewportHeight){const o=e.top,h=i-e.bottom,a=Math.max(Math.max(o,h)-75,0);this.maxAvailableHeight=a,this.lastViewportHeight=i,(parseFloat(this.style.getPropertyValue("height"))||0)>a&&this.style.setProperty("height",`${a}px`),this.sizeToContent(a)}this.style.setProperty("left",`${e.left}px`);const l=e.top,s=i-e.bottom;l>s?(this.style.removeProperty("top"),this.style.setProperty("bottom",`${i-e.top}px`)):(this.style.removeProperty("bottom"),this.style.setProperty("top",`${e.bottom}px`))}hideMenu(){this.classList.remove("visible");try{this.hidePopover()}catch{}}doKeyboardNav(t){const e=this.virtualizedItemsPool;if(e.length!==0)switch(t){case"ArrowDown":this.highlightIndex+=1,this.setHighlight(0);break;case"ArrowUp":this.highlightIndex-=1,this.setHighlight(e.length-1);break;case"Home":this.highlightIndex=0,this.setHighlight(0);break;case"End":this.highlightIndex=e.length-1,this.setHighlight(e.length-1);break;case"Enter":if(this.highlightIndex===-1)return;this.pickItem(e[this.highlightIndex]);break}}render(){return this.loading?p`<div class="status-message">Searching…</div>`:this.virtualizedItemsPool.length===0&&this.emptyMessage?p`<div class="status-message">${this.emptyMessage}</div>`:p`<lit-virtualizer
13
- ${I(this.virtualizerRef)}
12
+ </esp-picker-item>`},this.internals.role="listbox"}connectedCallback(){super.connectedCallback(),this.setAttribute("popover","manual")}updated(t){super.updated(t),t.has("multiSelect")&&(this.internals.ariaMultiSelectable=String(this.multiSelect)),t.has("label")&&(this.internals.ariaLabel=this.label),(t.has("virtualizedItemsPool")||t.has("loading"))&&this.maxAvailableHeight>0&&this.matches(":popover-open")&&this.resizeAndHighlight(t.has("virtualizedItemsPool"))}get pickerItems(){return this.virtualizedItemsPool}set pickerItems(t){const e=this.virtualizedItemsPool.filter(s=>s.selected).map(s=>s.value);this.virtualizedItemsPool=t;const i=t.filter(s=>s.selected),l=i.map(s=>s.value);(e.length!==l.length||e.some((s,r)=>s!==l[r]))&&this.dispatchEvent(new CustomEvent("selection-changed",{detail:i,bubbles:!0,composed:!0}))}setHighlight(t){const e=this.virtualizedItemsPool;if(e.length===0)return;(this.highlightIndex<0||this.highlightIndex>e.length-1)&&(this.highlightIndex=t);const i=this.virtualizerRef.value;i&&i.scrollToIndex(this.highlightIndex,"nearest"),this.applyHighlightClass()}async setHighlightAsync(t){const e=this.virtualizedItemsPool;if(e.length===0)return;(this.highlightIndex<0||this.highlightIndex>e.length-1)&&(this.highlightIndex=t);const i=this.virtualizerRef.value;i&&(i.scrollToIndex(this.highlightIndex,"nearest"),await i.layoutComplete),this.applyHighlightClass()}applyHighlightClass(){this.clearHighlight();const t=this.getHighlightedElement();t&&t.classList.add(c)}clearHighlight(){const t=this.virtualizerRef.value;if(t)for(const e of t.querySelectorAll(`esp-picker-item.${c}`))e.classList.remove(c)}resetHighlight(){this.clearHighlight();const t=this.virtualizedItemsPool.find(e=>e.selected);this.highlightIndex=t?this.virtualizedItemsPool.indexOf(t):-1}applyHighlightWithRetry(t){if(!this.isConnected||!this.matches(":popover-open"))return;this.clearHighlight();const e=this.getHighlightedElement();if(e){e.classList.add(c);return}t>0&&requestAnimationFrame(()=>this.applyHighlightWithRetry(t-1))}getHighlightedElement(){if(this.highlightIndex<0)return null;const t=this.virtualizerRef.value;if(!t)return null;const e=t.querySelectorAll("esp-picker-item");for(const i of e)if(this.virtualizedItemsPool.findIndex(s=>s.value===i.value&&s.text===i.text)===this.highlightIndex)return i;return null}pickItem(t){for(const i of this.pickerItems)i===t?i.selected=!i.selected:this.multiSelect||(i.selected=!1);const e=this.virtualizedItemsPool.indexOf(t);if(e!==-1){this.highlightIndex=e,this.clearHighlight();const i=this.getHighlightedElement();i&&i.classList.add(c)}this.pickerItems=[...this.pickerItems],this.dispatchEvent(new CustomEvent("selection-changed",{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0})),this.multiSelect||this.dispatchEvent(new CustomEvent("close-menu",{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0}))}selectItemByIndex(t){const e=Number.isInteger(t)?this.virtualizedItemsPool[t]:void 0;return e?(this.pickItem(e),!0):!1}getPickerItemElementAtPoint(t,e){const i=this.shadowRoot?.querySelectorAll("esp-picker-item[data-picker-index]");if(!i)return null;for(const l of i){const s=l.getBoundingClientRect();if(t>=s.left&&t<=s.right&&e>=s.top&&e<=s.bottom)return l}return null}selectPickerItemElement(t){return t?this.selectItemByIndex(Number(t.dataset.pickerIndex)):!1}selectItemAtPoint(t,e){return this.selectPickerItemElement(this.getPickerItemElementAtPoint(t,e))}selectItemFromPointerEvent(t){const e=t.composedPath().find(l=>l instanceof HTMLElement&&l.matches("esp-picker-item[data-picker-index]"));return this.selectPickerItemElement(e??this.getPickerItemElementAtPoint(t.clientX,t.clientY))?(t.preventDefault(),t.stopPropagation(),!0):!1}positionSelf(t){const e=t.getBoundingClientRect(),{height:i}=m(),{spaceAbove:l,spaceBelow:s}=f(e,i),r=Math.max(Math.max(l,s)-75,0);this.maxAvailableHeight=r,this.lastViewportHeight=i,this.style.setProperty("height",`${r}px`),this.style.setProperty("min-width",`${e.width}px`),this.style.setProperty("left",`${e.left}px`),this.style.removeProperty("top"),this.style.removeProperty("bottom"),l>s?this.style.setProperty("bottom",`${i-e.top}px`):this.style.setProperty("top",`${e.bottom}px`),this.classList.remove("visible"),this.matches(":popover-open")||this.showPopover();const o=this.pickerItems.find(a=>a.selected);this.highlightIndex=o?this.pickerItems.indexOf(o):0,this.setHighlightAsync(0).then(()=>{requestAnimationFrame(()=>{this.shrinkToFit(r),this.widenToFitContent(e),this.classList.add("visible")})})}async resizeAndHighlight(t){try{await this.updateComplete}catch{return}if(!this.isConnected||!this.matches(":popover-open"))return;const e=this.virtualizerRef.value;if(!e){requestAnimationFrame(()=>{if(!this.isConnected)return;const s=this.shadowRoot?.querySelector(".status-message");if(s){const r=Math.min(s.scrollHeight,this.maxAvailableHeight);this.style.setProperty("height",`${r}px`)}});return}try{const s=e.layoutComplete;s&&await s}catch{return}if(!this.isConnected||!this.matches(":popover-open")||(e.scrollTop=0,this.sizeToContent(this.maxAvailableHeight),!t))return;try{const s=e.layoutComplete;s&&await s}catch{return}if(!this.isConnected||!this.matches(":popover-open"))return;const i=this.virtualizedItemsPool;if(i.length===0)return;const l=i.findIndex(s=>s.selected);l>=0?this.highlightIndex=l:this.highlightIndex>=i.length?this.highlightIndex=i.length-1:this.highlightIndex<0&&(this.highlightIndex=0);try{e.scrollToIndex(this.highlightIndex,"nearest")}catch{}try{const s=e.layoutComplete;s&&await s}catch{return}!this.isConnected||!this.matches(":popover-open")||this.applyHighlightWithRetry(3)}sizeToContent(t){const e=this.measureContentHeight();e>0&&this.style.setProperty("height",`${Math.min(e,t)}px`)}shrinkToFit(t){const e=this.measureContentHeight();e>2&&e<t&&this.style.setProperty("height",`${e}px`)}measureContentHeight(){const t=this.virtualizerRef.value;if(!t)return 0;const e=t.querySelectorAll("esp-picker-item");if(e.length===0)return 0;const i=getComputedStyle(this),l=(parseFloat(i.borderTopWidth)||0)+(parseFloat(i.borderBottomWidth)||0),s=this.virtualizedItemsPool.length;if(e.length<s)return t.scrollHeight+l;t.scrollTop=0;const r=t.getBoundingClientRect();return e[e.length-1].getBoundingClientRect().bottom-r.top+l}widenToFitContent(t){const e=this.virtualizerRef.value;if(!e)return;const i=e.querySelectorAll("esp-picker-item");let l=t.width;for(const s of i)l=Math.max(l,s.scrollWidth);if(l+=2,l>t.width){const{width:s}=m(),r=Math.min(l,s-t.left);this.style.setProperty("width",`${r}px`)}}updatePosition(t){const e=t.getBoundingClientRect(),{height:i}=m();if(i!==this.lastViewportHeight){const{spaceAbove:r,spaceBelow:o}=f(e,i),a=Math.max(Math.max(r,o)-75,0);this.maxAvailableHeight=a,this.lastViewportHeight=i,(parseFloat(this.style.getPropertyValue("height"))||0)>a&&this.style.setProperty("height",`${a}px`),this.sizeToContent(a)}this.style.setProperty("left",`${e.left}px`);const l=e.top,s=i-e.bottom;l>s?(this.style.removeProperty("top"),this.style.setProperty("bottom",`${i-e.top}px`)):(this.style.removeProperty("bottom"),this.style.setProperty("top",`${e.bottom}px`))}hideMenu(){this.classList.remove("visible");try{this.hidePopover()}catch{}}doKeyboardNav(t){const e=this.virtualizedItemsPool;if(e.length!==0)switch(t){case"ArrowDown":this.highlightIndex+=1,this.setHighlight(0);break;case"ArrowUp":this.highlightIndex-=1,this.setHighlight(e.length-1);break;case"Home":this.highlightIndex=0,this.setHighlight(0);break;case"End":this.highlightIndex=e.length-1,this.setHighlight(e.length-1);break;case"Enter":if(this.highlightIndex===-1)return;this.pickItem(e[this.highlightIndex]);break}}render(){return this.loading?p`<div class="status-message">Searching…</div>`:this.virtualizedItemsPool.length===0&&this.emptyMessage?p`<div class="status-message">${this.emptyMessage}</div>`:p`<lit-virtualizer
13
+ ${b(this.virtualizerRef)}
14
14
  scroller
15
15
  .items=${this.virtualizedItemsPool}
16
16
  .renderItem=${this.renderPickerItem}
17
17
  @pointerdown=${this.handleItemPointerDown}
18
18
  @rangeChanged=${t=>{this.dispatchEvent(new CustomEvent("range-changed",{detail:{first:t.first,last:t.last,items:this.virtualizedItemsPool},bubbles:!0,composed:!0}))}}
19
- ></lit-virtualizer>`}};r.styles=f`
19
+ ></lit-virtualizer>`}};h.styles=y`
20
20
  :host {
21
21
  position: fixed;
22
22
  inset: unset;
@@ -54,4 +54,4 @@ var n=function(d,t,e,i){var l=arguments.length,s=l<3?t:i===null?i=Object.getOwnP
54
54
  font-style: italic;
55
55
  background: var(--esp-color-layer-2);
56
56
  }
57
- `,n([g({type:String})],r.prototype,"label",void 0),n([m()],r.prototype,"virtualizedItemsPool",void 0),n([m()],r.prototype,"highlightIndex",void 0),n([g({attribute:"multi-select",type:Boolean})],r.prototype,"multiSelect",void 0),n([g({type:Boolean})],r.prototype,"loading",void 0),n([g({type:String,attribute:"empty-message"})],r.prototype,"emptyMessage",void 0),r=n([v("esp-picker-menu")],r);export{r as EspalierPickerMenu};
57
+ `,n([g({type:String})],h.prototype,"label",void 0),n([u()],h.prototype,"virtualizedItemsPool",void 0),n([u()],h.prototype,"highlightIndex",void 0),n([g({attribute:"multi-select",type:Boolean})],h.prototype,"multiSelect",void 0),n([g({type:Boolean})],h.prototype,"loading",void 0),n([g({type:String,attribute:"empty-message"})],h.prototype,"emptyMessage",void 0),h=n([I("esp-picker-menu")],h);export{h as EspalierPickerMenu};
@@ -0,0 +1 @@
1
+ class t{constructor(e,n,s){this.item=e,this.hasPending=n,this.pending=s}static empty(){return new t(void 0,!1,void 0)}static resolve(e,n){const s=e.find(r=>r.value===n);return s?new t(s,!1,void 0):new t(void 0,!0,n)}static of(e){return new t(e,!1,void 0)}withProvisionalItem(e){return new t(e,this.hasPending,this.pending)}get value(){return this.item?.value}reapply(e){return this.hasPending?t.resolve(e,this.pending):this}}export{t as PickOneSelection};
@@ -1,6 +1,6 @@
1
- var n=function(u,t,e,r){var o=arguments.length,i=o<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,e):r,h;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(u,t,e,r);else for(var s=u.length-1;s>=0;s--)(h=u[s])&&(i=(o<3?h(i):o>3?h(t,e,i):h(t,e))||i);return o>3&&i&&Object.defineProperty(t,e,i),i};import{LitElement as b,css as T,html as w}from"lit";import{customElement as D,property as a,state as P}from"lit/decorators.js";import{createRef as g,ref as m}from"lit/directives/ref.js";import{findContainingPopovers as y,PopoverController as O}from"../shared/popover-controller.js";import{alignAttributeTextInheritance as C}from"../shared/style-fragments.js";let $=0,l=class extends b{constructor(){super(...arguments),this.popoverOpen=!1,this.thePopover=g(),this.popoverSlot=g(),this.targetSlot=g(),this.attachTo=null,this.showDelayTimer=null,this.hideDelayTimer=null,this.isHovered=!1,this.isFocused=!1,this.collisionRafId=0,this.popoverId=`esp-popover-${++$}`,this.popoverCtrl=new O({host:this,closeStrategy:"skip-list",isOpen:()=>this.popoverOpen,onShouldClose:()=>this.closePopover(),onPositionUpdate:()=>this.positionPopover(),getPositionElements:()=>[this.attachTo,this.thePopover.value],getInsideElements:()=>[this.thePopover.value??null],onOutsideClick:()=>this.closePopover()}),this.attach="below",this.collision="flip",this.align="start",this.offset="",this.offsetX=0,this.offsetY=0,this.trigger="click",this.showDelay=0,this.hideDelay=0,this.closePopover=()=>{this.cancelDelays(),this.cancelCollisionAdjustment();const t=this.thePopover.value;if(t&&this.popoverOpen)try{t.hidePopover()}catch{}this.popoverCtrl.stopTracking(),this.popoverCtrl.stopOutsideClick(),this.popoverOpen&&(this.popoverOpen=!1,this.dispatchEvent(new CustomEvent("popover-closed",{bubbles:!0,composed:!0})))},this.openPopover=()=>{this.scheduleOpen()},this.updatePosition=()=>{this.popoverOpen&&this.positionPopover()},this.toggleOpen=t=>{this.trigger==="click"&&(t.stopPropagation(),this.popoverOpen?this.closePopover():this.doOpen())}}cancelDelays(){this.showDelayTimer!==null&&(clearTimeout(this.showDelayTimer),this.showDelayTimer=null),this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null)}cancelCollisionAdjustment(){this.collisionRafId&&(cancelAnimationFrame(this.collisionRafId),this.collisionRafId=0)}applyPixelOffset(t,e){if(e===0)return t;const r=t.startsWith("calc(")&&t.endsWith(")")?t.slice(5,-1):t,o=e>0?"+":"-";return`calc(${r} ${o} ${Math.abs(e)}px)`}scheduleOpen(){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null),!this.popoverOpen&&(this.showDelay>0&&this.showDelayTimer===null?this.showDelayTimer=setTimeout(()=>{this.showDelayTimer=null,this.doOpen()},this.showDelay):this.showDelay<=0&&this.doOpen())}scheduleClose(){this.showDelayTimer!==null&&(clearTimeout(this.showDelayTimer),this.showDelayTimer=null),this.popoverOpen&&(this.hideDelay>0&&this.hideDelayTimer===null?this.hideDelayTimer=setTimeout(()=>{this.hideDelayTimer=null,this.closePopover()},this.hideDelay):this.hideDelay<=0&&this.closePopover())}doOpen(){if(this.popoverOpen)return;const t=y(this);this.popoverCtrl.publishCloseExcept(t),this.popoverOpen=!0,this.positionPopover(),this.popoverCtrl.startTracking(),this.popoverCtrl.startOutsideClick(),this.dispatchEvent(new CustomEvent("popover-opened",{bubbles:!0,composed:!0}))}positionPopover(){const t=this.thePopover.value;if(!t||!this.attachTo)return;const e=this.attachTo.getBoundingClientRect(),r=this.offset.length?this.offset:"0px";t.matches(":popover-open")||t.showPopover();const o=t.getBoundingClientRect(),i=window.innerHeight||document.documentElement.clientHeight,h=window.innerWidth||document.documentElement.clientWidth;this.cancelCollisionAdjustment();let s=this.attach;this.collision==="flip"&&(s==="above"&&e.top<o.height&&i-e.bottom>e.top?s="below":s==="below"&&i-e.bottom<o.height&&e.top>i-e.bottom?s="above":s==="left"&&e.left<o.width&&h-e.right>e.left?s="right":s==="right"&&h-e.right<o.width&&e.left>h-e.right&&(s="left"));let c="0px",f="0px";switch(s){case"above":c=`calc(${e.top-o.height}px - ${r})`;break;case"below":c=`calc(${e.bottom}px + ${r})`;break;case"left":f=`calc(${e.left-o.width}px - ${r})`;break;case"right":f=`calc(${e.right}px + ${r})`;break}if(s==="above"||s==="below")switch(this.align){case"start":f=`${e.left}px`;break;case"center":f=`${e.left+e.width/2-o.width/2}px`;break;case"end":f=`${e.right-o.width}px`;break}else switch(this.align){case"start":c=`${e.top}px`;break;case"center":c=`${e.top+e.height/2-o.height/2}px`;break;case"end":c=`${e.bottom-o.height}px`;break}f=this.applyPixelOffset(f,this.offsetX),c=this.applyPixelOffset(c,this.offsetY),t.style.top=c,t.style.left=f,this.collision!=="none"&&(this.collisionRafId=requestAnimationFrame(()=>{if(this.collisionRafId=0,!this.popoverOpen||!t.matches(":popover-open"))return;const p=t.getBoundingClientRect();let d=p.left;if(p.width>h?d=0:d=Math.min(Math.max(p.left,0),h-p.width),d!==p.left&&(t.style.left=`${d}px`),this.collision!=="shift")return;let v=p.top;p.height>i?v=0:v=Math.min(Math.max(p.top,0),i-p.height),v!==p.top&&(t.style.top=`${v}px`)}))}handleHoverEnter(){this.isHovered=!0,this.scheduleOpen()}handleHoverLeave(){if(this.isHovered=!1,this.trigger==="focus-hover"&&this.isFocused){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null);return}this.scheduleClose()}handleFocusIn(){this.isFocused=!0,this.scheduleOpen()}handleFocusOut(){if(this.isFocused=!1,this.trigger==="focus-hover"&&this.isHovered){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null);return}this.scheduleClose()}disconnectedCallback(){super.disconnectedCallback(),this.cancelDelays(),this.cancelCollisionAdjustment()}updated(t){t.has("trigger")&&(this.isHovered=!1,this.isFocused=!1,this.cancelDelays()),this.popoverOpen&&["attach","align","collision","offset","offsetX","offsetY"].some(e=>t.has(e))&&this.positionPopover()}firstUpdated(t){let e=this.targetSlot.value.assignedElements()[0];for(;e instanceof HTMLSlotElement;)e=e.assignedElements()[0];this.attachTo=e;const r=this.thePopover.value;r&&(r.setAttribute("popover","manual"),r.id=this.popoverId);const o=this.popoverSlot.value?.assignedElements();if(o?.length){let i=o[0];for(;i instanceof HTMLSlotElement;)i=i.assignedElements()[0];i&&(i["linked-popover"]=this,i.addEventListener("click",h=>{h.stopPropagation();const s=[this,...y(this)];this.popoverCtrl.publishCloseExcept(s)}))}}render(){return w`
1
+ var p=function(u,t,e,s){var i=arguments.length,o=i<3?t:s===null?s=Object.getOwnPropertyDescriptor(t,e):s,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(u,t,e,s);else for(var r=u.length-1;r>=0;r--)(l=u[r])&&(o=(i<3?l(o):i>3?l(t,e,o):l(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o};import{LitElement as m,css as y,html as b}from"lit";import{customElement as T,property as n,state as w}from"lit/decorators.js";import{createRef as f,ref as d}from"lit/directives/ref.js";import{findContainingPopovers as v,PopoverController as D}from"../shared/popover-controller.js";import{viewportSize as g}from"../shared/viewport.js";import{RafThrottle as P}from"../shared/raf-throttle.js";import{alignAttributeTextInheritance as O}from"../shared/style-fragments.js";let C=0,h=class extends m{constructor(){super(...arguments),this.popoverOpen=!1,this.thePopover=f(),this.popoverSlot=f(),this.targetSlot=f(),this.attachTo=null,this.showDelayTimer=null,this.hideDelayTimer=null,this.isHovered=!1,this.isFocused=!1,this.collisionFrame=new P(()=>this.applyCollisionAdjustment()),this.popoverId=`esp-popover-${++C}`,this.popoverCtrl=new D({host:this,closeStrategy:"skip-list",isOpen:()=>this.popoverOpen,onShouldClose:()=>this.closePopover(),onPositionUpdate:()=>this.positionPopover(),getPositionElements:()=>[this.attachTo,this.thePopover.value],getInsideElements:()=>[this.thePopover.value??null],onOutsideClick:()=>this.closePopover()}),this.attach="below",this.collision="flip",this.align="start",this.offset="",this.offsetX=0,this.offsetY=0,this.trigger="click",this.showDelay=0,this.hideDelay=0,this.closePopover=()=>{this.cancelDelays(),this.cancelCollisionAdjustment();const t=this.thePopover.value;if(t&&this.popoverOpen)try{t.hidePopover()}catch{}this.popoverCtrl.stopTracking(),this.popoverCtrl.stopOutsideClick(),this.popoverOpen&&(this.popoverOpen=!1,this.dispatchEvent(new CustomEvent("popover-closed",{bubbles:!0,composed:!0})))},this.openPopover=()=>{this.scheduleOpen()},this.updatePosition=()=>{this.popoverOpen&&this.positionPopover()},this.toggleOpen=t=>{this.trigger==="click"&&(t.stopPropagation(),this.popoverOpen?this.closePopover():this.doOpen())}}cancelDelays(){this.showDelayTimer!==null&&(clearTimeout(this.showDelayTimer),this.showDelayTimer=null),this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null)}cancelCollisionAdjustment(){this.collisionFrame.cancel()}applyPixelOffset(t,e){if(e===0)return t;const s=t.startsWith("calc(")&&t.endsWith(")")?t.slice(5,-1):t,i=e>0?"+":"-";return`calc(${s} ${i} ${Math.abs(e)}px)`}scheduleOpen(){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null),!this.popoverOpen&&(this.showDelay>0&&this.showDelayTimer===null?this.showDelayTimer=setTimeout(()=>{this.showDelayTimer=null,this.doOpen()},this.showDelay):this.showDelay<=0&&this.doOpen())}scheduleClose(){this.showDelayTimer!==null&&(clearTimeout(this.showDelayTimer),this.showDelayTimer=null),this.popoverOpen&&(this.hideDelay>0&&this.hideDelayTimer===null?this.hideDelayTimer=setTimeout(()=>{this.hideDelayTimer=null,this.closePopover()},this.hideDelay):this.hideDelay<=0&&this.closePopover())}doOpen(){if(this.popoverOpen)return;const t=v(this);this.popoverCtrl.publishCloseOthers(t),this.popoverOpen=!0,this.positionPopover(),this.popoverCtrl.startTracking(),this.popoverCtrl.startOutsideClick(),this.dispatchEvent(new CustomEvent("popover-opened",{bubbles:!0,composed:!0}))}positionPopover(){const t=this.thePopover.value;if(!t||!this.attachTo)return;const e=this.attachTo.getBoundingClientRect(),s=this.offset.length?this.offset:"0px";t.matches(":popover-open")||t.showPopover();const i=t.getBoundingClientRect(),{width:o,height:l}=g();this.cancelCollisionAdjustment();let r=this.attach;this.collision==="flip"&&(r==="above"&&e.top<i.height&&l-e.bottom>e.top?r="below":r==="below"&&l-e.bottom<i.height&&e.top>l-e.bottom?r="above":r==="left"&&e.left<i.width&&o-e.right>e.left?r="right":r==="right"&&o-e.right<i.width&&e.left>o-e.right&&(r="left"));let a="0px",c="0px";switch(r){case"above":a=`calc(${e.top-i.height}px - ${s})`;break;case"below":a=`calc(${e.bottom}px + ${s})`;break;case"left":c=`calc(${e.left-i.width}px - ${s})`;break;case"right":c=`calc(${e.right}px + ${s})`;break}if(r==="above"||r==="below")switch(this.align){case"start":c=`${e.left}px`;break;case"center":c=`${e.left+e.width/2-i.width/2}px`;break;case"end":c=`${e.right-i.width}px`;break}else switch(this.align){case"start":a=`${e.top}px`;break;case"center":a=`${e.top+e.height/2-i.height/2}px`;break;case"end":a=`${e.bottom-i.height}px`;break}c=this.applyPixelOffset(c,this.offsetX),a=this.applyPixelOffset(a,this.offsetY),t.style.top=a,t.style.left=c,this.collision!=="none"&&this.collisionFrame.schedule()}applyCollisionAdjustment(){const t=this.thePopover.value;if(!t||!this.popoverOpen||!t.matches(":popover-open"))return;const{width:e,height:s}=g(),i=t.getBoundingClientRect();let o=i.left;if(i.width>e?o=0:o=Math.min(Math.max(i.left,0),e-i.width),o!==i.left&&(t.style.left=`${o}px`),this.collision!=="shift")return;let l=i.top;i.height>s?l=0:l=Math.min(Math.max(i.top,0),s-i.height),l!==i.top&&(t.style.top=`${l}px`)}handleHoverEnter(){this.isHovered=!0,this.scheduleOpen()}handleHoverLeave(){if(this.isHovered=!1,this.trigger==="focus-hover"&&this.isFocused){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null);return}this.scheduleClose()}handleFocusIn(){this.isFocused=!0,this.scheduleOpen()}handleFocusOut(){if(this.isFocused=!1,this.trigger==="focus-hover"&&this.isHovered){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null);return}this.scheduleClose()}disconnectedCallback(){super.disconnectedCallback(),this.cancelDelays(),this.cancelCollisionAdjustment()}updated(t){t.has("trigger")&&(this.isHovered=!1,this.isFocused=!1,this.cancelDelays()),this.popoverOpen&&["attach","align","collision","offset","offsetX","offsetY"].some(e=>t.has(e))&&this.positionPopover()}firstUpdated(t){let e=this.targetSlot.value.assignedElements()[0];for(;e instanceof HTMLSlotElement;)e=e.assignedElements()[0];this.attachTo=e;const s=this.thePopover.value;s&&(s.setAttribute("popover","manual"),s.id=this.popoverId);const i=this.popoverSlot.value?.assignedElements();if(i?.length){let o=i[0];for(;o instanceof HTMLSlotElement;)o=o.assignedElements()[0];o&&(o["linked-popover"]=this,o.addEventListener("click",l=>{l.stopPropagation();const r=[this,...v(this)];this.popoverCtrl.publishCloseOthers(r)}))}}render(){return b`
2
2
  <slot
3
- ${m(this.targetSlot)}
3
+ ${d(this.targetSlot)}
4
4
  @click=${t=>{this.trigger==="click"&&this.toggleOpen(t)}}
5
5
  @mouseenter=${()=>{this.trigger!=="hover"&&this.trigger!=="focus-hover"||this.handleHoverEnter()}}
6
6
  @mouseleave=${()=>{this.trigger!=="hover"&&this.trigger!=="focus-hover"||this.handleHoverLeave()}}
@@ -9,14 +9,14 @@ var n=function(u,t,e,r){var o=arguments.length,i=o<3?t:r===null?r=Object.getOwnP
9
9
  name="target"
10
10
  ></slot>
11
11
  <div
12
- ${m(this.thePopover)}
12
+ ${d(this.thePopover)}
13
13
  class="popover-content"
14
14
  @mouseenter=${()=>{this.trigger!=="hover"&&this.trigger!=="focus-hover"||(this.isHovered=!0,this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null))}}
15
15
  @mouseleave=${()=>{this.trigger!=="hover"&&this.trigger!=="focus-hover"||this.handleHoverLeave()}}
16
16
  >
17
- <slot name="popover" ${m(this.popoverSlot)}></slot>
17
+ <slot name="popover" ${d(this.popoverSlot)}></slot>
18
18
  </div>
19
- `}};l.styles=[C,T`
19
+ `}};h.styles=[O,y`
20
20
  :host {
21
21
  position: relative;
22
22
  display: flex;
@@ -33,4 +33,4 @@ var n=function(u,t,e,r){var o=arguments.length,i=o<3?t:r===null?r=Object.getOwnP
33
33
  overflow: visible;
34
34
  color: var(--esp-color-text);
35
35
  }
36
- `],n([P()],l.prototype,"popoverOpen",void 0),n([a({attribute:"attach",type:String})],l.prototype,"attach",void 0),n([a({attribute:"collision",type:String})],l.prototype,"collision",void 0),n([a({attribute:"align",type:String})],l.prototype,"align",void 0),n([a({attribute:"offset",type:String})],l.prototype,"offset",void 0),n([a({attribute:"offset-x",type:Number})],l.prototype,"offsetX",void 0),n([a({attribute:"offset-y",type:Number})],l.prototype,"offsetY",void 0),n([a({attribute:"trigger",type:String})],l.prototype,"trigger",void 0),n([a({attribute:"show-delay",type:Number})],l.prototype,"showDelay",void 0),n([a({attribute:"hide-delay",type:Number})],l.prototype,"hideDelay",void 0),l=n([D("esp-popover")],l);export{l as EspalierPopover};
36
+ `],p([w()],h.prototype,"popoverOpen",void 0),p([n({attribute:"attach",type:String})],h.prototype,"attach",void 0),p([n({attribute:"collision",type:String})],h.prototype,"collision",void 0),p([n({attribute:"align",type:String})],h.prototype,"align",void 0),p([n({attribute:"offset",type:String})],h.prototype,"offset",void 0),p([n({attribute:"offset-x",type:Number})],h.prototype,"offsetX",void 0),p([n({attribute:"offset-y",type:Number})],h.prototype,"offsetY",void 0),p([n({attribute:"trigger",type:String})],h.prototype,"trigger",void 0),p([n({attribute:"show-delay",type:Number})],h.prototype,"showDelay",void 0),p([n({attribute:"hide-delay",type:Number})],h.prototype,"hideDelay",void 0),h=p([T("esp-popover")],h);export{h as EspalierPopover};
@@ -1,14 +1,17 @@
1
1
  import { nothing, type PropertyValues, type TemplateResult } from "lit";
2
2
  import { EspalierElementBase } from "../shared/esp-element-base.js";
3
+ import { type CursorPageRequest, type CursorPageResult } from "../shared/cursor-pagination.js";
3
4
  import "../shared/virtualizer/lit-virtualizer.js";
4
- export interface RepeaterFetchParams {
5
- cursor: string | null;
6
- limit: number;
7
- }
8
- export interface RepeaterFetchResult<T = unknown> {
9
- items: T[];
10
- nextCursor: string | null;
11
- }
5
+ /**
6
+ * @deprecated Use `CursorPageRequest` from `shared/cursor-pagination.js`. This
7
+ * alias is retained for one release; the shape is unchanged.
8
+ */
9
+ export type RepeaterFetchParams = CursorPageRequest;
10
+ /**
11
+ * @deprecated Use `CursorPageResult` from `shared/cursor-pagination.js`. This
12
+ * alias is retained for one release; the shape is unchanged.
13
+ */
14
+ export type RepeaterFetchResult<T = unknown> = CursorPageResult<T>;
12
15
  export type RepeaterLayout = "list" | "grid";
13
16
  export type RepeaterScrollModel = "contained" | "page";
14
17
  export type RepeaterRenderValue = TemplateResult | Node | string | number | boolean | typeof nothing | null | undefined;