@taprootio/espalier 2.13.1 → 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/custom-elements.json +7051 -5344
  3. package/dist/date-picker/esp-date-picker.js +22 -22
  4. package/dist/flyout/esp-flyout.js +14 -14
  5. package/dist/font-picker/esp-font-picker.js +3 -3
  6. package/dist/form/esp-form.js +1 -1
  7. package/dist/grid/esp-grid.d.ts +4 -12
  8. package/dist/grid/esp-grid.js +5 -5
  9. package/dist/header/esp-header.js +7 -7
  10. package/dist/lightbox/esp-lightbox.js +16 -16
  11. package/dist/page/esp-page.d.ts +27 -14
  12. package/dist/page/esp-page.js +85 -33
  13. package/dist/page/workspace-width.js +1 -0
  14. package/dist/pickers/esp-pick-one.d.ts +9 -30
  15. package/dist/pickers/esp-pick-one.js +18 -50
  16. package/dist/pickers/esp-pick-some.d.ts +4 -29
  17. package/dist/pickers/esp-pick-some.js +15 -42
  18. package/dist/pickers/esp-picker-base.d.ts +95 -0
  19. package/dist/pickers/esp-picker-base.js +33 -1
  20. package/dist/pickers/esp-picker-menu.d.ts +0 -2
  21. package/dist/pickers/esp-picker-menu.js +6 -6
  22. package/dist/pickers/pick-one-selection.js +1 -0
  23. package/dist/popover/esp-popover.js +6 -6
  24. package/dist/repeater/esp-repeater.d.ts +11 -8
  25. package/dist/repeater/esp-repeater.js +4 -4
  26. package/dist/shared/color-engine.js +1 -1
  27. package/dist/shared/cursor-pagination.d.ts +76 -0
  28. package/dist/shared/cursor-pagination.js +1 -0
  29. package/dist/shared/intent-values.d.ts +13 -2
  30. package/dist/shared/intent-values.js +1 -1
  31. package/dist/shared/popover-controller.js +1 -1
  32. package/dist/shared/raf-throttle.js +1 -0
  33. package/dist/shared/utilities.d.ts +27 -27
  34. package/dist/shared/utilities.js +1 -1
  35. package/dist/shared/viewport.d.ts +89 -0
  36. package/dist/shared/viewport.js +1 -0
  37. package/package.json +9 -1
  38. package/dist/header/esp-menu-group.js +0 -1
  39. package/dist/header/esp-menu-item.js +0 -1
  40. package/dist/header/esp-menu.js +0 -1
@@ -1,4 +1,4 @@
1
- var l=function(y,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(y,e,t,i);else for(var g=y.length-1;g>=0;g--)(o=y[g])&&(s=(r<3?o(s):r>3?o(e,t,s):o(e,t))||s);return r>3&&s&&Object.defineProperty(e,t,s),s};import{css as T,html as d,nothing as I}from"lit";import{customElement as F,property as h,state as b}from"lit/decorators.js";import{keyed as j}from"lit/directives/keyed.js";import{ifDefined as M}from"lit/directives/if-defined.js";import{createRef as G,ref as O}from"lit/directives/ref.js";import{styleMap as A}from"lit/directives/style-map.js";import{EspalierElementBase as E}from"../shared/esp-element-base.js";import"../shared/virtualizer/lit-virtualizer.js";let a=class extends E{constructor(){super(...arguments),this.virtualizerRef=G(),this.containerRef=G(),this.pageLoadVersion=0,this.nextCursor=null,this.lastObservedWidth=0,this.observersAttached=!1,this.gridObserversAttached=!1,this.resolvedGridColumns=1,this.memoizedGridRowsSource=null,this.memoizedGridRowsColumns=0,this.memoizedGridRows=[],this.hostAttributeObserver=null,this.resizeObserver=null,this.viewportResizeListener=null,this.pageScrollStabilizerActive=!1,this.activePageScrollStabilizer=null,this.isAdjustingHeight=!1,this.pendingHeightRetry=!1,this.heightRetryObserver=null,this.isLoadingPage=!1,this.loadedItems=[],this.hasMoreData=!1,this.effectiveListHeight="60vh",this.loadError="",this.items=[],this.renderItem=null,this.layout="list",this.scrollModel="contained",this.gridColumns=1,this.ariaLabel=null,this.listHeight="60vh",this.pageSize=25,this.prefetchThreshold=5,this.loading=!1,this.loadingMessage="Loading items\u2026",this.emptyMessage="No items found",this.errorMessage="",this.fetchPageBacker=null,this.renderVirtualItem=(e,t)=>{if(e===void 0)return d``;const i=this.renderItem??(r=>this.renderFallbackItem(r));return d`<div class="repeater-item" part="item" role="listitem">
1
+ var l=function(y,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(y,e,t,i);else for(var g=y.length-1;g>=0;g--)(a=y[g])&&(s=(r<3?a(s):r>3?a(e,t,s):a(e,t))||s);return r>3&&s&&Object.defineProperty(e,t,s),s};import{css as V,html as d,nothing as I}from"lit";import{customElement as F,property as h,state as b}from"lit/decorators.js";import{keyed as j}from"lit/directives/keyed.js";import{ifDefined as M}from"lit/directives/if-defined.js";import{createRef as G,ref as O}from"lit/directives/ref.js";import{styleMap as A}from"lit/directives/style-map.js";import{EspalierElementBase as E}from"../shared/esp-element-base.js";import{accumulatePage as N,RequestVersionGuard as B}from"../shared/cursor-pagination.js";import"../shared/virtualizer/lit-virtualizer.js";let o=class extends E{constructor(){super(...arguments),this.virtualizerRef=G(),this.containerRef=G(),this.pageLoads=new B,this.nextCursor=null,this.lastObservedWidth=0,this.observersAttached=!1,this.gridObserversAttached=!1,this.resolvedGridColumns=1,this.memoizedGridRowsSource=null,this.memoizedGridRowsColumns=0,this.memoizedGridRows=[],this.hostAttributeObserver=null,this.resizeObserver=null,this.viewportResizeListener=null,this.pageScrollStabilizerActive=!1,this.activePageScrollStabilizer=null,this.isAdjustingHeight=!1,this.pendingHeightRetry=!1,this.heightRetryObserver=null,this.isLoadingPage=!1,this.loadedItems=[],this.hasMoreData=!1,this.effectiveListHeight="60vh",this.loadError="",this.items=[],this.renderItem=null,this.layout="list",this.scrollModel="contained",this.gridColumns=1,this.ariaLabel=null,this.listHeight="60vh",this.pageSize=25,this.prefetchThreshold=5,this.loading=!1,this.loadingMessage="Loading items\u2026",this.emptyMessage="No items found",this.errorMessage="",this.fetchPageBacker=null,this.renderVirtualItem=(e,t)=>{if(e===void 0)return d``;const i=this.renderItem??(r=>this.renderFallbackItem(r));return d`<div class="repeater-item" part="item" role="listitem">
2
2
  ${i(e,t)}
3
3
  </div>`},this.renderVirtualRow=e=>{if(e===void 0)return d``;const t=this.renderItem??(r=>this.renderFallbackItem(r)),i={gridTemplateColumns:`repeat(${this.effectiveGridColumns}, minmax(0, 1fr))`};return d`<div
4
4
  class="repeater-row"
@@ -9,7 +9,7 @@ var l=function(y,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
9
9
  ${e.items.map((r,s)=>d`<div class="repeater-item repeater-grid-cell" part="item" role="listitem">
10
10
  ${t(r,e.startIndex+s)}
11
11
  </div>`)}
12
- </div>`},this.renderGridVirtualItem=(e,t)=>this.isGridRow(e)?this.renderVirtualRow(e,t):d``}get fetchPage(){return this.fetchPageBacker}set fetchPage(e){const t=this.fetchPageBacker;t!==e&&(this.fetchPageBacker=e,this.requestUpdate("fetchPage",t),this.resetPagedState(),e&&this.hasUpdated&&this.startPagedLoad(null))}get isPagedMode(){return this.fetchPage!==null}get isGridLayout(){return this.layout==="grid"}get isPageScrollModel(){return this.scrollModel==="page"}get isContainedScrollModel(){return!this.isPageScrollModel}get renderedItems(){return this.isPagedMode?this.loadedItems:this.items}get virtualizerItems(){return this.isGridLayout?this.buildGridRows(this.renderedItems,this.effectiveGridColumns):this.renderedItems}get isBusy(){return this.loading||this.isLoadingPage}get activeErrorMessage(){return this.errorMessage||this.loadError}get normalizedPageSize(){const e=Number(this.pageSize);return Number.isFinite(e)&&e>0?Math.floor(e):25}get normalizedPrefetchThreshold(){const e=Number(this.prefetchThreshold);return Number.isFinite(e)&&e>0?Math.floor(e):1}get normalizedGridColumns(){const e=Number(this.gridColumns);return Number.isFinite(e)&&e>0?Math.floor(e):1}get effectiveGridColumns(){return this.isGridLayout?this.resolvedGridColumns:1}connectedCallback(){super.connectedCallback(),this.attachObservers(),this.lastObservedWidth=this.clientWidth,this.syncResolvedGridColumns(),this.hasUpdated&&this.isContainedScrollModel&&this.adjustListHeight()}firstUpdated(e){if(super.firstUpdated(e),this.lastObservedWidth=this.clientWidth,this.fetchPage){this.startPagedLoad(null);return}this.adjustListHeight()}disconnectedCallback(){this.releaseActivePageScrollStabilizer(),this.heightRetryObserver?.disconnect(),this.heightRetryObserver=null,this.pendingHeightRetry=!1,this.detachObservers(),super.disconnectedCallback()}willUpdate(e){super.willUpdate(e),(e.has("layout")||e.has("gridColumns"))&&this.syncResolvedGridColumns()}updated(e){super.updated(e),e.has("layout")&&this.syncGridObservers(),(e.has("items")||e.has("loadedItems")||e.has("listHeight")||e.has("layout")||e.has("gridColumns")||e.has("scrollModel"))&&this.adjustListHeight()}parsePositiveIntegerToken(e){const t=Number(e.trim());return Number.isFinite(t)&&t>0?Math.floor(t):null}attachObservers(){this.observersAttached||(this.observersAttached=!0,this.getResizeObserver().observe(this),this.syncGridObservers())}detachObservers(){this.observersAttached&&(this.observersAttached=!1,this.detachGridObservers(),this.resizeObserver?.disconnect())}syncGridObservers(){if(this.observersAttached){if(!this.isGridLayout){this.detachGridObservers();return}this.gridObserversAttached||(this.gridObserversAttached=!0,this.getHostAttributeObserver().observe(this,{attributes:!0,attributeFilter:["class","style"]}),window.addEventListener("resize",this.getViewportResizeListener()))}}detachGridObservers(){if(!this.gridObserversAttached)return;this.gridObserversAttached=!1,this.hostAttributeObserver?.disconnect();const e=this.viewportResizeListener;e&&window.removeEventListener("resize",e)}getHostAttributeObserver(){return this.hostAttributeObserver||(this.hostAttributeObserver=new MutationObserver(()=>{this.refreshResolvedGridColumns()})),this.hostAttributeObserver}getResizeObserver(){return this.resizeObserver||(this.resizeObserver=new ResizeObserver(()=>{const e=this.clientWidth,t=e!==this.lastObservedWidth;this.lastObservedWidth=e;const i=this.isGridLayout?this.refreshResolvedGridColumns():!1;t&&!i&&this.isContainedScrollModel&&this.adjustListHeight()})),this.resizeObserver}getViewportResizeListener(){return this.viewportResizeListener||(this.viewportResizeListener=()=>{this.refreshResolvedGridColumns()}),this.viewportResizeListener}syncResolvedGridColumns(){this.resolvedGridColumns=this.isGridLayout?this.readResolvedGridColumns():1}readResolvedGridColumns(){return!this.isGridLayout||!this.isConnected?this.normalizedGridColumns:this.parsePositiveIntegerToken(getComputedStyle(this).getPropertyValue("--esp-repeater-grid-columns"))??this.normalizedGridColumns}refreshResolvedGridColumns(){if(!this.isGridLayout)return!1;const e=this.readResolvedGridColumns();return e===this.resolvedGridColumns?!1:(this.resolvedGridColumns=e,this.hasUpdated&&(this.requestUpdate(),this.adjustListHeight()),!0)}buildGridRows(e,t){if(this.memoizedGridRowsSource===e&&this.memoizedGridRowsColumns===t)return this.memoizedGridRows;const i=[];for(let r=0;r<e.length;r+=t)i.push({items:e.slice(r,r+t),startIndex:r});return this.memoizedGridRowsSource=e,this.memoizedGridRowsColumns=t,this.memoizedGridRows=i,i}isGridRow(e){return e!==null&&typeof e=="object"&&Array.isArray(e.items)&&typeof e.startIndex=="number"}renderFallbackItem(e){if(typeof e=="string"||typeof e=="number"||typeof e=="boolean")return String(e);let t="";try{t=JSON.stringify(e,null,2)??this.describeFallbackItem(e)}catch{t=this.describeFallbackItem(e)}return d`<pre>${t}</pre>`}describeFallbackItem(e){try{return String(e)}catch{return"Unrenderable item"}}async startPagedLoad(e){if(!this.fetchPage||this.isLoadingPage)return;const t=this.capturePageScrollTop(e);this.isLoadingPage=!0,await this.loadPage(e,t)}async loadPage(e,t){const i=this.fetchPage;if(!i)return;const r=++this.pageLoadVersion,s=this.activatePageScrollStabilizer(t,r);this.activePageScrollStabilizer=s;try{const o=await i({cursor:e,limit:this.normalizedPageSize});if(r!==this.pageLoadVersion)return;e===null?this.loadedItems=[...o.items]:this.loadedItems=[...this.loadedItems,...o.items],this.nextCursor=o.nextCursor,this.hasMoreData=o.nextCursor!==null,this.loadError=""}catch(o){if(r!==this.pageLoadVersion)return;this.nextCursor=null,this.hasMoreData=!1,this.loadError=o instanceof Error&&o.message.length>0?o.message:"Unable to load items."}finally{try{r===this.pageLoadVersion&&(this.isLoadingPage=!1),r===this.pageLoadVersion&&await this.restorePageScrollPositionIfNeeded(s.getRestoreScrollTop(),r)}finally{this.activePageScrollStabilizer===s&&this.releaseActivePageScrollStabilizer()}}}capturePageScrollTop(e){return!this.isPageScrollModel||e===null?null:window.scrollY}activatePageScrollStabilizer(e,t){if(e===null||!this.isPageScrollModel||t!==this.pageLoadVersion)return{release:()=>{},getRestoreScrollTop:()=>e};this.pageScrollStabilizerActive=!0;const i=this.getVirtualizerElement(),r=i?.getBoundingClientRect().height??0,s=this.activePageScrollStabilizer;s&&(this.activePageScrollStabilizer=null,s.release(),this.pageScrollStabilizerActive=!0),i&&r>0&&(i.style.minHeight=`${r}px`);const o="",g=r>0?Math.max(64,r*.5):Number.POSITIVE_INFINITY;let u=e,p=window.scrollY;const m=()=>{if(t!==this.pageLoadVersion)return;const c=window.scrollY;if(c>u+1){u=c,p=c;return}if(c+1>=u){p=c;return}const z=c<=1,v=p+1>=u&&p-c>=g;if(!z&&!v){u=c,p=c;return}window.scrollTo({top:u,left:window.scrollX,behavior:"auto"}),p=u};return window.addEventListener("scroll",m,{passive:!0}),{getRestoreScrollTop:()=>u,release:()=>{window.removeEventListener("scroll",m),this.pageScrollStabilizerActive=!1,i&&(i.style.minHeight=o)}}}async restorePageScrollPositionIfNeeded(e,t){if(e===null||!this.isPageScrollModel||t!==this.pageLoadVersion)return;await this.updateComplete;const i=this.getVirtualizerElement();i?.updateComplete&&await i.updateComplete,await new Promise(r=>requestAnimationFrame(r)),i?.layoutComplete&&await i.layoutComplete,t===this.pageLoadVersion&&window.scrollY+1<e&&window.scrollTo({top:e,left:window.scrollX,behavior:"auto"})}onRangeChanged(e){if(!this.isPagedMode||this.activeErrorMessage.length>0||!this.hasMoreData||this.isLoadingPage||this.nextCursor===null)return;const t=this.normalizedPrefetchThreshold;this.getLastVisibleItemIndex(e.last)>=this.loadedItems.length-t&&this.startPagedLoad(this.nextCursor)}getLastVisibleItemIndex(e){return this.isGridLayout?Math.min((e+1)*this.effectiveGridColumns-1,this.renderedItems.length-1):e}resetPagedState(){this.releaseActivePageScrollStabilizer(),this.pageLoadVersion+=1,this.isLoadingPage=!1,this.loadedItems=[],this.nextCursor=null,this.hasMoreData=!1,this.loadError=""}releaseActivePageScrollStabilizer(){const e=this.activePageScrollStabilizer;if(this.activePageScrollStabilizer=null,!e){this.pageScrollStabilizerActive=!1;return}e.release(),this.adjustListHeight()}async adjustListHeight(){if(!this.isContainedScrollModel){const e=this.getVirtualizerElement();e&&!this.pageScrollStabilizerActive&&(e.style.minHeight="");return}if(!this.isAdjustingHeight){this.isAdjustingHeight=!0;try{this.effectiveListHeight=this.listHeight;const e=this.getVirtualizerElement();e&&(e.style.minHeight=""),await this.updateComplete;const t=this.containerRef.value,i=this.getVirtualizerElement();if(!t)return;if(this.renderedItems.length===0||!i){let n=0;t.querySelectorAll(":scope > *").forEach(w=>{n+=w.offsetHeight});const f=t.offsetHeight;n>0&&n<f&&(this.effectiveListHeight=`${n}px`);return}if(this.hasMoreData||this.isBusy||this.activeErrorMessage.length>0)return;const r=this.isGridLayout?".repeater-row":".repeater-item",s=i.querySelectorAll(r);let o=0,g=!1;if(s.forEach(n=>{const f=n.offsetHeight;f===0&&(g=!0),o+=f}),s.length===0||g||o===0){this.pendingHeightRetry||(this.pendingHeightRetry=!0,this.observeForHeightRetry(i));return}const u=this.isGridLayout?".repeater-row :defined":".repeater-item :defined",p=i.querySelectorAll(u),m=[];p.forEach(n=>{"updateComplete"in n&&m.push(n.updateComplete)}),m.length>0&&(await Promise.all(m),o=0,s.forEach(n=>{o+=n.offsetHeight}));const z=t.querySelector(":scope > .status-footer")?.offsetHeight??0,v=o+z,x=t.offsetHeight,V=this.virtualizerItems.length;let R=!1;v>0&&v<x&&s.length>=V&&(i.style.minHeight=`${o}px`,this.effectiveListHeight=`${v}px`,R=!0),R&&!this.hasMoreData&&!this.pendingHeightRetry&&(this.pendingHeightRetry=!0,setTimeout(()=>{if(this.pendingHeightRetry=!1,!this.isContainedScrollModel||this.isBusy||this.activeErrorMessage.length>0)return;const n=this.containerRef.value,f=this.getVirtualizerElement();if(!n||!f||this.hasMoreData)return;const w=this.isGridLayout?".repeater-row":".repeater-item",C=f.querySelectorAll(w);let S=0,L=!1;if(C.forEach(k=>{const H=k.offsetHeight;H===0&&(L=!0),S+=H}),C.length===0||L||S===0)return;const $=n.querySelector(":scope > .status-footer")?.offsetHeight??0,P=S+$;P<n.offsetHeight&&C.length>=this.virtualizerItems.length&&(f.style.minHeight=`${S}px`,this.effectiveListHeight=`${P}px`)},100))}finally{this.isAdjustingHeight=!1}}}observeForHeightRetry(e){this.heightRetryObserver?.disconnect(),this.heightRetryObserver=new IntersectionObserver(t=>{if(!t.some(o=>o.isIntersecting))return;if(this.heightRetryObserver?.disconnect(),this.heightRetryObserver=null,!this.isContainedScrollModel){this.pendingHeightRetry=!1;return}let r=0;const s=()=>{this.pendingHeightRetry=!1,this.adjustListHeight(),this.pendingHeightRetry&&++r<5&&setTimeout(s,100)};requestAnimationFrame(()=>setTimeout(s,50))},{threshold:0}),this.heightRetryObserver.observe(e)}clear(){if(this.isPagedMode){this.resetPagedState(),this.adjustListHeight();return}this.items=[]}async reload(){this.isPagedMode&&(this.resetPagedState(),await this.startPagedLoad(null))}async scrollToIndex(e,t="center"){await this.updateComplete;const i=this.getVirtualizerElement();!i||!i.scrollToIndex||(await i.updateComplete,await new Promise(r=>requestAnimationFrame(r)),await i.layoutComplete,i.scrollToIndex(this.isGridLayout?Math.floor(e/this.effectiveGridColumns):e,t))}getVirtualizerElement(){return this.virtualizerRef.value}renderBlockingState(e,t,i){return d`<div class="state-panel" part="state" role=${i} aria-live=${M(i==="alert"?void 0:"polite")}>
12
+ </div>`},this.renderGridVirtualItem=(e,t)=>this.isGridRow(e)?this.renderVirtualRow(e,t):d``}get fetchPage(){return this.fetchPageBacker}set fetchPage(e){const t=this.fetchPageBacker;t!==e&&(this.fetchPageBacker=e,this.requestUpdate("fetchPage",t),this.resetPagedState(),e&&this.hasUpdated&&this.startPagedLoad(null))}get isPagedMode(){return this.fetchPage!==null}get isGridLayout(){return this.layout==="grid"}get isPageScrollModel(){return this.scrollModel==="page"}get isContainedScrollModel(){return!this.isPageScrollModel}get renderedItems(){return this.isPagedMode?this.loadedItems:this.items}get virtualizerItems(){return this.isGridLayout?this.buildGridRows(this.renderedItems,this.effectiveGridColumns):this.renderedItems}get isBusy(){return this.loading||this.isLoadingPage}get activeErrorMessage(){return this.errorMessage||this.loadError}get normalizedPageSize(){const e=Number(this.pageSize);return Number.isFinite(e)&&e>0?Math.floor(e):25}get normalizedPrefetchThreshold(){const e=Number(this.prefetchThreshold);return Number.isFinite(e)&&e>0?Math.floor(e):1}get normalizedGridColumns(){const e=Number(this.gridColumns);return Number.isFinite(e)&&e>0?Math.floor(e):1}get effectiveGridColumns(){return this.isGridLayout?this.resolvedGridColumns:1}connectedCallback(){super.connectedCallback(),this.attachObservers(),this.lastObservedWidth=this.clientWidth,this.syncResolvedGridColumns(),this.hasUpdated&&this.isContainedScrollModel&&this.adjustListHeight()}firstUpdated(e){if(super.firstUpdated(e),this.lastObservedWidth=this.clientWidth,this.fetchPage){this.startPagedLoad(null);return}this.adjustListHeight()}disconnectedCallback(){this.releaseActivePageScrollStabilizer(),this.heightRetryObserver?.disconnect(),this.heightRetryObserver=null,this.pendingHeightRetry=!1,this.detachObservers(),super.disconnectedCallback()}willUpdate(e){super.willUpdate(e),(e.has("layout")||e.has("gridColumns"))&&this.syncResolvedGridColumns()}updated(e){super.updated(e),e.has("layout")&&this.syncGridObservers(),(e.has("items")||e.has("loadedItems")||e.has("listHeight")||e.has("layout")||e.has("gridColumns")||e.has("scrollModel"))&&this.adjustListHeight()}parsePositiveIntegerToken(e){const t=Number(e.trim());return Number.isFinite(t)&&t>0?Math.floor(t):null}attachObservers(){this.observersAttached||(this.observersAttached=!0,this.getResizeObserver().observe(this),this.syncGridObservers())}detachObservers(){this.observersAttached&&(this.observersAttached=!1,this.detachGridObservers(),this.resizeObserver?.disconnect())}syncGridObservers(){if(this.observersAttached){if(!this.isGridLayout){this.detachGridObservers();return}this.gridObserversAttached||(this.gridObserversAttached=!0,this.getHostAttributeObserver().observe(this,{attributes:!0,attributeFilter:["class","style"]}),window.addEventListener("resize",this.getViewportResizeListener()))}}detachGridObservers(){if(!this.gridObserversAttached)return;this.gridObserversAttached=!1,this.hostAttributeObserver?.disconnect();const e=this.viewportResizeListener;e&&window.removeEventListener("resize",e)}getHostAttributeObserver(){return this.hostAttributeObserver||(this.hostAttributeObserver=new MutationObserver(()=>{this.refreshResolvedGridColumns()})),this.hostAttributeObserver}getResizeObserver(){return this.resizeObserver||(this.resizeObserver=new ResizeObserver(()=>{const e=this.clientWidth,t=e!==this.lastObservedWidth;this.lastObservedWidth=e;const i=this.isGridLayout?this.refreshResolvedGridColumns():!1;t&&!i&&this.isContainedScrollModel&&this.adjustListHeight()})),this.resizeObserver}getViewportResizeListener(){return this.viewportResizeListener||(this.viewportResizeListener=()=>{this.refreshResolvedGridColumns()}),this.viewportResizeListener}syncResolvedGridColumns(){this.resolvedGridColumns=this.isGridLayout?this.readResolvedGridColumns():1}readResolvedGridColumns(){return!this.isGridLayout||!this.isConnected?this.normalizedGridColumns:this.parsePositiveIntegerToken(getComputedStyle(this).getPropertyValue("--esp-repeater-grid-columns"))??this.normalizedGridColumns}refreshResolvedGridColumns(){if(!this.isGridLayout)return!1;const e=this.readResolvedGridColumns();return e===this.resolvedGridColumns?!1:(this.resolvedGridColumns=e,this.hasUpdated&&(this.requestUpdate(),this.adjustListHeight()),!0)}buildGridRows(e,t){if(this.memoizedGridRowsSource===e&&this.memoizedGridRowsColumns===t)return this.memoizedGridRows;const i=[];for(let r=0;r<e.length;r+=t)i.push({items:e.slice(r,r+t),startIndex:r});return this.memoizedGridRowsSource=e,this.memoizedGridRowsColumns=t,this.memoizedGridRows=i,i}isGridRow(e){return e!==null&&typeof e=="object"&&Array.isArray(e.items)&&typeof e.startIndex=="number"}renderFallbackItem(e){if(typeof e=="string"||typeof e=="number"||typeof e=="boolean")return String(e);let t="";try{t=JSON.stringify(e,null,2)??this.describeFallbackItem(e)}catch{t=this.describeFallbackItem(e)}return d`<pre>${t}</pre>`}describeFallbackItem(e){try{return String(e)}catch{return"Unrenderable item"}}async startPagedLoad(e){if(!this.fetchPage||this.isLoadingPage)return;const t=this.capturePageScrollTop(e);this.isLoadingPage=!0,await this.loadPage(e,t)}async loadPage(e,t){const i=this.fetchPage;if(!i)return;const r=this.pageLoads.begin(),s=this.activatePageScrollStabilizer(t,r);this.activePageScrollStabilizer=s;try{const a=await i({cursor:e,limit:this.normalizedPageSize});if(!this.pageLoads.isCurrent(r))return;this.loadedItems=N(this.loadedItems,a.items,e),this.nextCursor=a.nextCursor,this.hasMoreData=a.nextCursor!==null,this.loadError=""}catch(a){if(!this.pageLoads.isCurrent(r))return;this.nextCursor=null,this.hasMoreData=!1,this.loadError=a instanceof Error&&a.message.length>0?a.message:"Unable to load items."}finally{try{this.pageLoads.isCurrent(r)&&(this.isLoadingPage=!1),this.pageLoads.isCurrent(r)&&await this.restorePageScrollPositionIfNeeded(s.getRestoreScrollTop(),r)}finally{this.activePageScrollStabilizer===s&&this.releaseActivePageScrollStabilizer()}}}capturePageScrollTop(e){return!this.isPageScrollModel||e===null?null:window.scrollY}activatePageScrollStabilizer(e,t){if(e===null||!this.isPageScrollModel||!this.pageLoads.isCurrent(t))return{release:()=>{},getRestoreScrollTop:()=>e};this.pageScrollStabilizerActive=!0;const i=this.getVirtualizerElement(),r=i?.getBoundingClientRect().height??0,s=this.activePageScrollStabilizer;s&&(this.activePageScrollStabilizer=null,s.release(),this.pageScrollStabilizerActive=!0),i&&r>0&&(i.style.minHeight=`${r}px`);const a="",g=r>0?Math.max(64,r*.5):Number.POSITIVE_INFINITY;let u=e,p=window.scrollY;const m=()=>{if(!this.pageLoads.isCurrent(t))return;const c=window.scrollY;if(c>u+1){u=c,p=c;return}if(c+1>=u){p=c;return}const z=c<=1,v=p+1>=u&&p-c>=g;if(!z&&!v){u=c,p=c;return}window.scrollTo({top:u,left:window.scrollX,behavior:"auto"}),p=u};return window.addEventListener("scroll",m,{passive:!0}),{getRestoreScrollTop:()=>u,release:()=>{window.removeEventListener("scroll",m),this.pageScrollStabilizerActive=!1,i&&(i.style.minHeight=a)}}}async restorePageScrollPositionIfNeeded(e,t){if(e===null||!this.isPageScrollModel||!this.pageLoads.isCurrent(t))return;await this.updateComplete;const i=this.getVirtualizerElement();i?.updateComplete&&await i.updateComplete,await new Promise(r=>requestAnimationFrame(r)),i?.layoutComplete&&await i.layoutComplete,this.pageLoads.isCurrent(t)&&window.scrollY+1<e&&window.scrollTo({top:e,left:window.scrollX,behavior:"auto"})}onRangeChanged(e){if(!this.isPagedMode||this.activeErrorMessage.length>0||!this.hasMoreData||this.isLoadingPage||this.nextCursor===null)return;const t=this.normalizedPrefetchThreshold;this.getLastVisibleItemIndex(e.last)>=this.loadedItems.length-t&&this.startPagedLoad(this.nextCursor)}getLastVisibleItemIndex(e){return this.isGridLayout?Math.min((e+1)*this.effectiveGridColumns-1,this.renderedItems.length-1):e}resetPagedState(){this.releaseActivePageScrollStabilizer(),this.pageLoads.invalidate(),this.isLoadingPage=!1,this.loadedItems=[],this.nextCursor=null,this.hasMoreData=!1,this.loadError=""}releaseActivePageScrollStabilizer(){const e=this.activePageScrollStabilizer;if(this.activePageScrollStabilizer=null,!e){this.pageScrollStabilizerActive=!1;return}e.release(),this.adjustListHeight()}async adjustListHeight(){if(!this.isContainedScrollModel){const e=this.getVirtualizerElement();e&&!this.pageScrollStabilizerActive&&(e.style.minHeight="");return}if(!this.isAdjustingHeight){this.isAdjustingHeight=!0;try{this.effectiveListHeight=this.listHeight;const e=this.getVirtualizerElement();e&&(e.style.minHeight=""),await this.updateComplete;const t=this.containerRef.value,i=this.getVirtualizerElement();if(!t)return;if(this.renderedItems.length===0||!i){let n=0;t.querySelectorAll(":scope > *").forEach(w=>{n+=w.offsetHeight});const f=t.offsetHeight;n>0&&n<f&&(this.effectiveListHeight=`${n}px`);return}if(this.hasMoreData||this.isBusy||this.activeErrorMessage.length>0)return;const r=this.isGridLayout?".repeater-row":".repeater-item",s=i.querySelectorAll(r);let a=0,g=!1;if(s.forEach(n=>{const f=n.offsetHeight;f===0&&(g=!0),a+=f}),s.length===0||g||a===0){this.pendingHeightRetry||(this.pendingHeightRetry=!0,this.observeForHeightRetry(i));return}const u=this.isGridLayout?".repeater-row :defined":".repeater-item :defined",p=i.querySelectorAll(u),m=[];p.forEach(n=>{"updateComplete"in n&&m.push(n.updateComplete)}),m.length>0&&(await Promise.all(m),a=0,s.forEach(n=>{a+=n.offsetHeight}));const z=t.querySelector(":scope > .status-footer")?.offsetHeight??0,v=a+z,x=t.offsetHeight,$=this.virtualizerItems.length;let R=!1;v>0&&v<x&&s.length>=$&&(i.style.minHeight=`${a}px`,this.effectiveListHeight=`${v}px`,R=!0),R&&!this.hasMoreData&&!this.pendingHeightRetry&&(this.pendingHeightRetry=!0,setTimeout(()=>{if(this.pendingHeightRetry=!1,!this.isContainedScrollModel||this.isBusy||this.activeErrorMessage.length>0)return;const n=this.containerRef.value,f=this.getVirtualizerElement();if(!n||!f||this.hasMoreData)return;const w=this.isGridLayout?".repeater-row":".repeater-item",C=f.querySelectorAll(w);let S=0,L=!1;if(C.forEach(T=>{const H=T.offsetHeight;H===0&&(L=!0),S+=H}),C.length===0||L||S===0)return;const k=n.querySelector(":scope > .status-footer")?.offsetHeight??0,P=S+k;P<n.offsetHeight&&C.length>=this.virtualizerItems.length&&(f.style.minHeight=`${S}px`,this.effectiveListHeight=`${P}px`)},100))}finally{this.isAdjustingHeight=!1}}}observeForHeightRetry(e){this.heightRetryObserver?.disconnect(),this.heightRetryObserver=new IntersectionObserver(t=>{if(!t.some(a=>a.isIntersecting))return;if(this.heightRetryObserver?.disconnect(),this.heightRetryObserver=null,!this.isContainedScrollModel){this.pendingHeightRetry=!1;return}let r=0;const s=()=>{this.pendingHeightRetry=!1,this.adjustListHeight(),this.pendingHeightRetry&&++r<5&&setTimeout(s,100)};requestAnimationFrame(()=>setTimeout(s,50))},{threshold:0}),this.heightRetryObserver.observe(e)}clear(){if(this.isPagedMode){this.resetPagedState(),this.adjustListHeight();return}this.items=[]}async reload(){this.isPagedMode&&(this.resetPagedState(),await this.startPagedLoad(null))}async scrollToIndex(e,t="center"){await this.updateComplete;const i=this.getVirtualizerElement();!i||!i.scrollToIndex||(await i.updateComplete,await new Promise(r=>requestAnimationFrame(r)),await i.layoutComplete,i.scrollToIndex(this.isGridLayout?Math.floor(e/this.effectiveGridColumns):e,t))}getVirtualizerElement(){return this.virtualizerRef.value}renderBlockingState(e,t,i){return d`<div class="state-panel" part="state" role=${i} aria-live=${M(i==="alert"?void 0:"polite")}>
13
13
  <slot name=${e}>
14
14
  <div class="state-message">${t}</div>
15
15
  </slot>
@@ -41,7 +41,7 @@ var l=function(y,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
41
41
  >
42
42
  ${this.renderedItems.length===0?this.activeErrorMessage.length>0?this.renderBlockingState("error",this.activeErrorMessage,"alert"):this.isBusy?this.renderBlockingState("skeleton",this.loadingMessage,"status"):this.renderBlockingState("empty",this.emptyMessage,"status"):i}
43
43
  ${this.renderFooterState()}
44
- </div>`}};a.styles=[...E.styles,T`
44
+ </div>`}};o.styles=[...E.styles,V`
45
45
  .repeater-container {
46
46
  display: flex;
47
47
  flex-direction: column;
@@ -119,4 +119,4 @@ var l=function(y,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
119
119
  margin: 0;
120
120
  white-space: pre-wrap;
121
121
  }
122
- `],l([b()],a.prototype,"isLoadingPage",void 0),l([b()],a.prototype,"loadedItems",void 0),l([b()],a.prototype,"hasMoreData",void 0),l([b()],a.prototype,"effectiveListHeight",void 0),l([b()],a.prototype,"loadError",void 0),l([h({type:Array})],a.prototype,"items",void 0),l([h({attribute:!1})],a.prototype,"renderItem",void 0),l([h({type:String,reflect:!0})],a.prototype,"layout",void 0),l([h({attribute:"scroll-model",type:String,reflect:!0})],a.prototype,"scrollModel",void 0),l([h({attribute:"grid-columns",type:Number})],a.prototype,"gridColumns",void 0),l([h({attribute:"aria-label",type:String})],a.prototype,"ariaLabel",void 0),l([h({attribute:"list-height",type:String})],a.prototype,"listHeight",void 0),l([h({attribute:"page-size",type:Number})],a.prototype,"pageSize",void 0),l([h({attribute:"prefetch-threshold",type:Number})],a.prototype,"prefetchThreshold",void 0),l([h({type:Boolean})],a.prototype,"loading",void 0),l([h({attribute:"loading-message",type:String})],a.prototype,"loadingMessage",void 0),l([h({attribute:"empty-message",type:String})],a.prototype,"emptyMessage",void 0),l([h({attribute:"error-message",type:String})],a.prototype,"errorMessage",void 0),l([h({attribute:!1})],a.prototype,"fetchPage",null),a=l([F("esp-repeater")],a);export{a as EspalierRepeater};
122
+ `],l([b()],o.prototype,"isLoadingPage",void 0),l([b()],o.prototype,"loadedItems",void 0),l([b()],o.prototype,"hasMoreData",void 0),l([b()],o.prototype,"effectiveListHeight",void 0),l([b()],o.prototype,"loadError",void 0),l([h({type:Array})],o.prototype,"items",void 0),l([h({attribute:!1})],o.prototype,"renderItem",void 0),l([h({type:String,reflect:!0})],o.prototype,"layout",void 0),l([h({attribute:"scroll-model",type:String,reflect:!0})],o.prototype,"scrollModel",void 0),l([h({attribute:"grid-columns",type:Number})],o.prototype,"gridColumns",void 0),l([h({attribute:"aria-label",type:String})],o.prototype,"ariaLabel",void 0),l([h({attribute:"list-height",type:String})],o.prototype,"listHeight",void 0),l([h({attribute:"page-size",type:Number})],o.prototype,"pageSize",void 0),l([h({attribute:"prefetch-threshold",type:Number})],o.prototype,"prefetchThreshold",void 0),l([h({type:Boolean})],o.prototype,"loading",void 0),l([h({attribute:"loading-message",type:String})],o.prototype,"loadingMessage",void 0),l([h({attribute:"empty-message",type:String})],o.prototype,"emptyMessage",void 0),l([h({attribute:"error-message",type:String})],o.prototype,"errorMessage",void 0),l([h({attribute:!1})],o.prototype,"fetchPage",null),o=l([F("esp-repeater")],o);export{o as EspalierRepeater};
@@ -1 +1 @@
1
- const _=Math.PI/180,i=1e-4,S=50;function d(t){const n=t.h*_;return{L:t.l,a:t.c*Math.cos(n),b:t.c*Math.sin(n)}}function P(t){const n=Math.sqrt(t.a*t.a+t.b*t.b);let r=Math.atan2(t.b,t.a)/_;return r<0&&(r+=360),{l:t.L,c:n,h:r}}function N(t){const n=t.L+.3963377774*t.a+.2158037573*t.b,r=t.L-.1055613458*t.a-.0638541728*t.b,o=t.L-.0894841775*t.a-1.291485548*t.b,e=n*n*n,c=r*r*r,a=o*o*o;return{r:4.0767416621*e-3.3077115913*c+.2309699292*a,g:-1.2684380046*e+2.6097574011*c-.3413193965*a,b:-.0041960863*e-.7034186147*c+1.707614701*a}}function E(t){const n=Math.cbrt(.4122214708*t.r+.5363325363*t.g+.0514459929*t.b),r=Math.cbrt(.2119034982*t.r+.6806995451*t.g+.1073969566*t.b),o=Math.cbrt(.0883024619*t.r+.2817188376*t.g+.6299787005*t.b);return{L:.2104542553*n+.793617785*r-.0040720468*o,a:1.9779984951*n-2.428592205*r+.4505937099*o,b:.0259040371*n+.7827717662*r-.808675766*o}}function p(t){return t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055}function M(t){return t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function F(t){return{r:p(t.r),g:p(t.g),b:p(t.b)}}function I(t){return{r:M(t.r),g:M(t.g),b:M(t.b)}}function X(t){return t.r>=-i&&t.r<=1+i&&t.g>=-i&&t.g<=1+i&&t.b>=-i&&t.b<=1+i}function m(t){return Math.max(0,Math.min(1,t))}function W(t){const r=t.trim().match(/^oklch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)\s*\)$/i);if(!r)return null;let o=parseFloat(r[1]);r[2]==="%"&&(o/=100);const e=parseFloat(r[3]),c=parseFloat(r[4]);return isNaN(o)||isNaN(e)||isNaN(c)?null:{l:o,c:e,h:(c%360+360)%360}}function U(t){const n=G(t.l,6),r=G(t.c,6),o=G((t.h%360+360)%360,4);return`oklch(${n} ${r} ${o})`}function T(t){return F(N(d(t)))}function Y(t){return P(E(I(t)))}function x(t){return X(T(t))}function h(t){if(t.c<=i||x(t))return{...t};let n=0,r=t.c,o={...t};for(let e=0;e<S;e++){const c=(n+r)/2;if(o={l:t.l,c,h:t.h},x(o)?n=c:r=c,r-n<i)break}return{l:t.l,c:n,h:t.h}}function $(t,n,r){const o={l:t.l,c:Math.max(n,Math.min(r,t.c)),h:t.h};return h(o)}const f=.022,L=.012,C=.022,R=.57,k=.56,B=1.14,A=.001,l=.027;function w(t){const n=Math.pow(m(t.r),2.4),r=Math.pow(m(t.g),2.4),o=Math.pow(m(t.b),2.4);return .2126729*n+.7151522*r+.072175*o}function O(t,n){const r=T(h(t)),o=T(h(n));let e=w(r),c=w(o);if(e=e>f?e:e+Math.pow(f-e,1.414),c=c>f?c:c+Math.pow(f-c,1.414),Math.abs(c-e)<A)return 0;let a;if(c>e){const s=Math.pow(c,k),u=Math.pow(e,R);if(a=(s-u)*B,a<A)return 0;a=a<l?a-a*C*l:a-C}else{const s=Math.pow(c,k),u=Math.pow(e,R);if(a=(s-u)*B,a>-A)return 0;a=a>-l?a-a*L*l:a+L}return a*100}function b(t,n,r=60){let o=h({...t}),e=Math.abs(O(o,n));if(e>=r)return o;const c=n.l>.5,a=.01,s=c?0:1;for(let u=0;u<100;u++){if(c?o.l=Math.max(s,o.l-a):o.l=Math.min(s,o.l+a),o=h(o),e=Math.abs(O(o,n)),e>=r)return o;if(o.l<=0||o.l>=1)break}return o}function v(t,n){return((t+n)%360+360)%360}function q(t,n){return{l:t.l,c:t.c,h:v(t.h,n)}}function V(t,n,r,o){return $({l:n,c:t.c,h:t.h},r,o)}function z(t,n,r,o,e,c=60){const a=V(t,n,r,o);return b(a,e,c)}function G(t,n){const r=Math.pow(10,n);return Math.round(t*r)/r}export{O as apcaContrast,$ as clampChromaAndGamutMap,V as deriveSemantic,z as deriveSemanticWithContrast,q as deriveVariant,b as ensureContrast,h as gamutMapToSRGB,x as isInSRGBGamut,T as oklchToSRGB,W as parseOklch,v as rotateHue,U as serializeOklch,Y as srgbToOklch};
1
+ const S=Math.PI/180,s=1e-4,w=50;function P(t){const o=t.h*S;return{L:t.l,a:t.c*Math.cos(o),b:t.c*Math.sin(o)}}function k(t){const o=t.L+.3963377774*t.a+.2158037573*t.b,e=t.L-.1055613458*t.a-.0638541728*t.b,n=t.L-.0894841775*t.a-1.291485548*t.b,r=o*o*o,c=e*e*e,a=n*n*n;return{r:4.0767416621*r-3.3077115913*c+.2309699292*a,g:-1.2684380046*r+2.6097574011*c-.3413193965*a,b:-.0041960863*r-.7034186147*c+1.707614701*a}}function p(t){return t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055}function N(t){return{r:p(t.r),g:p(t.g),b:p(t.b)}}function O(t){return t.r>=-s&&t.r<=1+s&&t.g>=-s&&t.g<=1+s&&t.b>=-s&&t.b<=1+s}function M(t){return Math.max(0,Math.min(1,t))}function X(t){const e=t.trim().match(/^oklch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)\s*\)$/i);if(!e)return null;let n=parseFloat(e[1]);e[2]==="%"&&(n/=100);const r=parseFloat(e[3]),c=parseFloat(e[4]);return isNaN(n)||isNaN(r)||isNaN(c)?null:{l:n,c:r,h:(c%360+360)%360}}function $(t){const o=T(t.l,6),e=T(t.c,6),n=T((t.h%360+360)%360,4);return`oklch(${o} ${e} ${n})`}function m(t){return N(k(P(t)))}function _(t){return O(m(t))}function h(t){if(t.c<=s||_(t))return{...t};let o=0,e=t.c,n={...t};for(let r=0;r<w;r++){const c=(o+e)/2;if(n={l:t.l,c,h:t.h},_(n)?o=c:e=c,e-o<s)break}return{l:t.l,c:o,h:t.h}}function E(t,o,e){const n={l:t.l,c:Math.max(o,Math.min(e,t.c)),h:t.h};return h(n)}const f=.022,G=.012,x=.022,C=.57,L=.56,R=1.14,A=.001,l=.027;function d(t){const o=Math.pow(M(t.r),2.4),e=Math.pow(M(t.g),2.4),n=Math.pow(M(t.b),2.4);return .2126729*o+.7151522*e+.072175*n}function B(t,o){const e=m(h(t)),n=m(h(o));let r=d(e),c=d(n);if(r=r>f?r:r+Math.pow(f-r,1.414),c=c>f?c:c+Math.pow(f-c,1.414),Math.abs(c-r)<A)return 0;let a;if(c>r){const i=Math.pow(c,L),u=Math.pow(r,C);if(a=(i-u)*R,a<A)return 0;a=a<l?a-a*x*l:a-x}else{const i=Math.pow(c,L),u=Math.pow(r,C);if(a=(i-u)*R,a>-A)return 0;a=a>-l?a-a*G*l:a+G}return a*100}function F(t,o,e=60){let n=h({...t}),r=Math.abs(B(n,o));if(r>=e)return n;const c=o.l>.5,a=.01,i=c?0:1;for(let u=0;u<100;u++){if(c?n.l=Math.max(i,n.l-a):n.l=Math.min(i,n.l+a),n=h(n),r=Math.abs(B(n,o)),r>=e)return n;if(n.l<=0||n.l>=1)break}return n}function b(t,o){return((t+o)%360+360)%360}function I(t,o,e,n){return E({l:o,c:t.c,h:t.h},e,n)}function W(t,o,e,n,r,c=60){const a=I(t,o,e,n);return F(a,r,c)}function T(t,o){const e=Math.pow(10,o);return Math.round(t*e)/e}export{B as apcaContrast,E as clampChromaAndGamutMap,I as deriveSemantic,W as deriveSemanticWithContrast,F as ensureContrast,h as gamutMapToSRGB,_ as isInSRGBGamut,m as oklchToSRGB,X as parseOklch,b as rotateHue,$ as serializeOklch};
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @module cursor-pagination
3
+ *
4
+ * Shared vocabulary and the stale-response guard for cursor-paginated
5
+ * components (`esp-grid`, `esp-repeater`).
6
+ *
7
+ * **Why this is types plus one small class, and not a controller.** Both
8
+ * components run the same four-step core — bump a version, fetch, discard the
9
+ * response if a newer request started, replace-or-append — but everything
10
+ * around it differs: the grid dispatches four lifecycle events, rethrows, and
11
+ * resets the virtualizer's scroll; the repeater runs a page-scroll stabilizer
12
+ * and swallows errors into a `loadError` string. A controller covering both
13
+ * would need roughly five configuration hooks to absorb ~36 lines of shared
14
+ * code — more interface than implementation, for two callers.
15
+ *
16
+ * So the parts that genuinely benefit from being shared are extracted: the
17
+ * public type vocabulary, which was duplicated under two sets of names, and the
18
+ * version guard, which is the correctness core and the piece most likely to be
19
+ * subtly wrong when written twice.
20
+ */
21
+ /**
22
+ * The request for one page of cursor-paginated data.
23
+ *
24
+ * Components may extend this with their own query context — see `esp-grid`'s
25
+ * `CursorFetchParams`, which adds search and sort.
26
+ */
27
+ export interface CursorPageRequest {
28
+ /** Cursor for the page to fetch. `null` means the first page. */
29
+ cursor: string | null;
30
+ /** How many items to request. */
31
+ limit: number;
32
+ }
33
+ /** One page of cursor-paginated results. */
34
+ export interface CursorPageResult<T> {
35
+ /** The items for this page. */
36
+ items: T[];
37
+ /** Cursor for the next page, or `null` when there are none. */
38
+ nextCursor: string | null;
39
+ }
40
+ /**
41
+ * Monotonic token issuer for discarding superseded async responses.
42
+ *
43
+ * A user typing in a search box, or scrolling fast enough to trigger several
44
+ * page loads, produces overlapping requests that can resolve out of order.
45
+ * Without a guard, a slow early response overwrites a fast later one and the
46
+ * component shows stale data.
47
+ *
48
+ * ```ts
49
+ * const token = this.pageLoads.begin();
50
+ * const result = await fetchPage(params);
51
+ * if (!this.pageLoads.isCurrent(token)) return; // superseded — drop it
52
+ * ```
53
+ *
54
+ * Every `await` boundary in the load path needs a re-check: being current
55
+ * before the fetch says nothing about being current after it.
56
+ */
57
+ export declare class RequestVersionGuard {
58
+ /** Start a request and take its token. Supersedes every outstanding one. */
59
+ begin(): number;
60
+ /** Whether `token` is still the newest request. */
61
+ isCurrent(token: number): boolean;
62
+ /**
63
+ * Supersede every outstanding request without starting a new one.
64
+ *
65
+ * Use when a component disconnects or its data source changes and in-flight
66
+ * responses should be dropped rather than applied.
67
+ */
68
+ invalidate(): void;
69
+ }
70
+ /**
71
+ * Apply a page of results to an accumulated list: the first page replaces,
72
+ * subsequent pages append.
73
+ *
74
+ * Always returns a new array so Lit sees the change.
75
+ */
76
+ export declare function accumulatePage<T>(current: readonly T[], page: readonly T[], cursor: string | null): T[];
@@ -0,0 +1 @@
1
+ class n{constructor(){this.version=0}begin(){return++this.version}isCurrent(r){return r===this.version}invalidate(){this.version++}}function i(e,r,t){return t===null?[...r]:[...e,...r]}export{n as RequestVersionGuard,i as accumulatePage};
@@ -3,8 +3,19 @@ export declare const DEFAULT_ICON_SPRITE_URL = "/assets/icons.svg";
3
3
  export declare const DEFAULT_ICON_VIEW_BOX = "0 0 24 24";
4
4
  export declare const INTENT_VARIANTS: readonly EspalierIntentVariant[];
5
5
  export declare function normalizeIntentVariant(value: string | null | undefined): EspalierIntentVariant;
6
- export declare function getIconHref(icon: string | null | undefined, host?: Element | null | undefined): string;
7
- export declare const getIconHrefForHost: typeof getIconHref;
6
+ export declare function getIconHrefForHost(icon: string | null | undefined, host?: Element | null | undefined): string;
7
+ /**
8
+ * Former name of `getIconHrefForHost`.
9
+ *
10
+ * @deprecated Use `getIconHrefForHost`. This alias is retained for one release
11
+ * so existing consumers keep compiling; it will be removed after that.
12
+ *
13
+ * NOTE: do not use an inline `{@link}` tag in this comment. On an exported
14
+ * `const` alias the custom-elements-manifest analyzer tries to resolve the link
15
+ * target and serializes the TypeScript AST node, which fails `build-cem` with
16
+ * "Converting circular structure to JSON". A plain backticked name is safe.
17
+ */
18
+ export declare const getIconHref: typeof getIconHrefForHost;
8
19
  export declare function getIconSpriteUrl(host: Element | null | undefined): string;
9
20
  /**
10
21
  * Reset the per-process record of which invalid icon names have
@@ -1 +1 @@
1
- import{traverseToClosest as a}from"./utilities.js";const i="/assets/icons.svg",p="0 0 24 24",c=/^[A-Za-z0-9][A-Za-z0-9_-]*$/u,l=100,r=new Set,o=[],u=["neutral","success","warning","danger","info"];function N(n){return u.includes(n)?n:"neutral"}function I(n,t=null){const e=n?.trim()??"";if(!c.test(e))return e.length>0&&m(e)&&console.warn(`Invalid Espalier icon name "${e}". Icon names must start with a letter or number and may only contain letters, numbers, dashes, and underscores.`),"";const s=d(t);return s?`${s}#${e}`:""}const _=I;function d(n){const t=n?a(n,"esp-root"):null;return(t?(t.iconSpriteUrl??"").trim():i).split("#")[0]?.trim()||""}function m(n){if(r.has(n))return!1;if(r.add(n),o.push(n),o.length>l){const t=o.shift();t&&r.delete(t)}return!0}function g(){r.clear(),o.length=0}export{i as DEFAULT_ICON_SPRITE_URL,p as DEFAULT_ICON_VIEW_BOX,u as INTENT_VARIANTS,I as getIconHref,_ as getIconHrefForHost,d as getIconSpriteUrl,N as normalizeIntentVariant,g as resetWarnedInvalidIconNames};
1
+ import{traverseToClosest as a}from"./utilities.js";const i="/assets/icons.svg",p="0 0 24 24",c=/^[A-Za-z0-9][A-Za-z0-9_-]*$/u,l=100,r=new Set,o=[],u=["neutral","success","warning","danger","info"];function N(n){return u.includes(n)?n:"neutral"}function I(n,t=null){const e=n?.trim()??"";if(!c.test(e))return e.length>0&&m(e)&&console.warn(`Invalid Espalier icon name "${e}". Icon names must start with a letter or number and may only contain letters, numbers, dashes, and underscores.`),"";const s=d(t);return s?`${s}#${e}`:""}const _=I;function d(n){const t=n?a(n,"esp-root"):null;return(t?(t.iconSpriteUrl??"").trim():i).split("#")[0]?.trim()||""}function m(n){if(r.has(n))return!1;if(r.add(n),o.push(n),o.length>l){const t=o.shift();t&&r.delete(t)}return!0}function g(){r.clear(),o.length=0}export{i as DEFAULT_ICON_SPRITE_URL,p as DEFAULT_ICON_VIEW_BOX,u as INTENT_VARIANTS,_ as getIconHref,I as getIconHrefForHost,d as getIconSpriteUrl,N as normalizeIntentVariant,g as resetWarnedInvalidIconNames};
@@ -1 +1 @@
1
- import{getEspBus as c}from"./bus-events.js";function l(r){const s=[],t=new Set;let e=r;for(;e&&!t.has(e);){t.add(e);const i=e["linked-popover"];if(i){e=i;continue}const o=e.closest("esp-popover");if(o){s.includes(o)||s.push(o),e=o.parentElement||o.getRootNode()?.host;continue}const n=e.getRootNode();e=n instanceof ShadowRoot?n.host:void 0}return s}class u{constructor(s){this.bus=c(),this.rafId=0,this.positionResizeObserver=null,this.handleClosePopovers=t=>{if(!this.opts.isOpen())return;const e=this.opts.host;if(this.opts.closeStrategy==="source-identity"){if(!t.source||t.source===e||t.source instanceof Node&&(e.contains(t.source)||e.shadowRoot?.contains(t.source)))return}else if(t.skipPopovers?.includes(e))return;this.opts.onShouldClose()},this.onScrollOrResize=()=>{this.rafId||(this.rafId=requestAnimationFrame(()=>{if(this.rafId=0,!!this.opts.isOpen()){if(this.opts.shouldContinueTracking&&!this.opts.shouldContinueTracking()){this.opts.onShouldClose();return}this.opts.onPositionUpdate?.()}}))},this.onDocumentClick=t=>{const e=this.opts.host,i=t.composedPath();if(i.includes(e))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=s,s.host.addController(this)}hostConnected(){this.bus.subscribe("close-popovers",this.handleClosePopovers)}hostDisconnected(){this.bus.unsubscribe("close-popovers",this.handleClosePopovers),this.stopTracking(),this.stopOutsideClick()}startTracking(){if(this.opts.onPositionUpdate&&(window.addEventListener("scroll",this.onScrollOrResize,{capture:!0,passive:!0}),window.addEventListener("resize",this.onScrollOrResize,{passive:!0}),this.opts.getPositionElements&&typeof ResizeObserver<"u")){this.positionResizeObserver?.disconnect(),this.positionResizeObserver=new ResizeObserver(this.onScrollOrResize);const s=new Set(this.opts.getPositionElements().filter(Boolean));for(const t of s)this.positionResizeObserver.observe(t)}}stopTracking(){window.removeEventListener("scroll",this.onScrollOrResize,{capture:!0}),window.removeEventListener("resize",this.onScrollOrResize),this.positionResizeObserver?.disconnect(),this.positionResizeObserver=null,this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=0)}startOutsideClick(){this.opts.onOutsideClick&&document.addEventListener("click",this.onDocumentClick,!0)}stopOutsideClick(){document.removeEventListener("click",this.onDocumentClick,!0)}publishCloseOthers(s=[]){this.bus.publish("close-popovers",{source:this.opts.host,...s.length>0?{skipPopovers:s}:{}})}publishCloseExcept(s){this.bus.publish("close-popovers",{source:this.opts.host,skipPopovers:s})}}export{u as PopoverController,l as findContainingPopovers};
1
+ import{getEspBus as c}from"./bus-events.js";import{RafThrottle as h}from"./raf-throttle.js";function p(r){const t=[],s=new Set;let e=r;for(;e&&!s.has(e);){s.add(e);const i=e["linked-popover"];if(i){e=i;continue}const o=e.closest("esp-popover");if(o){t.includes(o)||t.push(o),e=o.parentElement||o.getRootNode()?.host;continue}const n=e.getRootNode();e=n instanceof ShadowRoot?n.host:void 0}return t}class d{constructor(t){this.bus=c(),this.positionFrame=new h(()=>this.runPositionUpdate()),this.positionResizeObserver=null,this.handleClosePopovers=s=>{if(!this.opts.isOpen())return;const e=this.opts.host;if(this.opts.closeStrategy==="source-identity"){if(!s.source||s.source===e||s.source instanceof Node&&(e.contains(s.source)||e.shadowRoot?.contains(s.source)))return}else if(s.skipPopovers?.includes(e))return;this.opts.onShouldClose()},this.onScrollOrResize=()=>this.positionFrame.schedule(),this.onDocumentClick=s=>{const e=this.opts.host,i=s.composedPath();if(i.includes(e))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(){if(this.opts.onPositionUpdate&&(window.addEventListener("scroll",this.onScrollOrResize,{capture:!0,passive:!0}),window.addEventListener("resize",this.onScrollOrResize,{passive:!0}),this.opts.getPositionElements&&typeof ResizeObserver<"u")){this.positionResizeObserver?.disconnect(),this.positionResizeObserver=new ResizeObserver(this.onScrollOrResize);const t=new Set(this.opts.getPositionElements().filter(Boolean));for(const s of t)this.positionResizeObserver.observe(s)}}stopTracking(){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{d as PopoverController,p as findContainingPopovers};
@@ -0,0 +1 @@
1
+ class l{constructor(e){this.callback=e,this.frameId=null}get isScheduled(){return this.frameId!==null}schedule(){this.frameId===null&&(this.frameId=requestAnimationFrame(()=>{this.frameId=null,this.callback()}))}restart(){this.cancel(),this.schedule()}cancel(){this.frameId!==null&&(cancelAnimationFrame(this.frameId),this.frameId=null)}}export{l as RafThrottle};
@@ -1,17 +1,15 @@
1
- type SpaceAboveBelow = {
2
- spaceAbove: number;
3
- spaceBelow: number;
4
- };
5
1
  /**
6
- * Calculates the available space above and below an element relative to the viewport.
7
- *
8
- * @param element - The HTML element to measure
9
- * @returns An object containing spaceAbove and spaceBelow in pixels
2
+ * `getSpaceAboveBelow` now lives in `./viewport.js` alongside the rest of the
3
+ * viewport measurement helpers. It is re-exported here because
4
+ * `@taprootio/espalier/shared/utilities` is a published entry point.
10
5
  */
11
- export declare function getSpaceAboveBelow(element: HTMLElement): SpaceAboveBelow;
6
+ export { getSpaceAboveBelow, type SpaceAboveBelow } from "./viewport.js";
12
7
  /**
13
- * Scrolls an element into view within a scrollable container.
14
- * Handles scrolling up or down based on the direction flag.
8
+ * Scroll an element into view within a scrollable container.
9
+ *
10
+ * @deprecated No longer used by Espalier. Prefer `Element.scrollIntoView` with
11
+ * `block: "nearest"`, which the platform implements natively. Scheduled for
12
+ * removal in the next major release.
15
13
  *
16
14
  * @param container - The scrollable container element
17
15
  * @param element - The element to scroll into view
@@ -19,31 +17,34 @@ export declare function getSpaceAboveBelow(element: HTMLElement): SpaceAboveBelo
19
17
  */
20
18
  export declare function scrollElementIntoView(container: HTMLElement, element: HTMLElement, up: boolean): void;
21
19
  /**
22
- * Traverses up the DOM tree from a given element to find the closest matching element.
23
- * Handles traversal across Shadow DOM boundaries to locate elements in parent scopes.
20
+ * Whether an element or any ancestor is fixed-positioned, crossing shadow
21
+ * boundaries.
24
22
  *
25
- * @template TElement - The expected type of the returned element
26
- * @param fromElement - The element to start the search from
27
- * @param selector - The CSS selector to match against
28
- * @returns The closest matching element, or null if none found
29
- */
30
- export declare function traverseToClosest<TElement extends HTMLElement>(fromElement: Element, selector: string): TElement | null;
31
- /**
32
- * Checks if an element or any of its ancestors have a fixed position within a Shadow DOM.
33
- * Recursively traverses the Shadow DOM tree to detect fixed positioning.
23
+ * @deprecated No longer used by Espalier. Scheduled for removal in the next
24
+ * major release.
34
25
  *
35
26
  * @param element - The element to check
36
- * @returns True if the element or any ancestor is fixed-positioned within Shadow DOM, false otherwise
37
27
  */
38
28
  export declare function isFixedInShadowDom(element: HTMLElement): boolean;
39
29
  /**
40
- * Checks if an element has a fixed position or if any of its ancestors are fixed-positioned.
41
- * Traverses up the DOM tree to detect fixed positioning at any level.
30
+ * Whether an element or any light-DOM ancestor is fixed-positioned.
31
+ *
32
+ * @deprecated No longer used by Espalier. Scheduled for removal in the next
33
+ * major release.
42
34
  *
43
35
  * @param element - The element to check
44
- * @returns True if the element or any ancestor has position: fixed, false otherwise
45
36
  */
46
37
  export declare function isFixedOrAncestorFixed(element: HTMLElement): boolean;
38
+ /**
39
+ * Traverses up the DOM tree from a given element to find the closest matching element.
40
+ * Handles traversal across Shadow DOM boundaries to locate elements in parent scopes.
41
+ *
42
+ * @template TElement - The expected type of the returned element
43
+ * @param fromElement - The element to start the search from
44
+ * @param selector - The CSS selector to match against
45
+ * @returns The closest matching element, or null if none found
46
+ */
47
+ export declare function traverseToClosest<TElement extends HTMLElement>(fromElement: Element, selector: string): TElement | null;
47
48
  /**
48
49
  * Compares two arrays to check if they contain the same values for a specific key.
49
50
  * Arrays are compared by extracting values for the given key, sorting them, and checking equality.
@@ -55,4 +56,3 @@ export declare function isFixedOrAncestorFixed(element: HTMLElement): boolean;
55
56
  * @returns True if both arrays have the same length and matching values for the key, false otherwise
56
57
  */
57
58
  export declare const arrayKeysMatch: (arr1: Array<Record<string, unknown>>, arr2: Array<Record<string, unknown>>, key: string) => boolean;
58
- export {};
@@ -1 +1 @@
1
- function c(t){const e=t.getBoundingClientRect(),o=window.innerHeight||document.documentElement.clientHeight,s=e.top,n=o-e.bottom;return{spaceAbove:s,spaceBelow:n}}function d(t,e,o){const s=t.getBoundingClientRect(),n=e.getBoundingClientRect();if(n.top<s.top||n.bottom>s.bottom){const i=n.top-s.top;o||!o&&i<0?t.scrollTop+=i:t.scrollBy({top:n.height})}}function u(t,e){let o=t,s=null;for(;!s&&o&&o.closest;)if(s=o.closest(e),!s){const n=o.getRootNode();n instanceof ShadowRoot?o=n.host:o=void 0}return s}function f(t){let e=t;for(;e;){if(r(e.assignedSlot?.parentNode)||getComputedStyle(e).position==="fixed")return!0;const n=e.assignedSlot?e.assignedSlot.getRootNode():e.getRootNode();if(n instanceof ShadowRoot)e=n.host;else break}return!1}function r(t){if(!t||!(t instanceof HTMLElement))return!1;let e=t;for(;e;){if(getComputedStyle(e).position==="fixed")return!0;e=e.parentElement}return!1}const p=(t,e,o)=>{if(t.length!==e.length)return!1;const s=t.map(i=>i[o]).sort(),n=e.map(i=>i[o]).sort();return s.every((i,l)=>i===n[l])};export{p as arrayKeysMatch,c as getSpaceAboveBelow,f as isFixedInShadowDom,r as isFixedOrAncestorFixed,d as scrollElementIntoView,u as traverseToClosest};
1
+ import{getSpaceAboveBelow as g}from"./viewport.js";function c(t,e,o){const n=t.getBoundingClientRect(),r=e.getBoundingClientRect();if(r.top<n.top||r.bottom>n.bottom){const s=r.top-n.top;o||s<0?t.scrollTop+=s:t.scrollBy({top:r.height})}}function f(t){let e=t;for(;e;){if(i(e.assignedSlot?.parentNode)||getComputedStyle(e).position==="fixed")return!0;const o=e.assignedSlot?e.assignedSlot.getRootNode():e.getRootNode();if(!(o instanceof ShadowRoot))break;e=o.host}return!1}function i(t){if(!t||!(t instanceof HTMLElement))return!1;let e=t;for(;e;){if(getComputedStyle(e).position==="fixed")return!0;e=e.parentElement}return!1}function u(t,e){let o=t,n=null;for(;!n&&o&&o.closest;)if(n=o.closest(e),!n){const r=o.getRootNode();r instanceof ShadowRoot?o=r.host:o=void 0}return n}const d=(t,e,o)=>{if(t.length!==e.length)return!1;const n=t.map(s=>s[o]).sort(),r=e.map(s=>s[o]).sort();return n.every((s,l)=>s===r[l])};export{d as arrayKeysMatch,g as getSpaceAboveBelow,f as isFixedInShadowDom,i as isFixedOrAncestorFixed,c as scrollElementIntoView,u as traverseToClosest};
@@ -0,0 +1,89 @@
1
+ /**
2
+ * @module viewport
3
+ *
4
+ * Shared viewport measurement for anchored surfaces (picker menus, popovers,
5
+ * date-picker calendars).
6
+ *
7
+ * Before this module the expression
8
+ * `window.innerHeight || document.documentElement.clientHeight` appeared in six
9
+ * files, and the `spaceAbove` / `spaceBelow` pair was recomputed inline at three
10
+ * call sites even though `getSpaceAboveBelow` already existed and had no
11
+ * callers.
12
+ *
13
+ * **On `visualViewport`:** `esp-page` deliberately measures against
14
+ * `window.visualViewport` so a pinch-zoomed or split-pane page allocates panes
15
+ * against what is actually visible. The anchored surfaces here intentionally do
16
+ * **not**: `visualViewport.height` shrinks when the software keyboard opens,
17
+ * and the pickers' keyboard-avoidance logic (`KEYBOARD_THRESHOLD` in
18
+ * `esp-picker-base`) is tuned against `innerHeight` staying stable. Unifying the
19
+ * two is a real improvement but a behavioural change, so it is deliberately not
20
+ * bundled into this refactor.
21
+ */
22
+ export interface ViewportSize {
23
+ width: number;
24
+ height: number;
25
+ }
26
+ export interface SpaceAboveBelow {
27
+ spaceAbove: number;
28
+ spaceBelow: number;
29
+ }
30
+ /**
31
+ * The layout viewport in CSS pixels.
32
+ *
33
+ * `innerHeight` / `innerWidth` are the primary source; the `documentElement`
34
+ * client dimensions are the fallback for environments that report zero (notably
35
+ * happy-dom in tests).
36
+ */
37
+ export declare function viewportSize(): ViewportSize;
38
+ /**
39
+ * Space above and below an already-measured rect.
40
+ *
41
+ * Prefer this over {@link getSpaceAboveBelow} in scroll- or resize-driven paths
42
+ * where the caller already holds a rect — it avoids a second forced layout.
43
+ *
44
+ * @param rect - A rect in viewport coordinates
45
+ * @param height - Viewport height; measured when omitted
46
+ */
47
+ export declare function spaceAroundRect(rect: DOMRect, height?: number): SpaceAboveBelow;
48
+ /**
49
+ * Space above and below an element, relative to the viewport.
50
+ *
51
+ * @param element - The element to measure
52
+ */
53
+ export declare function getSpaceAboveBelow(element: HTMLElement): SpaceAboveBelow;
54
+ /**
55
+ * Whether the user has asked the platform to reduce motion.
56
+ *
57
+ * Defaults to `false` where `matchMedia` is missing or returns nothing, so a
58
+ * constrained runtime gets ordinary motion rather than a thrown error.
59
+ */
60
+ export declare function prefersReducedMotion(): boolean;
61
+ /**
62
+ * The scroll behavior to use for programmatic scrolling — `"auto"` when the
63
+ * user prefers reduced motion, `"smooth"` otherwise.
64
+ *
65
+ * Every programmatic scroll in the library should go through this rather than
66
+ * hard-coding `behavior: "smooth"`.
67
+ */
68
+ export declare function scrollBehavior(): ScrollBehavior;
69
+ /**
70
+ * Gap left between an anchored surface and the viewport edge after scrolling it
71
+ * back into view, so the surface does not sit flush against the edge.
72
+ */
73
+ export declare const ANCHORED_SURFACE_SCROLL_MARGIN = 8;
74
+ /**
75
+ * Scroll the page so that an anchor (a trigger field) and its anchored surface
76
+ * (a dropdown, menu, or calendar) are both visible.
77
+ *
78
+ * Called when the viewport shrinks out from under an open surface — most often
79
+ * a software keyboard appearing on mobile. Does nothing when the pair already
80
+ * fits.
81
+ *
82
+ * `onReposition` runs on the next frame so the caller can re-run its own
83
+ * placement math against the new scroll offset.
84
+ *
85
+ * @param anchor - The trigger element
86
+ * @param surface - The open surface anchored to it
87
+ * @param onReposition - Re-placement callback, invoked only when a scroll happened
88
+ */
89
+ export declare function scrollToContainAnchoredSurface(anchor: HTMLElement, surface: HTMLElement, onReposition: () => void): void;
@@ -0,0 +1 @@
1
+ function d(){return{width:window.innerWidth||document.documentElement.clientWidth,height:window.innerHeight||document.documentElement.clientHeight}}function l(t,e=d().height){return{spaceAbove:t.top,spaceBelow:e-t.bottom}}function m(t){return l(t.getBoundingClientRect())}function h(){return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches??!1}function p(){return h()?"auto":"smooth"}const s=8;function w(t,e,a){const o=t.getBoundingClientRect(),n=e.getBoundingClientRect(),{height:i}=d(),c=Math.min(o.top,n.top),r=Math.max(o.bottom,n.bottom),u=p();if(r>i)window.scrollBy({top:r-i+s,behavior:u});else if(c<0)window.scrollBy({top:c-s,behavior:u});else return;requestAnimationFrame(a)}export{s as ANCHORED_SURFACE_SCROLL_MARGIN,m as getSpaceAboveBelow,h as prefersReducedMotion,p as scrollBehavior,w as scrollToContainAnchoredSurface,l as spaceAroundRect,d as viewportSize};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taprootio/espalier",
3
- "version": "2.13.1",
3
+ "version": "2.15.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",
@@ -270,6 +270,14 @@
270
270
  "types": "./dist/shared/font-helpers.d.ts",
271
271
  "import": "./dist/shared/font-helpers.js"
272
272
  },
273
+ "./shared/cursor-pagination": {
274
+ "types": "./dist/shared/cursor-pagination.d.ts",
275
+ "import": "./dist/shared/cursor-pagination.js"
276
+ },
277
+ "./shared/viewport": {
278
+ "types": "./dist/shared/viewport.d.ts",
279
+ "import": "./dist/shared/viewport.js"
280
+ },
273
281
  "./shared/utilities": {
274
282
  "types": "./dist/shared/utilities.d.ts",
275
283
  "import": "./dist/shared/utilities.js"
@@ -1 +0,0 @@
1
- export*from"../menu/esp-menu-group.js";
@@ -1 +0,0 @@
1
- export*from"../menu/esp-menu-item.js";
@@ -1 +0,0 @@
1
- export*from"../menu/esp-menu.js";