@taprootio/espalier 2.13.1 → 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.
- package/CHANGELOG.md +34 -0
- package/custom-elements.json +7051 -5344
- package/dist/date-picker/esp-date-picker.js +22 -22
- package/dist/flyout/esp-flyout.js +14 -14
- package/dist/font-picker/esp-font-picker.js +3 -3
- package/dist/form/esp-form.js +1 -1
- package/dist/grid/esp-grid.d.ts +4 -12
- package/dist/grid/esp-grid.js +5 -5
- package/dist/header/esp-header.js +7 -7
- package/dist/lightbox/esp-lightbox.js +16 -16
- package/dist/page/esp-page.d.ts +27 -14
- package/dist/page/esp-page.js +85 -33
- package/dist/page/workspace-width.js +1 -0
- package/dist/pickers/esp-pick-one.d.ts +9 -30
- package/dist/pickers/esp-pick-one.js +18 -50
- package/dist/pickers/esp-pick-some.d.ts +4 -29
- package/dist/pickers/esp-pick-some.js +15 -42
- package/dist/pickers/esp-picker-base.d.ts +95 -0
- package/dist/pickers/esp-picker-base.js +33 -1
- package/dist/pickers/esp-picker-menu.d.ts +0 -2
- package/dist/pickers/esp-picker-menu.js +6 -6
- package/dist/pickers/pick-one-selection.js +1 -0
- package/dist/popover/esp-popover.js +6 -6
- package/dist/repeater/esp-repeater.d.ts +11 -8
- package/dist/repeater/esp-repeater.js +4 -4
- package/dist/shared/color-engine.js +1 -1
- package/dist/shared/cursor-pagination.d.ts +76 -0
- package/dist/shared/cursor-pagination.js +1 -0
- package/dist/shared/intent-values.d.ts +13 -2
- package/dist/shared/intent-values.js +1 -1
- package/dist/shared/popover-controller.js +1 -1
- package/dist/shared/raf-throttle.js +1 -0
- package/dist/shared/utilities.d.ts +27 -27
- package/dist/shared/utilities.js +1 -1
- package/dist/shared/viewport.d.ts +89 -0
- package/dist/shared/viewport.js +1 -0
- package/package.json +9 -1
- package/dist/header/esp-menu-group.js +0 -1
- package/dist/header/esp-menu-item.js +0 -1
- package/dist/header/esp-menu.js +0 -1
|
@@ -3,7 +3,6 @@ import "./esp-picker-item.js";
|
|
|
3
3
|
import "./esp-picker-menu.js";
|
|
4
4
|
import { type PickerItem } from "./esp-picker-item.js";
|
|
5
5
|
import { EspalierPickerBase } from "./esp-picker-base.js";
|
|
6
|
-
import type { TypeaheadFetchItems } from "./types.js";
|
|
7
6
|
/**
|
|
8
7
|
* Component for selecting multiple options from a list of options.
|
|
9
8
|
*
|
|
@@ -154,34 +153,13 @@ import type { TypeaheadFetchItems } from "./types.js";
|
|
|
154
153
|
* @customElement esp-pick-some
|
|
155
154
|
*/
|
|
156
155
|
export declare class EspalierPickSome extends EspalierPickerBase {
|
|
156
|
+
protected decorateFilteredItems(items: PickerItem[]): PickerItem[];
|
|
157
|
+
/** Multi-select always clears the input — chips carry the selection. */
|
|
158
|
+
protected get typeaheadRestoreText(): string;
|
|
157
159
|
/**
|
|
158
160
|
* The values of all currently selected items.
|
|
159
161
|
*/
|
|
160
162
|
get values(): Array<string>;
|
|
161
|
-
/**
|
|
162
|
-
* When true, the picker input becomes a typeahead search field.
|
|
163
|
-
* The user types to filter the option list.
|
|
164
|
-
*
|
|
165
|
-
* @type {boolean}
|
|
166
|
-
*/
|
|
167
|
-
typeahead: boolean;
|
|
168
|
-
/**
|
|
169
|
-
* Async callback for fetching items from a remote source.
|
|
170
|
-
* When set alongside `typeahead`, the picker delegates to this
|
|
171
|
-
* callback instead of filtering locally.
|
|
172
|
-
*
|
|
173
|
-
* The callback receives the current query string and an
|
|
174
|
-
* `AbortSignal` that the component will abort when a newer
|
|
175
|
-
* query arrives before the previous request completes.
|
|
176
|
-
*/
|
|
177
|
-
fetchItems: TypeaheadFetchItems | null;
|
|
178
|
-
/**
|
|
179
|
-
* Debounce delay in milliseconds for typeahead input. Defaults
|
|
180
|
-
* to `0` for local filtering and `300` for remote fetching.
|
|
181
|
-
*
|
|
182
|
-
* @type {number}
|
|
183
|
-
*/
|
|
184
|
-
debounceMs: number | undefined;
|
|
185
163
|
/**
|
|
186
164
|
* Callback for adding a new value when the user types text
|
|
187
165
|
* that does not match any existing item. The callback receives
|
|
@@ -199,10 +177,7 @@ export declare class EspalierPickSome extends EspalierPickerBase {
|
|
|
199
177
|
} | null;
|
|
200
178
|
protected handlePickerReset(): void;
|
|
201
179
|
protected handlePickerRestore(state: string): void;
|
|
202
|
-
protected
|
|
203
|
-
protected get showOptions(): boolean;
|
|
204
|
-
protected willUpdate(changedProperties: PropertyValues): void;
|
|
205
|
-
protected firstUpdated(changedProperties: PropertyValues): void;
|
|
180
|
+
protected syncSelectionFromItems(changedProperties: PropertyValues): void;
|
|
206
181
|
protected render(): TemplateResult<1>;
|
|
207
182
|
static styles: import("lit").CSSResult[];
|
|
208
183
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
var
|
|
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=${
|
|
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=>
|
|
8
|
+
${this.selectedItems.map(e=>p`<span
|
|
9
9
|
class="selected-item"
|
|
10
|
-
@click=${
|
|
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
|
-
${
|
|
14
|
+
${d(this.theInput)}
|
|
15
15
|
class="esp-input"
|
|
16
16
|
placeholder=${this.placeholder}
|
|
17
17
|
?readonly=${!this.typeahead}
|
|
18
|
-
@input=${
|
|
18
|
+
@input=${this.handleTypeaheadInput}
|
|
19
19
|
@focus=${()=>{this.inputFocused=!0}}
|
|
20
|
-
@blur=${
|
|
21
|
-
@keydown=${e=>{if(this.pickerMenu.value)switch(e.key){case"
|
|
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=${
|
|
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.
|
|
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
|
-
${
|
|
40
|
+
${d(this.pickerMenu)}
|
|
41
41
|
multi-select
|
|
42
|
-
@selection-changed=${e=>{if(e.stopPropagation(),this.typeahead){const
|
|
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 ${
|
|
47
|
-
`}};r.styles=[...
|
|
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
|
|
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,
|
|
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=${
|
|
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,
|
|
13
|
-
${
|
|
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>`}};
|
|
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})],
|
|
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
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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" ${
|
|
17
|
+
<slot name="popover" ${d(this.popoverSlot)}></slot>
|
|
18
18
|
</div>
|
|
19
|
-
`}};
|
|
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
|
-
`],
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
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;
|