@taprootio/espalier 4.13.0 → 4.14.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.
@@ -1,12 +1,12 @@
1
- var a=function(h,e,t,s){var n=arguments.length,l=n<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,t):s,r;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")l=Reflect.decorate(h,e,t,s);else for(var d=h.length-1;d>=0;d--)(r=h[d])&&(l=(n<3?r(l):n>3?r(e,t,l):r(e,t))||l);return n>3&&l&&Object.defineProperty(e,t,l),l};import{css as B,html as x,nothing as T}from"lit";import{customElement as k,property as i,state as c}from"lit/decorators.js";import{classMap as A}from"lit/directives/class-map.js";import{styleMap as O}from"lit/directives/style-map.js";import"../burger/esp-burger.js";import{createRef as C,ref as D}from"lit/directives/ref.js";import{EspalierMenu as p}from"../menu/esp-menu.js";import{RafThrottle as _}from"../shared/raf-throttle.js";import{renderConfiguredBrand as R,resolveConfiguredBrand as E}from"../shared/configured-brand.js";import{EspalierElementBase as M}from"../shared/esp-element-base.js";import{ESP_EVENTS as z}from"../shared/events.js";const H="(max-width: 36rem)";function u(h,e){const t=new Set(h);return{allowedValues:t,converter:{fromAttribute(n){return n??e},toAttribute(n){return t.has(n)?n:e}},defaultValue:e}}const j=["standard","centered-brand","centered-menu","extended","extended-centered","minimal"],q=["start","center","end"],V=["truncate","wrap","nowrap"],N=["auto","inline","drawer"],U=["hidden","visible"],g=u(j,"standard"),b=u(q,"start"),f=u(V,"truncate"),v=u(N,"auto"),w=u(U,"hidden");let o=class extends M{constructor(){super(...arguments),this.menuOpen=!1,this.menuTooLarge=!1,this.mobileMenu=!1,this.scrolled=!1,this.hiddenByScroll=!1,this.scrollProgress=0,this.showBurger=!1,this.layout=g.defaultValue,this.brandText="",this.brandLogo="",this.lightBrandLogo="",this.darkBrandLogo="",this.brandHref="",this.brandAlt="",this.brandColor="",this.lightBrandColor="",this.darkBrandColor="",this.brandAlign=b.defaultValue,this.brandWrap=f.defaultValue,this.menuDisplay=v.defaultValue,this.themeToggle=w.defaultValue,this.scrollBehavior="none",this.scrollThreshold=16,this.dockOffset=0,this.drawerTarget="",this.previewCollapseRequested=!1,this.fullBleedContent=!1,this.menuContainer=C(),this.menuButton=C(),this.menu=void 0,this.externalDrawerTarget=null,this.lastScrollY=0,this.lastInlineMenuWidth=0,this.mobileMenuQuery=null,this.menuDrawerListenersAttached=!1,this.observingMenuContainer=!1,this.scrollListenersAttached=!1,this.scrollFrame=new _(()=>this.runScrollStateUpdate()),this.resizeObserver=new ResizeObserver(()=>this.syncMenuLayout()),this.menuChildObserver=null,this.updateScrollState=()=>this.scrollFrame.schedule(),this.handleMobileMenuQueryChange=e=>{this.mobileMenu=e.matches,this.syncMenuLayout(),this.syncExternalDrawerControl()},this.toggleTheme=()=>{const e=this.getThemeRoot();if(!e)return;e.scheme=e.scheme==="dark"?"light":"dark";const t=e.scheme==="dark"?"dark":"light";this.dispatchEvent(new CustomEvent(z.HEADER_THEME_TOGGLE,{detail:{scheme:t},bubbles:!0,composed:!0}))},this.handleMenuToggleClicked=()=>{if(this.menuOpen){this.closeNav();return}this.openNav()},this.onMenuDrawerOpened=()=>{this.menuOpen=!0,document.body.classList.add("menu-open"),this.burger&&(this.burger.menuOpen=!0)},this.onMenuDrawerClosed=()=>{this.menuOpen=!1,document.body.classList.remove("menu-open"),this.burger&&(this.burger.menuOpen=!1),this.demoteMenuToggle()},this.onMenuDrawerPresented=e=>{e.target!==this.menu||!this.menu?.isFullScreenDrawer||this.promoteMenuToggle()},this.menuTogglePromoted=!1,this.lastDrawerBrandKey="",this.inertedHeaderChrome=[]}syncMenuLayout(){if(!this.menuContainer.value||!this.menu||!this.menu.getWidth)return;this.positionPromotedToggle();const e=this.menu.getWidth();e>0&&(this.lastInlineMenuWidth=e);const t=this.lastInlineMenuWidth||e,s=this.getExternalDrawerTarget(),n=this.menuDisplay!=="inline",l=this.showBurger||this.menuDisplay==="drawer"||this.layout==="minimal"||this.previewCollapseRequested,r=n&&this.menuDisplay==="auto",d=r?this.layout==="centered-menu"?this.centeredMenuCapacity():this.menuContainer.value.clientWidth:0;this.menuTooLarge=r&&t>d,this.menu.sliding=n&&!s&&this.hasDrawerableContent()&&(this.menuTooLarge||l||this.mobileMenu)}centeredMenuCapacity(){const e=this.menuContainer.value?.parentElement;if(!(e instanceof HTMLElement))return 0;const t=d=>d?d.getBoundingClientRect().width:0,s=getComputedStyle(e),n=e.clientWidth-(Number.parseFloat(s.paddingLeft)||0)-(Number.parseFloat(s.paddingRight)||0),l=e.querySelector(":scope > section.brand"),r=e.querySelector(":scope > section.buttons");return n-t(l)-t(r)+t(r?.querySelector("esp-header-button.menu-toggle"))}menuHasContent(){return!!(this.menu??this.querySelector(':scope > [slot="menu"]'))?.querySelector("esp-menu-item, esp-menu-group")}hasDrawerableContent(){return this.showBurger||!!this.getExternalDrawerTarget()||this.menuHasContent()}getExternalDrawerTarget(){if(!this.drawerTarget)return null;const e=document.getElementById(this.drawerTarget);return e===this.menu?null:e&&"openDrawer"in e&&typeof e.openDrawer=="function"&&"closeDrawer"in e&&typeof e.closeDrawer=="function"?e:null}getBurgerFocusTarget(){const t=this.shadowRoot?.querySelector("esp-header-button.menu-toggle")?.shadowRoot?.querySelector("button"),s=this.menuButton.value?.shadowRoot?.querySelector("button");return t??s??null}getScrollTokens(){const e=this.scrollBehavior.split(/\s+/).map(t=>t.trim().toLowerCase()).filter(Boolean);return new Set(e.filter(t=>t!=="none"))}getEffectiveScrollThreshold(){return Number.isFinite(this.scrollThreshold)?Math.max(0,this.scrollThreshold):0}clearScrollState(){this.scrolled=!1,this.hiddenByScroll=!1,this.scrollProgress=0}runScrollStateUpdate(){const e=this.getScrollTokens();if(!e.size){this.clearScrollState();return}const t=Math.max(0,window.scrollY||document.documentElement.scrollTop||0),s=this.getEffectiveScrollThreshold(),n=Number.isFinite(this.dockOffset)?Math.max(0,this.dockOffset):s,l=t>(e.has("dock")?n:s),r=t>this.lastScrollY,d=e.has("reveal")&&r&&t>s&&!this.menuOpen;if(this.scrolled=l,this.hiddenByScroll=d,e.has("progress")){const m=document.documentElement,y=Math.max(1,m.scrollHeight-window.innerHeight);this.scrollProgress=Math.min(1,t/y)}else this.scrollProgress=0;this.lastScrollY=t}cancelScrollUpdate(){this.scrollFrame.cancel()}syncScrollListeners(){const e=this.getScrollTokens().size>0;if(e&&!this.scrollListenersAttached?(window.addEventListener("scroll",this.updateScrollState,{passive:!0}),window.addEventListener("resize",this.updateScrollState,{passive:!0}),this.scrollListenersAttached=!0):!e&&this.scrollListenersAttached&&this.removeScrollListeners(),e){this.updateScrollState();return}this.cancelScrollUpdate(),this.clearScrollState()}removeScrollListeners(){this.scrollListenersAttached&&(window.removeEventListener("scroll",this.updateScrollState),window.removeEventListener("resize",this.updateScrollState),this.scrollListenersAttached=!1)}addMenuDrawerListeners(){!this.menu||this.menuDrawerListenersAttached||(this.menu.addEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.menu.addEventListener("esp-menu-drawer-presented",this.onMenuDrawerPresented),this.menu.addEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed),this.menuDrawerListenersAttached=!0)}removeMenuDrawerListeners(){!this.menu||!this.menuDrawerListenersAttached||(this.menu.removeEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.menu.removeEventListener("esp-menu-drawer-presented",this.onMenuDrawerPresented),this.menu.removeEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed),this.menuDrawerListenersAttached=!1)}observeMenuContainer(){if(!this.menuContainer.value||this.observingMenuContainer)return;this.resizeObserver.observe(this.menuContainer.value);const e=this.menuContainer.value.parentElement;if(e){this.resizeObserver.observe(e);for(const t of e.querySelectorAll(":scope > section.brand, :scope > section.buttons"))this.resizeObserver.observe(t)}this.observingMenuContainer=!0}disconnectResizeObserver(){this.observingMenuContainer&&(this.resizeObserver.disconnect(),this.observingMenuContainer=!1)}observeMenuChildren(){!this.menu||this.menuChildObserver||(this.menuChildObserver=new MutationObserver(()=>{this.syncMenuLayout(),this.requestUpdate()}),this.menuChildObserver.observe(this.menu,{childList:!0,subtree:!0}))}syncMobileMenuQuery(){if("matchMedia"in window){if(!this.mobileMenuQuery){this.mobileMenuQuery=window.matchMedia(H),this.mobileMenu=this.mobileMenuQuery.matches,this.mobileMenuQuery.addEventListener("change",this.handleMobileMenuQueryChange);return}this.mobileMenu=this.mobileMenuQuery.matches}}getThemeRoot(){return this.traverseToClosest("esp-root")}syncExternalDrawerTarget(){const e=this.getExternalDrawerTarget(),t=e===this.menu?null:e;t!==this.externalDrawerTarget&&(this.externalDrawerTarget?.removeEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.externalDrawerTarget?.removeEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed),this.externalDrawerTarget instanceof p&&(this.externalDrawerTarget.hasExternalDrawerControl=!1),this.externalDrawerTarget=t,this.externalDrawerTarget?.addEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.externalDrawerTarget?.addEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed)),this.syncExternalDrawerControl()}burgerVisibleForTarget(){if(this.menuDisplay==="inline")return!1;const e=this.showBurger||this.menuDisplay==="drawer"||this.layout==="minimal"||this.previewCollapseRequested;return this.menuTooLarge||this.mobileMenu||e}syncExternalDrawerControl(){this.externalDrawerTarget instanceof p&&(this.externalDrawerTarget.hasExternalDrawerControl=this.burgerVisibleForTarget())}openNav(){const e=this.getBurgerFocusTarget(),t=this.getExternalDrawerTarget();if(this.burger&&(this.burger.menuOpen=!0),t){this.menuOpen=!0,t.openDrawer(e),document.body.classList.add("menu-open");return}if(this.menu){this.menu.sliding=!0,this.menuOpen=!0,this.menu.isFullScreenDrawer&&this.canPromoteMenuToggle()&&(this.menu.liftedCloseControl=this.getMenuToggleElement()),this.menu.openDrawer(e),document.body.classList.add("menu-open");return}this.burger&&(this.burger.menuOpen=!1)}closeNav(){this.menuOpen=!1,this.burger&&(this.burger.menuOpen=!1),this.demoteMenuToggle();const e=this.getExternalDrawerTarget();if(e){e.closeDrawer(),document.body.classList.remove("menu-open");return}this.menu&&(this.menu.closeDrawer(),document.body.classList.remove("menu-open"))}getMenuToggleElement(){return this.shadowRoot?.querySelector("esp-header-button.menu-toggle")??null}canPromoteMenuToggle(){const e=this.getMenuToggleElement();return!!e&&typeof e?.showPopover=="function"}setHeaderChromeInert(e){if(!e){for(const r of this.inertedHeaderChrome)r.inert=!1;this.inertedHeaderChrome=[];return}const t=this.menuContainer.value?.parentElement,s=this.getMenuToggleElement();if(!t||!s)return;const n=[];for(const r of t.querySelectorAll(":scope > section.brand, :scope > section.topbar"))n.push(r);const l=t.querySelector(":scope > section.buttons");for(const r of l?.children??[])if(!(!(r instanceof HTMLElement)||r===s)){if(r instanceof HTMLSlotElement){for(const d of r.assignedElements())d instanceof HTMLElement&&n.push(d);continue}n.push(r)}for(const r of n)r.inert||(r.inert=!0,this.inertedHeaderChrome.push(r))}promoteMenuToggle(){const e=this.getMenuToggleElement();if(!e||this.menuTogglePromoted||typeof e.showPopover!="function")return;const t=e.getBoundingClientRect();e.setAttribute("popover","manual"),Object.assign(e.style,{position:"fixed",inset:"auto",top:`${t.top}px`,left:`${t.left}px`,margin:"0",padding:"0",border:"0",background:"transparent",overflow:"visible"});try{e.showPopover()}catch{e.removeAttribute("popover"),e.removeAttribute("style"),this.menu&&(this.menu.liftedCloseControl=null);return}this.menuTogglePromoted=!0,this.menu&&(this.menu.liftedCloseControl=e),this.setHeaderChromeInert(!0)}positionPromotedToggle(){if(!this.menuTogglePromoted)return;const e=this.getMenuToggleElement(),t=this.shadowRoot?.querySelector("section.buttons");if(!e||!t)return;const s=t.getBoundingClientRect(),n=e.getBoundingClientRect(),l=getComputedStyle(t).direction==="rtl";e.style.top=`${s.top+(s.height-n.height)/2}px`,e.style.left=`${l?s.left:s.right-n.width}px`}demoteMenuToggle(){if(this.menu?.liftedCloseControl&&(this.menu.liftedCloseControl=null),!this.menuTogglePromoted)return;this.menuTogglePromoted=!1,this.setHeaderChromeInert(!1);const e=this.getMenuToggleElement();if(e){try{e.hidePopover()}catch{}e.removeAttribute("popover"),e.removeAttribute("style")}}syncDrawerBrand(){if(!this.menu)return;const e=E({scheme:this.scheme,brandLogo:this.brandLogo,brandColor:this.brandColor,lightBrandLogo:this.lightBrandLogo,darkBrandLogo:this.darkBrandLogo,lightBrandColor:this.lightBrandColor,darkBrandColor:this.darkBrandColor}),t=e.brandLogo||this.brandText?{brandLogo:e.brandLogo,brandText:this.brandText,brandHref:this.brandHref,brandAlt:this.brandAlt,brandColor:e.brandColor}:null,s=JSON.stringify(t);s!==this.lastDrawerBrandKey&&(this.lastDrawerBrandKey=s,this.menu.drawerBrand=t)}get burger(){return this.menuButton.value??void 0}willUpdate(e){super.willUpdate(e),e.has("layout")&&!g.allowedValues.has(this.layout)&&(this.layout=g.defaultValue),e.has("brandAlign")&&!b.allowedValues.has(this.brandAlign)&&(this.brandAlign=b.defaultValue),e.has("brandWrap")&&!f.allowedValues.has(this.brandWrap)&&(this.brandWrap=f.defaultValue),e.has("menuDisplay")&&!v.allowedValues.has(this.menuDisplay)&&(this.menuDisplay=v.defaultValue),e.has("themeToggle")&&!w.allowedValues.has(this.themeToggle)&&(this.themeToggle=w.defaultValue)}firstUpdated(e){if(super.firstUpdated(e),!this.menuContainer.value)return;const n=(this.menuContainer.value.firstElementChild?.assignedElements()??[])[0];n instanceof p?(this.menu=n,this.addMenuDrawerListeners(),this.observeMenuChildren(),this.syncDrawerBrand()):n&&console.warn("<esp-header>: the menu slot expects an <esp-menu> element, received",n),this.observeMenuContainer(),this.syncExternalDrawerTarget(),this.syncMobileMenuQuery(),this.syncScrollListeners(),this.syncMenuLayout()}updated(e){super.updated(e),this.syncDrawerBrand(),(e.has("showBurger")||e.has("drawerTarget")||e.has("menuDisplay")||e.has("layout")||e.has("previewCollapseRequested"))&&(this.syncExternalDrawerTarget(),this.syncMenuLayout()),(e.has("mobileMenu")||e.has("menuTooLarge"))&&this.syncExternalDrawerControl(),e.has("scrollBehavior")?this.syncScrollListeners():(e.has("scrollThreshold")||e.has("dockOffset"))&&this.updateScrollState()}connectedCallback(){super.connectedCallback(),this.syncScrollListeners(),this.syncMobileMenuQuery(),this.addMenuDrawerListeners(),this.syncExternalDrawerTarget(),this.observeMenuContainer(),this.observeMenuChildren()}disconnectedCallback(){this.removeMenuDrawerListeners(),this.externalDrawerTarget?.removeEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.externalDrawerTarget?.removeEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed),this.externalDrawerTarget instanceof p&&(this.externalDrawerTarget.hasExternalDrawerControl=!1),this.externalDrawerTarget=null,this.mobileMenuQuery?.removeEventListener("change",this.handleMobileMenuQueryChange),this.mobileMenuQuery=null,this.removeScrollListeners(),this.cancelScrollUpdate(),this.disconnectResizeObserver(),this.menuChildObserver?.disconnect(),this.menuChildObserver=null,this.demoteMenuToggle(),super.disconnectedCallback()}render(){const{menuOpen:e,menuTooLarge:t,mobileMenu:s}=this,n=this.menuDisplay!=="inline",l=n&&(this.showBurger||this.menuDisplay==="drawer"||this.layout==="minimal"||this.previewCollapseRequested),r=this.getScrollTokens(),d=r.has("progress"),m=E({scheme:this.scheme,brandLogo:this.brandLogo,brandColor:this.brandColor,lightBrandLogo:this.lightBrandLogo,darkBrandLogo:this.darkBrandLogo,lightBrandColor:this.lightBrandColor,darkBrandColor:this.darkBrandColor}),y={"--_esp-header-brand-color":m.brandColor||null,"--_esp-header-scroll-progress":String(this.scrollProgress)},L={"menu-open":e,"too-wide":n&&this.hasDrawerableContent()&&(t||s||l),[`layout-${this.layout}`]:!0,"is-scrolled":this.scrolled,"hide-on-scroll":this.hiddenByScroll,"scroll-compact":r.has("compact"),"scroll-elevate":r.has("elevate"),"scroll-transparent":r.has("transparent")||r.has("transparent-to-solid"),"scroll-collapse-topbar":r.has("collapse-topbar")},S=this.scheme==="dark"?"light":"dark";return x`
2
- <header class=${A(L)} style=${O(y)}>
1
+ var a=function(h,e,t,o){var r=arguments.length,i=r<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(h,e,t,o);else for(var d=h.length-1;d>=0;d--)(n=h[d])&&(i=(r<3?n(i):r>3?n(e,t,i):n(e,t))||i);return r>3&&i&&Object.defineProperty(e,t,i),i};import{css as k,html as x,nothing as T}from"lit";import{customElement as A,property as l,state as c}from"lit/decorators.js";import{classMap as O}from"lit/directives/class-map.js";import{styleMap as _}from"lit/directives/style-map.js";import"../burger/esp-burger.js";import{createRef as C,ref as D}from"lit/directives/ref.js";import{EspalierMenu as p}from"../menu/esp-menu.js";import{RafThrottle as E}from"../shared/raf-throttle.js";import{viewportSize as R}from"../shared/viewport.js";import{renderConfiguredBrand as z,resolveConfiguredBrand as M}from"../shared/configured-brand.js";import{EspalierElementBase as L}from"../shared/esp-element-base.js";import{ESP_EVENTS as H}from"../shared/events.js";const P="(max-width: 36rem)";function u(h,e){const t=new Set(h);return{allowedValues:t,converter:{fromAttribute(r){return r??e},toAttribute(r){return t.has(r)?r:e}},defaultValue:e}}const j=["standard","centered-brand","centered-menu","extended","extended-centered","minimal"],V=["start","center","end"],q=["truncate","wrap","nowrap"],N=["auto","inline","drawer"],U=["hidden","visible"],g=u(j,"standard"),b=u(V,"start"),f=u(q,"truncate"),v=u(N,"auto"),w=u(U,"hidden");let s=class extends L{constructor(){super(...arguments),this.menuOpen=!1,this.menuTooLarge=!1,this.mobileMenu=!1,this.scrolled=!1,this.hiddenByScroll=!1,this.scrollProgress=0,this.showBurger=!1,this.layout=g.defaultValue,this.brandText="",this.brandLogo="",this.lightBrandLogo="",this.darkBrandLogo="",this.brandHref="",this.brandAlt="",this.brandColor="",this.lightBrandColor="",this.darkBrandColor="",this.brandAlign=b.defaultValue,this.brandWrap=f.defaultValue,this.menuDisplay=v.defaultValue,this.themeToggle=w.defaultValue,this.scrollBehavior="none",this.scrollThreshold=16,this.dockOffset=0,this.drawerTarget="",this.previewCollapseRequested=!1,this.fullBleedContent=!1,this.menuContainer=C(),this.menuButton=C(),this.menu=void 0,this.externalDrawerTarget=null,this.lastScrollY=0,this.lastInlineMenuWidth=0,this.mobileMenuQuery=null,this.menuDrawerListenersAttached=!1,this.observingMenuContainer=!1,this.scrollListenersAttached=!1,this.scrollFrame=new E(()=>this.runScrollStateUpdate()),this.resizeObserver=new ResizeObserver(()=>this.syncMenuLayout()),this.menuChildObserver=null,this.updateScrollState=()=>this.scrollFrame.schedule(),this.handleMobileMenuQueryChange=e=>{this.mobileMenu=e.matches,this.syncMenuLayout(),this.syncExternalDrawerControl()},this.toggleTheme=()=>{const e=this.getThemeRoot();if(!e)return;e.scheme=e.scheme==="dark"?"light":"dark";const t=e.scheme==="dark"?"dark":"light";this.dispatchEvent(new CustomEvent(H.HEADER_THEME_TOGGLE,{detail:{scheme:t},bubbles:!0,composed:!0}))},this.handleMenuToggleClicked=()=>{if(this.menuOpen){this.closeNav();return}this.openNav()},this.onMenuDrawerOpened=()=>{this.menuOpen=!0,document.body.classList.add("menu-open"),this.burger&&(this.burger.menuOpen=!0)},this.onMenuDrawerClosed=()=>{this.menuOpen=!1,document.body.classList.remove("menu-open"),this.burger&&(this.burger.menuOpen=!1),this.demoteMenuToggle()},this.onMenuDrawerPresented=e=>{e.target!==this.menu||!this.menu?.isFullScreenDrawer||this.promoteMenuToggle()},this.menuTogglePromoted=!1,this.promotedToggleFrame=new E(()=>this.positionPromotedToggle()),this.handlePromotedViewportResize=()=>this.promotedToggleFrame.schedule(),this.lastDrawerBrandKey="",this.inertedHeaderChrome=[]}syncMenuLayout(){if(!this.menuContainer.value||!this.menu||!this.menu.getWidth)return;this.positionPromotedToggle();const e=this.menu.getWidth();e>0&&(this.lastInlineMenuWidth=e);const t=this.lastInlineMenuWidth||e,o=this.getExternalDrawerTarget(),r=this.menuDisplay!=="inline",i=this.showBurger||this.menuDisplay==="drawer"||this.layout==="minimal"||this.previewCollapseRequested,n=r&&this.menuDisplay==="auto",d=n?this.layout==="centered-menu"?this.centeredMenuCapacity():this.menuContainer.value.clientWidth:0;this.menuTooLarge=n&&t>d,this.menu.sliding=r&&!o&&this.hasDrawerableContent()&&(this.menuTooLarge||i||this.mobileMenu)}centeredMenuCapacity(){const e=this.menuContainer.value?.parentElement;if(!(e instanceof HTMLElement))return 0;const t=d=>d?d.getBoundingClientRect().width:0,o=getComputedStyle(e),r=e.clientWidth-(Number.parseFloat(o.paddingLeft)||0)-(Number.parseFloat(o.paddingRight)||0),i=e.querySelector(":scope > section.brand"),n=e.querySelector(":scope > section.buttons");return r-t(i)-t(n)+t(n?.querySelector("esp-header-button.menu-toggle"))}menuHasContent(){return!!(this.menu??this.querySelector(':scope > [slot="menu"]'))?.querySelector("esp-menu-item, esp-menu-group")}hasDrawerableContent(){return this.showBurger||!!this.getExternalDrawerTarget()||this.menuHasContent()}getExternalDrawerTarget(){if(!this.drawerTarget)return null;const e=document.getElementById(this.drawerTarget);return e===this.menu?null:e&&"openDrawer"in e&&typeof e.openDrawer=="function"&&"closeDrawer"in e&&typeof e.closeDrawer=="function"?e:null}getBurgerFocusTarget(){const t=this.shadowRoot?.querySelector("esp-header-button.menu-toggle")?.shadowRoot?.querySelector("button"),o=this.menuButton.value?.shadowRoot?.querySelector("button");return t??o??null}getScrollTokens(){const e=this.scrollBehavior.split(/\s+/).map(t=>t.trim().toLowerCase()).filter(Boolean);return new Set(e.filter(t=>t!=="none"))}getEffectiveScrollThreshold(){return Number.isFinite(this.scrollThreshold)?Math.max(0,this.scrollThreshold):0}clearScrollState(){this.scrolled=!1,this.hiddenByScroll=!1,this.scrollProgress=0}runScrollStateUpdate(){const e=this.getScrollTokens();if(!e.size){this.clearScrollState();return}const t=Math.max(0,window.scrollY||document.documentElement.scrollTop||0),o=this.getEffectiveScrollThreshold(),r=Number.isFinite(this.dockOffset)?Math.max(0,this.dockOffset):o,i=t>(e.has("dock")?r:o),n=t>this.lastScrollY,d=e.has("reveal")&&n&&t>o&&!this.menuOpen;if(this.scrolled=i,this.hiddenByScroll=d,e.has("progress")){const m=document.documentElement,y=Math.max(1,m.scrollHeight-window.innerHeight);this.scrollProgress=Math.min(1,t/y)}else this.scrollProgress=0;this.lastScrollY=t}cancelScrollUpdate(){this.scrollFrame.cancel()}syncScrollListeners(){const e=this.getScrollTokens().size>0;if(e&&!this.scrollListenersAttached?(window.addEventListener("scroll",this.updateScrollState,{passive:!0}),window.addEventListener("resize",this.updateScrollState,{passive:!0}),this.scrollListenersAttached=!0):!e&&this.scrollListenersAttached&&this.removeScrollListeners(),e){this.updateScrollState();return}this.cancelScrollUpdate(),this.clearScrollState()}removeScrollListeners(){this.scrollListenersAttached&&(window.removeEventListener("scroll",this.updateScrollState),window.removeEventListener("resize",this.updateScrollState),this.scrollListenersAttached=!1)}addMenuDrawerListeners(){!this.menu||this.menuDrawerListenersAttached||(this.menu.addEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.menu.addEventListener("esp-menu-drawer-presented",this.onMenuDrawerPresented),this.menu.addEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed),this.menuDrawerListenersAttached=!0)}removeMenuDrawerListeners(){!this.menu||!this.menuDrawerListenersAttached||(this.menu.removeEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.menu.removeEventListener("esp-menu-drawer-presented",this.onMenuDrawerPresented),this.menu.removeEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed),this.menuDrawerListenersAttached=!1)}observeMenuContainer(){if(!this.menuContainer.value||this.observingMenuContainer)return;this.resizeObserver.observe(this.menuContainer.value);const e=this.menuContainer.value.parentElement;if(e){this.resizeObserver.observe(e);for(const t of e.querySelectorAll(":scope > section.brand, :scope > section.buttons"))this.resizeObserver.observe(t)}this.observingMenuContainer=!0}disconnectResizeObserver(){this.observingMenuContainer&&(this.resizeObserver.disconnect(),this.observingMenuContainer=!1)}observeMenuChildren(){!this.menu||this.menuChildObserver||(this.menuChildObserver=new MutationObserver(()=>{this.syncMenuLayout(),this.requestUpdate()}),this.menuChildObserver.observe(this.menu,{childList:!0,subtree:!0}))}syncMobileMenuQuery(){if("matchMedia"in window){if(!this.mobileMenuQuery){this.mobileMenuQuery=window.matchMedia(P),this.mobileMenu=this.mobileMenuQuery.matches,this.mobileMenuQuery.addEventListener("change",this.handleMobileMenuQueryChange);return}this.mobileMenu=this.mobileMenuQuery.matches}}getThemeRoot(){return this.traverseToClosest("esp-root")}syncExternalDrawerTarget(){const e=this.getExternalDrawerTarget(),t=e===this.menu?null:e;t!==this.externalDrawerTarget&&(this.externalDrawerTarget?.removeEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.externalDrawerTarget?.removeEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed),this.externalDrawerTarget instanceof p&&(this.externalDrawerTarget.hasExternalDrawerControl=!1),this.externalDrawerTarget=t,this.externalDrawerTarget?.addEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.externalDrawerTarget?.addEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed)),this.syncExternalDrawerControl()}burgerVisibleForTarget(){if(this.menuDisplay==="inline")return!1;const e=this.showBurger||this.menuDisplay==="drawer"||this.layout==="minimal"||this.previewCollapseRequested;return this.menuTooLarge||this.mobileMenu||e}syncExternalDrawerControl(){this.externalDrawerTarget instanceof p&&(this.externalDrawerTarget.hasExternalDrawerControl=this.burgerVisibleForTarget())}openNav(){const e=this.getBurgerFocusTarget(),t=this.getExternalDrawerTarget();if(this.burger&&(this.burger.menuOpen=!0),t){this.menuOpen=!0,t.openDrawer(e),document.body.classList.add("menu-open");return}if(this.menu){this.menu.sliding=!0,this.menuOpen=!0,this.menu.isFullScreenDrawer&&this.canPromoteMenuToggle()&&(this.menu.liftedCloseControl=this.getMenuToggleElement()),this.menu.openDrawer(e),document.body.classList.add("menu-open");return}this.burger&&(this.burger.menuOpen=!1)}closeNav(){this.menuOpen=!1,this.burger&&(this.burger.menuOpen=!1),this.demoteMenuToggle();const e=this.getExternalDrawerTarget();if(e){e.closeDrawer(),document.body.classList.remove("menu-open");return}this.menu&&(this.menu.closeDrawer(),document.body.classList.remove("menu-open"))}getMenuToggleElement(){return this.shadowRoot?.querySelector("esp-header-button.menu-toggle")??null}canPromoteMenuToggle(){const e=this.getMenuToggleElement();return!!e&&typeof e?.showPopover=="function"}setHeaderChromeInert(e){if(!e){for(const n of this.inertedHeaderChrome)n.inert=!1;this.inertedHeaderChrome=[];return}const t=this.menuContainer.value?.parentElement,o=this.getMenuToggleElement();if(!t||!o)return;const r=[];for(const n of t.querySelectorAll(":scope > section.brand, :scope > section.topbar"))r.push(n);const i=t.querySelector(":scope > section.buttons");for(const n of i?.children??[])if(!(!(n instanceof HTMLElement)||n===o)){if(n instanceof HTMLSlotElement){for(const d of n.assignedElements())d instanceof HTMLElement&&r.push(d);continue}r.push(n)}for(const n of r)n.inert||(n.inert=!0,this.inertedHeaderChrome.push(n))}promoteMenuToggle(){const e=this.getMenuToggleElement();if(!e||this.menuTogglePromoted||typeof e.showPopover!="function")return;const t=e.getBoundingClientRect();e.setAttribute("popover","manual"),Object.assign(e.style,{position:"fixed",inset:"auto",margin:"0",padding:"0",border:"0",background:"transparent",overflow:"visible"}),this.setPromotedTogglePosition(e,t.left,t.top,t.width,t.height);try{e.showPopover()}catch{e.removeAttribute("popover"),e.removeAttribute("style"),this.menu&&(this.menu.liftedCloseControl=null);return}this.menuTogglePromoted=!0,window.addEventListener("resize",this.handlePromotedViewportResize),this.menu&&(this.menu.liftedCloseControl=e),this.setHeaderChromeInert(!0)}positionPromotedToggle(){if(!this.menuTogglePromoted)return;const e=this.getMenuToggleElement(),t=this.shadowRoot?.querySelector("section.buttons");if(!e||!t)return;const o=t.getBoundingClientRect(),r=e.getBoundingClientRect(),i=getComputedStyle(t).direction==="rtl";this.setPromotedTogglePosition(e,i?o.left:o.right-r.width,o.top+(o.height-r.height)/2,r.width,r.height)}setPromotedTogglePosition(e,t,o,r,i){const n=R();e.style.left=`${Math.max(0,Math.min(t,n.width-r))}px`,e.style.top=`${Math.max(0,Math.min(o,n.height-i))}px`}demoteMenuToggle(){if(window.removeEventListener("resize",this.handlePromotedViewportResize),this.promotedToggleFrame.cancel(),this.menu?.liftedCloseControl&&(this.menu.liftedCloseControl=null),!this.menuTogglePromoted)return;this.menuTogglePromoted=!1,this.setHeaderChromeInert(!1);const e=this.getMenuToggleElement();if(e){try{e.hidePopover()}catch{}e.removeAttribute("popover"),e.removeAttribute("style")}}syncDrawerBrand(){if(!this.menu)return;const e=M({scheme:this.scheme,brandLogo:this.brandLogo,brandColor:this.brandColor,lightBrandLogo:this.lightBrandLogo,darkBrandLogo:this.darkBrandLogo,lightBrandColor:this.lightBrandColor,darkBrandColor:this.darkBrandColor}),t=e.brandLogo||this.brandText?{brandLogo:e.brandLogo,brandText:this.brandText,brandHref:this.brandHref,brandAlt:this.brandAlt,brandColor:e.brandColor}:null,o=JSON.stringify(t);o!==this.lastDrawerBrandKey&&(this.lastDrawerBrandKey=o,this.menu.drawerBrand=t)}get burger(){return this.menuButton.value??void 0}willUpdate(e){super.willUpdate(e),e.has("layout")&&!g.allowedValues.has(this.layout)&&(this.layout=g.defaultValue),e.has("brandAlign")&&!b.allowedValues.has(this.brandAlign)&&(this.brandAlign=b.defaultValue),e.has("brandWrap")&&!f.allowedValues.has(this.brandWrap)&&(this.brandWrap=f.defaultValue),e.has("menuDisplay")&&!v.allowedValues.has(this.menuDisplay)&&(this.menuDisplay=v.defaultValue),e.has("themeToggle")&&!w.allowedValues.has(this.themeToggle)&&(this.themeToggle=w.defaultValue)}firstUpdated(e){if(super.firstUpdated(e),!this.menuContainer.value)return;const r=(this.menuContainer.value.firstElementChild?.assignedElements()??[])[0];r instanceof p?(this.menu=r,this.addMenuDrawerListeners(),this.observeMenuChildren(),this.syncDrawerBrand()):r&&console.warn("<esp-header>: the menu slot expects an <esp-menu> element, received",r),this.observeMenuContainer(),this.syncExternalDrawerTarget(),this.syncMobileMenuQuery(),this.syncScrollListeners(),this.syncMenuLayout()}updated(e){super.updated(e),this.syncDrawerBrand(),(e.has("showBurger")||e.has("drawerTarget")||e.has("menuDisplay")||e.has("layout")||e.has("previewCollapseRequested"))&&(this.syncExternalDrawerTarget(),this.syncMenuLayout()),(e.has("mobileMenu")||e.has("menuTooLarge"))&&this.syncExternalDrawerControl(),e.has("scrollBehavior")?this.syncScrollListeners():(e.has("scrollThreshold")||e.has("dockOffset"))&&this.updateScrollState()}connectedCallback(){super.connectedCallback(),this.syncScrollListeners(),this.syncMobileMenuQuery(),this.addMenuDrawerListeners(),this.syncExternalDrawerTarget(),this.observeMenuContainer(),this.observeMenuChildren()}disconnectedCallback(){this.removeMenuDrawerListeners(),this.externalDrawerTarget?.removeEventListener("esp-menu-drawer-opened",this.onMenuDrawerOpened),this.externalDrawerTarget?.removeEventListener("esp-menu-drawer-closed",this.onMenuDrawerClosed),this.externalDrawerTarget instanceof p&&(this.externalDrawerTarget.hasExternalDrawerControl=!1),this.externalDrawerTarget=null,this.mobileMenuQuery?.removeEventListener("change",this.handleMobileMenuQueryChange),this.mobileMenuQuery=null,this.removeScrollListeners(),this.cancelScrollUpdate(),this.disconnectResizeObserver(),this.menuChildObserver?.disconnect(),this.menuChildObserver=null,this.demoteMenuToggle(),super.disconnectedCallback()}render(){const{menuOpen:e,menuTooLarge:t,mobileMenu:o}=this,r=this.menuDisplay!=="inline",i=r&&(this.showBurger||this.menuDisplay==="drawer"||this.layout==="minimal"||this.previewCollapseRequested),n=this.getScrollTokens(),d=n.has("progress"),m=M({scheme:this.scheme,brandLogo:this.brandLogo,brandColor:this.brandColor,lightBrandLogo:this.lightBrandLogo,darkBrandLogo:this.darkBrandLogo,lightBrandColor:this.lightBrandColor,darkBrandColor:this.darkBrandColor}),y={"--_esp-header-brand-color":m.brandColor||null,"--_esp-header-scroll-progress":String(this.scrollProgress)},S={"menu-open":e,"too-wide":r&&this.hasDrawerableContent()&&(t||o||i),[`layout-${this.layout}`]:!0,"is-scrolled":this.scrolled,"hide-on-scroll":this.hiddenByScroll,"scroll-compact":n.has("compact"),"scroll-elevate":n.has("elevate"),"scroll-transparent":n.has("transparent")||n.has("transparent-to-solid"),"scroll-collapse-topbar":n.has("collapse-topbar")},B=this.scheme==="dark"?"light":"dark";return x`
2
+ <header class=${O(S)} style=${_(y)}>
3
3
  <section class="topbar">
4
4
  <slot name="topbar"></slot>
5
5
  </section>
6
6
 
7
7
  <section class="brand">
8
8
  <slot name="brand"
9
- >${R({brandLogo:m.brandLogo,brandText:this.brandText,brandHref:this.brandHref,brandAlt:this.brandAlt})}</slot
9
+ >${z({brandLogo:m.brandLogo,brandText:this.brandText,brandHref:this.brandHref,brandAlt:this.brandAlt})}</slot
10
10
  >
11
11
  </section>
12
12
 
@@ -19,7 +19,7 @@ var a=function(h,e,t,s){var n=arguments.length,l=n<3?e:s===null?s=Object.getOwnP
19
19
  ${this.themeToggle==="visible"?x`<esp-header-button
20
20
  class="theme-toggle"
21
21
  icon=${this.scheme==="dark"?"sun":"moon"}
22
- aria-label=${`Switch to ${S} mode`}
22
+ aria-label=${`Switch to ${B} mode`}
23
23
  @esp-clicked=${this.toggleTheme}
24
24
  ></esp-header-button>`:T}
25
25
  <esp-header-button
@@ -35,7 +35,7 @@ var a=function(h,e,t,s){var n=arguments.length,l=n<3?e:s===null?s=Object.getOwnP
35
35
  </section>
36
36
  ${d?x`<div class="scroll-progress" aria-hidden="true"></div>`:T}
37
37
  </header>
38
- `}};o.styles=[...M.styles,B`
38
+ `}};s.styles=[...L.styles,k`
39
39
  :host {
40
40
  --_esp-header-current-height: var(--esp-header-height, calc(4.5 * var(--esp-size-small)));
41
41
 
@@ -492,4 +492,4 @@ var a=function(h,e,t,s){var n=arguments.length,l=n<3?e:s===null?s=Object.getOwnP
492
492
  transition: none;
493
493
  }
494
494
  }
495
- `],a([c()],o.prototype,"menuOpen",void 0),a([c()],o.prototype,"menuTooLarge",void 0),a([c()],o.prototype,"mobileMenu",void 0),a([c()],o.prototype,"scrolled",void 0),a([c()],o.prototype,"hiddenByScroll",void 0),a([c()],o.prototype,"scrollProgress",void 0),a([i({attribute:"show-burger",type:Boolean})],o.prototype,"showBurger",void 0),a([i({converter:g.converter,reflect:!0})],o.prototype,"layout",void 0),a([i({attribute:"brand-text",type:String})],o.prototype,"brandText",void 0),a([i({attribute:"brand-logo",type:String})],o.prototype,"brandLogo",void 0),a([i({attribute:"light-brand-logo",type:String})],o.prototype,"lightBrandLogo",void 0),a([i({attribute:"dark-brand-logo",type:String})],o.prototype,"darkBrandLogo",void 0),a([i({attribute:"brand-href",type:String})],o.prototype,"brandHref",void 0),a([i({attribute:"brand-alt",type:String})],o.prototype,"brandAlt",void 0),a([i({attribute:"brand-color",type:String})],o.prototype,"brandColor",void 0),a([i({attribute:"light-brand-color",type:String})],o.prototype,"lightBrandColor",void 0),a([i({attribute:"dark-brand-color",type:String})],o.prototype,"darkBrandColor",void 0),a([i({attribute:"brand-align",converter:b.converter,reflect:!0})],o.prototype,"brandAlign",void 0),a([i({attribute:"brand-wrap",converter:f.converter,reflect:!0})],o.prototype,"brandWrap",void 0),a([i({attribute:"menu-display",converter:v.converter,reflect:!0})],o.prototype,"menuDisplay",void 0),a([i({attribute:"theme-toggle",converter:w.converter,reflect:!0})],o.prototype,"themeToggle",void 0),a([i({attribute:"scroll-behavior",type:String})],o.prototype,"scrollBehavior",void 0),a([i({attribute:"scroll-threshold",type:Number})],o.prototype,"scrollThreshold",void 0),a([i({attribute:"dock-offset",type:Number})],o.prototype,"dockOffset",void 0),a([i({attribute:"drawer-target",type:String})],o.prototype,"drawerTarget",void 0),a([i({attribute:!1})],o.prototype,"previewCollapseRequested",void 0),a([i({attribute:"full-bleed-content",type:Boolean,reflect:!0})],o.prototype,"fullBleedContent",void 0),o=a([k("esp-header")],o);export{o as EspalierHeader};
495
+ `],a([c()],s.prototype,"menuOpen",void 0),a([c()],s.prototype,"menuTooLarge",void 0),a([c()],s.prototype,"mobileMenu",void 0),a([c()],s.prototype,"scrolled",void 0),a([c()],s.prototype,"hiddenByScroll",void 0),a([c()],s.prototype,"scrollProgress",void 0),a([l({attribute:"show-burger",type:Boolean})],s.prototype,"showBurger",void 0),a([l({converter:g.converter,reflect:!0})],s.prototype,"layout",void 0),a([l({attribute:"brand-text",type:String})],s.prototype,"brandText",void 0),a([l({attribute:"brand-logo",type:String})],s.prototype,"brandLogo",void 0),a([l({attribute:"light-brand-logo",type:String})],s.prototype,"lightBrandLogo",void 0),a([l({attribute:"dark-brand-logo",type:String})],s.prototype,"darkBrandLogo",void 0),a([l({attribute:"brand-href",type:String})],s.prototype,"brandHref",void 0),a([l({attribute:"brand-alt",type:String})],s.prototype,"brandAlt",void 0),a([l({attribute:"brand-color",type:String})],s.prototype,"brandColor",void 0),a([l({attribute:"light-brand-color",type:String})],s.prototype,"lightBrandColor",void 0),a([l({attribute:"dark-brand-color",type:String})],s.prototype,"darkBrandColor",void 0),a([l({attribute:"brand-align",converter:b.converter,reflect:!0})],s.prototype,"brandAlign",void 0),a([l({attribute:"brand-wrap",converter:f.converter,reflect:!0})],s.prototype,"brandWrap",void 0),a([l({attribute:"menu-display",converter:v.converter,reflect:!0})],s.prototype,"menuDisplay",void 0),a([l({attribute:"theme-toggle",converter:w.converter,reflect:!0})],s.prototype,"themeToggle",void 0),a([l({attribute:"scroll-behavior",type:String})],s.prototype,"scrollBehavior",void 0),a([l({attribute:"scroll-threshold",type:Number})],s.prototype,"scrollThreshold",void 0),a([l({attribute:"dock-offset",type:Number})],s.prototype,"dockOffset",void 0),a([l({attribute:"drawer-target",type:String})],s.prototype,"drawerTarget",void 0),a([l({attribute:!1})],s.prototype,"previewCollapseRequested",void 0),a([l({attribute:"full-bleed-content",type:Boolean,reflect:!0})],s.prototype,"fullBleedContent",void 0),s=a([A("esp-header")],s);export{s as EspalierHeader};
@@ -2,7 +2,7 @@ import { nothing, type PropertyValues, type TemplateResult } from "lit";
2
2
  import { EspalierElementBase } from "../shared/esp-element-base.js";
3
3
  import { type CursorPageRequest, type CursorPageResult } from "../shared/cursor-pagination.js";
4
4
  import "../shared/virtualizer/lit-virtualizer.js";
5
- export type RepeaterLayout = "list" | "grid";
5
+ export type RepeaterLayout = "list" | "grid" | "masonry";
6
6
  export type RepeaterScrollModel = "contained" | "page";
7
7
  export type RepeaterRenderValue = TemplateResult | Node | string | number | boolean | typeof nothing | null | undefined;
8
8
  export type RepeaterRenderItem<T = unknown> = (item: T, index: number) => RepeaterRenderValue;
@@ -19,6 +19,15 @@ export type RepeaterRenderItem<T = unknown> = (item: T, index: number) => Repeat
19
19
  * provide a fixed fallback with `grid-columns` and override the live column
20
20
  * count with `--esp-repeater-grid-columns` in media queries.
21
21
  *
22
+ * Use `layout="masonry"` for cards of uneven height, such as an image library
23
+ * mixing portrait and landscape photos. Items keep their document order and
24
+ * flow into the same responsive column count as `grid`, but each card takes
25
+ * only the height it needs and the next card starts directly below it, so
26
+ * columns pack tightly instead of leaving blank space under shorter cards.
27
+ * Masonry measures every card, so it keeps all loaded items in the DOM
28
+ * instead of virtualizing them; pair it with cursor paging for large
29
+ * collections.
30
+ *
22
31
  * Use `scroll-model="page"` when the repeater should participate in the
23
32
  * document's natural page scroll instead of owning a nested scrolling
24
33
  * viewport. In page mode, `list-height` is ignored.
@@ -35,9 +44,9 @@ export type RepeaterRenderItem<T = unknown> = (item: T, index: number) => Repeat
35
44
  * @cssprop --esp-repeater-gap - Space between repeated items.
36
45
  * @cssprop --esp-repeater-padding - Padding used by repeater state panels and the loading/error footer.
37
46
  * @cssprop --esp-repeater-content-padding - Padding inside the virtualized content region. Defaults to `0`.
38
- * @cssprop --esp-repeater-grid-columns - Grid column count when `layout="grid"`. Supports media-query overrides.
39
- * @cssprop --esp-repeater-grid-column-gap - Horizontal gap between grid columns.
40
- * @cssprop --esp-repeater-grid-row-gap - Vertical gap between grid rows.
47
+ * @cssprop --esp-repeater-grid-columns - Column count when `layout="grid"` or `layout="masonry"`. Supports media-query overrides.
48
+ * @cssprop --esp-repeater-grid-column-gap - Horizontal gap between grid or masonry columns.
49
+ * @cssprop --esp-repeater-grid-row-gap - Vertical gap between grid rows or stacked masonry cards.
41
50
  *
42
51
  * @docPageTitle Repeater
43
52
  * @docUrl /components/repeater
@@ -268,6 +277,74 @@ export type RepeaterRenderItem<T = unknown> = (item: T, index: number) => Repeat
268
277
  * };
269
278
  * </script>
270
279
  * ```
280
+ *
281
+ * @example Masonry gallery with mixed portrait and landscape cards
282
+ * ```html
283
+ * <style>
284
+ * esp-repeater[layout="masonry"] {
285
+ * --esp-repeater-grid-columns: 1;
286
+ * --esp-repeater-grid-column-gap: var(--esp-size-padding);
287
+ * --esp-repeater-grid-row-gap: var(--esp-size-padding);
288
+ * }
289
+ *
290
+ * @media (min-width: 48rem) {
291
+ * esp-repeater[layout="masonry"] {
292
+ * --esp-repeater-grid-columns: 2;
293
+ * }
294
+ * }
295
+ *
296
+ * @media (min-width: 72rem) {
297
+ * esp-repeater[layout="masonry"] {
298
+ * --esp-repeater-grid-columns: 3;
299
+ * }
300
+ * }
301
+ * </style>
302
+ *
303
+ * <esp-repeater
304
+ * id="masonry-gallery"
305
+ * layout="masonry"
306
+ * scroll-model="page"
307
+ * grid-columns="1"
308
+ * page-size="9"
309
+ * aria-label="Masonry image gallery"
310
+ * ></esp-repeater>
311
+ * <script>
312
+ * const repeater = findByTagName("esp-repeater")[0];
313
+ * const allImages = Array.from({ length: 30 }, (_, index) => {
314
+ * const portrait = index % 3 === 1;
315
+ * return {
316
+ * id: index + 1,
317
+ * title: `Image ${index + 1}`,
318
+ * ratio: portrait ? "2 / 3" : "3 / 2",
319
+ * thumbnail: portrait
320
+ * ? `https://picsum.photos/seed/masonry-${index + 1}/320/480`
321
+ * : `https://picsum.photos/seed/masonry-${index + 1}/480/320`,
322
+ * };
323
+ * });
324
+ *
325
+ * repeater.renderItem = (image) => {
326
+ * const card = document.createElement("esp-box");
327
+ * card.innerHTML = `
328
+ * <article style="display:grid; gap:var(--esp-size-small);">
329
+ * <img src="${image.thumbnail}" alt="" style="width:100%; aspect-ratio:${image.ratio}; object-fit:cover; border-radius:var(--esp-size-border-radius);" />
330
+ * <h3 style="margin:0;">${image.title}</h3>
331
+ * </article>
332
+ * `;
333
+ * return card;
334
+ * };
335
+ *
336
+ * repeater.fetchPage = async ({ cursor, limit }) => {
337
+ * const start = cursor ? Number(cursor) : 0;
338
+ * const items = allImages.slice(start, start + limit);
339
+ * const nextStart = start + limit;
340
+ *
341
+ * return {
342
+ * items,
343
+ * nextCursor: nextStart < allImages.length ? String(nextStart) : null,
344
+ * };
345
+ * };
346
+ * </script>
347
+ * ```
271
348
  */
272
349
  export declare class EspalierRepeater extends EspalierElementBase {
273
350
  /**
@@ -288,9 +365,11 @@ export declare class EspalierRepeater extends EspalierElementBase {
288
365
  * Visual layout mode for the rendered content.
289
366
  *
290
367
  * Use `grid` to opt into responsive card-style rows while
291
- * preserving virtualization and paging behavior.
368
+ * preserving virtualization and paging behavior. Use `masonry` to
369
+ * pack cards of uneven height into the same responsive columns;
370
+ * masonry keeps every loaded item in the DOM rather than virtualizing.
292
371
  *
293
- * @type {"list" | "grid"}
372
+ * @type {"list" | "grid" | "masonry"}
294
373
  */
295
374
  layout: RepeaterLayout;
296
375
  /**
@@ -304,9 +383,9 @@ export declare class EspalierRepeater extends EspalierElementBase {
304
383
  */
305
384
  scrollModel: RepeaterScrollModel;
306
385
  /**
307
- * Fixed grid column count fallback used when `layout="grid"`
308
- * and no `--esp-repeater-grid-columns` custom property override
309
- * is applied.
386
+ * Fixed column count fallback used when `layout="grid"` or
387
+ * `layout="masonry"` and no `--esp-repeater-grid-columns` custom
388
+ * property override is applied.
310
389
  *
311
390
  * @type {number}
312
391
  */
@@ -1,28 +1,44 @@
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
- ${i(e,t)}
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
1
+ var n=function(f,e,t,s){var r=arguments.length,o=r<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,t):s,i;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(f,e,t,s);else for(var c=f.length-1;c>=0;c--)(i=f[c])&&(o=(r<3?i(o):r>3?i(e,t,o):i(e,t))||o);return r>3&&o&&Object.defineProperty(e,t,o),o};import{css as B,html as h,nothing as S}from"lit";import{customElement as N,property as d,state as g}from"lit/decorators.js";import{keyed as q}from"lit/directives/keyed.js";import{ifDefined as M}from"lit/directives/if-defined.js";import{createRef as R,ref as w}from"lit/directives/ref.js";import{repeat as T}from"lit/directives/repeat.js";import{styleMap as p}from"lit/directives/style-map.js";import{EspalierElementBase as I}from"../shared/esp-element-base.js";import{accumulatePage as V,RequestVersionGuard as j}from"../shared/cursor-pagination.js";import"../shared/virtualizer/lit-virtualizer.js";const P=4;let a=class extends I{constructor(){super(...arguments),this.virtualizerRef=R(),this.containerRef=R(),this.pageLoads=new j,this.nextCursor=null,this.lastRangeEnd=-1,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.masonryRef=R(),this.masonryCellObserver=null,this.masonryObservedCells=new Set,this.masonryPrefetchObserver=null,this.footerHoldScrollListener=null,this.isAdjustingHeight=!1,this.pendingHeightRetry=!1,this.heightRetryObserver=null,this.isLoadingPage=!1,this.loadedItems=[],this.hasMoreData=!1,this.effectiveListHeight="60vh",this.loadError="",this.footerHoldHeight=0,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 h``;const s=this.renderItem??(r=>this.renderFallbackItem(r));return h`<div class="repeater-item" part="item" role="listitem">
2
+ ${s(e,t)}
3
+ </div>`},this.renderVirtualRow=e=>{if(e===void 0)return h``;const t=this.renderItem??(r=>this.renderFallbackItem(r)),s={gridTemplateColumns:`repeat(${this.effectiveGridColumns}, minmax(0, 1fr))`};return h`<div
4
4
  class="repeater-row"
5
5
  part="row"
6
6
  role="presentation"
7
- style=${A(i)}
7
+ style=${p(s)}
8
8
  >
9
- ${e.items.map((r,s)=>d`<div class="repeater-item repeater-grid-cell" part="item" role="listitem">
10
- ${t(r,e.startIndex+s)}
9
+ ${e.items.map((r,o)=>h`<div class="repeater-item repeater-grid-cell" part="item" role="listitem">
10
+ ${t(r,e.startIndex+o)}
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.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")}>
12
+ </div>`},this.renderGridVirtualItem=(e,t)=>this.isGridRow(e)?this.renderVirtualRow(e,t):h``}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 isMasonryLayout(){return this.layout==="masonry"}get usesColumns(){return this.isGridLayout||this.isMasonryLayout}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.usesColumns?this.resolvedGridColumns:1}connectedCallback(){super.connectedCallback(),this.attachObservers(),this.lastObservedWidth=this.clientWidth,this.syncResolvedGridColumns(),this.hasUpdated&&this.isContainedScrollModel&&this.adjustListHeight(),this.hasUpdated&&this.isMasonryLayout&&this.syncMasonryObservers()}firstUpdated(e){if(super.firstUpdated(e),this.lastObservedWidth=this.clientWidth,this.fetchPage){this.startPagedLoad(null);return}this.adjustListHeight()}disconnectedCallback(){this.disconnectMasonryObservers(),this.releaseFooterHold(),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){if(super.updated(e),e.has("layout")&&(this.syncGridObservers(),this.isMasonryLayout||this.disconnectMasonryObservers()),this.isMasonryLayout&&(e.has("items")||e.has("loadedItems")||e.has("layout")||e.has("fetchPage")||e.has("prefetchThreshold")||e.has("scrollModel")))this.syncMasonryObservers();else if(this.isMasonryLayout&&e.has("isLoadingPage")){const t=this.masonryRef.value;t&&this.syncMasonryPrefetchTarget(t)}(e.has("items")||e.has("loadedItems")||e.has("listHeight")||e.has("layout")||e.has("gridColumns")||e.has("scrollModel"))&&this.adjustListHeight()}syncMasonryObservers(){for(const t of this.masonryObservedCells)t.isConnected||(this.masonryCellObserver?.unobserve(t),this.masonryObservedCells.delete(t));const e=this.masonryRef.value;if(!e){this.disconnectMasonryPrefetchObserver();return}this.masonryCellObserver||(this.masonryCellObserver=new ResizeObserver(t=>{this.applyMasonrySpans(t)}));for(const t of e.querySelectorAll(":scope > .repeater-masonry-cell"))this.masonryObservedCells.has(t)||(this.masonryObservedCells.add(t),this.masonryCellObserver.observe(t,{box:"border-box"}));this.syncMasonryPrefetchTarget(e)}applyMasonrySpans(e){for(const t of e){const s=t.target,r=t.borderBoxSize?.[0]?.blockSize??s.getBoundingClientRect().height,i=`span ${Math.max(1,Math.ceil(r/P))}`;s.style.gridRowEnd!==i&&(s.style.gridRowEnd=i)}this.isContainedScrollModel&&this.adjustListHeight()}syncMasonryPrefetchTarget(e){if(!this.isPagedMode){this.disconnectMasonryPrefetchObserver();return}const t=e.querySelectorAll(":scope > .repeater-masonry-cell"),s=t[Math.max(0,t.length-this.normalizedPrefetchThreshold)]??null;this.disconnectMasonryPrefetchObserver(),s&&(this.masonryPrefetchObserver=new IntersectionObserver(r=>{r.some(o=>o.isIntersecting)&&this.requestNextPageIfNeeded()},{root:this.isContainedScrollModel?e:null}),this.masonryPrefetchObserver.observe(s))}disconnectMasonryPrefetchObserver(){this.masonryPrefetchObserver?.disconnect(),this.masonryPrefetchObserver=null}disconnectMasonryObservers(){this.masonryCellObserver?.disconnect(),this.masonryCellObserver=null,this.masonryObservedCells.clear(),this.disconnectMasonryPrefetchObserver()}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.usesColumns){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 s=this.usesColumns?this.refreshResolvedGridColumns():!1;t&&!s&&this.isContainedScrollModel&&this.adjustListHeight()})),this.resizeObserver}getViewportResizeListener(){return this.viewportResizeListener||(this.viewportResizeListener=()=>{this.refreshResolvedGridColumns()}),this.viewportResizeListener}syncResolvedGridColumns(){this.resolvedGridColumns=this.usesColumns?this.readResolvedGridColumns():1}readResolvedGridColumns(){return!this.usesColumns||!this.isConnected?this.normalizedGridColumns:this.parsePositiveIntegerToken(getComputedStyle(this).getPropertyValue("--esp-repeater-grid-columns"))??this.normalizedGridColumns}refreshResolvedGridColumns(){if(!this.usesColumns)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 s=[];for(let r=0;r<e.length;r+=t)s.push({items:e.slice(r,r+t),startIndex:r});return this.memoizedGridRowsSource=e,this.memoizedGridRowsColumns=t,this.memoizedGridRows=s,s}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 h`<pre>${t}</pre>`}describeFallbackItem(e){try{return String(e)}catch{return"Unrenderable item"}}async startPagedLoad(e){!this.fetchPage||this.isLoadingPage||(this.releaseFooterHold(),this.isLoadingPage=!0,await this.loadPage(e))}async loadPage(e){const t=this.fetchPage;if(!t)return;const s=this.pageLoads.begin();let r=0,o=!1;try{const i=await t({cursor:e,limit:this.normalizedPageSize});if(!this.pageLoads.isCurrent(s))return;r=this.measureContentHeight(),this.loadedItems=V(this.loadedItems,i.items,e),o=e!==null&&i.items.length>0,this.nextCursor=i.nextCursor,this.hasMoreData=i.nextCursor!==null,this.loadError=""}catch(i){if(!this.pageLoads.isCurrent(s))return;this.nextCursor=null,this.hasMoreData=!1,this.loadError=i instanceof Error&&i.message.length>0?i.message:"Unable to load items."}finally{this.pageLoads.isCurrent(s)&&o&&this.isPageScrollModel&&await this.waitForContentGrowth(r,s),this.pageLoads.isCurrent(s)&&(this.isPageScrollModel&&this.holdFooterSpace(),this.isLoadingPage=!1,this.isMasonryLayout||this.requestNextPageForRange())}}footerHoldFor(e,t,s,r){return e<=0?0:t+s>r-e?e:0}holdFooterSpace(){const e=this.containerRef.value?.querySelector(":scope > .status-footer"),t=this.footerHoldFor(e?.getBoundingClientRect().height??0,window.scrollY,window.innerHeight,document.documentElement.scrollHeight);t<=0||(this.footerHoldHeight=t,this.footerHoldScrollListener||(this.footerHoldScrollListener=()=>this.releaseFooterHoldIfSafe(),window.addEventListener("scroll",this.footerHoldScrollListener,{passive:!0})))}releaseFooterHoldIfSafe(){const e=document.documentElement.scrollHeight;window.scrollY+window.innerHeight<=e-this.footerHoldHeight&&this.releaseFooterHold()}releaseFooterHold(){this.footerHoldScrollListener&&(window.removeEventListener("scroll",this.footerHoldScrollListener),this.footerHoldScrollListener=null),this.footerHoldHeight=0}measureContentHeight(){return(this.masonryRef.value??this.getVirtualizerElement())?.getBoundingClientRect().height??0}async waitForContentGrowth(e,t){await this.updateComplete;for(let s=0;s<12&&this.pageLoads.isCurrent(t);s+=1){if(this.measureContentHeight()>e)return;await new Promise(r=>requestAnimationFrame(r))}}requestNextPageIfNeeded(){!this.isPagedMode||this.activeErrorMessage.length>0||!this.hasMoreData||this.isLoadingPage||this.nextCursor===null||this.startPagedLoad(this.nextCursor)}onRangeChanged(e){this.lastRangeEnd=e.last,!(!this.isPagedMode||this.isLoadingPage)&&this.requestNextPageForRange()}requestNextPageForRange(){if(this.lastRangeEnd<0)return;const e=this.normalizedPrefetchThreshold;this.getLastVisibleItemIndex(this.lastRangeEnd)>=this.loadedItems.length-e&&this.requestNextPageIfNeeded()}getLastVisibleItemIndex(e){return this.isGridLayout?Math.min((e+1)*this.effectiveGridColumns-1,this.renderedItems.length-1):e}resetPagedState(){this.releaseFooterHold(),this.pageLoads.invalidate(),this.lastRangeEnd=-1,this.isLoadingPage=!1,this.loadedItems=[],this.nextCursor=null,this.hasMoreData=!1,this.loadError=""}async adjustListHeight(){if(this.isContainedScrollModel&&!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,s=this.getVirtualizerElement();if(!t)return;if(this.renderedItems.length===0||!s){if(this.isMasonryLayout&&(this.hasMoreData||this.isBusy))return;let l=0;t.querySelectorAll(":scope > *").forEach(b=>{l+=b.offsetHeight});const u=t.offsetHeight;l>0&&l<u&&(this.effectiveListHeight=`${l}px`);return}if(this.hasMoreData||this.isBusy||this.activeErrorMessage.length>0)return;const r=this.isGridLayout?".repeater-row":".repeater-item",o=s.querySelectorAll(r);let i=0,c=!1;if(o.forEach(l=>{const u=l.offsetHeight;u===0&&(c=!0),i+=u}),o.length===0||c||i===0){this.pendingHeightRetry||(this.pendingHeightRetry=!0,this.observeForHeightRetry(s));return}const G=this.isGridLayout?".repeater-row :defined":".repeater-item :defined",x=s.querySelectorAll(G),v=[];x.forEach(l=>{"updateComplete"in l&&v.push(l.updateComplete)}),v.length>0&&(await Promise.all(v),i=0,o.forEach(l=>{i+=l.offsetHeight}));const E=t.querySelector(":scope > .status-footer")?.offsetHeight??0,y=i+E,$=t.offsetHeight,A=this.virtualizerItems.length;let H=!1;y>0&&y<$&&o.length>=A&&(s.style.minHeight=`${i}px`,this.effectiveListHeight=`${y}px`,H=!0),H&&!this.hasMoreData&&!this.pendingHeightRetry&&(this.pendingHeightRetry=!0,setTimeout(()=>{if(this.pendingHeightRetry=!1,!this.isContainedScrollModel||this.isBusy||this.activeErrorMessage.length>0)return;const l=this.containerRef.value,u=this.getVirtualizerElement();if(!l||!u||this.hasMoreData)return;const b=this.isGridLayout?".repeater-row":".repeater-item",C=u.querySelectorAll(b);let m=0,L=!1;if(C.forEach(k=>{const z=k.offsetHeight;z===0&&(L=!0),m+=z}),C.length===0||L||m===0)return;const F=l.querySelector(":scope > .status-footer")?.offsetHeight??0,O=m+F;O<l.offsetHeight&&C.length>=this.virtualizerItems.length&&(u.style.minHeight=`${m}px`,this.effectiveListHeight=`${O}px`)},100))}finally{this.isAdjustingHeight=!1}}}observeForHeightRetry(e){this.heightRetryObserver?.disconnect(),this.heightRetryObserver=new IntersectionObserver(t=>{if(!t.some(i=>i.isIntersecting))return;if(this.heightRetryObserver?.disconnect(),this.heightRetryObserver=null,!this.isContainedScrollModel){this.pendingHeightRetry=!1;return}let r=0;const o=()=>{this.pendingHeightRetry=!1,this.adjustListHeight(),this.pendingHeightRetry&&++r<5&&setTimeout(o,100)};requestAnimationFrame(()=>setTimeout(o,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"){if(await this.updateComplete,this.isMasonryLayout){this.masonryRef.value?.querySelectorAll(":scope > .repeater-masonry-cell")?.[e]?.scrollIntoView({block:t});return}const s=this.getVirtualizerElement();!s||!s.scrollToIndex||(await s.updateComplete,await new Promise(r=>requestAnimationFrame(r)),await s.layoutComplete,s.scrollToIndex(this.isGridLayout?Math.floor(e/this.effectiveGridColumns):e,t))}getVirtualizerElement(){return this.virtualizerRef.value}renderBlockingState(e,t,s){return h`<div class="state-panel" part="state" role=${s} aria-live=${M(s==="alert"?void 0:"polite")}>
13
13
  <slot name=${e}>
14
14
  <div class="state-message">${t}</div>
15
15
  </slot>
16
- </div>`}renderFooterState(){return this.renderedItems.length===0?I:this.activeErrorMessage.length>0?d`<div class="status-footer" part="footer" role="alert">
16
+ </div>`}renderFooterState(){return this.renderedItems.length===0?S:this.activeErrorMessage.length>0?h`<div class="status-footer" part="footer" role="alert">
17
17
  <slot name="error">
18
18
  <div class="state-message">${this.activeErrorMessage}</div>
19
19
  </slot>
20
- </div>`:this.isBusy?d`<div class="status-footer" part="footer" role="status" aria-live="polite">
20
+ </div>`:this.isBusy?h`<div class="status-footer" part="footer" role="status" aria-live="polite">
21
21
  <slot name="loading">
22
22
  <div class="state-message">${this.loadingMessage}</div>
23
23
  </slot>
24
- </div>`:I}render(){const e=this.isContainedScrollModel?{height:this.effectiveListHeight}:{},t=this.isGridLayout?this.renderGridVirtualItem:this.renderVirtualItem,i=j(this.scrollModel,d`<lit-virtualizer
25
- ${O(this.virtualizerRef)}
24
+ </div>`:this.footerHoldHeight>0?h`<div
25
+ class="status-footer-hold"
26
+ aria-hidden="true"
27
+ style=${p({height:`${this.footerHoldHeight}px`})}
28
+ ></div>`:S}renderMasonry(){const e=this.renderItem??(s=>this.renderFallbackItem(s)),t={gridTemplateColumns:`repeat(${this.effectiveGridColumns}, minmax(0, 1fr))`,gridAutoRows:`${P}px`};return h`<div
29
+ ${w(this.masonryRef)}
30
+ class="repeater-masonry"
31
+ part="scroller"
32
+ role="list"
33
+ aria-busy=${this.isBusy?"true":"false"}
34
+ aria-label=${M(this.ariaLabel??void 0)}
35
+ style=${p(t)}
36
+ >
37
+ ${T(this.renderedItems,(s,r)=>r,(s,r)=>h`<div class="repeater-item repeater-masonry-cell" part="item" role="listitem">
38
+ ${e(s,r)}
39
+ </div>`)}
40
+ </div>`}render(){const e=this.isContainedScrollModel?{height:this.effectiveListHeight}:{},t=this.isGridLayout?this.renderGridVirtualItem:this.renderVirtualItem,s=q(this.scrollModel,h`<lit-virtualizer
41
+ ${w(this.virtualizerRef)}
26
42
  class="repeater-virtualizer"
27
43
  part="scroller"
28
44
  ?scroller=${this.isContainedScrollModel}
@@ -33,15 +49,15 @@ var l=function(y,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
33
49
  .items=${this.virtualizerItems}
34
50
  .renderItem=${t}
35
51
  @rangeChanged=${r=>this.onRangeChanged(r)}
36
- ></lit-virtualizer>`);return d`<div
52
+ ></lit-virtualizer>`);return h`<div
37
53
  class="repeater-container"
38
54
  part="container"
39
- ${O(this.containerRef)}
40
- style=${A(e)}
55
+ ${w(this.containerRef)}
56
+ style=${p(e)}
41
57
  >
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}
58
+ ${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"):this.isMasonryLayout?this.renderMasonry():s}
43
59
  ${this.renderFooterState()}
44
- </div>`}};o.styles=[...E.styles,V`
60
+ </div>`}};a.styles=[...I.styles,B`
45
61
  .repeater-container {
46
62
  display: flex;
47
63
  flex-direction: column;
@@ -73,6 +89,10 @@ var l=function(y,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
73
89
  flex-shrink: 0;
74
90
  }
75
91
 
92
+ .status-footer-hold {
93
+ flex-shrink: 0;
94
+ }
95
+
76
96
  .state-message {
77
97
  color: var(--esp-color-text);
78
98
  font-style: italic;
@@ -115,8 +135,38 @@ var l=function(y,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
115
135
  padding-bottom: 0;
116
136
  }
117
137
 
138
+
139
+ .repeater-masonry {
140
+ display: grid;
141
+ grid-auto-flow: row dense;
142
+ align-items: start;
143
+ column-gap: var(
144
+ --esp-repeater-grid-column-gap,
145
+ var(--esp-repeater-gap, var(--esp-size-small))
146
+ );
147
+ min-height: 0;
148
+ padding: var(--esp-repeater-content-padding, 0);
149
+ }
150
+
151
+ :host([scroll-model="contained"]) .repeater-masonry {
152
+ flex: 0 1 auto;
153
+ overflow: auto;
154
+ }
155
+
156
+ :host([scroll-model="page"]) .repeater-masonry {
157
+ overflow: visible;
158
+ }
159
+
160
+ .repeater-masonry-cell {
161
+ min-width: 0;
162
+ padding-bottom: var(
163
+ --esp-repeater-grid-row-gap,
164
+ var(--esp-repeater-gap, var(--esp-size-small))
165
+ );
166
+ }
167
+
118
168
  pre {
119
169
  margin: 0;
120
170
  white-space: pre-wrap;
121
171
  }
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};
172
+ `],n([g()],a.prototype,"isLoadingPage",void 0),n([g()],a.prototype,"loadedItems",void 0),n([g()],a.prototype,"hasMoreData",void 0),n([g()],a.prototype,"effectiveListHeight",void 0),n([g()],a.prototype,"loadError",void 0),n([g()],a.prototype,"footerHoldHeight",void 0),n([d({type:Array})],a.prototype,"items",void 0),n([d({attribute:!1})],a.prototype,"renderItem",void 0),n([d({type:String,reflect:!0})],a.prototype,"layout",void 0),n([d({attribute:"scroll-model",type:String,reflect:!0})],a.prototype,"scrollModel",void 0),n([d({attribute:"grid-columns",type:Number})],a.prototype,"gridColumns",void 0),n([d({attribute:"aria-label",type:String})],a.prototype,"ariaLabel",void 0),n([d({attribute:"list-height",type:String})],a.prototype,"listHeight",void 0),n([d({attribute:"page-size",type:Number})],a.prototype,"pageSize",void 0),n([d({attribute:"prefetch-threshold",type:Number})],a.prototype,"prefetchThreshold",void 0),n([d({type:Boolean})],a.prototype,"loading",void 0),n([d({attribute:"loading-message",type:String})],a.prototype,"loadingMessage",void 0),n([d({attribute:"empty-message",type:String})],a.prototype,"emptyMessage",void 0),n([d({attribute:"error-message",type:String})],a.prototype,"errorMessage",void 0),n([d({attribute:!1})],a.prototype,"fetchPage",null),a=n([N("esp-repeater")],a);export{a as EspalierRepeater};
@@ -1523,15 +1523,15 @@
1523
1523
  },
1524
1524
  {
1525
1525
  "name": "--esp-repeater-grid-column-gap",
1526
- "description": "Horizontal gap between grid columns."
1526
+ "description": "Horizontal gap between grid or masonry columns."
1527
1527
  },
1528
1528
  {
1529
1529
  "name": "--esp-repeater-grid-columns",
1530
- "description": "Grid column count when `layout=\"grid\"`. Supports media-query overrides."
1530
+ "description": "Column count when `layout=\"grid\"` or `layout=\"masonry\"`. Supports media-query overrides."
1531
1531
  },
1532
1532
  {
1533
1533
  "name": "--esp-repeater-grid-row-gap",
1534
- "description": "Vertical gap between grid rows."
1534
+ "description": "Vertical gap between grid rows or stacked masonry cards."
1535
1535
  },
1536
1536
  {
1537
1537
  "name": "--esp-repeater-padding",
@@ -2185,19 +2185,19 @@
2185
2185
  "name": "--esp-repeater-grid-column-gap",
2186
2186
  "category": "component",
2187
2187
  "component": "esp-repeater",
2188
- "description": "Horizontal gap between grid columns."
2188
+ "description": "Horizontal gap between grid or masonry columns."
2189
2189
  },
2190
2190
  {
2191
2191
  "name": "--esp-repeater-grid-columns",
2192
2192
  "category": "component",
2193
2193
  "component": "esp-repeater",
2194
- "description": "Grid column count when `layout=\"grid\"`. Supports media-query overrides."
2194
+ "description": "Column count when `layout=\"grid\"` or `layout=\"masonry\"`. Supports media-query overrides."
2195
2195
  },
2196
2196
  {
2197
2197
  "name": "--esp-repeater-grid-row-gap",
2198
2198
  "category": "component",
2199
2199
  "component": "esp-repeater",
2200
- "description": "Vertical gap between grid rows."
2200
+ "description": "Vertical gap between grid rows or stacked masonry cards."
2201
2201
  },
2202
2202
  {
2203
2203
  "name": "--esp-repeater-padding",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taprootio/espalier",
3
- "version": "4.13.0",
3
+ "version": "4.14.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",