@taprootio/espalier 2.20.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/custom-elements.json +18086 -15042
- package/dist/badge/esp-badge.d.ts +7 -6
- package/dist/badge/esp-badge.js +6 -6
- package/dist/box/esp-box.d.ts +5 -5
- package/dist/button/esp-button.d.ts +6 -12
- package/dist/button/esp-button.js +3 -3
- package/dist/date-picker/esp-date-picker.js +2 -2
- package/dist/details/esp-details-group.d.ts +0 -13
- package/dist/details/esp-details.d.ts +9 -9
- package/dist/dialog/esp-dialog.d.ts +4 -4
- package/dist/empty-state/esp-empty-state.d.ts +1 -1
- package/dist/form/esp-form.d.ts +5 -5
- package/dist/grid/esp-grid.d.ts +8 -8
- package/dist/info/esp-info.d.ts +6 -4
- package/dist/info/esp-info.js +15 -15
- package/dist/input/esp-input.d.ts +5 -3
- package/dist/lightbox/esp-lightbox.js +1 -1
- package/dist/pickers/esp-picker-menu.d.ts +1 -0
- package/dist/pickers/esp-picker-menu.js +6 -6
- package/dist/progress/esp-progress.d.ts +24 -24
- package/dist/repeater/esp-repeater.d.ts +0 -3
- package/dist/root/helpers/compute-theme-properties.js +1 -1
- package/dist/root/helpers/lightness-ramp-properties.js +1 -0
- package/dist/shared/bus-events.d.ts +2 -2
- package/dist/shared/esp-element-base.d.ts +33 -15
- package/dist/shared/esp-element-base.js +2 -2
- package/dist/shared/style-fragments.js +39 -9
- package/dist/shared/theme.d.ts +4 -15
- package/dist/shared/theme.js +1 -1
- package/dist/shared/toast-events.d.ts +6 -5
- package/dist/status-indicator/esp-status-indicator.d.ts +13 -12
- package/dist/status-indicator/esp-status-indicator.js +7 -7
- package/dist/tabs/esp-tab-group.d.ts +8 -6
- package/dist/textarea/esp-textarea.d.ts +5 -4
- package/dist/toaster/esp-toaster.d.ts +9 -9
- package/dist/toaster/esp-toaster.js +3 -3
- package/dist/tree/esp-tree.js +2 -2
- package/package.json +1 -1
- package/dist/shared/esp-intent-element-base.d.ts +0 -10
- package/dist/shared/esp-intent-element-base.js +0 -31
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var a=function(p,t,e,i){var l=arguments.length,s=l<3?t:i===null?i=Object.getOwnPropertyDescriptor(t,e):i,r;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(p,t,e,i);else for(var n=p.length-1;n>=0;n--)(r=p[n])&&(s=(l<3?r(s):l>3?r(t,e,s):r(t,e))||s);return l>3&&s&&Object.defineProperty(t,e,s),s};import{LitElement as y,css as I,html as d}from"lit";import{customElement as b,property as u,state as f}from"lit/decorators.js";import{createRef as x,ref as P}from"lit/directives/ref.js";import{styleMap as w}from"lit/directives/style-map.js";import"../shared/virtualizer/lit-virtualizer.js";import{spaceAroundRect as v,viewportSize as g}from"../shared/viewport.js";const c="highlighted";let o=class extends y{constructor(){super(),this.internals=this.attachInternals(),this.virtualizerRef=x(),this.internalPoolClone=null,this.lastPoolFingerprint=null,this.preRenderScrollTop=null,this.openSessionGeneration=0,this.maxAvailableHeight=0,this.lastViewportHeight=0,this.label="",this.virtualizedItemsPool=[],this.highlightIndex=-1,this.multiSelect=!1,this.loading=!1,this.emptyMessage="",this.handleItemPointerDown=t=>{this.selectItemFromPointerEvent(t)},this.menuDirty=!1,this.settlerActive=!1,this.pendingItemsChanged=!1,this.retargetingSequence=!1,this.renderPickerItem=(t,e)=>{const i={display:"block",cursor:"pointer",width:"100%",...t.styles};return d`<esp-picker-item
|
|
2
2
|
class="picker-item"
|
|
3
3
|
data-picker-index=${e}
|
|
4
4
|
.text=${t.text}
|
|
@@ -6,17 +6,17 @@ var n=function(d,t,e,i){var l=arguments.length,s=l<3?t:i===null?i=Object.getOwnP
|
|
|
6
6
|
.selected=${t.selected}
|
|
7
7
|
.icon=${t.icon??""}
|
|
8
8
|
.highlightRanges=${t.highlightRanges}
|
|
9
|
-
style=${
|
|
9
|
+
style=${w(i)}
|
|
10
10
|
>
|
|
11
11
|
${t.slotNodes?.map(l=>l.cloneNode(!0))}
|
|
12
|
-
</esp-picker-item>`},this.internals.role="listbox"}connectedCallback(){super.connectedCallback(),this.setAttribute("popover","manual"),this.hasAttribute("role")||this.setAttribute("role","listbox")}updated(t){super.updated(t),t.has("multiSelect")&&(this.internals.ariaMultiSelectable=String(this.multiSelect),this.setAttribute("aria-multiselectable",String(this.multiSelect))),t.has("label")&&(this.internals.ariaLabel=this.label,this.label?this.setAttribute("aria-label",this.label):this.removeAttribute("aria-label")),(t.has("virtualizedItemsPool")||t.has("loading"))&&this.maxAvailableHeight>0&&this.matches(":popover-open")&&this.resizeAndHighlight(t.has("virtualizedItemsPool"))}get pickerItems(){return this.virtualizedItemsPool}set pickerItems(t){const e=this.virtualizedItemsPool.filter(s=>s.selected).map(s=>s.value);this.virtualizedItemsPool=t;const i=t.filter(s=>s.selected),l=i.map(s=>s.value);(e.length!==l.length||e.some((s,r)=>s!==l[r]))&&this.dispatchEvent(new CustomEvent("selection-changed",{detail:i,bubbles:!0,composed:!0}))}setHighlight(t){const e=this.virtualizedItemsPool;if(e.length===0)return;(this.highlightIndex<0||this.highlightIndex>e.length-1)&&(this.highlightIndex=t);const i=this.virtualizerRef.value;i&&i.scrollToIndex(this.highlightIndex,"nearest"),this.applyHighlightClass()}async setHighlightAsync(t){const e=this.virtualizedItemsPool;if(e.length===0)return;(this.highlightIndex<0||this.highlightIndex>e.length-1)&&(this.highlightIndex=t);const i=this.virtualizerRef.value;if(i)try{const l=i.layoutComplete;l&&await l,i.scrollToIndex(this.highlightIndex,"nearest");const s=i.layoutComplete;s&&await s}catch{return}this.applyHighlightClass()}applyHighlightClass(){this.clearHighlight();const t=this.getHighlightedElement();t&&t.classList.add(c)}clearHighlight(){const t=this.virtualizerRef.value;if(t)for(const e of t.querySelectorAll(`esp-picker-item.${c}`))e.classList.remove(c)}resetHighlight(){this.clearHighlight();const t=this.virtualizedItemsPool.find(e=>e.selected);this.highlightIndex=t?this.virtualizedItemsPool.indexOf(t):-1}applyHighlightWithRetry(t){if(!this.isConnected||!this.matches(":popover-open"))return;this.clearHighlight();const e=this.getHighlightedElement();if(e){e.classList.add(c);return}t>0&&requestAnimationFrame(()=>this.applyHighlightWithRetry(t-1))}getHighlightedElement(){if(this.highlightIndex<0)return null;const t=this.virtualizerRef.value;if(!t)return null;const e=t.querySelectorAll("esp-picker-item");for(const i of e)if(this.virtualizedItemsPool.findIndex(s=>s.value===i.value&&s.text===i.text)===this.highlightIndex)return i;return null}pickItem(t){for(const i of this.pickerItems)i===t?i.selected=!i.selected:this.multiSelect||(i.selected=!1);const e=this.virtualizedItemsPool.indexOf(t);if(e!==-1){this.highlightIndex=e,this.clearHighlight();const i=this.getHighlightedElement();i&&i.classList.add(c)}this.pickerItems=[...this.pickerItems],this.dispatchEvent(new CustomEvent("selection-changed",{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0})),this.multiSelect||this.dispatchEvent(new CustomEvent("close-menu",{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0}))}selectItemByIndex(t){const e=Number.isInteger(t)?this.virtualizedItemsPool[t]:void 0;return e?(this.pickItem(e),!0):!1}getPickerItemElementAtPoint(t,e){const i=this.shadowRoot?.querySelectorAll("esp-picker-item[data-picker-index]");if(!i)return null;for(const l of i){const s=l.getBoundingClientRect();if(t>=s.left&&t<=s.right&&e>=s.top&&e<=s.bottom)return l}return null}selectPickerItemElement(t){return t?this.selectItemByIndex(Number(t.dataset.pickerIndex)):!1}selectItemAtPoint(t,e){return this.selectPickerItemElement(this.getPickerItemElementAtPoint(t,e))}selectItemFromPointerEvent(t){const e=t.composedPath().find(l=>l instanceof HTMLElement&&l.matches("esp-picker-item[data-picker-index]"));return this.selectPickerItemElement(e??this.getPickerItemElementAtPoint(t.clientX,t.clientY))?(t.preventDefault(),t.stopPropagation(),!0):!1}positionSelf(t){const e=t.getBoundingClientRect(),{height:i}=u(),{spaceAbove:l,spaceBelow:s}=f(e,i),r=Math.max(Math.max(l,s)-75,0);this.maxAvailableHeight=r,this.lastViewportHeight=i,this.style.setProperty("height",`${r}px`),this.style.setProperty("min-width",`${e.width}px`),this.style.setProperty("left",`${e.left}px`),this.style.removeProperty("top"),this.style.removeProperty("bottom"),l>s?this.style.setProperty("bottom",`${i-e.top}px`):this.style.setProperty("top",`${e.bottom}px`),this.classList.remove("visible"),this.matches(":popover-open")||this.showPopover();const o=this.pickerItems.find(a=>a.selected);this.highlightIndex=o?this.pickerItems.indexOf(o):0,this.setHighlightAsync(0).then(()=>{requestAnimationFrame(()=>{this.shrinkToFit(r),this.widenToFitContent(e),this.classList.add("visible")})})}async resizeAndHighlight(t){try{await this.updateComplete}catch{return}if(!this.isConnected||!this.matches(":popover-open"))return;const e=this.virtualizerRef.value;if(!e){requestAnimationFrame(()=>{if(!this.isConnected)return;const s=this.shadowRoot?.querySelector(".status-message");if(s){const r=Math.min(s.scrollHeight,this.maxAvailableHeight);this.style.setProperty("height",`${r}px`)}});return}try{const s=e.layoutComplete;s&&await s}catch{return}if(!this.isConnected||!this.matches(":popover-open")||(e.scrollTop=0,this.sizeToContent(this.maxAvailableHeight),!t))return;try{const s=e.layoutComplete;s&&await s}catch{return}if(!this.isConnected||!this.matches(":popover-open"))return;const i=this.virtualizedItemsPool;if(i.length===0)return;const l=i.findIndex(s=>s.selected);l>=0?this.highlightIndex=l:this.highlightIndex>=i.length?this.highlightIndex=i.length-1:this.highlightIndex<0&&(this.highlightIndex=0);try{e.scrollToIndex(this.highlightIndex,"nearest")}catch{}try{const s=e.layoutComplete;s&&await s}catch{return}!this.isConnected||!this.matches(":popover-open")||this.applyHighlightWithRetry(3)}sizeToContent(t){const e=this.measureContentHeight();e>0&&this.style.setProperty("height",`${Math.min(e,t)}px`)}shrinkToFit(t){const e=this.measureContentHeight();e>2&&e<t&&this.style.setProperty("height",`${e}px`)}measureContentHeight(){const t=this.virtualizerRef.value;if(!t)return 0;const e=t.querySelectorAll("esp-picker-item");if(e.length===0)return 0;const i=getComputedStyle(this),l=(parseFloat(i.borderTopWidth)||0)+(parseFloat(i.borderBottomWidth)||0),s=this.virtualizedItemsPool.length;if(e.length<s)return t.scrollHeight+l;t.scrollTop=0;const r=t.getBoundingClientRect();return e[e.length-1].getBoundingClientRect().bottom-r.top+l}widenToFitContent(t){const e=this.virtualizerRef.value;if(!e)return;const i=e.querySelectorAll("esp-picker-item");let l=t.width;for(const s of i)l=Math.max(l,s.scrollWidth);if(l+=2,l>t.width){const{width:s}=u(),r=Math.min(l,s-t.left);this.style.setProperty("width",`${r}px`)}}updatePosition(t){const e=t.getBoundingClientRect(),{height:i}=u();if(i!==this.lastViewportHeight){const{spaceAbove:r,spaceBelow:o}=f(e,i),a=Math.max(Math.max(r,o)-75,0);this.maxAvailableHeight=a,this.lastViewportHeight=i,(parseFloat(this.style.getPropertyValue("height"))||0)>a&&this.style.setProperty("height",`${a}px`),this.sizeToContent(a)}this.style.setProperty("left",`${e.left}px`);const l=e.top,s=i-e.bottom;l>s?(this.style.removeProperty("top"),this.style.setProperty("bottom",`${i-e.top}px`)):(this.style.removeProperty("bottom"),this.style.setProperty("top",`${e.bottom}px`))}hideMenu(){this.classList.remove("visible");try{this.hidePopover()}catch{}}doKeyboardNav(t){const e=this.virtualizedItemsPool;if(e.length!==0)switch(t){case"ArrowDown":this.highlightIndex+=1,this.setHighlight(0);break;case"ArrowUp":this.highlightIndex-=1,this.setHighlight(e.length-1);break;case"Home":this.highlightIndex=0,this.setHighlight(0);break;case"End":this.highlightIndex=e.length-1,this.setHighlight(e.length-1);break;case"Enter":if(this.highlightIndex===-1)return;this.pickItem(e[this.highlightIndex]);break}}render(){return this.loading?p`<div class="status-message">Searching…</div>`:this.virtualizedItemsPool.length===0&&this.emptyMessage?p`<div class="status-message">${this.emptyMessage}</div>`:p`<lit-virtualizer
|
|
13
|
-
${
|
|
12
|
+
</esp-picker-item>`},this.internals.role="listbox"}connectedCallback(){super.connectedCallback(),this.setAttribute("popover","manual"),this.hasAttribute("role")||this.setAttribute("role","listbox")}willUpdate(t){if(super.willUpdate(t),t.has("virtualizedItemsPool")&&this.preRenderScrollTop===null&&!this.retargetingSequence&&this.matches(":popover-open")){const e=this.virtualizerRef.value?.scrollTop??0;e>0&&(this.preRenderScrollTop=e)}}updated(t){super.updated(t),t.has("multiSelect")&&(this.internals.ariaMultiSelectable=String(this.multiSelect),this.setAttribute("aria-multiselectable",String(this.multiSelect))),t.has("label")&&(this.internals.ariaLabel=this.label,this.label?this.setAttribute("aria-label",this.label):this.removeAttribute("aria-label"));const e=t.has("virtualizedItemsPool");let i=!1;if(e){const l=this.virtualizedItemsPool===this.internalPoolClone;this.internalPoolClone=null;const s=this.virtualizedItemsPool.map(r=>`${r.value}\0${r.text}\0${r.selected===!0}`);i=!l&&(this.lastPoolFingerprint===null||this.lastPoolFingerprint.length!==s.length||this.lastPoolFingerprint.some((r,n)=>r!==s[n])),this.lastPoolFingerprint=s}(e||t.has("loading"))&&this.maxAvailableHeight>0&&this.matches(":popover-open")&&(this.pendingItemsChanged||=i,this.menuDirty=!0,this.settleMenuAfterUpdate())}get pickerItems(){return this.virtualizedItemsPool}set pickerItems(t){const e=this.virtualizedItemsPool.filter(s=>s.selected).map(s=>s.value);this.virtualizedItemsPool=t;const i=t.filter(s=>s.selected),l=i.map(s=>s.value);(e.length!==l.length||e.some((s,r)=>s!==l[r]))&&this.dispatchEvent(new CustomEvent("selection-changed",{detail:i,bubbles:!0,composed:!0}))}setHighlight(t){const e=this.virtualizedItemsPool;if(e.length===0)return;(this.highlightIndex<0||this.highlightIndex>e.length-1)&&(this.highlightIndex=t);const i=this.virtualizerRef.value;i&&i.scrollToIndex(this.highlightIndex,"nearest"),this.applyHighlightClass()}async setHighlightAsync(t){const e=this.openSessionGeneration,i=()=>e!==this.openSessionGeneration||!this.isConnected,l=this.virtualizedItemsPool;if(l.length===0)return;(this.highlightIndex<0||this.highlightIndex>l.length-1)&&(this.highlightIndex=t);const s=this.virtualizerRef.value;if(s){if(await this.stableLayout(s),i())return;const r=s.scrollTop;for(let n=0;n<3;n+=1)try{s.scrollToIndex(this.highlightIndex,"nearest");break}catch{if(await this.stableLayout(s),i()||s.scrollTop!==r)return}if(await this.stableLayout(s),i())return}this.applyHighlightWithRetry(3)}applyHighlightClass(){const t=this.getHighlightedElement();t&&(this.clearHighlight(),t.classList.add(c))}clearHighlight(){const t=this.virtualizerRef.value;if(t)for(const e of t.querySelectorAll(`esp-picker-item.${c}`))e.classList.remove(c)}resetHighlight(){this.clearHighlight();const t=this.virtualizedItemsPool.find(e=>e.selected);this.highlightIndex=t?this.virtualizedItemsPool.indexOf(t):-1}applyHighlightWithRetry(t){if(!this.isConnected||!this.matches(":popover-open"))return;const e=this.getHighlightedElement();if(e){this.clearHighlight(),e.classList.add(c);return}t>0&&requestAnimationFrame(()=>this.applyHighlightWithRetry(t-1))}getHighlightedElement(){if(this.highlightIndex<0)return null;const t=this.virtualizerRef.value;if(!t)return null;const e=t.querySelectorAll("esp-picker-item");for(const i of e)if(this.virtualizedItemsPool.findIndex(s=>s.value===i.value&&s.text===i.text)===this.highlightIndex)return i;return null}pickItem(t){for(const l of this.pickerItems)l===t?l.selected=!l.selected:this.multiSelect||(l.selected=!1);const e=this.virtualizedItemsPool.indexOf(t);if(e!==-1){this.highlightIndex=e;const l=this.getHighlightedElement();l&&(this.clearHighlight(),l.classList.add(c))}const i=[...this.pickerItems];this.internalPoolClone=i,this.pickerItems=i,this.dispatchEvent(new CustomEvent("selection-changed",{detail:this.pickerItems.filter(l=>l.selected),bubbles:!0,composed:!0})),this.multiSelect||this.dispatchEvent(new CustomEvent("close-menu",{detail:this.pickerItems.filter(l=>l.selected),bubbles:!0,composed:!0}))}selectItemByIndex(t){const e=Number.isInteger(t)?this.virtualizedItemsPool[t]:void 0;return e?(this.pickItem(e),!0):!1}getPickerItemElementAtPoint(t,e){const i=this.shadowRoot?.querySelectorAll("esp-picker-item[data-picker-index]");if(!i)return null;for(const l of i){const s=l.getBoundingClientRect();if(t>=s.left&&t<=s.right&&e>=s.top&&e<=s.bottom)return l}return null}selectPickerItemElement(t){return t?this.selectItemByIndex(Number(t.dataset.pickerIndex)):!1}selectItemAtPoint(t,e){return this.selectPickerItemElement(this.getPickerItemElementAtPoint(t,e))}selectItemFromPointerEvent(t){const e=t.composedPath().find(l=>l instanceof HTMLElement&&l.matches("esp-picker-item[data-picker-index]"));return this.selectPickerItemElement(e??this.getPickerItemElementAtPoint(t.clientX,t.clientY))?(t.preventDefault(),t.stopPropagation(),!0):!1}positionSelf(t){const e=t.getBoundingClientRect(),{height:i}=g(),{spaceAbove:l,spaceBelow:s}=v(e,i),r=Math.max(Math.max(l,s)-75,0);this.maxAvailableHeight=r,this.lastViewportHeight=i,this.style.setProperty("height",`${r}px`),this.style.setProperty("min-width",`${e.width}px`),this.style.setProperty("left",`${e.left}px`),this.style.removeProperty("top"),this.style.removeProperty("bottom"),l>s?this.style.setProperty("bottom",`${i-e.top}px`):this.style.setProperty("top",`${e.bottom}px`),this.classList.remove("visible"),this.matches(":popover-open")||this.showPopover();const n=this.pickerItems.find(m=>m.selected);this.highlightIndex=n?this.pickerItems.indexOf(n):0,this.openSessionGeneration+=1;const h=this.openSessionGeneration;this.setHighlightAsync(0).then(()=>{requestAnimationFrame(()=>{h!==this.openSessionGeneration||!this.isConnected||(this.shrinkToFit(r),this.widenToFitContent(e),this.classList.add("visible"))})})}async stableLayout(t){for(let e=0;e<20;e+=1){const i=t.layoutComplete;if(!i)return;const l=await Promise.race([i.then(()=>"settled",()=>"superseded"),new Promise(s=>setTimeout(()=>s("deadline"),250))]);if(l==="settled"||l==="deadline"||t.layoutComplete===i)return}}async settleMenuAfterUpdate(){if(this.settlerActive)return;this.settlerActive=!0;const t=()=>!this.isConnected||!this.matches(":popover-open")?(this.menuDirty=!1,this.preRenderScrollTop=null,this.pendingItemsChanged=!1,this.retargetingSequence=!1,!0):!1;try{for(let e=0;e<10&&this.menuDirty;e+=1){this.menuDirty=!1;try{await this.updateComplete}catch{this.menuDirty=!1;return}if(t())return;const i=this.virtualizerRef.value;if(!i){requestAnimationFrame(()=>{if(!this.isConnected)return;const r=this.shadowRoot?.querySelector(".status-message");if(r){const n=Math.min(r.scrollHeight,this.maxAvailableHeight);this.style.setProperty("height",`${n}px`)}});continue}if(await this.stableLayout(i),t())return;if(this.menuDirty)continue;const l=this.preRenderScrollTop??0;if(i.scrollTop=0,this.sizeToContent(this.maxAvailableHeight),l>0&&!this.pendingItemsChanged&&!this.retargetingSequence&&i.scrollTop<l){if(i.scrollTop=l,await this.stableLayout(i),t())return;if(this.menuDirty)continue}const s=this.virtualizedItemsPool;if(s.length!==0){if(this.pendingItemsChanged){this.pendingItemsChanged=!1,this.retargetingSequence=!0,this.preRenderScrollTop=null;const r=s.findIndex(n=>n.selected);r>=0?this.highlightIndex=r:this.highlightIndex>=s.length?this.highlightIndex=s.length-1:this.highlightIndex<0&&(this.highlightIndex=0)}if(this.retargetingSequence){try{i.scrollToIndex(this.highlightIndex,"nearest")}catch{}if(await this.stableLayout(i),t())return;if(this.menuDirty)continue}this.applyHighlightWithRetry(3),this.preRenderScrollTop=null,this.retargetingSequence=!1}}}finally{this.settlerActive=!1,this.menuDirty&&this.settleMenuAfterUpdate()}}sizeToContent(t){const e=this.measureContentHeight();e>0&&this.style.setProperty("height",`${Math.min(e,t)}px`)}shrinkToFit(t){const e=this.measureContentHeight();e>2&&e<t&&this.style.setProperty("height",`${e}px`)}measureContentHeight(){const t=this.virtualizerRef.value;if(!t)return 0;const e=t.querySelectorAll("esp-picker-item");if(e.length===0)return 0;const i=getComputedStyle(this),l=(parseFloat(i.borderTopWidth)||0)+(parseFloat(i.borderBottomWidth)||0),s=this.virtualizedItemsPool.length;if(e.length<s)return t.scrollHeight+l;const r=t.scrollTop;t.scrollTop=0;const n=t.getBoundingClientRect(),h=e[e.length-1].getBoundingClientRect();return r>0&&(t.scrollTop=r),h.bottom-n.top+l}widenToFitContent(t){const e=this.virtualizerRef.value;if(!e)return;const i=e.querySelectorAll("esp-picker-item");let l=t.width;for(const s of i)l=Math.max(l,s.scrollWidth);if(l+=2,l>t.width){const{width:s}=g(),r=Math.min(l,s-t.left);this.style.setProperty("width",`${r}px`)}}updatePosition(t){const e=t.getBoundingClientRect(),{height:i}=g();if(i!==this.lastViewportHeight){const{spaceAbove:r,spaceBelow:n}=v(e,i),h=Math.max(Math.max(r,n)-75,0);this.maxAvailableHeight=h,this.lastViewportHeight=i,(parseFloat(this.style.getPropertyValue("height"))||0)>h&&this.style.setProperty("height",`${h}px`),this.sizeToContent(h)}this.style.setProperty("left",`${e.left}px`);const l=e.top,s=i-e.bottom;l>s?(this.style.removeProperty("top"),this.style.setProperty("bottom",`${i-e.top}px`)):(this.style.removeProperty("bottom"),this.style.setProperty("top",`${e.bottom}px`))}hideMenu(){this.openSessionGeneration+=1,this.classList.remove("visible"),this.preRenderScrollTop=null,this.pendingItemsChanged=!1,this.retargetingSequence=!1,this.menuDirty=!1;try{this.hidePopover()}catch{}}doKeyboardNav(t){const e=this.virtualizedItemsPool;if(e.length!==0)switch(t){case"ArrowDown":this.highlightIndex+=1,this.setHighlight(0);break;case"ArrowUp":this.highlightIndex-=1,this.setHighlight(e.length-1);break;case"Home":this.highlightIndex=0,this.setHighlight(0);break;case"End":this.highlightIndex=e.length-1,this.setHighlight(e.length-1);break;case"Enter":if(this.highlightIndex===-1)return;this.pickItem(e[this.highlightIndex]);break}}render(){return this.loading?d`<div class="status-message">Searching…</div>`:this.virtualizedItemsPool.length===0&&this.emptyMessage?d`<div class="status-message">${this.emptyMessage}</div>`:d`<lit-virtualizer
|
|
13
|
+
${P(this.virtualizerRef)}
|
|
14
14
|
scroller
|
|
15
15
|
.items=${this.virtualizedItemsPool}
|
|
16
16
|
.renderItem=${this.renderPickerItem}
|
|
17
17
|
@pointerdown=${this.handleItemPointerDown}
|
|
18
18
|
@rangeChanged=${t=>{this.dispatchEvent(new CustomEvent("range-changed",{detail:{first:t.first,last:t.last,items:this.virtualizedItemsPool},bubbles:!0,composed:!0}))}}
|
|
19
|
-
></lit-virtualizer>`}};
|
|
19
|
+
></lit-virtualizer>`}};o.styles=I`
|
|
20
20
|
:host {
|
|
21
21
|
position: fixed;
|
|
22
22
|
inset: unset;
|
|
@@ -54,4 +54,4 @@ var n=function(d,t,e,i){var l=arguments.length,s=l<3?t:i===null?i=Object.getOwnP
|
|
|
54
54
|
font-style: italic;
|
|
55
55
|
background: var(--esp-color-layer-2);
|
|
56
56
|
}
|
|
57
|
-
`,
|
|
57
|
+
`,a([u({type:String})],o.prototype,"label",void 0),a([f()],o.prototype,"virtualizedItemsPool",void 0),a([f()],o.prototype,"highlightIndex",void 0),a([u({attribute:"multi-select",type:Boolean})],o.prototype,"multiSelect",void 0),a([u({type:Boolean})],o.prototype,"loading",void 0),a([u({type:String,attribute:"empty-message"})],o.prototype,"emptyMessage",void 0),o=a([b("esp-picker-menu")],o);export{o as EspalierPickerMenu};
|
|
@@ -28,14 +28,14 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
28
28
|
* </div>
|
|
29
29
|
* ```
|
|
30
30
|
*
|
|
31
|
-
*
|
|
31
|
+
* Intent colors match the design system:
|
|
32
32
|
*
|
|
33
33
|
* ```html
|
|
34
34
|
* <div style="display: grid; gap: var(--esp-size-padding);">
|
|
35
|
-
* <esp-progress value="80" label="Primary"
|
|
36
|
-
* <esp-progress value="60" label="Success"
|
|
37
|
-
* <esp-progress value="40" label="Warning"
|
|
38
|
-
* <esp-progress value="20" label="Danger"
|
|
35
|
+
* <esp-progress value="80" label="Primary" show-value></esp-progress>
|
|
36
|
+
* <esp-progress value="60" label="Success" intent="success" show-value></esp-progress>
|
|
37
|
+
* <esp-progress value="40" label="Warning" intent="warning" show-value></esp-progress>
|
|
38
|
+
* <esp-progress value="20" label="Danger" intent="danger" show-value></esp-progress>
|
|
39
39
|
* </div>
|
|
40
40
|
* ```
|
|
41
41
|
*
|
|
@@ -43,10 +43,10 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
43
43
|
*
|
|
44
44
|
* ```html
|
|
45
45
|
* <esp-box>
|
|
46
|
-
* <esp-progress id="demo-progress" value="0" label="Demo progress"
|
|
46
|
+
* <esp-progress id="demo-progress" value="0" label="Demo progress" intent="success" size="large" show-value></esp-progress>
|
|
47
47
|
* <div style="display: flex; gap: var(--esp-size-small); margin-top: var(--esp-size-small);">
|
|
48
|
-
* <esp-button id="start-btn" label="Start"
|
|
49
|
-
* <esp-button id="reset-btn" label="Reset"
|
|
48
|
+
* <esp-button id="start-btn" label="Start" collapsed></esp-button>
|
|
49
|
+
* <esp-button id="reset-btn" label="Reset" collapsed></esp-button>
|
|
50
50
|
* </div>
|
|
51
51
|
* </esp-box>
|
|
52
52
|
* <script>
|
|
@@ -67,7 +67,7 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
67
67
|
* requestAnimationFrame(step);
|
|
68
68
|
* } else {
|
|
69
69
|
* running = false;
|
|
70
|
-
* showToast({ message: "Complete!",
|
|
70
|
+
* showToast({ message: "Complete!", intent: "success", icon: "bread" });
|
|
71
71
|
* }
|
|
72
72
|
* }
|
|
73
73
|
* requestAnimationFrame(step);
|
|
@@ -79,14 +79,14 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
79
79
|
* </script>
|
|
80
80
|
* ```
|
|
81
81
|
*
|
|
82
|
-
* Indeterminate mode with different
|
|
82
|
+
* Indeterminate mode with different intents:
|
|
83
83
|
*
|
|
84
84
|
* ```html
|
|
85
85
|
* <div style="display: grid; gap: var(--esp-size-small);">
|
|
86
|
-
* <esp-progress label="Primary loading"
|
|
87
|
-
* <esp-progress label="Success loading"
|
|
88
|
-
* <esp-progress label="Warning loading"
|
|
89
|
-
* <esp-progress label="Danger loading"
|
|
86
|
+
* <esp-progress label="Primary loading"></esp-progress>
|
|
87
|
+
* <esp-progress label="Success loading" intent="success"></esp-progress>
|
|
88
|
+
* <esp-progress label="Warning loading" intent="warning"></esp-progress>
|
|
89
|
+
* <esp-progress label="Danger loading" intent="danger"></esp-progress>
|
|
90
90
|
* </div>
|
|
91
91
|
* ```
|
|
92
92
|
*
|
|
@@ -96,10 +96,10 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
96
96
|
*
|
|
97
97
|
* ```html
|
|
98
98
|
* <div style="display: flex; gap: var(--esp-size-padding); align-items: center; flex-wrap: wrap;">
|
|
99
|
-
* <esp-progress mode="circle" value="80" label="Primary"
|
|
100
|
-
* <esp-progress mode="circle" value="60" label="Success"
|
|
101
|
-
* <esp-progress mode="circle" value="40" label="Warning"
|
|
102
|
-
* <esp-progress mode="circle" value="20" label="Danger"
|
|
99
|
+
* <esp-progress mode="circle" value="80" label="Primary" show-value></esp-progress>
|
|
100
|
+
* <esp-progress mode="circle" value="60" label="Success" intent="success" show-value></esp-progress>
|
|
101
|
+
* <esp-progress mode="circle" value="40" label="Warning" intent="warning" show-value></esp-progress>
|
|
102
|
+
* <esp-progress mode="circle" value="20" label="Danger" intent="danger" show-value></esp-progress>
|
|
103
103
|
* </div>
|
|
104
104
|
* ```
|
|
105
105
|
*
|
|
@@ -117,8 +117,8 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
117
117
|
*
|
|
118
118
|
* ```html
|
|
119
119
|
* <div style="display: flex; gap: var(--esp-size-padding); align-items: center;">
|
|
120
|
-
* <esp-progress mode="circle" label="Primary loading"
|
|
121
|
-
* <esp-progress mode="circle" label="Success loading"
|
|
120
|
+
* <esp-progress mode="circle" label="Primary loading"></esp-progress>
|
|
121
|
+
* <esp-progress mode="circle" label="Success loading" intent="success"></esp-progress>
|
|
122
122
|
* </div>
|
|
123
123
|
* ```
|
|
124
124
|
*
|
|
@@ -127,10 +127,10 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
127
127
|
* ```html
|
|
128
128
|
* <esp-box>
|
|
129
129
|
* <div style="display: flex; align-items: center; gap: var(--esp-size-padding);">
|
|
130
|
-
* <esp-progress id="demo-circle" mode="circle" value="0" label="Circle demo"
|
|
130
|
+
* <esp-progress id="demo-circle" mode="circle" value="0" label="Circle demo" intent="success" size="large" show-value></esp-progress>
|
|
131
131
|
* <div style="display: flex; gap: var(--esp-size-small);">
|
|
132
|
-
* <esp-button id="start-circle-btn" label="Start"
|
|
133
|
-
* <esp-button id="reset-circle-btn" label="Reset"
|
|
132
|
+
* <esp-button id="start-circle-btn" label="Start" collapsed></esp-button>
|
|
133
|
+
* <esp-button id="reset-circle-btn" label="Reset" collapsed></esp-button>
|
|
134
134
|
* </div>
|
|
135
135
|
* </div>
|
|
136
136
|
* </esp-box>
|
|
@@ -152,7 +152,7 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
152
152
|
* requestAnimationFrame(step);
|
|
153
153
|
* } else {
|
|
154
154
|
* circleRunning = false;
|
|
155
|
-
* showToast({ message: "Complete!",
|
|
155
|
+
* showToast({ message: "Complete!", intent: "success", icon: "bread" });
|
|
156
156
|
* }
|
|
157
157
|
* }
|
|
158
158
|
* requestAnimationFrame(step);
|
|
@@ -88,7 +88,6 @@ export type RepeaterRenderItem<T = unknown> = (item: T, index: number) => Repeat
|
|
|
88
88
|
*
|
|
89
89
|
* repeater.renderItem = (image) => {
|
|
90
90
|
* const card = document.createElement("esp-box");
|
|
91
|
-
* card.variant = "analogous-right";
|
|
92
91
|
* card.innerHTML = `
|
|
93
92
|
* <div style="display:grid; gap:var(--esp-size-small); grid-template-columns:7rem 1fr; align-items:start;">
|
|
94
93
|
* <img src="${image.thumbnail}" alt="" style="width:7rem; aspect-ratio:4 / 3; object-fit:cover; border-radius:var(--esp-size-border-radius);" />
|
|
@@ -185,7 +184,6 @@ export type RepeaterRenderItem<T = unknown> = (item: T, index: number) => Repeat
|
|
|
185
184
|
*
|
|
186
185
|
* repeater.renderItem = (image) => {
|
|
187
186
|
* const card = document.createElement("esp-box");
|
|
188
|
-
* card.variant = "analogous-right";
|
|
189
187
|
* card.innerHTML = `
|
|
190
188
|
* <article style="display:grid; gap:var(--esp-size-small);">
|
|
191
189
|
* <img src="${image.thumbnail}" alt="" style="width:100%; aspect-ratio:16 / 10; object-fit:cover; border-radius:var(--esp-size-border-radius);" />
|
|
@@ -256,7 +254,6 @@ export type RepeaterRenderItem<T = unknown> = (item: T, index: number) => Repeat
|
|
|
256
254
|
*
|
|
257
255
|
* repeater.renderItem = (image) => {
|
|
258
256
|
* const card = document.createElement("esp-box");
|
|
259
|
-
* card.variant = "analogous-right";
|
|
260
257
|
* card.innerHTML = `
|
|
261
258
|
* <article style="display:grid; gap:var(--esp-size-small);">
|
|
262
259
|
* <img src="${image.thumbnail}" alt="" style="width:100%; aspect-ratio:3 / 2; object-fit:cover; border-radius:var(--esp-size-border-radius);" />
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseCssColor as g,serializeOklch as l,gamutMapToSRGB as f}from"../../shared/color-engine.js";import{generateScaleProperties as k}from"../../shared/scale-engine.js";import{DATA_SERIES_KEYS as u,DEFAULT_DATA_PALETTE as v,generateDivergingRamp as B,generateSequentialRamp as R}from"../../shared/data-colors.js";import{
|
|
1
|
+
import{parseCssColor as g,serializeOklch as l,gamutMapToSRGB as f}from"../../shared/color-engine.js";import{generateScaleProperties as k}from"../../shared/scale-engine.js";import{DATA_SERIES_KEYS as u,DEFAULT_DATA_PALETTE as v,generateDivergingRamp as B,generateSequentialRamp as R}from"../../shared/data-colors.js";import{resolveDataColorSource as w}from"../../shared/theme.js";import{lightnessRampProperties as O}from"./lightness-ramp-properties.js";import{computeVariants as $}from"./compute-variants.js";import{computeSemanticProperties as E}from"./compute-semantic-properties.js";function I(o){return{rootFontSize:o.rootFontSize,typeRatio:o.typeRatio,spaceRatio:o.spaceRatio,borderRadius:o.borderRadius,viewportMin:o.viewportMin,viewportMax:o.viewportMax}}function j(o,b,m){const i=g(o.seedColor);if(!i)return{};const a={};a["--esp-scheme"]=b,a["--esp-seed-color"]=o.seedColor;const c=$(i,o);for(const[e,n]of Object.entries(c))a[`--esp-color-${e}`]=l(f(n));const p=new Set,t=(e,n)=>{const r=typeof e=="string"?w(e,o.anchors):null;if(r)return r;const s=typeof e=="string"?e:String(e);return p.has(s)||(p.add(s),console.warn(`Espalier theme: ${n} color source "${s}" cannot be resolved \u2014 falling back to the seed. Run validateTheme for the declared data colors.`)),o.seedColor},y=o.dataPalette??v;for(let e=0;e<u.length;e+=1){const n=u[e],r=g(t(y[n],`dataPalette.${n}`))??i;a[`--esp-color-series-${e+1}`]=l(f(r))}for(const[e,n]of Object.entries(o.dataRamps??{}))try{(n.type==="sequential"?R(t(n.source,`dataRamps.${e}.source`),{steps:n.steps,lightnessStart:n.lightnessStart,lightnessEnd:n.lightnessEnd}):B(t(n.start,`dataRamps.${e}.start`),t(n.end,`dataRamps.${e}.end`),{steps:n.steps,neutral:n.neutral===void 0?void 0:t(n.neutral,`dataRamps.${e}.neutral`)})).forEach((s,S)=>{a[`--esp-color-ramp-${e}-${S+1}`]=s})}catch(r){console.warn(`Espalier theme: dataRamps.${e} cannot be generated \u2014 ${r instanceof Error?r.message:String(r)}`)}Object.assign(a,O(o));const d=new Set;return Object.assign(a,E(o,c,{trace:m,onUnresolvedSource:e=>{d.has(e)||(d.add(e),console.warn(`Espalier theme: color source "${e}" cannot be resolved \u2014 falling back to the seed. Run validateTheme for the declared anchors.`))}})),Object.assign(a,k(I(o))),o.fontBody&&(a["--esp-font-body"]=o.fontBody),o.fontHeadings&&(a["--esp-font-headings"]=o.fontHeadings),o.fontBrand&&(a["--esp-font-brand"]=o.fontBrand),o.fontMonospace&&(a["--esp-font-monospace"]=o.fontMonospace),a["--esp-font-weight-body"]=o.fontWeightBody,a["--esp-font-weight-headings"]=o.fontWeightHeadings,a["--esp-font-weight-brand"]=o.fontWeightBrand,a["--esp-font-weight-monospace"]=o.fontWeightMonospace,o.pageBackgroundImage&&(a["--esp-page-background-image"]=o.pageBackgroundImage),o.pageBackgroundImageOpacity!==void 0&&(a["--esp-page-background-image-opacity"]=o.pageBackgroundImageOpacity.toString()),o.boxBackgroundImage&&(a["--esp-box-background-image"]=o.boxBackgroundImage),o.boxBackgroundImageOpacity!==void 0&&(a["--esp-box-background-image-opacity"]=o.boxBackgroundImageOpacity.toString()),o.vellumOpacity!==void 0&&(a["--esp-vellum-opacity"]=o.vellumOpacity.toString()),o.vellumBackgroundImage&&(a["--esp-vellum-background-image"]=o.vellumBackgroundImage),o.vellumBackgroundImageOpacity!==void 0&&(a["--esp-vellum-background-image-opacity"]=o.vellumBackgroundImageOpacity.toString()),a}export{j as computeThemeProperties};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LIGHTNESS_KEYS as s}from"../../shared/theme.js";import{lightnessKeyToCSS as e}from"./lightness-key-to-css.js";function p(t){const o={};for(const r of s)o[e(r)]=`${Math.round(t.lightness[r]*100)}%`;return o}export{p as lightnessRampProperties};
|
|
@@ -33,7 +33,7 @@ import type { HelpRequest, HelpState } from "./help-events.js";
|
|
|
33
33
|
/**
|
|
34
34
|
* Contract for elements that provide a seed color to their subtree.
|
|
35
35
|
* Implemented by `EspalierRoot` (the global provider) and
|
|
36
|
-
* `EspalierElementBase` (
|
|
36
|
+
* `EspalierElementBase` (scoped context and intent derivation).
|
|
37
37
|
*
|
|
38
38
|
* @docUrl /api/seed-color-root
|
|
39
39
|
* @menuGroup Bus Events
|
|
@@ -48,7 +48,7 @@ export interface SeedColorRoot {
|
|
|
48
48
|
*
|
|
49
49
|
* Published by `<esp-root>` after initial mount and subscribed to by every
|
|
50
50
|
* `EspalierElementBase` descendant so that scheme, seed, and full-theme changes
|
|
51
|
-
* propagate to
|
|
51
|
+
* propagate to scoped-token-aware descendants. All roots share one global bus, so
|
|
52
52
|
* consumers should use `EspalierRoot.subscribeScoped()` instead of subscribing
|
|
53
53
|
* to these events directly. Read initial values from the root; these events are
|
|
54
54
|
* change-only and are not replayed for late subscribers.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { LitElement, type PropertyValues } from "lit";
|
|
2
2
|
import { type SeedColorRoot } from "./bus-events.js";
|
|
3
|
-
import { type
|
|
4
|
-
export type EspalierVariant = "analogous-left" | "analogous-right" | "complementary" | "danger" | "info" | "neutral" | "primary" | "split-complementary-left" | "split-complementary-right" | "success" | "triadic-left" | "triadic-right" | "warning" | "";
|
|
3
|
+
import { type EspalierIntentVariant } from "./intent-values.js";
|
|
5
4
|
/**
|
|
6
5
|
* Shared base class for Espalier elements.
|
|
7
6
|
*
|
|
@@ -18,7 +17,16 @@ export type EspalierVariant = "analogous-left" | "analogous-right" | "complement
|
|
|
18
17
|
* @cssprop --esp-field-focus-shadow - Shadow color used for shared field focus treatment. Defaults to `var(--esp-color-shadow)`.
|
|
19
18
|
*/
|
|
20
19
|
export declare class EspalierElementBase extends LitElement implements SeedColorRoot {
|
|
21
|
-
protected
|
|
20
|
+
protected intentBacker: EspalierIntentVariant;
|
|
21
|
+
/**
|
|
22
|
+
* Whether a non-neutral intent emits its inline tokens
|
|
23
|
+
* (`--esp-color-primary` and the filled-action pair). Interactive
|
|
24
|
+
* controls need them; chrome whose intent treatment is class-based
|
|
25
|
+
* (badges, callouts, status pills — see `intentSurfaceTokens`) opts
|
|
26
|
+
* out so a decorative intent never rewrites inherited tokens for
|
|
27
|
+
* slotted content.
|
|
28
|
+
*/
|
|
29
|
+
protected intentEmitsTokens: boolean;
|
|
22
30
|
get seedColor(): string;
|
|
23
31
|
set seedColor(val: string);
|
|
24
32
|
correlationId: `${string}-${string}-${string}-${string}-${string}`;
|
|
@@ -34,11 +42,20 @@ export declare class EspalierElementBase extends LitElement implements SeedColor
|
|
|
34
42
|
*/
|
|
35
43
|
scheme: "dark" | "light" | "";
|
|
36
44
|
/**
|
|
37
|
-
* The [
|
|
38
|
-
*
|
|
45
|
+
* The element's [intent](/espalier-guides/) — its meaning: `neutral`
|
|
46
|
+
* (no pin), `success`, `warning`, or `danger` (each pinned to its
|
|
47
|
+
* fixed status family), or `info` (pinned to the complementary
|
|
48
|
+
* family). On token-emitting controls a non-neutral intent pins the
|
|
49
|
+
* filled-action pair to that family, derived over the governing
|
|
50
|
+
* zone's theme; class-styled chrome (badges, callouts, status pills)
|
|
51
|
+
* opts out of inline emission and renders its treatment from CSS
|
|
52
|
+
* classes instead. An intent never repaints the surrounding zone,
|
|
53
|
+
* which is what contexts are for. Removing the attribute restores
|
|
54
|
+
* the element's own default intent.
|
|
55
|
+
* @type {EspalierIntentVariant}
|
|
39
56
|
*/
|
|
40
|
-
get
|
|
41
|
-
set
|
|
57
|
+
get intent(): EspalierIntentVariant;
|
|
58
|
+
set intent(value: EspalierIntentVariant | string | null);
|
|
42
59
|
/**
|
|
43
60
|
* A theme-defined color zone. The selected context rebinds designer-facing
|
|
44
61
|
* roles and emits a complete, contrast-enforced semantic token table on this
|
|
@@ -58,15 +75,16 @@ export declare class EspalierElementBase extends LitElement implements SeedColor
|
|
|
58
75
|
*/
|
|
59
76
|
traverseToClosest(selector: string): Element | null;
|
|
60
77
|
/**
|
|
61
|
-
* Compute and apply context- and
|
|
62
|
-
*
|
|
63
|
-
* With no context and the **primary** variant (or none), all semantic
|
|
64
|
-
* tokens cascade from `<esp-root>` and previous overrides are cleared.
|
|
78
|
+
* Compute and apply context- and intent-specific semantic color tokens.
|
|
65
79
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
80
|
+
* With no context and a `neutral` intent, all semantic tokens cascade
|
|
81
|
+
* from `<esp-root>` and previous overrides are cleared. A context
|
|
82
|
+
* emits the zone's complete nineteen-token table; a non-neutral intent
|
|
83
|
+
* then overlays the filled-action pair, derived over the governing
|
|
84
|
+
* zone's theme — this host's own context, or the nearest ancestor
|
|
85
|
+
* zone's — so its APCA enforcement runs against the zone's actual
|
|
86
|
+
* action surface.
|
|
68
87
|
*/
|
|
69
|
-
protected
|
|
70
|
-
protected getVariantColorSource(): ColorSource | "";
|
|
88
|
+
protected applyScopedColorTokens(): void;
|
|
71
89
|
static styles: import("lit").CSSResult[];
|
|
72
90
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var h=function(f,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(f,e,t,r);else for(var i=f.length-1;i>=0;i--)(a=f[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 p,state as S}from"lit/decorators.js";import{subscribeToRootEvent as u}from"./root-event-subscription.js";import{traverseToClosest as b}from"./utilities.js";import{parseCssColor as w,serializeOklch as x,gamutMapToSRGB as P}from"./color-engine.js";import{computeVariants as v}from"../root/helpers/compute-variants.js";import{computeSemanticProperties as m}from"../root/helpers/compute-semantic-properties.js";import{lightnessRampProperties as E}from"../root/helpers/lightness-ramp-properties.js";import{ROLE_NAMES as V,mergeTheme as U,semanticToCSS as A}from"./theme.js";import{alignAttributeTextInheritance as I,focusRing as O}from"./style-fragments.js";import{syncNormalizedAttribute as D}from"./attribute-helpers.js";import{INTENT_VARIANTS as y,normalizeIntentVariant as z}from"./intent-values.js";const k=new WeakMap;class n extends C{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=z(e);D(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=[u(e,"seed-color-changed",this.handleSeedColorChanged),u(e,"scheme-changed",this.handleSchemeChanged),u(e,"theme-changed",this.handleThemeChanged),u(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=w(o.seedColor);if(!s)return;const a=v(s,o),i={};if(r.applied&&(Object.assign(i,m(o,a)),Object.assign(i,E(o))),e){let c=o;r.applied||(c=this.resolveAncestorZoneTheme(t)??o);const l=c===o?a:v(s,c),T=m(c,l,{effectiveSource:(g,d)=>n.semanticActionTokens.has(g)?e:d});i["--esp-color-primary"]=x(P(l[e]));for(const g of n.semanticActionTokens){const d=A(g);i[d]=T[d]}}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){const r=e.contexts&&Object.prototype.hasOwnProperty.call(e.contexts,t)?e.contexts[t]:void 0;if(!r)return null;let o=k.get(e);const s=o?.get(t);if(s)return s;const a={};for(const c of V){const l=r[c];l!==void 0&&(a[c]=l)}const i=U(e,{lightness:r.lightness,roles:a});return o||(o=new Map,k.set(e,o)),o.set(t,i),i}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:"complementary",neutral:"",success:"success",warning:"warning"},n.semanticActionTokens=new Set(["actionBackground","actionText"]),n.styles=[O(".esp-field:focus-within","--esp-field-focus-shadow"),I,R`
|
|
2
2
|
:host {
|
|
3
3
|
|
|
4
4
|
--_esp-field-resolved-hover-bg: var(
|
|
@@ -122,4 +122,4 @@ var c=function(u,e,t,o){var r=arguments.length,s=r<3?e:o===null?o=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
|
-
`],
|
|
125
|
+
`],h([S()],n.prototype,"seedColor",null),h([p({attribute:!1})],n.prototype,"correlationId",void 0),h([p({type:String,reflect:!0})],n.prototype,"scheme",void 0),h([p({type:String,attribute:"intent",reflect:!0,useDefault:!0})],n.prototype,"intent",null),h([p({type:String,attribute:"context",reflect:!0})],n.prototype,"context",null);export{n as EspalierElementBase};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{css as
|
|
1
|
+
import{css as o,unsafeCSS as e}from"lit";const l=o`
|
|
2
2
|
:host([align]) {
|
|
3
3
|
text-align: inherit;
|
|
4
4
|
}
|
|
5
|
-
`,
|
|
5
|
+
`,a=o`
|
|
6
6
|
.sr-only {
|
|
7
7
|
position: absolute;
|
|
8
8
|
width: 1px;
|
|
@@ -14,14 +14,44 @@ import{css as n,unsafeCSS as t}from"lit";const a=n`
|
|
|
14
14
|
white-space: nowrap;
|
|
15
15
|
border: 0;
|
|
16
16
|
}
|
|
17
|
-
`;function
|
|
18
|
-
${
|
|
17
|
+
`;function i(r){const n=r.includes(":host")||r.includes("[disabled]")?r:`:host([disabled]) ${r}`;return o`
|
|
18
|
+
${e(n)} {
|
|
19
19
|
opacity: 0.5;
|
|
20
20
|
cursor: not-allowed;
|
|
21
21
|
}
|
|
22
|
-
`}function p(
|
|
23
|
-
${
|
|
24
|
-
box-shadow: ${
|
|
25
|
-
var(${
|
|
22
|
+
`}function p(r,n,t="0 0 3px",s=""){return o`
|
|
23
|
+
${e(r)} {
|
|
24
|
+
box-shadow: ${e(s)} ${e(t)}
|
|
25
|
+
var(${e(n)}, var(--esp-color-shadow));
|
|
26
26
|
}
|
|
27
|
-
`}
|
|
27
|
+
`}const d=o`
|
|
28
|
+
.intent-neutral {
|
|
29
|
+
--_esp-intent-background: var(--esp-color-layer-2);
|
|
30
|
+
--_esp-intent-border-color: var(--esp-color-border);
|
|
31
|
+
--_esp-intent-color: var(--esp-color-text);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.intent-success {
|
|
35
|
+
--_esp-intent-background: oklch(from var(--esp-color-success) var(--esp-l-raised-2) c h);
|
|
36
|
+
--_esp-intent-border-color: oklch(from var(--esp-color-success) var(--esp-l-border) c h);
|
|
37
|
+
--_esp-intent-color: oklch(from var(--esp-color-success) var(--esp-l-text) c h);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.intent-warning {
|
|
41
|
+
--_esp-intent-background: oklch(from var(--esp-color-warning) var(--esp-l-raised-2) c h);
|
|
42
|
+
--_esp-intent-border-color: oklch(from var(--esp-color-warning) var(--esp-l-border) c h);
|
|
43
|
+
--_esp-intent-color: oklch(from var(--esp-color-warning) var(--esp-l-text) c h);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.intent-danger {
|
|
47
|
+
--_esp-intent-background: oklch(from var(--esp-color-danger) var(--esp-l-raised-2) c h);
|
|
48
|
+
--_esp-intent-border-color: oklch(from var(--esp-color-danger) var(--esp-l-border) c h);
|
|
49
|
+
--_esp-intent-color: var(--esp-color-danger-text);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.intent-info {
|
|
53
|
+
--_esp-intent-background: var(--esp-color-link-hover-bg);
|
|
54
|
+
--_esp-intent-border-color: oklch(from var(--esp-color-link) var(--esp-l-border) c h);
|
|
55
|
+
--_esp-intent-color: var(--esp-color-link);
|
|
56
|
+
}
|
|
57
|
+
`;export{l as alignAttributeTextInheritance,i as disabledControl,p as focusRing,d as intentSurfaceTokens,a as srOnly};
|
package/dist/shared/theme.d.ts
CHANGED
|
@@ -97,9 +97,10 @@ export type ThemeAnchors = Record<string, ThemeAnchor>;
|
|
|
97
97
|
*
|
|
98
98
|
* An anchor source contributes its own hue **and chroma**; lightness
|
|
99
99
|
* always comes from the mapping's ramp stop, and APCA enforcement
|
|
100
|
-
* applies unchanged.
|
|
101
|
-
*
|
|
102
|
-
* so
|
|
100
|
+
* applies unchanged. Anchors are absolute sources rather than seed
|
|
101
|
+
* rotations — a brand color is a color, not a relationship to the
|
|
102
|
+
* seed — so they hold steady while contexts rebind roles around them
|
|
103
|
+
* and intents replace the filled-action source.
|
|
103
104
|
*/
|
|
104
105
|
export type MappingSource = ColorSource | `anchor:${string}`;
|
|
105
106
|
/** Anchor names and slot names share one slug grammar. */
|
|
@@ -586,18 +587,6 @@ export declare function encodeTheme(partial: PartialTheme): string;
|
|
|
586
587
|
* @returns A new fully-resolved {@link EspalierTheme}.
|
|
587
588
|
*/
|
|
588
589
|
export declare function mergeTheme(defaults: EspalierTheme, overrides: PartialTheme): EspalierTheme;
|
|
589
|
-
/**
|
|
590
|
-
* Validate a Base64-encoded theme string.
|
|
591
|
-
*
|
|
592
|
-
* Checks structure, types, and value ranges. The function is
|
|
593
|
-
* intentionally lenient on unknown keys (future-proofing) but
|
|
594
|
-
* strict on the keys it recognises.
|
|
595
|
-
*
|
|
596
|
-
* @param base64 A Base64-encoded JSON string representing a
|
|
597
|
-
* partial or full theme.
|
|
598
|
-
* @returns A {@link ThemeValidationResult} with `valid`, `errors`,
|
|
599
|
-
* and `warnings`.
|
|
600
|
-
*/
|
|
601
590
|
export declare function validateTheme(base64: string): ThemeValidationResult;
|
|
602
591
|
/**
|
|
603
592
|
* Validate the light and dark partials that form one scheme-paired theme.
|