@taprootio/espalier 4.11.0 → 4.13.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 +35 -0
- package/custom-elements.json +16090 -14099
- package/dist/font-picker/esp-font-picker.d.ts +17 -23
- package/dist/font-picker/esp-font-picker.js +5 -5
- package/dist/font-picker/font-types.d.ts +49 -0
- package/dist/font-picker/font-types.js +1 -0
- package/dist/help/esp-help-button.d.ts +1 -1
- package/dist/icons/icon-sprite.generated.d.ts +1 -1
- package/dist/icons/icon-sprite.generated.js +15 -0
- package/dist/image-picker/esp-image-picker.d.ts +97 -0
- package/dist/image-picker/esp-image-picker.js +74 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/lightbox/esp-lightbox.d.ts +1 -1
- package/dist/menu/drawer-nested-fit.js +1 -0
- package/dist/menu/esp-menu-group.js +5 -0
- package/dist/menu/esp-menu.d.ts +15 -0
- package/dist/menu/esp-menu.js +99 -25
- package/dist/pickers/esp-pick-one.js +5 -4
- package/dist/pickers/esp-picker-base.js +3 -3
- package/dist/pickers/esp-picker-menu.js +9 -9
- package/dist/shared/configured-brand.d.ts +1 -1
- package/dist/shared/events.d.ts +5 -0
- package/dist/shared/font-helpers.d.ts +8 -4
- package/dist/shared/font-helpers.js +1 -1
- package/dist/shared/font-stacks.d.ts +58 -0
- package/dist/shared/font-stacks.js +1 -0
- package/dist/shared/popover-controller.js +1 -1
- package/espalier.css-data.json +20 -0
- package/espalier.token-manifest.json +30 -0
- package/package.json +5 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var u=function(a,e,t,r){var s=arguments.length,i=s<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(a,e,t,r);else for(var n=a.length-1;n>=0;n--)(l=a[n])&&(i=(s<3?l(i):s>3?l(e,t,i):l(e,t))||i);return s>3&&i&&Object.defineProperty(e,t,i),i};import{LitElement as
|
|
1
|
+
var u=function(a,e,t,r){var s=arguments.length,i=s<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(a,e,t,r);else for(var n=a.length-1;n>=0;n--)(l=a[n])&&(i=(s<3?l(i):s>3?l(e,t,i):l(e,t))||i);return s>3&&i&&Object.defineProperty(e,t,i),i};import{LitElement as C,css as T,html as f,unsafeCSS as E}from"lit";import{customElement as H,property as b,state as S}from"lit/decorators.js";import{createRef as A,ref as R}from"lit/directives/ref.js";import{styleMap as M}from"lit/directives/style-map.js";import"../shared/virtualizer/lit-virtualizer.js";import{spaceAroundRect as x,viewportSize as g}from"../shared/viewport.js";import{ESP_EVENTS as y}from"../shared/events.js";import{COMPACT_VIEWPORT_MEDIA_QUERY as z,compactViewportMatches as F}from"../shared/responsive.js";import{findContainingPopovers as $}from"../shared/popover-controller.js";const v="highlighted",D=44;function w(a){if(!a)return null;const e=a;return typeof e.enterPickerMenuFullscreen=="function"&&typeof e.exitPickerMenuFullscreen=="function"&&typeof e.pickerMenuIsOpen=="function"?a:null}function _(a){if($(a).some(t=>[...t.shadowRoot?.querySelectorAll("[popover]")??[]].some(r=>r.matches(":popover-open"))))return!0;let e=a;for(;e;){const t=e.getRootNode();if(e=e.assignedSlot??e.parentElement??(t instanceof ShadowRoot?t.host:null),!e)return!1;if(e.matches(":popover-open")||e.matches("dialog[open], esp-dialog[is-open], esp-flyout[open]"))return!0}return!1}let c=class extends C{get fullscreenPresentation(){return this.hasAttribute("data-fullscreen")}constructor(){super(),this.internals=this.attachInternals(),this.virtualizerRef=A(),this.internalPoolClone=null,this.internalPoolFingerprint=null,this.internalPickScrollTop=null,this.lastPoolFingerprint=null,this.preRenderScrollTop=null,this.openSessionGeneration=0,this.maxAvailableHeight=0,this.lastViewportHeight=0,this.positionTarget=null,this.label="",this.virtualizedItemsPool=[],this.highlightIndex=-1,this.multiSelect=!1,this.loading=!1,this.emptyMessage="",this.handleItemPointerDown=e=>{this.selectItemFromPointerEvent(e)},this.menuDirty=!1,this.settlerActive=!1,this.pendingItemsChanged=!1,this.retargetingSequence=!1,this.renderPickerItem=(e,t)=>{const r={display:"block",cursor:"pointer",width:"100%",...e.styles};return f`<esp-picker-item
|
|
2
2
|
class="picker-item"
|
|
3
3
|
data-picker-index=${t}
|
|
4
4
|
.text=${e.text}
|
|
@@ -6,19 +6,19 @@ var u=function(a,e,t,r){var s=arguments.length,i=s<3?e:r===null?r=Object.getOwnP
|
|
|
6
6
|
.selected=${e.selected}
|
|
7
7
|
.icon=${e.icon??""}
|
|
8
8
|
.highlightRanges=${e.highlightRanges}
|
|
9
|
-
style=${
|
|
9
|
+
style=${M(r)}
|
|
10
10
|
>
|
|
11
11
|
${e.slotNodes?.map(s=>s.cloneNode(!0))}
|
|
12
|
-
</esp-picker-item>`},this.internals.role="listbox"}connectedCallback(){super.connectedCallback(),this.setAttribute("popover","manual"),this.hasAttribute("role")||this.setAttribute("role","listbox")}willUpdate(e){if(super.willUpdate(e),e.has("virtualizedItemsPool")&&this.preRenderScrollTop===null&&!this.retargetingSequence&&this.matches(":popover-open")){const t=this.virtualizerRef.value?.scrollTop??0;t>0&&(this.preRenderScrollTop=t)}}updated(e){super.updated(e),e.has("multiSelect")&&(this.internals.ariaMultiSelectable=String(this.multiSelect),this.setAttribute("aria-multiselectable",String(this.multiSelect))),e.has("label")&&(this.internals.ariaLabel=this.label,this.label?this.setAttribute("aria-label",this.label):this.removeAttribute("aria-label"));const t=e.has("virtualizedItemsPool");let r=!1;if(t){const s=this.virtualizedItemsPool.map(l=>`${l.value}\0${l.text}\0${l.selected===!0}`),i=this.virtualizedItemsPool===this.internalPoolClone||this.internalPoolFingerprint!==null&&this.internalPoolFingerprint.length===s.length&&this.internalPoolFingerprint.every((l,n)=>l===s[n]);this.internalPoolClone=null,i||(this.internalPoolFingerprint=null,this.internalPickScrollTop=null),r=!i&&(this.lastPoolFingerprint===null||this.lastPoolFingerprint.length!==s.length||this.lastPoolFingerprint.some((l,n)=>l!==s[n])),this.lastPoolFingerprint=s}(t||e.has("loading"))&&this.maxAvailableHeight>0&&this.matches(":popover-open")&&(this.pendingItemsChanged||=r,this.menuDirty=!0,this.settleMenuAfterUpdate())}get pickerItems(){return this.virtualizedItemsPool}set pickerItems(e){const t=this.virtualizedItemsPool.filter(i=>i.selected).map(i=>i.value);this.virtualizedItemsPool=e;const r=e.filter(i=>i.selected),s=r.map(i=>i.value);(t.length!==s.length||t.some((i,l)=>i!==s[l]))&&this.dispatchEvent(new CustomEvent(f.PICKER_MENU_SELECTION_CHANGED,{detail:r,bubbles:!0,composed:!0}))}setHighlight(e){const t=this.virtualizedItemsPool;if(t.length===0)return;(this.highlightIndex<0||this.highlightIndex>t.length-1)&&(this.highlightIndex=e);const r=this.virtualizerRef.value;r&&r.scrollToIndex(this.highlightIndex,"nearest"),this.applyHighlightClass()}async setHighlightAsync(e){const t=this.openSessionGeneration,r=()=>t!==this.openSessionGeneration||!this.isConnected,s=this.virtualizedItemsPool;if(s.length===0)return;(this.highlightIndex<0||this.highlightIndex>s.length-1)&&(this.highlightIndex=e);const i=this.virtualizerRef.value;if(i){if(await this.stableLayout(i),r())return;const l=i.scrollTop;for(let n=0;n<3;n+=1)try{i.scrollToIndex(this.highlightIndex,"nearest");break}catch{if(await this.stableLayout(i),r()||i.scrollTop!==l)return}if(await this.stableLayout(i),r())return}this.applyHighlightWithRetry(3)}applyHighlightClass(){const e=this.getHighlightedElement();e&&(this.clearHighlight(),e.classList.add(y))}clearHighlight(){const e=this.virtualizerRef.value;if(e)for(const t of e.querySelectorAll(`esp-picker-item.${y}`))t.classList.remove(y)}resetHighlight(){this.clearHighlight();const e=this.virtualizedItemsPool.find(t=>t.selected);this.highlightIndex=e?this.virtualizedItemsPool.indexOf(e):-1}applyHighlightWithRetry(e){if(!this.isConnected||!this.matches(":popover-open"))return;const t=this.getHighlightedElement();if(t){this.clearHighlight(),t.classList.add(y);return}e>0&&requestAnimationFrame(()=>this.applyHighlightWithRetry(e-1))}getHighlightedElement(){if(this.highlightIndex<0)return null;const e=this.virtualizerRef.value;if(!e)return null;const t=e.querySelectorAll("esp-picker-item");for(const r of t)if(this.virtualizedItemsPool.findIndex(i=>i.value===r.value&&i.text===r.text)===this.highlightIndex)return r;return null}pickItem(e){const t=this.virtualizerRef.value?.scrollTop??0;this.preRenderScrollTop===null&&t>0&&(this.preRenderScrollTop=t),t>0&&(this.internalPickScrollTop=t);for(const i of this.pickerItems)i===e?i.selected=!i.selected:this.multiSelect||(i.selected=!1);const r=this.virtualizedItemsPool.indexOf(e);if(r!==-1){this.highlightIndex=r;const i=this.getHighlightedElement();i&&(this.clearHighlight(),i.classList.add(y))}const s=[...this.pickerItems];this.internalPoolClone=s,this.internalPoolFingerprint=s.map(i=>`${i.value}\0${i.text}\0${i.selected===!0}`),this.pickerItems=s,this.dispatchEvent(new CustomEvent(f.PICKER_MENU_SELECTION_CHANGED,{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0})),this.multiSelect||this.dispatchEvent(new CustomEvent(f.PICKER_MENU_CLOSE_REQUESTED,{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0}))}selectItemByIndex(e){const t=Number.isInteger(e)?this.virtualizedItemsPool[e]:void 0;return t?(this.pickItem(t),!0):!1}getPickerItemElementAtPoint(e,t){const r=this.shadowRoot?.querySelectorAll("esp-picker-item[data-picker-index]");if(!r)return null;for(const s of r){const i=s.getBoundingClientRect();if(e>=i.left&&e<=i.right&&t>=i.top&&t<=i.bottom)return s}return null}selectPickerItemElement(e){return e?this.selectItemByIndex(Number(e.dataset.pickerIndex)):!1}selectItemAtPoint(e,t){return this.selectPickerItemElement(this.getPickerItemElementAtPoint(e,t))}selectItemFromPointerEvent(e){const t=e.composedPath().find(s=>s instanceof HTMLElement&&s.matches("esp-picker-item[data-picker-index]"));return this.selectPickerItemElement(t??this.getPickerItemElementAtPoint(e.clientX,e.clientY))?(e.preventDefault(),e.stopPropagation(),!0):!1}requestDismiss(){this.dispatchEvent(new CustomEvent(f.PICKER_MENU_DISMISS_REQUESTED,{bubbles:!0,composed:!0,cancelable:!0}))&&this.hideMenu()}clearFullscreenTarget(e=this.positionTarget){x(e)?.exitPickerMenuFullscreen()}syncPresentation(e){const t=this.positionTarget;t&&t!==e&&this.clearFullscreenTarget(t),this.positionTarget=e;const r=x(e),s=z()&&r!==null&&!$(e);if(!s)return this.clearFullscreenTarget(e),this.toggleAttribute("data-fullscreen",!1),{fullscreen:s,rect:e.getBoundingClientRect()};const i=r.enterPickerMenuFullscreen();return i?(this.toggleAttribute("data-fullscreen",!0),{fullscreen:s,rect:i}):(this.clearFullscreenTarget(e),this.toggleAttribute("data-fullscreen",!1),{fullscreen:!1,rect:e.getBoundingClientRect()})}applyFullscreenGeometry(e){const{height:t,width:r}=m(),s=Math.min(Math.max(e.bottom,F),t);this.maxAvailableHeight=Math.max(t-s,0),this.lastViewportHeight=t;const i={viewportWidth:r,viewportHeight:t,inputBottom:s};this.lastFullscreenGeometry?.viewportWidth===i.viewportWidth&&this.lastFullscreenGeometry.viewportHeight===i.viewportHeight&&this.lastFullscreenGeometry.inputBottom===i.inputBottom||(this.lastFullscreenGeometry=i,this.style.setProperty("height",`${t}px`),this.style.setProperty("width",`${r}px`),this.style.setProperty("min-width",`${r}px`),this.style.setProperty("left","0px"),this.style.setProperty("top","0px"),this.style.removeProperty("bottom"),this.style.setProperty("--_esp-picker-menu-input-bottom",`${s}px`))}clearFullscreenGeometry(){this.lastFullscreenGeometry=void 0,this.style.removeProperty("height"),this.style.removeProperty("width"),this.style.removeProperty("min-width"),this.style.removeProperty("left"),this.style.removeProperty("top"),this.style.removeProperty("bottom"),this.style.removeProperty("--_esp-picker-menu-input-bottom")}positionSelf(e){this.resetSettleState();const{fullscreen:t,rect:r}=this.syncPresentation(e),{height:s}=m();let i;if(t)this.applyFullscreenGeometry(r),i=this.maxAvailableHeight;else{this.clearFullscreenGeometry();const{spaceAbove:o,spaceBelow:h}=I(r,s);i=Math.max(Math.max(o,h)-75,0),this.maxAvailableHeight=i,this.lastViewportHeight=s,this.style.setProperty("height",`${i}px`),this.style.setProperty("min-width",`${r.width}px`),this.style.setProperty("left",`${r.left}px`),this.style.removeProperty("top"),this.style.removeProperty("bottom"),o>h?this.style.setProperty("bottom",`${s-r.top}px`):this.style.setProperty("top",`${r.bottom}px`)}this.classList.remove("visible"),this.matches(":popover-open")||this.showPopover();const l=this.pickerItems.find(o=>o.selected);this.highlightIndex=l?this.pickerItems.indexOf(l):0,this.openSessionGeneration+=1;const n=this.openSessionGeneration;this.setHighlightAsync(0).then(()=>{requestAnimationFrame(()=>{n!==this.openSessionGeneration||!this.isConnected||(this.fullscreenPresentation||(this.shrinkToFit(i),this.widenToFitContent(r)),this.classList.add("visible"))})})}async stableLayout(e){for(let t=0;t<20;t+=1){const r=e.layoutComplete;if(!r)return;const s=await Promise.race([r.then(()=>"settled",()=>"superseded"),new Promise(i=>setTimeout(()=>i("deadline"),250))]);if(s==="settled"||s==="deadline"||e.layoutComplete===r)return}}async settleMenuAfterUpdate(){if(this.settlerActive)return;this.settlerActive=!0;const e=this.openSessionGeneration,t=()=>e!==this.openSessionGeneration?!0:!this.isConnected||!this.matches(":popover-open")?(this.menuDirty=!1,this.preRenderScrollTop=null,this.pendingItemsChanged=!1,this.retargetingSequence=!1,this.internalPickScrollTop=null,!0):!1;try{for(let r=0;r<10&&this.menuDirty;r+=1){this.menuDirty=!1;try{await this.updateComplete}catch{this.menuDirty=!1;return}if(t())return;const s=this.virtualizerRef.value;if(!s){requestAnimationFrame(()=>{if(t()||this.fullscreenPresentation)return;const h=this.shadowRoot?.querySelector(".status-message");if(h){const c=Math.min(h.scrollHeight,this.maxAvailableHeight);this.style.setProperty("height",`${c}px`)}});continue}if(await this.stableLayout(s),t())return;if(this.menuDirty)continue;const i=this.preRenderScrollTop??0,l=i>0&&!this.pendingItemsChanged&&!this.retargetingSequence;if(s.scrollTop=0,this.sizeToContent(this.maxAvailableHeight),l&&s.scrollTop<i){if(s.scrollTop=i,await this.stableLayout(s),t())return;if(this.menuDirty)continue}const n=this.virtualizedItemsPool;if(n.length===0)continue;if(this.pendingItemsChanged){this.pendingItemsChanged=!1,this.retargetingSequence=!0,this.preRenderScrollTop=null;const h=n.findIndex(c=>c.selected);h>=0?this.highlightIndex=h:this.highlightIndex>=n.length?this.highlightIndex=n.length-1:this.highlightIndex<0&&(this.highlightIndex=0)}if(this.retargetingSequence){try{s.scrollToIndex(this.highlightIndex,"nearest")}catch{}if(await this.stableLayout(s),t())return;if(this.menuDirty)continue}this.applyHighlightWithRetry(3);const o=Math.max(l?i:0,this.internalPickScrollTop??0);if(o>0){if(s.scrollTop<o&&(s.scrollTop=o),await this.stableLayout(s),t())return;if(this.menuDirty)continue;if(await new Promise(h=>requestAnimationFrame(()=>h())),t())return;if(this.menuDirty)continue;s.scrollTop<o&&(s.scrollTop=o)}this.internalPickScrollTop=null,this.preRenderScrollTop=null,this.retargetingSequence=!1}}finally{this.settlerActive=!1,this.menuDirty&&this.settleMenuAfterUpdate()}}sizeToContent(e){if(this.fullscreenPresentation)return;const t=this.measureContentHeight();t>0&&this.style.setProperty("height",`${Math.min(t,e)}px`)}shrinkToFit(e){if(this.fullscreenPresentation)return;const t=this.measureContentHeight();t>2&&t<e&&this.style.setProperty("height",`${t}px`)}measureContentHeight(){const e=this.virtualizerRef.value;if(!e)return 0;const t=e.querySelectorAll("esp-picker-item");if(t.length===0)return 0;const r=getComputedStyle(this),s=(parseFloat(r.borderTopWidth)||0)+(parseFloat(r.borderBottomWidth)||0),i=this.virtualizedItemsPool.length;if(t.length<i)return e.scrollHeight+s;const l=e.scrollTop;e.scrollTop=0;const n=e.getBoundingClientRect(),o=t[t.length-1].getBoundingClientRect();return l>0&&(e.scrollTop=l),o.bottom-n.top+s}widenToFitContent(e){if(this.fullscreenPresentation)return;const t=this.virtualizerRef.value;if(!t)return;const r=t.querySelectorAll("esp-picker-item");let s=e.width;for(const i of r)s=Math.max(s,i.scrollWidth);if(s+=2,s>e.width){const{width:i}=m(),l=Math.min(s,i-e.left);this.style.setProperty("width",`${l}px`)}}updatePosition(e){const t=x(e);if(t&&!t.pickerMenuIsOpen())return;const r=this.fullscreenPresentation,{fullscreen:s,rect:i}=this.syncPresentation(e),l=r!==s;if(l){const c=this.virtualizerRef.value?.scrollTop??0;c>0&&this.preRenderScrollTop===null&&!this.pendingItemsChanged&&!this.retargetingSequence&&(this.preRenderScrollTop=c),this.openSessionGeneration+=1,this.menuDirty=!0}if(!this.matches(":popover-open")){if(!t?.pickerMenuIsOpen())return;try{this.showPopover()}catch{this.menuDirty=!1,this.clearFullscreenTarget(e),this.removeAttribute("data-fullscreen"),this.clearFullscreenGeometry(),this.requestDismiss();return}this.classList.add("visible")}if(l&&this.settleMenuAfterUpdate(),s){this.applyFullscreenGeometry(i),l&&this.classList.add("visible");return}if(r){this.clearFullscreenGeometry(),this.style.setProperty("min-width",`${i.width}px`);const{height:c}=m(),{spaceAbove:b,spaceBelow:d}=I(i,c),v=Math.max(Math.max(b,d)-75,0);this.maxAvailableHeight=v,this.lastViewportHeight=c,this.style.setProperty("height",`${v}px`),this.sizeToContent(v)}const{height:n}=m();if(n!==this.lastViewportHeight){const{spaceAbove:c,spaceBelow:b}=I(i,n),d=Math.max(Math.max(c,b)-75,0);this.maxAvailableHeight=d,this.lastViewportHeight=n,(parseFloat(this.style.getPropertyValue("height"))||0)>d&&this.style.setProperty("height",`${d}px`),this.sizeToContent(d)}this.style.setProperty("left",`${i.left}px`);const o=i.top,h=n-i.bottom;o>h?(this.style.removeProperty("top"),this.style.setProperty("bottom",`${n-i.top}px`)):(this.style.removeProperty("bottom"),this.style.setProperty("top",`${i.bottom}px`)),l&&this.classList.add("visible")}hideMenu(){this.openSessionGeneration+=1,this.classList.remove("visible"),this.resetSettleState(),this.clearFullscreenTarget(),this.positionTarget=null,this.removeAttribute("data-fullscreen"),this.clearFullscreenGeometry();try{this.hidePopover()}catch{}}resetSettleState(){this.preRenderScrollTop=null,this.pendingItemsChanged=!1,this.retargetingSequence=!1,this.internalPickScrollTop=null,this.menuDirty=!1}disconnectedCallback(){this.hideMenu(),super.disconnectedCallback()}doKeyboardNav(e){const t=this.virtualizedItemsPool;if(t.length!==0)switch(e){case"ArrowDown":this.highlightIndex+=1,this.setHighlight(0);break;case"ArrowUp":this.highlightIndex-=1,this.setHighlight(t.length-1);break;case"Home":this.highlightIndex=0,this.setHighlight(0);break;case"End":this.highlightIndex=t.length-1,this.setHighlight(t.length-1);break;case"Enter":if(this.highlightIndex===-1)return;this.pickItem(t[this.highlightIndex]);break}}render(){let e;return this.loading?e=g`<div class="status-message">Searching…</div>`:this.virtualizedItemsPool.length===0&&this.emptyMessage?e=g`<div class="status-message">${this.emptyMessage}</div>`:e=g`<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(e){if(super.willUpdate(e),e.has("virtualizedItemsPool")&&this.preRenderScrollTop===null&&!this.retargetingSequence&&this.matches(":popover-open")){const t=this.virtualizerRef.value?.scrollTop??0;t>0&&(this.preRenderScrollTop=t)}}updated(e){super.updated(e),e.has("multiSelect")&&(this.internals.ariaMultiSelectable=String(this.multiSelect),this.setAttribute("aria-multiselectable",String(this.multiSelect))),e.has("label")&&(this.internals.ariaLabel=this.label,this.label?this.setAttribute("aria-label",this.label):this.removeAttribute("aria-label"));const t=e.has("virtualizedItemsPool");let r=!1;if(t){const s=this.virtualizedItemsPool.map(l=>`${l.value}\0${l.text}\0${l.selected===!0}`),i=this.virtualizedItemsPool===this.internalPoolClone||this.internalPoolFingerprint!==null&&this.internalPoolFingerprint.length===s.length&&this.internalPoolFingerprint.every((l,n)=>l===s[n]);this.internalPoolClone=null,i||(this.internalPoolFingerprint=null,this.internalPickScrollTop=null),r=!i&&(this.lastPoolFingerprint===null||this.lastPoolFingerprint.length!==s.length||this.lastPoolFingerprint.some((l,n)=>l!==s[n])),this.lastPoolFingerprint=s}(t||e.has("loading"))&&this.maxAvailableHeight>0&&this.matches(":popover-open")&&(this.pendingItemsChanged||=r,this.menuDirty=!0,this.settleMenuAfterUpdate())}get pickerItems(){return this.virtualizedItemsPool}set pickerItems(e){const t=this.virtualizedItemsPool.filter(i=>i.selected).map(i=>i.value);this.virtualizedItemsPool=e;const r=e.filter(i=>i.selected),s=r.map(i=>i.value);(t.length!==s.length||t.some((i,l)=>i!==s[l]))&&this.dispatchEvent(new CustomEvent(y.PICKER_MENU_SELECTION_CHANGED,{detail:r,bubbles:!0,composed:!0}))}setHighlight(e){const t=this.virtualizedItemsPool;if(t.length===0)return;(this.highlightIndex<0||this.highlightIndex>t.length-1)&&(this.highlightIndex=e);const r=this.virtualizerRef.value;r&&r.scrollToIndex(this.highlightIndex,"nearest"),this.applyHighlightClass()}async setHighlightAsync(e){const t=this.openSessionGeneration,r=()=>t!==this.openSessionGeneration||!this.isConnected,s=this.virtualizedItemsPool;if(s.length===0)return;(this.highlightIndex<0||this.highlightIndex>s.length-1)&&(this.highlightIndex=e);const i=this.virtualizerRef.value;if(i){if(await this.stableLayout(i),r())return;const l=i.scrollTop;for(let n=0;n<3;n+=1)try{i.scrollToIndex(this.highlightIndex,"nearest");break}catch{if(await this.stableLayout(i),r()||i.scrollTop!==l)return}if(await this.stableLayout(i),r())return}this.applyHighlightWithRetry(3)}applyHighlightClass(){const e=this.getHighlightedElement();e&&(this.clearHighlight(),e.classList.add(v))}clearHighlight(){const e=this.virtualizerRef.value;if(e)for(const t of e.querySelectorAll(`esp-picker-item.${v}`))t.classList.remove(v)}resetHighlight(){this.clearHighlight();const e=this.virtualizedItemsPool.find(t=>t.selected);this.highlightIndex=e?this.virtualizedItemsPool.indexOf(e):-1}applyHighlightWithRetry(e){if(!this.isConnected||!this.matches(":popover-open"))return;const t=this.getHighlightedElement();if(t){this.clearHighlight(),t.classList.add(v);return}e>0&&requestAnimationFrame(()=>this.applyHighlightWithRetry(e-1))}getHighlightedElement(){if(this.highlightIndex<0)return null;const e=this.virtualizerRef.value;if(!e)return null;const t=e.querySelectorAll("esp-picker-item");for(const r of t)if(this.virtualizedItemsPool.findIndex(i=>i.value===r.value&&i.text===r.text)===this.highlightIndex)return r;return null}pickItem(e){const t=this.virtualizerRef.value?.scrollTop??0;this.preRenderScrollTop===null&&t>0&&(this.preRenderScrollTop=t),t>0&&(this.internalPickScrollTop=t);for(const i of this.pickerItems)i===e?i.selected=!i.selected:this.multiSelect||(i.selected=!1);const r=this.virtualizedItemsPool.indexOf(e);if(r!==-1){this.highlightIndex=r;const i=this.getHighlightedElement();i&&(this.clearHighlight(),i.classList.add(v))}const s=[...this.pickerItems];this.internalPoolClone=s,this.internalPoolFingerprint=s.map(i=>`${i.value}\0${i.text}\0${i.selected===!0}`),this.pickerItems=s,this.dispatchEvent(new CustomEvent(y.PICKER_MENU_SELECTION_CHANGED,{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0})),this.multiSelect||this.dispatchEvent(new CustomEvent(y.PICKER_MENU_CLOSE_REQUESTED,{detail:this.pickerItems.filter(i=>i.selected),bubbles:!0,composed:!0}))}selectItemByIndex(e){const t=Number.isInteger(e)?this.virtualizedItemsPool[e]:void 0;return t?(this.pickItem(t),!0):!1}getPickerItemElementAtPoint(e,t){const r=this.shadowRoot?.querySelectorAll("esp-picker-item[data-picker-index]");if(!r)return null;for(const s of r){const i=s.getBoundingClientRect();if(e>=i.left&&e<=i.right&&t>=i.top&&t<=i.bottom)return s}return null}selectPickerItemElement(e){return e?this.selectItemByIndex(Number(e.dataset.pickerIndex)):!1}selectItemAtPoint(e,t){return this.selectPickerItemElement(this.getPickerItemElementAtPoint(e,t))}selectItemFromPointerEvent(e){const t=e.composedPath().find(s=>s instanceof HTMLElement&&s.matches("esp-picker-item[data-picker-index]"));return this.selectPickerItemElement(t??this.getPickerItemElementAtPoint(e.clientX,e.clientY))?(e.preventDefault(),e.stopPropagation(),!0):!1}requestDismiss(){this.dispatchEvent(new CustomEvent(y.PICKER_MENU_DISMISS_REQUESTED,{bubbles:!0,composed:!0,cancelable:!0}))&&this.hideMenu()}clearFullscreenTarget(e=this.positionTarget){w(e)?.exitPickerMenuFullscreen()}syncPresentation(e){const t=this.positionTarget;t&&t!==e&&this.clearFullscreenTarget(t),this.positionTarget=e;const r=w(e),s=F()&&r!==null&&!_(e);if(!s)return this.clearFullscreenTarget(e),this.toggleAttribute("data-fullscreen",!1),{fullscreen:s,rect:e.getBoundingClientRect()};const i=r.enterPickerMenuFullscreen();return i?(this.toggleAttribute("data-fullscreen",!0),{fullscreen:s,rect:i}):(this.clearFullscreenTarget(e),this.toggleAttribute("data-fullscreen",!1),{fullscreen:!1,rect:e.getBoundingClientRect()})}applyFullscreenGeometry(e){const{height:t,width:r}=g(),s=Math.min(Math.max(e.bottom,D),t);this.maxAvailableHeight=Math.max(t-s,0),this.lastViewportHeight=t;const i={viewportWidth:r,viewportHeight:t,inputBottom:s};this.lastFullscreenGeometry?.viewportWidth===i.viewportWidth&&this.lastFullscreenGeometry.viewportHeight===i.viewportHeight&&this.lastFullscreenGeometry.inputBottom===i.inputBottom||(this.lastFullscreenGeometry=i,this.style.setProperty("height",`${t}px`),this.style.setProperty("width",`${r}px`),this.style.setProperty("min-width",`${r}px`),this.style.setProperty("left","0px"),this.style.setProperty("top","0px"),this.style.removeProperty("bottom"),this.style.setProperty("--_esp-picker-menu-input-bottom",`${s}px`))}clearFullscreenGeometry(){this.lastFullscreenGeometry=void 0,this.style.removeProperty("height"),this.style.removeProperty("width"),this.style.removeProperty("min-width"),this.style.removeProperty("left"),this.style.removeProperty("top"),this.style.removeProperty("bottom"),this.style.removeProperty("--_esp-picker-menu-input-bottom")}positionSelf(e){this.resetSettleState();const{fullscreen:t,rect:r}=this.syncPresentation(e),{height:s}=g();let i;if(t)this.applyFullscreenGeometry(r),i=this.maxAvailableHeight;else{this.clearFullscreenGeometry();const{spaceAbove:o,spaceBelow:h}=x(r,s);i=Math.max(Math.max(o,h)-75,0),this.maxAvailableHeight=i,this.lastViewportHeight=s,this.style.setProperty("height",`${i}px`),this.style.setProperty("min-width",`${r.width}px`),this.style.setProperty("left",`${r.left}px`),this.style.removeProperty("top"),this.style.removeProperty("bottom"),o>h?this.style.setProperty("bottom",`${s-r.top}px`):this.style.setProperty("top",`${r.bottom}px`)}this.classList.remove("visible"),this.matches(":popover-open")||this.showPopover();const l=this.pickerItems.find(o=>o.selected);this.highlightIndex=l?this.pickerItems.indexOf(l):0,this.openSessionGeneration+=1;const n=this.openSessionGeneration;this.setHighlightAsync(0).then(()=>{requestAnimationFrame(()=>{n!==this.openSessionGeneration||!this.isConnected||(this.fullscreenPresentation||(this.shrinkToFit(i),this.widenToFitContent(r)),this.classList.add("visible"))})})}async stableLayout(e){for(let t=0;t<20;t+=1){const r=e.layoutComplete;if(!r)return;const s=await Promise.race([r.then(()=>"settled",()=>"superseded"),new Promise(i=>setTimeout(()=>i("deadline"),250))]);if(s==="settled"||s==="deadline"||e.layoutComplete===r)return}}async settleMenuAfterUpdate(){if(this.settlerActive)return;this.settlerActive=!0;const e=this.openSessionGeneration,t=()=>e!==this.openSessionGeneration?!0:!this.isConnected||!this.matches(":popover-open")?(this.menuDirty=!1,this.preRenderScrollTop=null,this.pendingItemsChanged=!1,this.retargetingSequence=!1,this.internalPickScrollTop=null,!0):!1;try{for(let r=0;r<10&&this.menuDirty;r+=1){this.menuDirty=!1;try{await this.updateComplete}catch{this.menuDirty=!1;return}if(t())return;const s=this.virtualizerRef.value;if(!s){requestAnimationFrame(()=>{if(t()||this.fullscreenPresentation)return;const h=this.shadowRoot?.querySelector(".status-message");if(h){const m=Math.min(h.scrollHeight,this.maxAvailableHeight);this.style.setProperty("height",`${m}px`)}});continue}if(await this.stableLayout(s),t())return;if(this.menuDirty)continue;const i=this.preRenderScrollTop??0,l=i>0&&!this.pendingItemsChanged&&!this.retargetingSequence;if(s.scrollTop=0,this.sizeToContent(this.maxAvailableHeight),l&&s.scrollTop<i){if(s.scrollTop=i,await this.stableLayout(s),t())return;if(this.menuDirty)continue}const n=this.virtualizedItemsPool;if(n.length===0)continue;if(this.pendingItemsChanged){this.pendingItemsChanged=!1,this.retargetingSequence=!0,this.preRenderScrollTop=null;const h=n.findIndex(m=>m.selected);h>=0?this.highlightIndex=h:this.highlightIndex>=n.length?this.highlightIndex=n.length-1:this.highlightIndex<0&&(this.highlightIndex=0)}if(this.retargetingSequence){try{s.scrollToIndex(this.highlightIndex,"nearest")}catch{}if(await this.stableLayout(s),t())return;if(this.menuDirty)continue}this.applyHighlightWithRetry(3);const o=Math.max(l?i:0,this.internalPickScrollTop??0);if(o>0){if(s.scrollTop<o&&(s.scrollTop=o),await this.stableLayout(s),t())return;if(this.menuDirty)continue;if(await new Promise(h=>requestAnimationFrame(()=>h())),t())return;if(this.menuDirty)continue;s.scrollTop<o&&(s.scrollTop=o)}this.internalPickScrollTop=null,this.preRenderScrollTop=null,this.retargetingSequence=!1}}finally{this.settlerActive=!1,this.menuDirty&&this.settleMenuAfterUpdate()}}sizeToContent(e){if(this.fullscreenPresentation)return;const t=this.measureContentHeight();t>0&&this.style.setProperty("height",`${Math.min(t,e)}px`)}shrinkToFit(e){if(this.fullscreenPresentation)return;const t=this.measureContentHeight();t>2&&t<e&&this.style.setProperty("height",`${t}px`)}measureContentHeight(){const e=this.virtualizerRef.value;if(!e)return 0;const t=e.querySelectorAll("esp-picker-item");if(t.length===0)return 0;const r=getComputedStyle(this),s=(parseFloat(r.borderTopWidth)||0)+(parseFloat(r.borderBottomWidth)||0),i=this.virtualizedItemsPool.length;if(t.length<i)return e.scrollHeight+s;const l=e.scrollTop;e.scrollTop=0;const n=e.getBoundingClientRect(),o=t[t.length-1].getBoundingClientRect();return l>0&&(e.scrollTop=l),o.bottom-n.top+s}widenToFitContent(e){if(this.fullscreenPresentation)return;const t=this.virtualizerRef.value;if(!t)return;const r=t.querySelectorAll("esp-picker-item");let s=e.width;for(const i of r)s=Math.max(s,i.scrollWidth);if(s+=2,s>e.width){const{width:i}=g(),l=Math.min(s,i);this.style.setProperty("width",`${l}px`),this.style.setProperty("left",`${Math.max(0,Math.min(e.left,i-l))}px`)}}updatePosition(e){const t=w(e);if(t&&!t.pickerMenuIsOpen())return;const r=this.fullscreenPresentation,{fullscreen:s,rect:i}=this.syncPresentation(e),l=r!==s;if(l){const p=this.virtualizerRef.value?.scrollTop??0;p>0&&this.preRenderScrollTop===null&&!this.pendingItemsChanged&&!this.retargetingSequence&&(this.preRenderScrollTop=p),this.openSessionGeneration+=1,this.menuDirty=!0}if(!this.matches(":popover-open")){if(!t?.pickerMenuIsOpen())return;try{this.showPopover()}catch{this.menuDirty=!1,this.clearFullscreenTarget(e),this.removeAttribute("data-fullscreen"),this.clearFullscreenGeometry(),this.requestDismiss();return}this.classList.add("visible")}if(l&&this.settleMenuAfterUpdate(),s){this.applyFullscreenGeometry(i),l&&this.classList.add("visible");return}if(r){this.clearFullscreenGeometry(),this.style.setProperty("min-width",`${i.width}px`);const{height:p}=g(),{spaceAbove:I,spaceBelow:d}=x(i,p),P=Math.max(Math.max(I,d)-75,0);this.maxAvailableHeight=P,this.lastViewportHeight=p,this.style.setProperty("height",`${P}px`),this.sizeToContent(P)}const{height:n}=g();if(n!==this.lastViewportHeight){const{spaceAbove:p,spaceBelow:I}=x(i,n),d=Math.max(Math.max(p,I)-75,0);this.maxAvailableHeight=d,this.lastViewportHeight=n,(parseFloat(this.style.getPropertyValue("height"))||0)>d&&this.style.setProperty("height",`${d}px`),this.sizeToContent(d)}const{width:o}=g(),h=this.getBoundingClientRect().width;this.style.setProperty("left",`${Math.max(0,Math.min(i.left,o-h))}px`);const m=i.top,k=n-i.bottom;m>k?(this.style.removeProperty("top"),this.style.setProperty("bottom",`${n-i.top}px`)):(this.style.removeProperty("bottom"),this.style.setProperty("top",`${i.bottom}px`)),l&&this.classList.add("visible")}hideMenu(){this.openSessionGeneration+=1,this.classList.remove("visible"),this.resetSettleState(),this.clearFullscreenTarget(),this.positionTarget=null,this.removeAttribute("data-fullscreen"),this.clearFullscreenGeometry();try{this.hidePopover()}catch{}}resetSettleState(){this.preRenderScrollTop=null,this.pendingItemsChanged=!1,this.retargetingSequence=!1,this.internalPickScrollTop=null,this.menuDirty=!1}disconnectedCallback(){this.hideMenu(),super.disconnectedCallback()}doKeyboardNav(e){const t=this.virtualizedItemsPool;if(t.length!==0)switch(e){case"ArrowDown":this.highlightIndex+=1,this.setHighlight(0);break;case"ArrowUp":this.highlightIndex-=1,this.setHighlight(t.length-1);break;case"Home":this.highlightIndex=0,this.setHighlight(0);break;case"End":this.highlightIndex=t.length-1,this.setHighlight(t.length-1);break;case"Enter":if(this.highlightIndex===-1)return;this.pickItem(t[this.highlightIndex]);break}}render(){let e;return this.loading?e=f`<div class="status-message">Searching…</div>`:this.virtualizedItemsPool.length===0&&this.emptyMessage?e=f`<div class="status-message">${this.emptyMessage}</div>`:e=f`<lit-virtualizer
|
|
13
|
+
${R(this.virtualizerRef)}
|
|
14
14
|
scroller
|
|
15
15
|
.items=${this.virtualizedItemsPool}
|
|
16
16
|
.renderItem=${this.renderPickerItem}
|
|
17
17
|
@pointerdown=${this.handleItemPointerDown}
|
|
18
|
-
@rangeChanged=${t=>{this.dispatchEvent(new CustomEvent(
|
|
19
|
-
></lit-virtualizer>`,
|
|
18
|
+
@rangeChanged=${t=>{this.dispatchEvent(new CustomEvent(y.PICKER_MENU_RANGE_CHANGED,{detail:{first:t.first,last:t.last,items:this.virtualizedItemsPool},bubbles:!0,composed:!0}))}}
|
|
19
|
+
></lit-virtualizer>`,f`<div class="menu-content" @click=${t=>t.stopPropagation()}>
|
|
20
20
|
${e}
|
|
21
|
-
</div>`}};
|
|
21
|
+
</div>`}};c.styles=T`
|
|
22
22
|
:host {
|
|
23
23
|
position: fixed;
|
|
24
24
|
inset: unset;
|
|
@@ -63,7 +63,7 @@ var u=function(a,e,t,r){var s=arguments.length,i=s<3?e:r===null?r=Object.getOwnP
|
|
|
63
63
|
background: var(--esp-color-layer-2);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
@media ${
|
|
66
|
+
@media ${E(z)} {
|
|
67
67
|
:host([data-fullscreen]) {
|
|
68
68
|
display: grid;
|
|
69
69
|
grid-template-rows: var(--_esp-picker-menu-input-bottom, 2.75rem) minmax(0, 1fr);
|
|
@@ -89,4 +89,4 @@ var u=function(a,e,t,r){var s=arguments.length,i=s<3?e:r===null?r=Object.getOwnP
|
|
|
89
89
|
overscroll-behavior: contain;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
`,u([
|
|
92
|
+
`,u([b({type:String})],c.prototype,"label",void 0),u([S()],c.prototype,"virtualizedItemsPool",void 0),u([S()],c.prototype,"highlightIndex",void 0),u([b({attribute:"multi-select",type:Boolean})],c.prototype,"multiSelect",void 0),u([b({type:Boolean})],c.prototype,"loading",void 0),u([b({type:String,attribute:"empty-message"})],c.prototype,"emptyMessage",void 0),c=u([H("esp-picker-menu")],c);export{c as EspalierPickerMenu};
|
|
@@ -30,4 +30,4 @@ export declare function resolveConfiguredBrand({ scheme, brandLogo, brandColor,
|
|
|
30
30
|
* Plain anchors and images are intentional: a brand identity should not gain
|
|
31
31
|
* the interaction chrome of Espalier's application-navigation controls.
|
|
32
32
|
*/
|
|
33
|
-
export declare function renderConfiguredBrand({ brandLogo, brandText, brandHref, brandAlt, }: ConfiguredBrandOptions):
|
|
33
|
+
export declare function renderConfiguredBrand({ brandLogo, brandText, brandHref, brandAlt, }: ConfiguredBrandOptions): import("lit-html").TemplateResult<1> | typeof nothing;
|
package/dist/shared/events.d.ts
CHANGED
|
@@ -269,6 +269,11 @@ export interface EspalierColorPickerEventMap {
|
|
|
269
269
|
export interface EspalierFontPickerEventMap {
|
|
270
270
|
[ESP_EVENTS.VALUE_CHANGED]: CustomEvent<FontPickerValueChangedDetail>;
|
|
271
271
|
}
|
|
272
|
+
/** Events fired by `<esp-image-picker>`. */
|
|
273
|
+
export interface EspalierImagePickerEventMap {
|
|
274
|
+
[ESP_EVENTS.VALUE_CHANGED]: CustomEvent<string>;
|
|
275
|
+
[ESP_EVENTS.VALIDITY_CHANGED]: CustomEvent<ValidityChangedDetail>;
|
|
276
|
+
}
|
|
272
277
|
/** Events fired by `<esp-date-picker>`. */
|
|
273
278
|
export interface EspalierDatePickerEventMap {
|
|
274
279
|
[ESP_EVENTS.VALUE_CHANGED]: CustomEvent<string>;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* None of these functions touch the DOM or network — they operate
|
|
12
12
|
* entirely on data.
|
|
13
13
|
*/
|
|
14
|
-
import type {
|
|
14
|
+
import type { FontPickerFont } from "../font-picker/font-types.js";
|
|
15
15
|
/**
|
|
16
16
|
* Human-readable labels for the nine standard CSS `font-weight`
|
|
17
17
|
* values (100–900).
|
|
@@ -21,18 +21,22 @@ import type { GoogleFont } from "../font-picker/esp-font-picker.js";
|
|
|
21
21
|
*/
|
|
22
22
|
export declare const WEIGHT_LABELS: Readonly<Record<string, string>>;
|
|
23
23
|
/**
|
|
24
|
-
* Extract available non-italic weights from a
|
|
24
|
+
* Extract available non-italic weights from a `GoogleFont`,
|
|
25
25
|
* sorted numerically.
|
|
26
26
|
*
|
|
27
27
|
* Google Fonts encodes weights as variant strings: `"regular"` maps
|
|
28
28
|
* to `"400"`, italic variants (e.g. `"300italic"`) are excluded,
|
|
29
29
|
* and every other variant string is its numeric weight.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
31
|
+
* A device (web-safe) font reports the weights its stack's faces are
|
|
32
|
+
* expected to carry (ESP0206); the platform snaps to the nearest weight it
|
|
33
|
+
* actually has.
|
|
34
|
+
*
|
|
35
|
+
* @param font A Google Font entry, a web-safe font, or `null`.
|
|
32
36
|
* @returns Sorted weight strings. Defaults to `["400"]` when the
|
|
33
37
|
* font is `null` or has no non-italic variants.
|
|
34
38
|
*/
|
|
35
|
-
export declare function extractWeights(font:
|
|
39
|
+
export declare function extractWeights(font: FontPickerFont | null): string[];
|
|
36
40
|
/**
|
|
37
41
|
* Normalize a CSS `font-weight` keyword to its numeric equivalent.
|
|
38
42
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{webSafeFontWeights as l}from"./font-stacks.js";const g={100:"100 Thin",200:"200 Extra Light",300:"300 Light",400:"400 Regular",500:"500 Medium",600:"600 Semi Bold",700:"700 Bold",800:"800 Extra Bold",900:"900 Black"},f=e=>e.kind==="web-safe";function p(e){if(!e)return["400"];if(f(e))return l(e);const t=new Set;for(const r of e.variants)r.includes("italic")||t.add(r==="regular"?"400":r);const n=[...t].sort((r,i)=>Number(r)-Number(i));return n.length>0?n:["400"]}function b(e,t){return e?e==="bold"?"700":e==="normal"?"400":e:t}function u(e,t){const n=e===void 0||e===""?t:e;if(n===void 0)return null;if(typeof n=="number")return Number.isInteger(n)&&n>=1&&n<=1e3?n:null;const r=n.trim().toLowerCase();if(r==="normal")return 400;if(r==="bold")return 700;if(!/^\d{1,4}$/.test(r))return null;const i=Number(r);return Number.isInteger(i)&&i>=1&&i<=1e3?i:null}function x(e,t){if(t.length===0)return"400";if(t.includes(e))return e;const n=Number(e);let r=t[0],i=Math.abs(Number(r)-n);for(const s of t){const o=Math.abs(Number(s)-n);o<i&&(r=s,i=o)}return r}function y(e){let t="",n="",r=!1,i=0;for(const o of e.trim()){if(r){t+=o,r=!1;continue}if(o==="\\"){t+=o,r=!0;continue}if(n){t+=o,o===n&&(n="");continue}if(o==='"'||o==="'"){t+=o,n=o;continue}if(o==="("&&(i+=1),o===")"&&(i=Math.max(0,i-1)),o===","&&i===0)break;t+=o}const s=t.trim();return s.length>=2&&(s.startsWith('"')&&s.endsWith('"')||s.startsWith("'")&&s.endsWith("'"))?s.slice(1,-1).replace(/\\([\\"'])/g,"$1"):s}const m=new Set(["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-serif","ui-sans-serif","ui-monospace","ui-rounded","math","fangsong","-apple-system","blinkmacsystemfont","arial","helvetica","helvetica neue","liberation sans","liberation serif","liberation mono","verdana","tahoma","trebuchet ms","georgia","times new roman","courier new","segoe ui"].map(e=>e.toLowerCase()));function F(e){return m.has(e.trim().toLowerCase())}function W(e){switch(e){case"serif":return"serif";case"monospace":return"monospace";case"handwriting":return"cursive";default:return"sans-serif"}}const a="data-esp-google-font-owner";function d(e,t){const n=u(t,400)??400,r=n!==400?`:wght@${n}`:"";return`https://fonts.googleapis.com/css2?family=${encodeURIComponent(e)}${r}&display=swap`}function c(e){return document.head.querySelector(`link[${a}="${CSS.escape(e)}"]`)}function w(e){const t=c(e.owner),n=e.family.trim(),r=String(u(e.weight,400)??400);if(e.enabled===!1||!n)return t?.remove(),null;if(t?.dataset.espFamily===n&&t.dataset.espWeight===r)return t;t?.remove();const i=document.createElement("link");i.rel="stylesheet",i.href=d(n,r),i.setAttribute(a,e.owner),i.dataset.espFamily=n,i.dataset.espWeight=r;for(const[s,o]of Object.entries(e.attributes??{}))i.setAttribute(s,o);return document.head.appendChild(i),i}function L(e){c(e)?.remove()}function k(e){for(const t of document.head.querySelectorAll(`link[${a}]`))t.getAttribute(a)?.startsWith(e)&&t.remove()}export{a as RUNTIME_GOOGLE_FONT_OWNER_ATTR,g as WEIGHT_LABELS,x as bestAvailableWeight,y as extractFamily,p as extractWeights,W as getFallbackFont,d as googleFontStylesheetUrl,F as isLocalFontFamily,u as normalizeFontFaceWeight,b as normalizeWeight,L as removeRuntimeGoogleFontLink,k as removeRuntimeGoogleFontLinks,w as syncRuntimeGoogleFontLink};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module font-stacks
|
|
3
|
+
*
|
|
4
|
+
* Recognize device (web-safe) CSS font stacks (ESP0206).
|
|
5
|
+
*
|
|
6
|
+
* A stored theme may carry a stack that is equivalent to one of the picker's
|
|
7
|
+
* presets without being byte-identical — `system-ui, -apple-system,
|
|
8
|
+
* BlinkMacSystemFont, "Segoe UI", sans-serif` is the same choice as the
|
|
9
|
+
* System Sans preset. These helpers canonicalize a stack, map it to the
|
|
10
|
+
* preset its leading family implies, and describe a stack that matches no
|
|
11
|
+
* preset, so a picker can show the right selection without rewriting what
|
|
12
|
+
* the theme stores. Pure data; no DOM or network.
|
|
13
|
+
*/
|
|
14
|
+
import { type WebSafeCategory, type WebSafeFont } from "../font-picker/font-types.js";
|
|
15
|
+
/**
|
|
16
|
+
* Split a CSS `font-family` value into its families, unquoted, trimmed, and
|
|
17
|
+
* lowercased, respecting quotes and escapes. Empty entries are dropped.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* parseFontStack('system-ui, "Segoe UI", sans-serif');
|
|
21
|
+
* // ["system-ui", "segoe ui", "sans-serif"]
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseFontStack(stack: string): string[];
|
|
25
|
+
/** The canonical, comparable form of a stack: its parsed families joined. */
|
|
26
|
+
export declare function canonicalFontStack(stack: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* The category a stack implies: the last generic keyword it names, else the
|
|
29
|
+
* category of its leading family when that family identifies a preset, else
|
|
30
|
+
* `null` for a stack this module knows nothing about.
|
|
31
|
+
*/
|
|
32
|
+
export declare function classifyFontStack(stack: string): WebSafeCategory | null;
|
|
33
|
+
/**
|
|
34
|
+
* Whether a stack resolves to device faces: its leading family is a generic
|
|
35
|
+
* keyword, a platform UI face, or a conventional web-safe face. A stack that
|
|
36
|
+
* leads with a downloadable family (`Roboto, system-ui, sans-serif`) is not
|
|
37
|
+
* a device stack even though it falls back to one.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isDeviceFontStack(stack: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* The preset a stored stack is equivalent to, or `null`.
|
|
42
|
+
*
|
|
43
|
+
* An exact canonical match wins; otherwise the leading family decides, so
|
|
44
|
+
* `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`
|
|
45
|
+
* maps to System Sans and `ui-monospace, "SFMono-Regular", Consolas,
|
|
46
|
+
* monospace` to System Monospace. The returned preset is the catalog entry
|
|
47
|
+
* itself; callers keep the stored stack and only use the preset for display.
|
|
48
|
+
*/
|
|
49
|
+
export declare function matchWebSafeFont(stack: string, fonts?: ReadonlyArray<WebSafeFont>): WebSafeFont | null;
|
|
50
|
+
/**
|
|
51
|
+
* Describe a device stack that matches no preset so a picker can still show
|
|
52
|
+
* it as selected: the stack is both the label and the value, the category
|
|
53
|
+
* follows its generic, and the weights follow its leading family. Returns
|
|
54
|
+
* `null` for an empty stack.
|
|
55
|
+
*/
|
|
56
|
+
export declare function customWebSafeFont(stack: string): WebSafeFont | null;
|
|
57
|
+
/** Numeric weights a device font offers; see {@link WebSafeFont.weights}. */
|
|
58
|
+
export declare function webSafeFontWeights(font: WebSafeFont): string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DEVICE_DEFAULT_WEIGHTS as f,SYSTEM_TEXT_WEIGHTS as m,WEB_SAFE_FONTS as l}from"../font-picker/font-types.js";const p={serif:"serif","sans-serif":"sans-serif",monospace:"monospace","system-ui":"sans-serif","ui-serif":"serif","ui-sans-serif":"sans-serif","ui-monospace":"monospace","ui-rounded":"sans-serif"},c=[["System Sans",["system-ui","-apple-system","blinkmacsystemfont","ui-sans-serif","ui-rounded","segoe ui","sans-serif"]],["System Serif",["ui-serif","cambria","charter","iowan old style","serif"]],["System Monospace",["ui-monospace","sfmono-regular","sf mono","menlo","monaco","consolas","liberation mono","cascadia code","cascadia mono","monospace"]],["Arial / Helvetica",["arial","helvetica","helvetica neue","liberation sans"]],["Georgia / Times New Roman",["georgia","times new roman","times","liberation serif"]],["Verdana / Geneva",["verdana","geneva"]],["Tahoma / Geneva",["tahoma"]],["Trebuchet MS",["trebuchet ms"]],["Courier New",["courier new","courier"]]],S=new Set([...c[0][1],...c[1][1]]);function h(n){const e=n.trim();return e.length>=2&&(e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"))?e.slice(1,-1).replace(/\\([\\"'])/g,"$1"):e}function o(n){const e=[];let t="",s="",r=!1;for(const i of n){if(r){t+=i,r=!1;continue}if(i==="\\"){t+=i,r=!0;continue}if(s){t+=i,i===s&&(s="");continue}if(i==='"'||i==="'"){t+=i,s=i;continue}if(i===","){e.push(t),t="";continue}t+=i}return e.push(t),e.map(i=>h(i).replace(/\s+/g," ").toLowerCase()).filter(i=>i.length>0)}function d(n){return o(n).join(", ")}function g(n){const e=o(n);for(let s=e.length-1;s>=0;s-=1){const r=p[e[s]];if(r)return r}const t=u(e[0]);return t?l.find(s=>s.family===t)?.category??null:null}function u(n){if(!n)return null;for(const[e,t]of c)if(t.includes(n))return e;return null}function y(n){return u(o(n)[0])!==null}function F(n,e=l){const t=o(n);if(t.length===0)return null;const s=t.join(", "),r=e.find(a=>d(a.stack)===s);if(r)return r;const i=u(t[0]);return i?e.find(a=>a.family===i)??null:null}function T(n){const e=o(n);if(e.length===0)return null;const t=g(n)??"sans-serif",s=t!=="monospace"&&S.has(e[0])?[...m]:[...f];return{family:n.trim(),stack:n.trim(),category:t,kind:"web-safe",weights:s}}function _(n){return[...n.weights??f]}export{d as canonicalFontStack,g as classifyFontStack,T as customWebSafeFont,y as isDeviceFontStack,F as matchWebSafeFont,o as parseFontStack,_ as webSafeFontWeights};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getEspBus as c}from"./bus-events.js";import{RafThrottle as h}from"./raf-throttle.js";function
|
|
1
|
+
import{getEspBus as c}from"./bus-events.js";import{RafThrottle as h}from"./raf-throttle.js";function l(r,t){let e=t;for(;e;){if(e===r)return!0;e=e instanceof ShadowRoot?e.host:e.parentNode}return!1}function d(r){const t=[],e=new Set;let s=r;for(;s&&!e.has(s);){e.add(s);const i=s["linked-popover"];if(i){s=i;continue}const o=s.closest("esp-popover");if(o){t.includes(o)||t.push(o),s=o.parentElement||o.getRootNode()?.host;continue}const n=s.getRootNode();s=n instanceof ShadowRoot?n.host:void 0}return t}class a{constructor(t){this.bus=c(),this.positionFrame=new h(()=>this.runPositionUpdate()),this.positionResizeObserver=null,this.trackingPosition=!1,this.handleClosePopovers=e=>{if(!this.opts.isOpen())return;const s=this.opts.host;if(this.opts.closeStrategy==="source-identity"){if(!e.source||e.source===s||e.source instanceof Node&&l(s,e.source))return}else if(e.skipPopovers?.includes(s))return;this.opts.onShouldClose()},this.onScrollOrResize=()=>this.positionFrame.schedule(),this.onDocumentClick=e=>{const s=this.opts.host,i=e.composedPath();if(i.includes(s))return;const o=this.opts.getInsideElements?.()??[];for(const n of o)if(n&&i.includes(n))return;this.opts.isOpen()&&this.opts.onOutsideClick?.()},this.opts=t,t.host.addController(this)}hostConnected(){this.bus.subscribe("close-popovers",this.handleClosePopovers)}hostDisconnected(){this.bus.unsubscribe("close-popovers",this.handleClosePopovers),this.stopTracking(),this.stopOutsideClick()}runPositionUpdate(){if(this.opts.isOpen()){if(this.opts.shouldContinueTracking&&!this.opts.shouldContinueTracking()){this.opts.onShouldClose();return}this.opts.onPositionUpdate?.()}}startTracking(){this.opts.onPositionUpdate&&(this.trackingPosition=!0,window.addEventListener("scroll",this.onScrollOrResize,{capture:!0,passive:!0}),window.addEventListener("resize",this.onScrollOrResize,{passive:!0}),this.refreshPositionElements())}refreshPositionElements(){if(this.positionResizeObserver?.disconnect(),this.positionResizeObserver=null,!this.trackingPosition||!this.opts.getPositionElements||typeof ResizeObserver>"u")return;const t=new Set(this.opts.getPositionElements().filter(Boolean));if(t.size!==0){this.positionResizeObserver=new ResizeObserver(this.onScrollOrResize);for(const e of t)this.positionResizeObserver.observe(e)}}stopTracking(){this.trackingPosition=!1,window.removeEventListener("scroll",this.onScrollOrResize,{capture:!0}),window.removeEventListener("resize",this.onScrollOrResize),this.positionResizeObserver?.disconnect(),this.positionResizeObserver=null,this.positionFrame.cancel()}startOutsideClick(){this.opts.onOutsideClick&&document.addEventListener("click",this.onDocumentClick,!0)}stopOutsideClick(){document.removeEventListener("click",this.onDocumentClick,!0)}publishCloseOthers(t=[]){this.bus.publish("close-popovers",{source:this.opts.host,...t.length>0?{skipPopovers:t}:{}})}}export{a as PopoverController,d as findContainingPopovers,l as isComposedDescendant};
|
package/espalier.css-data.json
CHANGED
|
@@ -1009,6 +1009,18 @@
|
|
|
1009
1009
|
"name": "--esp-image-overlay-text-shadow",
|
|
1010
1010
|
"description": "Overlay text shadow; defaults to a soft polarity-matched halo. Set to `none` to disable."
|
|
1011
1011
|
},
|
|
1012
|
+
{
|
|
1013
|
+
"name": "--esp-image-picker-option-height",
|
|
1014
|
+
"description": "Height of dropdown images. Images retain their aspect ratio. Default 8rem."
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
"name": "--esp-image-picker-option-width",
|
|
1018
|
+
"description": "Width of dropdown images, capped at 40vw on narrow screens. Default 12rem."
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
"name": "--esp-image-picker-preview-height",
|
|
1022
|
+
"description": "Height of the large preview above the control. Default 16rem."
|
|
1023
|
+
},
|
|
1012
1024
|
{
|
|
1013
1025
|
"name": "--esp-image-preview-border-color",
|
|
1014
1026
|
"description": "The border color of the preview."
|
|
@@ -1161,6 +1173,14 @@
|
|
|
1161
1173
|
"name": "--esp-menu-drawer-item-font-size",
|
|
1162
1174
|
"description": "Item label size in the full-screen drawer. Defaults to `var(--esp-type-large)`."
|
|
1163
1175
|
},
|
|
1176
|
+
{
|
|
1177
|
+
"name": "--esp-menu-drawer-nested-item-max-font-size",
|
|
1178
|
+
"description": "Largest size for labels nested inside a group in the full-screen drawer; the measured fit starts here. Defaults to `calc(0.9 * var(--esp-menu-drawer-item-font-size, var(--esp-type-large)))`."
|
|
1179
|
+
},
|
|
1180
|
+
{
|
|
1181
|
+
"name": "--esp-menu-drawer-nested-item-min-font-size",
|
|
1182
|
+
"description": "Smallest size nested full-screen drawer labels shrink to before they wrap. Defaults to `max(14px, 0.875rem)`: above the ~12-13px critical print size at phone distance (Legge & Bigelow, 2011) and Material's 14sp body minimum, and it rises with a larger default font."
|
|
1183
|
+
},
|
|
1164
1184
|
{
|
|
1165
1185
|
"name": "--esp-menu-drawer-shadow",
|
|
1166
1186
|
"description": "Box shadow for the drawer overlay."
|
|
@@ -1428,6 +1428,24 @@
|
|
|
1428
1428
|
"component": "esp-image",
|
|
1429
1429
|
"description": "Overlay text shadow; defaults to a soft polarity-matched halo. Set to `none` to disable."
|
|
1430
1430
|
},
|
|
1431
|
+
{
|
|
1432
|
+
"name": "--esp-image-picker-option-height",
|
|
1433
|
+
"category": "component",
|
|
1434
|
+
"component": "esp-image-picker",
|
|
1435
|
+
"description": "Height of dropdown images. Images retain their aspect ratio. Default 8rem."
|
|
1436
|
+
},
|
|
1437
|
+
{
|
|
1438
|
+
"name": "--esp-image-picker-option-width",
|
|
1439
|
+
"category": "component",
|
|
1440
|
+
"component": "esp-image-picker",
|
|
1441
|
+
"description": "Width of dropdown images, capped at 40vw on narrow screens. Default 12rem."
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
"name": "--esp-image-picker-preview-height",
|
|
1445
|
+
"category": "component",
|
|
1446
|
+
"component": "esp-image-picker",
|
|
1447
|
+
"description": "Height of the large preview above the control. Default 16rem."
|
|
1448
|
+
},
|
|
1431
1449
|
{
|
|
1432
1450
|
"name": "--esp-image-preview-border-color",
|
|
1433
1451
|
"category": "component",
|
|
@@ -1643,6 +1661,18 @@
|
|
|
1643
1661
|
"component": "esp-menu",
|
|
1644
1662
|
"description": "Item label size in the full-screen drawer. Defaults to `var(--esp-type-large)`."
|
|
1645
1663
|
},
|
|
1664
|
+
{
|
|
1665
|
+
"name": "--esp-menu-drawer-nested-item-max-font-size",
|
|
1666
|
+
"category": "component",
|
|
1667
|
+
"component": "esp-menu",
|
|
1668
|
+
"description": "Largest size for labels nested inside a group in the full-screen drawer; the measured fit starts here. Defaults to `calc(0.9 * var(--esp-menu-drawer-item-font-size, var(--esp-type-large)))`."
|
|
1669
|
+
},
|
|
1670
|
+
{
|
|
1671
|
+
"name": "--esp-menu-drawer-nested-item-min-font-size",
|
|
1672
|
+
"category": "component",
|
|
1673
|
+
"component": "esp-menu",
|
|
1674
|
+
"description": "Smallest size nested full-screen drawer labels shrink to before they wrap. Defaults to `max(14px, 0.875rem)`: above the ~12-13px critical print size at phone distance (Legge & Bigelow, 2011) and Material's 14sp body minimum, and it rises with a larger default font."
|
|
1675
|
+
},
|
|
1646
1676
|
{
|
|
1647
1677
|
"name": "--esp-menu-drawer-shadow",
|
|
1648
1678
|
"category": "component",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/espalier",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.13.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",
|
|
@@ -157,6 +157,10 @@
|
|
|
157
157
|
"types": "./dist/image-upload/esp-image-upload.d.ts",
|
|
158
158
|
"import": "./dist/image-upload/esp-image-upload.js"
|
|
159
159
|
},
|
|
160
|
+
"./image-picker": {
|
|
161
|
+
"types": "./dist/image-picker/esp-image-picker.d.ts",
|
|
162
|
+
"import": "./dist/image-picker/esp-image-picker.js"
|
|
163
|
+
},
|
|
160
164
|
"./image-upload/helpers": {
|
|
161
165
|
"types": "./dist/image-upload/image-helpers.d.ts",
|
|
162
166
|
"import": "./dist/image-upload/image-helpers.js"
|