@taprootio/espalier 2.1.3 → 2.2.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/custom-elements.json +1554 -124
- package/dist/flyout/esp-flyout.d.ts +393 -0
- package/dist/flyout/esp-flyout.js +153 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/dist/page/esp-page.d.ts +20 -1
- package/dist/page/esp-page.js +90 -17
- package/dist/shared/bus-events.d.ts +18 -1
- package/dist/shared/events.d.ts +13 -0
- package/dist/shared/events.js +1 -1
- package/dist/shared/flyout-events.d.ts +87 -0
- package/dist/shared/flyout-events.js +1 -0
- package/dist/shared/overlay-controller.js +1 -1
- package/dist/toaster/esp-toaster.d.ts +21 -0
- package/dist/toaster/esp-toaster.js +9 -9
- package/espalier.token-manifest.json +49 -1
- package/package.json +1 -1
package/dist/page/esp-page.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var
|
|
2
|
-
<div part="wrapper" class="esp-page ${
|
|
1
|
+
var d=function(h,e,s,o){var n=arguments.length,a=n<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,s):o,t;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(h,e,s,o);else for(var r=h.length-1;r>=0;r--)(t=h[r])&&(a=(n<3?t(a):n>3?t(e,s,a):t(e,s))||a);return n>3&&a&&Object.defineProperty(e,s,a),a};import{css as f,html as m}from"lit";import{customElement as v,property as l}from"lit/decorators.js";import{classMap as y}from"lit/directives/class-map.js";import{createRef as c,ref as u}from"lit/directives/ref.js";import{EspalierElementBase as g}from"../shared/esp-element-base.js";import{BiDirectionalStickyController as p}from"./bi-directional-sticky-controller.js";import{getEspBus as w}from"../shared/bus-events.js";import"../toaster/esp-toaster.js";let i=class extends g{constructor(){super(),this.dialogZone=c(),this.flyoutSlot=c(),this.kind="wide",this.align="start",this.contained=!1,this.headerPosition="normal",this.fixedMenus=!1,new p(this,".esp-page-left > .sticky-wrapper"),new p(this,".esp-page-right > .sticky-wrapper"),new p(this,".esp-page-flyout > .sticky-wrapper"),this.addEventListener("flyout-state-changed",e=>this.syncFlyoutState(e))}syncFlyoutState(e){if(e&&e.target?.closest?.("esp-page")!==this)return;const s=t=>{const r=t.mode;return(typeof r=="string"?r:t.getAttribute("mode"))==="overlay"},o=t=>{const r=t.open;return typeof r=="boolean"?r:t.hasAttribute("open")},n=t=>t.anchor!=null,a=(this.flyoutSlot.value?.assignedElements()??[]).filter(t=>t.tagName==="ESP-FLYOUT");this.toggleAttribute("flyout-open",a.some(t=>o(t)&&!s(t))),this.toggleAttribute("flyout-overlay-open",a.some(t=>o(t)&&s(t))),this.toggleAttribute("flyout-anchored",a.some(t=>o(t)&&n(t)))}AddDialog(e){this.dialogZone.value?.appendChild(e)}firstUpdated(e){super.firstUpdated(e),this.syncFlyoutState()}updated(e){super.updated(e),(e.has("fixedMenus")||e.has("headerPosition"))&&w().publish("fixed-menus-changed",{fixed:this.fixedMenus||this.headerPosition==="fixed"})}render(){const e=this.fixedMenus||this.headerPosition==="fixed",s=!e&&this.headerPosition==="sticky";return m`
|
|
2
|
+
<div part="wrapper" class="esp-page ${y({"fixed-menus":e,"fixed-header":e,"sticky-header":s})}">
|
|
3
3
|
<div part="canvas" class="esp-page-canvas esp-page-canvas--left" aria-hidden="true"></div>
|
|
4
4
|
<div part="canvas" class="esp-page-canvas esp-page-canvas--right" aria-hidden="true"></div>
|
|
5
5
|
<div part="surface" class="esp-page-surface" aria-hidden="true"></div>
|
|
@@ -19,20 +19,40 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
19
19
|
<slot name="right"></slot>
|
|
20
20
|
</div>
|
|
21
21
|
</aside>
|
|
22
|
+
<div class="esp-page-flyout">
|
|
23
|
+
<div class="sticky-wrapper">
|
|
24
|
+
<slot
|
|
25
|
+
name="flyout"
|
|
26
|
+
${u(this.flyoutSlot)}
|
|
27
|
+
@slotchange=${()=>this.syncFlyoutState()}
|
|
28
|
+
></slot>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
22
31
|
<footer>
|
|
23
32
|
<slot name="footer"></slot>
|
|
24
33
|
</footer>
|
|
25
|
-
<div id="dialog-drop-zone" ${
|
|
34
|
+
<div id="dialog-drop-zone" ${u(this.dialogZone)}></div>
|
|
26
35
|
<esp-toaster></esp-toaster>
|
|
27
36
|
</div>
|
|
28
|
-
`}};
|
|
37
|
+
`}};i.styles=[...g.styles,f`
|
|
29
38
|
:host {
|
|
30
39
|
--_esp-page-resolved-max-width: var(--esp-page-max-width, 1536px);
|
|
31
40
|
|
|
32
41
|
--_esp-page-main-track: minmax(0, var(--_esp-page-resolved-max-width));
|
|
33
42
|
|
|
34
|
-
--_esp-page-gutter-left:
|
|
43
|
+
--_esp-page-gutter-left: 0fr;
|
|
35
44
|
--_esp-page-gutter-right: 1fr;
|
|
45
|
+
|
|
46
|
+
--_esp-page-flyout-min: 0px;
|
|
47
|
+
|
|
48
|
+
--_esp-page-surface-edge-shadow: 0.75rem 0 1.5rem -0.75rem var(--esp-color-shadow);
|
|
49
|
+
|
|
50
|
+
--_esp-page-surface-shadow: var(
|
|
51
|
+
--esp-page-surface-shadow,
|
|
52
|
+
-0.75rem 0 1.5rem -0.75rem var(--esp-color-shadow),
|
|
53
|
+
var(--_esp-page-surface-edge-shadow)
|
|
54
|
+
);
|
|
55
|
+
--_esp-page-surface-border: var(--esp-page-surface-border, none);
|
|
36
56
|
--_esp-page-fixed-header-offset: var(
|
|
37
57
|
--esp-page-fixed-header-offset,
|
|
38
58
|
var(--esp-header-height, calc(4.5 * var(--esp-size-small)))
|
|
@@ -52,15 +72,42 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
52
72
|
|
|
53
73
|
:host([align="end"]) {
|
|
54
74
|
--_esp-page-gutter-left: 1fr;
|
|
55
|
-
--_esp-page-gutter-right:
|
|
75
|
+
--_esp-page-gutter-right: 0fr;
|
|
56
76
|
}
|
|
57
77
|
|
|
58
78
|
|
|
59
79
|
:host([kind="full"]) {
|
|
60
80
|
--_esp-page-resolved-max-width: var(--esp-page-max-width, none);
|
|
61
81
|
--_esp-page-main-track: 1fr;
|
|
62
|
-
--_esp-page-gutter-left:
|
|
63
|
-
--_esp-page-gutter-right:
|
|
82
|
+
--_esp-page-gutter-left: 0fr;
|
|
83
|
+
--_esp-page-gutter-right: 0fr;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
:host([flyout-open]) {
|
|
88
|
+
--_esp-page-flyout-min: var(--esp-page-flyout-width, 20rem);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@media (max-width: 50em) {
|
|
93
|
+
:host([flyout-open]) {
|
|
94
|
+
--_esp-page-flyout-min: 0px;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
:host([flyout-overlay-open]) .esp-page > div.esp-page-flyout {
|
|
100
|
+
z-index: var(--esp-flyout-z-index, 3000);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
:host([flyout-anchored]) .esp-page > div.esp-page-flyout > .sticky-wrapper {
|
|
105
|
+
position: static;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
slot[name="flyout"]::slotted(esp-flyout[match-surface]) {
|
|
110
|
+
--esp-flyout-shadow: var(--_esp-page-surface-edge-shadow);
|
|
64
111
|
}
|
|
65
112
|
|
|
66
113
|
|
|
@@ -116,8 +163,13 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
116
163
|
[canvas-left-end surface-start left-start] min-content
|
|
117
164
|
[left-end main-start] var(--_esp-page-main-track)
|
|
118
165
|
[main-end right-start] min-content
|
|
119
|
-
[right-end surface-end canvas-right-start]
|
|
120
|
-
|
|
166
|
+
[right-end surface-end canvas-right-start flyout-start] minmax(
|
|
167
|
+
var(--_esp-page-flyout-min),
|
|
168
|
+
var(--_esp-page-gutter-right)
|
|
169
|
+
)
|
|
170
|
+
[flyout-end canvas-right-end full-end];
|
|
171
|
+
|
|
172
|
+
transition: grid-template-columns 0.25s ease;
|
|
121
173
|
grid-template-rows:
|
|
122
174
|
[top-start] min-content
|
|
123
175
|
[top-end content-start] 1fr
|
|
@@ -173,6 +225,8 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
173
225
|
position: relative;
|
|
174
226
|
overflow: hidden;
|
|
175
227
|
|
|
228
|
+
background: var(--esp-page-main-background, transparent);
|
|
229
|
+
|
|
176
230
|
contain: inline-size;
|
|
177
231
|
}
|
|
178
232
|
|
|
@@ -181,6 +235,21 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
181
235
|
}
|
|
182
236
|
|
|
183
237
|
|
|
238
|
+
> div.esp-page-flyout {
|
|
239
|
+
|
|
240
|
+
grid-column: flyout;
|
|
241
|
+
justify-self: start;
|
|
242
|
+
grid-row: content;
|
|
243
|
+
z-index: 5;
|
|
244
|
+
position: relative;
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@media (max-width: 50em) {
|
|
248
|
+
z-index: var(--esp-flyout-z-index, 3000);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
|
|
184
253
|
> .esp-page-canvas {
|
|
185
254
|
|
|
186
255
|
grid-row: top-start / footer-end;
|
|
@@ -204,6 +273,7 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
204
273
|
}
|
|
205
274
|
|
|
206
275
|
> .esp-page-canvas--right {
|
|
276
|
+
|
|
207
277
|
grid-column: canvas-right;
|
|
208
278
|
}
|
|
209
279
|
|
|
@@ -214,12 +284,8 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
214
284
|
grid-row: top-start / footer-end;
|
|
215
285
|
z-index: 2;
|
|
216
286
|
pointer-events: none;
|
|
217
|
-
box-shadow: var(
|
|
218
|
-
|
|
219
|
-
-0.75rem 0 1.5rem -0.75rem var(--esp-color-shadow),
|
|
220
|
-
0.75rem 0 1.5rem -0.75rem var(--esp-color-shadow)
|
|
221
|
-
);
|
|
222
|
-
border-inline: var(--esp-page-surface-border, none);
|
|
287
|
+
box-shadow: var(--_esp-page-surface-shadow);
|
|
288
|
+
border-inline: var(--_esp-page-surface-border);
|
|
223
289
|
}
|
|
224
290
|
|
|
225
291
|
|
|
@@ -270,6 +336,7 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
270
336
|
> div.esp-page-main,
|
|
271
337
|
> aside.esp-page-left,
|
|
272
338
|
> aside.esp-page-right,
|
|
339
|
+
> div.esp-page-flyout,
|
|
273
340
|
> .esp-page-surface,
|
|
274
341
|
> .esp-page-canvas {
|
|
275
342
|
margin-top: var(--_esp-page-fixed-header-offset);
|
|
@@ -299,4 +366,10 @@ var o=function(n,e,s,r){var d=arguments.length,a=d<3?e:r===null?r=Object.getOwnP
|
|
|
299
366
|
.esp-page:has(esp-dialog[is-open="true"]) {
|
|
300
367
|
overflow: hidden;
|
|
301
368
|
}
|
|
302
|
-
|
|
369
|
+
|
|
370
|
+
@media (prefers-reduced-motion: reduce) {
|
|
371
|
+
.esp-page {
|
|
372
|
+
transition: none;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
`],d([l({reflect:!0})],i.prototype,"kind",void 0),d([l({reflect:!0})],i.prototype,"align",void 0),d([l({type:Boolean,reflect:!0})],i.prototype,"contained",void 0),d([l({attribute:"header-position",reflect:!0})],i.prototype,"headerPosition",void 0),d([l({attribute:"fixed-menus",type:Boolean,reflect:!0})],i.prototype,"fixedMenus",void 0),i=d([v("esp-page")],i);export{i as EspalierPage};
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { EspBus } from "./esp-bus.js";
|
|
26
26
|
import type { ToastConfig } from "./toast-events.js";
|
|
27
|
+
import type { FlyoutConfig } from "./flyout-events.js";
|
|
27
28
|
/**
|
|
28
29
|
* Contract for elements that provide a seed color to their subtree.
|
|
29
30
|
* Implemented by `EspalierRoot` (the global provider) and
|
|
@@ -91,6 +92,22 @@ export interface SchemeEvents {
|
|
|
91
92
|
export interface ToastEvents {
|
|
92
93
|
"show-toast": ToastConfig;
|
|
93
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Flyout surface events.
|
|
97
|
+
*
|
|
98
|
+
* Published by the `showFlyout()` / `closeFlyout()` helpers and
|
|
99
|
+
* subscribed to by `<esp-flyout>`. This is how components that
|
|
100
|
+
* cannot know where the flyout lives (form items, help buttons,
|
|
101
|
+
* dialog content) request the page's flyout surface.
|
|
102
|
+
*
|
|
103
|
+
* @docUrl /api/flyout-events
|
|
104
|
+
* @menuGroup Bus Events
|
|
105
|
+
* @menuLabel FlyoutEvents
|
|
106
|
+
*/
|
|
107
|
+
export interface FlyoutEvents {
|
|
108
|
+
"show-flyout": FlyoutConfig;
|
|
109
|
+
"close-flyout": Record<string, never>;
|
|
110
|
+
}
|
|
94
111
|
/**
|
|
95
112
|
* Cross-popover coordination events.
|
|
96
113
|
*
|
|
@@ -157,7 +174,7 @@ export interface PageEventMap {
|
|
|
157
174
|
* @menuGroup Bus Events
|
|
158
175
|
* @menuLabel EspBusEventMap
|
|
159
176
|
*/
|
|
160
|
-
export type EspBusEventMap = SchemeEvents & ToastEvents & PopoverEvents & SizeEvents & PageEventMap;
|
|
177
|
+
export type EspBusEventMap = SchemeEvents & ToastEvents & FlyoutEvents & PopoverEvents & SizeEvents & PageEventMap;
|
|
161
178
|
/**
|
|
162
179
|
* Typed accessor for the singleton bus.
|
|
163
180
|
*
|
package/dist/shared/events.d.ts
CHANGED
|
@@ -26,10 +26,12 @@ export { type GridClickedEvent, type GridDataStateEventDetail, type GridItemsCha
|
|
|
26
26
|
export { type DestroyEspalierInfo } from "../info/esp-info.js";
|
|
27
27
|
export { type ValidityChangedDetail, type ValidationError, VALIDITY_CHANGED_EVENT, } from "./validation.js";
|
|
28
28
|
export { type ToastConfig } from "./toast-events.js";
|
|
29
|
+
export { type FlyoutConfig, type FlyoutCloseReason } from "./flyout-events.js";
|
|
29
30
|
export { type PickerItem } from "../pickers/esp-picker-item.js";
|
|
30
31
|
export { type EspalierUploadImage } from "../image-upload/image-helpers.js";
|
|
31
32
|
export { type FontPickerValueChangedDetail, type GoogleFont, type WebSafeFont, } from "../font-picker/esp-font-picker.js";
|
|
32
33
|
import type { EspalierDetails } from "../details/esp-details.js";
|
|
34
|
+
import type { FlyoutCloseReason } from "./flyout-events.js";
|
|
33
35
|
import type { ValidityChangedDetail } from "./validation.js";
|
|
34
36
|
import type { GridClickedEvent, GridItemsChangedEventDetail, GridLoadErrorEventDetail, GridLoadStartEventDetail, GridLoadSuccessEventDetail } from "../grid/esp-grid.js";
|
|
35
37
|
import type { DestroyEspalierInfo } from "../info/esp-info.js";
|
|
@@ -63,6 +65,9 @@ export declare const ESP_EVENTS: {
|
|
|
63
65
|
readonly ESP_ACCORDION_CHANGE: "esp-accordion-change";
|
|
64
66
|
readonly DRAWER_OPENED: "drawer-opened";
|
|
65
67
|
readonly DRAWER_CLOSED: "drawer-closed";
|
|
68
|
+
readonly FLYOUT_OPENED: "flyout-opened";
|
|
69
|
+
readonly FLYOUT_CLOSED: "flyout-closed";
|
|
70
|
+
readonly FLYOUT_STATE_CHANGED: "flyout-state-changed";
|
|
66
71
|
readonly POPOVER_OPENED: "popover-opened";
|
|
67
72
|
readonly POPOVER_CLOSED: "popover-closed";
|
|
68
73
|
readonly GRID_EVENT: "grid-event";
|
|
@@ -267,6 +272,14 @@ export interface EspalierMenuEventMap {
|
|
|
267
272
|
[ESP_EVENTS.DRAWER_OPENED]: CustomEvent<void>;
|
|
268
273
|
[ESP_EVENTS.DRAWER_CLOSED]: CustomEvent<void>;
|
|
269
274
|
}
|
|
275
|
+
/** Events fired by `<esp-flyout>`. */
|
|
276
|
+
export interface EspalierFlyoutEventMap {
|
|
277
|
+
[ESP_EVENTS.FLYOUT_OPENED]: CustomEvent<Record<string, never>>;
|
|
278
|
+
[ESP_EVENTS.FLYOUT_CLOSED]: CustomEvent<{
|
|
279
|
+
reason: FlyoutCloseReason;
|
|
280
|
+
}>;
|
|
281
|
+
[ESP_EVENTS.FLYOUT_STATE_CHANGED]: CustomEvent<Record<string, never>>;
|
|
282
|
+
}
|
|
270
283
|
/** Events fired by `<esp-header-button>`. */
|
|
271
284
|
export interface EspalierHeaderButtonEventMap {
|
|
272
285
|
[ESP_EVENTS.CLICKED]: CustomEvent<Record<string, never>>;
|
package/dist/shared/events.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{VALIDITY_CHANGED_EVENT as
|
|
1
|
+
import{VALIDITY_CHANGED_EVENT as D}from"./validation.js";const e={VALUE_CHANGED:"value-changed",VALIDITY_CHANGED:"validity-changed",CLICKED:"clicked",ESP_SUBMIT:"esp-submit",ESP_SUBMIT_RESPONSE:"esp-submit-response",ESP_SUBMIT_ERROR:"esp-submit-error",ESP_TAB_CHANGED:"esp-tab-changed",ESP_TAB_UPDATED:"esp-tab-updated",ESP_TOGGLE:"esp-toggle",ESP_ACCORDION_CHANGE:"esp-accordion-change",DRAWER_OPENED:"drawer-opened",DRAWER_CLOSED:"drawer-closed",FLYOUT_OPENED:"flyout-opened",FLYOUT_CLOSED:"flyout-closed",FLYOUT_STATE_CHANGED:"flyout-state-changed",POPOVER_OPENED:"popover-opened",POPOVER_CLOSED:"popover-closed",GRID_EVENT:"grid-event",GRID_LOAD_START:"esp-grid-load-start",GRID_LOAD_SUCCESS:"esp-grid-load-success",GRID_LOAD_ERROR:"esp-grid-load-error",GRID_ITEMS_CHANGED:"esp-grid-items-changed",DESTROY:"destroy",FILE_SELECTED:"file-selected",FILE_REMOVED:"file-removed",FILES_SELECTED:"files-selected",FILES_REJECTED:"files-rejected",UPLOAD_RETRY:"upload-retry",RETRY_UPLOAD:"retry-upload",IMAGES_REORDERED:"images-reordered",SEARCH_REQUESTED:"search-requested",RESULT_SELECTED:"result-selected",SEARCH_CLOSED:"search-closed",SELECTION_CHANGED:"selection-changed",CLOSE_MENU:"close-menu",REMOVE_IMAGE:"remove-image"};export{e as ESP_EVENTS,D as VALIDITY_CHANGED_EVENT};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reason a flyout closed, carried on the `flyout-closed`
|
|
3
|
+
* event detail.
|
|
4
|
+
*
|
|
5
|
+
* - `"escape"` — the user pressed the Escape key
|
|
6
|
+
* - `"vellum"` — the user clicked the overlay-mode backdrop
|
|
7
|
+
* - `"button"` — the user clicked the flyout's close button
|
|
8
|
+
* - `"programmatic"` — `close()` was called from code (including
|
|
9
|
+
* the `"close-flyout"` bus event)
|
|
10
|
+
*
|
|
11
|
+
* @docUrl /api/flyout-close-reason
|
|
12
|
+
* @menuGroup Event Details
|
|
13
|
+
* @menuLabel FlyoutCloseReason
|
|
14
|
+
*/
|
|
15
|
+
export type FlyoutCloseReason = "escape" | "vellum" | "button" | "programmatic";
|
|
16
|
+
/**
|
|
17
|
+
* Configuration for opening a flyout via {@link showFlyout}.
|
|
18
|
+
*
|
|
19
|
+
* @docUrl /api/flyout-config
|
|
20
|
+
* @menuGroup Configuration
|
|
21
|
+
* @menuLabel FlyoutConfig
|
|
22
|
+
*/
|
|
23
|
+
export type FlyoutConfig = {
|
|
24
|
+
/**
|
|
25
|
+
* Heading text shown in the flyout's header. Also becomes the
|
|
26
|
+
* flyout's accessible name unless an `aria-label` was set by
|
|
27
|
+
* the author. When omitted, the flyout keeps its current
|
|
28
|
+
* heading.
|
|
29
|
+
*/
|
|
30
|
+
heading?: string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Content to show. A string is rendered as plain text; pass a
|
|
33
|
+
* `Node` (element or fragment) for rich content. The flyout's
|
|
34
|
+
* existing light-DOM children are **replaced** — a second
|
|
35
|
+
* `showFlyout` swaps content in place, it never stacks. When
|
|
36
|
+
* omitted, the flyout opens with whatever content it already
|
|
37
|
+
* has (e.g. declaratively slotted markup).
|
|
38
|
+
*/
|
|
39
|
+
content?: string | Node | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Triggering element whose block-start edge the in-grid flyout
|
|
42
|
+
* should align with. The flyout stays in the page's normal scroll
|
|
43
|
+
* flow, shifting upward only while needed to fit the visible
|
|
44
|
+
* scrollport. Content taller than that scrollport scrolls inside the
|
|
45
|
+
* panel. Overlay drawers ignore this geometry and remain
|
|
46
|
+
* viewport-fixed. When omitted, the flyout starts at the top of the
|
|
47
|
+
* page's content row.
|
|
48
|
+
*/
|
|
49
|
+
anchor?: HTMLElement | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Element to return focus to when the flyout closes — pass the
|
|
52
|
+
* triggering control. In the in-grid modes (where opening never
|
|
53
|
+
* moves focus) it is focused only if focus is inside the panel at
|
|
54
|
+
* close; in the overlay-drawer mode (a modal, which does move focus
|
|
55
|
+
* in) it overrides the automatic restore-to-opener.
|
|
56
|
+
*/
|
|
57
|
+
returnFocusTo?: HTMLElement | undefined;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Open the page's flyout surface. Publishes a `"show-flyout"`
|
|
61
|
+
* event on `EspBus` which is picked up by `<esp-flyout>`.
|
|
62
|
+
*
|
|
63
|
+
* ```ts
|
|
64
|
+
* import { showFlyout } from "@taprootio/espalier";
|
|
65
|
+
*
|
|
66
|
+
* showFlyout({ heading: "Details", content: detailsFragment });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* If no `<esp-flyout>` is connected, the event goes unserviced —
|
|
70
|
+
* callers that need a fallback (e.g. opening a URL in a new tab)
|
|
71
|
+
* should check for a connected flyout themselves.
|
|
72
|
+
*
|
|
73
|
+
* @param config - Flyout configuration.
|
|
74
|
+
* @docUrl /api/show-flyout
|
|
75
|
+
* @menuGroup Functions
|
|
76
|
+
* @menuLabel showFlyout
|
|
77
|
+
*/
|
|
78
|
+
export declare function showFlyout(config?: FlyoutConfig): void;
|
|
79
|
+
/**
|
|
80
|
+
* Close the page's flyout surface. Publishes a `"close-flyout"`
|
|
81
|
+
* event on `EspBus`.
|
|
82
|
+
*
|
|
83
|
+
* @docUrl /api/close-flyout
|
|
84
|
+
* @menuGroup Functions
|
|
85
|
+
* @menuLabel closeFlyout
|
|
86
|
+
*/
|
|
87
|
+
export declare function closeFlyout(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getEspBus as o}from"./bus-events.js";function l(t={}){o().publish("show-flyout",t)}function s(){o().publish("close-flyout",{})}export{s as closeFlyout,l as showFlyout};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const c=['a[href]:not([disabled]):not([tabindex="-1"])','button:not([disabled]):not([tabindex="-1"])','input:not([disabled]):not([tabindex="-1"])','select:not([disabled]):not([tabindex="-1"])','textarea:not([disabled]):not([tabindex="-1"])','[tabindex]:not([tabindex="-1"]):not([disabled])'].join(", "),l="[autofocus]:not([disabled])";class o{static lock(){o._count===0&&(o._savedOverflow=document.body.style.overflow,document.body.style.overflow="hidden"),o._count++}static unlock(){o._count<=0||(o._count--,o._count===0&&(document.body.style.overflow=o._savedOverflow??"",o._savedOverflow=null))}static _reset(){o._count=0,o._savedOverflow=null}}o._count=0,o._savedOverflow=null;function f(){o._reset()}class r{static lock(t){const e=r._counts.get(t);return e!==void 0?(r._counts.set(t,e+1),!0):t.inert?!1:(r._counts.set(t,1),t.inert=!0,!0)}static unlock(t){const e=r._counts.get(t)??0;if(e<=0)return;const s=e-1;s===0?(t.inert=!1,r._counts.delete(t)):r._counts.set(t,s)}static _reset(){r._counts.clear()}}r._counts=new Map;function d(){r._reset()}class _{get isPromoting(){return this._promoting}constructor(t){this._isOpen=!1,this._previouslyFocused=null,this._inertElements=[],this._promoted=!1,this._pendingReactivation=!1,this._dropZone=null,this._promoting=!1,this._host=t.host,this._opts=t,t.host.addController(this)}get isOpen(){return this._isOpen}open(){this._isOpen||(this._pendingReactivation?this._pendingReactivation=!1:this._previouslyFocused=document.activeElement??null,this._isOpen=!0,o.lock(),this._opts.promote!==!1&&this._promoteToDropZone(),this._setInert(!0))}close(){if(this._pendingReactivation=!1,!this._isOpen){this._previouslyFocused?.focus(),this._previouslyFocused=null;return}this._isOpen=!1,o.unlock(),this._setInert(!1),this._previouslyFocused?.focus(),this._previouslyFocused=null}trapFocus(t){const e=this.getFocusableElements();if(e.length===0)return;const s=e[0],n=e[e.length-1],i=this._getDeepActiveElement();t.shiftKey?(i===s||this._isOrContains(s,i))&&(t.preventDefault(),n.focus()):(i===n||this._isOrContains(n,i))&&(t.preventDefault(),s.focus())}moveFocusInto(){const t=this._getAutofocusElement();if(t&&(t.focus(),this._autofocusLanded(t)))return;const e=this.getFocusableElements();if(e.length>0){e[0].focus();return}const s=this._opts.getFocusFallback?.();if(s){s.focus();return}this._opts.getFocusTrapContainer()?.focus()}_getAutofocusElement(){return this._getMatchingElements(l)[0]??null}getFocusableElements(){return this._getMatchingElements(c)}_getMatchingElements(t){const e=this._opts.getFocusTrapContainer();if(!e)return[];const s=[];for(const n of Array.from(e.querySelectorAll("*")))if(n instanceof HTMLElement){if(n.matches(t)&&s.push(n),n.shadowRoot){const i=n.shadowRoot.querySelectorAll(t);s.push(...Array.from(i))}if(n instanceof HTMLSlotElement)for(const i of n.assignedElements({flatten:!0})){if(!(i instanceof HTMLElement))continue;i.matches(t)&&s.push(i);const u=i.querySelectorAll(t);if(s.push(...Array.from(u)),i.shadowRoot){const a=i.shadowRoot.querySelectorAll(t);s.push(...Array.from(a))}}}for(const n of Array.from(this._host.children)){if(!(n instanceof HTMLElement))continue;n.matches(t)&&(s.includes(n)||s.push(n));const i=n.querySelectorAll(t);for(const u of Array.from(i))s.includes(u)||s.push(u);if(n.shadowRoot){const u=n.shadowRoot.querySelectorAll(t);for(const a of Array.from(u))s.includes(a)||s.push(a)}}return s}hostConnected(){}hostDisconnected(){this._promoting||this._isOpen&&(this._setInert(!1),o.unlock(),this._isOpen=!1,this._pendingReactivation=!0)}_setInert(t){if(t){this._inertElements=[];const e=this._resolveInertAnchor(),s=e.parentElement??document.body;for(const n of s.children)n instanceof HTMLElement&&n!==e&&r.lock(n)&&this._inertElements.push(n)}else{for(const e of this._inertElements)r.unlock(e);this._inertElements=[]}}_resolveInertAnchor(){if(this._dropZone)return this._dropZone;let t=this._host;for(;!t.parentElement;){const e=t.getRootNode();if(e instanceof ShadowRoot&&e.host instanceof HTMLElement)t=e.host;else break}return t}_getDeepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t}_isOrContains(t,e){return e?t===e?!0:t.contains(e):!1}_autofocusLanded(t){const e=this._getActiveElementChain(),s=e[0];return e.some(n=>this._isOrContains(t,n)?!0:n!==s&&n instanceof HTMLElement&&this._isOrContains(n,t))}_getActiveElementChain(){const t=[];let e=document.activeElement;for(;e;){t.push(e);const s=e.shadowRoot?.activeElement??null;if(!s||s===e)break;e=s}return t}_promoteToDropZone(){if(this._promoted&&this._dropZone){this._promoting=!0;try{this._dropZone.appendChild(this._host)}finally{this._promoting=!1}return}const t=this._host,e=t.closest("esp-page");if(e){if(customElements.get("esp-page")){this._tryPromote(e);return}customElements.whenDefined("esp-page").then(()=>{if(!this._isOpen||!t.isConnected)return;const s=t.closest("esp-page");this._tryPromote(s)&&(this._setInert(!1),this._setInert(!0))})}}_tryPromote(t){if(!t||this._promoted)return!1;const e=t.AddDialog;if(typeof e=="function"){this._promoting=!0;try{e.call(t,this._host)}finally{this._promoting=!1}return this._promoted=!0,this._dropZone=this._host.parentElement,!0}return!1}}export{c as FOCUSABLE_SELECTOR,_ as OverlayController,d as _resetInertLock,f as _resetScrollLock};
|
|
@@ -5,6 +5,27 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
|
5
5
|
* components. Place one `<esp-toaster>` in your page layout
|
|
6
6
|
* (it is included automatically inside `<esp-page>`).
|
|
7
7
|
*
|
|
8
|
+
* If more than one toaster is connected — for example a page that
|
|
9
|
+
* nests several `<esp-page>`s, each of which injects its own — all
|
|
10
|
+
* toasts live in one shared stack rendered by a single toaster, so
|
|
11
|
+
* each `showToast()` renders once, not once per toaster. The renderer
|
|
12
|
+
* is re-chosen whenever a toast arrives, a toaster connects or
|
|
13
|
+
* disconnects, or a toaster's size collapses or expands, preferring a
|
|
14
|
+
* **visible** instance, and the whole live stack migrates with it —
|
|
15
|
+
* a hidden toaster never swallows toasts, and the stack never
|
|
16
|
+
* fragments across instances. This needs no configuration.
|
|
17
|
+
*
|
|
18
|
+
* The migration timing contract: routing always skips instances
|
|
19
|
+
* hidden by `display`, `visibility`, `opacity: 0`, or
|
|
20
|
+
* `content-visibility` at decision time, and a live stack re-routes
|
|
21
|
+
* **immediately** when its renderer is collapsed via `display` (the
|
|
22
|
+
* collapse resizes the toaster, which is observed). A pure
|
|
23
|
+
* `visibility` or `opacity` flip produces no resize, so an
|
|
24
|
+
* already-rendered stack under one re-routes on the **next** toast,
|
|
25
|
+
* connect/disconnect, or resize instead. (The related `esp-flyout`
|
|
26
|
+
* uses an explicit `standalone` opt-out rather than routing, because
|
|
27
|
+
* its instances are distinct surfaces you target individually.)
|
|
28
|
+
*
|
|
8
29
|
* Toasts auto-dismiss after their `duration` (default 5 seconds).
|
|
9
30
|
* A duration of `0` creates a persistent toast that the user must
|
|
10
31
|
* dismiss manually.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=function(o,e,s,n){var c=arguments.length,r=c<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,s):n,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(o,e,s,n);else for(var d=o.length-1;d>=0;d--)(a=o[d])&&(r=(c<3?a(r):c>3?a(e,s,r):a(e,s))||r);return c>3&&r&&Object.defineProperty(e,s,r),r},t;import{css as f,html as l}from"lit";import{customElement as v,state as h}from"lit/decorators.js";import{EspalierElementBase as p}from"../shared/esp-element-base.js";import{getEspBus as b}from"../shared/bus-events.js";import{getIconHrefForHost as m}from"../shared/intent-values.js";import{renderSpriteIcon as y}from"../shared/svgs/render-sprite-icon.js";let i=t=class extends p{constructor(){super(...arguments),this.toasts=[]}connectedCallback(){super.connectedCallback(),t.connected.push(this),t.busSubscribed||(b().subscribe("show-toast",t.boundDeliver),t.busSubscribed=!0),typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(()=>t.syncRenderer()),this.resizeObserver.observe(this)),t.syncRenderer()}disconnectedCallback(){super.disconnectedCallback(),this.resizeObserver?.disconnect(),this.resizeObserver=void 0,t.connected=t.connected.filter(e=>e!==this),t.connected.length===0?(t.busSubscribed&&(b().unsubscribe("show-toast",t.boundDeliver),t.busSubscribed=!1),t.queue=[]):t.syncRenderer()}static deliver(e){t.queue=[...t.queue,e];const s=e.duration??5;s>0&&setTimeout(()=>t.dismiss(e),s*1e3),t.syncRenderer()}static dismiss(e){t.queue.includes(e)&&(t.queue=t.queue.filter(s=>s!==e),e.onClosed?.(),t.syncRenderer())}static syncRenderer(){const e=t.connected.find(s=>s.isVisible())??t.connected[0];for(const s of t.connected){const n=s===e?t.queue:[];s.toasts.length===n.length&&s.toasts.every((c,r)=>c===n[r])||(s.toasts=[...n])}}isVisible(){const e=this;return typeof e.checkVisibility=="function"?e.checkVisibility({visibilityProperty:!0,opacityProperty:!0,checkVisibilityCSS:!0,checkOpacity:!0}):this.offsetParent!==null}removeToast(e){t.dismiss(e)}getToastIconHref(e){return e.svgPath?.trim()||m(e.icon,this)}render(){return l`
|
|
2
2
|
<div id="toaster" role="region" aria-label="Notifications" aria-live="polite">
|
|
3
|
-
${this.toasts.map(
|
|
4
|
-
.destroyable=${(
|
|
5
|
-
.variant=${
|
|
6
|
-
@destroy=${()=>this.removeToast(
|
|
3
|
+
${this.toasts.map(e=>{const s=this.getToastIconHref(e);return l`<esp-info
|
|
4
|
+
.destroyable=${(e.duration??5)===0}
|
|
5
|
+
.variant=${e.variant??"complementary"}
|
|
6
|
+
@destroy=${()=>this.removeToast(e)}
|
|
7
7
|
>
|
|
8
|
-
${
|
|
9
|
-
${
|
|
8
|
+
${s?y(s,{"aria-hidden":null,class:null,slot:"icon-slot"}):l``}
|
|
9
|
+
${e.message}</esp-info
|
|
10
10
|
>`})}
|
|
11
11
|
</div>
|
|
12
|
-
`}};
|
|
12
|
+
`}};i.connected=[],i.busSubscribed=!1,i.queue=[],i.boundDeliver=o=>t.deliver(o),i.styles=[...p.styles,f`
|
|
13
13
|
#toaster {
|
|
14
14
|
z-index: var(--esp-toaster-z-index, 5000);
|
|
15
15
|
position: fixed;
|
|
@@ -25,4 +25,4 @@ var d=function(a,t,e,o){var i=arguments.length,s=i<3?t:o===null?o=Object.getOwnP
|
|
|
25
25
|
box-shadow: 3px 3px 6px var(--esp-color-shadow);
|
|
26
26
|
pointer-events: all;
|
|
27
27
|
}
|
|
28
|
-
`],
|
|
28
|
+
`],u([h()],i.prototype,"toasts",void 0),i=t=u([v("esp-toaster")],i);export{i as EspalierToaster};
|
|
@@ -460,6 +460,42 @@
|
|
|
460
460
|
"category": "shared-hook",
|
|
461
461
|
"description": "Text color used inside the shared field shell. Defaults to `var(--esp-color-text)`."
|
|
462
462
|
},
|
|
463
|
+
{
|
|
464
|
+
"name": "--esp-flyout-background",
|
|
465
|
+
"category": "component",
|
|
466
|
+
"component": "esp-flyout",
|
|
467
|
+
"description": "The background color of the panel. Defaults to `var(--esp-color-background)`."
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
"name": "--esp-flyout-border",
|
|
471
|
+
"category": "component",
|
|
472
|
+
"component": "esp-flyout",
|
|
473
|
+
"description": "The border on the panel's leading edge. Defaults to the tear-off perforation, `1px dotted var(--esp-color-border)`."
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
"name": "--esp-flyout-padding",
|
|
477
|
+
"category": "component",
|
|
478
|
+
"component": "esp-flyout",
|
|
479
|
+
"description": "Padding inside the panel's header and content regions. Defaults to `var(--esp-size-padding)`."
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
"name": "--esp-flyout-radius",
|
|
483
|
+
"category": "component",
|
|
484
|
+
"component": "esp-flyout",
|
|
485
|
+
"description": "The radius of the panel's trailing corners. Defaults to `var(--esp-size-border-radius)`; the overlay drawer squares them."
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
"name": "--esp-flyout-shadow",
|
|
489
|
+
"category": "component",
|
|
490
|
+
"component": "esp-flyout",
|
|
491
|
+
"description": "The panel's shadow. Defaults to `none` in the gutter/docked modes (the perforation does the separating) and to a drawer shadow in overlay mode."
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
"name": "--esp-flyout-z-index",
|
|
495
|
+
"category": "component",
|
|
496
|
+
"component": "esp-flyout",
|
|
497
|
+
"description": "Stack order of the overlay-drawer mode. Defaults to `3000` — above page chrome, below the dialog drop zone (4000). Set it on the `esp-page` (or an ancestor), not on the flyout itself: the page reads the same token to hoist the drawer's aside above its header."
|
|
498
|
+
},
|
|
463
499
|
{
|
|
464
500
|
"name": "--esp-font-body",
|
|
465
501
|
"category": "root-theme",
|
|
@@ -1267,12 +1303,24 @@
|
|
|
1267
1303
|
"component": "esp-page",
|
|
1268
1304
|
"description": "Offset reserved for fixed headers. Defaults to `var(--esp-header-height)`."
|
|
1269
1305
|
},
|
|
1306
|
+
{
|
|
1307
|
+
"name": "--esp-page-flyout-width",
|
|
1308
|
+
"category": "component",
|
|
1309
|
+
"component": "esp-page",
|
|
1310
|
+
"description": "The width of the open flyout track (and of the `esp-flyout` overlay drawer). Defaults to `20rem`."
|
|
1311
|
+
},
|
|
1270
1312
|
{
|
|
1271
1313
|
"name": "--esp-page-header-z-index",
|
|
1272
1314
|
"category": "component",
|
|
1273
1315
|
"component": "esp-page",
|
|
1274
1316
|
"description": "Z-index for fixed/sticky header regions. Defaults to `20`."
|
|
1275
1317
|
},
|
|
1318
|
+
{
|
|
1319
|
+
"name": "--esp-page-main-background",
|
|
1320
|
+
"category": "component",
|
|
1321
|
+
"component": "esp-page",
|
|
1322
|
+
"description": "The background of the main content well. Defaults to `transparent` (the well shows the page background). Set it to give the content well its own card color, or pair the transparent default with `--esp-page-surface-shadow: none` for content that floats directly on the page with no frame."
|
|
1323
|
+
},
|
|
1276
1324
|
{
|
|
1277
1325
|
"name": "--esp-page-max-width",
|
|
1278
1326
|
"category": "component",
|
|
@@ -1289,7 +1337,7 @@
|
|
|
1289
1337
|
"name": "--esp-page-surface-border",
|
|
1290
1338
|
"category": "component",
|
|
1291
1339
|
"component": "esp-page",
|
|
1292
|
-
"description": "An optional border on the inline edges of the surface, for themes preferring a hairline over a shadow. Defaults to `none` (e.g. `1px solid var(--esp-color-border)`)."
|
|
1340
|
+
"description": "An optional border on the inline edges of the surface, for themes preferring a hairline over a shadow. Defaults to `none` (e.g. `1px solid var(--esp-color-border)`). Combine with `--esp-page-surface-shadow: none` to switch the content frame from a drop shadow to a hairline, or turn both off for no frame."
|
|
1293
1341
|
},
|
|
1294
1342
|
{
|
|
1295
1343
|
"name": "--esp-page-surface-shadow",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/espalier",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Espalier — a themeable, accessible, framework-agnostic, enterprise-grade design system built on web standards and love.",
|
|
5
5
|
"customElements": "custom-elements.json",
|
|
6
6
|
"type": "module",
|