@taprootio/espalier 2.11.0 → 2.12.1

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,4 +1,4 @@
1
- var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(d,e,t,r);else for(var i=d.length-1;i>=0;i--)(n=d[i])&&(s=(o<3?n(s):o>3?n(e,t,s):n(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s};import{css as p,html as w,nothing as T}from"lit";import{customElement as O,property as h}from"lit/decorators.js";import{classMap as _}from"lit/directives/class-map.js";import{createRef as F,ref as L}from"lit/directives/ref.js";import{EspalierElementBase as k}from"../shared/esp-element-base.js";import{getEspBus as f}from"../shared/bus-events.js";import{FLYOUT_FULL_HEIGHT_REQUEST_EVENT as A,markFlyoutRequestServiced as M}from"../shared/flyout-events.js";import{OverlayController as q}from"../shared/overlay-controller.js";import{cancelSVG as G}from"../shared/svgs/cancel.js";import{traverseToClosest as v}from"../shared/utilities.js";const B="(max-width: 50em)",H="Flyout",R=p`
1
+ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(d,e,t,r);else for(var i=d.length-1;i>=0;i--)(n=d[i])&&(s=(o<3?n(s):o>3?n(e,t,s):n(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s};import{css as p,html as w,nothing as T}from"lit";import{customElement as _,property as h}from"lit/decorators.js";import{classMap as O}from"lit/directives/class-map.js";import{createRef as F,ref as L}from"lit/directives/ref.js";import{EspalierElementBase as k}from"../shared/esp-element-base.js";import{getEspBus as f}from"../shared/bus-events.js";import{FLYOUT_FULL_HEIGHT_REQUEST_EVENT as A,markFlyoutRequestServiced as M}from"../shared/flyout-events.js";import{OverlayController as q}from"../shared/overlay-controller.js";import{cancelSVG as G}from"../shared/svgs/cancel.js";import{traverseToClosest as v}from"../shared/utilities.js";const B="(max-width: 50em)",H="Flyout",R=p`
2
2
  position: fixed;
3
3
  inset: 0;
4
4
  margin-block-start: 0;
@@ -34,7 +34,7 @@ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
34
34
  `;let a=class extends k{constructor(){super(...arguments),this.open=!1,this.heading="",this.mode="auto",this.pageOverlayRequested=!1,this.fullHeight=!1,this.matchSurface=!1,this.standalone=!1,this.scope="outermost",this.lastGeneratedAriaLabel=null,this.boundKeydown=e=>this.handleKeydown(e),this.boundShowRequest=e=>this.handleShowRequest(e),this.boundCloseRequest=()=>this.close(),this.boundOverlayMediaChange=()=>{this.syncOverlayModal(),this.syncAnchorTracking(),this.syncAnchorGeometry(),this.dispatchEvent(new CustomEvent("flyout-state-changed",{detail:{},bubbles:!0,composed:!0}))},this.boundAnchorViewportChange=()=>this.scheduleAnchorGeometrySync(),this.boundFullHeightRequest=e=>{e.stopPropagation(),this.fullHeight=!0},this.anchorPositionRaf=0,this.trackingAnchorPosition=!1,this.busSubscribed=!1,this.panelRef=F(),this.overlay=new q({host:this,getFocusTrapContainer:()=>this.panelRef.value??null,getFocusFallback:()=>this.panelRef.value??null,promote:!1}),this.overlayActive=!1,this.baseRole="complementary"}get effectiveOverlay(){return this.mode==="overlay"||this.pageOverlayRequested||(this.overlayMediaQuery?.matches??!1)}connectedCallback(){super.connectedCallback(),this.hasAttribute("role")||this.setAttribute("role","complementary"),this.baseRole=this.getAttribute("role")??"complementary",!this.overlayMediaQuery&&typeof window<"u"&&"matchMedia"in window&&(this.overlayMediaQuery=window.matchMedia(B)),this.overlayMediaQuery?.addEventListener("change",this.boundOverlayMediaChange),this.syncBusSubscription(),document.addEventListener("keydown",this.boundKeydown),this.addEventListener(A,this.boundFullHeightRequest),this.syncOverlayModal(),this.syncAnchorTracking(),this.syncAnchorGeometry()}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeBus(),this.overlayMediaQuery?.removeEventListener("change",this.boundOverlayMediaChange),document.removeEventListener("keydown",this.boundKeydown),this.removeEventListener(A,this.boundFullHeightRequest),this.stopAnchorTracking(),this.overlayActive&&(this.overlayActive=!1,this.setAttribute("role",this.baseRole),this.removeAttribute("aria-modal"),this.updateGeneratedAriaLabel()),this.overlayReturnFocusTo=void 0}syncBusSubscription(){if(this.standalone||!this.isConnected){this.unsubscribeBus();return}this.busSubscribed||(f().subscribe("show-flyout",this.boundShowRequest),f().subscribe("close-flyout",this.boundCloseRequest),this.busSubscribed=!0)}unsubscribeBus(){this.busSubscribed&&(f().unsubscribe("show-flyout",this.boundShowRequest),f().unsubscribe("close-flyout",this.boundCloseRequest),this.busSubscribed=!1)}show(){this.open||(this.open=!0,this.dispatchEvent(new CustomEvent("flyout-opened",{detail:{},bubbles:!0,composed:!0})))}close(e="programmatic"){if(this.open){if(this.open=!1,this.overlayActive)this.overlayReturnFocusTo=this.returnFocusTo;else{const t=this.focusIsInside();this.overlay.close(),t&&this.returnFocusTo?.focus()}this.returnFocusTo=void 0,this.dispatchEvent(new CustomEvent("flyout-closed",{detail:{reason:e},bubbles:!0,composed:!0}))}}toggle(){this.open?this.close():this.show()}handleShowRequest(e){this.shouldHandleShowRequest(e)&&(M(e),e.heading!==void 0&&(this.heading=e.heading),e.content!==void 0&&this.replaceChildren(typeof e.content=="string"?document.createTextNode(e.content):e.content),this.anchor=e.anchor,this.fullHeight=e.fullHeight??!1,this.returnFocusTo=e.returnFocusTo,this.show())}shouldHandleShowRequest(e){const t=v(this,"esp-page"),r=e.anchor??e.returnFocusTo;if(!r){if(!t)return!0;const i=this.getPageChain(t);return this.scope==="outermost"&&i[i.length-1]===t}const o=this.getPageChain(r);if(o.length===0)return t===null;const s=o.find(i=>this.hasNearestScopeFlyout(i)),n=s??o[o.length-1];return t!==n?!1:s?this.scope==="nearest":this.scope==="outermost"}getPageChain(e){const t=[];let r=e;for(;r;){const o=v(r,"esp-page");if(!o||t.includes(o))break;t.push(o),r=this.composedParent(o)}return t}hasNearestScopeFlyout(e){return Array.from(e.querySelectorAll("esp-flyout")).some(t=>!t.standalone&&t.scope==="nearest"&&v(t,"esp-page")===e)}handleKeydown(e){if(this.open){if(this.overlayActive&&e.key==="Tab"){this.overlay.trapFocus(e);return}e.key!=="Escape"||e.defaultPrevented||(e.preventDefault(),this.close("escape"))}}focusIsInside(){const e=document.activeElement;return e&&this.contains(e)?!0:this.shadowRoot?.activeElement!=null}updated(e){super.updated(e),e.has("standalone")&&this.syncBusSubscription(),e.has("heading")&&this.updateGeneratedAriaLabel(),(e.has("anchor")||e.has("fullHeight")||e.has("open")||e.has("mode")||e.has("pageOverlayRequested"))&&(this.syncAnchorTracking(),this.syncAnchorGeometry()),(e.has("open")||e.has("mode")||e.has("pageOverlayRequested"))&&this.syncOverlayModal(),(e.has("open")||e.has("mode")||e.has("anchor")||e.has("pageOverlayRequested"))&&this.dispatchEvent(new CustomEvent("flyout-state-changed",{detail:{},bubbles:!0,composed:!0}))}syncAnchorGeometry(){const e=v(this,"esp-page"),t=this.anchor?this.getPageChain(this.anchor):[],r=e?.shadowRoot?.querySelector(".esp-page-main"),o=this.panelRef.value;if(!this.open||this.effectiveOverlay||!this.anchor||!e||!t.includes(e)||!r||!o){this.clearAnchorGeometry();return}const s=this.anchor.getBoundingClientRect(),n=Math.max(0,s.top-r.getBoundingClientRect().top),i=this.getVisibleBlockBounds(),u=Math.max(0,i.bottom-i.top),c=Number.isFinite(s.height)?s.height:0;this.setGeometryProperty("--_esp-flyout-anchor-offset",`${n}px`),this.setGeometryProperty("--_esp-flyout-max-block-size",`${u}px`),this.setGeometryProperty("--_esp-flyout-anchor-block-size",`${c}px`);const y=o.getBoundingClientRect().height||u,b=Math.max(0,s.top+y-i.bottom),P=Math.max(0,y-c),g=this.fullHeight?b:Math.min(b,P);this.setGeometryProperty("--_esp-flyout-viewport-shift",`${g}px`);const C=s.top-g,m=8,E=s.top+c/2,S=Math.min(Math.max(m,y-m),Math.max(m,E-C));this.setGeometryProperty("--_esp-flyout-anchor-marker-offset",`${S}px`)}getVisibleBlockBounds(){const e=window.visualViewport;let t=e?.offsetTop??0,r=t+(e?.height??window.innerHeight);for(let o=this.composedParent(this);o;o=this.composedParent(o)){const s=getComputedStyle(o).overflowY;if(s!=="auto"&&s!=="scroll")continue;const n=o.getBoundingClientRect(),i=o instanceof HTMLElement?o.clientTop:0,u=o instanceof HTMLElement?o.clientHeight:n.height;if(u<=0)continue;const c=n.top+i;t=Math.max(t,c),r=Math.min(r,c+u)}return{top:t,bottom:Math.max(t,r)}}composedParent(e){if(e.parentElement)return e.parentElement;const t=e.getRootNode();return t instanceof ShadowRoot?t.host:null}setGeometryProperty(e,t){this.style.getPropertyValue(e)!==t&&this.style.setProperty(e,t)}clearAnchorGeometry(){this.style.removeProperty("--_esp-flyout-anchor-offset"),this.style.removeProperty("--_esp-flyout-viewport-shift"),this.style.removeProperty("--_esp-flyout-max-block-size"),this.style.removeProperty("--_esp-flyout-anchor-block-size"),this.style.removeProperty("--_esp-flyout-anchor-marker-offset")}scheduleAnchorGeometrySync(){!this.isConnected||this.anchorPositionRaf||(this.anchorPositionRaf=requestAnimationFrame(()=>{this.anchorPositionRaf=0,this.syncAnchorGeometry()}))}syncAnchorTracking(){if(!(this.isConnected&&this.open&&!!this.anchor&&!this.effectiveOverlay)){this.stopAnchorTracking();return}this.trackingAnchorPosition||(this.trackingAnchorPosition=!0,window.addEventListener("scroll",this.boundAnchorViewportChange,{capture:!0,passive:!0}),window.addEventListener("resize",this.boundAnchorViewportChange,{passive:!0}));const t=this.panelRef.value;t&&t!==this.observedAnchorPanel&&typeof ResizeObserver<"u"&&(this.anchorResizeObserver??=new ResizeObserver(this.boundAnchorViewportChange),this.anchorResizeObserver.disconnect(),this.anchorResizeObserver.observe(t),this.observedAnchorPanel=t)}stopAnchorTracking(){this.trackingAnchorPosition&&(window.removeEventListener("scroll",this.boundAnchorViewportChange,{capture:!0}),window.removeEventListener("resize",this.boundAnchorViewportChange),this.trackingAnchorPosition=!1),this.anchorPositionRaf&&(cancelAnimationFrame(this.anchorPositionRaf),this.anchorPositionRaf=0),this.anchorResizeObserver?.disconnect(),this.observedAnchorPanel=void 0}syncOverlayModal(){const e=this.isConnected&&this.open&&this.effectiveOverlay;if(e===this.overlayActive){!e&&!this.open&&this.overlay.close();return}e?(this.overlayActive=!0,this.setAttribute("role","dialog"),this.setAttribute("aria-modal","true"),this.updateGeneratedAriaLabel(),this.overlay.open(),this.updateComplete.then(()=>{this.overlayActive&&this.overlay.moveFocusInto()})):(this.overlayActive=!1,this.overlay.close(),this.overlayReturnFocusTo&&(this.overlayReturnFocusTo.focus(),this.overlayReturnFocusTo=void 0),this.setAttribute("role",this.baseRole),this.removeAttribute("aria-modal"),this.updateGeneratedAriaLabel())}updateGeneratedAriaLabel(){const e=this.getAttribute("aria-label");if(e!==null&&e!==this.lastGeneratedAriaLabel)return;const t=this.heading||(this.overlayActive?H:"");t?(this.setAttribute("aria-label",t),this.lastGeneratedAriaLabel=t):(this.removeAttribute("aria-label"),this.lastGeneratedAriaLabel=null)}render(){return w`
35
35
  <div class="vellum" aria-hidden="true" @click=${()=>this.close("vellum")}></div>
36
36
  <div
37
- class=${_({panel:!0,anchored:!!this.anchor,"full-height":this.fullHeight})}
37
+ class=${O({panel:!0,anchored:!!this.anchor,"full-height":this.fullHeight})}
38
38
  part="panel"
39
39
  ${L(this.panelRef)}
40
40
  >
@@ -111,7 +111,7 @@ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
111
111
  }
112
112
 
113
113
  > .anchor-terminus {
114
- display: block;
114
+ display: var(--_esp-flyout-preview-anchor-display, none);
115
115
  position: absolute;
116
116
  z-index: 2;
117
117
  inset-block-start: var(--_esp-flyout-anchor-marker-offset, 50%);
@@ -251,4 +251,4 @@ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
251
251
  transition: none;
252
252
  }
253
253
  }
254
- `],l([h({type:Boolean,reflect:!0})],a.prototype,"open",void 0),l([h({type:String})],a.prototype,"heading",void 0),l([h({reflect:!0})],a.prototype,"mode",void 0),l([h({type:Boolean,reflect:!0,attribute:"data-page-overlay"})],a.prototype,"pageOverlayRequested",void 0),l([h({attribute:!1})],a.prototype,"anchor",void 0),l([h({type:Boolean,reflect:!0,attribute:"full-height"})],a.prototype,"fullHeight",void 0),l([h({type:Boolean,reflect:!0,attribute:"match-surface"})],a.prototype,"matchSurface",void 0),l([h({type:Boolean,reflect:!0})],a.prototype,"standalone",void 0),l([h({type:String,reflect:!0})],a.prototype,"scope",void 0),a=l([O("esp-flyout")],a);export{a as EspalierFlyout};
254
+ `],l([h({type:Boolean,reflect:!0})],a.prototype,"open",void 0),l([h({type:String})],a.prototype,"heading",void 0),l([h({reflect:!0})],a.prototype,"mode",void 0),l([h({type:Boolean,reflect:!0,attribute:"data-page-overlay"})],a.prototype,"pageOverlayRequested",void 0),l([h({attribute:!1})],a.prototype,"anchor",void 0),l([h({type:Boolean,reflect:!0,attribute:"full-height"})],a.prototype,"fullHeight",void 0),l([h({type:Boolean,reflect:!0,attribute:"match-surface"})],a.prototype,"matchSurface",void 0),l([h({type:Boolean,reflect:!0})],a.prototype,"standalone",void 0),l([h({type:String,reflect:!0})],a.prototype,"scope",void 0),a=l([_("esp-flyout")],a);export{a as EspalierFlyout};
@@ -1,5 +1,5 @@
1
- var d=function(r,e,t,n){var o=arguments.length,s=o<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,i;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var a=r.length-1;a>=0;a--)(i=r[a])&&(s=(o<3?i(s):o>3?i(e,t,s):i(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s};import{css as p,nothing as b}from"lit";import{customElement as f}from"lit/decorators.js";import{EspalierElementBase as v}from"../shared/esp-element-base.js";import{getEspBus as c}from"../shared/bus-events.js";import{publishFlyoutRequest as m}from"../shared/flyout-events.js";import{openHelpInNewTab as h}from"../shared/help-events.js";import{createHelpDocumentView as C,createHelpStatusView as u,normalizeHelpDocument as R}from"./help-document.js";let l=class extends v{constructor(){super(...arguments),this.cache=new Map,this.warnedMissingAnchors=new Set,this.activeRequest=null,this.activeController=null,this.activeContent=null,this.contentObserver=new MutationObserver(()=>{this.activeContent&&!this.activeContent.isConnected&&this.endActiveRequest()}),this.requestSequence=0,this.subscribed=!1,this.boundRequest=e=>{this.handleRequest(e)},this.boundCloseRequest=e=>{let t;try{t=new URL(e.src,document.baseURI).href}catch{return}if(!this.activeRequest||t!==this.activeRequest.src||(e.anchor??"")!==(this.activeRequest.anchor??""))return;const n=this.activeContent?.parentElement;n?.localName==="esp-flyout"&&n.close("programmatic")},this.boundFlyoutClosed=e=>{const t=e.target;!(t instanceof Element)||!this.activeContent||t.contains(this.activeContent)&&this.endActiveRequest()}}connectedCallback(){super.connectedCallback(),this.subscribed||(c().subscribe("request-help",this.boundRequest),c().subscribe("close-help",this.boundCloseRequest),this.subscribed=!0),document.addEventListener("flyout-closed",this.boundFlyoutClosed)}disconnectedCallback(){this.subscribed&&(c().unsubscribe("request-help",this.boundRequest),c().unsubscribe("close-help",this.boundCloseRequest),this.subscribed=!1),document.removeEventListener("flyout-closed",this.boundFlyoutClosed),this.endActiveRequest(),super.disconnectedCallback()}render(){return b}async handleRequest(e){const t=++this.requestSequence;this.activeController?.abort();const n=new AbortController;if(this.activeController=n,this.activeRequest=e,this.publishState(e,!0),this.showInFlyout(e,{heading:e.title??"Help",content:u({message:"Loading help\u2026"})})===0){this.endActiveRequest(),h(e);return}try{const s=this.cache.get(e.src)??await this.fetchDocument(e,n);if(t!==this.requestSequence||n.signal.aborted)return;if(!this.activeContent?.isConnected){this.endActiveRequest();return}this.cache.set(e.src,s);const i=C(s,e.anchor);this.warnForMissingAnchor(e,i.anchorFound),this.showInFlyout(e,{heading:e.title??i.topicTitle??s.title??"Help",content:i.element,fullHeight:i.fullDocument})}catch(s){if(t!==this.requestSequence||n.signal.aborted||w(s))return;if(!this.activeContent?.isConnected){this.endActiveRequest();return}this.showInFlyout(e,{heading:e.title??"Help unavailable",content:u({message:"Help could not be loaded.",actionLabel:"Open help document",onAction:()=>h(e)})})}finally{t===this.requestSequence&&(this.activeController=null)}}async fetchDocument(e,t){const n=await fetch(e.src,{signal:t.signal});if(!n.ok)throw new Error(`Help request failed with HTTP ${n.status}.`);return R(await n.text(),n.url||e.src)}showInFlyout(e,t){this.contentObserver.disconnect(),this.activeContent=t.content instanceof HTMLElement?t.content:null;const n=m({...t,anchor:e.placementTarget??e.trigger,returnFocusTo:e.trigger}),o=this.activeContent?.parentElement;return n&&o&&this.contentObserver.observe(o,{childList:!0}),n?1:0}publishState(e,t){c().publish("help-state-changed",{src:e.src,...e.anchor?{anchor:e.anchor}:{},open:t})}publishClosedState(){this.activeRequest&&(this.publishState(this.activeRequest,!1),this.activeRequest=null)}endActiveRequest(){(this.activeRequest||this.activeController)&&++this.requestSequence,this.activeController?.abort(),this.activeController=null,this.contentObserver.disconnect(),this.activeContent=null,this.publishClosedState()}warnForMissingAnchor(e,t){if(!e.anchor||t)return;const n=`${e.src}#${e.anchor}`;this.warnedMissingAnchors.has(n)||(this.warnedMissingAnchors.add(n),console.warn(`Help anchor "${e.anchor}" was not found in ${e.src}; showing the full document.`))}};l.styles=[p`
1
+ var p=function(r,e,t,n){var i=arguments.length,s=i<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var c=r.length-1;c>=0;c--)(o=r[c])&&(s=(i<3?o(s):i>3?o(e,t,s):o(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s};import{css as f,nothing as b}from"lit";import{customElement as v}from"lit/decorators.js";import{EspalierElementBase as m}from"../shared/esp-element-base.js";import{getEspBus as l}from"../shared/bus-events.js";import{publishFlyoutRequest as C}from"../shared/flyout-events.js";import{openHelpInNewTab as u}from"../shared/help-events.js";import{createHelpDocumentView as R,createHelpStatusView as d,normalizeHelpDocument as w}from"./help-document.js";let a=class extends m{constructor(){super(...arguments),this.cache=new Map,this.warnedMissingAnchors=new Set,this.activeRequest=null,this.activeController=null,this.activeContent=null,this.contentObserver=new MutationObserver(()=>{this.activeContent&&!this.activeContent.isConnected&&this.endActiveRequest()}),this.requestSequence=0,this.subscribed=!1,this.boundRequest=e=>{this.handleRequest(e)},this.boundCloseRequest=e=>{let t;try{t=new URL(e.src,document.baseURI).href}catch{return}if(!this.activeRequest||t!==this.activeRequest.src||(e.anchor??"")!==(this.activeRequest.anchor??""))return;const n=this.activeContent?.parentElement;n?.localName==="esp-flyout"&&n.close("programmatic")},this.boundFlyoutClosed=e=>{const t=e.target;!(t instanceof Element)||!this.activeContent||t.contains(this.activeContent)&&this.endActiveRequest()}}connectedCallback(){super.connectedCallback(),this.subscribed||(l().subscribe("request-help",this.boundRequest),l().subscribe("close-help",this.boundCloseRequest),this.subscribed=!0),document.addEventListener("flyout-closed",this.boundFlyoutClosed)}disconnectedCallback(){this.subscribed&&(l().unsubscribe("request-help",this.boundRequest),l().unsubscribe("close-help",this.boundCloseRequest),this.subscribed=!1),document.removeEventListener("flyout-closed",this.boundFlyoutClosed),this.endActiveRequest(),super.disconnectedCallback()}render(){return b}async handleRequest(e){const t=++this.requestSequence;this.activeController?.abort();const n=new AbortController;if(this.activeController=n,this.activeRequest=e,this.publishState(e,!0),this.showInFlyout(e,{heading:e.title??"Help",content:d({message:"Loading help\u2026"})})===0){this.endActiveRequest(),u(e);return}try{const s=this.cache.get(e.src)??await this.fetchDocument(e,n);if(t!==this.requestSequence||n.signal.aborted)return;if(!this.activeContent?.isConnected){this.endActiveRequest();return}this.cache.set(e.src,s);const o=R(s,e.anchor,{onFullDocument:c=>{const h=c.parentElement;h?.localName==="esp-flyout"&&(h.heading=s.title??"Help")}});this.warnForMissingAnchor(e,o.anchorFound),this.showInFlyout(e,{heading:e.title??o.topicTitle??s.title??"Help",content:o.element,fullHeight:o.fullDocument})}catch(s){if(t!==this.requestSequence||n.signal.aborted||g(s))return;if(!this.activeContent?.isConnected){this.endActiveRequest();return}this.showInFlyout(e,{heading:e.title??"Help unavailable",content:d({message:"Help could not be loaded.",actionLabel:"Open help document",onAction:()=>u(e)})})}finally{t===this.requestSequence&&(this.activeController=null)}}async fetchDocument(e,t){const n=await fetch(e.src,{signal:t.signal});if(!n.ok)throw new Error(`Help request failed with HTTP ${n.status}.`);return w(await n.text(),n.url||e.src)}showInFlyout(e,t){this.contentObserver.disconnect(),this.activeContent=t.content instanceof HTMLElement?t.content:null;const n=C({...t,anchor:e.placementTarget??e.trigger,returnFocusTo:e.trigger}),i=this.activeContent?.parentElement;return n&&i&&(!e.anchor&&i.localName==="esp-flyout"&&this.resetFlyoutScroll(i,this.activeContent),this.contentObserver.observe(i,{childList:!0})),n?1:0}resetFlyoutScroll(e,t){const n=()=>{if(this.activeContent!==t)return;const i=e.shadowRoot?.querySelector('[part="content"]')??null;i&&(i.scrollTop=0)};n(),e.updateComplete.then(n)}publishState(e,t){l().publish("help-state-changed",{src:e.src,...e.anchor?{anchor:e.anchor}:{},open:t})}publishClosedState(){this.activeRequest&&(this.publishState(this.activeRequest,!1),this.activeRequest=null)}endActiveRequest(){(this.activeRequest||this.activeController)&&++this.requestSequence,this.activeController?.abort(),this.activeController=null,this.contentObserver.disconnect(),this.activeContent=null,this.publishClosedState()}warnForMissingAnchor(e,t){if(!e.anchor||t)return;const n=`${e.src}#${e.anchor}`;this.warnedMissingAnchors.has(n)||(this.warnedMissingAnchors.add(n),console.warn(`Help anchor "${e.anchor}" was not found in ${e.src}; showing the full document.`))}};a.styles=[f`
2
2
  :host {
3
3
  display: none;
4
4
  }
5
- `],l=d([f("esp-help-provider")],l);function w(r){return r instanceof DOMException&&r.name==="AbortError"}export{l as EspalierHelpProvider};
5
+ `],a=p([v("esp-help-provider")],a);function g(r){return r instanceof DOMException&&r.name==="AbortError"}export{a as EspalierHelpProvider};
@@ -1,4 +1,4 @@
1
- import"../button/esp-button.js";import{FLYOUT_FULL_HEIGHT_REQUEST_EVENT as w}from"../shared/flyout-events.js";import{decodeFragment as E}from"../shared/help-events.js";const v=new Set(["A","ABBR","B","BLOCKQUOTE","BR","CODE","DD","DEL","DETAILS","DL","DT","EM","FIGCAPTION","FIGURE","H1","H2","H3","H4","H5","H6","HR","I","IMG","KBD","LI","MARK","OL","P","PRE","Q","S","SAMP","SMALL","STRONG","SUB","SUMMARY","SUP","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","U","UL","VAR"]),N=new Set(["SCRIPT","STYLE","TEMPLATE","NOSCRIPT"]),y={A:["href"],DETAILS:["open"],IMG:["src","alt","width","height"],LI:["value"],OL:["start","reversed"],TD:["colspan","rowspan"],TH:["colspan","rowspan","scope"]},g=`
1
+ import"../button/esp-button.js";import{FLYOUT_FULL_HEIGHT_REQUEST_EVENT as D}from"../shared/flyout-events.js";import{decodeFragment as T}from"../shared/help-events.js";const y=new Set(["A","ABBR","B","BLOCKQUOTE","BR","CODE","DD","DEL","DETAILS","DL","DT","EM","FIGCAPTION","FIGURE","H1","H2","H3","H4","H5","H6","HR","I","IMG","KBD","LI","MARK","OL","P","PRE","Q","S","SAMP","SMALL","STRONG","SUB","SUMMARY","SUP","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","U","UL","VAR"]),C=new Set(["SCRIPT","STYLE","TEMPLATE","NOSCRIPT","TITLE"]),H={A:["href"],DETAILS:["open"],IMG:["src","alt","width","height"],LI:["value"],OL:["start","reversed"],TD:["colspan","rowspan"],TH:["colspan","rowspan","scope"]},g=`
2
2
  :host {
3
3
  color: var(--esp-color-text);
4
4
  display: block;
@@ -49,4 +49,4 @@ import"../button/esp-button.js";import{FLYOUT_FULL_HEIGHT_REQUEST_EVENT as w}fro
49
49
  [part="actions"] {
50
50
  margin-block-start: var(--esp-size-padding);
51
51
  }
52
- `;function P(e,t={}){const n=t.helpUrl?.trim()??"",o=n?"":H(e),r=n||o;if(!r)return null;let c;try{c=new URL(r,e.ownerDocument.baseURI)}catch{return null}const i=E(c.hash);c.hash="";const a=m(t.anchor,t.fallbackAnchor),s=n?m(i,a):m(a,i),u=new URL(c.href);return s&&(u.hash=s),{src:c.href,...s?{anchor:s}:{},href:u.href}}function k(e,t){const n=new URL(t,document.baseURI);n.hash="";const o=new DOMParser().parseFromString(e,"text/html"),r=o.querySelector("title")?.textContent?.trim()||void 0,c=document.createDocumentFragment();for(const i of[...o.body.childNodes])b(i,c,n.href);return{src:n.href,...r?{title:r}:{},body:c}}function D(e,t){const n=t?.trim()??"";if(!n)return{content:e.body.cloneNode(!0),anchorFound:!0,sectioned:!1};const o=T(e.body,n);if(!o)return{content:e.body.cloneNode(!0),anchorFound:!1,sectioned:!1};const r=A(o);if(!r||!o.parentNode)return{content:e.body.cloneNode(!0),anchorFound:!0,sectioned:!1};const c=document.createDocumentFragment();let i=o.nextSibling;for(;i;){if(i instanceof Element){const a=A(i);if(a&&a<=r)break}c.append(i.cloneNode(!0)),i=i.nextSibling}return{content:c,anchorFound:!0,sectioned:!0,heading:o.textContent?.trim()||void 0}}function B(e,t){const n=t?.trim()||void 0,o=D(e,n),r=document.createElement("section");r.dataset.espHelpDocument="";const c=r.attachShadow({mode:"open"}),i=document.createElement("style");i.textContent=g;const a=document.createElement("div");a.setAttribute("part","content");const s=document.createElement("div");s.setAttribute("part","actions");const u=d=>{a.replaceChildren(e.body.cloneNode(!0)),l?.setAttribute("disabled",""),l?.setAttribute("label","Full document"),r.dispatchEvent(new CustomEvent(w,{bubbles:!0,composed:!0})),d&&queueMicrotask(()=>S(a,d))};let l=null;return o.sectioned?(a.append(o.content),l=document.createElement("esp-button"),l.setAttribute("label","View full document"),l.setAttribute("collapsed",""),l.setAttribute("incognito",""),l.addEventListener("clicked",()=>u(n)),s.append(l)):a.append(o.content),a.addEventListener("click",d=>{const f=d.composedPath().find(L=>L instanceof HTMLAnchorElement)?.getAttribute("href")??"";if(!f)return;if(!f.startsWith("#")){d.preventDefault(),window.open(f,"_blank","noopener,noreferrer");return}d.preventDefault();const p=E(f);p&&(o.sectioned?u(p):S(a,p))}),c.append(i,a,s),{element:r,anchorFound:o.anchorFound,fullDocument:!o.sectioned,...o.heading?{topicTitle:o.heading}:{}}}function M(e){const t=document.createElement("section");t.dataset.espHelpStatus="";const n=t.attachShadow({mode:"open"}),o=document.createElement("style");o.textContent=g;const r=document.createElement("p");if(r.setAttribute("part","message"),r.textContent=e.message,n.append(o,r),e.actionLabel&&e.onAction){const c=document.createElement("div");c.setAttribute("part","actions");const i=document.createElement("esp-button");i.setAttribute("label",e.actionLabel),i.setAttribute("collapsed",""),i.addEventListener("clicked",e.onAction),c.append(i),n.append(c)}return t}function H(e){let t=e;const n=new Set;for(;t&&!n.has(t);){n.add(t);const o=t.getAttribute("help-src")?.trim()??"";if(o)return o;t=h(t)}return""}function h(e){if(e.assignedSlot)return e.assignedSlot;if(e.parentElement)return e.parentElement;const t=e.getRootNode();return t instanceof ShadowRoot?t.host:null}function m(...e){for(const t of e){const n=t?.trim()??"";if(n)return n}}function b(e,t,n){if(e.nodeType===Node.TEXT_NODE){t.appendChild(document.createTextNode(e.textContent??""));return}if(!(e instanceof Element)||N.has(e.tagName))return;if(!v.has(e.tagName)){for(const r of[...e.childNodes])b(r,t,n);return}const o=document.createElement(e.tagName.toLowerCase());R(e,o,n);for(const r of[...e.childNodes])b(r,o,n);t.appendChild(o)}function R(e,t,n){const o=e.getAttribute("id")?.trim();o&&t.setAttribute("id",o);for(const r of y[e.tagName]??[]){if(!e.hasAttribute(r))continue;const c=e.getAttribute(r)??"",i=r==="href"||r==="src"?C(c,n):c;i!==null&&t.setAttribute(r,i)}}function C(e,t){if(!e||e.startsWith("#"))return e;try{const n=new URL(e,t);return["http:","https:","mailto:","tel:"].includes(n.protocol)?n.href:null}catch{return null}}function T(e,t){return[...e.querySelectorAll("[id]")].find(n=>n.id===t)??null}function A(e){const t=/^H([1-6])$/u.exec(e.tagName);return t?Number(t[1]):null}function S(e,t){const n=T(e,t);if(!n)return;const o=x(n);if(!o)return;const r=n.getBoundingClientRect().top,c=o.getBoundingClientRect().top;o.scrollTop+=r-c}function x(e){for(let t=h(e);t;t=h(t)){if(!(t instanceof HTMLElement))continue;const n=getComputedStyle(t).overflowY;if(n==="auto"||n==="scroll")return t}return null}export{B as createHelpDocumentView,M as createHelpStatusView,k as normalizeHelpDocument,P as resolveHelpTarget,D as selectHelpContent};
52
+ `;function M(e,t={}){const n=t.helpUrl?.trim()??"",o=n?"":R(e),r=n||o;if(!r)return null;let c;try{c=new URL(r,e.ownerDocument.baseURI)}catch{return null}const i=T(c.hash);c.hash="";const a=m(t.anchor,t.fallbackAnchor),l=n?m(i,a):m(a,i),d=new URL(c.href);return l&&(d.hash=l),{src:c.href,...l?{anchor:l}:{},href:d.href}}function _(e,t){const n=new URL(t,document.baseURI);n.hash="";const o=new DOMParser().parseFromString(e,"text/html"),r=o.querySelector("title")?.textContent?.trim()||void 0,c=document.createDocumentFragment();for(const i of[...o.body.childNodes])b(i,c,n.href);return{src:n.href,...r?{title:r}:{},body:c}}function x(e,t){const n=t?.trim()??"";if(!n)return{content:e.body.cloneNode(!0),anchorFound:!0,sectioned:!1};const o=A(e.body,n);if(!o)return{content:e.body.cloneNode(!0),anchorFound:!1,sectioned:!1};const r=S(o);if(!r||!o.parentNode)return{content:e.body.cloneNode(!0),anchorFound:!0,sectioned:!1};const c=document.createDocumentFragment();let i=o.nextSibling;for(;i;){if(i instanceof Element){const a=S(i);if(a&&a<=r)break}c.append(i.cloneNode(!0)),i=i.nextSibling}return{content:c,anchorFound:!0,sectioned:!0,heading:o.textContent?.trim()||void 0}}function G(e,t,n={}){const o=t?.trim()||void 0,r=x(e,o),c=document.createElement("section");c.dataset.espHelpDocument="";const i=c.attachShadow({mode:"open"}),a=document.createElement("style");a.textContent=g;const l=document.createElement("div");l.setAttribute("part","content");const d=document.createElement("div");d.setAttribute("part","actions");const E=u=>{l.replaceChildren(L(e)),s?.setAttribute("disabled",""),s?.setAttribute("label","Full document"),c.dispatchEvent(new CustomEvent(D,{bubbles:!0,composed:!0})),n.onFullDocument?.(c),u&&queueMicrotask(()=>N(l,u))};let s=null;return r.sectioned?(l.append(r.content),s=document.createElement("esp-button"),s.setAttribute("label","View full document"),s.setAttribute("collapsed",""),s.setAttribute("incognito",""),s.addEventListener("clicked",()=>E(o)),d.append(s)):l.append(L(e)),l.addEventListener("click",u=>{const f=u.composedPath().find(v=>v instanceof HTMLAnchorElement)?.getAttribute("href")??"";if(!f)return;if(!f.startsWith("#")){u.preventDefault(),window.open(f,"_blank","noopener,noreferrer");return}u.preventDefault();const p=T(f);p&&(r.sectioned?E(p):N(l,p))}),i.append(a,l,d),{element:c,anchorFound:r.anchorFound,fullDocument:!r.sectioned,...r.heading?{topicTitle:r.heading}:{}}}function V(e){const t=document.createElement("section");t.dataset.espHelpStatus="";const n=t.attachShadow({mode:"open"}),o=document.createElement("style");o.textContent=g;const r=document.createElement("p");if(r.setAttribute("part","message"),r.textContent=e.message,n.append(o,r),e.actionLabel&&e.onAction){const c=document.createElement("div");c.setAttribute("part","actions");const i=document.createElement("esp-button");i.setAttribute("label",e.actionLabel),i.setAttribute("collapsed",""),i.addEventListener("clicked",e.onAction),c.append(i),n.append(c)}return t}function R(e){let t=e;const n=new Set;for(;t&&!n.has(t);){n.add(t);const o=t.getAttribute("help-src")?.trim()??"";if(o)return o;t=h(t)}return""}function h(e){if(e.assignedSlot)return e.assignedSlot;if(e.parentElement)return e.parentElement;const t=e.getRootNode();return t instanceof ShadowRoot?t.host:null}function m(...e){for(const t of e){const n=t?.trim()??"";if(n)return n}}function b(e,t,n){if(e.nodeType===Node.TEXT_NODE){t.appendChild(document.createTextNode(e.textContent??""));return}if(!(e instanceof Element)||C.has(e.tagName))return;if(!y.has(e.tagName)){for(const r of[...e.childNodes])b(r,t,n);return}const o=document.createElement(e.tagName.toLowerCase());F(e,o,n);for(const r of[...e.childNodes])b(r,o,n);t.appendChild(o)}function F(e,t,n){const o=e.getAttribute("id")?.trim();o&&t.setAttribute("id",o);for(const r of H[e.tagName]??[]){if(!e.hasAttribute(r))continue;const c=e.getAttribute(r)??"",i=r==="href"||r==="src"?I(c,n):c;i!==null&&t.setAttribute(r,i)}}function I(e,t){if(!e||e.startsWith("#"))return e;try{const n=new URL(e,t);return["http:","https:","mailto:","tel:"].includes(n.protocol)?n.href:null}catch{return null}}function A(e,t){return[...e.querySelectorAll("[id]")].find(n=>n.id===t)??null}function S(e){const t=/^H([1-6])$/u.exec(e.tagName);return t?Number(t[1]):null}function L(e){const t=e.body.cloneNode(!0),n=w(e.title);if(!n)return t;let o=t.firstChild;for(;o?.nodeType===Node.TEXT_NODE&&!o.textContent?.trim();)o=o.nextSibling;return o instanceof Element&&o.tagName==="H1"&&w(o.textContent)===n&&o.remove(),t}function w(e){return e?.replace(/\s+/gu," ").trim().toLowerCase()??""}function N(e,t){const n=A(e,t);if(!n)return;const o=U(n);if(!o)return;const r=n.getBoundingClientRect().top,c=o.getBoundingClientRect().top;o.scrollTop+=r-c}function U(e){for(let t=h(e);t;t=h(t)){if(!(t instanceof HTMLElement))continue;const n=getComputedStyle(t).overflowY;if(n==="auto"||n==="scroll")return t}return null}export{G as createHelpDocumentView,V as createHelpStatusView,_ as normalizeHelpDocument,M as resolveHelpTarget,x as selectHelpContent};
@@ -3,6 +3,23 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
3
3
  import { type EspalierDialog } from "../dialog/esp-dialog.js";
4
4
  import "../toaster/esp-toaster.js";
5
5
  type HeaderPosition = "normal" | "sticky" | "fixed";
6
+ export type PageWorkspaceSeparator = "main-preview" | "preview-flyout" | "main-flyout";
7
+ export type PageWorkspaceResizeSource = "keyboard" | "pointer";
8
+ /** Detail emitted while an `esp-page` workspace separator changes pane sizes. */
9
+ export interface PageWorkspaceResizeDetail {
10
+ /**
11
+ * Separator that initiated the resize. The second physical seam reports
12
+ * `"preview-flyout"` while preview is visible and `"main-flyout"` when it
13
+ * sits directly between main and help because preview is hidden or closed.
14
+ */
15
+ separator: PageWorkspaceSeparator;
16
+ /** Input modality that initiated the resize. */
17
+ source: PageWorkspaceResizeSource;
18
+ /** Currently allocated preview width in CSS pixels, or zero while preview is hidden. */
19
+ previewWidth: number;
20
+ /** Currently allocated in-grid flyout/help width in CSS pixels, or zero when closed. */
21
+ flyoutWidth: number;
22
+ }
6
23
  /**
7
24
  * Used to lay out standard page structure.
8
25
  *
@@ -34,8 +51,12 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
34
51
  *
35
52
  * The authoring workspace is ordered main, preview, then help. Each region
36
53
  * negotiates between public minimum and maximum widths; preview grows first,
37
- * then help. Opt into collapsing a directly paired header/sidebar navigation
38
- * to its accessible burger/drawer mode when the combined workspace needs it.
54
+ * then help. Set `workspace-resizable` to expose accessible drag and keyboard
55
+ * separators on the dotted seams. Preferred pane sizes remain attached to the
56
+ * mounted page instance and are re-clamped by the same allocator whenever the
57
+ * available inline size changes. Opt into collapsing a directly paired
58
+ * header/sidebar navigation to its accessible burger/drawer mode when the
59
+ * combined workspace needs it.
39
60
  *
40
61
  * @slot sidebar - Contextual navigation placed in the left aside.
41
62
  * @slot right - Content to place in the right aside.
@@ -65,6 +86,12 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
65
86
  * slotted children are constrained to `max-inline-size: 66ch`
66
87
  * for optimal reading measure.
67
88
  *
89
+ * @event {CustomEvent<PageWorkspaceResizeDetail>} esp-page-workspace-resize -
90
+ * Fired while a pointer or keyboard interaction changes a preferred workspace
91
+ * allocation. `separator` is `"main-preview"`, `"preview-flyout"`, or
92
+ * `"main-flyout"` (the second seam without a visible preview). Bubbles and
93
+ * crosses the shadow boundary.
94
+ *
68
95
  * ```html
69
96
  * <esp-page class="docs">
70
97
  * <esp-header slot="header">
@@ -172,6 +199,16 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
172
199
  * to `20rem`.
173
200
  * @cssprop --esp-page-flyout-max-width - Maximum help width and overlay drawer
174
201
  * cap before the `85vw` viewport cap. Defaults to `30rem`.
202
+ * @cssprop --esp-page-resize-step - Arrow-key resize step. Defaults to `1rem`.
203
+ * @cssprop --esp-page-resize-large-step - Shift+Arrow resize step. Defaults to
204
+ * `4rem`.
205
+ * @cssprop --esp-page-resize-handle-hit-size - Transparent inline hit target
206
+ * centered on each dotted seam. Defaults to `2.75rem`.
207
+ * @cssprop --esp-page-resize-focus-outline - Keyboard-focus line drawn along
208
+ * the focused seam, spanning the visible dotted edge up to one viewport
209
+ * height. Defaults to `2px dashed var(--esp-color-link)`.
210
+ * @cssprop --esp-page-resize-focus-shadow - Glow cast by the focused seam
211
+ * line, in the line's color. Defaults to `0 0 0.75rem var(--esp-color-link)`.
175
212
  * @cssprop --esp-page-preview-width - Legacy fixed-width alias that pins both
176
213
  * preview bounds.
177
214
  * @cssprop --esp-page-flyout-width - Legacy fixed-width alias that pins both
@@ -189,6 +226,13 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
189
226
  * @csspart surface - The surface backdrop carrying the edge shadow/border.
190
227
  * @csspart preview - The persistent preview complementary landmark.
191
228
  * @csspart preview-content - The sticky wrapper around preview content.
229
+ * @csspart main-preview-resize-handle - Separator between main and preview.
230
+ * Announces main's width.
231
+ * @csspart preview-flyout-resize-handle - Separator between preview and
232
+ * in-grid flyout/help while preview is visible. Announces help's width.
233
+ * @csspart main-flyout-resize-handle - The same physical seam while preview
234
+ * is hidden or closed: it then sits between main and in-grid help, sizes
235
+ * help directly against main, and reports `separator: "main-flyout"`.
192
236
  *
193
237
  * ```html
194
238
  * <style>
@@ -239,16 +283,54 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
239
283
  * @menuIcon layout
240
284
  *
241
285
  *
286
+ * @example Resizable preview
287
+ * ```html
288
+ * <style>
289
+ * .page-preview-resize-demo {
290
+ * --esp-page-main-min-width: 100px;
291
+ * --esp-page-main-max-width: 100vw;
292
+ * --esp-page-preview-min-width: 100px;
293
+ * --esp-page-preview-max-width: 100vw;
294
+ * }
295
+ *
296
+ * .page-preview-resize-demo > main,
297
+ * .page-preview-resize-demo > [slot="preview"] {
298
+ * box-sizing: border-box;
299
+ * padding: var(--esp-size-padding-page);
300
+ * }
301
+ * </style>
302
+ *
303
+ * <esp-page
304
+ * class="page-preview-resize-demo"
305
+ * preview-open
306
+ * preview-label="Article preview"
307
+ * workspace-resizable
308
+ * >
309
+ * <main>
310
+ * <h2>Article editor</h2>
311
+ * <p>
312
+ * Preview starts at its minimum width. Drag the dotted seam left to
313
+ * enlarge it, then resize in either direction. You can also focus the
314
+ * seam and use Left/Right Arrow.
315
+ * </p>
316
+ * </main>
317
+ * <article slot="preview">
318
+ * <h2>Article preview</h2>
319
+ * <p>The selected width stays with this mounted page and adapts when its container changes.</p>
320
+ * </article>
321
+ * </esp-page>
322
+ * ```
323
+ *
242
324
  * @example Main, preview, and contextual help
243
325
  * ```html
244
326
  * <style>
245
327
  * .page-workspace-demo {
246
- * --esp-page-main-min-width: 26rem;
247
- * --esp-page-main-max-width: 48rem;
248
- * --esp-page-preview-min-width: 18rem;
249
- * --esp-page-preview-max-width: 26rem;
250
- * --esp-page-flyout-min-width: 18rem;
251
- * --esp-page-flyout-max-width: 22rem;
328
+ * --esp-page-main-min-width: 100px;
329
+ * --esp-page-main-max-width: 100vw;
330
+ * --esp-page-preview-min-width: 100px;
331
+ * --esp-page-preview-max-width: 100vw;
332
+ * --esp-page-flyout-min-width: 100px;
333
+ * --esp-page-flyout-max-width: 100vw;
252
334
  * }
253
335
  *
254
336
  * .page-workspace-demo > main,
@@ -267,6 +349,7 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
267
349
  * class="page-workspace-demo"
268
350
  * preview-open
269
351
  * preview-label="Rendered page preview"
352
+ * workspace-resizable
270
353
  * >
271
354
  * <main>
272
355
  * <h2>Page details</h2>
@@ -276,6 +359,7 @@ type HeaderPosition = "normal" | "sticky" | "fixed";
276
359
  * <p>
277
360
  * Help is anchored to the title field in this main editor. Its caret and
278
361
  * dotted connector cross the persistent preview without blocking it.
362
+ * Both dotted pane seams are resize handles while their panes are in-grid.
279
363
  * </p>
280
364
  * <esp-button id="page-workspace-preview-toggle" label="Toggle preview"></esp-button>
281
365
  * <esp-button id="page-workspace-help-toggle" label="Toggle title help"></esp-button>
@@ -398,6 +482,12 @@ export declare class EspalierPage extends EspalierElementBase {
398
482
  * collapse to its burger/drawer presentation when preview needs more room.
399
483
  */
400
484
  previewCollapseSidebar: boolean;
485
+ /**
486
+ * Expose accessible pointer and keyboard separators for the visible
487
+ * Main → Preview → Flyout/Help workspace seams. Preferred sizes remain on
488
+ * this mounted instance and are continuously re-clamped by page allocation.
489
+ */
490
+ workspaceResizable: boolean;
401
491
  /**
402
492
  * Whether preview content is currently rendered. Managed by the page's
403
493
  * space negotiation; consumers should treat this reflected property as read-only.