@taprootio/espalier 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @module icons
3
+ *
4
+ * The offline story for Espalier icons (ESP0176).
5
+ *
6
+ * A fully self-contained page — an email attachment, an artifact, a
7
+ * USB-stick deliverable — cannot fetch `/assets/icons.svg`, and the
8
+ * browser blocks `data:` URLs as `<use>` targets. This module ships the
9
+ * sprite as a string instead: inline it once, point the root at it with
10
+ * the same-document form of `icon-sprite-url`, and every component
11
+ * renders icons with zero network requests:
12
+ *
13
+ * ```js
14
+ * import { installIconSprite } from "@taprootio/espalier/icons";
15
+ *
16
+ * document.querySelector("esp-root")
17
+ * .setAttribute("icon-sprite-url", installIconSprite());
18
+ * ```
19
+ *
20
+ * The same-document form works for any sprite, not only this one: give
21
+ * your own `<svg id="brand-icons"><symbol id="…">…</symbol></svg>` an
22
+ * id, inline it, and set `icon-sprite-url="#brand-icons"` — components
23
+ * adopt the referenced symbols into their shadow roots, which is what
24
+ * makes same-document references work across shadow boundaries.
25
+ */
26
+ import { ICON_SPRITE, ICON_SPRITE_ID } from "./icon-sprite.generated.js";
27
+ export { ICON_SPRITE, ICON_SPRITE_ID };
28
+ /**
29
+ * Inline the Espalier sprite into a document (once — reruns are
30
+ * no-ops) and return the `icon-sprite-url` value that references it.
31
+ *
32
+ * The sprite lands at the end of `<body>` (or the document element
33
+ * before body exists), hidden and aria-hidden. Set the returned value
34
+ * on the root *after* installing, so components adopt from a sprite
35
+ * that is already present.
36
+ *
37
+ * @param target The document to install into; defaults to `document`.
38
+ * @returns The same-document sprite reference, `"#esp-icons"`.
39
+ */
40
+ export declare function installIconSprite(target?: Document): string;
@@ -0,0 +1 @@
1
+ import{ICON_SPRITE as r,ICON_SPRITE_ID as t}from"./icon-sprite.generated.js";function a(n=document){const e=n.getElementById(t);if(e){if(!(e.namespaceURI==="http://www.w3.org/2000/svg"&&e.localName==="svg"&&e.hasAttribute("data-esp-icon-sprite")))throw new Error(`installIconSprite: an unrelated <${e.localName}> already has id="${t}". Rename that element (the id belongs to the Espalier icon sprite) or inline the sprite under a different id and reference it directly.`);return`#${t}`}return(n.body??n.documentElement).insertAdjacentHTML("beforeend",r),`#${t}`}export{r as ICON_SPRITE,t as ICON_SPRITE_ID,a as installIconSprite};
package/dist/index.d.ts CHANGED
@@ -60,7 +60,7 @@ export * from "./search/esp-search.js";
60
60
  export * from "./status-indicator/esp-status-indicator.js";
61
61
  export * from "./tree/esp-tree.js";
62
62
  export * from "./tree/esp-tree-item.js";
63
- export { DEFAULT_ICON_SPRITE_URL, DEFAULT_ICON_VIEW_BOX, INTENT_VARIANTS, type EspalierIntentVariant, normalizeIntentVariant, getIconHref, getIconHrefForHost, getIconSpriteUrl, } from "./shared/intent-values.js";
63
+ export { DEFAULT_ICON_SPRITE_URL, DEFAULT_ICON_VIEW_BOX, INTENT_VARIANTS, type EspalierIntentVariant, normalizeIntentVariant, getIconHref, getIconHrefForHost, getIconSpriteUrl, getIconSpriteReference, type IconSpriteReference, } from "./shared/intent-values.js";
64
64
  export { EspalierElementBase } from "./shared/esp-element-base.js";
65
65
  export { type ValidationError, VALIDITY_CHANGED_EVENT, type ValidityChangedDetail, } from "./shared/validation.js";
66
66
  export { FormFieldController, type FormFieldControllerOptions, } from "./shared/form-field-controller.js";
@@ -78,4 +78,5 @@ export { auditDataPalette, generateSequentialRamp, generateDivergingRamp, COLOR_
78
78
  export { WEIGHT_LABELS, extractWeights, normalizeWeight, bestAvailableWeight, extractFamily, getFallbackFont, } from "./shared/font-helpers.js";
79
79
  export { getGoogleFonts } from "./font-picker/esp-font-picker.js";
80
80
  export { ROOT_SURFACE, themeFitReport, themeFitRows, themeFitLints, themeFitReportSuite, printThemeFitReport, type ThemeFitReport, type ThemeFitReportOptions, type ThemeFitToken, type ThemeFitApcaAction, type ThemeFitAnchor, type ThemeFitRow, type ThemeFitLint, type ThemeFitSurfaceReport, type ThemeFitSuite, } from "./shared/theme-fit-report.js";
81
+ export { ICON_SPRITE, ICON_SPRITE_ID, installIconSprite } from "./icons/index.js";
81
82
  export { deriveLightnessRamp, themeFromSwatches, type ThemeFromSwatchesOptions, type ThemeFromSwatchesResult, } from "./shared/theme-swatches.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"./flyout/esp-flyout.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./help/esp-help-button.js";export*from"./help/esp-help-provider.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./section/esp-section.js";export*from"./stack/esp-stack.js";export*from"./row/esp-row.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"./focus-picker/esp-focus-picker.js";export*from"./footer/index.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./image/image-focus.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 _r,DEFAULT_ICON_VIEW_BOX as Ar,INTENT_VARIANTS as Er,normalizeIntentVariant as ir,getIconHref as lr,getIconHrefForHost as sr,getIconSpriteUrl as Ir}from"./shared/intent-values.js";import{EspalierElementBase as hr}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as Dr}from"./shared/validation.js";import{FormFieldController as Rr}from"./shared/form-field-controller.js";import{traverseToClosest as Lr}from"./shared/utilities.js";import{showToast as Pr}from"./shared/toast-events.js";import{showFlyout as ur,closeFlyout as Or}from"./shared/flyout-events.js";import{requestHelp as Cr}from"./shared/help-events.js";import{getEspBus as Hr}from"./shared/bus-events.js";export*from"./shared/events.js";import{getImageDetails as Vr,releasePreviewUrl as Gr}from"./image-upload/image-helpers.js";import{calculatePhotoLayout as wr}from"./shared/justified-layout.js";import{encodeTheme as Wr,parseTheme as Br,mergePartials as Yr,layerThemes as kr,validateThemePair as qr,resolveContextTheme as zr,buildTaprootLightTheme as Kr,buildTaprootDarkTheme as Xr,NESTED_THEME_KEYS as jr}from"./shared/theme.js";import{auditDataPalette as Qr,generateSequentialRamp as Zr,generateDivergingRamp as $r,COLOR_VISION_SIMULATIONS as ro,DATA_SERIES_KEYS as oo,DEFAULT_DATA_PALETTE as eo,DEFAULT_DATA_RAMP_STEPS as to,DEFAULT_DIVERGING_NEUTRAL as mo,MAX_DATA_RAMP_STEPS as po,MIN_DATA_COLOR_DISTANCE as xo,MIN_DATA_RAMP_LIGHTNESS_STEP as fo,MIN_DATA_RAMP_STEPS as To}from"./shared/data-colors.js";import{WEIGHT_LABELS as _o,extractWeights as Ao,normalizeWeight as Eo,bestAvailableWeight as io,extractFamily as lo,getFallbackFont as so}from"./shared/font-helpers.js";import{getGoogleFonts as So}from"./font-picker/esp-font-picker.js";import{ROOT_SURFACE as no,themeFitReport as Do,themeFitRows as Fo,themeFitLints as Ro,themeFitReportSuite as go,printThemeFitReport as Lo}from"./shared/theme-fit-report.js";import{deriveLightnessRamp as Po,themeFromSwatches as co}from"./shared/theme-swatches.js";export{ro as COLOR_VISION_SIMULATIONS,oo as DATA_SERIES_KEYS,eo as DEFAULT_DATA_PALETTE,to as DEFAULT_DATA_RAMP_STEPS,mo as DEFAULT_DIVERGING_NEUTRAL,_r as DEFAULT_ICON_SPRITE_URL,Ar as DEFAULT_ICON_VIEW_BOX,hr as EspalierElementBase,Rr as FormFieldController,Er as INTENT_VARIANTS,po as MAX_DATA_RAMP_STEPS,xo as MIN_DATA_COLOR_DISTANCE,fo as MIN_DATA_RAMP_LIGHTNESS_STEP,To as MIN_DATA_RAMP_STEPS,jr as NESTED_THEME_KEYS,no as ROOT_SURFACE,Dr as VALIDITY_CHANGED_EVENT,_o as WEIGHT_LABELS,Qr as auditDataPalette,io as bestAvailableWeight,Xr as buildTaprootDarkTheme,Kr as buildTaprootLightTheme,wr as calculatePhotoLayout,Or as closeFlyout,Po as deriveLightnessRamp,Wr as encodeTheme,lo as extractFamily,Ao as extractWeights,$r as generateDivergingRamp,Zr as generateSequentialRamp,Hr as getEspBus,so as getFallbackFont,So as getGoogleFonts,lr as getIconHref,sr as getIconHrefForHost,Ir as getIconSpriteUrl,Vr as getImageDetails,kr as layerThemes,Yr as mergePartials,ir as normalizeIntentVariant,Eo as normalizeWeight,Br as parseTheme,Lo as printThemeFitReport,Gr as releasePreviewUrl,Cr as requestHelp,zr as resolveContextTheme,ur as showFlyout,Pr as showToast,Ro as themeFitLints,Do as themeFitReport,go as themeFitReportSuite,Fo as themeFitRows,co as themeFromSwatches,Lr as traverseToClosest,qr as validateThemePair};
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"./help/esp-help-button.js";export*from"./help/esp-help-provider.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./section/esp-section.js";export*from"./stack/esp-stack.js";export*from"./row/esp-row.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"./focus-picker/esp-focus-picker.js";export*from"./footer/index.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./image/image-focus.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 _r,DEFAULT_ICON_VIEW_BOX as Er,INTENT_VARIANTS as ir,normalizeIntentVariant as Ar,getIconHref as lr,getIconHrefForHost as Ir,getIconSpriteUrl as Sr,getIconSpriteReference as sr}from"./shared/intent-values.js";import{EspalierElementBase as Rr}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as Dr}from"./shared/validation.js";import{FormFieldController as gr}from"./shared/form-field-controller.js";import{traverseToClosest as Nr}from"./shared/utilities.js";import{showToast as cr}from"./shared/toast-events.js";import{showFlyout as Cr,closeFlyout as ur}from"./shared/flyout-events.js";import{requestHelp as Mr}from"./shared/help-events.js";import{getEspBus as dr}from"./shared/bus-events.js";export*from"./shared/events.js";import{getImageDetails as Gr,releasePreviewUrl as br}from"./image-upload/image-helpers.js";import{calculatePhotoLayout as yr}from"./shared/justified-layout.js";import{encodeTheme as Br,parseTheme as Yr,mergePartials as kr,layerThemes as qr,validateThemePair as zr,resolveContextTheme as Kr,buildTaprootLightTheme as Xr,buildTaprootDarkTheme as jr,NESTED_THEME_KEYS as Jr}from"./shared/theme.js";import{auditDataPalette as Zr,generateSequentialRamp as $r,generateDivergingRamp as ro,COLOR_VISION_SIMULATIONS as oo,DATA_SERIES_KEYS as eo,DEFAULT_DATA_PALETTE as to,DEFAULT_DATA_RAMP_STEPS as mo,DEFAULT_DIVERGING_NEUTRAL as po,MAX_DATA_RAMP_STEPS as fo,MIN_DATA_COLOR_DISTANCE as xo,MIN_DATA_RAMP_LIGHTNESS_STEP as To,MIN_DATA_RAMP_STEPS as ao}from"./shared/data-colors.js";import{WEIGHT_LABELS as Eo,extractWeights as io,normalizeWeight as Ao,bestAvailableWeight as lo,extractFamily as Io,getFallbackFont as So}from"./shared/font-helpers.js";import{getGoogleFonts as no}from"./font-picker/esp-font-picker.js";import{ROOT_SURFACE as ho,themeFitReport as Do,themeFitRows as Fo,themeFitLints as go,themeFitReportSuite as Lo,printThemeFitReport as No}from"./shared/theme-fit-report.js";import{ICON_SPRITE as co,ICON_SPRITE_ID as Oo,installIconSprite as Co}from"./icons/index.js";import{deriveLightnessRamp as Uo,themeFromSwatches as Mo}from"./shared/theme-swatches.js";export{oo as COLOR_VISION_SIMULATIONS,eo as DATA_SERIES_KEYS,to as DEFAULT_DATA_PALETTE,mo as DEFAULT_DATA_RAMP_STEPS,po as DEFAULT_DIVERGING_NEUTRAL,_r as DEFAULT_ICON_SPRITE_URL,Er as DEFAULT_ICON_VIEW_BOX,Rr as EspalierElementBase,gr as FormFieldController,co as ICON_SPRITE,Oo as ICON_SPRITE_ID,ir as INTENT_VARIANTS,fo as MAX_DATA_RAMP_STEPS,xo as MIN_DATA_COLOR_DISTANCE,To as MIN_DATA_RAMP_LIGHTNESS_STEP,ao as MIN_DATA_RAMP_STEPS,Jr as NESTED_THEME_KEYS,ho as ROOT_SURFACE,Dr as VALIDITY_CHANGED_EVENT,Eo as WEIGHT_LABELS,Zr as auditDataPalette,lo as bestAvailableWeight,jr as buildTaprootDarkTheme,Xr as buildTaprootLightTheme,yr as calculatePhotoLayout,ur as closeFlyout,Uo as deriveLightnessRamp,Br as encodeTheme,Io as extractFamily,io as extractWeights,ro as generateDivergingRamp,$r as generateSequentialRamp,dr as getEspBus,So as getFallbackFont,no as getGoogleFonts,lr as getIconHref,Ir as getIconHrefForHost,sr as getIconSpriteReference,Sr as getIconSpriteUrl,Gr as getImageDetails,Co as installIconSprite,qr as layerThemes,kr as mergePartials,Ar as normalizeIntentVariant,Ao as normalizeWeight,Yr as parseTheme,No as printThemeFitReport,br as releasePreviewUrl,Mr as requestHelp,Kr as resolveContextTheme,Cr as showFlyout,cr as showToast,go as themeFitLints,Do as themeFitReport,Lo as themeFitReportSuite,Fo as themeFitRows,Mo as themeFromSwatches,Nr as traverseToClosest,zr as validateThemePair};
@@ -1,4 +1,4 @@
1
- var l=function(p,t,i,s){var o=arguments.length,e=o<3?t:s===null?s=Object.getOwnPropertyDescriptor(t,i):s,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")e=Reflect.decorate(p,t,i,s);else for(var h=p.length-1;h>=0;h--)(n=p[h])&&(e=(o<3?n(e):o>3?n(t,i,e):n(t,i))||e);return o>3&&e&&Object.defineProperty(t,i,e),e};import{LitElement as d,nothing as g,css as v,html as a}from"lit";import{customElement as u,property as c}from"lit/decorators.js";import{ref as m}from"lit/directives/ref.js";import{getIconHrefForHost as f}from"../shared/intent-values.js";import{SlottedIconController as y}from"../shared/slotted-icon-controller.js";import{renderSpriteIcon as b}from"../shared/svgs/render-sprite-icon.js";let r=class extends d{constructor(){super(),this.internals=this.attachInternals(),this.iconSlot=new y(this),this.text="",this.icon="",this.value="",this.selected=!1,this.internals.role="option"}connectedCallback(){super.connectedCallback(),this.hasAttribute("role")||this.setAttribute("role","option")}updated(t){super.updated(t),t.has("selected")&&(this.internals.ariaSelected=String(this.selected),this.setAttribute("aria-selected",String(this.selected)))}renderHighlightedText(){const t=this.highlightRanges;if(!t||t.length===0)return this.text;const i=[...t].sort((e,n)=>e[0]-n[0]),s=[];let o=0;for(const[e,n]of i)e>o&&s.push(a`${this.text.slice(o,e)}`),s.push(a`<mark>${this.text.slice(e,n)}</mark>`),o=n;return o<this.text.length&&s.push(a`${this.text.slice(o)}`),s}render(){const t=f(this.icon,this),i=this.iconSlot.hasSlottedIcon(":scope > *");return a`<div>
1
+ var l=function(p,t,i,s){var o=arguments.length,e=o<3?t:s===null?s=Object.getOwnPropertyDescriptor(t,i):s,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")e=Reflect.decorate(p,t,i,s);else for(var h=p.length-1;h>=0;h--)(n=p[h])&&(e=(o<3?n(e):o>3?n(t,i,e):n(t,i))||e);return o>3&&e&&Object.defineProperty(t,i,e),e};import{LitElement as d,nothing as g,css as u,html as a}from"lit";import{customElement as v,property as c}from"lit/decorators.js";import{ref as m}from"lit/directives/ref.js";import{getIconHrefForHost as f}from"../shared/intent-values.js";import{SlottedIconController as y}from"../shared/slotted-icon-controller.js";import{renderSpriteIcon as b}from"../shared/svgs/render-sprite-icon.js";import{DocumentSpriteController as k}from"../shared/document-sprite.js";let r=class extends d{constructor(){super(),this.internals=this.attachInternals(),this.iconSlot=new y(this),this.text="",this.icon="",this.value="",this.selected=!1,new k(this,{reactToSpriteChanges:!0}),this.internals.role="option"}connectedCallback(){super.connectedCallback(),this.hasAttribute("role")||this.setAttribute("role","option")}updated(t){super.updated(t),t.has("selected")&&(this.internals.ariaSelected=String(this.selected),this.setAttribute("aria-selected",String(this.selected)))}renderHighlightedText(){const t=this.highlightRanges;if(!t||t.length===0)return this.text;const i=[...t].sort((e,n)=>e[0]-n[0]),s=[];let o=0;for(const[e,n]of i)e>o&&s.push(a`${this.text.slice(o,e)}`),s.push(a`<mark>${this.text.slice(e,n)}</mark>`),o=n;return o<this.text.length&&s.push(a`${this.text.slice(o)}`),s}render(){const t=f(this.icon,this),i=this.iconSlot.hasSlottedIcon(":scope > *");return a`<div>
2
2
  <span class="icon">
3
3
  <slot ${m(this.iconSlot.slotRef)} @slotchange=${this.iconSlot.handleSlotChange}></slot>
4
4
  ${!i&&t?b(t):g}
@@ -19,7 +19,7 @@ var l=function(p,t,i,s){var o=arguments.length,e=o<3?t:s===null?s=Object.getOwnP
19
19
  />
20
20
  <path d="M9 12l2 2l4 -4" />
21
21
  </svg>`:a``}
22
- </div>`}};r.styles=v`
22
+ </div>`}};r.styles=u`
23
23
  :host(:hover),
24
24
  :host(.highlighted) {
25
25
  div {
@@ -77,4 +77,4 @@ var l=function(p,t,i,s){var o=arguments.length,e=o<3?t:s===null?s=Object.getOwnP
77
77
  margin: var(--esp-size-tiny);
78
78
  }
79
79
  }
80
- `,l([c({type:Object})],r.prototype,"styles",void 0),l([c({type:String})],r.prototype,"text",void 0),l([c({type:String})],r.prototype,"icon",void 0),l([c({type:String})],r.prototype,"value",void 0),l([c({type:Boolean})],r.prototype,"selected",void 0),l([c({attribute:"highlight-ranges",type:Array})],r.prototype,"highlightRanges",void 0),r=l([u("esp-picker-item")],r);export{r as EspalierPickerItem};
80
+ `,l([c({type:Object})],r.prototype,"styles",void 0),l([c({type:String})],r.prototype,"text",void 0),l([c({type:String})],r.prototype,"icon",void 0),l([c({type:String})],r.prototype,"value",void 0),l([c({type:Boolean})],r.prototype,"selected",void 0),l([c({attribute:"highlight-ranges",type:Array})],r.prototype,"highlightRanges",void 0),r=l([v("esp-picker-item")],r);export{r as EspalierPickerItem};
@@ -1,4 +1,4 @@
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`
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 O}from"../shared/raf-throttle.js";import{alignAttributeTextInheritance as P}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 O(()=>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){super.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)}}
@@ -16,7 +16,7 @@ var p=function(u,t,e,s){var i=arguments.length,o=i<3?t:s===null?s=Object.getOwnP
16
16
  >
17
17
  <slot name="popover" ${d(this.popoverSlot)}></slot>
18
18
  </div>
19
- `}};h.styles=[O,y`
19
+ `}};h.styles=[P,y`
20
20
  :host {
21
21
  position: relative;
22
22
  display: flex;
@@ -232,6 +232,49 @@ export declare class EspalierRoot extends LitElement implements SeedColorRoot {
232
232
  * @type {string}
233
233
  */
234
234
  iconSpriteUrl: string;
235
+ /**
236
+ * Hold descendant paint until the first author theme resolves
237
+ * (ESP0177) — opt in when the theme is assigned from script.
238
+ *
239
+ * A script-mounted theme lands after the elements upgrade, so without
240
+ * this the page paints one frame on the default palette and then
241
+ * repaints on the brand's. Declaring `theme-pending` keeps the
242
+ * subtree invisible (it still takes its space, so nothing shifts)
243
+ * until the theme applies.
244
+ *
245
+ * Server-rendered `light-theme` / `dark-theme` attributes close a
246
+ * different window: the theme is present when the root upgrades, so
247
+ * it settles on its first update and never renders the defaults. They
248
+ * do not cover the frame before this module runs, when the host is
249
+ * still an unknown element painting its light DOM unstyled — a
250
+ * server-rendered page whose bundle may load after first paint wants
251
+ * this attribute too, plus the page-level gate, and its hold releases
252
+ * the moment it upgrades.
253
+ *
254
+ * The hold always ends: if no theme arrives within
255
+ * {@link THEME_SETTLE_TIMEOUT_MS} the root reveals anyway and warns,
256
+ * so a broken mount degrades to the default palette instead of a
257
+ * blank page.
258
+ */
259
+ themePending: boolean;
260
+ /**
261
+ * `true` once the theme this root will render with is the theme it
262
+ * has — an author theme resolved, or the pre-theme window closed with
263
+ * none. Mirrored to the `data-theme-ready` attribute so page CSS can
264
+ * gate on it. Pair it with the opt-in attribute —
265
+ * `esp-root[theme-pending]:not([data-theme-ready]) { visibility: hidden }`
266
+ * — which is the only frame-zero cover for the window before this
267
+ * module runs, and which scopes the hold to roots that asked for it:
268
+ * unscoped, the rule would also blank a page that never mounts a
269
+ * theme, until its deadline closes the window.
270
+ */
271
+ get themeSettled(): boolean;
272
+ /**
273
+ * Resolves when {@link themeSettled} turns true — the honest moment
274
+ * to judge whether a named context is genuinely missing rather than
275
+ * merely not mounted yet.
276
+ */
277
+ whenThemeSettled(): Promise<void>;
235
278
  /**
236
279
  * Initial color scheme to apply when `scheme` is not set.
237
280
  *
@@ -1,4 +1,4 @@
1
- var a=function(d,e,t,o){var l=arguments.length,s=l<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,r;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(d,e,t,o);else for(var n=d.length-1;n>=0;n--)(r=d[n])&&(s=(l<3?r(s):l>3?r(e,t,s):r(e,t))||s);return l>3&&s&&Object.defineProperty(e,t,s),s},h;import{css as b,html as T,LitElement as C}from"lit";import{customElement as E,property as c}from"lit/decorators.js";import{getEspBus as p}from"../shared/bus-events.js";import{subscribeToRootEvent as x}from"../shared/root-event-subscription.js";import{DEFAULT_LIGHT_THEME as f,DEFAULT_DARK_THEME as y,encodeTheme as v,parseTheme as g,mergeTheme as S}from"../shared/theme.js";import{computeThemeProperties as R}from"./helpers/compute-theme-properties.js";import{registerImageTexture as D,registeredImageTextures as L}from"../shared/image-texture-registry.js";import{registerImageTexture as _,registeredImageTextures as H,BUILT_IN_IMAGE_TEXTURES as M}from"../shared/image-texture-registry.js";let i=h=class extends C{constructor(){super(...arguments),this.schemeBacker="",this.schemeExplicitlySet=!1,this.resolvingDefaultScheme=!1,this.themeEventsReady=!1,this.systemSchemeQuery=null,this.lastSeedColor="",this.resolvedLightTheme={...f},this.resolvedDarkTheme={...y},this.appliedDataRampProperties=new Set,this.documentClickRegistrationActive=!1,this.correlationId=globalThis.crypto?.randomUUID?.()??Math.random().toString(36),this.lightThemeAttr="",this.darkThemeAttr="",this.fontCSSRoot="/css/fonts/",this.fontDefinitionsUrl="",this.googleFontLoading="auto",this.iconSpriteUrl="/assets/icons.svg",this.defaultScheme="light",this.resizeObserver=new ResizeObserver(()=>{p().publish("window-resized",{emWidth:window.innerWidth/parseFloat(getComputedStyle(document.documentElement).fontSize),emHeight:window.innerHeight/parseFloat(getComputedStyle(document.documentElement).fontSize),pxWidth:window.innerWidth,pxHeight:window.innerHeight})}),this.handleSystemSchemeChange=e=>{this.schemeExplicitlySet||this.defaultScheme!=="system"||(this.resolvingDefaultScheme=!0,this.scheme=e.matches?"dark":"light",this.resolvingDefaultScheme=!1)}}static registerTexture(e,t){D(e,t)}static registeredTextures(){return L()}subscribeScoped(e,t){return x(this,e,t)}get lightTheme(){return this.lightThemeAttr?g(this.lightThemeAttr):null}set lightTheme(e){this.lightThemeAttr=e?v(e):""}get darkTheme(){return this.darkThemeAttr?g(this.darkThemeAttr):null}set darkTheme(e){this.darkThemeAttr=e?v(e):""}get scheme(){return this.schemeBacker}set scheme(e){const t=e==="dark"?"dark":e==="light"?"light":"",o=this.schemeBacker,l=this.schemeExplicitlySet;this.resolvingDefaultScheme||(this.schemeExplicitlySet=t.length>0);const s=t||this.resolveDefaultScheme();l!==this.schemeExplicitlySet&&this.isConnected&&this.syncSystemSchemeListener(),s!==o&&(this.schemeBacker=s,this.requestUpdate("scheme",o),this.themeEventsReady&&p().publish("scheme-changed",{scheme:s,correlationId:this.correlationId}))}get seedColor(){return this.activeTheme.seedColor}static extractFamily(e){if(!e)return"";const t=e.match(/^"([^"]+)"|^'([^']+)'/);return t&&(t[1]||t[2])||""}injectGoogleFontLink(e,t,o){const l="data-esp-font",s=`${this.correlationId}-${e}`,r=document.head.querySelector(`link[${l}="${s}"]`);if(this.googleFontLoading==="none"){r?.remove();return}if(r&&t&&r.dataset.espFamily===t&&r.dataset.espWeight===(o??"")||(r?.remove(),!t))return;const n=encodeURIComponent(t),u=o==="bold"?"700":o==="normal"?"400":o,k=u&&u!=="400"?`:wght@${u}`:"",m=document.createElement("link");m.rel="stylesheet",m.href=`https://fonts.googleapis.com/css2?family=${n}${k}&display=swap`,m.setAttribute(l,s),m.dataset.espFamily=t,m.dataset.espWeight=o??"",document.head.appendChild(m)}syncGoogleFontLinks(){this.googleFontLoading==="none"&&this.removeRuntimeGoogleFontLinks();const e=this.activeTheme;this.injectGoogleFontLink("body",h.extractFamily(e.fontBody),e.fontWeightBody),this.injectGoogleFontLink("headings",h.extractFamily(e.fontHeadings),e.fontWeightHeadings),this.injectGoogleFontLink("brand",h.extractFamily(e.fontBrand),e.fontWeightBrand),this.injectGoogleFontLink("monospace",h.extractFamily(e.fontMonospace),e.fontWeightMonospace)}removeRuntimeGoogleFontLinks(){for(const e of document.head.querySelectorAll(`link[data-esp-font^="${this.correlationId}-"]`))e.remove();for(const e of document.head.querySelectorAll(`link[data-esp-font-picker-root="${CSS.escape(this.correlationId)}"]`))e.remove()}get activeTheme(){return this.scheme==="dark"?this.resolvedDarkTheme:this.resolvedLightTheme}resolveThemes(){const e=this.lightThemeAttr?g(this.lightThemeAttr):null;this.resolvedLightTheme=e?S(f,e):{...f};const t=this.darkThemeAttr?g(this.darkThemeAttr):null;this.resolvedDarkTheme=t?S(y,t):{...y}}connectedCallback(){super.connectedCallback(),this.registerDocumentClickBridge(),this.resizeObserver.observe(this),this.hasUpdated&&(this.applyDefaultScheme(),this.syncGoogleFontLinks())}willUpdate(e){const t=["lightThemeAttr","darkThemeAttr"];(!this.lastSeedColor||t.some(n=>e.has(n)))&&(this.resolveThemes(),this.themeEventsReady&&p().publish("theme-changed",{correlationId:this.correlationId}));const l=R(this.activeTheme,this.scheme==="dark"?"dark":"light"),s=new Set(Object.keys(l).filter(n=>n.startsWith("--esp-color-ramp-")));for(const n of this.appliedDataRampProperties)s.has(n)||this.style.removeProperty(n);for(const[n,u]of Object.entries(l))this.style.setProperty(n,u);this.appliedDataRampProperties=s;const r=this.activeTheme.seedColor;this.themeEventsReady&&this.lastSeedColor&&this.lastSeedColor!==r&&p().publish("seed-color-changed",{seedColor:r,correlationId:this.correlationId}),this.lastSeedColor=r,this.themeEventsReady&&e.has("iconSpriteUrl")&&p().publish("icon-sprite-url-changed",{iconSpriteUrl:this.iconSpriteUrl,correlationId:this.correlationId}),this.syncGoogleFontLinks()}firstUpdated(){const e=this.activeTheme.stylesheets;if(e.length)for(const t of e){const o=document.createElement("link");o.rel="stylesheet",o.href=t,document.head.appendChild(o)}if(!document.getElementById("esp-root-base-styles")){const t=document.createElement("style");t.id="esp-root-base-styles",t.textContent=h.lightDomStyles,document.head.appendChild(t)}this.applyDefaultScheme(),this.lastSeedColor=this.activeTheme.seedColor,this.themeEventsReady=!0}updated(e){(e.has("defaultScheme")||e.has("scheme"))&&!this.schemeExplicitlySet&&this.applyDefaultScheme()}disconnectedCallback(){this.unregisterDocumentClickBridge(),this.systemSchemeQuery?.removeEventListener("change",this.handleSystemSchemeChange),this.systemSchemeQuery=null,this.resizeObserver.disconnect(),this.removeRuntimeGoogleFontLinks(),super.disconnectedCallback()}registerDocumentClickBridge(){this.documentClickRegistrationActive||(this.documentClickRegistrationActive=!0,h.connectedRootCount+=1,h.connectedRootCount===1&&document.addEventListener("click",h.handleDocumentClick))}unregisterDocumentClickBridge(){this.documentClickRegistrationActive&&(this.documentClickRegistrationActive=!1,h.connectedRootCount=Math.max(0,h.connectedRootCount-1),h.connectedRootCount===0&&document.removeEventListener("click",h.handleDocumentClick))}applyDefaultScheme(){this.schemeExplicitlySet||(this.resolvingDefaultScheme=!0,this.scheme=this.resolveDefaultScheme(),this.resolvingDefaultScheme=!1,this.syncSystemSchemeListener())}resolveDefaultScheme(){return this.defaultScheme==="dark"||this.defaultScheme==="system"&&window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light"}syncSystemSchemeListener(){if(this.schemeExplicitlySet||this.defaultScheme!=="system"||!window.matchMedia){this.systemSchemeQuery?.removeEventListener("change",this.handleSystemSchemeChange),this.systemSchemeQuery=null;return}this.systemSchemeQuery||(this.systemSchemeQuery=window.matchMedia("(prefers-color-scheme: dark)"),this.systemSchemeQuery.addEventListener("change",this.handleSystemSchemeChange))}render(){return T`<slot></slot>`}};i.connectedRootCount=0,i.handleDocumentClick=d=>{const e=d.composedPath().filter(t=>t instanceof HTMLElement&&t.tagName==="ESP-POPOVER");p().publish("close-popovers",{source:d.target??void 0,skipPopovers:e})},i.lightDomStyles=`
1
+ var h=function(c,e,t,i){var l=arguments.length,s=l<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,r;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(c,e,t,i);else for(var n=c.length-1;n>=0;n--)(r=c[n])&&(s=(l<3?r(s):l>3?r(e,t,s):r(e,t))||s);return l>3&&s&&Object.defineProperty(e,t,s),s},a;import{css as b,html as w,LitElement as E}from"lit";import{customElement as C,property as m,state as R}from"lit/decorators.js";import{getEspBus as p}from"../shared/bus-events.js";import{subscribeToRootEvent as x}from"../shared/root-event-subscription.js";import{DEFAULT_LIGHT_THEME as f,DEFAULT_DARK_THEME as y,encodeTheme as S,parseTheme as g,mergeTheme as v}from"../shared/theme.js";import{computeThemeProperties as D}from"./helpers/compute-theme-properties.js";import{registerImageTexture as A,registeredImageTextures as L}from"../shared/image-texture-registry.js";import{registerImageTexture as O,registeredImageTextures as j,BUILT_IN_IMAGE_TEXTURES as H}from"../shared/image-texture-registry.js";const T=1e3;let o=a=class extends E{constructor(){super(...arguments),this.schemeBacker="",this.schemeExplicitlySet=!1,this.resolvingDefaultScheme=!1,this.themeEventsReady=!1,this.systemSchemeQuery=null,this.lastSeedColor="",this.resolvedLightTheme={...f},this.resolvedDarkTheme={...y},this.appliedDataRampProperties=new Set,this.documentClickRegistrationActive=!1,this.correlationId=globalThis.crypto?.randomUUID?.()??Math.random().toString(36),this.lightThemeAttr="",this.darkThemeAttr="",this.fontCSSRoot="/css/fonts/",this.fontDefinitionsUrl="",this.googleFontLoading="auto",this.iconSpriteUrl="/assets/icons.svg",this.themePending=!1,this.themeReadyState=!1,this.themeSettleWaiters=[],this.warnedThemeSettleTimeout=!1,this.defaultScheme="light",this.resizeObserver=new ResizeObserver(()=>{p().publish("window-resized",{emWidth:window.innerWidth/parseFloat(getComputedStyle(document.documentElement).fontSize),emHeight:window.innerHeight/parseFloat(getComputedStyle(document.documentElement).fontSize),pxWidth:window.innerWidth,pxHeight:window.innerHeight})}),this.handleSystemSchemeChange=e=>{this.schemeExplicitlySet||this.defaultScheme!=="system"||(this.resolvingDefaultScheme=!0,this.scheme=e.matches?"dark":"light",this.resolvingDefaultScheme=!1)}}static registerTexture(e,t){A(e,t)}static registeredTextures(){return L()}subscribeScoped(e,t){return x(this,e,t)}get lightTheme(){return this.lightThemeAttr?g(this.lightThemeAttr):null}set lightTheme(e){this.lightThemeAttr=e?S(e):""}get darkTheme(){return this.darkThemeAttr?g(this.darkThemeAttr):null}set darkTheme(e){this.darkThemeAttr=e?S(e):""}get themeSettled(){return this.themeReadyState}whenThemeSettled(){return this.themeReadyState?Promise.resolve():new Promise(e=>{this.themeSettleWaiters.push(e)})}get hasAuthorTheme(){return!!(this.scheme==="dark"?this.darkThemeAttr:this.lightThemeAttr)}settleTheme(){if(this.themeSettleTimer!==void 0&&(clearTimeout(this.themeSettleTimer),this.themeSettleTimer=void 0),this.themeReadyState)return;this.themeReadyState=!0;const e=this.themeSettleWaiters;this.themeSettleWaiters=[];for(const t of e)t()}get scheme(){return this.schemeBacker}set scheme(e){const t=e==="dark"?"dark":e==="light"?"light":"",i=this.schemeBacker,l=this.schemeExplicitlySet;this.resolvingDefaultScheme||(this.schemeExplicitlySet=t.length>0);const s=t||this.resolveDefaultScheme();l!==this.schemeExplicitlySet&&this.isConnected&&this.syncSystemSchemeListener(),s!==i&&(this.schemeBacker=s,this.requestUpdate("scheme",i),this.themeEventsReady&&p().publish("scheme-changed",{scheme:s,correlationId:this.correlationId}))}get seedColor(){return this.activeTheme.seedColor}static extractFamily(e){if(!e)return"";const t=e.match(/^"([^"]+)"|^'([^']+)'/);return t&&(t[1]||t[2])||""}injectGoogleFontLink(e,t,i){const l="data-esp-font",s=`${this.correlationId}-${e}`,r=document.head.querySelector(`link[${l}="${s}"]`);if(this.googleFontLoading==="none"){r?.remove();return}if(r&&t&&r.dataset.espFamily===t&&r.dataset.espWeight===(i??"")||(r?.remove(),!t))return;const n=encodeURIComponent(t),u=i==="bold"?"700":i==="normal"?"400":i,k=u&&u!=="400"?`:wght@${u}`:"",d=document.createElement("link");d.rel="stylesheet",d.href=`https://fonts.googleapis.com/css2?family=${n}${k}&display=swap`,d.setAttribute(l,s),d.dataset.espFamily=t,d.dataset.espWeight=i??"",document.head.appendChild(d)}syncGoogleFontLinks(){this.googleFontLoading==="none"&&this.removeRuntimeGoogleFontLinks();const e=this.activeTheme;this.injectGoogleFontLink("body",a.extractFamily(e.fontBody),e.fontWeightBody),this.injectGoogleFontLink("headings",a.extractFamily(e.fontHeadings),e.fontWeightHeadings),this.injectGoogleFontLink("brand",a.extractFamily(e.fontBrand),e.fontWeightBrand),this.injectGoogleFontLink("monospace",a.extractFamily(e.fontMonospace),e.fontWeightMonospace)}removeRuntimeGoogleFontLinks(){for(const e of document.head.querySelectorAll(`link[data-esp-font^="${this.correlationId}-"]`))e.remove();for(const e of document.head.querySelectorAll(`link[data-esp-font-picker-root="${CSS.escape(this.correlationId)}"]`))e.remove()}get activeTheme(){return this.scheme==="dark"?this.resolvedDarkTheme:this.resolvedLightTheme}resolveThemes(){const e=this.lightThemeAttr?g(this.lightThemeAttr):null;this.resolvedLightTheme=e?v(f,e):{...f};const t=this.darkThemeAttr?g(this.darkThemeAttr):null;this.resolvedDarkTheme=t?v(y,t):{...y}}connectedCallback(){super.connectedCallback(),this.registerDocumentClickBridge(),this.resizeObserver.observe(this),this.hasUpdated&&(this.applyDefaultScheme(),this.syncGoogleFontLinks(),this.hasAuthorTheme||this.startThemeSettleTimer())}willUpdate(e){const t=["lightThemeAttr","darkThemeAttr"];(!this.lastSeedColor||t.some(n=>e.has(n)))&&(this.resolveThemes(),this.themeEventsReady&&p().publish("theme-changed",{correlationId:this.correlationId})),this.hasAuthorTheme&&this.settleTheme();const l=D(this.activeTheme,this.scheme==="dark"?"dark":"light"),s=new Set(Object.keys(l).filter(n=>n.startsWith("--esp-color-ramp-")));for(const n of this.appliedDataRampProperties)s.has(n)||this.style.removeProperty(n);for(const[n,u]of Object.entries(l))this.style.setProperty(n,u);this.appliedDataRampProperties=s;const r=this.activeTheme.seedColor;this.themeEventsReady&&this.lastSeedColor&&this.lastSeedColor!==r&&p().publish("seed-color-changed",{seedColor:r,correlationId:this.correlationId}),this.lastSeedColor=r,this.themeEventsReady&&e.has("iconSpriteUrl")&&p().publish("icon-sprite-url-changed",{iconSpriteUrl:this.iconSpriteUrl,correlationId:this.correlationId}),this.syncGoogleFontLinks()}firstUpdated(){const e=this.activeTheme.stylesheets;if(e.length)for(const t of e){const i=document.createElement("link");i.rel="stylesheet",i.href=t,document.head.appendChild(i)}if(!document.getElementById("esp-root-base-styles")){const t=document.createElement("style");t.id="esp-root-base-styles",t.textContent=a.lightDomStyles,document.head.appendChild(t)}this.applyDefaultScheme(),this.lastSeedColor=this.activeTheme.seedColor,this.themeEventsReady=!0,this.startThemeSettleTimer()}startThemeSettleTimer(){if(this.themeReadyState||this.themeSettleTimer!==void 0)return;this.themeSettleDeadline??=performance.now()+T;const e=Math.max(0,this.themeSettleDeadline-performance.now());if(e===0){this.closeThemeWindow();return}this.themeSettleTimer=setTimeout(()=>this.closeThemeWindow(),e)}closeThemeWindow(){this.themeSettleTimer=void 0,this.themePending&&!this.warnedThemeSettleTimeout&&(this.warnedThemeSettleTimeout=!0,console.warn(`Espalier root: theme-pending was declared but no ${this.scheme} theme arrived within ${T}ms, so the default palette is rendering. Assign ${this.scheme==="dark"?"darkTheme":"lightTheme"} (or remove theme-pending).`)),this.settleTheme()}updated(e){this.toggleAttribute("data-theme-ready",this.themeReadyState),(e.has("defaultScheme")||e.has("scheme"))&&!this.schemeExplicitlySet&&this.applyDefaultScheme()}disconnectedCallback(){this.themeSettleTimer!==void 0&&(clearTimeout(this.themeSettleTimer),this.themeSettleTimer=void 0),this.unregisterDocumentClickBridge(),this.systemSchemeQuery?.removeEventListener("change",this.handleSystemSchemeChange),this.systemSchemeQuery=null,this.resizeObserver.disconnect(),this.removeRuntimeGoogleFontLinks(),super.disconnectedCallback()}registerDocumentClickBridge(){this.documentClickRegistrationActive||(this.documentClickRegistrationActive=!0,a.connectedRootCount+=1,a.connectedRootCount===1&&document.addEventListener("click",a.handleDocumentClick))}unregisterDocumentClickBridge(){this.documentClickRegistrationActive&&(this.documentClickRegistrationActive=!1,a.connectedRootCount=Math.max(0,a.connectedRootCount-1),a.connectedRootCount===0&&document.removeEventListener("click",a.handleDocumentClick))}applyDefaultScheme(){this.schemeExplicitlySet||(this.resolvingDefaultScheme=!0,this.scheme=this.resolveDefaultScheme(),this.resolvingDefaultScheme=!1,this.syncSystemSchemeListener())}resolveDefaultScheme(){return this.defaultScheme==="dark"||this.defaultScheme==="system"&&window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light"}syncSystemSchemeListener(){if(this.schemeExplicitlySet||this.defaultScheme!=="system"||!window.matchMedia){this.systemSchemeQuery?.removeEventListener("change",this.handleSystemSchemeChange),this.systemSchemeQuery=null;return}this.systemSchemeQuery||(this.systemSchemeQuery=window.matchMedia("(prefers-color-scheme: dark)"),this.systemSchemeQuery.addEventListener("change",this.handleSystemSchemeChange))}render(){return w`<slot></slot>`}};o.connectedRootCount=0,o.handleDocumentClick=c=>{const e=c.composedPath().filter(t=>t instanceof HTMLElement&&t.tagName==="ESP-POPOVER");p().publish("close-popovers",{source:c.target??void 0,skipPopovers:e})},o.lightDomStyles=`
2
2
 
3
3
  esp-root {
4
4
  font-family: var(--esp-font-body);
@@ -121,8 +121,13 @@ var a=function(d,e,t,o){var l=arguments.length,s=l<3?e:o===null?o=Object.getOwnP
121
121
  max-width: 100%;
122
122
  display: block;
123
123
  }
124
- `,i.styles=b`
124
+ `,o.styles=b`
125
125
  :host {
126
126
  display: block;
127
127
  }
128
- `,a([c({attribute:!1})],i.prototype,"correlationId",void 0),a([c({attribute:"light-theme"})],i.prototype,"lightThemeAttr",void 0),a([c({attribute:"dark-theme"})],i.prototype,"darkThemeAttr",void 0),a([c({attribute:!1})],i.prototype,"lightTheme",null),a([c({attribute:!1})],i.prototype,"darkTheme",null),a([c({attribute:"font-css-root",type:String})],i.prototype,"fontCSSRoot",void 0),a([c({attribute:"font-definitions-url",type:String})],i.prototype,"fontDefinitionsUrl",void 0),a([c({attribute:"google-font-loading",type:String})],i.prototype,"googleFontLoading",void 0),a([c({attribute:"icon-sprite-url",type:String})],i.prototype,"iconSpriteUrl",void 0),a([c({attribute:"default-scheme",type:String,reflect:!0})],i.prototype,"defaultScheme",void 0),a([c({attribute:"scheme",type:String,reflect:!0})],i.prototype,"scheme",null),i=h=a([E("esp-root")],i);export{M as BUILT_IN_IMAGE_TEXTURES,i as EspalierRoot,_ as registerImageTexture,H as registeredImageTextures};
128
+
129
+
130
+ :host([theme-pending]:not([data-theme-ready])) {
131
+ visibility: hidden;
132
+ }
133
+ `,h([m({attribute:!1})],o.prototype,"correlationId",void 0),h([m({attribute:"light-theme"})],o.prototype,"lightThemeAttr",void 0),h([m({attribute:"dark-theme"})],o.prototype,"darkThemeAttr",void 0),h([m({attribute:!1})],o.prototype,"lightTheme",null),h([m({attribute:!1})],o.prototype,"darkTheme",null),h([m({attribute:"font-css-root",type:String})],o.prototype,"fontCSSRoot",void 0),h([m({attribute:"font-definitions-url",type:String})],o.prototype,"fontDefinitionsUrl",void 0),h([m({attribute:"google-font-loading",type:String})],o.prototype,"googleFontLoading",void 0),h([m({attribute:"icon-sprite-url",type:String})],o.prototype,"iconSpriteUrl",void 0),h([m({attribute:"theme-pending",reflect:!0,type:Boolean})],o.prototype,"themePending",void 0),h([R()],o.prototype,"themeReadyState",void 0),h([m({attribute:"default-scheme",type:String,reflect:!0})],o.prototype,"defaultScheme",void 0),h([m({attribute:"scheme",type:String,reflect:!0})],o.prototype,"scheme",null),o=a=h([C("esp-root")],o);export{H as BUILT_IN_IMAGE_TEXTURES,o as EspalierRoot,O as registerImageTexture,j as registeredImageTextures};
@@ -0,0 +1 @@
1
+ import{classifyIconSpriteValue as D}from"./intent-values.js";import{traverseToClosest as L}from"./utilities.js";import{subscribeToRootEvent as P}from"./root-event-subscription.js";const E="data-esp-adopted-icons",A="http://www.w3.org/2000/svg",k=new Set;function ee(){k.clear()}function N(e,t){k.has(e)||(k.add(e),console.warn(t))}const v=new Map,g=new WeakMap;function V(e,t){const n=g.get(t);if(n===e)return;n&&C(n,t),g.set(t,e);let o=v.get(e);if(!o){const s=new Set,c=new MutationObserver(a=>{if(a.some(f=>f.target===e||e.contains(f.target)||[...f.removedNodes].some(i=>i===e||i.contains(e))||[...f.addedNodes].some(i=>i===e||i.contains(e))))for(const f of s)f.requestUpdate()});c.observe(e,{attributes:!0,characterData:!0,childList:!0,subtree:!0});const u=e.ownerDocument?.documentElement;u&&c.observe(u,{childList:!0,subtree:!0}),o={hosts:s,observer:c},v.set(e,o)}o.hosts.add(t)}function C(e,t){const n=v.get(e);n&&(n.hosts.delete(t),n.hosts.size===0&&(n.observer.disconnect(),v.delete(e)))}function $(e){const t=g.get(e);t&&(C(t,e),g.delete(e)),U(e)}const T=new WeakMap,w=new WeakMap;function z(e,t,n){const o=w.get(n);o&&(o.document!==e||o.spriteId!==t)&&U(n);let s=T.get(e);s||(s=new Map,T.set(e,s));let c=s.get(t);if(!c){const u=new Set,a=new MutationObserver(()=>{if(e.getElementById(t)){a.disconnect(),s.delete(t);for(const h of u)w.delete(h),h.requestUpdate()}});a.observe(e.documentElement,{childList:!0,subtree:!0}),c={hosts:u,observer:a},s.set(t,c)}c.hosts.add(n),w.set(n,{document:e,spriteId:t})}function U(e){const t=w.get(e);if(!t)return;w.delete(e);const n=T.get(t.document),o=n?.get(t.spriteId);o&&(o.hosts.delete(e),o.hosts.size===0&&(o.observer.disconnect(),n.delete(t.spriteId)))}function B(e,t,n){if(!t)return;const o=D(e?e.iconSpriteUrl:null);let s=t.querySelector(`svg[${E}]`);if(o.kind!=="document"){s?.remove(),n&&$(n);return}const c=new Set;for(const i of t.querySelectorAll("use")){if(s&&s.contains(i))continue;const l=x(i);l&&c.add(l)}if(c.size===0&&!s)return;const u=e?.ownerDocument??document,a=u.getElementById(o.spriteId);if(!a){if(N(o.spriteId,`Espalier icons: icon-sprite-url references "#${o.spriteId}" but no element with that id is in the document. Inline the sprite before setting icon-sprite-url (or set it again after), and icons will render.`),s?.remove(),n){const i=g.get(n);i&&(C(i,n),g.delete(n)),z(u,o.spriteId,n)}return}if(n&&U(n),a.namespaceURI!==A||a.localName!=="svg"){N(o.spriteId,`Espalier icons: icon-sprite-url references "#${o.spriteId}", but that element is a <${a.localName}>, not an inline SVG sprite. Icons stay empty until the id names an <svg> containing <symbol>s.`),s?.remove(),n&&$(n);return}n&&V(a,n);{const i=new Set,l=[...c];for(;l.length>0;){const r=l.pop();if(i.has(r))continue;i.add(r);const d=M(a,r);if(d)for(const m of Z(d))i.has(m)||(c.add(m),l.push(m))}}s&&s.getAttribute(E)!==o.spriteId&&(s.remove(),s=null);const h=new Map,f=i=>{const l=M(a,i);return l?{clone:K(l,a,o.spriteId,h)?l.cloneNode(!0):null,source:l}:{clone:null,source:null}};if(s){for(const i of[...s.children]){const l=i.getAttribute("id")??"",{clone:r,source:d}=c.has(l)?f(l):{clone:null,source:null};!r||!d?i.remove():i.isEqualNode(d)||s.replaceChild(r,i)}s.children.length===0&&c.size===0&&(s.remove(),s=null)}for(const i of c){if(s?.querySelector(`#${R(i)}`))continue;const{clone:l}=f(i);if(l){if(!s){s=t.ownerDocument.createElementNS(A,"svg"),s.setAttribute(E,o.spriteId),s.setAttribute("aria-hidden","true");const r=s.style;r.position="absolute",r.width="0",r.height="0",r.overflow="hidden",t.appendChild(s)}s.appendChild(l)}}}const O="http://www.w3.org/1999/xlink",F=new Set(["a","animate","animatemotion","animatetransform","discard","foreignobject","script","set","style"]),H=["href","xlink:href"],G=/url\(/giu,j=/url\(\s*(?:"#([^"\\]*)"|'#([^'\\]*)'|#([^\s)"'\\]*))\s*\)/giu;function I(e){let t=!1;const n=e.replace(/(%[0-9A-Fa-f]{2})+/gu,o=>{try{return decodeURIComponent(o)}catch{return t=!0,o}});return t?null:n}function _(e){const t=[...e.matchAll(G)].length,n=[];for(const o of e.matchAll(j)){const s=o[1]??o[2]??o[3]??"";if(s.length===0)continue;const c=I(s);c!==null&&n.push(c)}return{ids:n,ok:n.length===t}}function x(e){const t=W(e);return t===null?null:I(t)}function W(e){if(e.localName!=="use")return null;const t=e.getAttribute("href")??e.getAttribute("xlink:href")??e.getAttributeNS(O,"href");if(!t)return null;const n=t.trim();return n.startsWith("#")&&n.length>1?n.slice(1):null}function K(e,t,n,o){const s=o.get(e);if(s!==void 0)return s;const c=new Map,u=[],a=new Map,h=r=>(a.has(r)||a.set(r,M(t,r)),a.get(r)??null),f=[e];for(;f.length>0;){const r=f.pop();if(c.has(r))continue;const d=o.get(r);if(d!==void 0){c.set(r,{dependencies:[],localOk:d,missing:[]}),u.push(r);continue}const m=X(r,n),b=[],S=[];for(const q of m.dependencyIds){const y=h(q);y?(b.push(y),f.push(y)):S.push(q)}c.set(r,{dependencies:b,localOk:m.ok,missing:S}),u.push(r)}const i=new Set;for(const r of u){const d=c.get(r);(!d.localOk||d.missing.length>0)&&i.add(r)}let l=!0;for(;l;){l=!1;for(const r of u)i.has(r)||c.get(r).dependencies.some(d=>i.has(d))&&(i.add(r),l=!0)}for(const r of u){const d=c.get(r),m=!i.has(r);if(!m&&d.localOk){const b=d.missing[0]??d.dependencies.find(S=>i.has(S))?.getAttribute("id")??"?";p(r,n,d.missing.length>0?`composes or paints through #${b}, which is not in the sprite`:`composes or paints through the refused member #${b}`)}o.set(r,m)}return o.get(e)}function X(e,t){const n=[],o=[e,...e.querySelectorAll("*")];for(const s of o){if(s.namespaceURI!==A)return p(e,t,`contains the non-SVG element <${s.localName}>`),{dependencyIds:n,ok:!1};if(F.has(s.localName.toLowerCase()))return p(e,t,`contains <${s.localName}>`),{dependencyIds:n,ok:!1};let c=s.getAttributeNS(O,"href")!==null;for(const h of s.getAttributeNames()){const f=h.toLowerCase();if(f.startsWith("on"))return p(e,t,`carries the event-handler attribute ${h}`),{dependencyIds:n,ok:!1};if(H.includes(f)&&(c=!0),f==="src")return p(e,t,"carries a src attribute"),{dependencyIds:n,ok:!1};if(f==="style")return p(e,t,"carries an inline style attribute \u2014 use presentation attributes"),{dependencyIds:n,ok:!1};const i=s.getAttribute(h)??"";if(i.includes("\\"))return p(e,t,`carries a CSS escape sequence in ${h}`),{dependencyIds:n,ok:!1};const l=_(i);if(!l.ok)return p(e,t,`carries an unparseable or external url() reference in ${h}`),{dependencyIds:n,ok:!1};n.push(...l.ids)}const u=W(s),a=u===null?null:I(u);if(u!==null&&a===null)return p(e,t,`composes <use href="#${u}">, an undecodable fragment the browser resolves to nothing`),{dependencyIds:n,ok:!1};if(c&&a===null)return p(e,t,"carries an href outside a local-fragment <use> reference"),{dependencyIds:n,ok:!1};a!==null&&n.push(a)}return{dependencyIds:n,ok:!0}}function p(e,t,n){const o=e.getAttribute("id")??"(unnamed)";N(`${t}#${o}`,`Espalier icons: symbol "${o}" in "#${t}" ${n} and was not adopted \u2014 sprite symbols must be passive SVG (shapes, paths, local <use> composition).`)}function M(e,t){if(!t)return null;const o=e.querySelector(`symbol#${R(t)}`)??e.querySelector(`#${R(t)}`);return o&&o.namespaceURI===A?o:null}function Z(e){const t=new Set,n=[e,...e.querySelectorAll("*")];for(const o of n){const s=x(o);s&&t.add(s);for(const c of o.getAttributeNames())for(const u of _(o.getAttribute(c)??"").ids)t.add(u)}return t}function R(e){const t=globalThis.CSS?.escape;return t?t(e):e.replace(/[^A-Za-z0-9_-]/gu,"\\$&")}class te{constructor(t,n){this.host=t,this.options=n,this.root=null,this.unsubscribe=null,t.addController(this)}hostConnected(){this.root=L(this.host,"esp-root"),this.options.reactToSpriteChanges&&this.root&&(this.unsubscribe=P(this.root,"icon-sprite-url-changed",()=>{this.host.requestUpdate()}))}hostDisconnected(){this.unsubscribe?.(),this.unsubscribe=null,this.root=null,$(this.host)}hostUpdated(){this.root??=L(this.host,"esp-root"),B(this.root,this.host.shadowRoot,this.host)}}export{te as DocumentSpriteController,B as adoptDocumentSpriteSymbols,I as decodeFragmentId,ee as resetWarnedMissingSprites};
@@ -66,6 +66,7 @@ export declare class EspalierElementBase extends LitElement implements SeedColor
66
66
  connectedCallback(): void;
67
67
  disconnectedCallback(): void;
68
68
  protected firstUpdated(_changedProperties: PropertyValues): void;
69
+ constructor();
69
70
  /**
70
71
  * Traverse up the DOM tree to find the closest element that
71
72
  * matches the selector. This method is aware of shadow DOM
@@ -1,4 +1,4 @@
1
- var c=function(u,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(u,e,t,r);else for(var i=u.length-1;i>=0;i--)(a=u[i])&&(s=(o<3?a(s):o>3?a(e,t,s):a(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s};import{css as R,LitElement as T}from"lit";import{property as d,state as C}from"lit/decorators.js";import{subscribeToRootEvent as p}from"./root-event-subscription.js";import{traverseToClosest as b}from"./utilities.js";import{parseCssColor as S,serializeOklch as w,gamutMapToSRGB as P}from"./color-engine.js";import{computeVariants as m}from"../root/helpers/compute-variants.js";import{computeSemanticProperties as v}from"../root/helpers/compute-semantic-properties.js";import{dataCompanionProperties as x}from"../root/helpers/data-companion-properties.js";import{dataSeriesProperties as E}from"../root/helpers/compute-theme-properties.js";import{lightnessRampProperties as V}from"../root/helpers/lightness-ramp-properties.js";import{ELEVATION_PROPERTIES as U}from"./scale-engine.js";import{resolveContextTheme as I,resolveDataColorSource as A,semanticToCSS as O}from"./theme.js";import{alignAttributeTextInheritance as D,focusRing as z}from"./style-fragments.js";import{syncNormalizedAttribute as F}from"./attribute-helpers.js";import{INTENT_VARIANTS as y,normalizeIntentVariant as N}from"./intent-values.js";class n extends T{constructor(){super(...arguments),this.seedColorBacker="oklch(0.7 0.125 216)",this.espRoot=null,this.contextBacker="",this.scopedTokenOriginalValues=new Map,this.warnedUnknownContexts=new Set,this.pendingInitialThemeRoot=null,this.rootEventSubscriptionsActive=!1,this.subscribedRoot=null,this.rootEventUnsubscribers=[],this.intentBacker="neutral",this.intentEmitsTokens=!0,this.warnedUnknownIntents=new Set,this.correlationId=globalThis.crypto?.randomUUID?.()??Math.random().toString(36),this.scheme="light",this.handleSeedColorChanged=e=>{this.syncRootFromDom(!1)&&(this.seedColor=e.seedColor,this.applyScopedColorTokens())},this.handleSchemeChanged=e=>{!this.syncRootFromDom(!1)||this.scheme===e.scheme||(this.scheme=e.scheme,this.applyScopedColorTokens())},this.handleThemeChanged=()=>{this.syncRootFromDom(!1)&&this.applyScopedColorTokens()},this.handleIconSpriteUrlChanged=()=>{this.syncRootFromDom(!1)&&this.requestUpdate()}}get seedColor(){return this.seedColorBacker}set seedColor(e){this.seedColorBacker=e}focusResolvedElementAfterUpdate(e,t){const r=()=>{const o=e();return o?(o.focus(t),!0):!1};r()||this.updateComplete.then(()=>{r()})}focusShadowElementAfterUpdate(e,t){this.focusResolvedElementAfterUpdate(()=>this.shadowRoot?.querySelector(e),t)}emitValueChanged(e){this.dispatchEvent(new CustomEvent("value-changed",{detail:e,bubbles:!0,composed:!0}))}get intent(){return this.intentBacker}set intent(e){const t=typeof e=="string"?e.trim():"";t!==""&&!y.includes(t)&&!this.warnedUnknownIntents.has(t)&&(this.warnedUnknownIntents.add(t),console.warn(`Espalier intent: "${t}" is not an intent; expected one of ${y.join(", ")}. Treating it as "neutral".`));const r=this.intentBacker,o=N(e);F(this,"intent",o),o!==r&&(this.intentBacker=o,this.requestUpdate("intent",r),this.applyTokensWhenRootReady())}get context(){return this.contextBacker}set context(e){const t=e??"";t!==this.contextBacker&&(this.contextBacker=t,this.applyTokensWhenRootReady(),this.refreshDescendantIntentDerivations())}refreshDescendantIntentDerivations(){const e=new Set,t=o=>{for(const s of Array.from(o.children))r(s)},r=o=>{if(!e.has(o)){if(e.add(o),o instanceof n&&o.applyTokensWhenRootReady(),o.shadowRoot&&t(o.shadowRoot),o instanceof HTMLSlotElement)for(const s of o.assignedElements({flatten:!0}))r(s);t(o)}};t(this),this.shadowRoot&&t(this.shadowRoot)}static flattenedParent(e){return e instanceof Element&&e.assignedSlot?e.assignedSlot:e instanceof ShadowRoot?e.host:e.parentNode}resolveAncestorZoneTheme(e){let t=n.flattenedParent(this);for(;t;){if(t instanceof Element&&t.localName==="esp-root")return null;if(t instanceof n){const r=t.contextBacker.trim();if(r){const o=this.resolveNamedContextTheme(e,r);if(o)return o}}t=n.flattenedParent(t)}return null}connectedCallback(){super.connectedCallback();const e=this.syncRootFromDom(!1);e&&this.subscribeToRootEvents(e)}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeFromRootEvents(),this.clearScopedTokens(),this.espRoot=null}firstUpdated(e){this.syncRootFromDom(!0),this.applyTokensWhenRootReady()}syncRootFromDom(e){const t=b(this,"esp-root");if(!t){if(this.espRoot&&this.clearScopedTokens(),this.unsubscribeFromRootEvents(),this.espRoot=null,!e)return null;throw new Error("No esp-root ancestor found. Espalier components must be placed inside an <esp-root> element.")}const r=t!==this.espRoot,s=t.scheme==="dark"?"dark":"light",a=this.scheme!==s,i=this.seedColor!==t.seedColor;return this.espRoot=t,r&&this.isConnected&&this.subscribeToRootEvents(t),(r||a||i)&&(this.scheme=s,this.seedColor=t.seedColor,this.applyTokensWhenRootReady()),r&&this.requestUpdate(),t}applyTokensWhenRootReady(){const e=this.espRoot;if(e&&(!e.hasUpdated||e.isUpdatePending)){this.applyTokensAfterInitialRootUpdate(e);return}this.applyScopedColorTokens()}applyTokensAfterInitialRootUpdate(e){if(this.pendingInitialThemeRoot===e)return;this.pendingInitialThemeRoot=e;const t=e.updateComplete;if(!t){this.pendingInitialThemeRoot=null,this.applyScopedColorTokens();return}t.then(()=>{this.pendingInitialThemeRoot===e&&(this.pendingInitialThemeRoot=null),!(!this.isConnected||this.espRoot!==e)&&(this.scheme=e.scheme==="dark"?"dark":"light",this.seedColor=e.seedColor,this.applyScopedColorTokens())})}subscribeToRootEvents(e){this.rootEventSubscriptionsActive&&this.subscribedRoot===e||(this.unsubscribeFromRootEvents(),this.subscribedRoot=e,this.rootEventUnsubscribers=[p(e,"seed-color-changed",this.handleSeedColorChanged),p(e,"scheme-changed",this.handleSchemeChanged),p(e,"theme-changed",this.handleThemeChanged),p(e,"icon-sprite-url-changed",this.handleIconSpriteUrlChanged)],this.rootEventSubscriptionsActive=!0)}unsubscribeFromRootEvents(){if(this.rootEventSubscriptionsActive){for(const e of this.rootEventUnsubscribers)e();this.rootEventUnsubscribers=[],this.subscribedRoot=null,this.rootEventSubscriptionsActive=!1}}traverseToClosest(e){return b(this,e)}applyScopedColorTokens(){if(!this.espRoot)return;const e=this.intentEmitsTokens?n.intentColorSources[this.intentBacker]:"";if(!e&&!this.context.trim()){this.clearScopedTokens();return}const t=this.espRoot.activeTheme;if(!t){this.clearScopedTokens();return}const r=this.resolveContextTheme(t),o=r.theme,s=S(o.seedColor);if(!s)return;const a=m(s,o),i={};if(r.applied&&(Object.assign(i,v(o,a)),Object.assign(i,V(o)),Object.assign(i,U),Object.assign(i,x(i,E(o,s,l=>(typeof l=="string"?A(l,o.anchors):null)??o.seedColor)))),e){let l=o;r.applied||(l=this.resolveAncestorZoneTheme(t)??o);const g=l===o?a:m(s,l),k=v(l,g,{effectiveSource:(f,h)=>n.semanticActionTokens.has(f)?e:h});i["--esp-color-primary"]=w(P(g[e]));for(const f of n.semanticActionTokens){const h=O(f);i[h]=k[h]}}this.applyScopedTokenProperties(i)}resolveContextTheme(e){const t=this.context.trim();if(!t)return{applied:!1,theme:e};const r=this.resolveNamedContextTheme(e,t);return r?{applied:!0,theme:r}:(this.warnedUnknownContexts.has(t)||(this.warnedUnknownContexts.add(t),console.warn(`Espalier context: "${t}" is not defined by the active theme; inheriting root tokens.`)),{applied:!1,theme:e})}resolveNamedContextTheme(e,t){return I(e,t)}applyScopedTokenProperties(e){for(const t of this.scopedTokenOriginalValues.keys())t in e||this.restoreScopedTokenProperty(t);for(const[t,r]of Object.entries(e))this.setScopedTokenProperty(t,r)}setScopedTokenProperty(e,t){const r=this.scopedTokenOriginalValues.get(e);if(r){const o=this.style.getPropertyValue(e),s=this.style.getPropertyPriority(e);(o!==r.generatedValue||s!==r.generatedPriority)&&(r.originalValue=o.length?o:null,r.originalPriority=s),r.generatedValue=t,r.generatedPriority=""}else{const o=this.style.getPropertyValue(e);this.scopedTokenOriginalValues.set(e,{generatedPriority:"",generatedValue:t,originalPriority:this.style.getPropertyPriority(e),originalValue:o.length?o:null})}this.style.setProperty(e,t)}restoreScopedTokenProperty(e){const t=this.scopedTokenOriginalValues.get(e);if(!t)return;const r=this.style.getPropertyValue(e),o=this.style.getPropertyPriority(e);(r!==t.generatedValue||o!==t.generatedPriority)&&(t.originalValue=r.length?r:null,t.originalPriority=o),t.originalValue===null?this.style.removeProperty(e):this.style.setProperty(e,t.originalValue,t.originalPriority),this.scopedTokenOriginalValues.delete(e)}clearScopedTokens(){for(const e of[...this.scopedTokenOriginalValues.keys()])this.restoreScopedTokenProperty(e)}}n.intentColorSources={danger:"danger",info:"info",neutral:"",success:"success",warning:"warning"},n.semanticActionTokens=new Set(["actionBackground","actionText"]),n.styles=[z(".esp-field:focus-within","--esp-field-focus-shadow"),D,R`
1
+ var c=function(u,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(u,e,t,r);else for(var i=u.length-1;i>=0;i--)(a=u[i])&&(s=(o<3?a(s):o>3?a(e,t,s):a(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s};import{css as R,LitElement as C}from"lit";import{property as d,state as S}from"lit/decorators.js";import{subscribeToRootEvent as p}from"./root-event-subscription.js";import{traverseToClosest as m}from"./utilities.js";import{parseCssColor as w,serializeOklch as x,gamutMapToSRGB as P}from"./color-engine.js";import{computeVariants as b}from"../root/helpers/compute-variants.js";import{computeSemanticProperties as v}from"../root/helpers/compute-semantic-properties.js";import{DocumentSpriteController as E}from"./document-sprite.js";import{dataCompanionProperties as U}from"../root/helpers/data-companion-properties.js";import{dataSeriesProperties as V}from"../root/helpers/compute-theme-properties.js";import{lightnessRampProperties as I}from"../root/helpers/lightness-ramp-properties.js";import{ELEVATION_PROPERTIES as A}from"./scale-engine.js";import{resolveContextTheme as y,resolveDataColorSource as O,semanticToCSS as D}from"./theme.js";import{alignAttributeTextInheritance as z,focusRing as F}from"./style-fragments.js";import{syncNormalizedAttribute as N}from"./attribute-helpers.js";import{INTENT_VARIANTS as k,normalizeIntentVariant as j}from"./intent-values.js";class n extends C{get seedColor(){return this.seedColorBacker}set seedColor(e){this.seedColorBacker=e}focusResolvedElementAfterUpdate(e,t){const r=()=>{const o=e();return o?(o.focus(t),!0):!1};r()||this.updateComplete.then(()=>{r()})}focusShadowElementAfterUpdate(e,t){this.focusResolvedElementAfterUpdate(()=>this.shadowRoot?.querySelector(e),t)}emitValueChanged(e){this.dispatchEvent(new CustomEvent("value-changed",{detail:e,bubbles:!0,composed:!0}))}get intent(){return this.intentBacker}set intent(e){const t=typeof e=="string"?e.trim():"";t!==""&&!k.includes(t)&&!this.warnedUnknownIntents.has(t)&&(this.warnedUnknownIntents.add(t),console.warn(`Espalier intent: "${t}" is not an intent; expected one of ${k.join(", ")}. Treating it as "neutral".`));const r=this.intentBacker,o=j(e);N(this,"intent",o),o!==r&&(this.intentBacker=o,this.requestUpdate("intent",r),this.applyTokensWhenRootReady())}get context(){return this.contextBacker}set context(e){const t=e??"";t!==this.contextBacker&&(this.contextBacker=t,this.applyTokensWhenRootReady(),this.refreshDescendantIntentDerivations())}refreshDescendantIntentDerivations(){const e=new Set,t=o=>{for(const s of Array.from(o.children))r(s)},r=o=>{if(!e.has(o)){if(e.add(o),o instanceof n&&o.applyTokensWhenRootReady(),o.shadowRoot&&t(o.shadowRoot),o instanceof HTMLSlotElement)for(const s of o.assignedElements({flatten:!0}))r(s);t(o)}};t(this),this.shadowRoot&&t(this.shadowRoot)}static flattenedParent(e){return e instanceof Element&&e.assignedSlot?e.assignedSlot:e instanceof ShadowRoot?e.host:e.parentNode}resolveAncestorZoneTheme(e){let t=n.flattenedParent(this);for(;t;){if(t instanceof Element&&t.localName==="esp-root")return null;if(t instanceof n){const r=t.contextBacker.trim();if(r){const o=this.resolveNamedContextTheme(e,r);if(o)return o}}t=n.flattenedParent(t)}return null}connectedCallback(){super.connectedCallback();const e=this.syncRootFromDom(!1);e&&this.subscribeToRootEvents(e)}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeFromRootEvents(),this.clearScopedTokens(),this.espRoot=null}firstUpdated(e){this.syncRootFromDom(!0),this.applyTokensWhenRootReady()}syncRootFromDom(e){const t=m(this,"esp-root");if(!t){if(this.espRoot&&this.clearScopedTokens(),this.unsubscribeFromRootEvents(),this.espRoot=null,!e)return null;throw new Error("No esp-root ancestor found. Espalier components must be placed inside an <esp-root> element.")}const r=t!==this.espRoot,s=t.scheme==="dark"?"dark":"light",a=this.scheme!==s,i=this.seedColor!==t.seedColor;return this.espRoot=t,r&&this.isConnected&&this.subscribeToRootEvents(t),(r||a||i)&&(this.scheme=s,this.seedColor=t.seedColor,this.applyTokensWhenRootReady()),r&&this.requestUpdate(),t}applyTokensWhenRootReady(){const e=this.espRoot;if(e&&(!e.hasUpdated||e.isUpdatePending)){this.applyTokensAfterInitialRootUpdate(e);return}this.applyScopedColorTokens()}applyTokensAfterInitialRootUpdate(e){if(this.pendingInitialThemeRoot===e)return;this.pendingInitialThemeRoot=e;const t=e.updateComplete;if(!t){this.pendingInitialThemeRoot=null,this.applyScopedColorTokens();return}t.then(()=>{this.pendingInitialThemeRoot===e&&(this.pendingInitialThemeRoot=null),!(!this.isConnected||this.espRoot!==e)&&(this.scheme=e.scheme==="dark"?"dark":"light",this.seedColor=e.seedColor,this.applyScopedColorTokens())})}subscribeToRootEvents(e){this.rootEventSubscriptionsActive&&this.subscribedRoot===e||(this.unsubscribeFromRootEvents(),this.subscribedRoot=e,this.rootEventUnsubscribers=[p(e,"seed-color-changed",this.handleSeedColorChanged),p(e,"scheme-changed",this.handleSchemeChanged),p(e,"theme-changed",this.handleThemeChanged),p(e,"icon-sprite-url-changed",this.handleIconSpriteUrlChanged)],this.rootEventSubscriptionsActive=!0)}unsubscribeFromRootEvents(){if(this.rootEventSubscriptionsActive){for(const e of this.rootEventUnsubscribers)e();this.rootEventUnsubscribers=[],this.subscribedRoot=null,this.rootEventSubscriptionsActive=!1}}constructor(){super(),this.seedColorBacker="oklch(0.7 0.125 216)",this.espRoot=null,this.contextBacker="",this.scopedTokenOriginalValues=new Map,this.warnedUnknownContexts=new Set,this.pendingInitialThemeRoot=null,this.rootEventSubscriptionsActive=!1,this.subscribedRoot=null,this.rootEventUnsubscribers=[],this.intentBacker="neutral",this.intentEmitsTokens=!0,this.warnedUnknownIntents=new Set,this.correlationId=globalThis.crypto?.randomUUID?.()??Math.random().toString(36),this.scheme="light",this.handleSeedColorChanged=e=>{this.syncRootFromDom(!1)&&(this.seedColor=e.seedColor,this.applyScopedColorTokens())},this.handleSchemeChanged=e=>{!this.syncRootFromDom(!1)||this.scheme===e.scheme||(this.scheme=e.scheme,this.applyScopedColorTokens())},this.handleThemeChanged=()=>{this.syncRootFromDom(!1)&&this.applyScopedColorTokens()},this.handleIconSpriteUrlChanged=()=>{this.syncRootFromDom(!1)&&this.requestUpdate()},new E(this,{reactToSpriteChanges:!1})}traverseToClosest(e){return m(this,e)}applyScopedColorTokens(){if(!this.espRoot)return;const e=this.intentEmitsTokens?n.intentColorSources[this.intentBacker]:"";if(!e&&!this.context.trim()){this.clearScopedTokens();return}const t=this.espRoot.activeTheme;if(!t){this.clearScopedTokens();return}const r=this.resolveContextTheme(t),o=r.theme,s=w(o.seedColor);if(!s)return;const a=b(s,o),i={};if(r.applied&&(Object.assign(i,v(o,a)),Object.assign(i,I(o)),Object.assign(i,A),Object.assign(i,U(i,V(o,s,l=>(typeof l=="string"?O(l,o.anchors):null)??o.seedColor)))),e){let l=o;r.applied||(l=this.resolveAncestorZoneTheme(t)??o);const g=l===o?a:b(s,l),T=v(l,g,{effectiveSource:(f,h)=>n.semanticActionTokens.has(f)?e:h});i["--esp-color-primary"]=x(P(g[e]));for(const f of n.semanticActionTokens){const h=D(f);i[h]=T[h]}}this.applyScopedTokenProperties(i)}resolveContextTheme(e){const t=this.context.trim();if(!t)return{applied:!1,theme:e};const r=this.resolveNamedContextTheme(e,t);return r?{applied:!0,theme:r}:(this.warnUnknownContextWhenSettled(t),{applied:!1,theme:e})}warnUnknownContextWhenSettled(e){if(this.warnedUnknownContexts.has(e))return;const t=this.espRoot;if(t&&!t.themeSettled){t.whenThemeSettled().then(()=>{if(!this.isConnected||this.espRoot!==t||this.context.trim()!==e)return;const r=t.activeTheme;r&&y(r,e)||this.warnUnknownContextWhenSettled(e)});return}this.warnedUnknownContexts.add(e),console.warn(`Espalier context: "${e}" is not defined by the active theme; inheriting root tokens.`)}resolveNamedContextTheme(e,t){return y(e,t)}applyScopedTokenProperties(e){for(const t of this.scopedTokenOriginalValues.keys())t in e||this.restoreScopedTokenProperty(t);for(const[t,r]of Object.entries(e))this.setScopedTokenProperty(t,r)}setScopedTokenProperty(e,t){const r=this.scopedTokenOriginalValues.get(e);if(r){const o=this.style.getPropertyValue(e),s=this.style.getPropertyPriority(e);(o!==r.generatedValue||s!==r.generatedPriority)&&(r.originalValue=o.length?o:null,r.originalPriority=s),r.generatedValue=t,r.generatedPriority=""}else{const o=this.style.getPropertyValue(e);this.scopedTokenOriginalValues.set(e,{generatedPriority:"",generatedValue:t,originalPriority:this.style.getPropertyPriority(e),originalValue:o.length?o:null})}this.style.setProperty(e,t)}restoreScopedTokenProperty(e){const t=this.scopedTokenOriginalValues.get(e);if(!t)return;const r=this.style.getPropertyValue(e),o=this.style.getPropertyPriority(e);(r!==t.generatedValue||o!==t.generatedPriority)&&(t.originalValue=r.length?r:null,t.originalPriority=o),t.originalValue===null?this.style.removeProperty(e):this.style.setProperty(e,t.originalValue,t.originalPriority),this.scopedTokenOriginalValues.delete(e)}clearScopedTokens(){for(const e of[...this.scopedTokenOriginalValues.keys()])this.restoreScopedTokenProperty(e)}}n.intentColorSources={danger:"danger",info:"info",neutral:"",success:"success",warning:"warning"},n.semanticActionTokens=new Set(["actionBackground","actionText"]),n.styles=[F(".esp-field:focus-within","--esp-field-focus-shadow"),z,R`
2
2
  :host {
3
3
 
4
4
  --_esp-field-resolved-hover-bg: var(
@@ -122,4 +122,4 @@ var c=function(u,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
122
122
  .esp-field:has(textarea:disabled):hover {
123
123
  background-color: var(--esp-field-background, var(--esp-color-layer-2));
124
124
  }
125
- `],c([C()],n.prototype,"seedColor",null),c([d({attribute:!1})],n.prototype,"correlationId",void 0),c([d({type:String,reflect:!0})],n.prototype,"scheme",void 0),c([d({type:String,attribute:"intent",reflect:!0,useDefault:!0})],n.prototype,"intent",null),c([d({type:String,attribute:"context",reflect:!0})],n.prototype,"context",null);export{n as EspalierElementBase};
125
+ `],c([S()],n.prototype,"seedColor",null),c([d({attribute:!1})],n.prototype,"correlationId",void 0),c([d({type:String,reflect:!0})],n.prototype,"scheme",void 0),c([d({type:String,attribute:"intent",reflect:!0,useDefault:!0})],n.prototype,"intent",null),c([d({type:String,attribute:"context",reflect:!0})],n.prototype,"context",null);export{n as EspalierElementBase};
@@ -16,6 +16,35 @@ export declare function getIconHrefForHost(icon: string | null | undefined, host
16
16
  * "Converting circular structure to JSON". A plain backticked name is safe.
17
17
  */
18
18
  export declare const getIconHref: typeof getIconHrefForHost;
19
+ /**
20
+ * The configured sprite, classified (ESP0176).
21
+ *
22
+ * - `url` — an ordinary sprite location; hrefs become `url#name`.
23
+ * - `document` — the same-document form: a value that IS a fragment
24
+ * (`#sprite-id`) names an inline `<svg>` sprite already in the
25
+ * document — Espalier's own `ICON_SPRITE`, or any sprite the site
26
+ * provides. Hrefs become bare `#name` and components adopt the
27
+ * referenced symbols into their shadow roots.
28
+ * - `none` — the empty value; generated sprite icons are disabled.
29
+ */
30
+ export type IconSpriteReference = {
31
+ kind: "url";
32
+ url: string;
33
+ } | {
34
+ kind: "document";
35
+ spriteId: string;
36
+ } | {
37
+ kind: "none";
38
+ };
39
+ export declare function getIconSpriteReference(host: Element | null | undefined): IconSpriteReference;
40
+ /** Classify a raw `icon-sprite-url` value. */
41
+ export declare function classifyIconSpriteValue(value: string | null | undefined): IconSpriteReference;
42
+ /**
43
+ * The configured sprite URL with any fragment stripped, or `""` when
44
+ * generated icons are off — including the same-document form, which
45
+ * has no URL. Prefer {@link getIconSpriteReference}, which the
46
+ * same-document mode of ESP0176 made the complete answer.
47
+ */
19
48
  export declare function getIconSpriteUrl(host: Element | null | undefined): string;
20
49
  /**
21
50
  * Reset the per-process record of which invalid icon names have
@@ -1 +1 @@
1
- import{traverseToClosest as a}from"./utilities.js";const i="/assets/icons.svg",p="0 0 24 24",c=/^[A-Za-z0-9][A-Za-z0-9_-]*$/u,l=100,r=new Set,o=[],u=["neutral","success","warning","danger","info"];function N(n){return u.includes(n)?n:"neutral"}function I(n,t=null){const e=n?.trim()??"";if(!c.test(e))return e.length>0&&m(e)&&console.warn(`Invalid Espalier icon name "${e}". Icon names must start with a letter or number and may only contain letters, numbers, dashes, and underscores.`),"";const s=d(t);return s?`${s}#${e}`:""}const _=I;function d(n){const t=n?a(n,"esp-root"):null;return(t?(t.iconSpriteUrl??"").trim():i).split("#")[0]?.trim()||""}function m(n){if(r.has(n))return!1;if(r.add(n),o.push(n),o.length>l){const t=o.shift();t&&r.delete(t)}return!0}function g(){r.clear(),o.length=0}export{i as DEFAULT_ICON_SPRITE_URL,p as DEFAULT_ICON_VIEW_BOX,u as INTENT_VARIANTS,_ as getIconHref,I as getIconHrefForHost,d as getIconSpriteUrl,N as normalizeIntentVariant,g as resetWarnedInvalidIconNames};
1
+ import{traverseToClosest as i}from"./utilities.js";const u="/assets/icons.svg",N="0 0 24 24",a=/^[A-Za-z0-9][A-Za-z0-9_-]*$/u,l=100,o=new Set,s=[],d=["neutral","success","warning","danger","info"];function _(n){return d.includes(n)?n:"neutral"}function I(n,e=null){const t=n?.trim()??"";if(!a.test(t))return t.length>0&&m(t)&&console.warn(`Invalid Espalier icon name "${t}". Icon names must start with a letter or number and may only contain letters, numbers, dashes, and underscores.`),"";const r=c(e);switch(r.kind){case"url":return`${r.url}#${t}`;case"document":return`#${t}`;default:return""}}const g=I;function c(n){const e=n?i(n,"esp-root"):null;return f(e?e.iconSpriteUrl:u)}function f(n){const e=(n??"").trim();if(e.startsWith("#")){const r=e.slice(1).trim();return r?{kind:"document",spriteId:r}:{kind:"none"}}const t=e.split("#")[0]?.trim()||"";return t?{kind:"url",url:t}:{kind:"none"}}function A(n){const e=c(n);return e.kind==="url"?e.url:""}function m(n){if(o.has(n))return!1;if(o.add(n),s.push(n),s.length>l){const e=s.shift();e&&o.delete(e)}return!0}function h(){o.clear(),s.length=0}export{u as DEFAULT_ICON_SPRITE_URL,N as DEFAULT_ICON_VIEW_BOX,d as INTENT_VARIANTS,f as classifyIconSpriteValue,g as getIconHref,I as getIconHrefForHost,c as getIconSpriteReference,A as getIconSpriteUrl,_ as normalizeIntentVariant,h as resetWarnedInvalidIconNames};
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "updatedAt": "2026-08-19",
3
+ "updatedAt": "2026-08-22",
4
4
  "entries": [
5
5
  {
6
6
  "id": "google-font-preview-assets",
@@ -28,7 +28,8 @@
28
28
  {
29
29
  "id": "tabler-svg-sprite",
30
30
  "paths": [
31
- "assets/icons.svg"
31
+ "assets/icons.svg",
32
+ "icon-sprite.generated.ts"
32
33
  ],
33
34
  "assetType": "SVG sprite",
34
35
  "classification": "mixed third-party and Taproot-owned",
@@ -38,9 +39,10 @@
38
39
  "transformations": [
39
40
  "Converted selected SVG icons into <symbol> entries",
40
41
  "Normalized currentColor usage and sprite ids",
41
- "Added Taproot-owned taproot-logo symbol"
42
+ "Added Taproot-owned taproot-logo symbol",
43
+ "Generated importable module (icon-sprite.generated.ts) from the sprite via scripts/build-icon-module.js for the offline story (ESP0176)"
42
44
  ],
43
- "packageInclusion": "not included in npm package",
45
+ "packageInclusion": "included in npm package as dist/icons/icon-sprite.generated.js (the importable inline sprite); the .svg asset itself is not packaged",
44
46
  "docsInclusion": "copied to public docs assets by Eleventy and referenced by examples",
45
47
  "noticeRequirement": "required",
46
48
  "noticePaths": [
@@ -293,7 +295,7 @@
293
295
  "None; used as-is as a repeating docs-site canvas gutter background at 50% image-layer opacity"
294
296
  ],
295
297
  "packageInclusion": "not included in npm package",
296
- "docsInclusion": "docs-site only referenced as --esp-page-canvas-background-image in css/docs.css (which the public @taprootio/espalier package excludes) and served from the Eleventy /assets passthrough",
298
+ "docsInclusion": "docs-site only \u2014 referenced as --esp-page-canvas-background-image in css/docs.css (which the public @taprootio/espalier package excludes) and served from the Eleventy /assets passthrough",
297
299
  "noticeRequirement": "none",
298
300
  "noticePaths": [],
299
301
  "reviewStatus": "documented"
@@ -312,7 +314,7 @@
312
314
  "None; used as-is as a repeating docs-site dark-mode canvas gutter background at 50% image-layer opacity"
313
315
  ],
314
316
  "packageInclusion": "not included in npm package",
315
- "docsInclusion": "docs-site only referenced as --esp-page-canvas-background-image under esp-root[scheme=\"dark\"] in css/docs.css (excluded from the public @taprootio/espalier package) and served from the Eleventy /assets passthrough",
317
+ "docsInclusion": "docs-site only \u2014 referenced as --esp-page-canvas-background-image under esp-root[scheme=\"dark\"] in css/docs.css (excluded from the public @taprootio/espalier package) and served from the Eleventy /assets passthrough",
316
318
  "noticeRequirement": "none",
317
319
  "noticePaths": [],
318
320
  "reviewStatus": "documented"
@@ -366,7 +368,7 @@
366
368
  }
367
369
  ],
368
370
  "packageInclusion": "not included in npm package",
369
- "docsInclusion": "docs-site only linked from docs/_includes/layout.vto and docs/404.vto and served from the Eleventy /assets passthrough, so the documentation shell renders its theme faces without runtime fonts.googleapis.com links",
371
+ "docsInclusion": "docs-site only \u2014 linked from docs/_includes/layout.vto and docs/404.vto and served from the Eleventy /assets passthrough, so the documentation shell renders its theme faces without runtime fonts.googleapis.com links",
370
372
  "noticeRequirement": "required",
371
373
  "noticePaths": [
372
374
  "licenses/THIRD_PARTY_NOTICES.md"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taprootio/espalier",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "packageManager": "bun@1.3.12",
5
5
  "description": "Espalier — a themeable, accessible, framework-agnostic, enterprise-grade design system built on web standards and love.",
6
6
  "customElements": "custom-elements.json",
@@ -133,6 +133,10 @@
133
133
  "types": "./dist/grid/esp-grid.d.ts",
134
134
  "import": "./dist/grid/esp-grid.js"
135
135
  },
136
+ "./icons": {
137
+ "types": "./dist/icons/index.d.ts",
138
+ "import": "./dist/icons/index.js"
139
+ },
136
140
  "./header": {
137
141
  "types": "./dist/header/index.d.ts",
138
142
  "import": "./dist/header/index.js"