@taprootio/espalier 2.13.1 → 2.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.
- package/CHANGELOG.md +34 -0
- package/custom-elements.json +6012 -5743
- package/dist/flyout/esp-flyout.js +13 -13
- package/dist/page/esp-page.d.ts +27 -14
- package/dist/page/esp-page.js +85 -33
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var l=function(
|
|
1
|
+
var l=function(u,e,t,s){var o=arguments.length,r=o<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,t):s,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(u,e,t,s);else for(var i=u.length-1;i>=0;i--)(n=u[i])&&(r=(o<3?n(r):o>3?n(e,t,r):n(e,t))||r);return o>3&&r&&Object.defineProperty(e,t,r),r};import{css as p,html as g,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 w}from"../shared/esp-element-base.js";import{getEspBus as f}from"../shared/bus-events.js";import{FLYOUT_FULL_HEIGHT_REQUEST_EVENT as k,markFlyoutRequestServiced as M}from"../shared/flyout-events.js";import{OverlayController as G}from"../shared/overlay-controller.js";import{cancelSVG as q}from"../shared/svgs/cancel.js";import{traverseToClosest as y}from"../shared/utilities.js";const B="(max-width: 50em)",H="Flyout",A=p`
|
|
2
2
|
position: fixed;
|
|
3
3
|
inset: 0;
|
|
4
4
|
margin-block-start: 0;
|
|
@@ -7,13 +7,13 @@ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
|
|
|
7
7
|
height: 100vh;
|
|
8
8
|
height: 100dvh;
|
|
9
9
|
z-index: var(--esp-flyout-z-index, 3000);
|
|
10
|
-
`,
|
|
10
|
+
`,R=p`
|
|
11
11
|
display: block;
|
|
12
12
|
position: absolute;
|
|
13
13
|
inset: 0;
|
|
14
14
|
background-color: var(--esp-vellum-background, var(--esp-color-layer-3));
|
|
15
15
|
opacity: var(--esp-vellum-opacity, 0.85);
|
|
16
|
-
`,
|
|
16
|
+
`,x=p`
|
|
17
17
|
position: absolute;
|
|
18
18
|
inset-block: 0;
|
|
19
19
|
inset-inline-end: 0;
|
|
@@ -31,7 +31,7 @@ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
|
|
|
31
31
|
@starting-style {
|
|
32
32
|
translate: 100% 0;
|
|
33
33
|
}
|
|
34
|
-
`;let a=class extends
|
|
34
|
+
`;let a=class extends w{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 G({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(k,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(k,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=y(this,"esp-page"),s=e.anchor??e.returnFocusTo;if(!s){if(!t)return!0;const i=this.getPageChain(t);return this.scope==="outermost"&&i[i.length-1]===t}const o=this.getPageChain(s);if(o.length===0)return t===null;const r=o.find(i=>this.hasNearestScopeFlyout(i)),n=r??o[o.length-1];return t!==n?!1:r?this.scope==="nearest":this.scope==="outermost"}getPageChain(e){const t=[];let s=e;for(;s;){const o=y(s,"esp-page");if(!o||t.includes(o))break;t.push(o),s=this.composedParent(o)}return t}hasNearestScopeFlyout(e){return Array.from(e.querySelectorAll("esp-flyout")).some(t=>!t.standalone&&t.scope==="nearest"&&y(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("fullHeight")||e.has("pageOverlayRequested"))&&this.dispatchEvent(new CustomEvent("flyout-state-changed",{detail:{},bubbles:!0,composed:!0}))}syncAnchorGeometry(){const e=y(this,"esp-page"),t=this.anchor?this.getPageChain(this.anchor):[],s=e?.shadowRoot?.querySelector(".esp-page-main"),o=this.panelRef.value;if(!this.open||this.effectiveOverlay||!o){this.clearAnchorGeometry();return}const r=this.getVisibleBlockBounds(),n=Math.max(0,r.bottom-r.top);if(this.setGeometryProperty("--_esp-flyout-max-block-size",`${n}px`),this.fullHeight){this.clearAnchorPlacementGeometry();return}if(!this.anchor||!e||!t.includes(e)||!s){this.clearAnchorGeometry();return}const i=this.anchor.getBoundingClientRect(),d=Math.max(0,i.top-s.getBoundingClientRect().top),c=Number.isFinite(i.height)?i.height:0;this.setGeometryProperty("--_esp-flyout-anchor-offset",`${d}px`),this.setGeometryProperty("--_esp-flyout-anchor-block-size",`${c}px`);const v=o.getBoundingClientRect().height||n,P=Math.max(0,i.top+v-r.bottom),z=Math.max(0,v-c),b=Math.min(P,z);this.setGeometryProperty("--_esp-flyout-viewport-shift",`${b}px`);const C=i.top-b,m=8,E=i.top+c/2,S=Math.min(Math.max(m,v-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,s=t+(e?.height??window.innerHeight);for(let o=this.composedParent(this);o;o=this.composedParent(o)){const r=getComputedStyle(o).overflowY;if(r!=="auto"&&r!=="scroll")continue;const n=o.getBoundingClientRect(),i=o instanceof HTMLElement?o.clientTop:0,d=o instanceof HTMLElement?o.clientHeight:n.height;if(d<=0)continue;const c=n.top+i;t=Math.max(t,c),s=Math.min(s,c+d)}return{top:t,bottom:Math.max(t,s)}}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.clearAnchorPlacementGeometry(),this.style.removeProperty("--_esp-flyout-max-block-size")}clearAnchorPlacementGeometry(){this.style.removeProperty("--_esp-flyout-anchor-offset"),this.style.removeProperty("--_esp-flyout-viewport-shift"),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.fullHeight)&&!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 g`
|
|
35
35
|
<div class="vellum" aria-hidden="true" @click=${()=>this.close("vellum")}></div>
|
|
36
36
|
<div
|
|
37
37
|
class=${O({panel:!0,anchored:!!this.anchor,"full-height":this.fullHeight})}
|
|
@@ -40,17 +40,17 @@ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
|
|
|
40
40
|
>
|
|
41
41
|
<span class="anchor-terminus" aria-hidden="true"></span>
|
|
42
42
|
<header part="header">
|
|
43
|
-
${this.heading?
|
|
43
|
+
${this.heading?g`<h2>${this.heading}</h2>`:T}
|
|
44
44
|
|
|
45
45
|
<button class="close" aria-label="Close" @click=${()=>this.close("button")}>
|
|
46
|
-
${
|
|
46
|
+
${q}
|
|
47
47
|
</button>
|
|
48
48
|
</header>
|
|
49
49
|
<div class="content" part="content">
|
|
50
50
|
<slot @slotchange=${this.boundAnchorViewportChange}></slot>
|
|
51
51
|
</div>
|
|
52
52
|
</div>
|
|
53
|
-
`}};a.styles=[...
|
|
53
|
+
`}};a.styles=[...w.styles,p`
|
|
54
54
|
:host {
|
|
55
55
|
display: none;
|
|
56
56
|
}
|
|
@@ -203,17 +203,17 @@ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
|
|
|
203
203
|
|
|
204
204
|
:host([open][mode="overlay"]),
|
|
205
205
|
:host([open][data-page-overlay]) {
|
|
206
|
-
${
|
|
206
|
+
${A}
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
:host([open][mode="overlay"]) .vellum,
|
|
210
210
|
:host([open][data-page-overlay]) .vellum {
|
|
211
|
-
${
|
|
211
|
+
${R}
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
:host([open][mode="overlay"]) .panel,
|
|
215
215
|
:host([open][data-page-overlay]) .panel {
|
|
216
|
-
${
|
|
216
|
+
${x}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
:host([open][mode="overlay"]) .panel.anchored::before,
|
|
@@ -228,15 +228,15 @@ var l=function(d,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnP
|
|
|
228
228
|
|
|
229
229
|
@media (max-width: 50em) {
|
|
230
230
|
:host([open]) {
|
|
231
|
-
${
|
|
231
|
+
${A}
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
.vellum {
|
|
235
|
-
${
|
|
235
|
+
${R}
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
.panel {
|
|
239
|
-
${
|
|
239
|
+
${x}
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
.panel.anchored::before,
|
package/dist/page/esp-page.d.ts
CHANGED
|
@@ -3,14 +3,16 @@ 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";
|
|
6
|
+
export type PageWorkspaceSeparator = "main-preview" | "preview-flyout" | "main-flyout" | "preview-end" | "flyout-end";
|
|
7
7
|
export type PageWorkspaceResizeSource = "keyboard" | "pointer";
|
|
8
8
|
/** Detail emitted while an `esp-page` workspace separator changes pane sizes. */
|
|
9
9
|
export interface PageWorkspaceResizeDetail {
|
|
10
10
|
/**
|
|
11
|
-
* Separator that initiated the resize. The second
|
|
11
|
+
* Separator that initiated the resize. The second internal seam reports
|
|
12
12
|
* `"preview-flyout"` while preview is visible and `"main-flyout"` when it
|
|
13
13
|
* sits directly between main and help because preview is hidden or closed.
|
|
14
|
+
* The exposed trailing workspace edge reports `"preview-end"` or
|
|
15
|
+
* `"flyout-end"` for the pane that owns that edge.
|
|
14
16
|
*/
|
|
15
17
|
separator: PageWorkspaceSeparator;
|
|
16
18
|
/** Input modality that initiated the resize. */
|
|
@@ -52,11 +54,13 @@ export interface PageWorkspaceResizeDetail {
|
|
|
52
54
|
* The authoring workspace is ordered main, preview, then help. Each region
|
|
53
55
|
* negotiates between public minimum and maximum widths; preview grows first,
|
|
54
56
|
* then help. Set `workspace-resizable` to expose accessible drag and keyboard
|
|
55
|
-
* separators on the dotted seams
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
57
|
+
* separators on the dotted internal seams and the exposed trailing edge of the
|
|
58
|
+
* last auxiliary pane. Preferred pane sizes remain attached to the mounted
|
|
59
|
+
* page instance and are re-clamped by the same allocator whenever the available
|
|
60
|
+
* inline size changes. Opt into collapsing a directly paired
|
|
61
|
+
* header/sidebar navigation to its accessible burger/drawer mode after
|
|
62
|
+
* auxiliary panes contract and before main is reclaimed. The rail returns
|
|
63
|
+
* only when doing so preserves the settled pane allocation.
|
|
60
64
|
*
|
|
61
65
|
* @slot sidebar - Contextual navigation placed in the left aside.
|
|
62
66
|
* @slot right - Content to place in the right aside.
|
|
@@ -92,9 +96,10 @@ export interface PageWorkspaceResizeDetail {
|
|
|
92
96
|
*
|
|
93
97
|
* @event {CustomEvent<PageWorkspaceResizeDetail>} esp-page-workspace-resize -
|
|
94
98
|
* Fired while a pointer or keyboard interaction changes a preferred workspace
|
|
95
|
-
* allocation. `separator`
|
|
96
|
-
* `"main-flyout"`
|
|
97
|
-
* crosses the shadow
|
|
99
|
+
* allocation. `separator` identifies an internal seam (`"main-preview"`,
|
|
100
|
+
* `"preview-flyout"`, or `"main-flyout"`) or the exposed trailing edge
|
|
101
|
+
* (`"preview-end"` or `"flyout-end"`). Bubbles and crosses the shadow
|
|
102
|
+
* boundary.
|
|
98
103
|
*
|
|
99
104
|
* ```html
|
|
100
105
|
* <esp-page class="docs">
|
|
@@ -240,12 +245,17 @@ export interface PageWorkspaceResizeDetail {
|
|
|
240
245
|
* @csspart preview - The persistent preview complementary landmark.
|
|
241
246
|
* @csspart preview-content - The sticky wrapper around preview content.
|
|
242
247
|
* @csspart main-preview-resize-handle - Separator between main and preview.
|
|
243
|
-
* Announces main's width
|
|
248
|
+
* Announces main's width and includes preview's changing width in its value
|
|
249
|
+
* text when main is capped.
|
|
244
250
|
* @csspart preview-flyout-resize-handle - Separator between preview and
|
|
245
251
|
* in-grid flyout/help while preview is visible. Announces help's width.
|
|
246
252
|
* @csspart main-flyout-resize-handle - The same physical seam while preview
|
|
247
253
|
* is hidden or closed: it then sits between main and in-grid help, sizes
|
|
248
254
|
* help directly against main, and reports `separator: "main-flyout"`.
|
|
255
|
+
* @csspart preview-end-resize-handle - The exposed trailing edge of preview
|
|
256
|
+
* while preview is the last in-grid auxiliary pane.
|
|
257
|
+
* @csspart flyout-end-resize-handle - The exposed trailing edge of in-grid
|
|
258
|
+
* flyout/help while help is the last auxiliary pane.
|
|
249
259
|
*
|
|
250
260
|
* ```html
|
|
251
261
|
* <style>
|
|
@@ -372,7 +382,8 @@ export interface PageWorkspaceResizeDetail {
|
|
|
372
382
|
* <p>
|
|
373
383
|
* Help is anchored to the title field in this main editor. Its caret and
|
|
374
384
|
* dotted connector cross the persistent preview without blocking it.
|
|
375
|
-
*
|
|
385
|
+
* The dotted internal seams and any exposed trailing pane edge are resize
|
|
386
|
+
* handles while their panes are in-grid.
|
|
376
387
|
* </p>
|
|
377
388
|
* <esp-button id="page-workspace-preview-toggle" label="Toggle preview"></esp-button>
|
|
378
389
|
* <esp-button id="page-workspace-help-toggle" label="Toggle title help"></esp-button>
|
|
@@ -498,8 +509,10 @@ export declare class EspalierPage extends EspalierElementBase {
|
|
|
498
509
|
previewCollapseSidebar: boolean;
|
|
499
510
|
/**
|
|
500
511
|
* Expose accessible pointer and keyboard separators for the visible
|
|
501
|
-
* Main → Preview → Flyout/Help workspace seams
|
|
502
|
-
*
|
|
512
|
+
* Main → Preview → Flyout/Help workspace seams and for the trailing edge of
|
|
513
|
+
* the last auxiliary pane when outer canvas is available. Preferred sizes
|
|
514
|
+
* remain on this mounted instance and are continuously re-clamped by page
|
|
515
|
+
* allocation.
|
|
503
516
|
*/
|
|
504
517
|
workspaceResizable: boolean;
|
|
505
518
|
/**
|