@taprootio/espalier 3.8.0 → 4.0.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 (104) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/custom-elements.json +2075 -2706
  3. package/dist/action-menu/esp-action-menu-item.d.ts +4 -4
  4. package/dist/action-menu/esp-action-menu-item.js +1 -1
  5. package/dist/action-menu/esp-action-menu.d.ts +2 -2
  6. package/dist/action-menu/esp-action-menu.js +6 -6
  7. package/dist/box/esp-box.d.ts +1 -1
  8. package/dist/burger/esp-burger.d.ts +4 -4
  9. package/dist/burger/esp-burger.js +4 -4
  10. package/dist/button/action-state-lightness.js +1 -1
  11. package/dist/button/esp-button.d.ts +39 -5
  12. package/dist/button/esp-button.js +41 -51
  13. package/dist/checkbox/esp-checkbox-group.d.ts +4 -2
  14. package/dist/checkbox/esp-checkbox-group.js +1 -1
  15. package/dist/checkbox/esp-checkbox.d.ts +4 -2
  16. package/dist/color-picker/esp-color-picker.d.ts +2 -2
  17. package/dist/color-picker/esp-color-picker.js +4 -4
  18. package/dist/date-picker/esp-date-picker.d.ts +5 -3
  19. package/dist/date-picker/esp-date-picker.js +7 -7
  20. package/dist/details/esp-details-group.d.ts +1 -1
  21. package/dist/details/esp-details-group.js +3 -3
  22. package/dist/details/esp-details.d.ts +2 -2
  23. package/dist/details/esp-details.js +3 -3
  24. package/dist/dialog/esp-dialog.d.ts +7 -7
  25. package/dist/dialog/esp-dialog.js +7 -7
  26. package/dist/file-upload/esp-file-upload.d.ts +5 -2
  27. package/dist/file-upload/esp-file-upload.js +3 -3
  28. package/dist/flyout/esp-flyout.d.ts +10 -10
  29. package/dist/flyout/esp-flyout.js +14 -14
  30. package/dist/focus-picker/esp-focus-picker.d.ts +4 -4
  31. package/dist/focus-picker/esp-focus-picker.js +4 -4
  32. package/dist/font-picker/esp-font-picker.d.ts +1 -1
  33. package/dist/font-picker/esp-font-picker.js +2 -2
  34. package/dist/form/esp-form.d.ts +9 -9
  35. package/dist/form/esp-form.js +1 -1
  36. package/dist/grid/esp-grid.d.ts +10 -10
  37. package/dist/grid/esp-grid.js +13 -11
  38. package/dist/header/esp-header-button.d.ts +2 -2
  39. package/dist/header/esp-header-button.js +1 -1
  40. package/dist/header/esp-header.d.ts +5 -5
  41. package/dist/header/esp-header.js +4 -4
  42. package/dist/help/esp-help-provider.js +1 -1
  43. package/dist/help/help-document.js +1 -1
  44. package/dist/image-upload/esp-image-preview.js +8 -8
  45. package/dist/image-upload/esp-image-upload.d.ts +14 -14
  46. package/dist/image-upload/esp-image-upload.js +10 -10
  47. package/dist/image-upload/image-helpers.d.ts +2 -2
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.js +1 -1
  50. package/dist/info/esp-info.d.ts +2 -2
  51. package/dist/info/esp-info.js +6 -6
  52. package/dist/input/esp-input.d.ts +8 -7
  53. package/dist/input/esp-input.js +2 -2
  54. package/dist/lightbox/esp-lightbox.js +6 -6
  55. package/dist/menu/esp-menu-group.d.ts +1 -1
  56. package/dist/menu/esp-menu-group.js +1 -1
  57. package/dist/menu/esp-menu-item.d.ts +2 -2
  58. package/dist/menu/esp-menu-item.js +2 -2
  59. package/dist/menu/esp-menu.d.ts +2 -2
  60. package/dist/menu/esp-menu.js +9 -9
  61. package/dist/page/esp-page.d.ts +4 -4
  62. package/dist/page/esp-page.js +1 -1
  63. package/dist/pickers/esp-pick-one.d.ts +3 -1
  64. package/dist/pickers/esp-pick-one.js +2 -2
  65. package/dist/pickers/esp-pick-some.d.ts +3 -1
  66. package/dist/pickers/esp-pick-some.js +1 -1
  67. package/dist/pickers/esp-picker-base.d.ts +1 -1
  68. package/dist/pickers/esp-picker-menu.d.ts +4 -4
  69. package/dist/pickers/esp-picker-menu.js +7 -7
  70. package/dist/popover/esp-popover.d.ts +2 -2
  71. package/dist/popover/esp-popover.js +3 -3
  72. package/dist/progress/esp-progress.d.ts +4 -4
  73. package/dist/radio-button/esp-radio-button-group.d.ts +4 -2
  74. package/dist/radio-button/esp-radio-button-group.js +4 -4
  75. package/dist/radio-button/esp-radio-button.d.ts +1 -1
  76. package/dist/repeater/esp-repeater.d.ts +2 -12
  77. package/dist/search/esp-search.d.ts +4 -4
  78. package/dist/search/esp-search.js +3 -3
  79. package/dist/shared/esp-element-base.js +1 -1
  80. package/dist/shared/events.d.ts +151 -70
  81. package/dist/shared/events.js +1 -1
  82. package/dist/shared/flyout-events.d.ts +1 -1
  83. package/dist/shared/flyout-events.js +1 -1
  84. package/dist/shared/form-field-controller.d.ts +3 -3
  85. package/dist/shared/intent-values.d.ts +0 -12
  86. package/dist/shared/intent-values.js +1 -1
  87. package/dist/shared/utilities.d.ts +0 -31
  88. package/dist/shared/utilities.js +1 -1
  89. package/dist/shared/validation.d.ts +2 -2
  90. package/dist/shared/validation.js +1 -1
  91. package/dist/slider/esp-slider.d.ts +4 -2
  92. package/dist/status-indicator/esp-status-indicator.js +2 -2
  93. package/dist/switch/esp-switch.d.ts +4 -2
  94. package/dist/tabs/esp-tab-group.d.ts +2 -2
  95. package/dist/tabs/esp-tab-group.js +4 -4
  96. package/dist/tabs/esp-tab.d.ts +2 -1
  97. package/dist/tabs/esp-tab.js +2 -2
  98. package/dist/textarea/esp-textarea.d.ts +6 -5
  99. package/dist/textarea/esp-textarea.js +1 -1
  100. package/dist/toaster/esp-toaster.d.ts +4 -4
  101. package/dist/toaster/esp-toaster.js +1 -1
  102. package/dist/tree/esp-tree.d.ts +2 -1
  103. package/dist/tree/esp-tree.js +26 -26
  104. package/package.json +1 -1
@@ -9,7 +9,7 @@ export type ActionMenuItemIconPosition = "left" | "right";
9
9
  *
10
10
  * Use the optional `icon` slot for a leading visual cue. Link-style
11
11
  * action items are intentionally not part of this API yet; use the
12
- * parent menu's `select` event and handle navigation in application
12
+ * parent menu's `esp-action-menu-select` event and handle navigation in application
13
13
  * code until the href behavior is reviewed.
14
14
  *
15
15
  * ```html
@@ -30,8 +30,8 @@ export type ActionMenuItemIconPosition = "left" | "right";
30
30
  * @slot icon - Optional custom leading icon. Slotted icons override
31
31
  * the generated SVG from the `icon` attribute.
32
32
  *
33
- * @event {CustomEvent<ActionMenuItemActivateDetail>} esp-action-menu-item-activate -
34
- * Internal activation event consumed by the parent action menu.
33
+ * Activation is reported through a private coordination event consumed by
34
+ * the parent action menu.
35
35
  *
36
36
  * @cssprop --esp-action-menu-item-padding - Padding inside each
37
37
  * menu item. Defaults to `var(--esp-size-tiny) var(--esp-size-small)`.
@@ -68,7 +68,7 @@ export declare class EspalierActionMenuItem extends EspalierElementBase {
68
68
  */
69
69
  icon: string;
70
70
  /**
71
- * Value included in the parent menu's `select` event detail.
71
+ * Value included in the parent menu's `esp-action-menu-select` event detail.
72
72
  */
73
73
  value: string;
74
74
  /**
@@ -1,4 +1,4 @@
1
- var s=function(r,i,t,n){var a=arguments.length,e=a<3?i:n===null?n=Object.getOwnPropertyDescriptor(i,t):n,c;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")e=Reflect.decorate(r,i,t,n);else for(var p=r.length-1;p>=0;p--)(c=r[p])&&(e=(a<3?c(e):a>3?c(i,t,e):c(i,t))||e);return a>3&&e&&Object.defineProperty(i,t,e),e};import{css as h,html as m,nothing as u}from"lit";import{customElement as f,property as l}from"lit/decorators.js";import{classMap as g}from"lit/directives/class-map.js";import{ref as v}from"lit/directives/ref.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";import{getIconHrefForHost as b}from"../shared/intent-values.js";import{SlottedIconController as y}from"../shared/slotted-icon-controller.js";import{renderSpriteIcon as P}from"../shared/svgs/render-sprite-icon.js";let o=class extends d{constructor(){super(...arguments),this.iconSlot=new y(this),this.iconPositionExplicit=!1,this.inheritingIconPosition=!1,this._iconPosition="left",this.icon="",this.value="",this.disabled=!1,this.handleClick=i=>{if(this.disabled){i.preventDefault();return}this.activate()}}get iconPosition(){return this._iconPosition}set iconPosition(i){const t=this._iconPosition;this._iconPosition=i,this.inheritingIconPosition||(this.iconPositionExplicit=!0),this.requestUpdate("iconPosition",t)}connectedCallback(){super.connectedCallback(),this.addEventListener("click",this.handleClick)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("click",this.handleClick)}updated(i){super.updated(i),this.setAttribute("role","menuitem"),this.setAttribute("aria-disabled",String(this.disabled))}activate(){this.disabled||this.dispatchEvent(new CustomEvent("esp-action-menu-item-activate",{detail:{item:this},bubbles:!0,composed:!0}))}inheritIconPosition(i){this.iconPositionExplicit||(this.inheritingIconPosition=!0,this.iconPosition=i,this.inheritingIconPosition=!1)}render(){const i=b(this.icon,this),t=this.iconSlot.hasSlottedIcon(),n={item:!0,"has-icon":t||i.length>0,"icon-right":this.iconPosition==="right"};return m`
1
+ var s=function(r,i,t,n){var a=arguments.length,e=a<3?i:n===null?n=Object.getOwnPropertyDescriptor(i,t):n,c;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")e=Reflect.decorate(r,i,t,n);else for(var p=r.length-1;p>=0;p--)(c=r[p])&&(e=(a<3?c(e):a>3?c(i,t,e):c(i,t))||e);return a>3&&e&&Object.defineProperty(i,t,e),e};import{css as h,html as m,nothing as u}from"lit";import{customElement as f,property as l}from"lit/decorators.js";import{classMap as g}from"lit/directives/class-map.js";import{ref as v}from"lit/directives/ref.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";import{getIconHrefForHost as b}from"../shared/intent-values.js";import{SlottedIconController as y}from"../shared/slotted-icon-controller.js";import{renderSpriteIcon as P}from"../shared/svgs/render-sprite-icon.js";let o=class extends d{constructor(){super(...arguments),this.iconSlot=new y(this),this.iconPositionExplicit=!1,this.inheritingIconPosition=!1,this._iconPosition="left",this.icon="",this.value="",this.disabled=!1,this.handleClick=i=>{if(this.disabled){i.preventDefault();return}this.activate()}}get iconPosition(){return this._iconPosition}set iconPosition(i){const t=this._iconPosition;this._iconPosition=i,this.inheritingIconPosition||(this.iconPositionExplicit=!0),this.requestUpdate("iconPosition",t)}connectedCallback(){super.connectedCallback(),this.addEventListener("click",this.handleClick)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("click",this.handleClick)}updated(i){super.updated(i),this.setAttribute("role","menuitem"),this.setAttribute("aria-disabled",String(this.disabled))}activate(){this.disabled||this.dispatchEvent(new CustomEvent("esp-internal-action-menu-item-activate",{detail:{item:this},bubbles:!0,composed:!0}))}inheritIconPosition(i){this.iconPositionExplicit||(this.inheritingIconPosition=!0,this.iconPosition=i,this.inheritingIconPosition=!1)}render(){const i=b(this.icon,this),t=this.iconSlot.hasSlottedIcon(),n={item:!0,"has-icon":t||i.length>0,"icon-right":this.iconPosition==="right"};return m`
2
2
  <span part="item" class=${g(n)}>
3
3
  <span part="icon" class="icon">
4
4
  <slot
@@ -35,7 +35,7 @@ export type ActionMenuSelectDetail = {
35
35
  * </esp-action-menu-item>
36
36
  * </esp-action-menu>
37
37
  * <script>
38
- * findById("demo-actions").addEventListener("select", (event) => {
38
+ * findById("demo-actions").addEventListener("esp-action-menu-select", (event) => {
39
39
  * showToast({
40
40
  * message: `Selected ${event.detail.value}`,
41
41
  * icon: "info-i",
@@ -70,7 +70,7 @@ export type ActionMenuSelectDetail = {
70
70
  * @slot - Place `esp-action-menu-item` children here.
71
71
  * @slot trigger - Optional custom trigger element.
72
72
  *
73
- * @event {CustomEvent<ActionMenuSelectDetail>} select - Emitted from
73
+ * @event {CustomEvent<ActionMenuSelectDetail>} esp-action-menu-select - Emitted from
74
74
  * the menu when an enabled item is activated.
75
75
  *
76
76
  * @cssprop --esp-action-menu-background - Menu surface background.
@@ -1,4 +1,4 @@
1
- var l=function(c,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(c,e,t,s);else for(var r=c.length-1;r>=0;r--)(a=c[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 g}from"lit";import{customElement as I,property as u,state as p}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-action-menu-item.js";const w=g` <svg
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
2
2
  xmlns="http://www.w3.org/2000/svg"
3
3
  viewBox="0 0 24 24"
4
4
  fill="currentColor"
@@ -7,15 +7,15 @@ var l=function(c,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=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-action-menu-item-activate",this.handleItemActivate),this.addEventListener("keydown",this.handleMenuKeydown)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("esp-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("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 g`
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`
11
11
  <esp-popover
12
12
  ${h(this.popoverRef)}
13
13
  .trigger=${"none"}
14
14
  attach=${e}
15
15
  align=${t}
16
16
  offset="2px"
17
- @popover-opened=${this.handlePopoverOpened}
18
- @popover-closed=${this.handlePopoverClosed}
17
+ @esp-popover-opened=${this.handlePopoverOpened}
18
+ @esp-popover-closed=${this.handlePopoverClosed}
19
19
  >
20
20
  <span
21
21
  ${h(this.triggerShell)}
@@ -33,7 +33,7 @@ var l=function(c,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
- ${w}
36
+ ${y}
37
37
  </esp-button>
38
38
  </slot>
39
39
  </span>
@@ -72,4 +72,4 @@ var l=function(c,e,t,s){var o=arguments.length,i=o<3?e:s===null?s=Object.getOwnP
72
72
  ::slotted(esp-action-menu-item + esp-action-menu-item) {
73
73
  border-top: 1px dotted var(--esp-color-border);
74
74
  }
75
- `],l([p()],n.prototype,"open",void 0),l([p()],n.prototype,"focusedIndex",void 0),l([u({type:String})],n.prototype,"placement",void 0),l([u({type:Boolean,reflect:!0})],n.prototype,"disabled",void 0),l([u({attribute:"icon-position",type:String})],n.prototype,"iconPosition",void 0),n=l([I("esp-action-menu")],n);export{n as EspalierActionMenu};
75
+ `],l([g()],n.prototype,"open",void 0),l([g()],n.prototype,"focusedIndex",void 0),l([u({type:String})],n.prototype,"placement",void 0),l([u({type:Boolean,reflect:!0})],n.prototype,"disabled",void 0),l([u({attribute:"icon-position",type:String})],n.prototype,"iconPosition",void 0),n=l([I("esp-action-menu")],n);export{n as EspalierActionMenu};
@@ -113,7 +113,7 @@ export declare class EspalierBox extends EspalierElementBase {
113
113
  * let fullScreen = false;
114
114
  * const theBox = findByTagName("esp-box")[0];
115
115
  * const theButton = findByTagName("esp-button")[0];
116
- * theButton.addEventListener("clicked", () => {
116
+ * theButton.addEventListener("esp-clicked", () => {
117
117
  * fullScreen = !fullScreen;
118
118
  *
119
119
  * if(fullScreen) {
@@ -12,22 +12,22 @@ import { LitElement } from "lit";
12
12
  * @cssprop --esp-color-burger-opened - The color of the burger lines when open.
13
13
  * @cssprop --esp-color-burger-opened-hover - The hover color of the burger lines when open.
14
14
  * @cssprop --esp-size-burger-stroke - The stroke width of the burger lines.
15
- * @event {CustomEvent} opened - Emitted when the button is clicked and the image changes from a burger to an X.
16
- * @event {CustomEvent} closed - Emitted when the button is clicked and the image changes from an X to a burger.
15
+ * @event {CustomEvent} esp-burger-opened - Emitted when the button is clicked and the image changes from a burger to an X.
16
+ * @event {CustomEvent} esp-burger-closed - Emitted when the button is clicked and the image changes from an X to a burger.
17
17
  *
18
18
  * ```html
19
19
  * <esp-burger></esp-burger>
20
20
  * <script>
21
21
  * const theBurger = findByTagName("esp-burger")[0];
22
22
  *
23
- * theBurger.addEventListener("opened", () => {
23
+ * theBurger.addEventListener("esp-burger-opened", () => {
24
24
  * showToast({
25
25
  * message: "It would be a good time to show the menu. This message will self-destruct in 4 seconds...",
26
26
  * icon: "info-i",
27
27
  * duration: 4
28
28
  * });
29
29
  * });
30
- * theBurger.addEventListener("closed", () => {
30
+ * theBurger.addEventListener("esp-burger-closed", () => {
31
31
  * showToast({
32
32
  * message: "It would be a good time to hide the menu. This message will self-destruct in 4 seconds...",
33
33
  * icon: "info-i",
@@ -1,4 +1,4 @@
1
- var p=function(n,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(n,e,t,i);else for(var l=n.length-1;l>=0;l--)(o=n[l])&&(s=(r<3?o(s):r>3?o(e,t,s):o(e,t))||s);return r>3&&s&&Object.defineProperty(e,t,s),s};import{LitElement as h,css as m,html as c}from"lit";import{classMap as C}from"lit/directives/class-map.js";import{customElement as u,property as d}from"lit/decorators.js";let a=class extends h{constructor(){super(...arguments),this.menuOpen=!1,this.presentationOnly=!1}render(){const{menuOpen:e}=this,t=e?"Close menu":"Open menu",r=c`
1
+ var p=function(n,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(n,e,t,i);else for(var l=n.length-1;l>=0;l--)(o=n[l])&&(s=(r<3?o(s):r>3?o(e,t,s):o(e,t))||s);return r>3&&s&&Object.defineProperty(e,t,s),s};import{LitElement as m,css as C,html as c}from"lit";import{classMap as u}from"lit/directives/class-map.js";import{customElement as v,property as h}from"lit/decorators.js";import{ESP_EVENTS as d}from"../shared/events.js";let a=class extends m{constructor(){super(...arguments),this.menuOpen=!1,this.presentationOnly=!1}render(){const{menuOpen:e}=this,t=e?"Close menu":"Open menu",r=c`
2
2
  <svg>
3
3
  <defs>
4
4
  <filter id="animate-button">
@@ -13,7 +13,7 @@ var p=function(n,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
13
13
  </filter>
14
14
  </defs>
15
15
  </svg>
16
- <div class=${C({plate:!0,active:e})}>
16
+ <div class=${u({plate:!0,active:e})}>
17
17
  <svg class="esp-burger" version="1.1" viewBox="0 0 100 100">
18
18
  <path
19
19
  class="line line1"
@@ -47,7 +47,7 @@ var p=function(n,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
47
47
  </div>
48
48
  `;return this.presentationOnly?c`<div class="animated-mb" aria-hidden="true">${r}</div>`:c`<button class="animated-mb" @click=${this.toggleMenu} aria-label=${t}>
49
49
  ${r}
50
- </button>`}toggleMenu(){this.menuOpen=!this.menuOpen,this.menuOpen?this.dispatchEvent(new CustomEvent("opened",{bubbles:!0,composed:!0})):this.dispatchEvent(new CustomEvent("closed",{bubbles:!0,composed:!0}))}};a.styles=m`
50
+ </button>`}toggleMenu(){this.menuOpen=!this.menuOpen,this.menuOpen?this.dispatchEvent(new CustomEvent(d.BURGER_OPENED,{bubbles:!0,composed:!0})):this.dispatchEvent(new CustomEvent(d.BURGER_CLOSED,{bubbles:!0,composed:!0}))}};a.styles=C`
51
51
  :host {
52
52
  height: var(--esp-header-height, calc(4.5 * var(--esp-size-small)));
53
53
  width: var(--esp-header-height, calc(4.5 * var(--esp-size-small)));
@@ -200,4 +200,4 @@ var p=function(n,e,t,i){var r=arguments.length,s=r<3?e:i===null?i=Object.getOwnP
200
200
  transition: transform 400ms 50ms;
201
201
  }
202
202
  }
203
- `,p([d({attribute:"menu-open",type:Boolean})],a.prototype,"menuOpen",void 0),p([d({attribute:"presentation-only",type:Boolean})],a.prototype,"presentationOnly",void 0),a=p([u("esp-burger")],a);export{a as EspalierBurger};
203
+ `,p([h({attribute:"menu-open",type:Boolean})],a.prototype,"menuOpen",void 0),p([h({attribute:"presentation-only",type:Boolean})],a.prototype,"presentationOnly",void 0),a=p([v("esp-burger")],a);export{a as EspalierBurger};
@@ -1 +1 @@
1
- const T=.9,N=.88,_=.8;export{_ as BUTTON_ICON_INTERACTION_LIGHTNESS_FACTOR,T as BUTTON_ICON_SPLIT_LIGHTNESS_FACTOR,N as BUTTON_INTERACTION_LIGHTNESS_FACTOR};
1
+ const T=.88;export{T as BUTTON_INTERACTION_LIGHTNESS_FACTOR};
@@ -1,5 +1,6 @@
1
1
  import { type TemplateResult } from "lit";
2
2
  import { EspalierElementBase } from "../shared/esp-element-base.js";
3
+ export type ButtonIconPosition = "left" | "right";
3
4
  /**
4
5
  * Used to initiate a user action or link to another page.
5
6
  *
@@ -7,7 +8,7 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
7
8
  * <esp-button label="Hello there!"></esp-button>
8
9
  * <script>
9
10
  * const theButton = findByTagName("esp-button")[0];
10
- * theButton.addEventListener("clicked", () => {
11
+ * theButton.addEventListener("esp-clicked", () => {
11
12
  * showToast({
12
13
  * message: `You clicked the button!`,
13
14
  * icon: "info-i",
@@ -29,6 +30,27 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
29
30
  * </div>
30
31
  * ```
31
32
  *
33
+ * Use `icon-position="left"` for a leading icon. The default `"right"`
34
+ * position keeps the icon trailing; both positions follow writing direction
35
+ * and therefore mirror in RTL.
36
+ *
37
+ * ```html
38
+ * <div style="display: flex; gap: var(--esp-size-padding);">
39
+ * <esp-button
40
+ * collapsed
41
+ * label="Save"
42
+ * icon="save"
43
+ * icon-position="left">
44
+ * </esp-button>
45
+ * <esp-button
46
+ * collapsed
47
+ * label="Next"
48
+ * icon="arrow-big-right"
49
+ * icon-position="right">
50
+ * </esp-button>
51
+ * </div>
52
+ * ```
53
+ *
32
54
  * @customElement esp-button
33
55
  * @slot - Optional custom SVG icon. Slotted icons override the
34
56
  * generated SVG from the `icon` attribute.
@@ -37,13 +59,13 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
37
59
  * <esp-button label="Profile" icon="user-circle"></esp-button>
38
60
  * ```
39
61
  *
40
- * @event {CustomEvent} clicked - Emitted when the button is clicked.
62
+ * @event {CustomEvent} esp-clicked - Emitted when the button is clicked.
41
63
  *
42
64
  * ```html
43
65
  * <esp-button label="Click me!"></esp-button>
44
66
  * <script>
45
67
  * const theButton = findByTagName("esp-button")[0];
46
- * theButton.addEventListener("clicked", () => {
68
+ * theButton.addEventListener("esp-clicked", () => {
47
69
  * showToast({
48
70
  * message: `Hi! You clicked the button. This message will self-destruct in 4 seconds...`,
49
71
  * icon: "info-i",
@@ -129,7 +151,7 @@ export declare class EspalierButton extends EspalierElementBase {
129
151
  * <esp-button disabled label="Disabled"></esp-button>
130
152
  * <script>
131
153
  * const theButton = findByTagName("esp-button")[0];
132
- * theButton.addEventListener("clicked", () => {
154
+ * theButton.addEventListener("esp-clicked", () => {
133
155
  * alert("We will not get here...");
134
156
  * });
135
157
  * </script>
@@ -180,6 +202,18 @@ export declare class EspalierButton extends EspalierElementBase {
180
202
  * @type {string}
181
203
  */
182
204
  icon: string;
205
+ /**
206
+ * Places the optional icon on the logical leading (`"left"`) or trailing
207
+ * (`"right"`) side of the label. Logical placement mirrors in RTL.
208
+ *
209
+ * ```html
210
+ * <esp-button label="Save" icon="save" icon-position="left"></esp-button>
211
+ * <esp-button label="Next" icon="arrow-big-right" icon-position="right"></esp-button>
212
+ * ```
213
+ *
214
+ * @type {"left" | "right"}
215
+ */
216
+ iconPosition: ButtonIconPosition;
183
217
  /**
184
218
  * The label of the button.
185
219
  *
@@ -199,7 +233,7 @@ export declare class EspalierButton extends EspalierElementBase {
199
233
  * <esp-button label="Click me..." icon="save"></esp-button>
200
234
  * <script>
201
235
  * const theButton = findByTagName("esp-button")[0];
202
- * theButton.addEventListener("clicked", async () => {
236
+ * theButton.addEventListener("esp-clicked", async () => {
203
237
  * theButton.loading = true;
204
238
  * setTimeout(function() {
205
239
  * theButton.loading = false;
@@ -1,4 +1,4 @@
1
- var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnPropertyDescriptor(t,i):e,c;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(h,t,i,e);else for(var d=h.length-1;d>=0;d--)(c=h[d])&&(r=(a<3?c(r):a>3?c(t,i,r):c(t,i))||r);return a>3&&r&&Object.defineProperty(t,i,r),r};import{css as f,html as p,nothing as l}from"lit";import{customElement as m,eventOptions as v,property as s,state as y}from"lit/decorators.js";import{classMap as u}from"lit/directives/class-map.js";import{EspalierElementBase as b}from"../shared/esp-element-base.js";import{ref as k}from"lit/directives/ref.js";import{getIconHrefForHost as x}from"../shared/intent-values.js";import{SlottedIconController as T}from"../shared/slotted-icon-controller.js";import{renderSpriteIcon as w}from"../shared/svgs/render-sprite-icon.js";import{BUTTON_ICON_INTERACTION_LIGHTNESS_FACTOR as S,BUTTON_ICON_SPLIT_LIGHTNESS_FACTOR as g,BUTTON_INTERACTION_LIGHTNESS_FACTOR as $}from"./action-state-lightness.js";const N=p`<svg
1
+ var n=function(h,t,r,o){var a=arguments.length,i=a<3?t:o===null?o=Object.getOwnPropertyDescriptor(t,r):o,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(h,t,r,o);else for(var p=h.length-1;p>=0;p--)(d=h[p])&&(i=(a<3?d(i):a>3?d(t,r,i):d(t,r))||i);return a>3&&i&&Object.defineProperty(t,r,i),i};import{css as f,html as c,nothing as l}from"lit";import{customElement as g,eventOptions as m,property as s,state as v}from"lit/decorators.js";import{classMap as u}from"lit/directives/class-map.js";import{EspalierElementBase as b}from"../shared/esp-element-base.js";import{ESP_EVENTS as y}from"../shared/events.js";import{ref as w}from"lit/directives/ref.js";import{getIconHrefForHost as x}from"../shared/intent-values.js";import{SlottedIconController as k}from"../shared/slotted-icon-controller.js";import{renderSpriteIcon as T}from"../shared/svgs/render-sprite-icon.js";import{BUTTON_INTERACTION_LIGHTNESS_FACTOR as S}from"./action-state-lightness.js";const $=c`<svg
2
2
  xmlns="http://www.w3.org/2000/svg"
3
3
  viewBox="0 0 24 24"
4
4
  fill="none"
@@ -10,40 +10,40 @@ var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnP
10
10
  >
11
11
  <path stroke="none" d="M0 0h24v24H0z" fill="none" />
12
12
  <path d="M4.05 11a8 8 0 1 1 .5 4m-.5 5v-5h5" />
13
- </svg>`;let o=class extends b{constructor(){super(...arguments),this.iconSlot=new T(this),this.innerTabindex=null,this.neutralizingTabindex=!1,this.buttonType="button",this.collapsed=!1,this.disabled=!1,this.href="",this.iconOnly=!1,this.incognito=!1,this.icon="",this.label="",this.loading=!1,this.target="",this.rel="",this.formNoValidate=!1,this.buildIcon=t=>this.loading?p` <span>${N}</span> `:p`
13
+ </svg>`;let e=class extends b{constructor(){super(...arguments),this.iconSlot=new k(this),this.innerTabindex=null,this.neutralizingTabindex=!1,this.buttonType="button",this.collapsed=!1,this.disabled=!1,this.href="",this.iconOnly=!1,this.incognito=!1,this.icon="",this.iconPosition="right",this.label="",this.loading=!1,this.target="",this.rel="",this.formNoValidate=!1,this.buildIcon=t=>this.loading?c` <span>${$}</span> `:c`
14
14
  <span>
15
- <slot ${k(this.iconSlot.slotRef)} @slotchange=${this.iconSlot.handleSlotChange}></slot>
16
- ${!this.iconSlot.hasSlottedIcon(":scope > *")&&t?w(t):l}
15
+ <slot ${w(this.iconSlot.slotRef)} @slotchange=${this.iconSlot.handleSlotChange}></slot>
16
+ ${!this.iconSlot.hasSlottedIcon(":scope > *")&&t?T(t):l}
17
17
  </span>
18
- `}static get observedAttributes(){return[...super.observedAttributes,"tabindex","aria-pressed"]}attributeChangedCallback(t,i,e){if(super.attributeChangedCallback(t,i,e),t==="aria-pressed"){this.requestUpdate();return}if(t!=="tabindex"||this.neutralizingTabindex)return;const a=e===null?null:Number(e),r=a===null||Number.isNaN(a)?null:a;r!==null&&r>=0?(this.innerTabindex=r,this.writeHostTabindex(null)):r===null&&e!==null?(this.innerTabindex=null,this.writeHostTabindex(null)):this.innerTabindex=r}writeHostTabindex(t){this.getAttribute("tabindex")!==t&&(this.neutralizingTabindex=!0,t===null?this.removeAttribute("tabindex"):this.setAttribute("tabindex",t),this.neutralizingTabindex=!1)}removeAttribute(t){super.removeAttribute(t),t==="tabindex"&&!this.neutralizingTabindex&&(this.innerTabindex=null)}focus(t){this.focusShadowElementAfterUpdate("button, a",t)}handleClick(t){if(this.dispatchEvent(new CustomEvent("clicked",{detail:{},bubbles:!0,composed:!0})),this.buttonType==="submit"){const i=this.closest("form");if(i){const e=document.createElement("button");e.type="submit",e.hidden=!0,this.formNoValidate&&(e.formNoValidate=!0),i.appendChild(e),i.requestSubmit(e),e.remove()}}else this.buttonType==="reset"&&this.closest("form")?.reset()}render(){const t=x(this.icon,this),i=this.loading||this.iconSlot.hasSlottedIcon(":scope > *")||t.length>0,{collapsed:e,iconOnly:a}=this,r=a?this.getAttribute("aria-label")||this.label||l:l,c=this.getAttribute("aria-pressed")||l,d={"esp-field":!0,"icon-only":a,incognito:this.incognito,"is-collapsed":e,"has-icon":i};return this.href.length?p`
19
- <div part="wrapper" class=${u(d)}>
18
+ `}static get observedAttributes(){return[...super.observedAttributes,"tabindex","aria-pressed"]}attributeChangedCallback(t,r,o){if(super.attributeChangedCallback(t,r,o),t==="aria-pressed"){this.requestUpdate();return}if(t!=="tabindex"||this.neutralizingTabindex)return;const a=o===null?null:Number(o),i=a===null||Number.isNaN(a)?null:a;i!==null&&i>=0?(this.innerTabindex=i,this.writeHostTabindex(null)):i===null&&o!==null?(this.innerTabindex=null,this.writeHostTabindex(null)):this.innerTabindex=i}writeHostTabindex(t){this.getAttribute("tabindex")!==t&&(this.neutralizingTabindex=!0,t===null?this.removeAttribute("tabindex"):this.setAttribute("tabindex",t),this.neutralizingTabindex=!1)}removeAttribute(t){super.removeAttribute(t),t==="tabindex"&&!this.neutralizingTabindex&&(this.innerTabindex=null)}focus(t){this.focusShadowElementAfterUpdate("button, a",t)}handleClick(t){if(this.dispatchEvent(new CustomEvent(y.CLICKED,{detail:{},bubbles:!0,composed:!0})),this.buttonType==="submit"){const r=this.closest("form");if(r){const o=document.createElement("button");o.type="submit",o.hidden=!0,this.formNoValidate&&(o.formNoValidate=!0),r.appendChild(o),r.requestSubmit(o),o.remove()}}else this.buttonType==="reset"&&this.closest("form")?.reset()}render(){const t=x(this.icon,this),r=this.loading||this.iconSlot.hasSlottedIcon(":scope > *")||t.length>0,{collapsed:o,iconOnly:a}=this,i=a?this.getAttribute("aria-label")||this.label||l:l,d=this.getAttribute("aria-pressed")||l,p={"esp-field":!0,"icon-only":a,incognito:this.incognito,"is-collapsed":o,"has-icon":r,"icon-left":r&&!a&&this.iconPosition==="left"};return this.href.length?c`
19
+ <div part="wrapper" class=${u(p)}>
20
20
  <a
21
21
  ?disabled=${this.disabled}
22
22
  href=${this.href}
23
23
  target=${this.target}
24
24
  rel=${this.rel||l}
25
25
  tabindex=${this.innerTabindex??l}
26
- aria-label=${r}
26
+ aria-label=${i}
27
27
  >
28
28
  <span>${this.label??""}</span>
29
29
  ${this.buildIcon(t)}
30
30
  </a>
31
31
  </div>
32
- `:p`
33
- <div part="wrapper" class=${u(d)}>
32
+ `:c`
33
+ <div part="wrapper" class=${u(p)}>
34
34
  <button
35
35
  ?disabled=${this.disabled||this.loading}
36
36
  @click=${this.handleClick}
37
37
  type=${this.buttonType}
38
38
  tabindex=${this.innerTabindex??l}
39
- aria-label=${r}
40
- aria-pressed=${c}
39
+ aria-label=${i}
40
+ aria-pressed=${d}
41
41
  >
42
42
  <span>${this.label??""}</span>
43
43
  ${this.buildIcon(t)}
44
44
  </button>
45
45
  </div>
46
- `}};o.styles=[...b.styles,f`
46
+ `}};e.styles=[...b.styles,f`
47
47
  :host {
48
48
  --_esp-button-radius: var(--esp-size-border-radius);
49
49
  }
@@ -81,15 +81,8 @@ var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnP
81
81
  }
82
82
 
83
83
  > span:nth-child(2) {
84
- background-color: oklch(
85
- from var(--esp-color-action-background)
86
- calc(l * ${g}) c h
87
- );
88
84
  display: none;
89
85
  place-content: center;
90
- border-left: 1px dotted var(--esp-color-border);
91
- border-bottom-right-radius: max(0px, calc(var(--_esp-button-radius) - 0.1rem));
92
- border-top-right-radius: max(0px, calc(var(--_esp-button-radius) - 0.1rem));
93
86
  padding: var(--esp-button-padding, var(--esp-size-padding));
94
87
 
95
88
  .generated-icon,
@@ -101,6 +94,17 @@ var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnP
101
94
  }
102
95
  }
103
96
 
97
+ &.icon-left {
98
+ button,
99
+ a {
100
+ grid-template-columns: min-content auto;
101
+
102
+ > span:nth-child(2) {
103
+ order: -1;
104
+ }
105
+ }
106
+ }
107
+
104
108
  &.has-icon {
105
109
  button,
106
110
  a {
@@ -123,7 +127,6 @@ var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnP
123
127
  }
124
128
 
125
129
  > span:nth-child(2) {
126
- background-color: var(--esp-color-action-background);
127
130
  border: none;
128
131
  border-radius: var(--_esp-button-radius);
129
132
  }
@@ -136,24 +139,12 @@ var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnP
136
139
  &:hover,
137
140
  &:focus-within {
138
141
  background-color: oklch(
139
- from var(--esp-color-action-background) calc(l * ${$})
142
+ from var(--esp-color-action-background) calc(l * ${S})
140
143
  c h
141
144
  );
142
-
143
- button,
144
- a {
145
- > span:nth-child(2) {
146
- background-color: oklch(
147
- from var(--esp-color-action-background)
148
- calc(l * ${S}) c h
149
- );
150
- border-color: oklch(from var(--esp-color-border) calc(l * 1.2) c h);
151
- }
152
- }
153
145
  }
154
146
 
155
147
  &.incognito {
156
- grid-template-columns: min-content auto;
157
148
  background-color: transparent;
158
149
  border-color: transparent;
159
150
  color: var(--esp-color-text);
@@ -162,17 +153,27 @@ var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnP
162
153
  button,
163
154
  a {
164
155
  > span:nth-child(1) {
165
- grid-column: 2;
166
- justify-content: left;
156
+ justify-content: start;
167
157
  padding: var(--esp-button-incognito-padding, var(--esp-size-tiny)) 0;
168
- padding-right: calc(2 * var(--esp-button-incognito-padding, var(--esp-size-tiny)));
158
+ padding-inline-end: calc(
159
+ 2 * var(--esp-button-incognito-padding, var(--esp-size-tiny))
160
+ );
169
161
  }
170
162
 
171
163
  > span:nth-child(2) {
172
- grid-row: 1;
173
- grid-column: 1;
174
164
  background-color: transparent;
175
- border-color: transparent;
165
+ }
166
+ }
167
+
168
+ &.icon-left {
169
+ button,
170
+ a {
171
+ > span:nth-child(1) {
172
+ padding-inline-start: calc(
173
+ 2 * var(--esp-button-incognito-padding, var(--esp-size-tiny))
174
+ );
175
+ padding-inline-end: 0;
176
+ }
176
177
  }
177
178
  }
178
179
 
@@ -193,17 +194,6 @@ var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnP
193
194
  &:has(button:disabled):hover,
194
195
  &:has(button:disabled):focus-within {
195
196
  background-color: var(--esp-color-action-background);
196
-
197
- button,
198
- a {
199
- > span:nth-child(2) {
200
- background-color: oklch(
201
- from var(--esp-color-action-background)
202
- calc(l * ${g}) c h
203
- );
204
- border-color: var(--esp-color-border);
205
- }
206
- }
207
197
  }
208
198
 
209
199
  svg.rotate {
@@ -223,4 +213,4 @@ var n=function(h,t,i,e){var a=arguments.length,r=a<3?t:e===null?e=Object.getOwnP
223
213
  transform: rotate(360deg);
224
214
  }
225
215
  }
226
- `],n([y()],o.prototype,"innerTabindex",void 0),n([s({attribute:"button-type",type:String})],o.prototype,"buttonType",void 0),n([s({type:Boolean})],o.prototype,"collapsed",void 0),n([s({type:Boolean,reflect:!0})],o.prototype,"disabled",void 0),n([s({type:String})],o.prototype,"href",void 0),n([s({attribute:"icon-only",type:Boolean})],o.prototype,"iconOnly",void 0),n([s({type:Boolean,reflect:!0})],o.prototype,"incognito",void 0),n([s({type:String})],o.prototype,"icon",void 0),n([s({type:String})],o.prototype,"label",void 0),n([s({type:Boolean,reflect:!0})],o.prototype,"loading",void 0),n([s({type:String})],o.prototype,"target",void 0),n([s({type:String})],o.prototype,"rel",void 0),n([s({attribute:"formnovalidate",type:Boolean})],o.prototype,"formNoValidate",void 0),n([v({capture:!1,passive:!0})],o.prototype,"handleClick",null),o=n([m("esp-button")],o);export{o as EspalierButton};
216
+ `],n([v()],e.prototype,"innerTabindex",void 0),n([s({attribute:"button-type",type:String})],e.prototype,"buttonType",void 0),n([s({type:Boolean})],e.prototype,"collapsed",void 0),n([s({type:Boolean,reflect:!0})],e.prototype,"disabled",void 0),n([s({type:String})],e.prototype,"href",void 0),n([s({attribute:"icon-only",type:Boolean})],e.prototype,"iconOnly",void 0),n([s({type:Boolean,reflect:!0})],e.prototype,"incognito",void 0),n([s({type:String})],e.prototype,"icon",void 0),n([s({attribute:"icon-position",type:String})],e.prototype,"iconPosition",void 0),n([s({type:String})],e.prototype,"label",void 0),n([s({type:Boolean,reflect:!0})],e.prototype,"loading",void 0),n([s({type:String})],e.prototype,"target",void 0),n([s({type:String})],e.prototype,"rel",void 0),n([s({attribute:"formnovalidate",type:Boolean})],e.prototype,"formNoValidate",void 0),n([m({capture:!1,passive:!0})],e.prototype,"handleClick",null),e=n([g("esp-button")],e);export{e as EspalierButton};
@@ -33,9 +33,11 @@ import { type EspalierFormField } from "../form-item/esp-form-item.js";
33
33
  *
34
34
  * @slot - Place `esp-checkbox` elements in the default slot.
35
35
  *
36
- * @event {CustomEvent<string[]>} value-changed - Fired when any
36
+ * @event {CustomEvent<string[]>} esp-value-changed - Fired when any
37
37
  * child checkbox state changes. The detail is an array of the
38
38
  * values of all currently checked checkboxes.
39
+ * @event {CustomEvent<{ valid: boolean; message: string }>} esp-validity-changed -
40
+ * Fired whenever constraint validation runs.
39
41
  *
40
42
  * @docPageTitle Checkbox Group
41
43
  * @docUrl /components/checkbox/group
@@ -77,7 +79,7 @@ export declare class EspalierCheckboxGroup extends EspalierElementBase implement
77
79
  * Focus the first non-disabled checkbox in the group.
78
80
  */
79
81
  focus(options?: FocusOptions): void;
80
- /** Re-run constraint validation and dispatch `validity-changed`. */
82
+ /** Re-run constraint validation and dispatch `esp-validity-changed`. */
81
83
  validate(): void;
82
84
  /** Check whether the current state is valid (delegates to ElementInternals). */
83
85
  checkValidity(): boolean;
@@ -1,5 +1,5 @@
1
1
  var o=function(l,e,t,r){var a=arguments.length,i=a<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,h;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(l,e,t,r);else for(var c=l.length-1;c>=0;c--)(h=l[c])&&(i=(a<3?h(i):a>3?h(e,t,i):h(e,t))||i);return a>3&&i&&Object.defineProperty(e,t,i),i};import{css as p,html as m}from"lit";import{customElement as f,property as n}from"lit/decorators.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";import{createRef as u,ref as b}from"lit/directives/ref.js";import{EspalierCheckbox as g}from"./esp-checkbox.js";import{FormFieldController as C}from"../shared/form-field-controller.js";let s=class extends d{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new C({host:this,internals:this.internals,getFormValue:()=>{const e=this.values;return e.length>0?e.join(","):null},getValidity:()=>this.required&&this.values.length===0?{flags:{valueMissing:!0},message:this.requiredMessage||"Please select at least one option."}:null,onReset:()=>{for(const e of this.getCheckboxes())e.checked=!1},onRestore:e=>{const t=e.split(",");for(const r of this.getCheckboxes())r.checked=t.includes(r.value)},onDisabled:e=>{this.disabled=e}}),this.itemsSlot=u(),this.formItemDescription=null,this.describedCheckboxes=new Set,this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1,this.handleItemsSlotChange=()=>{this.applyDisabledState(),this.applyFormItemDescription()}}get values(){return this.getCheckboxes().filter(e=>e.checked).map(e=>e.value)}focus(e){this.focusResolvedElementAfterUpdate(()=>this.getCheckboxes().find(t=>!t.disabled),e)}setFormItemDescription(e){this.formItemDescription=e,this.applyFormItemDescription()}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}getCheckboxes(){return this.itemsSlot.value?Array.from(this.itemsSlot.value.assignedElements()).filter(e=>e instanceof g):[]}applyDisabledState(){for(const e of this.getCheckboxes())e.disabled=this.disabled}applyFormItemDescription(){const e=new Set(this.getCheckboxes());for(const t of this.describedCheckboxes)e.has(t)||t.setFormItemDescription(null);for(const t of e)t.setFormItemDescription(this.formItemDescription);this.describedCheckboxes=e}handleChildChanged(e){e.stopPropagation(),this.formCtrl.syncValue(),this.emitValueChanged(this.values)}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}firstUpdated(e){super.firstUpdated(e),this.applyDisabledState(),this.applyFormItemDescription()}updated(e){super.updated(e),e.has("disabled")&&this.applyDisabledState()}render(){return m`
2
- <div class="checkbox-group" role="group" @value-changed=${this.handleChildChanged}>
2
+ <div class="checkbox-group" role="group" @esp-value-changed=${this.handleChildChanged}>
3
3
  <slot ${b(this.itemsSlot)} @slotchange=${this.handleItemsSlotChange}></slot>
4
4
  </div>
5
5
  `}};s.formAssociated=!0,s.styles=[...d.styles,p`
@@ -33,9 +33,11 @@ import { type EspalierFormField } from "../form-item/esp-form-item.js";
33
33
  *
34
34
  * @slot - The label text for the checkbox.
35
35
  *
36
- * @event {CustomEvent<{ checked: boolean; value: string }>} value-changed -
36
+ * @event {CustomEvent<{ checked: boolean; value: string }>} esp-value-changed -
37
37
  * Fired when the checkbox is toggled. The detail contains the new
38
38
  * `checked` state and the checkbox `value`.
39
+ * @event {CustomEvent<{ valid: boolean; message: string }>} esp-validity-changed -
40
+ * Fired whenever constraint validation runs.
39
41
  *
40
42
  * @cssprop --esp-checkbox-size - The width and height of the
41
43
  * checkbox icon. Defaults to `var(--esp-size-normal-to-medium)`.
@@ -102,7 +104,7 @@ export declare class EspalierCheckbox extends EspalierElementBase implements Esp
102
104
  * Focus the checkbox control.
103
105
  */
104
106
  focus(options?: FocusOptions): void;
105
- /** Re-run constraint validation and dispatch `validity-changed`. */
107
+ /** Re-run constraint validation and dispatch `esp-validity-changed`. */
106
108
  validate(): void;
107
109
  /** Check whether the current state is valid (delegates to ElementInternals). */
108
110
  checkValidity(): boolean;
@@ -9,7 +9,7 @@ export type ColorPickerMode = "hc" | "hcl";
9
9
  * needs to tune hue, chroma, and lightness directly.
10
10
  *
11
11
  * @customElement esp-color-picker
12
- * @event {CustomEvent<{ seedColor: string, hue: number, chroma: number, lightness: number }>} value-changed - Fired
12
+ * @event {CustomEvent<{ seedColor: string, hue: number, chroma: number, lightness: number }>} esp-value-changed - Fired
13
13
  * when the user changes the color. The event detail contains the seed
14
14
  * color OKLCH string, plus raw hue, chroma, and lightness values.
15
15
  *
@@ -30,7 +30,7 @@ export type ColorPickerMode = "hc" | "hcl";
30
30
  * colorPicker.chroma = Math.round(+parts[2] * 100);
31
31
  * }
32
32
  *
33
- * colorPicker.addEventListener("value-changed", (event) => {
33
+ * colorPicker.addEventListener("esp-value-changed", (event) => {
34
34
  * const { seedColor } = event.detail;
35
35
  * localStorage.setItem("esp-seed-color", seedColor);
36
36
  * espRoot.setAttribute("seed-color", seedColor);
@@ -1,4 +1,4 @@
1
- var a=function(r,e,t,i){var s=arguments.length,o=s<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,h;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(r,e,t,i);else for(var d=r.length-1;d>=0;d--)(h=r[d])&&(o=(s<3?h(o):s>3?h(e,t,o):h(e,t))||o);return s>3&&o&&Object.defineProperty(e,t,o),o};import{LitElement as g,css as b,html as m,nothing as f,unsafeCSS as $}from"lit";import{customElement as y,property as n}from"lit/decorators.js";import{classMap as w}from"lit/directives/class-map.js";import{createRef as u,ref as p}from"lit/directives/ref.js";import{styleMap as k}from"lit/directives/style-map.js";const v=70;let c="linear-gradient(to right,";for(let r=0;r<361;r++)c+=`oklch(${v}% 0.25 ${r}),`;c=c.slice(0,-1)+")";const x=r=>Number((r/100).toFixed(4)).toString();let l=class extends g{constructor(){super(...arguments),this.hueInput=u(),this.chromaInput=u(),this.lightnessInput=u(),this.mode="hc",this.chroma=25,this.hue=180,this.lightness=v,this.changed=()=>{const{hue:e,chroma:t,lightness:i}=this,s=`oklch(${x(i)} ${(t/100).toFixed(4)} ${e})`;this.dispatchEvent(new CustomEvent("value-changed",{detail:{seedColor:s,hue:e,chroma:t,lightness:i},bubbles:!0,composed:!0}))}}render(){const{hue:e,chroma:t,lightness:i}=this,s={"--selected-hue":e,"--selected-chroma":t,"--selected-lightness":`${i}%`};return m`
1
+ var a=function(r,e,t,i){var s=arguments.length,o=s<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,h;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(r,e,t,i);else for(var d=r.length-1;d>=0;d--)(h=r[d])&&(o=(s<3?h(o):s>3?h(e,t,o):h(e,t))||o);return s>3&&o&&Object.defineProperty(e,t,o),o};import{LitElement as g,css as b,html as m,nothing as f,unsafeCSS as $}from"lit";import{customElement as y,property as n}from"lit/decorators.js";import{classMap as w}from"lit/directives/class-map.js";import{createRef as p,ref as u}from"lit/directives/ref.js";import{styleMap as k}from"lit/directives/style-map.js";import{ESP_EVENTS as x}from"../shared/events.js";const v=70;let c="linear-gradient(to right,";for(let r=0;r<361;r++)c+=`oklch(${v}% 0.25 ${r}),`;c=c.slice(0,-1)+")";const E=r=>Number((r/100).toFixed(4)).toString();let l=class extends g{constructor(){super(...arguments),this.hueInput=p(),this.chromaInput=p(),this.lightnessInput=p(),this.mode="hc",this.chroma=25,this.hue=180,this.lightness=v,this.changed=()=>{const{hue:e,chroma:t,lightness:i}=this,s=`oklch(${E(i)} ${(t/100).toFixed(4)} ${e})`;this.dispatchEvent(new CustomEvent(x.VALUE_CHANGED,{detail:{seedColor:s,hue:e,chroma:t,lightness:i},bubbles:!0,composed:!0}))}}render(){const{hue:e,chroma:t,lightness:i}=this,s={"--selected-hue":e,"--selected-chroma":t,"--selected-lightness":`${i}%`};return m`
2
2
  <div
3
3
  class=${w({"esp-color-picker":!0,hcl:this.mode==="hcl"})}
4
4
  style=${k(s)}
@@ -7,7 +7,7 @@ var a=function(r,e,t,i){var s=arguments.length,o=s<3?e:i===null?i=Object.getOwnP
7
7
  <div class="hue">
8
8
  <label for="hue-slider">Hue <span class="value">${this.hue}°</span></label>
9
9
  <input
10
- ${p(this.hueInput)}
10
+ ${u(this.hueInput)}
11
11
  id="hue-slider"
12
12
  type="range"
13
13
  min="0"
@@ -21,7 +21,7 @@ var a=function(r,e,t,i){var s=arguments.length,o=s<3?e:i===null?i=Object.getOwnP
21
21
  >Chroma <span class="value">${(this.chroma/100).toFixed(3)}</span></label
22
22
  >
23
23
  <input
24
- ${p(this.chromaInput)}
24
+ ${u(this.chromaInput)}
25
25
  id="chroma-slider"
26
26
  type="range"
27
27
  min="0"
@@ -35,7 +35,7 @@ var a=function(r,e,t,i){var s=arguments.length,o=s<3?e:i===null?i=Object.getOwnP
35
35
  >Lightness <span class="value">${this.lightness}%</span></label
36
36
  >
37
37
  <input
38
- ${p(this.lightnessInput)}
38
+ ${u(this.lightnessInput)}
39
39
  id="lightness-slider"
40
40
  type="range"
41
41
  min="0"