@taprootio/espalier 6.2.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +5 -5
  3. package/custom-elements.json +1498 -778
  4. package/dist/action-menu/esp-action-menu-item.js +1 -0
  5. package/dist/action-menu/esp-action-menu.js +4 -3
  6. package/dist/box/esp-box.d.ts +49 -3
  7. package/dist/box/esp-box.js +26 -11
  8. package/dist/button/esp-button.d.ts +4 -4
  9. package/dist/date-picker/helpers/styles.js +1 -0
  10. package/dist/details/esp-details.d.ts +3 -0
  11. package/dist/details/esp-details.js +13 -6
  12. package/dist/dialog/esp-dialog.d.ts +82 -2
  13. package/dist/dialog/esp-dialog.js +71 -59
  14. package/dist/flyout/esp-flyout.d.ts +2 -2
  15. package/dist/flyout/esp-flyout.js +6 -5
  16. package/dist/focus-picker/esp-focus-picker.js +3 -2
  17. package/dist/footer/esp-footer.d.ts +3 -3
  18. package/dist/footer/esp-footer.js +10 -10
  19. package/dist/grid/esp-grid.d.ts +3 -0
  20. package/dist/grid/esp-grid.js +25 -17
  21. package/dist/header/esp-header-button.d.ts +6 -15
  22. package/dist/header/esp-header.d.ts +4 -2
  23. package/dist/header/esp-header.js +8 -7
  24. package/dist/image-picker/esp-image-picker.js +1 -0
  25. package/dist/image-upload/esp-image-upload.js +1 -0
  26. package/dist/info/esp-info.d.ts +3 -1
  27. package/dist/info/esp-info.js +8 -8
  28. package/dist/lightbox/esp-lightbox.d.ts +3 -0
  29. package/dist/lightbox/esp-lightbox.js +12 -9
  30. package/dist/menu/esp-menu-group.js +6 -2
  31. package/dist/menu/esp-menu-item.js +7 -3
  32. package/dist/menu/esp-menu.js +4 -2
  33. package/dist/page/esp-page.d.ts +1 -1
  34. package/dist/page/esp-page.styles.js +1 -0
  35. package/dist/pickers/esp-pick-one.d.ts +1 -2
  36. package/dist/pickers/esp-pick-some.d.ts +1 -1
  37. package/dist/pickers/esp-picker-item.js +9 -5
  38. package/dist/pickers/esp-picker-menu.js +2 -0
  39. package/dist/popover/esp-popover.d.ts +2 -4
  40. package/dist/repeater/esp-repeater.js +1 -0
  41. package/dist/root/esp-root.d.ts +4 -4
  42. package/dist/root/esp-root.js +5 -3
  43. package/dist/row/esp-row.d.ts +1 -2
  44. package/dist/search/esp-search.js +2 -0
  45. package/dist/section/esp-section.d.ts +1 -1
  46. package/dist/section/esp-section.js +2 -1
  47. package/dist/shared/configured-brand.d.ts +11 -37
  48. package/dist/shared/esp-element-base.d.ts +4 -1
  49. package/dist/shared/esp-element-base.js +27 -30
  50. package/dist/shared/justified-layout.d.ts +6 -18
  51. package/dist/shared/surface-layer.d.ts +12 -0
  52. package/dist/shared/surface-layer.js +10 -0
  53. package/dist/shared/theme.d.ts +7 -18
  54. package/dist/slider/esp-slider.d.ts +2 -4
  55. package/dist/stack/esp-stack.d.ts +1 -2
  56. package/dist/switch/esp-switch.d.ts +2 -4
  57. package/dist/tabs/esp-tab-group.d.ts +3 -0
  58. package/dist/tabs/esp-tab-group.js +7 -7
  59. package/dist/tooltip/esp-tooltip.js +1 -0
  60. package/dist/tree/esp-tree.d.ts +0 -5
  61. package/dist/tree/esp-tree.js +3 -0
  62. package/espalier.css-data.json +17 -1
  63. package/espalier.token-manifest.json +25 -1
  64. package/licenses/README.md +18 -15
  65. package/package.json +5 -1
@@ -84,6 +84,7 @@ var s=function(r,i,t,n){var a=arguments.length,e=a<3?i:n===null?n=Object.getOwnP
84
84
 
85
85
  :host(:not([disabled]):hover) .item,
86
86
  :host(:not([disabled]):focus-visible) .item {
87
+ --_esp-surface-layer: 2;
87
88
  background: var(--esp-action-menu-item-hover-background, var(--esp-color-layer-2));
88
89
  }
89
90
 
@@ -1,4 +1,4 @@
1
- var l=function(d,e,t,s){var o=arguments.length,i=o<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,t):s,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(d,e,t,s);else for(var r=d.length-1;r>=0;r--)(a=d[r])&&(i=(o<3?a(i):o>3?a(e,t,i):a(e,t))||i);return o>3&&i&&Object.defineProperty(e,t,i),i};import{css as v,html as p}from"lit";import{customElement as I,property as u,state as g}from"lit/decorators.js";import{createRef as c,ref as h}from"lit/directives/ref.js";import"../button/esp-button.js";import"../popover/esp-popover.js";import{EspalierElementBase as f}from"../shared/esp-element-base.js";import{ESP_EVENTS as w}from"../shared/events.js";import"./esp-action-menu-item.js";const y=p` <svg
1
+ var l=function(c,e,t,s){var o=arguments.length,r=o<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,t):s,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(c,e,t,s);else for(var i=c.length-1;i>=0;i--)(a=c[i])&&(r=(o<3?a(r):o>3?a(e,t,r):a(e,t))||r);return o>3&&r&&Object.defineProperty(e,t,r),r};import{css as v,html as p}from"lit";import{customElement as I,property as u,state as g}from"lit/decorators.js";import{createRef as d,ref as h}from"lit/directives/ref.js";import"../button/esp-button.js";import"../popover/esp-popover.js";import{EspalierElementBase as f}from"../shared/esp-element-base.js";import{ESP_EVENTS as y}from"../shared/events.js";import"./esp-action-menu-item.js";const w=p` <svg
2
2
  xmlns="http://www.w3.org/2000/svg"
3
3
  viewBox="0 0 24 24"
4
4
  fill="currentColor"
@@ -7,7 +7,7 @@ var l=function(d,e,t,s){var o=arguments.length,i=o<3?e:s===null?s=Object.getOwnP
7
7
  <circle cx="5" cy="12" r="2" />
8
8
  <circle cx="12" cy="12" r="2" />
9
9
  <circle cx="19" cy="12" r="2" />
10
- </svg>`;let n=class extends f{constructor(){super(...arguments),this.popoverRef=c(),this.itemsSlot=c(),this.triggerSlot=c(),this.triggerShell=c(),this.handledTriggerEvents=new WeakSet,this.wiredTriggerControls=new WeakSet,this.open=!1,this.focusedIndex=-1,this.placement="bottom-end",this.disabled=!1,this.iconPosition="left",this.handleTriggerSlotChange=()=>{this.syncTriggerAttributes()},this.syncItems=()=>{const e=this.items,t=this.enabledItems;for(const s of e)s.inheritIconPosition(this.iconPosition),s.setAttribute("role","menuitem"),s.tabIndex=t[0]===s&&this.focusedIndex<0?0:-1,s.setAttribute("aria-disabled",String(s.disabled));if(this.focusedIndex>=0){const s=t[this.focusedIndex];for(const o of t)o.tabIndex=o===s?0:-1}},this.handleTriggerClick=e=>{this.handledTriggerEvents.has(e)||(this.handledTriggerEvents.add(e),this.toggleMenu(e))},this.toggleMenu=e=>{e.preventDefault(),!this.disabled&&(this.open?this.closeMenu({restoreFocus:!0}):this.openMenu())},this.handleTriggerKeydown=async e=>{if(!this.disabled)switch(e.key){case"Enter":case" ":e.preventDefault(),e.stopPropagation(),this.openMenu(),await this.updateComplete,this.focusFirstItem();break;case"ArrowDown":e.preventDefault(),e.stopPropagation(),this.openMenu(),await this.updateComplete,this.focusFirstItem();break;case"ArrowUp":e.preventDefault(),e.stopPropagation(),this.openMenu(),await this.updateComplete,this.focusLastItem();break}},this.handleMenuKeydown=e=>{if(this.open)switch(e.key){case"ArrowDown":e.preventDefault(),this.focusNextItem(1);break;case"ArrowUp":e.preventDefault(),this.focusNextItem(-1);break;case"Home":e.preventDefault(),this.focusFirstItem();break;case"End":e.preventDefault(),this.focusLastItem();break;case"Enter":case" ":e.preventDefault(),this.activeItemForEvent(e)?.activate();break;case"Escape":e.preventDefault(),this.closeMenu({restoreFocus:!0});break}},this.handleItemActivate=e=>{const{item:t}=e.detail;this.selectItem(t)},this.handlePopoverOpened=()=>{this.open=!0,this.syncItems()},this.handlePopoverClosed=()=>{this.open=!1,this.focusedIndex=-1,this.syncItems()}}connectedCallback(){super.connectedCallback(),this.addEventListener("esp-internal-action-menu-item-activate",this.handleItemActivate),this.addEventListener("keydown",this.handleMenuKeydown)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("esp-internal-action-menu-item-activate",this.handleItemActivate),this.removeEventListener("keydown",this.handleMenuKeydown)}firstUpdated(e){super.firstUpdated(e),this.syncTriggerAttributes(),this.syncItems()}updated(e){super.updated(e),(e.has("open")||e.has("disabled"))&&this.syncTriggerAttributes(),e.has("iconPosition")&&this.syncItems()}openMenu(){this.disabled||this.open||(this.popoverRef.value?.openPopover(),this.open=!0)}closeMenu(e={}){this.open&&(this.popoverRef.value?.closePopover(),this.open=!1,this.focusedIndex=-1,this.syncItems(),e.restoreFocus&&this.focusTrigger())}get placementParts(){const[e,t]=this.placement.split("-"),s=t==="start"||t==="end"?t:"center";switch(e){case"top":return{attach:"above",align:s};case"right":return{attach:"right",align:s};case"left":return{attach:"left",align:s};case"bottom":default:return{attach:"below",align:s}}}get items(){return Array.from(this.querySelectorAll("esp-action-menu-item"))}get enabledItems(){return this.items.filter(e=>!e.disabled)}get defaultTrigger(){return this.shadowRoot?.querySelector(".default-trigger")}get slottedTrigger(){return this.triggerSlot.value?.assignedElements({flatten:!0})[0]}getTriggerControl(e){return e?.shadowRoot?.querySelector("button, a, [tabindex]")??null}wireTriggerControl(e){!e||this.wiredTriggerControls.has(e)||(e.addEventListener("click",this.handleTriggerClick),this.wiredTriggerControls.add(e))}syncTriggerAttributes(){const e={"aria-haspopup":"menu","aria-expanded":String(this.open),"aria-disabled":String(this.disabled)},t=r=>{if(r){for(const[m,b]of Object.entries(e))r.setAttribute(m,b);"disabled"in r&&(r.disabled=this.disabled)}};t(this.triggerShell.value);const s=this.slottedTrigger;t(s);const o=this.getTriggerControl(s);t(o),this.wireTriggerControl(o);const i=this.defaultTrigger;i?.setAttribute("aria-label","Actions"),t(i);const a=this.getTriggerControl(i);t(a),this.wireTriggerControl(a),i&&i.updateComplete.then(()=>{const r=this.getTriggerControl(i);t(r),r?.setAttribute("aria-label","Actions"),this.wireTriggerControl(r)}),s&&"updateComplete"in s&&s.updateComplete.then(()=>{const r=this.getTriggerControl(s);t(r),this.wireTriggerControl(r)})}activeItemForEvent(e){const t=this.enabledItems;return t[this.focusedIndex]??t.find(s=>e.composedPath().includes(s))??t.find(s=>s.matches(":focus"))}selectItem(e){e.disabled||(this.dispatchEvent(new CustomEvent(w.ACTION_MENU_SELECT,{detail:{value:e.value,item:e},bubbles:!0,composed:!0})),this.closeMenu({restoreFocus:!0}))}focusFirstItem(){this.focusItem(0)}focusLastItem(){this.focusItem(this.enabledItems.length-1)}focusNextItem(e){const t=this.enabledItems;if(t.length===0)return;const o=((this.focusedIndex<0?0:this.focusedIndex)+e+t.length)%t.length;this.focusItem(o)}focusItem(e){const t=this.enabledItems;e<0||e>=t.length||(this.focusedIndex=e,this.syncItems(),t[e].focus())}focusTrigger(){const e=this.slottedTrigger;if(e){(this.getTriggerControl(e)??e).focus();return}const t=this.defaultTrigger;(this.getTriggerControl(t)??t??this.triggerShell.value)?.focus()}render(){const{attach:e,align:t}=this.placementParts;return p`
10
+ </svg>`;let n=class extends f{constructor(){super(...arguments),this.popoverRef=d(),this.itemsSlot=d(),this.triggerSlot=d(),this.triggerShell=d(),this.handledTriggerEvents=new WeakSet,this.wiredTriggerControls=new WeakSet,this.open=!1,this.focusedIndex=-1,this.placement="bottom-end",this.disabled=!1,this.iconPosition="left",this.handleTriggerSlotChange=()=>{this.syncTriggerAttributes()},this.syncItems=()=>{const e=this.items,t=this.enabledItems;for(const s of e)s.inheritIconPosition(this.iconPosition),s.setAttribute("role","menuitem"),s.tabIndex=t[0]===s&&this.focusedIndex<0?0:-1,s.setAttribute("aria-disabled",String(s.disabled));if(this.focusedIndex>=0){const s=t[this.focusedIndex];for(const o of t)o.tabIndex=o===s?0:-1}},this.handleTriggerClick=e=>{this.handledTriggerEvents.has(e)||(this.handledTriggerEvents.add(e),this.toggleMenu(e))},this.toggleMenu=e=>{e.preventDefault(),!this.disabled&&(this.open?this.closeMenu({restoreFocus:!0}):this.openMenu())},this.handleTriggerKeydown=async e=>{if(!this.disabled)switch(e.key){case"Enter":case" ":e.preventDefault(),e.stopPropagation(),this.openMenu(),await this.updateComplete,this.focusFirstItem();break;case"ArrowDown":e.preventDefault(),e.stopPropagation(),this.openMenu(),await this.updateComplete,this.focusFirstItem();break;case"ArrowUp":e.preventDefault(),e.stopPropagation(),this.openMenu(),await this.updateComplete,this.focusLastItem();break}},this.handleMenuKeydown=e=>{if(this.open)switch(e.key){case"ArrowDown":e.preventDefault(),this.focusNextItem(1);break;case"ArrowUp":e.preventDefault(),this.focusNextItem(-1);break;case"Home":e.preventDefault(),this.focusFirstItem();break;case"End":e.preventDefault(),this.focusLastItem();break;case"Enter":case" ":e.preventDefault(),this.activeItemForEvent(e)?.activate();break;case"Escape":e.preventDefault(),this.closeMenu({restoreFocus:!0});break}},this.handleItemActivate=e=>{const{item:t}=e.detail;this.selectItem(t)},this.handlePopoverOpened=()=>{this.open=!0,this.syncItems()},this.handlePopoverClosed=()=>{this.open=!1,this.focusedIndex=-1,this.syncItems()}}connectedCallback(){super.connectedCallback(),this.addEventListener("esp-internal-action-menu-item-activate",this.handleItemActivate),this.addEventListener("keydown",this.handleMenuKeydown)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("esp-internal-action-menu-item-activate",this.handleItemActivate),this.removeEventListener("keydown",this.handleMenuKeydown)}firstUpdated(e){super.firstUpdated(e),this.syncTriggerAttributes(),this.syncItems()}updated(e){super.updated(e),(e.has("open")||e.has("disabled"))&&this.syncTriggerAttributes(),e.has("iconPosition")&&this.syncItems()}openMenu(){this.disabled||this.open||(this.popoverRef.value?.openPopover(),this.open=!0)}closeMenu(e={}){this.open&&(this.popoverRef.value?.closePopover(),this.open=!1,this.focusedIndex=-1,this.syncItems(),e.restoreFocus&&this.focusTrigger())}get placementParts(){const[e,t]=this.placement.split("-"),s=t==="start"||t==="end"?t:"center";switch(e){case"top":return{attach:"above",align:s};case"right":return{attach:"right",align:s};case"left":return{attach:"left",align:s};case"bottom":default:return{attach:"below",align:s}}}get items(){return Array.from(this.querySelectorAll("esp-action-menu-item"))}get enabledItems(){return this.items.filter(e=>!e.disabled)}get defaultTrigger(){return this.shadowRoot?.querySelector(".default-trigger")}get slottedTrigger(){return this.triggerSlot.value?.assignedElements({flatten:!0})[0]}getTriggerControl(e){return e?.shadowRoot?.querySelector("button, a, [tabindex]")??null}wireTriggerControl(e){!e||this.wiredTriggerControls.has(e)||(e.addEventListener("click",this.handleTriggerClick),this.wiredTriggerControls.add(e))}syncTriggerAttributes(){const e={"aria-haspopup":"menu","aria-expanded":String(this.open),"aria-disabled":String(this.disabled)},t=i=>{if(i){for(const[m,b]of Object.entries(e))i.setAttribute(m,b);"disabled"in i&&(i.disabled=this.disabled)}};t(this.triggerShell.value);const s=this.slottedTrigger;t(s);const o=this.getTriggerControl(s);t(o),this.wireTriggerControl(o);const r=this.defaultTrigger;r?.setAttribute("aria-label","Actions"),t(r);const a=this.getTriggerControl(r);t(a),this.wireTriggerControl(a),r&&r.updateComplete.then(()=>{const i=this.getTriggerControl(r);t(i),i?.setAttribute("aria-label","Actions"),this.wireTriggerControl(i)}),s&&"updateComplete"in s&&s.updateComplete.then(()=>{const i=this.getTriggerControl(s);t(i),this.wireTriggerControl(i)})}activeItemForEvent(e){const t=this.enabledItems;return t[this.focusedIndex]??t.find(s=>e.composedPath().includes(s))??t.find(s=>s.matches(":focus"))}selectItem(e){e.disabled||(this.dispatchEvent(new CustomEvent(y.ACTION_MENU_SELECT,{detail:{value:e.value,item:e},bubbles:!0,composed:!0})),this.closeMenu({restoreFocus:!0}))}focusFirstItem(){this.focusItem(0)}focusLastItem(){this.focusItem(this.enabledItems.length-1)}focusNextItem(e){const t=this.enabledItems;if(t.length===0)return;const o=((this.focusedIndex<0?0:this.focusedIndex)+e+t.length)%t.length;this.focusItem(o)}focusItem(e){const t=this.enabledItems;e<0||e>=t.length||(this.focusedIndex=e,this.syncItems(),t[e].focus())}focusTrigger(){const e=this.slottedTrigger;if(e){(this.getTriggerControl(e)??e).focus();return}const t=this.defaultTrigger;(this.getTriggerControl(t)??t??this.triggerShell.value)?.focus()}render(){const{attach:e,align:t}=this.placementParts;return p`
11
11
  <esp-popover
12
12
  ${h(this.popoverRef)}
13
13
  .trigger=${"none"}
@@ -33,7 +33,7 @@ var l=function(d,e,t,s){var o=arguments.length,i=o<3?e:s===null?s=Object.getOwnP
33
33
  .disabled=${this.disabled}
34
34
  label="Actions"
35
35
  >
36
- ${y}
36
+ ${w}
37
37
  </esp-button>
38
38
  </slot>
39
39
  </span>
@@ -58,6 +58,7 @@ var l=function(d,e,t,s){var o=arguments.length,i=o<3?e:s===null?s=Object.getOwnP
58
58
  }
59
59
 
60
60
  .menu {
61
+ --_esp-surface-layer: 1;
61
62
  display: grid;
62
63
  min-width: var(--esp-action-menu-min-width, 12rem);
63
64
  padding: 0;
@@ -1,8 +1,10 @@
1
1
  import { EspalierElementBase } from "../shared/esp-element-base.js";
2
2
  /**
3
- * Used as a base to group context visually. `esp-box`
4
- * has a css part of `box` that can be styled to create cards,
5
- * forms, and other UI elements.
3
+ * Groups related content in a themed container. Style its `box` CSS part
4
+ * to create cards, forms, or other grouped regions.
5
+ *
6
+ * A field fills one layer above the surface it sits on.
7
+ * Use `surface-layer="1|2|3|4"` to select the default painted layer.
6
8
  *
7
9
  * ```html
8
10
  * <esp-box>
@@ -20,6 +22,15 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
20
22
  * panels, and form surfaces — and replace any pre-3.2 "neutralized box"
21
23
  * band with a bare section.
22
24
  *
25
+ * Select a raised form surface with `surface-layer`; fields follow it automatically.
26
+ *
27
+ * ```html
28
+ * <esp-box surface-layer="2">
29
+ * <esp-input placeholder="Search"></esp-input>
30
+ * <esp-input readonly value="A read-only value"></esp-input>
31
+ * </esp-box>
32
+ * ```
33
+ *
23
34
  * @customElement esp-box
24
35
  * @slot - The default slot holds elements to display in the box.
25
36
  *
@@ -125,6 +136,41 @@ export declare class EspalierBox extends EspalierElementBase {
125
136
  * </script>
126
137
  * ```
127
138
  *
139
+ * A full-screen box fills the viewport. Inside a
140
+ * [bounded dialog](/components/dialog) it fills exactly the dialog's
141
+ * rectangle instead: it takes its position and size from the same
142
+ * `--esp-dialog-inset-*` custom properties, set on the `esp-dialog` or any
143
+ * ancestor of the box.
144
+ *
145
+ * ```html
146
+ * <style>
147
+ * esp-dialog.bounded-box {
148
+ * --esp-dialog-inset-block-start: 6rem;
149
+ * --esp-dialog-inset-inline-start: 3rem;
150
+ * --esp-dialog-inset-inline-end: 3rem;
151
+ * --esp-dialog-inset-block-end: 2rem;
152
+ * }
153
+ * </style>
154
+ * <esp-dialog class="bounded-box" full-screen>
155
+ * <esp-box full-screen>
156
+ * <h2>Box in a bounded dialog</h2>
157
+ * <p>This box fills the rectangle the dialog is bounded to.</p>
158
+ * <esp-button intent="danger" label="Close"></esp-button>
159
+ * </esp-box>
160
+ * </esp-dialog>
161
+ * <esp-button label="Show Dialog"></esp-button>
162
+ * <script>
163
+ * const theDialog = findByTagName("esp-dialog")[0];
164
+ * const buttons = findByTagName("esp-button");
165
+ * buttons[0].addEventListener("esp-clicked", () => {
166
+ * theDialog.toggleOpen();
167
+ * });
168
+ * buttons[1].addEventListener("esp-clicked", () => {
169
+ * theDialog.toggleOpen();
170
+ * });
171
+ * </script>
172
+ * ```
173
+ *
128
174
  * @type {boolean}
129
175
  */
130
176
  fullScreen: boolean;
@@ -1,16 +1,16 @@
1
- var n=function(t,e,r,i){var a=arguments.length,o=a<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,r):i,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(t,e,r,i);else for(var p=t.length-1;p>=0;p--)(l=t[p])&&(o=(a<3?l(o):a>3?l(e,r,o):l(e,r))||o);return a>3&&o&&Object.defineProperty(e,r,o),o};import{css as c,html as v}from"lit";import{customElement as b,property as h}from"lit/decorators.js";import{classMap as f}from"lit/directives/class-map.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";let s=class extends d{constructor(){super(...arguments),this.fullScreen=!1}render(){const{fullScreen:e}=this;return v`
2
- <div class=${f({"esp-box":!0,"full-screen":e})}>
1
+ var p=function(r,e,s,i){var a=arguments.length,o=a<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,s):i,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(r,e,s,i);else for(var n=r.length-1;n>=0;n--)(l=r[n])&&(o=(a<3?l(o):a>3?l(e,s,o):l(e,s))||o);return a>3&&o&&Object.defineProperty(e,s,o),o};import{paintedSurface as c}from"../shared/surface-layer.js";import{css as v,html as b}from"lit";import{customElement as f,property as h}from"lit/decorators.js";import{classMap as u}from"lit/directives/class-map.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";let t=class extends d{constructor(){super(...arguments),this.fullScreen=!1}render(){const{fullScreen:e}=this;return b`
2
+ <div class=${u({"esp-box":!0,"full-screen":e})}>
3
3
  <div part="box">
4
4
  <slot></slot>
5
5
  </div>
6
6
  </div>
7
- `}};s.styles=[...d.styles,c`
7
+ `}};t.styles=[...d.styles,c(1),v`
8
8
  :host {
9
9
  display: block;
10
10
  }
11
11
 
12
12
  .esp-box {
13
- background-color: var(--esp-color-box-background, var(--esp-color-layer-1));
13
+ background-color: var(--esp-color-box-background, var(--_esp-surface-background));
14
14
  border-radius: var(--esp-size-border-radius);
15
15
  box-shadow: var(--esp-box-shadow, var(--esp-shadow-1, 1px 1px 4px var(--esp-color-shadow)));
16
16
  overflow: visible;
@@ -42,16 +42,31 @@ var n=function(t,e,r,i){var a=arguments.length,o=a<3?e:i===null?i=Object.getOwnP
42
42
  }
43
43
 
44
44
  &.full-screen {
45
- width: 100vw;
46
-
47
- height: 100vh;
48
- height: 100dvh;
45
+ width: calc(
46
+ 100vw - var(--esp-dialog-inset-inline-start, 0px) - var(
47
+ --esp-dialog-inset-inline-end,
48
+ 0px
49
+ )
50
+ );
51
+ height: calc(
52
+ 100vh - var(--esp-dialog-inset-block-start, 0px) - var(
53
+ --esp-dialog-inset-block-end,
54
+ 0px
55
+ )
56
+ );
57
+ height: calc(
58
+ 100dvh - var(--esp-dialog-inset-block-start, 0px) - var(
59
+ --esp-dialog-inset-block-end,
60
+ 0px
61
+ )
62
+ );
49
63
  position: fixed;
50
- top: 0;
51
- left: 0;
64
+ inset-block-start: var(--esp-dialog-inset-block-start, 0px);
65
+ inset-inline-start: var(--esp-dialog-inset-inline-start, 0px);
52
66
  z-index: 10;
53
67
 
54
68
  > div {
69
+ position: relative;
55
70
  overflow-y: auto;
56
71
 
57
72
  padding-bottom: max(
@@ -61,4 +76,4 @@ var n=function(t,e,r,i){var a=arguments.length,o=a<3?e:i===null?i=Object.getOwnP
61
76
  }
62
77
  }
63
78
  }
64
- `],n([h({attribute:"full-screen",type:Boolean})],s.prototype,"fullScreen",void 0),s=n([b("esp-box")],s);export{s as EspalierBox};
79
+ `],p([h({attribute:"full-screen",type:Boolean})],t.prototype,"fullScreen",void 0),t=p([f("esp-box")],t);export{t as EspalierBox};
@@ -2,7 +2,7 @@ import { type TemplateResult } from "lit";
2
2
  import { EspalierElementBase } from "../shared/esp-element-base.js";
3
3
  export type ButtonIconPosition = "left" | "right";
4
4
  /**
5
- * Used to initiate a user action or link to another page.
5
+ * Triggers an action or links to another page.
6
6
  *
7
7
  * ```html
8
8
  * <esp-button label="Hello there!"></esp-button>
@@ -18,7 +18,7 @@ export type ButtonIconPosition = "left" | "right";
18
18
  * </script>
19
19
  * ```
20
20
  *
21
- * Here is each of the button intents:
21
+ * Choose an intent to express the action's status:
22
22
  *
23
23
  * ```html
24
24
  * <div style="display: flex; flex-wrap: wrap; gap: var(--esp-size-padding);">
@@ -145,7 +145,7 @@ export declare class EspalierButton extends EspalierElementBase {
145
145
  */
146
146
  collapsed: boolean;
147
147
  /**
148
- * Controls whether or not the button is disabled.
148
+ * Disables the button.
149
149
  *
150
150
  * ```html
151
151
  * <esp-button disabled label="Disabled"></esp-button>
@@ -225,7 +225,7 @@ export declare class EspalierButton extends EspalierElementBase {
225
225
  */
226
226
  label: string;
227
227
  /**
228
- * Controls whether or not the button is in a loading state.
228
+ * Shows the button's loading state.
229
229
  * The button will be disabled and show a spinner while loading
230
230
  * is true.
231
231
  *
@@ -39,6 +39,7 @@ import{css as e}from"lit";const t=e`
39
39
 
40
40
 
41
41
  .picker-popover {
42
+ --_esp-surface-layer: 1;
42
43
  position: fixed;
43
44
  inset: unset;
44
45
  margin: 0;
@@ -6,6 +6,9 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
6
6
  * [esp-details-group](/components/details/group) to create an
7
7
  * accordion where only one item is open at a time.
8
8
  *
9
+ * A field fills one layer above the surface it sits on.
10
+ * Use `surface-layer="1|2|3|4"` to select the default painted layer.
11
+ *
9
12
  * ```html
10
13
  * <esp-details summary="What is Espalier?">
11
14
  * <p>Espalier is a design system and component library
@@ -1,4 +1,4 @@
1
- var d=function(i,e,o,s){var t=arguments.length,r=t<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,o):s,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(i,e,o,s);else for(var l=i.length-1;l>=0;l--)(n=i[l])&&(r=(t<3?n(r):t>3?n(e,o,r):n(e,o))||r);return t>3&&r&&Object.defineProperty(e,o,r),r};import{css as h,html as f}from"lit";import{customElement as b,property as p}from"lit/decorators.js";import{EspalierElementBase as m}from"../shared/esp-element-base.js";import{ESP_EVENTS as u}from"../shared/events.js";import{disabledControl as v}from"../shared/style-fragments.js";let a=class extends m{constructor(){super(...arguments),this.summary="",this.open=!1,this.disabled=!1,this._toggleFromClick=!1}close(){this.open=!1}getScrollParent(){let e=this.assignedSlot?.parentElement??(this.parentNode instanceof ShadowRoot?this.parentNode.host:this.parentElement);for(;e&&e!==document.documentElement;){const s=getComputedStyle(e).overflowY;if((s==="auto"||s==="scroll")&&e.scrollHeight>e.clientHeight)return e;e=e.assignedSlot?.parentElement??(e.parentNode instanceof ShadowRoot?e.parentNode.host:e.parentElement)}return null}handleToggle(e){const o=e.target;if(this.disabled){o.open=this.open;return}if(this._toggleFromClick){this._toggleFromClick=!1;return}this.open=o.open,this.dispatchEvent(new CustomEvent(u.DETAILS_TOGGLE,{detail:{open:this.open},bubbles:!0,composed:!0}))}handleSummaryClick(e){if(e.preventDefault(),this.disabled)return;const o=e.currentTarget,s=o.getBoundingClientRect().top,t=this.getScrollParent(),r=t?t.scrollTop:window.scrollY;this._toggleFromClick=!0,this.open=!this.open,this.updateComplete.then(()=>{this._toggleFromClick=!1,this.dispatchEvent(new CustomEvent(u.DETAILS_TOGGLE,{detail:{open:this.open},bubbles:!0,composed:!0}));const l=o.getBoundingClientRect().top-s;if(Math.abs(l)>1)if(t){const c=t.scrollTop;Math.abs(c-r)>1&&(t.scrollTop=r)}else{const c=window.scrollY;Math.abs(c-r)>1&&window.scrollBy(0,l)}})}render(){return f`
1
+ var d=function(i,e,o,s){var t=arguments.length,r=t<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,o):s,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(i,e,o,s);else for(var l=i.length-1;l>=0;l--)(n=i[l])&&(r=(t<3?n(r):t>3?n(e,o,r):n(e,o))||r);return t>3&&r&&Object.defineProperty(e,o,r),r};import{paintedSurface as h}from"../shared/surface-layer.js";import{css as f,html as b}from"lit";import{customElement as v,property as p}from"lit/decorators.js";import{EspalierElementBase as m}from"../shared/esp-element-base.js";import{ESP_EVENTS as u}from"../shared/events.js";import{disabledControl as g}from"../shared/style-fragments.js";let a=class extends m{constructor(){super(...arguments),this.summary="",this.open=!1,this.disabled=!1,this._toggleFromClick=!1}close(){this.open=!1}getScrollParent(){let e=this.assignedSlot?.parentElement??(this.parentNode instanceof ShadowRoot?this.parentNode.host:this.parentElement);for(;e&&e!==document.documentElement;){const s=getComputedStyle(e).overflowY;if((s==="auto"||s==="scroll")&&e.scrollHeight>e.clientHeight)return e;e=e.assignedSlot?.parentElement??(e.parentNode instanceof ShadowRoot?e.parentNode.host:e.parentElement)}return null}handleToggle(e){const o=e.target;if(this.disabled){o.open=this.open;return}if(this._toggleFromClick){this._toggleFromClick=!1;return}this.open=o.open,this.dispatchEvent(new CustomEvent(u.DETAILS_TOGGLE,{detail:{open:this.open},bubbles:!0,composed:!0}))}handleSummaryClick(e){if(e.preventDefault(),this.disabled)return;const o=e.currentTarget,s=o.getBoundingClientRect().top,t=this.getScrollParent(),r=t?t.scrollTop:window.scrollY;this._toggleFromClick=!0,this.open=!this.open,this.updateComplete.then(()=>{this._toggleFromClick=!1,this.dispatchEvent(new CustomEvent(u.DETAILS_TOGGLE,{detail:{open:this.open},bubbles:!0,composed:!0}));const l=o.getBoundingClientRect().top-s;if(Math.abs(l)>1)if(t){const c=t.scrollTop;Math.abs(c-r)>1&&(t.scrollTop=r)}else{const c=window.scrollY;Math.abs(c-r)>1&&window.scrollBy(0,l)}})}render(){return b`
2
2
  <details ?open=${this.open} @toggle=${this.handleToggle}>
3
3
  <summary @click=${this.handleSummaryClick}>
4
4
  <span class="indicator"></span>
@@ -8,7 +8,7 @@ var d=function(i,e,o,s){var t=arguments.length,r=t<3?e:s===null?s=Object.getOwnP
8
8
  <slot></slot>
9
9
  </div>
10
10
  </details>
11
- `}};a.styles=[...m.styles,v(":host([disabled]) summary"),h`
11
+ `}};a.styles=[...m.styles,h(1),g(":host([disabled]) summary"),f`
12
12
  :host {
13
13
  display: block;
14
14
 
@@ -28,7 +28,7 @@ var d=function(i,e,o,s){var t=arguments.length,r=t<3?e:s===null?s=Object.getOwnP
28
28
  }
29
29
 
30
30
  details {
31
- background-color: var(--esp-details-color-background, var(--esp-color-layer-1));
31
+ background-color: var(--esp-details-color-background, var(--_esp-surface-background));
32
32
  border-radius: var(--esp-size-border-radius);
33
33
  box-shadow: 1px 1px 4px var(--esp-color-shadow);
34
34
  border: 1px solid var(--esp-details-color-border, var(--esp-color-border));
@@ -50,7 +50,10 @@ var d=function(i,e,o,s){var t=arguments.length,r=t<3?e:s===null?s=Object.getOwnP
50
50
  font-size: var(--esp-size-font);
51
51
  font-weight: 600;
52
52
  color: var(--esp-color-headings);
53
- background-color: var(--esp-details-color-summary-background, var(--esp-color-layer-1));
53
+ background-color: var(
54
+ --esp-details-color-summary-background,
55
+ var(--_esp-surface-background)
56
+ );
54
57
  transition: background-color cubic-bezier(0.075, 0.82, 0.165, 1) 0.5s;
55
58
  }
56
59
 
@@ -67,6 +70,7 @@ var d=function(i,e,o,s){var t=arguments.length,r=t<3?e:s===null?s=Object.getOwnP
67
70
  }
68
71
 
69
72
  details[open] > summary {
73
+ --_esp-surface-layer: 2;
70
74
  background-color: var(
71
75
  --esp-details-color-summary-background-active,
72
76
  var(--esp-color-layer-2)
@@ -108,7 +112,10 @@ var d=function(i,e,o,s){var t=arguments.length,r=t<3?e:s===null?s=Object.getOwnP
108
112
  }
109
113
 
110
114
  :host([disabled]) summary:hover {
111
- background-color: var(--esp-details-color-summary-background, var(--esp-color-layer-1));
115
+ background-color: var(
116
+ --esp-details-color-summary-background,
117
+ var(--_esp-surface-background)
118
+ );
112
119
  }
113
120
 
114
121
 
@@ -125,4 +132,4 @@ var d=function(i,e,o,s){var t=arguments.length,r=t<3?e:s===null?s=Object.getOwnP
125
132
  :host([in-group]:last-of-type) details {
126
133
  border-bottom: none;
127
134
  }
128
- `],d([p({type:String})],a.prototype,"summary",void 0),d([p({type:Boolean,reflect:!0})],a.prototype,"open",void 0),d([p({type:Boolean,reflect:!0})],a.prototype,"disabled",void 0),a=d([b("esp-details")],a);export{a as EspalierDetails};
135
+ `],d([p({type:String})],a.prototype,"summary",void 0),d([p({type:Boolean,reflect:!0})],a.prototype,"open",void 0),d([p({type:Boolean,reflect:!0})],a.prototype,"disabled",void 0),a=d([v("esp-details")],a);export{a as EspalierDetails};
@@ -1,10 +1,13 @@
1
1
  import { LitElement } from "lit";
2
2
  /**
3
- * Used to focus content modally. By default, on large screens the
3
+ * Shows content in a modal dialog. By default, on large screens the
4
4
  * dialog content is centered horizontally near the top of the
5
5
  * screen. On small screens, the content always tries to take up
6
6
  * the full screen width.
7
7
  *
8
+ * A field fills one layer above the surface it sits on.
9
+ * Use `surface-layer="1|2|3|4"` to select the default painted layer.
10
+ *
8
11
  * When opened, the dialog:
9
12
  * - Moves focus to the first `[autofocus]` element inside the slotted
10
13
  * content, then the first focusable element (or the dialog container
@@ -17,6 +20,78 @@ import { LitElement } from "lit";
17
20
  * - Restores focus to the element that was focused before the
18
21
  * dialog was opened.
19
22
  *
23
+ * ### Bounded dialog
24
+ *
25
+ * A dialog covers the whole viewport by default. Set the four inset custom
26
+ * properties on the `esp-dialog` host to confine it to a rectangle and leave
27
+ * the rest of the page visible, for example to keep a header or a live preview
28
+ * on screen while a full-screen editor is open. The vellum (the dialog's
29
+ * scrolling surface) and its backdrop paint only inside the rectangle, and a
30
+ * slotted `esp-box full-screen` fills exactly that rectangle.
31
+ *
32
+ * The insets are lengths (`0px`, `4rem`, `var(--header-height)`), not unitless
33
+ * numbers, and they are measured from the viewport edges. They are logical, so
34
+ * "inline start" is the left edge in left-to-right text and the right edge in
35
+ * right-to-left text. Because custom properties inherit, a dialog nested inside
36
+ * a bounded dialog's markup is bounded the same way unless it sets its own
37
+ * insets.
38
+ *
39
+ * Bounds change only where the dialog paints. What stays reachable is decided
40
+ * by the same rules as an unbounded dialog:
41
+ *
42
+ * - The dialog has no click-outside dismissal, bounded or not. It closes on
43
+ * `Escape`, an `esp-form-dialog-close-requested` event, or `toggleOpen()`, so
44
+ * a click on the uncovered region never counts as an "outside" click.
45
+ * - The dialog marks `inert` the siblings of its anchor element, not the
46
+ * regions its bounds leave uncovered. The anchor is `esp-page`'s dialog drop
47
+ * zone when the dialog sits in the page's markup, so there the page's
48
+ * internal tracks (header, menus, preview, help, footer) are inert and not
49
+ * clickable even where the dialog does not cover them. A dialog that is a
50
+ * direct child of another component's shadow root is anchored on the nearest
51
+ * ancestor host that has a light-DOM parent, and only that host's siblings
52
+ * go inert; the page around it stays live. A dialog wrapped in an element
53
+ * inside that shadow root is anchored on itself, so its siblings in the
54
+ * wrapper go inert instead.
55
+ * - A region that is not inert receives clicks and keyboard focus. The focus
56
+ * trap wraps `Tab` and `Shift+Tab` at the dialog's first and last focusable
57
+ * elements, and `Escape` is handled on the dialog, both only while focus is
58
+ * inside it. A click on an uncovered control moves focus there, and from then
59
+ * on `Tab` continues through the page and `Escape` no longer closes the
60
+ * dialog. Set `inert` on the uncovered regions that must not be reachable
61
+ * while the dialog is open (an inert region is also skipped by screen
62
+ * readers).
63
+ * - Bounds assume a horizontal writing mode: the insets are logical, but the
64
+ * dialog's width and height are physical.
65
+ *
66
+ * ```html
67
+ * <style>
68
+ * esp-dialog.bounded {
69
+ * --esp-dialog-inset-block-start: 6rem;
70
+ * --esp-dialog-inset-inline-start: 3rem;
71
+ * --esp-dialog-inset-inline-end: 3rem;
72
+ * --esp-dialog-inset-block-end: 2rem;
73
+ * }
74
+ * </style>
75
+ * <esp-dialog class="bounded" full-screen>
76
+ * <esp-box full-screen>
77
+ * <h2>Bounded dialog</h2>
78
+ * <p>The page above and around this box stays visible.</p>
79
+ * <esp-button intent="danger" label="Close"></esp-button>
80
+ * </esp-box>
81
+ * </esp-dialog>
82
+ * <esp-button label="Show Dialog"></esp-button>
83
+ * <script>
84
+ * const theDialog = findByTagName("esp-dialog")[0];
85
+ * const buttons = findByTagName("esp-button");
86
+ * buttons[0].addEventListener("esp-clicked", () => {
87
+ * theDialog.toggleOpen();
88
+ * });
89
+ * buttons[1].addEventListener("esp-clicked", () => {
90
+ * theDialog.toggleOpen();
91
+ * });
92
+ * </script>
93
+ * ```
94
+ *
20
95
  * @slot - Place content to show modally in the default slot.
21
96
  *
22
97
  * ```html
@@ -102,6 +177,11 @@ import { LitElement } from "lit";
102
177
  *
103
178
  * @cssprop --esp-color-dialog-bg - The background color of the dialog overlay.
104
179
  * @cssprop --esp-dialog-bg-opacity - The opacity of the dialog overlay background.
180
+ * @cssprop --esp-dialog-inset-block-start - The top edge of the area the dialog covers, as a length from the viewport top. Defaults to `0px`.
181
+ * @cssprop --esp-dialog-inset-inline-start - The leading edge (left in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`.
182
+ * @cssprop --esp-dialog-inset-inline-end - The trailing edge (right in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`.
183
+ * @cssprop --esp-dialog-inset-block-end - The bottom edge of the area the dialog covers, as a length from the viewport bottom. Defaults to `0px`.
184
+ * @attr {"1"|"2"|"3"|"4"} surface-layer - Declares the painted surface depth; defaults to layer 3.
105
185
  * @customElement esp-dialog
106
186
  * @docPageTitle Dialog
107
187
  * @docUrl /components/dialog
@@ -155,7 +235,7 @@ export declare class EspalierDialog extends LitElement {
155
235
  protected firstUpdated(): void;
156
236
  disconnectedCallback(): void;
157
237
  protected render(): import("lit-html").TemplateResult<1>;
158
- static styles: import("lit").CSSResult;
238
+ static styles: import("lit").CSSResult[];
159
239
  }
160
240
  declare global {
161
241
  interface HTMLElementTagNameMap {
@@ -1,6 +1,6 @@
1
- var c=function(l,e,t,o){var n=arguments.length,i=n<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,r;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(l,e,t,o);else for(var a=l.length-1;a>=0;a--)(r=l[a])&&(i=(n<3?r(i):n>3?r(e,t,i):r(e,t))||i);return n>3&&i&&Object.defineProperty(e,t,i),i};import{LitElement as f,css as v,html as m,nothing as d}from"lit";import{customElement as b,property as g,state as y}from"lit/decorators.js";import{classMap as _}from"lit/directives/class-map.js";import{createRef as u,ref as h}from"lit/directives/ref.js";import{OverlayController as O}from"../shared/overlay-controller.js";import{ESP_EVENTS as p}from"../shared/events.js";let s=class extends f{constructor(){super(...arguments),this.dialogSlot=u(),this.vellumRef=u(),this.isOpen=!1,this._overlay=new O({host:this,getFocusTrapContainer:()=>this.vellumRef.value??null,getFocusFallback:()=>this.vellumRef.value??null}),this._closeReason="api",this._lifecycleToken=0,this.fullScreen=!1}toggleOpen(){if(this.isOpen){const e=this._closeReason;this._closeReason="api";const t=new CustomEvent(p.DIALOG_CLOSING,{detail:{reason:e},bubbles:!0,composed:!0,cancelable:!0});if(!this.dispatchEvent(t))return;const o=++this._lifecycleToken;this.removeAttribute("is-open"),this.isOpen=!1,this._overlay.close(),this.updateComplete.then(()=>{this.isOpen||this._lifecycleToken!==o||this.dispatchEvent(new CustomEvent(p.DIALOG_CLOSED,{detail:{reason:e},bubbles:!0,composed:!0}))})}else{const e=++this._lifecycleToken;this.setAttribute("is-open","true"),this.isOpen=!0,this._overlay.open(),this.updateComplete.then(()=>{!this.isOpen||this._lifecycleToken!==e||(this._moveFocusIntoDialog(),this.dispatchEvent(new CustomEvent(p.DIALOG_OPENED,{detail:{},bubbles:!0,composed:!0})))})}}_handleKeyDown(e){if(this.isOpen){if(e.key==="Escape"){e.preventDefault(),this._closeReason="escape",this.toggleOpen();return}e.key==="Tab"&&this._overlay.trapFocus(e)}}_moveFocusIntoDialog(){this._overlay.moveFocusInto()}firstUpdated(){this.dialogSlot.value&&this.dialogSlot.value.addEventListener("esp-form-dialog-close-requested",e=>{this._closeReason="close-dialog",this.toggleOpen(),e.preventDefault()})}disconnectedCallback(){super.disconnectedCallback()}render(){const{isOpen:e,fullScreen:t}=this,o={"is-open":e,"full-screen":t};return m`<div
1
+ var p=function(l,e,t,i){var n=arguments.length,s=n<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(l,e,t,i);else for(var r=l.length-1;r>=0;r--)(a=l[r])&&(s=(n<3?a(s):n>3?a(e,t,s):a(e,t))||s);return n>3&&s&&Object.defineProperty(e,t,s),s};import{paintedSurface as v,surfaceLayerAttributes as f}from"../shared/surface-layer.js";import{LitElement as g,css as b,html as m,nothing as d}from"lit";import{customElement as y,property as k,state as _}from"lit/decorators.js";import{classMap as x}from"lit/directives/class-map.js";import{createRef as u,ref as h}from"lit/directives/ref.js";import{OverlayController as O}from"../shared/overlay-controller.js";import{ESP_EVENTS as c}from"../shared/events.js";let o=class extends g{constructor(){super(...arguments),this.dialogSlot=u(),this.vellumRef=u(),this.isOpen=!1,this._overlay=new O({host:this,getFocusTrapContainer:()=>this.vellumRef.value??null,getFocusFallback:()=>this.vellumRef.value??null}),this._closeReason="api",this._lifecycleToken=0,this.fullScreen=!1}toggleOpen(){if(this.isOpen){const e=this._closeReason;this._closeReason="api";const t=new CustomEvent(c.DIALOG_CLOSING,{detail:{reason:e},bubbles:!0,composed:!0,cancelable:!0});if(!this.dispatchEvent(t))return;const i=++this._lifecycleToken;this.removeAttribute("is-open"),this.isOpen=!1,this._overlay.close(),this.updateComplete.then(()=>{this.isOpen||this._lifecycleToken!==i||this.dispatchEvent(new CustomEvent(c.DIALOG_CLOSED,{detail:{reason:e},bubbles:!0,composed:!0}))})}else{const e=++this._lifecycleToken;this.setAttribute("is-open","true"),this.isOpen=!0,this._overlay.open(),this.updateComplete.then(()=>{!this.isOpen||this._lifecycleToken!==e||(this._moveFocusIntoDialog(),this.dispatchEvent(new CustomEvent(c.DIALOG_OPENED,{detail:{},bubbles:!0,composed:!0})))})}}_handleKeyDown(e){if(this.isOpen){if(e.key==="Escape"){e.preventDefault(),this._closeReason="escape",this.toggleOpen();return}e.key==="Tab"&&this._overlay.trapFocus(e)}}_moveFocusIntoDialog(){this._overlay.moveFocusInto()}firstUpdated(){this.dialogSlot.value&&this.dialogSlot.value.addEventListener("esp-form-dialog-close-requested",e=>{this._closeReason="close-dialog",this.toggleOpen(),e.preventDefault()})}disconnectedCallback(){super.disconnectedCallback()}render(){const{isOpen:e,fullScreen:t}=this,i={"is-open":e,"full-screen":t};return m`<div
2
2
  ${h(this.vellumRef)}
3
- class="vellum ${_(o)}"
3
+ class="vellum ${x(i)}"
4
4
  data-no-swipe
5
5
  role=${e?"dialog":d}
6
6
  aria-modal=${e?"true":d}
@@ -8,70 +8,82 @@ var c=function(l,e,t,o){var n=arguments.length,i=n<3?e:o===null?o=Object.getOwnP
8
8
  @keydown=${this._handleKeyDown}
9
9
  >
10
10
  <slot ${h(this.dialogSlot)}></slot>
11
- </div>`}};s.styles=v`
12
- :host {
13
- display: block;
14
- }
15
- .vellum {
16
- display: grid;
17
- box-sizing: border-box;
18
- justify-content: center;
19
- padding: 0;
20
- visibility: hidden;
21
- position: fixed;
22
- z-index: 10000;
23
- left: 0;
24
- top: 0;
25
-
26
- height: 100vh;
27
- height: 100dvh;
28
- width: 100vw;
29
- overflow-y: auto;
30
- outline: none;
31
-
32
- ::slotted(*) {
33
- z-index: 10;
34
- position: relative;
35
- }
36
-
37
- &::before {
38
- content: "";
11
+ </div>`}};o.styles=[v(3),f(":host"),b`
12
+ :host {
39
13
  display: block;
14
+ }
15
+ .vellum {
16
+ display: grid;
17
+ box-sizing: border-box;
18
+ justify-content: center;
19
+ padding: 0;
20
+ visibility: hidden;
40
21
  position: fixed;
41
- inset: 0;
42
- opacity: var(--esp-dialog-bg-opacity, var(--esp-vellum-opacity, 0.85));
43
- background: var(
44
- --esp-color-dialog-bg,
45
- var(--esp-vellum-background, var(--esp-color-layer-3))
22
+ z-index: 10000;
23
+ inset-inline-start: var(--esp-dialog-inset-inline-start, 0px);
24
+ inset-block-start: var(--esp-dialog-inset-block-start, 0px);
25
+
26
+ width: calc(
27
+ 100vw - var(--esp-dialog-inset-inline-start, 0px) - var(
28
+ --esp-dialog-inset-inline-end,
29
+ 0px
30
+ )
46
31
  );
47
- z-index: 1;
48
- }
32
+ height: calc(
33
+ 100vh - var(--esp-dialog-inset-block-start, 0px) - var(--esp-dialog-inset-block-end, 0px)
34
+ );
35
+ height: calc(
36
+ 100dvh - var(--esp-dialog-inset-block-start, 0px) - var(--esp-dialog-inset-block-end, 0px)
37
+ );
38
+ overflow-y: auto;
39
+ outline: none;
49
40
 
50
- &::after {
51
- content: "";
52
- display: block;
53
- position: fixed;
54
- inset: 0;
55
- background-image: var(--esp-vellum-background-image, none);
56
- background-repeat: repeat;
57
- opacity: var(--esp-vellum-background-image-opacity, 0.3);
58
- z-index: 2;
59
- pointer-events: none;
60
- }
41
+ ::slotted(*) {
42
+ z-index: 10;
43
+ position: relative;
44
+ }
45
+
46
+ &::before,
47
+ &::after {
48
+ content: "";
49
+ display: block;
50
+ position: fixed;
51
+ inset-inline: var(--esp-dialog-inset-inline-start, 0px)
52
+ var(--esp-dialog-inset-inline-end, 0px);
53
+ inset-block: var(--esp-dialog-inset-block-start, 0px)
54
+ var(--esp-dialog-inset-block-end, 0px);
55
+ }
56
+
57
+ &::before {
58
+ opacity: var(--esp-dialog-bg-opacity, var(--esp-vellum-opacity, 0.85));
59
+ background: var(
60
+ --esp-color-dialog-bg,
61
+ var(--esp-vellum-background, var(--_esp-surface-background))
62
+ );
63
+ z-index: 1;
64
+ }
65
+
66
+ &::after {
67
+ background-image: var(--esp-vellum-background-image, none);
68
+ background-repeat: repeat;
69
+ opacity: var(--esp-vellum-background-image-opacity, 0.3);
70
+ z-index: 2;
71
+ pointer-events: none;
72
+ }
61
73
 
62
- &.is-open {
63
- visibility: visible;
74
+ &.is-open {
75
+ visibility: visible;
76
+ }
64
77
  }
65
- }
66
78
 
67
- @media screen and (min-width: 400px) {
68
- .vellum {
69
- grid-template-columns: auto auto;
70
- padding: var(--esp-size-big-to-large) 0;
79
+ @media screen and (min-width: 400px) {
80
+ .vellum {
81
+ grid-template-columns: auto auto;
82
+ padding: var(--esp-size-big-to-large) 0;
71
83
 
72
- &.full-screen {
73
- padding: 0;
84
+ &.full-screen {
85
+ padding: 0;
86
+ }
74
87
  }
75
88
  }
76
- }
77
- `,c([y()],s.prototype,"isOpen",void 0),c([g({attribute:"full-screen",type:Boolean})],s.prototype,"fullScreen",void 0),s=c([b("esp-dialog")],s);export{s as EspalierDialog};
89
+ `],p([_()],o.prototype,"isOpen",void 0),p([k({attribute:"full-screen",type:Boolean})],o.prototype,"fullScreen",void 0),o=p([y("esp-dialog")],o);export{o as EspalierDialog};
@@ -2,8 +2,8 @@ import { type PropertyValues } from "lit";
2
2
  import { EspalierElementBase } from "../shared/esp-element-base.js";
3
3
  import { type FlyoutCloseReason } from "../shared/flyout-events.js";
4
4
  /**
5
- * A transient panel for help and more-info content that claims designed spare
6
- * width before ever covering the page.
5
+ * A panel for help and additional information. Uses spare page width when
6
+ * available and switches to an overlay when the workspace cannot fit it.
7
7
  *
8
8
  * Place one `esp-flyout` in an `esp-page`'s `flyout` slot. The panel
9
9
  * lives on the canvas after any persistent preview, outside the content