@m3e/web 2.5.9 → 2.5.11

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 (96) hide show
  1. package/dist/all.js +299 -96
  2. package/dist/all.js.map +1 -1
  3. package/dist/all.min.js +14 -14
  4. package/dist/all.min.js.map +1 -1
  5. package/dist/breadcrumb.js +1 -1
  6. package/dist/breadcrumb.js.map +1 -1
  7. package/dist/breadcrumb.min.js +1 -1
  8. package/dist/breadcrumb.min.js.map +1 -1
  9. package/dist/button-group.js +9 -2
  10. package/dist/button-group.js.map +1 -1
  11. package/dist/button-group.min.js +1 -1
  12. package/dist/button-group.min.js.map +1 -1
  13. package/dist/button.js +17 -11
  14. package/dist/button.js.map +1 -1
  15. package/dist/button.min.js +1 -1
  16. package/dist/button.min.js.map +1 -1
  17. package/dist/checkbox.js +5 -0
  18. package/dist/checkbox.js.map +1 -1
  19. package/dist/checkbox.min.js +1 -1
  20. package/dist/checkbox.min.js.map +1 -1
  21. package/dist/chips.js +2 -2
  22. package/dist/chips.js.map +1 -1
  23. package/dist/chips.min.js +1 -1
  24. package/dist/chips.min.js.map +1 -1
  25. package/dist/css-custom-data.json +5283 -5253
  26. package/dist/custom-elements.json +49983 -49091
  27. package/dist/fab.js +9 -9
  28. package/dist/fab.js.map +1 -1
  29. package/dist/fab.min.js +1 -1
  30. package/dist/fab.min.js.map +1 -1
  31. package/dist/form-field.js +4 -5
  32. package/dist/form-field.js.map +1 -1
  33. package/dist/form-field.min.js +1 -1
  34. package/dist/form-field.min.js.map +1 -1
  35. package/dist/html-custom-data.json +1691 -1664
  36. package/dist/icon-button.js +52 -46
  37. package/dist/icon-button.js.map +1 -1
  38. package/dist/icon-button.min.js +1 -1
  39. package/dist/icon-button.min.js.map +1 -1
  40. package/dist/menu.js +2 -2
  41. package/dist/menu.js.map +1 -1
  42. package/dist/menu.min.js +1 -1
  43. package/dist/menu.min.js.map +1 -1
  44. package/dist/option.js +1 -1
  45. package/dist/option.js.map +1 -1
  46. package/dist/option.min.js +1 -1
  47. package/dist/option.min.js.map +1 -1
  48. package/dist/paginator.js +1 -1
  49. package/dist/paginator.js.map +1 -1
  50. package/dist/paginator.min.js +2 -2
  51. package/dist/paginator.min.js.map +1 -1
  52. package/dist/radio-group.js +6 -1
  53. package/dist/radio-group.js.map +1 -1
  54. package/dist/radio-group.min.js +1 -1
  55. package/dist/radio-group.min.js.map +1 -1
  56. package/dist/split-button.js +1 -1
  57. package/dist/split-button.js.map +1 -1
  58. package/dist/split-button.min.js +1 -1
  59. package/dist/split-button.min.js.map +1 -1
  60. package/dist/src/button/ButtonElement.d.ts +1 -0
  61. package/dist/src/button/ButtonElement.d.ts.map +1 -1
  62. package/dist/src/button/styles/ButtonStyle.d.ts.map +1 -1
  63. package/dist/src/button-group/ButtonGroupElement.d.ts.map +1 -1
  64. package/dist/src/checkbox/CheckboxElement.d.ts.map +1 -1
  65. package/dist/src/fab/styles/FabSizeToken.d.ts.map +1 -1
  66. package/dist/src/form-field/FormFieldElement.d.ts.map +1 -1
  67. package/dist/src/icon-button/IconButtonElement.d.ts +1 -0
  68. package/dist/src/icon-button/IconButtonElement.d.ts.map +1 -1
  69. package/dist/src/icon-button/styles/IconButtonSizeStyle.d.ts.map +1 -1
  70. package/dist/src/icon-button/styles/IconButtonSizeToken.d.ts.map +1 -1
  71. package/dist/src/icon-button/styles/IconButtonStyle.d.ts.map +1 -1
  72. package/dist/src/menu/MenuElement.d.ts.map +1 -1
  73. package/dist/src/menu/MenuItemElementBase.d.ts.map +1 -1
  74. package/dist/src/option/OptionElement.d.ts.map +1 -1
  75. package/dist/src/paginator/PaginatorElement.d.ts.map +1 -1
  76. package/dist/src/radio-group/RadioElement.d.ts.map +1 -1
  77. package/dist/src/split-button/SplitButtonElement.d.ts.map +1 -1
  78. package/dist/src/switch/SwitchElement.d.ts.map +1 -1
  79. package/dist/src/switch/styles/SwitchToken.d.ts.map +1 -1
  80. package/dist/src/theme/ThemeElement.d.ts +6 -0
  81. package/dist/src/theme/ThemeElement.d.ts.map +1 -1
  82. package/dist/src/theme/ThemeIconElement.d.ts +60 -0
  83. package/dist/src/theme/ThemeIconElement.d.ts.map +1 -0
  84. package/dist/src/theme/ThemeVariant.d.ts +3 -0
  85. package/dist/src/theme/ThemeVariant.d.ts.map +1 -0
  86. package/dist/src/theme/index.d.ts +2 -0
  87. package/dist/src/theme/index.d.ts.map +1 -1
  88. package/dist/switch.js +16 -11
  89. package/dist/switch.js.map +1 -1
  90. package/dist/switch.min.js +1 -1
  91. package/dist/switch.min.js.map +1 -1
  92. package/dist/theme.js +174 -4
  93. package/dist/theme.js.map +1 -1
  94. package/dist/theme.min.js +31 -31
  95. package/dist/theme.min.js.map +1 -1
  96. package/package.json +1 -1
@@ -3,5 +3,5 @@
3
3
  * Copyright (c) 2025–2026 matraic
4
4
  * See LICENSE file in the project root for full license text.
5
5
  */
6
- import{__classPrivateFieldGet as e,__decorate as t}from"tslib";import{LitElement as s,html as a,css as r}from"lit";import{query as n,property as o,queryAssignedElements as i}from"lit/decorators.js";import{Role as l,PressedController as d,setCustomState as c,addCustomState as u,isSelectedMixin as p,prefersReducedMotion as h,hasCustomState as m,DesignToken as g,customElement as b}from"@m3e/web/core";var v,f,x,z,_,$;let y=class extends(l(s,"group")){constructor(){super(...arguments),v.add(this),f.set(this,new d(this,{target:null,capture:!0,minPressedDuration:150,isPressedKey:e=>" "===e,callback:t=>e(this,v,"m",_).call(this,t)})),this.variant="standard",this.size="small",this.multi=!1}connectedCallback(){super.connectedCallback(),this.hasAttribute("disable-role")&&(this.role=null)}disconnectedCallback(){super.disconnectedCallback(),this._base?.style.removeProperty("--_button-group-width"),this._base?.classList.remove("pressed")}update(t){super.update(t),(t.has("multi")||t.has("variant"))&&e(this,v,"m",x).call(this),t.has("variant")&&this._base?.style.removeProperty("--_button-group-width")}render(){return a`<div class="base"><slot @slotchange="${e(this,v,"m",x)}" @change="${e(this,v,"m",z)}"></slot></div>`}};f=new WeakMap,v=new WeakSet,x=function(){const t=this.buttons;for(const t of e(this,f,"f").targets)e(this,f,"f").unobserve(t);const s=[...t].some(e=>e.toggle);this.hasAttribute("disable-role")||(this.role=s&&!this.multi?"radiogroup":"group");const a="radiogroup"===this.role?"radio":"button";t.forEach((s,r)=>{if(e(this,f,"f").observe(s),c(s,"--connected","connected"===this.variant),u(s,"--grouped"),c(s,"--first",0==r),c(s,"--last",r==t.length-1),!this.hasAttribute("disable-role")&&s.role!==a&&s.toggle){const e=s.toggle?s.selected?"true":"false":null;s.role=a,"button"===s.role?(s.ariaPressed=e,s.ariaChecked=null):(s.ariaChecked=e,s.ariaPressed=null)}})},z=function(e){if(!this.multi&&e.target instanceof HTMLElement&&("M3E-BUTTON"===e.target.tagName||"M3E-ICON-BUTTON"===e.target.tagName)){if(!p(e.target)||!e.target.selected)return;for(const t of this.buttons)t!==e.target&&t.selected&&(t.selected=!1)}},_=function(t){const s=this._base;if(s)if(t&&"connected"!==this.variant)s.classList.add("pressed"),s.style.setProperty("--_button-group-width",`${s.getBoundingClientRect().width}px`);else{const t=this.buttons.find(e=>e===document.activeElement);!h()&&t?t.addEventListener("transitionend",()=>queueMicrotask(()=>{m(t,"--pressed")||e(this,v,"m",$).call(this,s)}),{once:!0}):e(this,v,"m",$).call(this,s)}},$=function(e){e.style.removeProperty("--_button-group-width"),e.classList.remove("pressed")},y.styles=r`:host { display: flex; vertical-align: middle; flex-wrap: nowrap; align-items: center; } .base { display: flex; vertical-align: middle; flex-wrap: nowrap; align-items: center; } :host([variant="standard"]) { justify-content: center; } :host([variant="connected"]) .base { flex: 1 1 auto; } :host([variant="standard"]) .base { width: fit-content; flex: none; } :host([variant="standard"]) .base.pressed { justify-content: space-between; width: var(--_button-group-width); } :host([variant="standard"][size="extra-small"]) .base { column-gap: var(--m3e-standard-button-group-extra-small-spacing, 1.125rem); } :host([variant="standard"][size="small"]) .base { column-gap: var(--m3e-standard-button-group-small-spacing, 0.75rem); } :host([variant="standard"][size="medium"]).base { column-gap: var(--m3e-standard-button-group-medium-spacing, 0.5rem); } :host([variant="standard"][size="large"]) .base { column-gap: var(--m3e-standard-button-group-large-spacing, 0.5rem); } :host([variant="standard"][size="extra-large"]) .base { column-gap: var(--m3e-standard-button-group-extra-large-spacing, 0.5rem); } :host([variant="connected"]) .base { column-gap: var(--m3e-connected-button-group-spacing, 0.125rem); } :host([variant="connected"][size="extra-small"]) ::slotted(:is(:state(--first), :--first)[size="extra-small"]), :host([variant="connected"][size="extra-small"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="extra-small"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-extra-small-inner-shape, ${g.shape.corner.small} ); --_button-square-end-shape: var( --m3e-connected-button-group-extra-small-inner-shape, ${g.shape.corner.small} ); --_button-square-end-pressed-shape: var( --m3e-connected-button-group-extra-small-inner-pressed-shape, ${g.shape.corner.extraSmall} ); } :host([variant="connected"][size="extra-small"]) ::slotted(:is(:state(--last), :--last)[size="extra-small"]), :host([variant="connected"][size="extra-small"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="extra-small"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-extra-small-inner-shape, ${g.shape.corner.small} ); --_button-square-start-shape: var( --m3e-connected-button-group-extra-small-inner-shape, ${g.shape.corner.small} ); --_button-square-start-pressed-shape: var( --m3e-connected-button-group-extra-small-inner-pressed-shape, ${g.shape.corner.extraSmall} ); } :host([variant="connected"][size="small"]) ::slotted(:is(:state(--first), :--first)[size="small"]), :host([variant="connected"][size="small"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="small"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-small-inner-shape, ${g.shape.corner.small} ); --_button-square-end-shape: var( --m3e-connected-button-group-small-inner-shape, ${g.shape.corner.small} ); --_button-end-shape-pressed-morph: var( --m3e-connected-button-group-small-inner-pressed-shape, ${g.shape.corner.extraSmall} ); } :host([variant="connected"][size="small"]) ::slotted(:is(:state(--last), :--last)[size="small"]), :host([variant="connected"][size="small"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="small"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-small-inner-shape, ${g.shape.corner.small} ); --_button-square-start-shape: var( --m3e-connected-button-group-small-inner-shape, ${g.shape.corner.small} ); --_button-start-shape-pressed-morph: var( --m3e-connected-button-group-small-inner-pressed-shape, ${g.shape.corner.extraSmall} ); } :host([variant="connected"][size="medium"]) ::slotted(:is(:state(--first), :--first)[size="medium"]), :host([variant="connected"][size="medium"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="medium"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-medium-inner-shape, ${g.shape.corner.small} ); --_button-square-end-shape: var( --m3e-connected-button-group-medium-inner-shape, ${g.shape.corner.small} ); --_button-square-end-pressed-shape: var( --m3e-connected-button-group-medium-inner-pressed-shape, ${g.shape.corner.extraSmall} ); } :host([variant="connected"][size="medium"]) ::slotted(:is(:state(--last), :--last)[size="medium"]), :host([variant="connected"][size="medium"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="medium"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-medium-inner-shape, ${g.shape.corner.small} ); --_button-square-start-shape: var( --m3e-connected-button-group-medium-inner-shape, ${g.shape.corner.small} ); --_button-square-start-pressed-shape: var( --m3e-connected-button-group-medium-inner-pressed-shape, ${g.shape.corner.extraSmall} ); } :host([variant="connected"][size="large"]) ::slotted(:is(:state(--first), :--first)[size="large"]), :host([variant="connected"][size="large"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="large"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-large-inner-shape, ${g.shape.corner.large} ); --_button-square-end-shape: var( --m3e-connected-button-group-large-inner-shape, ${g.shape.corner.large} ); --_button-square-end-pressed-shape: var( --m3e-connected-button-group-large-inner-pressed-shape, ${g.shape.corner.medium} ); } :host([variant="connected"][size="large"]) ::slotted(:is(:state(--last), :--last)[size="large"]), :host([variant="connected"][size="large"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="large"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-large-inner-shape, ${g.shape.corner.large} ); --_button-square-start-shape: var( --m3e-connected-button-group-large-inner-shape, ${g.shape.corner.large} ); --_button-square-start-pressed-shape: var( --m3e-connected-button-group-large-inner-pressed-shape, ${g.shape.corner.medium} ); } :host([variant="connected"][size="extra-large"]) ::slotted(:is(:state(--first), :--first)[size="extra-large"]), :host([variant="connected"][size="extra-large"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="extra-large"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-extra-large-inner-shape, ${g.shape.corner.largeIncreased} ); --_button-square-end-shape: var( --m3e-connected-button-group-extra-large-inner-shape, ${g.shape.corner.largeIncreased} ); --_button-square-end-pressed-shape: var( --m3e-connected-button-group-extra-large-inner-pressed-shape, ${g.shape.corner.large} ); } :host([variant="connected"][size="extra-large"]) ::slotted(:is(:state(--last), :--last)[size="extra-large"]), :host([variant="connected"][size="extra-large"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="extra-large"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-extra-large-inner-shape, ${g.shape.corner.largeIncreased} ); --_button-square-start-shape: var( --m3e-connected-button-group-extra-large-inner-shape, ${g.shape.corner.largeIncreased} ); --_button-square-start-pressed-shape: var( --m3e-connected-button-group-extra-large-inner-pressed-shape, ${g.shape.corner.large} ); }`,t([n(".base")],y.prototype,"_base",void 0),t([o({reflect:!0})],y.prototype,"variant",void 0),t([o({reflect:!0})],y.prototype,"size",void 0),t([o({type:Boolean})],y.prototype,"multi",void 0),t([i({slot:"",selector:"m3e-button,m3e-icon-button",flatten:!0})],y.prototype,"buttons",void 0),y=t([b("m3e-button-group")],y);export{y as M3eButtonGroupElement};
6
+ import{__classPrivateFieldGet as e,__decorate as t}from"tslib";import{LitElement as s,html as a,css as r}from"lit";import{query as n,property as o,queryAssignedElements as i}from"lit/decorators.js";import{Role as l,PressedController as d,waitForUpgrade as c,setCustomState as u,addCustomState as p,isSelectedMixin as h,prefersReducedMotion as m,hasCustomState as g,DesignToken as b,customElement as v}from"@m3e/web/core";var f,x,z,_,$,y;let q=class extends(l(s,"group")){constructor(){super(...arguments),f.add(this),x.set(this,new d(this,{target:null,capture:!0,minPressedDuration:150,isPressedKey:e=>" "===e,callback:t=>e(this,f,"m",$).call(this,t)})),this.variant="standard",this.size="small",this.multi=!1}connectedCallback(){super.connectedCallback(),this.hasAttribute("disable-role")&&(this.role=null)}disconnectedCallback(){super.disconnectedCallback(),this._base?.style.removeProperty("--_button-group-width"),this._base?.classList.remove("pressed")}update(t){super.update(t),(t.has("multi")||t.has("variant"))&&e(this,f,"m",z).call(this),t.has("variant")&&this._base?.style.removeProperty("--_button-group-width")}render(){return a`<div class="base"><slot @slotchange="${e(this,f,"m",z)}" @change="${e(this,f,"m",_)}"></slot></div>`}};x=new WeakMap,f=new WeakSet,z=async function(){const t=this.buttons;for(const t of e(this,x,"f").targets)e(this,x,"f").unobserve(t);for(const e of this.buttons)await c(e),e.isUpdatePending&&await e.updateComplete;const s=[...t].some(e=>e.toggle);this.hasAttribute("disable-role")||(this.role=s&&!this.multi?"radiogroup":"group");const a="radiogroup"===this.role?"radio":"button";t.forEach((s,r)=>{if(e(this,x,"f").observe(s),u(s,"--connected","connected"===this.variant),p(s,"--grouped"),u(s,"--first",0==r),u(s,"--last",r==t.length-1),!this.hasAttribute("disable-role")&&s.role!==a&&s.toggle){const e=s.toggle?s.selected?"true":"false":null;s.role=a,"button"===s.role?(s.ariaPressed=e,s.ariaChecked=null):(s.ariaChecked=e,s.ariaPressed=null)}})},_=function(e){if(!this.multi&&e.target instanceof HTMLElement&&("M3E-BUTTON"===e.target.tagName||"M3E-ICON-BUTTON"===e.target.tagName)){if(!h(e.target)||!e.target.selected)return;for(const t of this.buttons)t!==e.target&&t.selected&&(t.selected=!1)}},$=function(t){const s=this._base;if(s)if(t&&"connected"!==this.variant)s.classList.add("pressed"),s.style.setProperty("--_button-group-width",`${s.getBoundingClientRect().width}px`);else{const t=this.buttons.find(e=>e===document.activeElement);!m()&&t?t.addEventListener("transitionend",()=>queueMicrotask(()=>{g(t,"--pressed")||e(this,f,"m",y).call(this,s)}),{once:!0}):e(this,f,"m",y).call(this,s)}},y=function(e){e.style.removeProperty("--_button-group-width"),e.classList.remove("pressed")},q.styles=r`:host { display: flex; vertical-align: middle; flex-wrap: nowrap; align-items: center; } .base { display: flex; vertical-align: middle; flex-wrap: nowrap; align-items: center; } :host([variant="standard"]) { justify-content: center; } :host([variant="connected"]) .base { flex: 1 1 auto; } :host([variant="standard"]) .base { width: fit-content; flex: none; } :host([variant="standard"]) .base.pressed { justify-content: space-between; width: var(--_button-group-width); } :host([variant="standard"][size="extra-small"]) .base { column-gap: var(--m3e-standard-button-group-extra-small-spacing, 1.125rem); } :host([variant="standard"][size="small"]) .base { column-gap: var(--m3e-standard-button-group-small-spacing, 0.75rem); } :host([variant="standard"][size="medium"]).base { column-gap: var(--m3e-standard-button-group-medium-spacing, 0.5rem); } :host([variant="standard"][size="large"]) .base { column-gap: var(--m3e-standard-button-group-large-spacing, 0.5rem); } :host([variant="standard"][size="extra-large"]) .base { column-gap: var(--m3e-standard-button-group-extra-large-spacing, 0.5rem); } :host([variant="connected"]) .base { column-gap: var(--m3e-connected-button-group-spacing, 0.125rem); } :host([variant="connected"][size="extra-small"]) ::slotted(:is(:state(--first), :--first)[size="extra-small"]), :host([variant="connected"][size="extra-small"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="extra-small"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-extra-small-inner-shape, ${b.shape.corner.small} ); --_button-square-end-shape: var( --m3e-connected-button-group-extra-small-inner-shape, ${b.shape.corner.small} ); --_button-square-end-pressed-shape: var( --m3e-connected-button-group-extra-small-inner-pressed-shape, ${b.shape.corner.extraSmall} ); } :host([variant="connected"][size="extra-small"]) ::slotted(:is(:state(--last), :--last)[size="extra-small"]), :host([variant="connected"][size="extra-small"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="extra-small"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-extra-small-inner-shape, ${b.shape.corner.small} ); --_button-square-start-shape: var( --m3e-connected-button-group-extra-small-inner-shape, ${b.shape.corner.small} ); --_button-square-start-pressed-shape: var( --m3e-connected-button-group-extra-small-inner-pressed-shape, ${b.shape.corner.extraSmall} ); } :host([variant="connected"][size="small"]) ::slotted(:is(:state(--first), :--first)[size="small"]), :host([variant="connected"][size="small"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="small"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-small-inner-shape, ${b.shape.corner.small} ); --_button-square-end-shape: var( --m3e-connected-button-group-small-inner-shape, ${b.shape.corner.small} ); --_button-end-shape-pressed-morph: var( --m3e-connected-button-group-small-inner-pressed-shape, ${b.shape.corner.extraSmall} ); } :host([variant="connected"][size="small"]) ::slotted(:is(:state(--last), :--last)[size="small"]), :host([variant="connected"][size="small"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="small"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-small-inner-shape, ${b.shape.corner.small} ); --_button-square-start-shape: var( --m3e-connected-button-group-small-inner-shape, ${b.shape.corner.small} ); --_button-start-shape-pressed-morph: var( --m3e-connected-button-group-small-inner-pressed-shape, ${b.shape.corner.extraSmall} ); } :host([variant="connected"][size="medium"]) ::slotted(:is(:state(--first), :--first)[size="medium"]), :host([variant="connected"][size="medium"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="medium"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-medium-inner-shape, ${b.shape.corner.small} ); --_button-square-end-shape: var( --m3e-connected-button-group-medium-inner-shape, ${b.shape.corner.small} ); --_button-square-end-pressed-shape: var( --m3e-connected-button-group-medium-inner-pressed-shape, ${b.shape.corner.extraSmall} ); } :host([variant="connected"][size="medium"]) ::slotted(:is(:state(--last), :--last)[size="medium"]), :host([variant="connected"][size="medium"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="medium"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-medium-inner-shape, ${b.shape.corner.small} ); --_button-square-start-shape: var( --m3e-connected-button-group-medium-inner-shape, ${b.shape.corner.small} ); --_button-square-start-pressed-shape: var( --m3e-connected-button-group-medium-inner-pressed-shape, ${b.shape.corner.extraSmall} ); } :host([variant="connected"][size="large"]) ::slotted(:is(:state(--first), :--first)[size="large"]), :host([variant="connected"][size="large"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="large"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-large-inner-shape, ${b.shape.corner.large} ); --_button-square-end-shape: var( --m3e-connected-button-group-large-inner-shape, ${b.shape.corner.large} ); --_button-square-end-pressed-shape: var( --m3e-connected-button-group-large-inner-pressed-shape, ${b.shape.corner.medium} ); } :host([variant="connected"][size="large"]) ::slotted(:is(:state(--last), :--last)[size="large"]), :host([variant="connected"][size="large"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="large"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-large-inner-shape, ${b.shape.corner.large} ); --_button-square-start-shape: var( --m3e-connected-button-group-large-inner-shape, ${b.shape.corner.large} ); --_button-square-start-pressed-shape: var( --m3e-connected-button-group-large-inner-pressed-shape, ${b.shape.corner.medium} ); } :host([variant="connected"][size="extra-large"]) ::slotted(:is(:state(--first), :--first)[size="extra-large"]), :host([variant="connected"][size="extra-large"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="extra-large"]) { --_button-rounded-end-shape: var( --m3e-connected-button-group-extra-large-inner-shape, ${b.shape.corner.largeIncreased} ); --_button-square-end-shape: var( --m3e-connected-button-group-extra-large-inner-shape, ${b.shape.corner.largeIncreased} ); --_button-square-end-pressed-shape: var( --m3e-connected-button-group-extra-large-inner-pressed-shape, ${b.shape.corner.large} ); } :host([variant="connected"][size="extra-large"]) ::slotted(:is(:state(--last), :--last)[size="extra-large"]), :host([variant="connected"][size="extra-large"]) ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size="extra-large"]) { --_button-rounded-start-shape: var( --m3e-connected-button-group-extra-large-inner-shape, ${b.shape.corner.largeIncreased} ); --_button-square-start-shape: var( --m3e-connected-button-group-extra-large-inner-shape, ${b.shape.corner.largeIncreased} ); --_button-square-start-pressed-shape: var( --m3e-connected-button-group-extra-large-inner-pressed-shape, ${b.shape.corner.large} ); }`,t([n(".base")],q.prototype,"_base",void 0),t([o({reflect:!0})],q.prototype,"variant",void 0),t([o({reflect:!0})],q.prototype,"size",void 0),t([o({type:Boolean})],q.prototype,"multi",void 0),t([i({slot:"",selector:"m3e-button,m3e-icon-button",flatten:!0})],q.prototype,"buttons",void 0),q=t([v("m3e-button-group")],q);export{q as M3eButtonGroupElement};
7
7
  //# sourceMappingURL=button-group.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"button-group.min.js","sources":["../../src/button-group/ButtonGroupElement.ts"],"sourcesContent":["import { css, CSSResultGroup, html, LitElement, PropertyValues } from \"lit\";\r\nimport { property, query, queryAssignedElements } from \"lit/decorators.js\";\r\n\r\nimport {\r\n PressedController,\r\n Role,\r\n isSelectedMixin,\r\n DesignToken,\r\n setCustomState,\r\n addCustomState,\r\n customElement,\r\n prefersReducedMotion,\r\n hasCustomState,\r\n} from \"@m3e/web/core\";\r\n\r\nimport { M3eButtonElement } from \"@m3e/web/button\";\r\nimport { M3eIconButtonElement } from \"@m3e/web/icon-button\";\r\n\r\nimport { ButtonGroupVariant } from \"./ButtonGroupVariant\";\r\nimport { ButtonGroupSize } from \"./ButtonGroupSize\";\r\n\r\n/**\r\n * Organizes buttons and adds interactions between them.\r\n *\r\n * @description\r\n * The `m3e-button-group` component arranges multiple buttons into a unified, expressive layout,\r\n * supporting both `standard` and `connected` variants. It enables seamless, accessible grouping\r\n * of actions, adapts to various sizes, and ensures consistent spacing, shape, and alignment.\r\n * Designed according to Material 3 principles, it empowers users to interact with related actions\r\n * in a visually harmonious and intuitive way.\r\n *\r\n * @example\r\n * The following example illustrates a standard button group.\r\n * ``` html\r\n * <m3e-button-group>\r\n * <m3e-icon-button variant=\"tonal\" toggle><m3e-icon name=\"format_bold\"></m3e-icon></m3e-icon-button>\r\n * <m3e-icon-button variant=\"tonal\" toggle><m3e-icon name=\"format_italic\"></m3e-icon></m3e-icon-button>\r\n * <m3e-icon-button variant=\"tonal\" toggle><m3e-icon name=\"format_underlined\"></m3e-icon></m3e-icon-button>\r\n * </m3e-button-group>\r\n * ```\r\n * @example\r\n * The next example illustrates a connected button group.\r\n * ```html\r\n * <m3e-button-group variant=\"connected\">\r\n * <m3e-button variant=\"tonal\" shape=\"square\" toggle>Start</m3e-button>\r\n * <m3e-button variant=\"tonal\" shape=\"square\" toggle>Directions</m3e-button>\r\n * <m3e-button variant=\"tonal\" shape=\"square\" toggle>Share</m3e-button>\r\n * </m3e-button-group>\r\n * ```\r\n *\r\n * @tag m3e-button-group\r\n *\r\n * @slot - Renders the buttons of the group.\r\n *\r\n * @attr multi - Whether multiple toggle buttons can be selected.\r\n * @attr size - The size of the group.\r\n * @attr variant - The appearance variant of the group.\r\n *\r\n * @cssprop --m3e-standard-button-group-extra-small-spacing - Spacing between buttons in standard variant, extra-small size.\r\n * @cssprop --m3e-standard-button-group-small-spacing - Spacing between buttons in standard variant, small size.\r\n * @cssprop --m3e-standard-button-group-medium-spacing - Spacing between buttons in standard variant, medium size.\r\n * @cssprop --m3e-standard-button-group-large-spacing - Spacing between buttons in standard variant, large size.\r\n * @cssprop --m3e-standard-button-group-extra-large-spacing - Spacing between buttons in standard variant, extra-large size.\r\n * @cssprop --m3e-connected-button-group-spacing - Spacing between buttons in connected variant.\r\n * @cssprop --m3e-connected-button-group-extra-small-inner-shape - Corner shape for connected variant, extra-small size.\r\n * @cssprop --m3e-connected-button-group-extra-small-inner-pressed-shape - Pressed corner shape for connected variant, extra-small size.\r\n * @cssprop --m3e-connected-button-group-small-inner-shape - Corner shape for connected variant, small size.\r\n * @cssprop --m3e-connected-button-group-small-inner-pressed-shape - Pressed corner shape for connected variant, small size.\r\n * @cssprop --m3e-connected-button-group-medium-inner-shape - Corner shape for connected variant, medium size.\r\n * @cssprop --m3e-connected-button-group-medium-inner-pressed-shape - Pressed corner shape for connected variant, medium size.\r\n * @cssprop --m3e-connected-button-group-large-inner-shape - Corner shape for connected variant, large size.\r\n * @cssprop --m3e-connected-button-group-large-inner-pressed-shape - Pressed corner shape for connected variant, large size.\r\n * @cssprop --m3e-connected-button-group-extra-large-inner-shape - Corner shape for connected variant, extra-large size.\r\n * @cssprop --m3e-connected-button-group-extra-large-inner-pressed-shape - Pressed corner shape for connected variant, extra-large size.\r\n */\r\n@customElement(\"m3e-button-group\")\r\nexport class M3eButtonGroupElement extends Role(LitElement, \"group\") {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: flex;\r\n vertical-align: middle;\r\n flex-wrap: nowrap;\r\n align-items: center;\r\n }\r\n .base {\r\n display: flex;\r\n vertical-align: middle;\r\n flex-wrap: nowrap;\r\n align-items: center;\r\n }\r\n :host([variant=\"standard\"]) {\r\n justify-content: center;\r\n }\r\n :host([variant=\"connected\"]) .base {\r\n flex: 1 1 auto;\r\n }\r\n :host([variant=\"standard\"]) .base {\r\n width: fit-content;\r\n flex: none;\r\n }\r\n :host([variant=\"standard\"]) .base.pressed {\r\n justify-content: space-between;\r\n width: var(--_button-group-width);\r\n }\r\n :host([variant=\"standard\"][size=\"extra-small\"]) .base {\r\n column-gap: var(--m3e-standard-button-group-extra-small-spacing, 1.125rem);\r\n }\r\n :host([variant=\"standard\"][size=\"small\"]) .base {\r\n column-gap: var(--m3e-standard-button-group-small-spacing, 0.75rem);\r\n }\r\n :host([variant=\"standard\"][size=\"medium\"]).base {\r\n column-gap: var(--m3e-standard-button-group-medium-spacing, 0.5rem);\r\n }\r\n :host([variant=\"standard\"][size=\"large\"]) .base {\r\n column-gap: var(--m3e-standard-button-group-large-spacing, 0.5rem);\r\n }\r\n :host([variant=\"standard\"][size=\"extra-large\"]) .base {\r\n column-gap: var(--m3e-standard-button-group-extra-large-spacing, 0.5rem);\r\n }\r\n :host([variant=\"connected\"]) .base {\r\n column-gap: var(--m3e-connected-button-group-spacing, 0.125rem);\r\n }\r\n :host([variant=\"connected\"][size=\"extra-small\"]) ::slotted(:is(:state(--first), :--first)[size=\"extra-small\"]),\r\n :host([variant=\"connected\"][size=\"extra-small\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"extra-small\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-pressed-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"extra-small\"]) ::slotted(:is(:state(--last), :--last)[size=\"extra-small\"]),\r\n :host([variant=\"connected\"][size=\"extra-small\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"extra-small\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-pressed-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"small\"]) ::slotted(:is(:state(--first), :--first)[size=\"small\"]),\r\n :host([variant=\"connected\"][size=\"small\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"small\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-end-shape-pressed-morph: var(\r\n --m3e-connected-button-group-small-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"small\"]) ::slotted(:is(:state(--last), :--last)[size=\"small\"]),\r\n :host([variant=\"connected\"][size=\"small\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"small\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-start-shape-pressed-morph: var(\r\n --m3e-connected-button-group-small-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"medium\"]) ::slotted(:is(:state(--first), :--first)[size=\"medium\"]),\r\n :host([variant=\"connected\"][size=\"medium\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"medium\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-medium-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-medium-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-pressed-shape: var(\r\n --m3e-connected-button-group-medium-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"medium\"]) ::slotted(:is(:state(--last), :--last)[size=\"medium\"]),\r\n :host([variant=\"connected\"][size=\"medium\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"medium\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-medium-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-medium-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-pressed-shape: var(\r\n --m3e-connected-button-group-medium-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"large\"]) ::slotted(:is(:state(--first), :--first)[size=\"large\"]),\r\n :host([variant=\"connected\"][size=\"large\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"large\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-large-inner-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-large-inner-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n --_button-square-end-pressed-shape: var(\r\n --m3e-connected-button-group-large-inner-pressed-shape,\r\n ${DesignToken.shape.corner.medium}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"large\"]) ::slotted(:is(:state(--last), :--last)[size=\"large\"]),\r\n :host([variant=\"connected\"][size=\"large\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"large\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-large-inner-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-large-inner-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n --_button-square-start-pressed-shape: var(\r\n --m3e-connected-button-group-large-inner-pressed-shape,\r\n ${DesignToken.shape.corner.medium}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"extra-large\"]) ::slotted(:is(:state(--first), :--first)[size=\"extra-large\"]),\r\n :host([variant=\"connected\"][size=\"extra-large\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"extra-large\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-shape,\r\n ${DesignToken.shape.corner.largeIncreased}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-shape,\r\n ${DesignToken.shape.corner.largeIncreased}\r\n );\r\n --_button-square-end-pressed-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-pressed-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"extra-large\"]) ::slotted(:is(:state(--last), :--last)[size=\"extra-large\"]),\r\n :host([variant=\"connected\"][size=\"extra-large\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"extra-large\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-shape,\r\n ${DesignToken.shape.corner.largeIncreased}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-shape,\r\n ${DesignToken.shape.corner.largeIncreased}\r\n );\r\n --_button-square-start-pressed-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-pressed-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n }\r\n `;\r\n\r\n /** @private */ readonly #pressedController = new PressedController(this, {\r\n target: null,\r\n capture: true,\r\n minPressedDuration: 150,\r\n isPressedKey: (key) => key === \" \",\r\n callback: (pressed) => this.#handlePressedChange(pressed),\r\n });\r\n\r\n @query(\".base\") private readonly _base?: HTMLElement;\r\n\r\n /**\r\n * The appearance variant of the group.\r\n * @default \"standard\"\r\n */\r\n @property({ reflect: true }) variant: ButtonGroupVariant = \"standard\";\r\n\r\n /**\r\n * The size of the group.\r\n * @default \"small\"\r\n */\r\n @property({ reflect: true }) size: ButtonGroupSize = \"small\";\r\n\r\n /**\r\n * Whether multiple toggle buttons can be selected.\r\n * @default false\r\n */\r\n @property({ type: Boolean }) multi = false;\r\n\r\n /** The buttons contained by the group. */\r\n @queryAssignedElements({ slot: \"\", selector: \"m3e-button,m3e-icon-button\", flatten: true })\r\n readonly buttons!: ReadonlyArray<M3eButtonElement | M3eIconButtonElement>;\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n\r\n if (this.hasAttribute(\"disable-role\")) {\r\n this.role = null;\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this._base?.style.removeProperty(\"--_button-group-width\");\r\n this._base?.classList.remove(\"pressed\");\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override update(changedProperties: PropertyValues<this>): void {\r\n super.update(changedProperties);\r\n\r\n if (changedProperties.has(\"multi\") || changedProperties.has(\"variant\")) {\r\n this.#updateButtons();\r\n }\r\n if (changedProperties.has(\"variant\")) {\r\n this._base?.style.removeProperty(\"--_button-group-width\");\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n return html`<div class=\"base\">\r\n <slot @slotchange=\"${this.#updateButtons}\" @change=\"${this.#handleChange}\"></slot>\r\n </div>`;\r\n }\r\n\r\n /** @private */\r\n #updateButtons(): void {\r\n const buttons = this.buttons;\r\n for (const target of this.#pressedController.targets) {\r\n this.#pressedController.unobserve(target);\r\n }\r\n const canToggle = [...buttons].some((x) => x.toggle);\r\n\r\n // disable-role is an internal attribute to by split-button to disable setting roles.\r\n if (!this.hasAttribute(\"disable-role\")) {\r\n this.role = canToggle && !this.multi ? \"radiogroup\" : \"group\";\r\n }\r\n\r\n const buttonRole = this.role === \"radiogroup\" ? \"radio\" : \"button\";\r\n\r\n buttons.forEach((button, i) => {\r\n this.#pressedController.observe(button);\r\n setCustomState(button, \"--connected\", this.variant === \"connected\");\r\n addCustomState(button, \"--grouped\");\r\n setCustomState(button, \"--first\", i == 0);\r\n setCustomState(button, \"--last\", i == buttons.length - 1);\r\n\r\n if (!this.hasAttribute(\"disable-role\") && button.role !== buttonRole && button.toggle) {\r\n const checked = !button.toggle ? null : button.selected ? \"true\" : \"false\";\r\n button.role = buttonRole;\r\n if (button.role === \"button\") {\r\n button.ariaPressed = checked;\r\n button.ariaChecked = null;\r\n } else {\r\n button.ariaChecked = checked;\r\n button.ariaPressed = null;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /** @private */\r\n #handleChange(e: Event): void {\r\n if (this.multi || !(e.target instanceof HTMLElement)) return;\r\n if (e.target.tagName === \"M3E-BUTTON\" || e.target.tagName === \"M3E-ICON-BUTTON\") {\r\n if (!isSelectedMixin(e.target) || !e.target.selected) {\r\n return;\r\n }\r\n\r\n for (const button of this.buttons) {\r\n if (button === e.target || !button.selected) continue;\r\n button.selected = false;\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n #handlePressedChange(pressed: boolean): void {\r\n const base = this._base;\r\n if (!base) return;\r\n if (!pressed || this.variant === \"connected\") {\r\n const button = this.buttons.find((x) => x === document.activeElement);\r\n if (!prefersReducedMotion() && button) {\r\n button.addEventListener(\r\n \"transitionend\",\r\n () =>\r\n queueMicrotask(() => {\r\n // Pressed state is tested to ensure this runs only when the button\r\n // is no longer pressed. This handles changes to pressed state in\r\n // quick succession.\r\n\r\n if (!hasCustomState(button, \"--pressed\")) {\r\n this.#cleanupPressed(base);\r\n }\r\n }),\r\n { once: true },\r\n );\r\n } else {\r\n this.#cleanupPressed(base);\r\n }\r\n } else {\r\n base.classList.add(\"pressed\");\r\n base.style.setProperty(\"--_button-group-width\", `${base.getBoundingClientRect().width}px`);\r\n }\r\n }\r\n\r\n /** @private */\r\n #cleanupPressed(base: HTMLElement): void {\r\n base.style.removeProperty(\"--_button-group-width\");\r\n base.classList.remove(\"pressed\");\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-button-group\": M3eButtonGroupElement;\r\n }\r\n}\r\n"],"names":["M3eButtonGroupElement","Role","LitElement","constructor","_M3eButtonGroupElement_pressedController","set","this","PressedController","target","capture","minPressedDuration","isPressedKey","key","callback","pressed","__classPrivateFieldGet","_M3eButtonGroupElement_instances","_M3eButtonGroupElement_handlePressedChange","call","variant","size","multi","connectedCallback","super","hasAttribute","role","disconnectedCallback","_base","style","removeProperty","classList","remove","update","changedProperties","has","_M3eButtonGroupElement_updateButtons","render","html","_M3eButtonGroupElement_handleChange","buttons","targets","unobserve","canToggle","some","x","toggle","buttonRole","forEach","button","i","observe","setCustomState","addCustomState","length","checked","selected","ariaPressed","ariaChecked","e","HTMLElement","tagName","isSelectedMixin","base","add","setProperty","getBoundingClientRect","width","find","document","activeElement","prefersReducedMotion","addEventListener","queueMicrotask","hasCustomState","_M3eButtonGroupElement_cleanupPressed","once","styles","css","DesignToken","shape","corner","small","extraSmall","large","medium","largeIncreased","__decorate","query","prototype","property","reflect","type","Boolean","queryAssignedElements","slot","selector","flatten","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"button-group.min.js","sources":["../../src/button-group/ButtonGroupElement.ts"],"sourcesContent":["import { css, CSSResultGroup, html, LitElement, PropertyValues } from \"lit\";\r\nimport { property, query, queryAssignedElements } from \"lit/decorators.js\";\r\n\r\nimport {\r\n PressedController,\r\n Role,\r\n isSelectedMixin,\r\n DesignToken,\r\n setCustomState,\r\n addCustomState,\r\n customElement,\r\n prefersReducedMotion,\r\n hasCustomState,\r\n waitForUpgrade,\r\n} from \"@m3e/web/core\";\r\n\r\nimport { M3eButtonElement } from \"@m3e/web/button\";\r\nimport { M3eIconButtonElement } from \"@m3e/web/icon-button\";\r\n\r\nimport { ButtonGroupVariant } from \"./ButtonGroupVariant\";\r\nimport { ButtonGroupSize } from \"./ButtonGroupSize\";\r\n\r\n/**\r\n * Organizes buttons and adds interactions between them.\r\n *\r\n * @description\r\n * The `m3e-button-group` component arranges multiple buttons into a unified, expressive layout,\r\n * supporting both `standard` and `connected` variants. It enables seamless, accessible grouping\r\n * of actions, adapts to various sizes, and ensures consistent spacing, shape, and alignment.\r\n * Designed according to Material 3 principles, it empowers users to interact with related actions\r\n * in a visually harmonious and intuitive way.\r\n *\r\n * @example\r\n * The following example illustrates a standard button group.\r\n * ``` html\r\n * <m3e-button-group>\r\n * <m3e-icon-button variant=\"tonal\" toggle><m3e-icon name=\"format_bold\"></m3e-icon></m3e-icon-button>\r\n * <m3e-icon-button variant=\"tonal\" toggle><m3e-icon name=\"format_italic\"></m3e-icon></m3e-icon-button>\r\n * <m3e-icon-button variant=\"tonal\" toggle><m3e-icon name=\"format_underlined\"></m3e-icon></m3e-icon-button>\r\n * </m3e-button-group>\r\n * ```\r\n * @example\r\n * The next example illustrates a connected button group.\r\n * ```html\r\n * <m3e-button-group variant=\"connected\">\r\n * <m3e-button variant=\"tonal\" shape=\"square\" toggle>Start</m3e-button>\r\n * <m3e-button variant=\"tonal\" shape=\"square\" toggle>Directions</m3e-button>\r\n * <m3e-button variant=\"tonal\" shape=\"square\" toggle>Share</m3e-button>\r\n * </m3e-button-group>\r\n * ```\r\n *\r\n * @tag m3e-button-group\r\n *\r\n * @slot - Renders the buttons of the group.\r\n *\r\n * @attr multi - Whether multiple toggle buttons can be selected.\r\n * @attr size - The size of the group.\r\n * @attr variant - The appearance variant of the group.\r\n *\r\n * @cssprop --m3e-standard-button-group-extra-small-spacing - Spacing between buttons in standard variant, extra-small size.\r\n * @cssprop --m3e-standard-button-group-small-spacing - Spacing between buttons in standard variant, small size.\r\n * @cssprop --m3e-standard-button-group-medium-spacing - Spacing between buttons in standard variant, medium size.\r\n * @cssprop --m3e-standard-button-group-large-spacing - Spacing between buttons in standard variant, large size.\r\n * @cssprop --m3e-standard-button-group-extra-large-spacing - Spacing between buttons in standard variant, extra-large size.\r\n * @cssprop --m3e-connected-button-group-spacing - Spacing between buttons in connected variant.\r\n * @cssprop --m3e-connected-button-group-extra-small-inner-shape - Corner shape for connected variant, extra-small size.\r\n * @cssprop --m3e-connected-button-group-extra-small-inner-pressed-shape - Pressed corner shape for connected variant, extra-small size.\r\n * @cssprop --m3e-connected-button-group-small-inner-shape - Corner shape for connected variant, small size.\r\n * @cssprop --m3e-connected-button-group-small-inner-pressed-shape - Pressed corner shape for connected variant, small size.\r\n * @cssprop --m3e-connected-button-group-medium-inner-shape - Corner shape for connected variant, medium size.\r\n * @cssprop --m3e-connected-button-group-medium-inner-pressed-shape - Pressed corner shape for connected variant, medium size.\r\n * @cssprop --m3e-connected-button-group-large-inner-shape - Corner shape for connected variant, large size.\r\n * @cssprop --m3e-connected-button-group-large-inner-pressed-shape - Pressed corner shape for connected variant, large size.\r\n * @cssprop --m3e-connected-button-group-extra-large-inner-shape - Corner shape for connected variant, extra-large size.\r\n * @cssprop --m3e-connected-button-group-extra-large-inner-pressed-shape - Pressed corner shape for connected variant, extra-large size.\r\n */\r\n@customElement(\"m3e-button-group\")\r\nexport class M3eButtonGroupElement extends Role(LitElement, \"group\") {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: flex;\r\n vertical-align: middle;\r\n flex-wrap: nowrap;\r\n align-items: center;\r\n }\r\n .base {\r\n display: flex;\r\n vertical-align: middle;\r\n flex-wrap: nowrap;\r\n align-items: center;\r\n }\r\n :host([variant=\"standard\"]) {\r\n justify-content: center;\r\n }\r\n :host([variant=\"connected\"]) .base {\r\n flex: 1 1 auto;\r\n }\r\n :host([variant=\"standard\"]) .base {\r\n width: fit-content;\r\n flex: none;\r\n }\r\n :host([variant=\"standard\"]) .base.pressed {\r\n justify-content: space-between;\r\n width: var(--_button-group-width);\r\n }\r\n :host([variant=\"standard\"][size=\"extra-small\"]) .base {\r\n column-gap: var(--m3e-standard-button-group-extra-small-spacing, 1.125rem);\r\n }\r\n :host([variant=\"standard\"][size=\"small\"]) .base {\r\n column-gap: var(--m3e-standard-button-group-small-spacing, 0.75rem);\r\n }\r\n :host([variant=\"standard\"][size=\"medium\"]).base {\r\n column-gap: var(--m3e-standard-button-group-medium-spacing, 0.5rem);\r\n }\r\n :host([variant=\"standard\"][size=\"large\"]) .base {\r\n column-gap: var(--m3e-standard-button-group-large-spacing, 0.5rem);\r\n }\r\n :host([variant=\"standard\"][size=\"extra-large\"]) .base {\r\n column-gap: var(--m3e-standard-button-group-extra-large-spacing, 0.5rem);\r\n }\r\n :host([variant=\"connected\"]) .base {\r\n column-gap: var(--m3e-connected-button-group-spacing, 0.125rem);\r\n }\r\n :host([variant=\"connected\"][size=\"extra-small\"]) ::slotted(:is(:state(--first), :--first)[size=\"extra-small\"]),\r\n :host([variant=\"connected\"][size=\"extra-small\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"extra-small\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-pressed-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"extra-small\"]) ::slotted(:is(:state(--last), :--last)[size=\"extra-small\"]),\r\n :host([variant=\"connected\"][size=\"extra-small\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"extra-small\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-pressed-shape: var(\r\n --m3e-connected-button-group-extra-small-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"small\"]) ::slotted(:is(:state(--first), :--first)[size=\"small\"]),\r\n :host([variant=\"connected\"][size=\"small\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"small\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-end-shape-pressed-morph: var(\r\n --m3e-connected-button-group-small-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"small\"]) ::slotted(:is(:state(--last), :--last)[size=\"small\"]),\r\n :host([variant=\"connected\"][size=\"small\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"small\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-small-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-start-shape-pressed-morph: var(\r\n --m3e-connected-button-group-small-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"medium\"]) ::slotted(:is(:state(--first), :--first)[size=\"medium\"]),\r\n :host([variant=\"connected\"][size=\"medium\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"medium\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-medium-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-medium-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-end-pressed-shape: var(\r\n --m3e-connected-button-group-medium-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"medium\"]) ::slotted(:is(:state(--last), :--last)[size=\"medium\"]),\r\n :host([variant=\"connected\"][size=\"medium\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"medium\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-medium-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-medium-inner-shape,\r\n ${DesignToken.shape.corner.small}\r\n );\r\n --_button-square-start-pressed-shape: var(\r\n --m3e-connected-button-group-medium-inner-pressed-shape,\r\n ${DesignToken.shape.corner.extraSmall}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"large\"]) ::slotted(:is(:state(--first), :--first)[size=\"large\"]),\r\n :host([variant=\"connected\"][size=\"large\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"large\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-large-inner-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-large-inner-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n --_button-square-end-pressed-shape: var(\r\n --m3e-connected-button-group-large-inner-pressed-shape,\r\n ${DesignToken.shape.corner.medium}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"large\"]) ::slotted(:is(:state(--last), :--last)[size=\"large\"]),\r\n :host([variant=\"connected\"][size=\"large\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"large\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-large-inner-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-large-inner-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n --_button-square-start-pressed-shape: var(\r\n --m3e-connected-button-group-large-inner-pressed-shape,\r\n ${DesignToken.shape.corner.medium}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"extra-large\"]) ::slotted(:is(:state(--first), :--first)[size=\"extra-large\"]),\r\n :host([variant=\"connected\"][size=\"extra-large\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"extra-large\"]) {\r\n --_button-rounded-end-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-shape,\r\n ${DesignToken.shape.corner.largeIncreased}\r\n );\r\n --_button-square-end-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-shape,\r\n ${DesignToken.shape.corner.largeIncreased}\r\n );\r\n --_button-square-end-pressed-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-pressed-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n }\r\n :host([variant=\"connected\"][size=\"extra-large\"]) ::slotted(:is(:state(--last), :--last)[size=\"extra-large\"]),\r\n :host([variant=\"connected\"][size=\"extra-large\"])\r\n ::slotted(:not(:is(:state(--first), :--first)):not(:is(:state(--last), :--last))[size=\"extra-large\"]) {\r\n --_button-rounded-start-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-shape,\r\n ${DesignToken.shape.corner.largeIncreased}\r\n );\r\n --_button-square-start-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-shape,\r\n ${DesignToken.shape.corner.largeIncreased}\r\n );\r\n --_button-square-start-pressed-shape: var(\r\n --m3e-connected-button-group-extra-large-inner-pressed-shape,\r\n ${DesignToken.shape.corner.large}\r\n );\r\n }\r\n `;\r\n\r\n /** @private */ readonly #pressedController = new PressedController(this, {\r\n target: null,\r\n capture: true,\r\n minPressedDuration: 150,\r\n isPressedKey: (key) => key === \" \",\r\n callback: (pressed) => this.#handlePressedChange(pressed),\r\n });\r\n\r\n @query(\".base\") private readonly _base?: HTMLElement;\r\n\r\n /**\r\n * The appearance variant of the group.\r\n * @default \"standard\"\r\n */\r\n @property({ reflect: true }) variant: ButtonGroupVariant = \"standard\";\r\n\r\n /**\r\n * The size of the group.\r\n * @default \"small\"\r\n */\r\n @property({ reflect: true }) size: ButtonGroupSize = \"small\";\r\n\r\n /**\r\n * Whether multiple toggle buttons can be selected.\r\n * @default false\r\n */\r\n @property({ type: Boolean }) multi = false;\r\n\r\n /** The buttons contained by the group. */\r\n @queryAssignedElements({ slot: \"\", selector: \"m3e-button,m3e-icon-button\", flatten: true })\r\n readonly buttons!: ReadonlyArray<M3eButtonElement | M3eIconButtonElement>;\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n\r\n if (this.hasAttribute(\"disable-role\")) {\r\n this.role = null;\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this._base?.style.removeProperty(\"--_button-group-width\");\r\n this._base?.classList.remove(\"pressed\");\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override update(changedProperties: PropertyValues<this>): void {\r\n super.update(changedProperties);\r\n\r\n if (changedProperties.has(\"multi\") || changedProperties.has(\"variant\")) {\r\n this.#updateButtons();\r\n }\r\n if (changedProperties.has(\"variant\")) {\r\n this._base?.style.removeProperty(\"--_button-group-width\");\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n return html`<div class=\"base\">\r\n <slot @slotchange=\"${this.#updateButtons}\" @change=\"${this.#handleChange}\"></slot>\r\n </div>`;\r\n }\r\n\r\n /** @private */\r\n async #updateButtons(): Promise<void> {\r\n const buttons = this.buttons;\r\n for (const target of this.#pressedController.targets) {\r\n this.#pressedController.unobserve(target);\r\n }\r\n for (const button of this.buttons) {\r\n await waitForUpgrade(button);\r\n if (button.isUpdatePending) {\r\n await button.updateComplete;\r\n }\r\n }\r\n const canToggle = [...buttons].some((x) => x.toggle);\r\n\r\n // disable-role is an internal attribute to by split-button to disable setting roles.\r\n if (!this.hasAttribute(\"disable-role\")) {\r\n this.role = canToggle && !this.multi ? \"radiogroup\" : \"group\";\r\n }\r\n\r\n const buttonRole = this.role === \"radiogroup\" ? \"radio\" : \"button\";\r\n\r\n buttons.forEach((button, i) => {\r\n this.#pressedController.observe(button);\r\n setCustomState(button, \"--connected\", this.variant === \"connected\");\r\n addCustomState(button, \"--grouped\");\r\n setCustomState(button, \"--first\", i == 0);\r\n setCustomState(button, \"--last\", i == buttons.length - 1);\r\n\r\n if (!this.hasAttribute(\"disable-role\") && button.role !== buttonRole && button.toggle) {\r\n const checked = !button.toggle ? null : button.selected ? \"true\" : \"false\";\r\n button.role = buttonRole;\r\n if (button.role === \"button\") {\r\n button.ariaPressed = checked;\r\n button.ariaChecked = null;\r\n } else {\r\n button.ariaChecked = checked;\r\n button.ariaPressed = null;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /** @private */\r\n #handleChange(e: Event): void {\r\n if (this.multi || !(e.target instanceof HTMLElement)) return;\r\n if (e.target.tagName === \"M3E-BUTTON\" || e.target.tagName === \"M3E-ICON-BUTTON\") {\r\n if (!isSelectedMixin(e.target) || !e.target.selected) {\r\n return;\r\n }\r\n\r\n for (const button of this.buttons) {\r\n if (button === e.target || !button.selected) continue;\r\n button.selected = false;\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n #handlePressedChange(pressed: boolean): void {\r\n const base = this._base;\r\n if (!base) return;\r\n if (!pressed || this.variant === \"connected\") {\r\n const button = this.buttons.find((x) => x === document.activeElement);\r\n if (!prefersReducedMotion() && button) {\r\n button.addEventListener(\r\n \"transitionend\",\r\n () =>\r\n queueMicrotask(() => {\r\n // Pressed state is tested to ensure this runs only when the button\r\n // is no longer pressed. This handles changes to pressed state in\r\n // quick succession.\r\n\r\n if (!hasCustomState(button, \"--pressed\")) {\r\n this.#cleanupPressed(base);\r\n }\r\n }),\r\n { once: true },\r\n );\r\n } else {\r\n this.#cleanupPressed(base);\r\n }\r\n } else {\r\n base.classList.add(\"pressed\");\r\n base.style.setProperty(\"--_button-group-width\", `${base.getBoundingClientRect().width}px`);\r\n }\r\n }\r\n\r\n /** @private */\r\n #cleanupPressed(base: HTMLElement): void {\r\n base.style.removeProperty(\"--_button-group-width\");\r\n base.classList.remove(\"pressed\");\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-button-group\": M3eButtonGroupElement;\r\n }\r\n}\r\n"],"names":["M3eButtonGroupElement","Role","LitElement","constructor","_M3eButtonGroupElement_pressedController","set","this","PressedController","target","capture","minPressedDuration","isPressedKey","key","callback","pressed","__classPrivateFieldGet","_M3eButtonGroupElement_instances","_M3eButtonGroupElement_handlePressedChange","call","variant","size","multi","connectedCallback","super","hasAttribute","role","disconnectedCallback","_base","style","removeProperty","classList","remove","update","changedProperties","has","_M3eButtonGroupElement_updateButtons","render","html","_M3eButtonGroupElement_handleChange","async","buttons","targets","unobserve","button","waitForUpgrade","isUpdatePending","updateComplete","canToggle","some","x","toggle","buttonRole","forEach","i","observe","setCustomState","addCustomState","length","checked","selected","ariaPressed","ariaChecked","e","HTMLElement","tagName","isSelectedMixin","base","add","setProperty","getBoundingClientRect","width","find","document","activeElement","prefersReducedMotion","addEventListener","queueMicrotask","hasCustomState","_M3eButtonGroupElement_cleanupPressed","once","styles","css","DesignToken","shape","corner","small","extraSmall","large","medium","largeIncreased","__decorate","query","prototype","property","reflect","type","Boolean","queryAssignedElements","slot","selector","flatten","customElement"],"mappings":"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"}
package/dist/button.js CHANGED
@@ -14,7 +14,7 @@ import { DesignToken, KeyboardClick, LinkButton, FormSubmitter, Focusable, Disab
14
14
  */
15
15
  const ButtonSizeToken = {
16
16
  "extra-small": {
17
- containerHeight: unsafeCSS(`calc(var(--m3e-button-extra-small-container-height, var(--m3e-button-container-height, 2rem)) + ${DesignToken.density.calc(0)})`),
17
+ containerHeight: unsafeCSS(`calc(var(--m3e-button-extra-small-container-height, var(--m3e-button-container-height, 2rem)) + ${DesignToken.density.calc(-3)})`),
18
18
  outlineThickness: unsafeCSS("var(--m3e-button-extra-small-outline-thickness, var(--m3e-button-outline-thickness, 1px))"),
19
19
  labelTextFontSize: unsafeCSS(`var(--m3e-button-extra-small-label-text-font-size, var(--m3e-button-label-text-font-size, ${DesignToken.typescale.standard.label.large.fontSize}))`),
20
20
  labelTextFontWeight: unsafeCSS(`var(--m3e-button-extra-small-label-text-font-weight, var(--m3e-button-label-text-font-weight, ${DesignToken.typescale.standard.label.large.fontWeight}))`),
@@ -31,7 +31,7 @@ const ButtonSizeToken = {
31
31
  iconLabelSpace: unsafeCSS("var(--m3e-button-extra-small-icon-label-space, var(--m3e-button-icon-label-space, 0.5rem))")
32
32
  },
33
33
  small: {
34
- containerHeight: unsafeCSS(`calc(var(--m3e-button-small-container-height, var(--m3e-button-container-height, 2.5rem)) + ${DesignToken.density.calc(-1)})`),
34
+ containerHeight: unsafeCSS(`calc(var(--m3e-button-small-container-height, var(--m3e-button-container-height, 2.5rem)) + ${DesignToken.density.calc(-3)})`),
35
35
  outlineThickness: unsafeCSS("var(--m3e-button-small-outline-thickness, var(--m3e-button-outline-thickness, 1px))"),
36
36
  labelTextFontSize: unsafeCSS(`var(--m3e-button-small-label-text-font-size, var(--m3e-button-label-text-font-size, ${DesignToken.typescale.standard.label.large.fontSize}))`),
37
37
  labelTextFontWeight: unsafeCSS(`var(--m3e-button-small-label-text-font-weight, var(--m3e-button-label-text-font-weight, ${DesignToken.typescale.standard.label.large.fontWeight}))`),
@@ -48,7 +48,7 @@ const ButtonSizeToken = {
48
48
  iconLabelSpace: unsafeCSS("var(--m3e-button-small-icon-label-space, var(--m3e-button-icon-label-space, 0.5rem))")
49
49
  },
50
50
  medium: {
51
- containerHeight: unsafeCSS(`calc(var(--m3e-button-medium-container-height, var(--m3e-button-container-height, 3.5rem)) + ${DesignToken.density.calc(-2)})`),
51
+ containerHeight: unsafeCSS(`calc(var(--m3e-button-medium-container-height, var(--m3e-button-container-height, 3.5rem)) + ${DesignToken.density.calc(-3)})`),
52
52
  outlineThickness: unsafeCSS("var(--m3e-button-medium-outline-thickness, var(--m3e-button-outline-thickness, 1px))"),
53
53
  labelTextFontSize: unsafeCSS(`var(--m3e-button-medium-label-text-font-size, var(--m3e-button-label-text-font-size, ${DesignToken.typescale.standard.body.large.fontSize}))`),
54
54
  labelTextFontWeight: unsafeCSS(`var(--m3e-button-medium-label-text-font-weight, var(--m3e-button-label-text-font-weight, ${DesignToken.typescale.standard.body.large.fontWeight}))`),
@@ -102,7 +102,7 @@ const ButtonSizeToken = {
102
102
 
103
103
  /** @private */
104
104
  function buttonStyle(size) {
105
- return css`:host([size="${unsafeCSS(size)}"]) .base { height: ${ButtonSizeToken[size].containerHeight}; } :host([size="${unsafeCSS(size)}"]) .wrapper { padding-inline-start: calc(${ButtonSizeToken[size].leadingSpace} - calc(calc(var(--_adjacent-shrink, 0px) / 2))); padding-inline-end: calc(${ButtonSizeToken[size].trailingSpace} - calc(calc(var(--_adjacent-shrink, 0px) / 2))); column-gap: ${ButtonSizeToken[size].iconLabelSpace}; } :host([size="${unsafeCSS(size)}"]) .label { font-size: ${ButtonSizeToken[size].labelTextFontSize}; font-weight: ${ButtonSizeToken[size].labelTextFontWeight}; line-height: ${ButtonSizeToken[size].labelTextLineHeight}; letter-spacing: ${ButtonSizeToken[size].labelTextTracking}; } :host([size="${unsafeCSS(size)}"]) .icon { font-size: ${ButtonSizeToken[size].iconSize}; --m3e-icon-size: ${ButtonSizeToken[size].iconSize}; } :host([size="${unsafeCSS(size)}"]) .base { outline-offset: calc(0px - ${ButtonSizeToken[size].outlineThickness}); outline-width: ${ButtonSizeToken[size].outlineThickness}; } :host(:not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"][shape="rounded"]) .base { border-radius: var(--_button-shape, ${ButtonSizeToken[size].shapeRound}); } :host( :is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"][shape="rounded"][toggle][selected]:not( :is(:state(--pressed), :--pressed) ) ) .base { border-radius: var(--_button-shape, ${ButtonSizeToken[size].shapeRound}); } :host( :not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"][shape="rounded"][toggle][selected]:not( :is(:state(--pressed), :--pressed) ) ) .base { border-radius: ${ButtonSizeToken[size].selectedShapeRound}; } :host(:not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"][shape="square"]) .base { border-radius: ${ButtonSizeToken[size].shapeSquare}; } :host( :not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"][shape="square"][toggle][selected]:not( :is(:state(--pressed), :--pressed) ) ) .base { border-radius: var(--_button-shape, ${ButtonSizeToken[size].selectedShapeSquare}); } :host(:not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"]:is(:state(--pressed), :--pressed)) .base { border-radius: ${ButtonSizeToken[size].shapePressedMorph}; } :host(:is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"][shape="rounded"]:not([toggle][selected])) .base { border-start-start-radius: var( --_button-rounded-start-shape, var(--_button-shape, ${ButtonSizeToken[size].shapeRound}) ); border-end-start-radius: var( --_button-rounded-start-shape, var(--_button-shape, ${ButtonSizeToken[size].shapeRound}) ); border-start-end-radius: var( --_button-rounded-end-shape, var(--_button-shape, ${ButtonSizeToken[size].shapeRound}) ); border-end-end-radius: var( --_button-rounded-end-shape, var(--_button-shape, ${ButtonSizeToken[size].shapeRound}) ); } :host(:is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"][shape="square"]) .base { border-start-start-radius: var(--_button-square-start-shape, ${ButtonSizeToken[size].shapeSquare}); border-end-start-radius: var(--_button-square-start-shape, ${ButtonSizeToken[size].shapeSquare}); border-start-end-radius: var(--_button-square-end-shape, ${ButtonSizeToken[size].shapeSquare}); border-end-end-radius: var(--_button-square-end-shape, ${ButtonSizeToken[size].shapeSquare}); } :host( :is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"][shape="square"][toggle][selected]:not( :is(:state(--pressed), :--pressed) ) ) .base { border-radius: var(--_button-shape, ${ButtonSizeToken[size].selectedShapeSquare}); } :host(:is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"]:is(:state(--pressed), :--pressed)) .base { border-start-start-radius: var(--_button-start-shape-pressed-morph, ${ButtonSizeToken[size].shapePressedMorph}); border-end-start-radius: var(--_button-start-shape-pressed-morph, ${ButtonSizeToken[size].shapePressedMorph}); border-start-end-radius: var(--_button-end-shape-pressed-morph, ${ButtonSizeToken[size].shapePressedMorph}); border-end-end-radius: var(--_button-end-shape-pressed-morph, ${ButtonSizeToken[size].shapePressedMorph}); }`;
105
+ return css`:host([size="${unsafeCSS(size)}"]) .base { height: ${ButtonSizeToken[size].containerHeight}; } :host([size="${unsafeCSS(size)}"]) .wrapper { padding-inline-start: calc(${ButtonSizeToken[size].leadingSpace} - calc(var(--_adjacent-shrink, 0px) / 2)); padding-inline-end: calc(${ButtonSizeToken[size].trailingSpace} - calc(var(--_adjacent-shrink, 0px) / 2)); column-gap: ${ButtonSizeToken[size].iconLabelSpace}; } :host([size="${unsafeCSS(size)}"]) .label { font-size: ${ButtonSizeToken[size].labelTextFontSize}; font-weight: ${ButtonSizeToken[size].labelTextFontWeight}; line-height: ${ButtonSizeToken[size].labelTextLineHeight}; letter-spacing: ${ButtonSizeToken[size].labelTextTracking}; } :host([size="${unsafeCSS(size)}"]) .icon { font-size: ${ButtonSizeToken[size].iconSize}; --m3e-icon-size: ${ButtonSizeToken[size].iconSize}; } :host([size="${unsafeCSS(size)}"]) .base { outline-offset: calc(0px - ${ButtonSizeToken[size].outlineThickness}); outline-width: ${ButtonSizeToken[size].outlineThickness}; } :host(:not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"][shape="rounded"]) .base { border-radius: var(--_button-shape, ${ButtonSizeToken[size].shapeRound}); } :host( :is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"][shape="rounded"][toggle][selected]:not( :is(:state(--pressed), :--pressed) ) ) .base { border-radius: var(--_button-shape, ${ButtonSizeToken[size].shapeRound}); } :host( :not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"][shape="rounded"][toggle][selected]:not( :is(:state(--pressed), :--pressed) ) ) .base { border-radius: ${ButtonSizeToken[size].selectedShapeRound}; } :host(:not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"][shape="square"]) .base { border-radius: ${ButtonSizeToken[size].shapeSquare}; } :host( :not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"][shape="square"][toggle][selected]:not( :is(:state(--pressed), :--pressed) ) ) .base { border-radius: var(--_button-shape, ${ButtonSizeToken[size].selectedShapeSquare}); } :host(:not(:is(:state(--connected), :--connected))[size="${unsafeCSS(size)}"]:is(:state(--pressed), :--pressed)) .base { border-radius: ${ButtonSizeToken[size].shapePressedMorph}; } :host(:is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"][shape="rounded"]:not([toggle][selected])) .base { border-start-start-radius: var( --_button-rounded-start-shape, var(--_button-shape, ${ButtonSizeToken[size].shapeRound}) ); border-end-start-radius: var( --_button-rounded-start-shape, var(--_button-shape, ${ButtonSizeToken[size].shapeRound}) ); border-start-end-radius: var( --_button-rounded-end-shape, var(--_button-shape, ${ButtonSizeToken[size].shapeRound}) ); border-end-end-radius: var( --_button-rounded-end-shape, var(--_button-shape, ${ButtonSizeToken[size].shapeRound}) ); } :host(:is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"][shape="square"]) .base { border-start-start-radius: var(--_button-square-start-shape, ${ButtonSizeToken[size].shapeSquare}); border-end-start-radius: var(--_button-square-start-shape, ${ButtonSizeToken[size].shapeSquare}); border-start-end-radius: var(--_button-square-end-shape, ${ButtonSizeToken[size].shapeSquare}); border-end-end-radius: var(--_button-square-end-shape, ${ButtonSizeToken[size].shapeSquare}); } :host( :is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"][shape="square"][toggle][selected]:not( :is(:state(--pressed), :--pressed) ) ) .base { border-radius: var(--_button-shape, ${ButtonSizeToken[size].selectedShapeSquare}); } :host(:is(:state(--connected), :--connected)[size="${unsafeCSS(size)}"]:is(:state(--pressed), :--pressed)) .base { border-start-start-radius: var(--_button-start-shape-pressed-morph, ${ButtonSizeToken[size].shapePressedMorph}); border-end-start-radius: var(--_button-start-shape-pressed-morph, ${ButtonSizeToken[size].shapePressedMorph}); border-start-end-radius: var(--_button-end-shape-pressed-morph, ${ButtonSizeToken[size].shapePressedMorph}); border-end-end-radius: var(--_button-end-shape-pressed-morph, ${ButtonSizeToken[size].shapePressedMorph}); }`;
106
106
  }
107
107
  /**
108
108
  * Size variant styles for `M3eButtonElement`.
@@ -115,7 +115,7 @@ const ButtonSizeStyle = [buttonStyle("extra-small"), buttonStyle("small"), butto
115
115
  * @internal
116
116
  */
117
117
  const ButtonStyle = css`:host { display: inline-block; outline: none; user-select: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .base { box-sizing: border-box; vertical-align: middle; display: inline-flex; align-items: center; justify-content: center; position: relative; width: 100%; transition: ${unsafeCSS(`background-color ${DesignToken.motion.duration.short4} ${DesignToken.motion.easing.standard}`)}; } .touch { position: absolute; height: 3rem; left: 0; right: 0; } :host(:is(:state(--pressed), :--pressed)) .base, :host(:is(:state(--resting), :--resting)) .base { transition: ${unsafeCSS(`background-color ${DesignToken.motion.duration.short4} ${DesignToken.motion.easing.standard},
118
- border-radius ${DesignToken.motion.spring.fastEffects}`)}; } .wrapper { width: 100%; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; } .label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: ${unsafeCSS(`color ${DesignToken.motion.duration.short4} ${DesignToken.motion.easing.standard}`)}; } .icon { transition: ${unsafeCSS(`color ${DesignToken.motion.duration.short4} ${DesignToken.motion.easing.standard}`)}; } :host(:not(:disabled):not([disabled-interactive])) { cursor: pointer; } :host([disabled-interactive]) { cursor: not-allowed; } ::slotted([slot="icon"]), ::slotted([slot="selected-icon"]), ::slotted([slot="trailing-icon"]) { font-size: inherit !important; flex: none; } ::slotted(svg[slot="icon"]), ::slotted(svg[slot="selected-icon"]), ::slotted(svg[slot="trailing-icon"]) { width: 1em; height: 1em; } :host([toggle]:not([selected])) .base.with-selected-icon slot[name="selected-icon"], :host([toggle][selected]) .base.with-selected-icon slot[name="icon"] { display: none; } a { all: unset; display: block; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 1; } :host(:is(:state(--grouped), :--grouped):is(:state(--connected), :--connected)) { flex: 1 1 auto; } :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))) { transition: ${unsafeCSS(`flex-basis ${DesignToken.motion.spring.fastEffects}`)}; } :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))) .wrapper { transition: ${unsafeCSS(`padding-inline ${DesignToken.motion.spring.fastEffects}`)}; } :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))) { flex-shrink: 0; flex-grow: 0; } :host( :is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected)):not( :is(:state(--pressed), :--pressed, :state(--adjacent-pressed), :--adjacent-pressed) ) ) { flex-basis: var(--_button-width); } :host( :is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected)):is( :state(--pressed), :--pressed ):not([disabled-interactive]):not(:disabled) ) { flex-basis: calc( var(--_button-width) + calc(var(--_button-width) * var(--m3e-standard-button-group-width-multiplier, 0.15)) ); } :host( :is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected)):is( :state(--adjacent-pressed), :--adjacent-pressed ):not(:is(:state(--pressed), :--pressed)) ) .label { text-overflow: clip; } @media (forced-colors: active) { .base, .label, .icon { transition: none; } :host(:is(:state(--pressed), :--pressed)) .base, :host(:is(:state(--resting), :--resting)) .base { transition: ${unsafeCSS(`border-radius ${DesignToken.motion.spring.fastEffects}`)}; } :host([variant]:not(:disabled):not([disabled-interactive]):not([toggle])) .base { background-color: ButtonFace; outline-color: ButtonText; } :host([variant]:not(:disabled):not([disabled-interactive]):not([toggle])) .label, :host([variant]:not(:disabled):not([disabled-interactive]):not([toggle])) .icon { color: ButtonText; } :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .base { background-color: ButtonFace; outline-color: ButtonText; } :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .label, :host([variant]:hover:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .label, :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected]):focus) .label, :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .icon, :host([variant]:hover:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .icon, :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected]):focus) .icon { color: ButtonText; } :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]) .base { background-color: ButtonText; outline: none; } :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]) .label, :host([variant]:hover:not(:disabled):not([disabled-interactive])[toggle][selected]) .label, :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]:focus) .label, :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]) .icon, :host([variant]:hover:not(:disabled):not([disabled-interactive])[toggle][selected]) .icon, :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]:focus) .icon { forced-color-adjust: none; color: ButtonFace; background-color: ButtonText; } :host([variant]:disabled) .base, :host([variant][disabled-interactive]) .base { outline-color: GrayText; background-color: unset; } :host([variant]:disabled) .label, :host([variant][disabled-interactive]) .label, :host([variant]:disabled) .icon, :host([variant][disabled-interactive]) .icon { color: GrayText; } .base { outline-style: solid; } :host([size="extra-small"]) .base { outline-offset: calc(0px - var(--m3e-button-extra-small-outline-thickness, 1px)); outline-width: var(--m3e-button-extra-small-outline-thickness, 1px); } :host([size="small"]) .base { outline-offset: calc(0px - var(--m3e-button-small-outline-thickness, 1px)); outline-width: var(--m3e-button-small-outline-thickness, 1px); } :host([size="medium"]) .base { outline-offset: calc(0px - var(--m3e-button-medium-outline-thickness, 1px)); outline-width: var(--m3e-button-medium-outline-thickness, 1px); } :host([size="large"]) .base { outline-offset: calc(0px - var(--m3e-button-large-outline-thickness, 2px)); outline-width: var(--m3e-button-large-outline-thickness, 2px); } :host([size="extra-large"]) .base { outline-offset: calc(0px - var(--m3e-button-extra-large-outline-thickness, 3px)); outline-width: var(--m3e-button-extra-large-outline-thickness, 3px); } } @media (prefers-reduced-motion) { :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))), :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))) .wrapper, :host(:is(:state(--pressed), :--pressed)) .base, :host(:is(:state(--resting), :--resting)) .base, .base, .label, .icon { transition: none; } }`;
118
+ border-radius ${DesignToken.motion.spring.fastEffects}`)}; } .wrapper { width: 100%; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; } .label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: ${unsafeCSS(`color ${DesignToken.motion.duration.short4} ${DesignToken.motion.easing.standard}`)}; } .icon { transition: ${unsafeCSS(`color ${DesignToken.motion.duration.short4} ${DesignToken.motion.easing.standard}`)}; } :host(:not(:disabled):not([disabled-interactive])) { cursor: pointer; } :host([disabled-interactive]) { cursor: not-allowed; } ::slotted([slot="icon"]), ::slotted([slot="selected-icon"]), ::slotted([slot="trailing-icon"]) { font-size: inherit !important; flex: none; } ::slotted(svg[slot="icon"]), ::slotted(svg[slot="selected-icon"]), ::slotted(svg[slot="trailing-icon"]) { width: 1em; height: 1em; } :host([toggle]:not([selected])) .base.with-selected-icon slot[name="selected-icon"], :host([toggle][selected]) .base.with-selected-icon slot[name="icon"] { display: none; } a { all: unset; display: block; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 1; } :host(:is(:state(--grouped), :--grouped):is(:state(--connected), :--connected)) { flex: 1 1 auto; } :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))) { transition: ${unsafeCSS(`width ${DesignToken.motion.spring.fastEffects}`)}; } :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))) .wrapper { transition: ${unsafeCSS(`padding-inline ${DesignToken.motion.spring.fastEffects}`)}; } :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))) { flex-shrink: 0; flex-grow: 0; } :host( :is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected)):not( :is(:state(--pressed), :--pressed, :state(--adjacent-pressed), :--adjacent-pressed) ) ) { width: var(--_button-width); } :host( :is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected)):not( :is(:state(--pressed), :--pressed) ):is(:state(--adjacent-pressed), :--adjacent-pressed) ) { width: calc(var(--_button-width) - var(--_adjacent-shrink, 0px)); } :host( :is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected)):is( :state(--pressed), :--pressed ):not([disabled-interactive]):not(:disabled) ) { width: calc( var(--_button-width) + calc(var(--_button-width) * var(--m3e-standard-button-group-width-multiplier, 0.15)) ); } :host( :is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected)):is( :state(--adjacent-pressed), :--adjacent-pressed ):not(:is(:state(--pressed), :--pressed)) ) .label { text-overflow: clip; } @media (forced-colors: active) { .base, .label, .icon { transition: none; } :host(:is(:state(--pressed), :--pressed)) .base, :host(:is(:state(--resting), :--resting)) .base { transition: ${unsafeCSS(`border-radius ${DesignToken.motion.spring.fastEffects}`)}; } :host([variant]:not(:disabled):not([disabled-interactive]):not([toggle])) .base { background-color: ButtonFace; outline-color: ButtonText; } :host([variant]:not(:disabled):not([disabled-interactive]):not([toggle])) .label, :host([variant]:not(:disabled):not([disabled-interactive]):not([toggle])) .icon { color: ButtonText; } :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .base { background-color: ButtonFace; outline-color: ButtonText; } :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .label, :host([variant]:hover:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .label, :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected]):focus) .label, :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .icon, :host([variant]:hover:not(:disabled):not([disabled-interactive])[toggle]:not([selected])) .icon, :host([variant]:not(:disabled):not([disabled-interactive])[toggle]:not([selected]):focus) .icon { color: ButtonText; } :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]) .base { background-color: ButtonText; outline: none; } :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]) .label, :host([variant]:hover:not(:disabled):not([disabled-interactive])[toggle][selected]) .label, :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]:focus) .label, :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]) .icon, :host([variant]:hover:not(:disabled):not([disabled-interactive])[toggle][selected]) .icon, :host([variant]:not(:disabled):not([disabled-interactive])[toggle][selected]:focus) .icon { forced-color-adjust: none; color: ButtonFace; background-color: ButtonText; } :host([variant]:disabled) .base, :host([variant][disabled-interactive]) .base { outline-color: GrayText; background-color: unset; } :host([variant]:disabled) .label, :host([variant][disabled-interactive]) .label, :host([variant]:disabled) .icon, :host([variant][disabled-interactive]) .icon { color: GrayText; } .base { outline-style: solid; } :host([size="extra-small"]) .base { outline-offset: calc(0px - var(--m3e-button-extra-small-outline-thickness, 1px)); outline-width: var(--m3e-button-extra-small-outline-thickness, 1px); } :host([size="small"]) .base { outline-offset: calc(0px - var(--m3e-button-small-outline-thickness, 1px)); outline-width: var(--m3e-button-small-outline-thickness, 1px); } :host([size="medium"]) .base { outline-offset: calc(0px - var(--m3e-button-medium-outline-thickness, 1px)); outline-width: var(--m3e-button-medium-outline-thickness, 1px); } :host([size="large"]) .base { outline-offset: calc(0px - var(--m3e-button-large-outline-thickness, 2px)); outline-width: var(--m3e-button-large-outline-thickness, 2px); } :host([size="extra-large"]) .base { outline-offset: calc(0px - var(--m3e-button-extra-large-outline-thickness, 3px)); outline-width: var(--m3e-button-extra-large-outline-thickness, 3px); } } @media (prefers-reduced-motion) { :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))), :host(:is(:state(--grouped), :--grouped):not(:is(:state(--connected), :--connected))) .wrapper, :host(:is(:state(--pressed), :--pressed)) .base, :host(:is(:state(--resting), :--resting)) .base, .base, .label, .icon { transition: none; } }`;
119
119
 
120
120
  /**
121
121
  * Component design tokens that control the appearance variants of `M3eButtonElement`.
@@ -1132,6 +1132,8 @@ let M3eButtonElement = class M3eButtonElement extends KeyboardClick(LinkButton(F
1132
1132
  constructor() {
1133
1133
  super();
1134
1134
  _M3eButtonElement_instances.add(this);
1135
+ /** @internal */
1136
+ this._adjacentPressedTimeout = -1;
1135
1137
  /** @private */
1136
1138
  _M3eButtonElement_clickHandler.set(this, e => __classPrivateFieldGet(this, _M3eButtonElement_instances, "m", _M3eButtonElement_handleClick).call(this, e));
1137
1139
  /**
@@ -1231,7 +1233,7 @@ let M3eButtonElement = class M3eButtonElement extends KeyboardClick(LinkButton(F
1231
1233
  /** @private */
1232
1234
  _handleResize() {
1233
1235
  if (this.grouped && !hasCustomState(this, "--no-resize") && this !== document.activeElement) {
1234
- this.style.setProperty("--_button-width", `${this.clientWidth}px`);
1236
+ this.style.setProperty("--_button-width", `${this.getBoundingClientRect().width}px`);
1235
1237
  __classPrivateFieldGet(this, _M3eButtonElement_instances, "m", _M3eButtonElement_updateButtonShape).call(this, true);
1236
1238
  }
1237
1239
  }
@@ -1276,6 +1278,10 @@ _M3eButtonElement_handlePressedChange = function _M3eButtonElement_handlePressed
1276
1278
  const group = this.closest("m3e-button-group");
1277
1279
  if (group && group.variant === "standard") {
1278
1280
  const buttons = [...group.querySelectorAll("m3e-button,m3e-icon-button")];
1281
+ for (const button of buttons) {
1282
+ clearTimeout(button._adjacentPressedTimeout);
1283
+ button._adjacentPressedTimeout = -1;
1284
+ }
1279
1285
  const index = buttons.indexOf(this);
1280
1286
  if (pressed) {
1281
1287
  const multiplier = parseFloat(getComputedStyle(this).getPropertyValue("--m3e-standard-button-group-width-multiplier") || "0.15");
@@ -1306,15 +1312,15 @@ _M3eButtonElement_handlePressedChange = function _M3eButtonElement_handlePressed
1306
1312
  }
1307
1313
  if (!prefersReducedMotion()) {
1308
1314
  this.addEventListener("transitionend", e => {
1309
- if (e.propertyName === "flex-basis") {
1310
- queueMicrotask(() => {
1311
- // Pressed state is tested to ensure this runs only when the button
1315
+ if (e.propertyName === "width") {
1316
+ this._adjacentPressedTimeout = setTimeout(() => {
1317
+ // Pressed timeout is tested to ensure this runs only when the button
1312
1318
  // is no longer pressed. This handles changes to pressed state in
1313
1319
  // quick succession.
1314
- if (!hasCustomState(this, "--pressed")) {
1320
+ if (this._adjacentPressedTimeout > -1) {
1315
1321
  __classPrivateFieldGet(this, _M3eButtonElement_instances, "m", _M3eButtonElement_cleanupAdjacentPressed).call(this, buttons);
1316
1322
  }
1317
- });
1323
+ }, 600);
1318
1324
  }
1319
1325
  }, {
1320
1326
  once: true