@taprootio/espalier 2.1.3 → 2.3.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.
@@ -25,7 +25,12 @@ export type EspalierFormField = {
25
25
  * </esp-box>
26
26
  * ```
27
27
  *
28
+ * @slot - The single form control the item wraps.
29
+ * @slot hint - Rich hint content; replaces the `hint` attribute text when present.
30
+ *
28
31
  * @cssprop --esp-form-item-label-color - The color of the label text.
32
+ * @cssprop --esp-form-item-hint-color - The color of the hint text. Defaults to a muted variant of the body text color.
33
+ * @cssprop --esp-form-item-hint-font-size - The font size of the hint text. Defaults to `var(--esp-type-tiny)`.
29
34
  * @cssprop --esp-form-item-error-color - The color of the visible error badge text.
30
35
  * @cssprop --esp-form-item-error-background - The background color of the visible error badge.
31
36
  * @cssprop --esp-form-item-error-field-background - The background color applied to slotted fields while an error is shown.
@@ -55,6 +60,51 @@ export declare class EspalierFormItem extends LitElement {
55
60
  * focus captured.
56
61
  */
57
62
  autofocus: boolean;
63
+ /**
64
+ * Persistent helper text shown with the field — the bottom rung of
65
+ * the help ladder. Hints are static authored guidance such as an
66
+ * expected format; validation messaging belongs to `error` and
67
+ * `warning` and must not be routed through the hint. The hint stays
68
+ * visible while an error or warning badge is showing, and is
69
+ * announced to assistive technology as the field's description via
70
+ * `aria-describedby`.
71
+ *
72
+ * ```html
73
+ * <esp-box class="demo-form">
74
+ * <esp-form-item
75
+ * label="Employer ID"
76
+ * hint="Use the format XX-XXXXXXX.">
77
+ * <esp-input></esp-input>
78
+ * </esp-form-item>
79
+ * <esp-button label="Form Things"></esp-button>
80
+ * </esp-box>
81
+ * ```
82
+ *
83
+ * For rich hint content, slot markup into the `hint` slot instead;
84
+ * it replaces the attribute text when present.
85
+ *
86
+ * @type {string}
87
+ */
88
+ hint: string;
89
+ /**
90
+ * Where the hint renders. `below` (the default) places it directly
91
+ * under the field, above the error/warning badge rows. `above`
92
+ * places it between the label text and the field. Any other value
93
+ * falls back to `below`.
94
+ *
95
+ * ```html
96
+ * <esp-box class="demo-form">
97
+ * <esp-form-item
98
+ * label="Employer ID"
99
+ * hint="Use the format XX-XXXXXXX."
100
+ * hint-placement="above">
101
+ * <esp-input></esp-input>
102
+ * </esp-form-item>
103
+ * <esp-button label="Form Things"></esp-button>
104
+ * </esp-box>
105
+ * ```
106
+ */
107
+ hintPlacement: "below" | "above";
58
108
  /**
59
109
  * An error message to show for the given form control.
60
110
  *
@@ -119,6 +169,8 @@ export declare class EspalierFormItem extends LitElement {
119
169
  set errorPool(errors: Array<ValidationError>);
120
170
  protected firstUpdated(): void;
121
171
  protected updated(changed: PropertyValues): void;
172
+ connectedCallback(): void;
173
+ disconnectedCallback(): void;
122
174
  /**
123
175
  * Focus the assigned slotted field.
124
176
  */
@@ -1,11 +1,16 @@
1
- var i=function(n,r,e,o){var l=arguments.length,s=l<3?r:o===null?o=Object.getOwnPropertyDescriptor(r,e):o,p;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(n,r,e,o);else for(var c=n.length-1;c>=0;c--)(p=n[c])&&(s=(l<3?p(s):l>3?p(r,e,s):p(r,e))||s);return l>3&&s&&Object.defineProperty(r,e,s),s};import{LitElement as f,css as d,html as h}from"lit";import{customElement as m,property as a}from"lit/decorators.js";import{classMap as g}from"lit/directives/class-map.js";import{createRef as v,ref as u}from"lit/directives/ref.js";import{VALIDITY_CHANGED_EVENT as w}from"../shared/validation.js";let t=class extends f{constructor(){super(...arguments),this.fieldSlot=v(),this.theField={focus:()=>{}},this._errorSource="manual",this.label="",this.autofocus=!1,this._error="",this._warning="",this.fieldName="",this._errorPool=[]}get error(){return this._error}set error(r){this._setError(r,"manual")}_setError(r,e){const o=this._error;this._error=r,this._errorSource=e,this.requestUpdate("error",o)}get warning(){return this._warning}set warning(r){const e=this._warning;this._warning=r,this.requestUpdate("warning",e)}get errorPool(){return this._errorPool}set errorPool(r){const e=this._errorPool;this._errorPool=r,this.requestUpdate("errorPool",e);const o=r.filter(l=>l.fieldName===this.fieldName);if(o.length===0){this._errorSource==="pool"&&this._setError("","pool");return}this._setError(o[0].errorMessage,"pool")}firstUpdated(){if(this.fieldSlot.value?.assignedElements().length!=1)throw new Error("esp-form-item requires exactly one slotted element.");this.theField=this.fieldSlot.value?.assignedElements()[0],this.fieldName&&this.theField.setAttribute("name",this.fieldName),this.autofocus&&this.focus(),this.addEventListener(w,e=>{const o=e.detail;this._errorSource==="pool"&&this._error.length>0||(o.valid?this._errorSource==="native"&&this._setError("","manual"):this._setError(o.message,"native"))});const r=this.theField;r.addEventListener("invalid",e=>{e.preventDefault(),!(this._errorSource==="pool"&&this._error.length>0)&&"validationMessage"in r&&this._setError(r.validationMessage,"native")})}updated(r){if(super.updated(r),!r.has("fieldName"))return;const e=this.theField;e instanceof Element&&(this.fieldName?e.setAttribute("name",this.fieldName):e.removeAttribute("name"))}focus(r){(this.fieldSlot.value?.assignedElements()[0]??this.theField).focus(r)}render(){const r={"form-item":!0,"has-error":this.error.length>0,"has-warning":this.warning.length>0&&this.error.length===0};return h`
2
- <div class=${g(r)}>
1
+ var n=function(l,e,t,r){var o=arguments.length,i=o<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,h;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(l,e,t,r);else for(var d=l.length-1;d>=0;d--)(h=l[d])&&(i=(o<3?h(i):o>3?h(e,t,i):h(e,t))||i);return o>3&&i&&Object.defineProperty(e,t,i),i};import{LitElement as f,css as u,html as m,nothing as c}from"lit";import{customElement as g,property as a}from"lit/decorators.js";import{classMap as v}from"lit/directives/class-map.js";import{createRef as b,ref as y}from"lit/directives/ref.js";import{VALIDITY_CHANGED_EVENT as w}from"../shared/validation.js";let p=0,s=class extends f{constructor(){super(...arguments),this.fieldSlot=b(),this.theField={focus:()=>{}},this._errorSource="manual",this.label="",this.autofocus=!1,this.hint="",this.hintPlacement="below",this.hintId=`esp-form-item-hint-${++p}`,this.managedHintEl=null,this.appliedHintTokens=[],this.hintContentObserver=new MutationObserver(()=>{this.syncFieldDescribedBy()}),this._error="",this._warning="",this.fieldName="",this._errorPool=[],this.handleHintSlotChange=()=>{this.syncManagedHint(),this.observeConsumerHintContent(),this.requestUpdate(),this.syncFieldDescribedBy()}}get hasHint(){return!!this.hint||this.consumerHintElements().length>0}consumerHintElements(){return[...this.children].filter(e=>e.slot==="hint"&&!e.hasAttribute("data-esp-managed-hint"))}get error(){return this._error}set error(e){this._setError(e,"manual")}_setError(e,t){const r=this._error;this._error=e,this._errorSource=t,this.requestUpdate("error",r)}get warning(){return this._warning}set warning(e){const t=this._warning;this._warning=e,this.requestUpdate("warning",t)}get errorPool(){return this._errorPool}set errorPool(e){const t=this._errorPool;this._errorPool=e,this.requestUpdate("errorPool",t);const r=e.filter(o=>o.fieldName===this.fieldName);if(r.length===0){this._errorSource==="pool"&&this._setError("","pool");return}this._setError(r[0].errorMessage,"pool")}firstUpdated(){if(this.fieldSlot.value?.assignedElements().length!=1)throw new Error("esp-form-item requires exactly one slotted element.");this.theField=this.fieldSlot.value?.assignedElements()[0],this.fieldName&&this.theField.setAttribute("name",this.fieldName),this.syncFieldDescribedBy(),this.autofocus&&this.focus(),this.addEventListener(w,t=>{const r=t.detail;this._errorSource==="pool"&&this._error.length>0||(r.valid?this._errorSource==="native"&&this._setError("","manual"):this._setError(r.message,"native"))});const e=this.theField;e.addEventListener("invalid",t=>{t.preventDefault(),!(this._errorSource==="pool"&&this._error.length>0)&&"validationMessage"in e&&this._setError(e.validationMessage,"native")})}updated(e){if(super.updated(e),(e.has("hint")||e.has("hintPlacement"))&&(this.syncManagedHint(),this.syncFieldDescribedBy()),!e.has("fieldName"))return;const t=this.theField;t instanceof Element&&(this.fieldName?t.setAttribute("name",this.fieldName):t.removeAttribute("name"))}connectedCallback(){super.connectedCallback(),this.observeConsumerHintContent()}disconnectedCallback(){this.hintContentObserver.disconnect(),super.disconnectedCallback()}observeConsumerHintContent(){this.hintContentObserver.disconnect();for(const e of this.consumerHintElements())this.hintContentObserver.observe(e,{attributes:!0,attributeFilter:["id"],characterData:!0,childList:!0,subtree:!0})}syncManagedHint(){if(!(!!this.hint&&this.consumerHintElements().length===0)){this.managedHintEl?.remove(),this.managedHintEl=null;return}if(!this.managedHintEl){const t=document.createElement("span");t.slot="hint",t.id=this.hintId,t.toggleAttribute("data-esp-managed-hint",!0),this.managedHintEl=t,this.appendChild(t)}this.managedHintEl.textContent=this.hint}hintDescriptionIds(){return this.managedHintEl?[this.managedHintEl.id]:this.consumerHintElements().map(e=>(e.id||(e.id=`esp-form-item-hint-${++p}`),e.id))}hintDescriptionText(){if(!this.hasHint)return null;if(this.managedHintEl)return this.managedHintEl.textContent??"";const e=this.consumerHintElements();return e.length===0?this.hint:e.map(t=>t.textContent?.trim()??"").filter(Boolean).join(" ")}syncFieldDescribedBy(){const e=this.fieldSlot.value?.assignedElements()[0];if(!e)return;const t=this.hasHint?this.hintDescriptionIds():[],r=(e.getAttribute("aria-describedby")??"").split(/\s+/).filter(i=>i&&!this.appliedHintTokens.includes(i)&&!t.includes(i));this.appliedHintTokens=t;const o=[...r,...t];o.length>0?e.setAttribute("aria-describedby",o.join(" ")):e.removeAttribute("aria-describedby"),e.setFormItemDescription?.(this.hintDescriptionText())}focus(e){(this.fieldSlot.value?.assignedElements()[0]??this.theField).focus(e)}renderHint(){return m`
2
+ <div class="hint" aria-hidden=${this.hintPlacement==="above"?"true":c}>
3
+ <slot name="hint" @slotchange=${this.handleHintSlotChange}></slot>
4
+ </div>
5
+ `}render(){const e={"form-item":!0,"has-hint":this.hasHint,"has-error":this.error.length>0,"has-warning":this.warning.length>0&&this.error.length===0};return m`
6
+ <div class=${v(e)}>
3
7
  <label
4
- @click=${e=>{this.focus(),e.stopPropagation()}}
8
+ @click=${t=>{this.focus(),t.stopPropagation()}}
5
9
  >
6
- ${this.label}
7
- <slot ${u(this.fieldSlot)}></slot>
10
+ ${this.label} ${this.hintPlacement==="above"?this.renderHint():c}
11
+ <slot ${y(this.fieldSlot)}></slot>
8
12
  </label>
13
+ ${this.hintPlacement!=="above"?this.renderHint():c}
9
14
  <div class="error-message">
10
15
  <span>${this.error}</span>
11
16
  </div>
@@ -13,7 +18,7 @@ var i=function(n,r,e,o){var l=arguments.length,s=l<3?r:o===null?o=Object.getOwnP
13
18
  <span>${this.warning}</span>
14
19
  </div>
15
20
  </div>
16
- `}};t.styles=d`
21
+ `}};s.styles=u`
17
22
  .form-item {
18
23
  font-family: var(--esp-form-item-font, var(--esp-font-body));
19
24
  font-size: var(--esp-form-item-font-size, var(--esp-size-font));
@@ -25,6 +30,21 @@ var i=function(n,r,e,o){var l=arguments.length,s=l<3?r:o===null?o=Object.getOwnP
25
30
  color: var(--esp-form-item-label-color, var(--esp-color-text));
26
31
  }
27
32
 
33
+ .hint {
34
+ display: none;
35
+ font-size: var(--esp-form-item-hint-font-size, var(--esp-type-tiny));
36
+ font-weight: normal;
37
+ color: var(--esp-form-item-hint-color, oklch(from var(--esp-color-text) l c h / 0.7));
38
+ }
39
+
40
+ > .hint {
41
+ margin: var(--esp-size-tiny) 0;
42
+ }
43
+
44
+ &.has-hint .hint {
45
+ display: block;
46
+ }
47
+
28
48
  > .error-message {
29
49
  font-size: var(--esp-type-tiny);
30
50
  color: var(
@@ -126,4 +146,4 @@ var i=function(n,r,e,o){var l=arguments.length,s=l<3?r:o===null?o=Object.getOwnP
126
146
  }
127
147
  }
128
148
  }
129
- `,i([a({type:String})],t.prototype,"label",void 0),i([a({type:Boolean,reflect:!0})],t.prototype,"autofocus",void 0),i([a({type:String})],t.prototype,"error",null),i([a({type:String})],t.prototype,"warning",null),i([a({attribute:"field-name",type:String})],t.prototype,"fieldName",void 0),i([a({attribute:"error-pool",type:Array})],t.prototype,"errorPool",null),t=i([m("esp-form-item")],t);export{t as EspalierFormItem};
149
+ `,n([a({type:String})],s.prototype,"label",void 0),n([a({type:Boolean,reflect:!0})],s.prototype,"autofocus",void 0),n([a({type:String})],s.prototype,"hint",void 0),n([a({attribute:"hint-placement",type:String})],s.prototype,"hintPlacement",void 0),n([a({type:String})],s.prototype,"error",null),n([a({type:String})],s.prototype,"warning",null),n([a({attribute:"field-name",type:String})],s.prototype,"fieldName",void 0),n([a({attribute:"error-pool",type:Array})],s.prototype,"errorPool",null),s=n([g("esp-form-item")],s);export{s as EspalierFormItem};
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ export * from "./breadcrumbs/esp-breadcrumbs.js";
14
14
  export * from "./button/esp-button.js";
15
15
  export * from "./button/esp-button-group.js";
16
16
  export * from "./color-picker/esp-color-picker.js";
17
+ export * from "./flyout/esp-flyout.js";
17
18
  export * from "./form/esp-form.js";
18
19
  export * from "./form-item/esp-form-item.js";
19
20
  export * from "./header/index.js";
@@ -57,7 +58,8 @@ export { type ValidationError, VALIDITY_CHANGED_EVENT, type ValidityChangedDetai
57
58
  export { FormFieldController, type FormFieldControllerOptions, } from "./shared/form-field-controller.js";
58
59
  export { traverseToClosest } from "./shared/utilities.js";
59
60
  export { showToast, type ToastConfig } from "./shared/toast-events.js";
60
- export { getEspBus, type EspBusEventMap, type SchemeEvents, type ToastEvents, type PopoverEvents, type SizeEvents, type PageEventMap, type SeedColorRoot, } from "./shared/bus-events.js";
61
+ export { showFlyout, closeFlyout, type FlyoutConfig, type FlyoutCloseReason, } from "./shared/flyout-events.js";
62
+ export { getEspBus, type EspBusEventMap, type SchemeEvents, type ToastEvents, type FlyoutEvents, type PopoverEvents, type SizeEvents, type PageEventMap, type SeedColorRoot, } from "./shared/bus-events.js";
61
63
  export * from "./shared/events.js";
62
64
  export { getImageDetails, releasePreviewUrl, type EspalierUploadImage, type ImageDetailsOptions, type SelectedUploadImage, type ExistingUploadImage, type ExistingImage, type ResponsiveImageUrl, type UploadCallbacks, type UploadEventDetail, } from "./image-upload/image-helpers.js";
63
65
  export { calculatePhotoLayout, type LayoutImage, type PhotoRow, } from "./shared/justified-layout.js";
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export*from"./box/esp-box.js";export*from"./action-menu/esp-action-menu.js";export*from"./action-menu/esp-action-menu-item.js";export*from"./avatar/esp-avatar.js";export*from"./avatar/esp-profile-chip.js";export*from"./badge/esp-badge.js";export*from"./checkbox/esp-checkbox.js";export*from"./checkbox/esp-checkbox-group.js";export*from"./data-cell/esp-data-cell.js";export*from"./radio-button/esp-radio-button.js";export*from"./radio-button/esp-radio-button-group.js";export*from"./repeater/esp-repeater.js";export*from"./breadcrumbs/esp-breadcrumbs.js";export*from"./button/esp-button.js";export*from"./button/esp-button-group.js";export*from"./color-picker/esp-color-picker.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./popover/esp-popover.js";export*from"./dialog/esp-dialog.js";export*from"./empty-state/esp-empty-state.js";export*from"./image-upload/esp-image-upload.js";export*from"./file-upload/esp-file-upload.js";export*from"./font-picker/esp-font-picker.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./lightbox/esp-lightbox.js";export*from"./info/esp-info.js";export*from"./input/esp-input.js";export*from"./textarea/esp-textarea.js";export*from"./pickers/esp-pick-one.js";export*from"./pickers/esp-pick-some.js";export*from"./pickers/esp-picker-menu.js";export*from"./pickers/esp-picker-item.js";export*from"./root/esp-root.js";export*from"./menu/index.js";export*from"./burger/esp-burger.js";export*from"./date-picker/esp-date-picker.js";export*from"./details/esp-details.js";export*from"./details/esp-details-group.js";export*from"./tabs/esp-tab.js";export*from"./tabs/esp-tab-group.js";export*from"./slider/esp-slider.js";export*from"./switch/esp-switch.js";export*from"./toaster/esp-toaster.js";export*from"./tooltip/esp-tooltip.js";export*from"./progress/esp-progress.js";export*from"./search/esp-search.js";export*from"./status-indicator/esp-status-indicator.js";export*from"./tree/esp-tree.js";export*from"./tree/esp-tree-item.js";import{DEFAULT_ICON_SPRITE_URL as ro,DEFAULT_ICON_VIEW_BOX as eo,INTENT_VARIANTS as to,normalizeIntentVariant as mo,getIconHref as po,getIconHrefForHost as fo,getIconSpriteUrl as xo}from"./shared/intent-values.js";import{EspalierElementBase as lo}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as so}from"./shared/validation.js";import{FormFieldController as io}from"./shared/form-field-controller.js";import{traverseToClosest as Io}from"./shared/utilities.js";import{showToast as _o}from"./shared/toast-events.js";import{getEspBus as co}from"./shared/bus-events.js";export*from"./shared/events.js";import{getImageDetails as Lo,releasePreviewUrl as No}from"./image-upload/image-helpers.js";import{calculatePhotoLayout as Ho}from"./shared/justified-layout.js";import{encodeTheme as bo,parseTheme as uo,mergePartials as Co,layerThemes as Uo,buildTaprootLightTheme as Vo,buildTaprootDarkTheme as Wo,NESTED_THEME_KEYS as Bo}from"./shared/theme.js";import{WEIGHT_LABELS as vo,extractWeights as yo,normalizeWeight as Go,bestAvailableWeight as Oo,extractFamily as Ro,getFallbackFont as ko}from"./shared/font-helpers.js";import{getGoogleFonts as zo}from"./font-picker/esp-font-picker.js";export{ro as DEFAULT_ICON_SPRITE_URL,eo as DEFAULT_ICON_VIEW_BOX,lo as EspalierElementBase,io as FormFieldController,to as INTENT_VARIANTS,Bo as NESTED_THEME_KEYS,so as VALIDITY_CHANGED_EVENT,vo as WEIGHT_LABELS,Oo as bestAvailableWeight,Wo as buildTaprootDarkTheme,Vo as buildTaprootLightTheme,Ho as calculatePhotoLayout,bo as encodeTheme,Ro as extractFamily,yo as extractWeights,co as getEspBus,ko as getFallbackFont,zo as getGoogleFonts,po as getIconHref,fo as getIconHrefForHost,xo as getIconSpriteUrl,Lo as getImageDetails,Uo as layerThemes,Co as mergePartials,mo as normalizeIntentVariant,Go as normalizeWeight,uo as parseTheme,No as releasePreviewUrl,_o as showToast,Io as traverseToClosest};
1
+ export*from"./box/esp-box.js";export*from"./action-menu/esp-action-menu.js";export*from"./action-menu/esp-action-menu-item.js";export*from"./avatar/esp-avatar.js";export*from"./avatar/esp-profile-chip.js";export*from"./badge/esp-badge.js";export*from"./checkbox/esp-checkbox.js";export*from"./checkbox/esp-checkbox-group.js";export*from"./data-cell/esp-data-cell.js";export*from"./radio-button/esp-radio-button.js";export*from"./radio-button/esp-radio-button-group.js";export*from"./repeater/esp-repeater.js";export*from"./breadcrumbs/esp-breadcrumbs.js";export*from"./button/esp-button.js";export*from"./button/esp-button-group.js";export*from"./color-picker/esp-color-picker.js";export*from"./flyout/esp-flyout.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./popover/esp-popover.js";export*from"./dialog/esp-dialog.js";export*from"./empty-state/esp-empty-state.js";export*from"./image-upload/esp-image-upload.js";export*from"./file-upload/esp-file-upload.js";export*from"./font-picker/esp-font-picker.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./lightbox/esp-lightbox.js";export*from"./info/esp-info.js";export*from"./input/esp-input.js";export*from"./textarea/esp-textarea.js";export*from"./pickers/esp-pick-one.js";export*from"./pickers/esp-pick-some.js";export*from"./pickers/esp-picker-menu.js";export*from"./pickers/esp-picker-item.js";export*from"./root/esp-root.js";export*from"./menu/index.js";export*from"./burger/esp-burger.js";export*from"./date-picker/esp-date-picker.js";export*from"./details/esp-details.js";export*from"./details/esp-details-group.js";export*from"./tabs/esp-tab.js";export*from"./tabs/esp-tab-group.js";export*from"./slider/esp-slider.js";export*from"./switch/esp-switch.js";export*from"./toaster/esp-toaster.js";export*from"./tooltip/esp-tooltip.js";export*from"./progress/esp-progress.js";export*from"./search/esp-search.js";export*from"./status-indicator/esp-status-indicator.js";export*from"./tree/esp-tree.js";export*from"./tree/esp-tree-item.js";import{DEFAULT_ICON_SPRITE_URL as eo,DEFAULT_ICON_VIEW_BOX as to,INTENT_VARIANTS as mo,normalizeIntentVariant as po,getIconHref as fo,getIconHrefForHost as xo,getIconSpriteUrl as ao}from"./shared/intent-values.js";import{EspalierElementBase as so}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as Eo}from"./shared/validation.js";import{FormFieldController as go}from"./shared/form-field-controller.js";import{traverseToClosest as no}from"./shared/utilities.js";import{showToast as _o}from"./shared/toast-events.js";import{showFlyout as co,closeFlyout as Ao}from"./shared/flyout-events.js";import{getEspBus as No}from"./shared/bus-events.js";export*from"./shared/events.js";import{getImageDetails as Ho,releasePreviewUrl as So}from"./image-upload/image-helpers.js";import{calculatePhotoLayout as yo}from"./shared/justified-layout.js";import{encodeTheme as Uo,parseTheme as Vo,mergePartials as Wo,layerThemes as Bo,buildTaprootLightTheme as Po,buildTaprootDarkTheme as vo,NESTED_THEME_KEYS as wo}from"./shared/theme.js";import{WEIGHT_LABELS as Oo,extractWeights as Ro,normalizeWeight as ko,bestAvailableWeight as zo,extractFamily as Yo,getFallbackFont as Ko}from"./shared/font-helpers.js";import{getGoogleFonts as Xo}from"./font-picker/esp-font-picker.js";export{eo as DEFAULT_ICON_SPRITE_URL,to as DEFAULT_ICON_VIEW_BOX,so as EspalierElementBase,go as FormFieldController,mo as INTENT_VARIANTS,wo as NESTED_THEME_KEYS,Eo as VALIDITY_CHANGED_EVENT,Oo as WEIGHT_LABELS,zo as bestAvailableWeight,vo as buildTaprootDarkTheme,Po as buildTaprootLightTheme,yo as calculatePhotoLayout,Ao as closeFlyout,Uo as encodeTheme,Yo as extractFamily,Ro as extractWeights,No as getEspBus,Ko as getFallbackFont,Xo as getGoogleFonts,fo as getIconHref,xo as getIconHrefForHost,ao as getIconSpriteUrl,Ho as getImageDetails,Bo as layerThemes,Wo as mergePartials,po as normalizeIntentVariant,ko as normalizeWeight,Vo as parseTheme,So as releasePreviewUrl,co as showFlyout,_o as showToast,no as traverseToClosest};
@@ -1,4 +1,4 @@
1
- var r=function(p,e,t,i){var a=arguments.length,l=a<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")l=Reflect.decorate(p,e,t,i);else for(var u=p.length-1;u>=0;u--)(o=p[u])&&(l=(a<3?o(l):a>3?o(e,t,l):o(e,t))||l);return a>3&&l&&Object.defineProperty(e,t,l),l};import{css as _,html as c,nothing as b}from"lit";import{customElement as T,property as n,state as y}from"lit/decorators.js";import{ifDefined as h}from"lit/directives/if-defined.js";import{createRef as D,ref as f}from"lit/directives/ref.js";import{EspalierElementBase as g}from"../shared/esp-element-base.js";import{FormFieldController as x}from"../shared/form-field-controller.js";import{getIconHrefForHost as v}from"../shared/intent-values.js";import{SlottedIconController as M}from"../shared/slotted-icon-controller.js";import{renderSpriteIcon as I}from"../shared/svgs/render-sprite-icon.js";import{detectDatePattern as P,parseDateInput as C,formatDateForLocale as d}from"./date-locale.js";import{getPhoneLocalities as S,parsePhoneInput as $,formatPhoneForLocale as L}from"./tel-locale.js";let s=class extends g{constructor(){super(...arguments),this.internals=this.attachInternals(),this.theInput=D(),this.iconSlot=new M(this),this.formCtrl=new x({host:this,internals:this.internals,getFormValue:()=>this.value||null,getValidity:()=>this._getValidity(),getValidationAnchor:()=>this.theInput.value??this,onReset:()=>{this.value="",this._dateDisplayText="",this._dateManaged=!1,this._telDisplayText="",this._telManaged=!1,this._hasVisibleError=!1},onRestore:e=>{this.value=e,this.inputType==="date"&&e&&this._restoreDateDisplay(e),this.inputType==="tel"&&e&&this._restoreTelDisplay(e)},onDisabled:e=>{this.disabled=e}}),this._hasVisibleError=!1,this._datePattern=null,this._dateDisplayText="",this._dateManaged=!1,this._phoneLocalitiesCache=null,this._telDisplayText="",this._telManaged=!1,this.fieldName="",this.icon="",this.iconLabel="",this.inputType="text",this.forceLowercase=!1,this.value="",this.name="",this.required=!1,this.requiredMessage="",this.validationMessage="",this.disabled=!1,this.readonly=!1,this._trackVisibleError=e=>{const t=e.detail;this._hasVisibleError=!t.valid}}_getDatePattern(){return this._datePattern||(this._datePattern=P()),this._datePattern}_getPhoneLocalities(){if(!this._phoneLocalitiesCache){const e=this.telLocalities?this.telLocalities.trim().split(/\s+/):void 0;this._phoneLocalitiesCache=S(e)}return this._phoneLocalitiesCache}get _nativeInputType(){return this.inputType==="date"?"text":this.inputType}get _effectiveInputmode(){if(this.inputmode)return this.inputmode;switch(this.inputType){case"email":return"email";case"url":return"url";case"tel":return"tel";case"number":return"decimal";case"date":return"numeric";default:return}}get _displayValue(){return this.inputType==="date"?this._dateDisplayText:this.inputType==="tel"?this._telDisplayText:this.value}get _effectivePlaceholder(){if(this.placeholder!==void 0)return this.placeholder;if(this.inputType==="date")return this._getDatePattern().placeholder;if(this.inputType==="tel"){const e=this._getPhoneLocalities();return e.length>0?e[0].placeholder:void 0}}handleInput(e){const t=e.target;if(this.readonly){t.value=this._displayValue;return}let i=t.value;if(this.inputType==="date"){const a=i.replace(/[^\d/\-.\s]/g,"");if(a!==i){const l=i.length-a.length,o=Math.max(0,(t.selectionStart??a.length)-l);t.value=a,t.setSelectionRange(o,o),i=a}this._dateDisplayText=i,this._dateManaged=!0,i||(this.value="",this._syncInput());return}if(this.inputType==="tel"){const a=i.replace(/[^\d+\-.()\s]/g,"");if(a!==i){const l=i.length-a.length,o=Math.max(0,(t.selectionStart??a.length)-l);t.value=a,t.setSelectionRange(o,o),i=a}this._telDisplayText=i,this._telManaged=!0,i||(this.value="",this._syncInput());return}this.forceLowercase&&(i=i.toLowerCase()),this.value=t.value=i,this._syncInput()}_syncInput(){this._hasVisibleError?this.formCtrl.syncValue():this.formCtrl.syncValueSilently(),this.emitValueChanged(this.value)}_handleBlur(){this.inputType==="date"&&this._finalizeDateValue(),this.inputType==="tel"&&this._finalizeTelValue(),this.formCtrl.syncValue()}_finalizeDateValue(){const e=this._dateDisplayText;if(!e.trim()){this.value="",this._dateDisplayText="",this._dateManaged=!1,this.emitValueChanged(this.value);return}const t=this._getDatePattern(),i=C(e,t);i?(this._dateDisplayText=d(i,t),this.value=i.toString()):this.value=e,this._dateManaged=!0,this.requestUpdate(),this.emitValueChanged(this.value)}_finalizeTelValue(){const e=this._telDisplayText;if(!e.trim()){this.value="",this._telDisplayText="",this._telManaged=!1,this.emitValueChanged(this.value);return}const t=this._getPhoneLocalities(),i=$(e,t);i?(this._telDisplayText=i.displayText,this.value=i.e164):this.value=e,this._telManaged=!0,this.requestUpdate(),this.emitValueChanged(this.value)}_getValidity(){if(this.inputType==="date")return this._getDateValidity();if(this.inputType==="tel")return this._getTelValidity();const e=this.theInput.value;if(e&&!e.validity.valid){const t=e.validity,i={valueMissing:t.valueMissing,typeMismatch:t.typeMismatch,patternMismatch:t.patternMismatch,tooLong:t.tooLong,tooShort:t.tooShort,rangeUnderflow:t.rangeUnderflow,rangeOverflow:t.rangeOverflow,stepMismatch:t.stepMismatch,badInput:t.badInput};return{flags:i,message:this._getFriendlyMessage(i)}}return this.required&&!this.value?{flags:{valueMissing:!0},message:this.requiredMessage||"Please fill out this field."}:null}_getFriendlyMessage(e){if(e.valueMissing)return this.requiredMessage||"Please fill out this field.";if(e.typeMismatch){if(this.validationMessage)return this.validationMessage;switch(this.inputType){case"email":return"Please enter a valid email address.";case"url":return"Please enter a valid URL.";case"number":return"Please enter a valid number.";case"tel":return"Please enter a valid phone number.";default:return"Please enter a valid value."}}return e.patternMismatch?this.validationMessage||"Please match the requested format.":e.tooShort?`Must be at least ${this.minlength} characters.`:e.tooLong?`Must be no more than ${this.maxlength} characters.`:e.rangeUnderflow?`Value must be ${this.min} or greater.`:e.rangeOverflow?`Value must be ${this.max} or less.`:(e.stepMismatch||e.badInput,"Please enter a valid value.")}_getDateValidity(){if(this.required&&!this.value)return{flags:{valueMissing:!0},message:this.requiredMessage||"Please fill out this field."};if(!this.value)return null;let e;try{e=Temporal.PlainDate.from(this.value)}catch{return{flags:{typeMismatch:!0},message:this.validationMessage||"Please enter a valid date."}}if(this.min)try{const t=Temporal.PlainDate.from(this.min);if(Temporal.PlainDate.compare(e,t)<0){const i=this._getDatePattern(),a=d(t,i);return{flags:{rangeUnderflow:!0},message:`Date must be ${a} or later.`}}}catch{}if(this.max)try{const t=Temporal.PlainDate.from(this.max);if(Temporal.PlainDate.compare(e,t)>0){const i=this._getDatePattern(),a=d(t,i);return{flags:{rangeOverflow:!0},message:`Date must be ${a} or earlier.`}}}catch{}return null}_getTelValidity(){return this.required&&!this.value?{flags:{valueMissing:!0},message:this.requiredMessage||"Please fill out this field."}:this.value?/^\+\d+$/.test(this.value)?null:{flags:{typeMismatch:!0},message:this.validationMessage||"Please enter a valid phone number."}:null}focus(e){this.focusResolvedElementAfterUpdate(()=>this.theInput.value,e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}connectedCallback(){super.connectedCallback(),this.addEventListener("validity-changed",this._trackVisibleError),this.inputType==="date"&&this.value&&this._restoreDateDisplay(this.value),this.inputType==="tel"&&this.value&&this._restoreTelDisplay(this.value)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("validity-changed",this._trackVisibleError)}updated(e){super.updated(e),e.has("value")&&this.inputType==="date"&&!this._dateManaged&&this._restoreDateDisplay(this.value),e.has("value")&&this.inputType==="tel"&&!this._telManaged&&this._restoreTelDisplay(this.value),e.has("telLocalities")&&(this._phoneLocalitiesCache=null),this._dateManaged=!1,this._telManaged=!1}_restoreDateDisplay(e){if(!e){this._dateDisplayText="";return}try{const t=Temporal.PlainDate.from(e),i=this._getDatePattern();this._dateDisplayText=d(t,i)}catch{this._dateDisplayText=e}}_restoreTelDisplay(e){if(!e){this._telDisplayText="";return}const t=this._getPhoneLocalities();this._telDisplayText=L(e,t)}_handleIconClick(){this.disabled||!(this.hasIconSlotContent||v(this.icon,this).length>0)||this.dispatchEvent(new CustomEvent("icon-clicked",{bubbles:!0,composed:!0}))}get hasIconSlotContent(){return this.iconSlot.hasSlottedIcon(":scope > :not([slot]), :scope > [slot='']")}_getIconButtonLabel(){const e=this.iconLabel.trim();if(e)return e;const t=this.icon.trim();return t?`${this._humanizeIconName(t)} action`:"Input icon action"}_humanizeIconName(e){const t=e.replace(/[-_]+/gu," ").trim();return t?t.charAt(0).toUpperCase()+t.slice(1):"Icon"}render(){const e=this.inputType==="date",t=this.inputType==="number",i=this.inputType==="tel",a=e||t||i,l=v(this.icon,this),o=this.hasIconSlotContent,u=o||l.length>0,m=this._getIconButtonLabel();return c`
1
+ var r=function(p,e,t,i){var a=arguments.length,l=a<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")l=Reflect.decorate(p,e,t,i);else for(var u=p.length-1;u>=0;u--)(o=p[u])&&(l=(a<3?o(l):a>3?o(e,t,l):o(e,t))||l);return a>3&&l&&Object.defineProperty(e,t,l),l};import{css as _,html as c,nothing as b}from"lit";import{customElement as D,property as n,state as g}from"lit/decorators.js";import{ifDefined as h}from"lit/directives/if-defined.js";import{createRef as T,ref as f}from"lit/directives/ref.js";import{EspalierElementBase as y}from"../shared/esp-element-base.js";import{FormFieldController as x}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as M}from"../shared/form-field-description-controller.js";import{getIconHrefForHost as v}from"../shared/intent-values.js";import{SlottedIconController as I}from"../shared/slotted-icon-controller.js";import{renderSpriteIcon as C}from"../shared/svgs/render-sprite-icon.js";import{detectDatePattern as P,parseDateInput as S,formatDateForLocale as d}from"./date-locale.js";import{getPhoneLocalities as $,parsePhoneInput as w,formatPhoneForLocale as L}from"./tel-locale.js";let s=class extends y{constructor(){super(...arguments),this.internals=this.attachInternals(),this.theInput=T(),this.iconSlot=new I(this),this.formCtrl=new x({host:this,internals:this.internals,getFormValue:()=>this.value||null,getValidity:()=>this._getValidity(),getValidationAnchor:()=>this.theInput.value??this,onReset:()=>{this.value="",this._dateDisplayText="",this._dateManaged=!1,this._telDisplayText="",this._telManaged=!1,this._hasVisibleError=!1},onRestore:e=>{this.value=e,this.inputType==="date"&&e&&this._restoreDateDisplay(e),this.inputType==="tel"&&e&&this._restoreTelDisplay(e)},onDisabled:e=>{this.disabled=e}}),this.formItemDescription=new M({host:this,getTarget:()=>this.theInput.value}),this._hasVisibleError=!1,this._datePattern=null,this._dateDisplayText="",this._dateManaged=!1,this._phoneLocalitiesCache=null,this._telDisplayText="",this._telManaged=!1,this.fieldName="",this.icon="",this.iconLabel="",this.inputType="text",this.forceLowercase=!1,this.value="",this.name="",this.required=!1,this.requiredMessage="",this.validationMessage="",this.disabled=!1,this.readonly=!1,this._trackVisibleError=e=>{const t=e.detail;this._hasVisibleError=!t.valid}}_getDatePattern(){return this._datePattern||(this._datePattern=P()),this._datePattern}_getPhoneLocalities(){if(!this._phoneLocalitiesCache){const e=this.telLocalities?this.telLocalities.trim().split(/\s+/):void 0;this._phoneLocalitiesCache=$(e)}return this._phoneLocalitiesCache}get _nativeInputType(){return this.inputType==="date"?"text":this.inputType}get _effectiveInputmode(){if(this.inputmode)return this.inputmode;switch(this.inputType){case"email":return"email";case"url":return"url";case"tel":return"tel";case"number":return"decimal";case"date":return"numeric";default:return}}get _displayValue(){return this.inputType==="date"?this._dateDisplayText:this.inputType==="tel"?this._telDisplayText:this.value}get _effectivePlaceholder(){if(this.placeholder!==void 0)return this.placeholder;if(this.inputType==="date")return this._getDatePattern().placeholder;if(this.inputType==="tel"){const e=this._getPhoneLocalities();return e.length>0?e[0].placeholder:void 0}}handleInput(e){const t=e.target;if(this.readonly){t.value=this._displayValue;return}let i=t.value;if(this.inputType==="date"){const a=i.replace(/[^\d/\-.\s]/g,"");if(a!==i){const l=i.length-a.length,o=Math.max(0,(t.selectionStart??a.length)-l);t.value=a,t.setSelectionRange(o,o),i=a}this._dateDisplayText=i,this._dateManaged=!0,i||(this.value="",this._syncInput());return}if(this.inputType==="tel"){const a=i.replace(/[^\d+\-.()\s]/g,"");if(a!==i){const l=i.length-a.length,o=Math.max(0,(t.selectionStart??a.length)-l);t.value=a,t.setSelectionRange(o,o),i=a}this._telDisplayText=i,this._telManaged=!0,i||(this.value="",this._syncInput());return}this.forceLowercase&&(i=i.toLowerCase()),this.value=t.value=i,this._syncInput()}_syncInput(){this._hasVisibleError?this.formCtrl.syncValue():this.formCtrl.syncValueSilently(),this.emitValueChanged(this.value)}_handleBlur(){this.inputType==="date"&&this._finalizeDateValue(),this.inputType==="tel"&&this._finalizeTelValue(),this.formCtrl.syncValue()}_finalizeDateValue(){const e=this._dateDisplayText;if(!e.trim()){this.value="",this._dateDisplayText="",this._dateManaged=!1,this.emitValueChanged(this.value);return}const t=this._getDatePattern(),i=S(e,t);i?(this._dateDisplayText=d(i,t),this.value=i.toString()):this.value=e,this._dateManaged=!0,this.requestUpdate(),this.emitValueChanged(this.value)}_finalizeTelValue(){const e=this._telDisplayText;if(!e.trim()){this.value="",this._telDisplayText="",this._telManaged=!1,this.emitValueChanged(this.value);return}const t=this._getPhoneLocalities(),i=w(e,t);i?(this._telDisplayText=i.displayText,this.value=i.e164):this.value=e,this._telManaged=!0,this.requestUpdate(),this.emitValueChanged(this.value)}_getValidity(){if(this.inputType==="date")return this._getDateValidity();if(this.inputType==="tel")return this._getTelValidity();const e=this.theInput.value;if(e&&!e.validity.valid){const t=e.validity,i={valueMissing:t.valueMissing,typeMismatch:t.typeMismatch,patternMismatch:t.patternMismatch,tooLong:t.tooLong,tooShort:t.tooShort,rangeUnderflow:t.rangeUnderflow,rangeOverflow:t.rangeOverflow,stepMismatch:t.stepMismatch,badInput:t.badInput};return{flags:i,message:this._getFriendlyMessage(i)}}return this.required&&!this.value?{flags:{valueMissing:!0},message:this.requiredMessage||"Please fill out this field."}:null}_getFriendlyMessage(e){if(e.valueMissing)return this.requiredMessage||"Please fill out this field.";if(e.typeMismatch){if(this.validationMessage)return this.validationMessage;switch(this.inputType){case"email":return"Please enter a valid email address.";case"url":return"Please enter a valid URL.";case"number":return"Please enter a valid number.";case"tel":return"Please enter a valid phone number.";default:return"Please enter a valid value."}}return e.patternMismatch?this.validationMessage||"Please match the requested format.":e.tooShort?`Must be at least ${this.minlength} characters.`:e.tooLong?`Must be no more than ${this.maxlength} characters.`:e.rangeUnderflow?`Value must be ${this.min} or greater.`:e.rangeOverflow?`Value must be ${this.max} or less.`:(e.stepMismatch||e.badInput,"Please enter a valid value.")}_getDateValidity(){if(this.required&&!this.value)return{flags:{valueMissing:!0},message:this.requiredMessage||"Please fill out this field."};if(!this.value)return null;let e;try{e=Temporal.PlainDate.from(this.value)}catch{return{flags:{typeMismatch:!0},message:this.validationMessage||"Please enter a valid date."}}if(this.min)try{const t=Temporal.PlainDate.from(this.min);if(Temporal.PlainDate.compare(e,t)<0){const i=this._getDatePattern(),a=d(t,i);return{flags:{rangeUnderflow:!0},message:`Date must be ${a} or later.`}}}catch{}if(this.max)try{const t=Temporal.PlainDate.from(this.max);if(Temporal.PlainDate.compare(e,t)>0){const i=this._getDatePattern(),a=d(t,i);return{flags:{rangeOverflow:!0},message:`Date must be ${a} or earlier.`}}}catch{}return null}_getTelValidity(){return this.required&&!this.value?{flags:{valueMissing:!0},message:this.requiredMessage||"Please fill out this field."}:this.value?/^\+\d+$/.test(this.value)?null:{flags:{typeMismatch:!0},message:this.validationMessage||"Please enter a valid phone number."}:null}focus(e){this.focusResolvedElementAfterUpdate(()=>this.theInput.value,e)}setFormItemDescription(e){this.formItemDescription.setDescription(e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}connectedCallback(){super.connectedCallback(),this.addEventListener("validity-changed",this._trackVisibleError),this.inputType==="date"&&this.value&&this._restoreDateDisplay(this.value),this.inputType==="tel"&&this.value&&this._restoreTelDisplay(this.value)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("validity-changed",this._trackVisibleError)}updated(e){super.updated(e),e.has("value")&&this.inputType==="date"&&!this._dateManaged&&this._restoreDateDisplay(this.value),e.has("value")&&this.inputType==="tel"&&!this._telManaged&&this._restoreTelDisplay(this.value),e.has("telLocalities")&&(this._phoneLocalitiesCache=null),this._dateManaged=!1,this._telManaged=!1}_restoreDateDisplay(e){if(!e){this._dateDisplayText="";return}try{const t=Temporal.PlainDate.from(e),i=this._getDatePattern();this._dateDisplayText=d(t,i)}catch{this._dateDisplayText=e}}_restoreTelDisplay(e){if(!e){this._telDisplayText="";return}const t=this._getPhoneLocalities();this._telDisplayText=L(e,t)}_handleIconClick(){this.disabled||!(this.hasIconSlotContent||v(this.icon,this).length>0)||this.dispatchEvent(new CustomEvent("icon-clicked",{bubbles:!0,composed:!0}))}get hasIconSlotContent(){return this.iconSlot.hasSlottedIcon(":scope > :not([slot]), :scope > [slot='']")}_getIconButtonLabel(){const e=this.iconLabel.trim();if(e)return e;const t=this.icon.trim();return t?`${this._humanizeIconName(t)} action`:"Input icon action"}_humanizeIconName(e){const t=e.replace(/[-_]+/gu," ").trim();return t?t.charAt(0).toUpperCase()+t.slice(1):"Icon"}render(){const e=this.inputType==="date",t=this.inputType==="number",i=this.inputType==="tel",a=e||t||i,l=v(this.icon,this),o=this.hasIconSlotContent,u=o||l.length>0,m=this._getIconButtonLabel();return c`
2
2
  <div class="esp-field">
3
3
  <input
4
4
  id=${this.fieldName}
@@ -32,7 +32,7 @@ var r=function(p,e,t,i){var a=arguments.length,l=a<3?e:i===null?i=Object.getOwnP
32
32
  ${f(this.iconSlot.slotRef)}
33
33
  @slotchange=${this.iconSlot.handleSlotChange}
34
34
  ></slot>
35
- ${!o&&l?I(l):b}
35
+ ${!o&&l?C(l):b}
36
36
  </button>
37
37
  `:c`
38
38
  <span class="icon-slot-probe" hidden>
@@ -43,7 +43,7 @@ var r=function(p,e,t,i){var a=arguments.length,l=a<3?e:i===null?i=Object.getOwnP
43
43
  </span>
44
44
  `}
45
45
  </div>
46
- `}};s.formAssociated=!0,s.styles=[...g.styles,_`
46
+ `}};s.formAssociated=!0,s.styles=[...y.styles,_`
47
47
  .esp-field {
48
48
  margin: 1px;
49
49
  display: grid;
@@ -88,4 +88,4 @@ var r=function(p,e,t,i){var a=arguments.length,l=a<3?e:i===null?i=Object.getOwnP
88
88
  }
89
89
  }
90
90
  }
91
- `],r([y()],s.prototype,"_dateDisplayText",void 0),r([y()],s.prototype,"_telDisplayText",void 0),r([n({attribute:"field-name",type:String})],s.prototype,"fieldName",void 0),r([n({type:String})],s.prototype,"icon",void 0),r([n({attribute:"icon-label",type:String})],s.prototype,"iconLabel",void 0),r([n({attribute:"input-type",type:String})],s.prototype,"inputType",void 0),r([n({type:String})],s.prototype,"placeholder",void 0),r([n({attribute:"force-lowercase",type:Boolean})],s.prototype,"forceLowercase",void 0),r([n({type:String})],s.prototype,"value",void 0),r([n({type:String,reflect:!0})],s.prototype,"name",void 0),r([n({type:Boolean,reflect:!0})],s.prototype,"required",void 0),r([n({attribute:"required-message"})],s.prototype,"requiredMessage",void 0),r([n({attribute:"validation-message"})],s.prototype,"validationMessage",void 0),r([n({type:Boolean,reflect:!0})],s.prototype,"disabled",void 0),r([n({type:Boolean,reflect:!0})],s.prototype,"readonly",void 0),r([n({type:String})],s.prototype,"pattern",void 0),r([n({type:Number})],s.prototype,"minlength",void 0),r([n({type:Number})],s.prototype,"maxlength",void 0),r([n({type:String})],s.prototype,"min",void 0),r([n({type:String})],s.prototype,"max",void 0),r([n({type:Number})],s.prototype,"step",void 0),r([n({type:String})],s.prototype,"inputmode",void 0),r([n({attribute:"tel-localities",type:String})],s.prototype,"telLocalities",void 0),s=r([T("esp-input")],s);export{s as EspalierInput};
91
+ `],r([g()],s.prototype,"_dateDisplayText",void 0),r([g()],s.prototype,"_telDisplayText",void 0),r([n({attribute:"field-name",type:String})],s.prototype,"fieldName",void 0),r([n({type:String})],s.prototype,"icon",void 0),r([n({attribute:"icon-label",type:String})],s.prototype,"iconLabel",void 0),r([n({attribute:"input-type",type:String})],s.prototype,"inputType",void 0),r([n({type:String})],s.prototype,"placeholder",void 0),r([n({attribute:"force-lowercase",type:Boolean})],s.prototype,"forceLowercase",void 0),r([n({type:String})],s.prototype,"value",void 0),r([n({type:String,reflect:!0})],s.prototype,"name",void 0),r([n({type:Boolean,reflect:!0})],s.prototype,"required",void 0),r([n({attribute:"required-message"})],s.prototype,"requiredMessage",void 0),r([n({attribute:"validation-message"})],s.prototype,"validationMessage",void 0),r([n({type:Boolean,reflect:!0})],s.prototype,"disabled",void 0),r([n({type:Boolean,reflect:!0})],s.prototype,"readonly",void 0),r([n({type:String})],s.prototype,"pattern",void 0),r([n({type:Number})],s.prototype,"minlength",void 0),r([n({type:Number})],s.prototype,"maxlength",void 0),r([n({type:String})],s.prototype,"min",void 0),r([n({type:String})],s.prototype,"max",void 0),r([n({type:Number})],s.prototype,"step",void 0),r([n({type:String})],s.prototype,"inputmode",void 0),r([n({attribute:"tel-localities",type:String})],s.prototype,"telLocalities",void 0),s=r([D("esp-input")],s);export{s as EspalierInput};
@@ -34,6 +34,15 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
34
34
  *
35
35
  * @slot sidebar - Contextual navigation placed in the left aside.
36
36
  * @slot right - Content to place in the right aside.
37
+ * @slot flyout - A transient `esp-flyout` panel that lives on the
38
+ * canvas, outside the content surface. Closed it costs no width; open
39
+ * it claims the right canvas gutter first — the surface keeps its
40
+ * alignment weighting and shifts only as far as the flyout's width
41
+ * requires — then docks as a width-competing right sidebar when no
42
+ * gutter exists, and becomes an overlay drawer on small viewports.
43
+ * The persistent `right` aside and the transient flyout are
44
+ * complementary, not alternatives. A flyout opened with an `anchor`
45
+ * aligns to that trigger and stays in the same document scroll flow.
37
46
  * @slot footer - Content to place in the footer.
38
47
  * @slot - The main page content. The main content region applies
39
48
  * `contain: inline-size` so child components cannot push the
@@ -122,7 +131,16 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
122
131
  * only shows above the cap. Set to `none` to remove it.
123
132
  * @cssprop --esp-page-surface-border - An optional border on the inline
124
133
  * edges of the surface, for themes preferring a hairline over a shadow.
125
- * Defaults to `none` (e.g. `1px solid var(--esp-color-border)`).
134
+ * Defaults to `none` (e.g. `1px solid var(--esp-color-border)`). Combine
135
+ * with `--esp-page-surface-shadow: none` to switch the content frame
136
+ * from a drop shadow to a hairline, or turn both off for no frame.
137
+ * @cssprop --esp-page-main-background - The background of the main
138
+ * content well. Defaults to `transparent` (the well shows the page
139
+ * background). Set it to give the content well its own card color, or
140
+ * pair the transparent default with `--esp-page-surface-shadow: none`
141
+ * for content that floats directly on the page with no frame.
142
+ * @cssprop --esp-page-flyout-width - The width of the open flyout
143
+ * track (and of the `esp-flyout` overlay drawer). Defaults to `20rem`.
126
144
  * @cssprop --esp-page-fixed-header-offset - Offset reserved for fixed
127
145
  * headers. Defaults to `var(--esp-header-height)`.
128
146
  * @cssprop --esp-page-sticky-header-top - Top inset for sticky headers.
@@ -251,6 +269,7 @@ export declare class EspalierPage extends EspalierElementBase {
251
269
  * @param dialog The EspalierDialog to show.
252
270
  */
253
271
  AddDialog(dialog: EspalierDialog | DocumentFragment | HTMLElement): void;
272
+ protected firstUpdated(changedProperties: PropertyValues): void;
254
273
  protected updated(changedProperties: PropertyValues): void;
255
274
  protected render(): import("lit-html").TemplateResult<1>;
256
275
  static styles: import("lit").CSSResult[];
@@ -1,5 +1,5 @@
1
- var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,s):r,p;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(n,e,s,r);else for(var l=n.length-1;l>=0;l--)(p=n[l])&&(a=(d<3?p(a):d>3?p(e,s,a):p(e,s))||a);return d>3&&a&&Object.defineProperty(e,s,a),a};import{css as g,html as f}from"lit";import{customElement as u,property as i}from"lit/decorators.js";import{classMap as m}from"lit/directives/class-map.js";import{createRef as v,ref as w}from"lit/directives/ref.js";import{EspalierElementBase as h}from"../shared/esp-element-base.js";import{BiDirectionalStickyController as c}from"./bi-directional-sticky-controller.js";import{getEspBus as b}from"../shared/bus-events.js";import"../toaster/esp-toaster.js";let t=class extends h{constructor(){super(),this.dialogZone=v(),this.kind="wide",this.align="start",this.contained=!1,this.headerPosition="normal",this.fixedMenus=!1,new c(this,".esp-page-left > .sticky-wrapper"),new c(this,".esp-page-right > .sticky-wrapper")}AddDialog(e){this.dialogZone.value?.appendChild(e)}updated(e){super.updated(e),(e.has("fixedMenus")||e.has("headerPosition"))&&b().publish("fixed-menus-changed",{fixed:this.fixedMenus||this.headerPosition==="fixed"})}render(){const e=this.fixedMenus||this.headerPosition==="fixed",s=!e&&this.headerPosition==="sticky";return f`
2
- <div part="wrapper" class="esp-page ${m({"fixed-menus":e,"fixed-header":e,"sticky-header":s})}">
1
+ var d=function(h,e,s,o){var n=arguments.length,a=n<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,s):o,t;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(h,e,s,o);else for(var r=h.length-1;r>=0;r--)(t=h[r])&&(a=(n<3?t(a):n>3?t(e,s,a):t(e,s))||a);return n>3&&a&&Object.defineProperty(e,s,a),a};import{css as f,html as m}from"lit";import{customElement as v,property as l}from"lit/decorators.js";import{classMap as y}from"lit/directives/class-map.js";import{createRef as c,ref as u}from"lit/directives/ref.js";import{EspalierElementBase as g}from"../shared/esp-element-base.js";import{BiDirectionalStickyController as p}from"./bi-directional-sticky-controller.js";import{getEspBus as w}from"../shared/bus-events.js";import"../toaster/esp-toaster.js";let i=class extends g{constructor(){super(),this.dialogZone=c(),this.flyoutSlot=c(),this.kind="wide",this.align="start",this.contained=!1,this.headerPosition="normal",this.fixedMenus=!1,new p(this,".esp-page-left > .sticky-wrapper"),new p(this,".esp-page-right > .sticky-wrapper"),new p(this,".esp-page-flyout > .sticky-wrapper"),this.addEventListener("flyout-state-changed",e=>this.syncFlyoutState(e))}syncFlyoutState(e){if(e&&e.target?.closest?.("esp-page")!==this)return;const s=t=>{const r=t.mode;return(typeof r=="string"?r:t.getAttribute("mode"))==="overlay"},o=t=>{const r=t.open;return typeof r=="boolean"?r:t.hasAttribute("open")},n=t=>t.anchor!=null,a=(this.flyoutSlot.value?.assignedElements()??[]).filter(t=>t.tagName==="ESP-FLYOUT");this.toggleAttribute("flyout-open",a.some(t=>o(t)&&!s(t))),this.toggleAttribute("flyout-overlay-open",a.some(t=>o(t)&&s(t))),this.toggleAttribute("flyout-anchored",a.some(t=>o(t)&&n(t)))}AddDialog(e){this.dialogZone.value?.appendChild(e)}firstUpdated(e){super.firstUpdated(e),this.syncFlyoutState()}updated(e){super.updated(e),(e.has("fixedMenus")||e.has("headerPosition"))&&w().publish("fixed-menus-changed",{fixed:this.fixedMenus||this.headerPosition==="fixed"})}render(){const e=this.fixedMenus||this.headerPosition==="fixed",s=!e&&this.headerPosition==="sticky";return m`
2
+ <div part="wrapper" class="esp-page ${y({"fixed-menus":e,"fixed-header":e,"sticky-header":s})}">
3
3
  <div part="canvas" class="esp-page-canvas esp-page-canvas--left" aria-hidden="true"></div>
4
4
  <div part="canvas" class="esp-page-canvas esp-page-canvas--right" aria-hidden="true"></div>
5
5
  <div part="surface" class="esp-page-surface" aria-hidden="true"></div>
@@ -19,20 +19,40 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
19
19
  <slot name="right"></slot>
20
20
  </div>
21
21
  </aside>
22
+ <div class="esp-page-flyout">
23
+ <div class="sticky-wrapper">
24
+ <slot
25
+ name="flyout"
26
+ ${u(this.flyoutSlot)}
27
+ @slotchange=${()=>this.syncFlyoutState()}
28
+ ></slot>
29
+ </div>
30
+ </div>
22
31
  <footer>
23
32
  <slot name="footer"></slot>
24
33
  </footer>
25
- <div id="dialog-drop-zone" ${w(this.dialogZone)}></div>
34
+ <div id="dialog-drop-zone" ${u(this.dialogZone)}></div>
26
35
  <esp-toaster></esp-toaster>
27
36
  </div>
28
- `}};t.styles=[...h.styles,g`
37
+ `}};i.styles=[...g.styles,f`
29
38
  :host {
30
39
  --_esp-page-resolved-max-width: var(--esp-page-max-width, 1536px);
31
40
 
32
41
  --_esp-page-main-track: minmax(0, var(--_esp-page-resolved-max-width));
33
42
 
34
- --_esp-page-gutter-left: 0;
43
+ --_esp-page-gutter-left: 0fr;
35
44
  --_esp-page-gutter-right: 1fr;
45
+
46
+ --_esp-page-flyout-min: 0px;
47
+
48
+ --_esp-page-surface-edge-shadow: 0.75rem 0 1.5rem -0.75rem var(--esp-color-shadow);
49
+
50
+ --_esp-page-surface-shadow: var(
51
+ --esp-page-surface-shadow,
52
+ -0.75rem 0 1.5rem -0.75rem var(--esp-color-shadow),
53
+ var(--_esp-page-surface-edge-shadow)
54
+ );
55
+ --_esp-page-surface-border: var(--esp-page-surface-border, none);
36
56
  --_esp-page-fixed-header-offset: var(
37
57
  --esp-page-fixed-header-offset,
38
58
  var(--esp-header-height, calc(4.5 * var(--esp-size-small)))
@@ -52,15 +72,42 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
52
72
 
53
73
  :host([align="end"]) {
54
74
  --_esp-page-gutter-left: 1fr;
55
- --_esp-page-gutter-right: 0;
75
+ --_esp-page-gutter-right: 0fr;
56
76
  }
57
77
 
58
78
 
59
79
  :host([kind="full"]) {
60
80
  --_esp-page-resolved-max-width: var(--esp-page-max-width, none);
61
81
  --_esp-page-main-track: 1fr;
62
- --_esp-page-gutter-left: 0;
63
- --_esp-page-gutter-right: 0;
82
+ --_esp-page-gutter-left: 0fr;
83
+ --_esp-page-gutter-right: 0fr;
84
+ }
85
+
86
+
87
+ :host([flyout-open]) {
88
+ --_esp-page-flyout-min: var(--esp-page-flyout-width, 20rem);
89
+ }
90
+
91
+
92
+ @media (max-width: 50em) {
93
+ :host([flyout-open]) {
94
+ --_esp-page-flyout-min: 0px;
95
+ }
96
+ }
97
+
98
+
99
+ :host([flyout-overlay-open]) .esp-page > div.esp-page-flyout {
100
+ z-index: var(--esp-flyout-z-index, 3000);
101
+ }
102
+
103
+
104
+ :host([flyout-anchored]) .esp-page > div.esp-page-flyout > .sticky-wrapper {
105
+ position: static;
106
+ }
107
+
108
+
109
+ slot[name="flyout"]::slotted(esp-flyout[match-surface]) {
110
+ --esp-flyout-shadow: var(--_esp-page-surface-edge-shadow);
64
111
  }
65
112
 
66
113
 
@@ -116,8 +163,13 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
116
163
  [canvas-left-end surface-start left-start] min-content
117
164
  [left-end main-start] var(--_esp-page-main-track)
118
165
  [main-end right-start] min-content
119
- [right-end surface-end canvas-right-start] var(--_esp-page-gutter-right)
120
- [canvas-right-end full-end];
166
+ [right-end surface-end canvas-right-start flyout-start] minmax(
167
+ var(--_esp-page-flyout-min),
168
+ var(--_esp-page-gutter-right)
169
+ )
170
+ [flyout-end canvas-right-end full-end];
171
+
172
+ transition: grid-template-columns 0.25s ease;
121
173
  grid-template-rows:
122
174
  [top-start] min-content
123
175
  [top-end content-start] 1fr
@@ -173,6 +225,8 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
173
225
  position: relative;
174
226
  overflow: hidden;
175
227
 
228
+ background: var(--esp-page-main-background, transparent);
229
+
176
230
  contain: inline-size;
177
231
  }
178
232
 
@@ -181,6 +235,21 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
181
235
  }
182
236
 
183
237
 
238
+ > div.esp-page-flyout {
239
+
240
+ grid-column: flyout;
241
+ justify-self: start;
242
+ grid-row: content;
243
+ z-index: 5;
244
+ position: relative;
245
+
246
+
247
+ @media (max-width: 50em) {
248
+ z-index: var(--esp-flyout-z-index, 3000);
249
+ }
250
+ }
251
+
252
+
184
253
  > .esp-page-canvas {
185
254
 
186
255
  grid-row: top-start / footer-end;
@@ -204,6 +273,7 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
204
273
  }
205
274
 
206
275
  > .esp-page-canvas--right {
276
+
207
277
  grid-column: canvas-right;
208
278
  }
209
279
 
@@ -214,12 +284,8 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
214
284
  grid-row: top-start / footer-end;
215
285
  z-index: 2;
216
286
  pointer-events: none;
217
- box-shadow: var(
218
- --esp-page-surface-shadow,
219
- -0.75rem 0 1.5rem -0.75rem var(--esp-color-shadow),
220
- 0.75rem 0 1.5rem -0.75rem var(--esp-color-shadow)
221
- );
222
- border-inline: var(--esp-page-surface-border, none);
287
+ box-shadow: var(--_esp-page-surface-shadow);
288
+ border-inline: var(--_esp-page-surface-border);
223
289
  }
224
290
 
225
291
 
@@ -270,6 +336,7 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
270
336
  > div.esp-page-main,
271
337
  > aside.esp-page-left,
272
338
  > aside.esp-page-right,
339
+ > div.esp-page-flyout,
273
340
  > .esp-page-surface,
274
341
  > .esp-page-canvas {
275
342
  margin-top: var(--_esp-page-fixed-header-offset);
@@ -299,4 +366,10 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
299
366
  .esp-page:has(esp-dialog[is-open="true"]) {
300
367
  overflow: hidden;
301
368
  }
302
- `],o([i({reflect:!0})],t.prototype,"kind",void 0),o([i({reflect:!0})],t.prototype,"align",void 0),o([i({type:Boolean,reflect:!0})],t.prototype,"contained",void 0),o([i({attribute:"header-position",reflect:!0})],t.prototype,"headerPosition",void 0),o([i({attribute:"fixed-menus",type:Boolean,reflect:!0})],t.prototype,"fixedMenus",void 0),t=o([u("esp-page")],t);export{t as EspalierPage};
369
+
370
+ @media (prefers-reduced-motion: reduce) {
371
+ .esp-page {
372
+ transition: none;
373
+ }
374
+ }
375
+ `],d([l({reflect:!0})],i.prototype,"kind",void 0),d([l({reflect:!0})],i.prototype,"align",void 0),d([l({type:Boolean,reflect:!0})],i.prototype,"contained",void 0),d([l({attribute:"header-position",reflect:!0})],i.prototype,"headerPosition",void 0),d([l({attribute:"fixed-menus",type:Boolean,reflect:!0})],i.prototype,"fixedMenus",void 0),i=d([v("esp-page")],i);export{i as EspalierPage};
@@ -1 +1 @@
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{PopoverController as g}from"../shared/popover-controller.js";import{FormFieldController as v}from"../shared/form-field-controller.js";class r extends d{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new v({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._showOptions=!1,this.itemsSlot=u(),this.pickerMenu=u(),this.theInput=u(),this._lastViewportHeight=0,this.popoverCtrl=new g({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(),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()}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 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{PopoverController as g}from"../shared/popover-controller.js";import{FormFieldController as v}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as w}from"../shared/form-field-description-controller.js";class r extends d{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new v({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 w({host:this,getTarget:()=>this.theInput.value}),this._showOptions=!1,this.itemsSlot=u(),this.pickerMenu=u(),this.theInput=u(),this._lastViewportHeight=0,this.popoverCtrl=new g({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(),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,13 +1,13 @@
1
- var l=function(n,e,t,r){var a=arguments.length,i=a<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(n,e,t,r);else for(var u=n.length-1;u>=0;u--)(o=n[u])&&(i=(a<3?o(i):a>3?o(e,t,i):o(e,t))||i);return a>3&&i&&Object.defineProperty(e,t,i),i};import{css as f,html as c}from"lit";import{customElement as p,property as d}from"lit/decorators.js";import{EspalierElementBase as h}from"../shared/esp-element-base.js";import{createRef as m,ref as g}from"lit/directives/ref.js";import{EspalierRadioButton as y}from"./esp-radio-button.js";import{FormFieldController as b}from"../shared/form-field-controller.js";let s=class extends h{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new b({host:this,internals:this.internals,getFormValue:()=>this.value||null,getValidity:()=>this.required&&!this.value?{flags:{valueMissing:!0},message:this.requiredMessage||"Please select an option."}:null,onReset:()=>{for(const e of this.getRadioButtons())e.checked=!1},onRestore:e=>{for(const t of this.getRadioButtons())t.checked=t.value===e},onDisabled:e=>{this.disabled=e}}),this.itemsSlot=m(),this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1}get value(){return this.getRadioButtons().find(e=>e.checked)?.value??""}focus(e){this.focusResolvedElementAfterUpdate(()=>{const t=this.getRadioButtons();return t.find(r=>r.checked&&!r.disabled)??t.find(r=>!r.disabled)},e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}getRadioButtons(){return this.itemsSlot.value?Array.from(this.itemsSlot.value.assignedElements()).filter(e=>e instanceof y):[]}applyDisabledState(){for(const e of this.getRadioButtons())e.disabled=this.disabled}handleChildChanged(e){e.stopPropagation();const t=e.detail;if(t.checked){for(const r of this.getRadioButtons())r.value!==t.value&&(r.checked=!1);this.formCtrl.syncValue(),this.emitValueChanged(t.value)}}handleKeyDown(e){if(!["ArrowDown","ArrowRight","ArrowUp","ArrowLeft"].includes(e.key))return;e.preventDefault();const t=this.getRadioButtons().filter(o=>!o.disabled);if(t.length===0)return;const r=t.findIndex(o=>o.checked),a=e.key==="ArrowDown"||e.key==="ArrowRight";let i;r===-1?i=0:a?i=(r+1)%t.length:i=(r-1+t.length)%t.length,r!==-1&&(t[r].checked=!1),t[i].checked=!0,t[i].focus(),this.formCtrl.syncValue(),this.emitValueChanged(t[i].value)}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}firstUpdated(e){super.firstUpdated(e),this.applyDisabledState()}updated(e){super.updated(e),e.has("disabled")&&this.applyDisabledState()}render(){return c`
1
+ var l=function(n,e,t,i){var a=arguments.length,r=a<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(n,e,t,i);else for(var h=n.length-1;h>=0;h--)(o=n[h])&&(r=(a<3?o(r):a>3?o(e,t,r):o(e,t))||r);return a>3&&r&&Object.defineProperty(e,t,r),r};import{css as f,html as c}from"lit";import{customElement as p,property as d}from"lit/decorators.js";import{EspalierElementBase as u}from"../shared/esp-element-base.js";import{createRef as m,ref as g}from"lit/directives/ref.js";import{EspalierRadioButton as y}from"./esp-radio-button.js";import{FormFieldController as b}from"../shared/form-field-controller.js";let s=class extends u{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new b({host:this,internals:this.internals,getFormValue:()=>this.value||null,getValidity:()=>this.required&&!this.value?{flags:{valueMissing:!0},message:this.requiredMessage||"Please select an option."}:null,onReset:()=>{for(const e of this.getRadioButtons())e.checked=!1},onRestore:e=>{for(const t of this.getRadioButtons())t.checked=t.value===e},onDisabled:e=>{this.disabled=e}}),this.itemsSlot=m(),this.formItemDescription=null,this.describedRadios=new Set,this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1,this.handleItemsSlotChange=()=>{this.applyDisabledState(),this.applyFormItemDescription()}}get value(){return this.getRadioButtons().find(e=>e.checked)?.value??""}focus(e){this.focusResolvedElementAfterUpdate(()=>{const t=this.getRadioButtons();return t.find(i=>i.checked&&!i.disabled)??t.find(i=>!i.disabled)},e)}setFormItemDescription(e){this.formItemDescription=e,this.applyFormItemDescription()}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}getRadioButtons(){return this.itemsSlot.value?Array.from(this.itemsSlot.value.assignedElements()).filter(e=>e instanceof y):[]}applyDisabledState(){for(const e of this.getRadioButtons())e.disabled=this.disabled}applyFormItemDescription(){const e=new Set(this.getRadioButtons());for(const t of this.describedRadios)e.has(t)||t.setFormItemDescription(null);for(const t of e)t.setFormItemDescription(this.formItemDescription);this.describedRadios=e}handleChildChanged(e){e.stopPropagation();const t=e.detail;if(t.checked){for(const i of this.getRadioButtons())i.value!==t.value&&(i.checked=!1);this.formCtrl.syncValue(),this.emitValueChanged(t.value)}}handleKeyDown(e){if(!["ArrowDown","ArrowRight","ArrowUp","ArrowLeft"].includes(e.key))return;e.preventDefault();const t=this.getRadioButtons().filter(o=>!o.disabled);if(t.length===0)return;const i=t.findIndex(o=>o.checked),a=e.key==="ArrowDown"||e.key==="ArrowRight";let r;i===-1?r=0:a?r=(i+1)%t.length:r=(i-1+t.length)%t.length,i!==-1&&(t[i].checked=!1),t[r].checked=!0,t[r].focus(),this.formCtrl.syncValue(),this.emitValueChanged(t[r].value)}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}firstUpdated(e){super.firstUpdated(e),this.applyDisabledState(),this.applyFormItemDescription()}updated(e){super.updated(e),e.has("disabled")&&this.applyDisabledState()}render(){return c`
2
2
  <div
3
3
  class="radio-group"
4
4
  role="radiogroup"
5
5
  @value-changed=${this.handleChildChanged}
6
6
  @keydown=${this.handleKeyDown}
7
7
  >
8
- <slot ${g(this.itemsSlot)}></slot>
8
+ <slot ${g(this.itemsSlot)} @slotchange=${this.handleItemsSlotChange}></slot>
9
9
  </div>
10
- `}};s.formAssociated=!0,s.styles=[...h.styles,f`
10
+ `}};s.formAssociated=!0,s.styles=[...u.styles,f`
11
11
  .radio-group {
12
12
  display: grid;
13
13
  gap: var(--esp-size-tiny);
@@ -1,4 +1,4 @@
1
- var n=function(r,e,i,s){var a=arguments.length,t=a<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,i):s,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")t=Reflect.decorate(r,e,i,s);else for(var c=r.length-1;c>=0;c--)(l=r[c])&&(t=(a<3?l(t):a>3?l(e,i,t):l(e,i))||t);return a>3&&t&&Object.defineProperty(e,i,t),t};import{css as h,html as u}from"lit";import{customElement as f,property as d}from"lit/decorators.js";import{EspalierElementBase as p}from"../shared/esp-element-base.js";import{radioSelected as m}from"../shared/svgs/radio-selected.js";import{radioUnselected as v}from"../shared/svgs/radio-unselected.js";import{disabledControl as b,focusRing as y}from"../shared/style-fragments.js";let o=class extends p{constructor(){super(...arguments),this.checked=!1,this.value="",this.disabled=!1}focus(e){this.focusShadowElementAfterUpdate(".radio-control",e)}select(){this.disabled||this.checked||(this.checked=!0,this.emitValueChanged({checked:this.checked,value:this.value}))}handleKeyDown(e){e.key===" "&&(e.preventDefault(),this.select())}render(){return u`
1
+ var l=function(r,e,i,s){var n=arguments.length,t=n<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,i):s,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")t=Reflect.decorate(r,e,i,s);else for(var c=r.length-1;c>=0;c--)(a=r[c])&&(t=(n<3?a(t):n>3?a(e,i,t):a(e,i))||t);return n>3&&t&&Object.defineProperty(e,i,t),t};import{css as h,html as u}from"lit";import{customElement as m,property as d}from"lit/decorators.js";import{EspalierElementBase as p}from"../shared/esp-element-base.js";import{FormFieldDescriptionController as f}from"../shared/form-field-description-controller.js";import{radioSelected as v}from"../shared/svgs/radio-selected.js";import{radioUnselected as b}from"../shared/svgs/radio-unselected.js";import{disabledControl as y,focusRing as g}from"../shared/style-fragments.js";let o=class extends p{constructor(){super(...arguments),this.formItemDescription=new f({host:this,getTarget:()=>this.shadowRoot?.querySelector(".radio-control")}),this.checked=!1,this.value="",this.disabled=!1}focus(e){this.focusShadowElementAfterUpdate(".radio-control",e)}setFormItemDescription(e){this.formItemDescription.setDescription(e)}select(){this.disabled||this.checked||(this.checked=!0,this.emitValueChanged({checked:this.checked,value:this.value}))}handleKeyDown(e){e.key===" "&&(e.preventDefault(),this.select())}render(){return u`
2
2
  <div
3
3
  class="radio-control"
4
4
  role="radio"
@@ -8,10 +8,10 @@ var n=function(r,e,i,s){var a=arguments.length,t=a<3?e:s===null?s=Object.getOwnP
8
8
  @click=${this.select}
9
9
  @keydown=${this.handleKeyDown}
10
10
  >
11
- <span class="icon">${this.checked?m:v}</span>
11
+ <span class="icon">${this.checked?v:b}</span>
12
12
  <span class="label"><slot></slot></span>
13
13
  </div>
14
- `}};o.styles=[...p.styles,y(".radio-control:focus-visible","--esp-radio-button-focus-shadow"),b(".radio-control"),h`
14
+ `}};o.styles=[...p.styles,g(".radio-control:focus-visible","--esp-radio-button-focus-shadow"),y(".radio-control"),h`
15
15
  :host {
16
16
  display: block;
17
17
  }
@@ -44,4 +44,4 @@ var n=function(r,e,i,s){var a=arguments.length,t=a<3?e:s===null?s=Object.getOwnP
44
44
  line-height: 1.3;
45
45
  }
46
46
  }
47
- `],n([d({type:Boolean,reflect:!0})],o.prototype,"checked",void 0),n([d({type:String})],o.prototype,"value",void 0),n([d({type:Boolean,reflect:!0})],o.prototype,"disabled",void 0),o=n([f("esp-radio-button")],o);export{o as EspalierRadioButton};
47
+ `],l([d({type:Boolean,reflect:!0})],o.prototype,"checked",void 0),l([d({type:String})],o.prototype,"value",void 0),l([d({type:Boolean,reflect:!0})],o.prototype,"disabled",void 0),o=l([m("esp-radio-button")],o);export{o as EspalierRadioButton};