@awc-ui/core 1.0.0-beta → 1.0.0-beta.1

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 (79) hide show
  1. package/dist/components/p-6wZSqm_2.js +2 -0
  2. package/dist/components/{p-Bx5sxRqa.js.map → p-6wZSqm_2.js.map} +1 -1
  3. package/dist/components/p-7fN_yCXW.js +2 -0
  4. package/dist/components/{p-CJdqKSuf.js.map → p-7fN_yCXW.js.map} +1 -1
  5. package/dist/components/{p-G5m2pHZ2.js → p-B0Opn6dK.js} +2 -2
  6. package/dist/components/{p-pDrTJmeT.js → p-B3MWYEEJ.js} +2 -2
  7. package/dist/components/{p-DGGkdSZk.js → p-BwXpiUsu.js} +2 -2
  8. package/dist/{md3/p-B0NLeNWu.js → components/p-Bx6--dQF.js} +2 -2
  9. package/dist/components/{p-BIIp3Qod.js → p-C8EP4S21.js} +2 -2
  10. package/dist/components/{p-CWM3KSti.js → p-C_ogF68H.js} +2 -2
  11. package/dist/components/{p-BlwGYUkt.js → p-Ch2-tttM.js} +2 -2
  12. package/dist/components/p-DXXUoRSH.js +2 -0
  13. package/dist/components/{p-DWUCvzfU.js.map → p-DXXUoRSH.js.map} +1 -1
  14. package/dist/components/p-Dp-w93ot.js +2 -0
  15. package/dist/components/{p-BUYYCrGa.js.map → p-Dp-w93ot.js.map} +1 -1
  16. package/dist/{md3/p-CGStn3Iq.js → components/p-DvOKnoqK.js} +2 -2
  17. package/dist/components/{p-B7yMxWo-.js → p-DzPKu-Ma.js} +2 -2
  18. package/dist/components/{p-CXpXrhQH.js → p-RLxbNqRv.js} +2 -2
  19. package/dist/components/p-UdGDg2oJ.js +2 -0
  20. package/dist/components/{p-BujtL9xW.js.map → p-UdGDg2oJ.js.map} +1 -1
  21. package/dist/components/p-e2HRV63Y.js +2 -0
  22. package/dist/components/{p-CrlkPxeB.js.map → p-e2HRV63Y.js.map} +1 -1
  23. package/dist/components/p-stybaFzj.js +2 -0
  24. package/dist/components/{p-JbwZ84YK.js.map → p-stybaFzj.js.map} +1 -1
  25. package/dist/components/p-uTEkf0sE.js +2 -0
  26. package/dist/components/{p-BXwh1zjF.js.map → p-uTEkf0sE.js.map} +1 -1
  27. package/dist/esm/{a11y-C9_cZAF_.js → a11y-C6CRqodW.js} +3 -3
  28. package/dist/esm/{a11y-C9_cZAF_.js.map → a11y-C6CRqodW.js.map} +1 -1
  29. package/dist/esm/{bar-chart-IvBgAmmF.js → bar-chart-ZZrajEkM.js} +4 -4
  30. package/dist/esm/{bar-chart-IvBgAmmF.js.map → bar-chart-ZZrajEkM.js.map} +1 -1
  31. package/dist/esm/{chart-D1kP9gfW.js → chart-32olae06.js} +4 -4
  32. package/dist/esm/{chart-D1kP9gfW.js.map → chart-32olae06.js.map} +1 -1
  33. package/dist/esm/{hit-test-DFfwlMb9.js → hit-test-DHldf5Lm.js} +3 -3
  34. package/dist/esm/{hit-test-DFfwlMb9.js.map → hit-test-DHldf5Lm.js.map} +1 -1
  35. package/dist/esm/{rtl-CGStn3Iq.js → rtl-DvOKnoqK.js} +3 -3
  36. package/dist/esm/{rtl-CGStn3Iq.js.map → rtl-DvOKnoqK.js.map} +1 -1
  37. package/dist/md3/p-04e97f5d.entry.js +2 -0
  38. package/dist/md3/{p-ec14eaca.entry.js.map → p-04e97f5d.entry.js.map} +1 -1
  39. package/dist/md3/p-3cce1de3.entry.js +2 -0
  40. package/dist/md3/{p-2121c939.entry.js.map → p-3cce1de3.entry.js.map} +1 -1
  41. package/dist/md3/p-4d82132d.entry.js +2 -0
  42. package/dist/md3/{p-fe78659d.entry.js.map → p-4d82132d.entry.js.map} +1 -1
  43. package/dist/{components/p-Bu-m4Gm2.js → md3/p-Bx6--dQF.js} +2 -2
  44. package/dist/md3/{p-B0NLeNWu.js.map → p-Bx6--dQF.js.map} +1 -1
  45. package/dist/md3/{p-CWM3KSti.js → p-C_ogF68H.js} +2 -2
  46. package/dist/md3/{p-CWM3KSti.js.map → p-C_ogF68H.js.map} +1 -1
  47. package/dist/{components/p-CGStn3Iq.js → md3/p-DvOKnoqK.js} +2 -2
  48. package/dist/md3/{p-CGStn3Iq.js.map → p-DvOKnoqK.js.map} +1 -1
  49. package/dist/md3/{p-B7yMxWo-.js → p-DzPKu-Ma.js} +2 -2
  50. package/dist/md3/{p-B7yMxWo-.js.map → p-DzPKu-Ma.js.map} +1 -1
  51. package/dist/md3/{p-CXpXrhQH.js → p-RLxbNqRv.js} +2 -2
  52. package/dist/md3/{p-CXpXrhQH.js.map → p-RLxbNqRv.js.map} +1 -1
  53. package/dist/md3/{p-f6373c6c.entry.js → p-aaec2698.entry.js} +2 -2
  54. package/dist/md3/{p-9ff2d5d1.entry.js → p-c063c823.entry.js} +2 -2
  55. package/main-llm.md +2 -2
  56. package/package.json +24 -3
  57. package/dist/components/p-BUYYCrGa.js +0 -2
  58. package/dist/components/p-BXwh1zjF.js +0 -2
  59. package/dist/components/p-BujtL9xW.js +0 -2
  60. package/dist/components/p-Bx5sxRqa.js +0 -2
  61. package/dist/components/p-CJdqKSuf.js +0 -2
  62. package/dist/components/p-CrlkPxeB.js +0 -2
  63. package/dist/components/p-DWUCvzfU.js +0 -2
  64. package/dist/components/p-JbwZ84YK.js +0 -2
  65. package/dist/md3/p-2121c939.entry.js +0 -2
  66. package/dist/md3/p-ec14eaca.entry.js +0 -2
  67. package/dist/md3/p-fe78659d.entry.js +0 -2
  68. /package/dist/components/{p-G5m2pHZ2.js.map → p-B0Opn6dK.js.map} +0 -0
  69. /package/dist/components/{p-pDrTJmeT.js.map → p-B3MWYEEJ.js.map} +0 -0
  70. /package/dist/components/{p-DGGkdSZk.js.map → p-BwXpiUsu.js.map} +0 -0
  71. /package/dist/components/{p-Bu-m4Gm2.js.map → p-Bx6--dQF.js.map} +0 -0
  72. /package/dist/components/{p-BIIp3Qod.js.map → p-C8EP4S21.js.map} +0 -0
  73. /package/dist/components/{p-CWM3KSti.js.map → p-C_ogF68H.js.map} +0 -0
  74. /package/dist/components/{p-BlwGYUkt.js.map → p-Ch2-tttM.js.map} +0 -0
  75. /package/dist/components/{p-CGStn3Iq.js.map → p-DvOKnoqK.js.map} +0 -0
  76. /package/dist/components/{p-B7yMxWo-.js.map → p-DzPKu-Ma.js.map} +0 -0
  77. /package/dist/components/{p-CXpXrhQH.js.map → p-RLxbNqRv.js.map} +0 -0
  78. /package/dist/md3/{p-f6373c6c.entry.js.map → p-aaec2698.entry.js.map} +0 -0
  79. /package/dist/md3/{p-9ff2d5d1.entry.js.map → p-c063c823.entry.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"names":["mdButtonCss","MdButton","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","type","variant","size","shape","disabled","softDisabled","ripple","loading","icon","trailingIcon","href","target","toggle","selected","shapeMorph","mirrorIcon","suppressExpandIconFlip","fullWidth","connectedLeft","connectedRight","value","groupTabindex","roleOverride","density","hasSlottedLeadingIcon","hasSlottedTrailingIcon","pressed","handleClick","e","isDisabled","preventDefault","nextSelected","evt","mdClick","emit","originalEvent","defaultPrevented","mdChange","sanitizeHref","window","open","SAFE_WINDOW_FEATURES","internals","form","requestSubmit","reset","handleKeyDown","key","triggerRipple","el","click","setTimeout","handlePointerDown","handlePointerUp","componentDidLoad","shadow","shadowRoot","leadingSlot","querySelector","trailingSlot","addEventListener","assignedElements","length","render","isEffectivelyDisabled","hasLeadingIcon","hasTrailingIcon","h","Host","class","role","String","undefined","tabindex","onClick","onKeyDown","onPointerDown","onPointerUp","onPointerLeave","onPointerCancel","part","name"],"sources":["src/components/md-button/md-button.css?tag=md-button&encapsulation=shadow","src/components/md-button/md-button.tsx"],"sourcesContent":["/* ==========================================================\n md-button — Material Design 3 Common Button\n Spec: https://m3.material.io/components/buttons/specs\n API: https://developer.android.com/reference/kotlin/\n androidx/compose/material3/ButtonDefaults\n Supports M3 + M3 Expressive (size, shape)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-button-container-color Container background\n --md-button-label-color Label + icon text color\n --md-button-icon-color Icon-only color override\n --md-button-icon-size Icon dimensions\n --md-button-container-shape Border-radius override\n --md-button-outline-color Outlined border color\n --md-button-outline-width Outlined border width\n --md-button-width Fixed inline-size (default: auto)\n --md-button-min-width Minimum inline-size (default: per-size touch target)\n --md-button-max-width Maximum inline-size (default: none)\n --md-button-height Fixed block-size (default: auto)\n --md-button-min-height Minimum block-size (default: per-size touch target)\n\n CSS PARTS:\n state-layer State-layer overlay\n icon Leading icon (fallback)\n trailing-icon Trailing icon (fallback)\n label Label text wrapper\n loading Loading spinner\n\n SLOTS:\n leading-icon Custom leading icon (replaces icon prop)\n trailing-icon Custom trailing icon (replaces trailingIcon prop)\n\n RTL:\n Layout uses CSS logical properties throughout, so leading/\n trailing icons swap visual sides automatically in `dir=\"rtl\"`.\n Set the `mirror-icon` attribute on buttons that use directional\n glyphs (arrows, chevrons) so the icon path itself flips.\n ========================================================== */\n\n:host {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n --_container-elevation: var(--md-sys-elevation-0, none);\n --_icon-size: var(--md-button-icon-size, 18px);\n\n /* Sizing — defaults come from each size class via --_size-* tokens.\n Public --md-button-{width,min-width,max-width,height,min-height}\n custom properties override per-instance for variable / full-width\n buttons without sacrificing the spec touch-target on resize. */\n --_width: var(--md-button-width, auto);\n /* Min-width tightens with density too (floored at 40px) so short-label\n buttons narrow, not just content-wide ones. Unchanged at density 0. */\n --_min-width: var(\n --md-button-min-width,\n max(40px, calc(var(--_size-min-width, 48px) + var(--md-sys-density-scale, 0) * 4px))\n );\n --_max-width: var(--md-button-max-width, none);\n --_height: var(--md-button-height, auto);\n /* Global density: on top of the size scale, each `data-density` rung (0…-4)\n trims 4px off the touch target, floored at 24px so small buttons stay\n usable. density-scale is 0 by default so the per-size height is unchanged. */\n --_min-height: var(\n --md-button-min-height,\n max(24px, calc(var(--_size-min-height, 32px) + var(--md-sys-density-scale, 0) * 4px))\n );\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n user-select: none;\n text-decoration: none;\n border: none;\n /* Transparent resting outline; focus-visible swaps outline-color in instantly.\n Deliberately NOT transitioned — on hydration the host's pre-upgrade UA outline\n (style:none, color:currentColor) animates to solid/transparent, which renders a\n dark ring that fades out on every button. Most visible when many mount at once\n (e.g. the 42 day cells in md-date-picker). Instant focus ring matches M3. */\n outline: 3px solid transparent;\n outline-offset: 2px;\n box-sizing: border-box;\n inline-size: var(--_width);\n block-size: var(--_height);\n min-inline-size: var(--_min-width);\n min-block-size: var(--_min-height);\n max-inline-size: var(--_max-width);\n background-color: var(--_container-color);\n color: var(--_label-color);\n box-shadow: var(--_container-elevation);\n --_shape-round: 20px;\n transition:\n box-shadow var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n background-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-radius var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n -webkit-tap-highlight-color: transparent;\n vertical-align: middle;\n}\n\n/* ==========================================================\n 1. SIZE\n XS (32px) · SM (40px, default) · MD (48px) · LG (56px) · XL (96px)\n ========================================================== */\n/* Icon<->label gap tapers with density like the rest of the button: the\n container height and icon already shrink per rung, so a frozen gap made\n compact buttons read as loosely spaced. Each tier halves across the range\n (rate = base/8 per rung), floored at half its base. */\n:host(.md-button--xs) {\n --_icon-size: var(--md-button-icon-size, max(10px, calc(20px + var(--md-sys-density-scale, 0) * 2.5px)));\n --_shape-round: 16px;\n --_size-min-height: 32px;\n --_size-min-width: 48px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(6px, calc(12px + var(--md-sys-density-scale, 0) * 0.75px));\n gap: max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px));\n font-family: var(--md-sys-typescale-label-medium-font-family, Roboto, sans-serif);\n font-size: max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-medium-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-medium-letter-spacing, 0.5px);\n line-height: max(14px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n}\n\n:host(.md-button--sm) {\n --_icon-size: var(--md-button-icon-size, max(10px, calc(20px + var(--md-sys-density-scale, 0) * 2.5px)));\n --_shape-round: 20px;\n --_size-min-height: 40px;\n --_size-min-width: 58px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(8px, calc(16px + var(--md-sys-density-scale, 0) * 1px));\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n font-family: var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-large-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-large-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--md) {\n --_icon-size: var(--md-button-icon-size, max(12px, calc(24px + var(--md-sys-density-scale, 0) * 3px)));\n --_shape-round: 28px;\n --_size-min-height: 56px;\n --_size-min-width: 72px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(12px, calc(24px + var(--md-sys-density-scale, 0) * 1.5px));\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n font-family: var(--md-sys-typescale-title-small-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-title-small-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-title-small-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--lg) {\n --_icon-size: var(--md-button-icon-size, max(16px, calc(32px + var(--md-sys-density-scale, 0) * 4px)));\n --_shape-round: 48px;\n --_size-min-height: 96px;\n --_size-min-width: 88px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(24px, calc(48px + var(--md-sys-density-scale, 0) * 3px));\n gap: max(6px, calc(12px + var(--md-sys-density-scale, 0) * 1.5px));\n font-family: var(--md-sys-typescale-title-medium-font-family, Roboto, sans-serif);\n font-size: max(13px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-title-medium-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-title-medium-letter-spacing, 0.15px);\n line-height: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--xl) {\n --_icon-size: var(--md-button-icon-size, max(20px, calc(40px + var(--md-sys-density-scale, 0) * 5px)));\n --_shape-round: 68px;\n --_size-min-height: 136px;\n --_size-min-width: 120px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(32px, calc(64px + var(--md-sys-density-scale, 0) * 4px));\n gap: max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px));\n font-family: var(--md-sys-typescale-headline-small-font-family, Roboto, sans-serif);\n font-size: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n font-weight: var(--md-sys-typescale-headline-small-font-weight, 400);\n letter-spacing: var(--md-sys-typescale-headline-small-letter-spacing, 0px);\n line-height: max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px));\n}\n\n/* ==========================================================\n 1b. FULL WIDTH — block-level, fills inline axis\n `full-width` switches the host from inline-flex to flex and stretches\n inline-size to 100% of the containing block. The size's\n --_size-min-height (touch target) is still in force, so the button\n keeps its spec block-size unless --md-button-height overrides it.\n --md-button-width still wins if explicitly set.\n ========================================================== */\n:host(.md-button--full-width) {\n display: flex;\n --_width: var(--md-button-width, 100%);\n}\n\n/* ==========================================================\n 2. SHAPE\n Round (default) · Square (scaled corner radius)\n Round uses --_shape-round (height/2 per size) instead of\n corner-full (9999px) so the browser can smoothly interpolate\n border-radius transitions between resting and morphed states.\n --md-button-container-shape overrides both.\n ========================================================== */\n/* The RESTING radius is named (--_shape-rest) so the morph states below can be\n expressed as a blend back toward it. --_morph-to carries the morphed target\n and defaults to the resting value, so a button with no active morph state\n resolves to exactly its resting radius:\n\n calc(REST + FLAG * (MORPH - REST)) FLAG 1 -> MORPH, FLAG 0 -> REST\n\n That is what makes `data-shape-morph=\"off\"` / `shape-morph=\"off\"` freeze the\n shape (§13 in tokens.css) without a re-render and without :host-context,\n which Firefox does not implement. */\n:host(.md-button--round) {\n --_shape-rest: var(--md-button-container-shape, var(--_shape-round));\n border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest)));\n}\n\n:host(.md-button--square.md-button--xs) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-small, 8px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--sm) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--md) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--lg) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-large, 16px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--xl) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-extra-large, 28px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n\n/* ==========================================================\n 2b. SHAPE MORPHING — M3 Expressive\n Uses direct border-radius overrides for reliable transitions.\n\n Order: selected rules FIRST, pressed rules LAST so pressed\n always wins while the pointer is down.\n\n Asymmetric timing (M3 motion tokens):\n Release / selected : medium4 (400ms) + emphasized-decelerate\n Press-in : short4 (200ms) + standard\n ========================================================== */\n\n/* ── Selected shape — round resting → square tokens when selected ── */\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--xs) { --_morph-to: var(--md-sys-shape-corner-small, 8px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--sm) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--md) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--lg) { --_morph-to: var(--md-sys-shape-corner-large, 16px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--xl) { --_morph-to: var(--md-sys-shape-corner-extra-large, 28px); }\n\n/* ── Selected shape — square resting → round when selected ── */\n:host(.md-button--shape-morph.md-button--square.md-button--selected) {\n --_morph-to: var(--md-button-container-shape, var(--_shape-round));\n}\n\n/* ── Pressed shape — both round & square morph to more square, overrides selected ── */\n:host(.md-button--pressed.md-button--xs) {\n --_morph-to: var(--md-sys-shape-corner-extra-small, 4px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--sm) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--md) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--lg) {\n --_morph-to: var(--md-sys-shape-corner-medium, 12px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--xl) {\n --_morph-to: var(--md-sys-shape-corner-large, 16px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n 2c. CONNECTED GROUP — per-corner border-radius\n Set by md-button-group when variant=\"connected\".\n shapeMorph is disabled for connected children so these rules\n only need to beat the base shape rules (section 2, specificity 0-1-0).\n ========================================================== */\n\n:host(.md-button--connected-left.md-button--xs),\n:host(.md-button--connected-right.md-button--xs) { --_c-inner: 4px; }\n:host(.md-button--connected-left.md-button--sm),\n:host(.md-button--connected-right.md-button--sm) { --_c-inner: 8px; }\n:host(.md-button--connected-left.md-button--md),\n:host(.md-button--connected-right.md-button--md) { --_c-inner: 8px; }\n:host(.md-button--connected-left.md-button--lg),\n:host(.md-button--connected-right.md-button--lg) { --_c-inner: 16px; }\n:host(.md-button--connected-left.md-button--xl),\n:host(.md-button--connected-right.md-button--xl) { --_c-inner: 20px; }\n\n/* Middle button — all corners inner */\n:host(.md-button--connected-left.md-button--connected-right) {\n border-radius: var(--_c-inner);\n}\n\n/* `connected-left` / `connected-right` reflect DOM-order siblings (set by\n md-button-group when a previous / next sibling exists), so the radii\n here must use logical corner properties to flip correctly under\n `dir=\"rtl\"`. The outer pill always lives on the free inline-start\n (first child) or inline-end (last child) edge. */\n\n/* First button (round) — pill on inline-start edge, inner on inline-end edge */\n:host(.md-button--round.md-button--connected-right:not(.md-button--connected-left)) {\n border-start-start-radius: var(--_shape-round);\n border-end-start-radius: var(--_shape-round);\n border-start-end-radius: var(--_c-inner);\n border-end-end-radius: var(--_c-inner);\n}\n\n/* Last button (round) — inner on inline-start edge, pill on inline-end edge */\n:host(.md-button--round.md-button--connected-left:not(.md-button--connected-right)) {\n border-start-start-radius: var(--_c-inner);\n border-end-start-radius: var(--_c-inner);\n border-start-end-radius: var(--_shape-round);\n border-end-end-radius: var(--_shape-round);\n}\n\n/* Square first / last — outer equals inner */\n:host(.md-button--square.md-button--connected-right:not(.md-button--connected-left)),\n:host(.md-button--square.md-button--connected-left:not(.md-button--connected-right)) {\n border-radius: var(--_c-inner);\n}\n\n/* ==========================================================\n 3. ICON PADDING\n An icon does NOT change the button's insets. The M3 Expressive size sheet\n specifies the SAME padding on both sides whether or not a leading icon is\n present (12/12, 16/16, 24/24, 48/48, 64/64) — the third number on those\n drawings is the icon-to-label gap, not a reduced leading inset. The size's\n base padding therefore applies symmetrically and there is nothing to override.\n ========================================================== */\n\n/* ==========================================================\n 4. COLOR VARIANTS\n --md-button-container-color and --md-button-label-color\n override the variant defaults when set.\n ========================================================== */\n\n/* Filled */\n:host(.md-button--filled) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-primary));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-primary));\n --_state-layer-color: var(--md-sys-color-on-primary);\n}\n:host(.md-button--filled:hover) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--filled:active) { --_container-elevation: var(--md-sys-elevation-0, none); }\n:host(.md-button--filled:focus-visible) { --_container-elevation: var(--md-sys-elevation-0, none); }\n\n/* Outlined */\n:host(.md-button--outlined) {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n border: var(--md-button-outline-width, 1px) solid var(--md-button-outline-color, var(--md-sys-color-outline));\n}\n:host(.md-button--outlined.md-button--xs) { padding: 0 max(3px, calc(11px + var(--md-sys-density-scale, 0) * 2px)); }\n:host(.md-button--outlined.md-button--sm) { padding: 0 max(7px, calc(23px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--outlined.md-button--md) { padding: 0 max(9px, calc(27px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--outlined.md-button--lg) { padding: 0 max(10px, calc(31px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--outlined.md-button--xl) { padding: 0 max(15px, calc(47px + var(--md-sys-density-scale, 0) * 2px)); }\n:host(.md-button--outlined:hover:not(.md-button--disabled)) {\n border-color: var(--md-button-outline-color, var(--md-sys-color-primary));\n}\n:host(.md-button--outlined:focus-visible) {\n border-color: var(--md-button-outline-color, var(--md-sys-color-primary));\n}\n\n/* Text */\n:host(.md-button--text) {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n}\n:host(.md-button--text.md-button--xs) { padding: 0 max(3px, calc(8px + var(--md-sys-density-scale, 0) * 2px)); }\n:host(.md-button--text.md-button--sm) { padding: 0 max(4px, calc(12px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--text.md-button--md) { padding: 0 max(5px, calc(16px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--text.md-button--lg) { padding: 0 max(6px, calc(20px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--text.md-button--xl) { padding: 0 max(10px, calc(32px + var(--md-sys-density-scale, 0) * 2px)); }\n\n/* Elevated */\n:host(.md-button--elevated) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-low));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n --_container-elevation: var(--md-sys-elevation-1);\n}\n:host(.md-button--elevated:hover) { --_container-elevation: var(--md-sys-elevation-2); }\n:host(.md-button--elevated:focus-visible) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--elevated:active) { --_container-elevation: var(--md-sys-elevation-1); }\n\n/* Tonal */\n:host(.md-button--tonal) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-secondary-container));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-secondary-container));\n --_state-layer-color: var(--md-sys-color-on-secondary-container);\n}\n:host(.md-button--tonal:hover) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--tonal:focus-visible) { --_container-elevation: var(--md-sys-elevation-0, none); }\n:host(.md-button--tonal:active) { --_container-elevation: var(--md-sys-elevation-0, none); }\n\n/* ==========================================================\n 4b. TOGGLE SELECTED / UNSELECTED — MD3 spec\n When toggle=true, the unselected state is muted; selected\n shows the full variant color. Mirrors md-icon-button pattern.\n ========================================================== */\n\n/* The toggle-state rules below all carry `:not(.md-button--disabled)` so\n they drop out when the host becomes disabled. Without it, their higher\n specificity (4 classes vs the disabled rules' 2–3) would override the\n muted disabled palette and the button would still look enabled. */\n\n/* ── Filled toggle ── */\n:host(.md-button--filled.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n}\n\n/* ── Tonal toggle ── */\n:host(.md-button--tonal.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* ── Outlined toggle ── */\n:host(.md-button--outlined.md-button--toggle.md-button--selected:not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-secondary-container, #1E192B));\n --_state-layer-color: var(--md-sys-color-on-secondary-container, #1E192B);\n border-color: transparent;\n}\n\n/* ── Elevated toggle ── */\n:host(.md-button--elevated.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n/* ── Text toggle ── */\n:host(.md-button--text.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* ==========================================================\n 5. STATE LAYER\n ========================================================== */\n.md-button__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n:host(:hover) .md-button__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n:host(:active:not(.md-button--disabled)) .md-button__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n transition-duration: var(--md-sys-motion-duration-short1, 50ms);\n transition-timing-function: var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n:host(:focus-visible) .md-button__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 6. FOCUS RING\n `z-index: 1` raises the focused button above its siblings so the\n outline is never clipped by a neighbor — important inside\n md-button-group, where connected groups have only 2px between\n buttons and standard groups animate neighbor padding on press.\n ========================================================== */\n/* Connected children inside md-button-group sit only 2px apart, so a\n 3px-outset focus ring naturally extends across the neighbor. The\n `z-index: 1` raise lets it draw *on top* of the neighbor cleanly so\n the ring keeps its full 2px breathing room — same visual treatment\n as a stand-alone button. */\n:host(:focus-visible) {\n outline-color: var(--md-sys-color-secondary);\n z-index: 1;\n}\n\n/* ==========================================================\n 7. DISABLED\n ========================================================== */\n:host(.md-button--disabled) {\n cursor: default;\n pointer-events: none;\n --_container-elevation: var(--md-sys-elevation-0, none) !important;\n transition: none;\n}\n\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n:host([soft-disabled]) .md-button__state-layer { display: none; }\n\n:host(.md-button--filled.md-button--disabled),\n:host(.md-button--tonal.md-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n:host(.md-button--elevated.md-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-button--disabled) {\n --_label-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-button--outlined.md-button--disabled) {\n --_container-color: transparent;\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-button--text.md-button--disabled) {\n --_container-color: transparent;\n}\n\n:host(.md-button--disabled:hover) .md-button__state-layer,\n:host(.md-button--disabled:active) .md-button__state-layer,\n:host(.md-button--disabled:focus-visible) .md-button__state-layer {\n opacity: 0;\n}\n\n/* ==========================================================\n 8. ICON (prop-based fallback inside slot)\n ========================================================== */\n.md-button__icon,\n.md-button__trailing-icon {\n color: var(--md-button-icon-color, inherit);\n font-size: var(--_icon-size, 18px);\n width: var(--_icon-size, 18px);\n height: var(--_icon-size, 18px);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 9. NAMED ICON SLOTS\n Slots use display:contents so they don't create a box;\n slotted content participates directly in flex layout.\n ========================================================== */\nslot[name=\"leading-icon\"],\nslot[name=\"trailing-icon\"] {\n display: contents;\n}\n\n::slotted([slot=\"leading-icon\"]),\n::slotted([slot=\"trailing-icon\"]) {\n color: var(--md-button-icon-color, inherit);\n width: var(--_icon-size, 18px);\n height: var(--_icon-size, 18px);\n flex-shrink: 0;\n}\n\n/* ----------------------------------------------------------\n Trailing-icon rotation when this button is a popover anchor.\n\n md-menu (and any other popup component using the same ARIA\n contract) sets aria-expanded=\"true\" on its anchor element\n while the popup is open. Rotating the trailing dropdown\n indicator 180° on that signal flips arrow_drop_down to\n point up, matching MD3 select-trigger behavior, with no\n wiring needed on the consumer side.\n\n Honors prefers-reduced-motion via short2 motion duration.\n ---------------------------------------------------------- */\n.md-button__trailing-icon,\n::slotted([slot=\"trailing-icon\"]) {\n transition: transform var(--md-sys-motion-duration-short2, 150ms)\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host([aria-expanded=\"true\"]:not([suppress-expand-icon-flip])) .md-button__trailing-icon,\n:host([aria-expanded=\"true\"]:not([suppress-expand-icon-flip])) ::slotted([slot=\"trailing-icon\"]) {\n transform: rotate(180deg);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-button__state-layer {\n transition: none;\n }\n\n .md-button__trailing-icon,\n ::slotted([slot=\"trailing-icon\"]) {\n transition: none;\n }\n}\n\n/* ==========================================================\n 10. LABEL\n ========================================================== */\n.md-button__label {\n display: flex;\n align-items: center;\n white-space: nowrap;\n}\n\n/* ==========================================================\n 11. LOADING SPINNER (scales with icon size)\n ========================================================== */\n.md-button__loading {\n /* A FRACTION of the icon it stands in for. Two constraints pull against each\n other: at full --_icon-size the ring reads heavier than the glyph (a bare\n stroke has none of the internal padding a Material glyph carries), but at\n 1em it was pinned to the label and stopped scaling per tier -- sm and md\n share a 14px label, so a 40px and a 56px button drew the same 14px ring\n despite 20px vs 24px icons. 0.7 keeps it visibly lighter than a glyph while\n tracking the tier, and inherits the icon's density taper. */\n /* 10px floor: the icon token itself bottoms out at 10px on the small tiers,\n and 0.7 of that is a 7px ring — too small to read as a spinner at all. */\n --_loading-size: var(--md-button-loading-size, max(10px, calc(var(--_icon-size, 18px) * 0.7)));\n\n /* Hand the size straight to md-loading-indicator's PUBLIC hooks. These\n replace the child's whole default expression, so the button's own taper\n (and its 10px floor) survives instead of hitting the child's 32px floor.\n Not --_size / --_shape-size: those are the child's private vars and\n writing them from out here is the handoff trap. currentColor keeps the\n indicator matching each variant's label, which a token would not. */\n --md-loading-indicator-size: var(--_loading-size);\n --md-loading-indicator-shape-size: var(--_loading-size);\n --md-loading-indicator-color: currentColor;\n flex-shrink: 0;\n /* A wrapper now, so the hooks above reach a SLOTTED replacement too. It has\n to lay out like the indicator it replaced — an inline span would add a text\n baseline gap next to the label. */\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Whatever the consumer slots in gets the same box the default occupies. */\n.md-button__loading ::slotted(*) {\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 12. MATERIAL SYMBOLS (default icon font)\n ========================================================== */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-weight: normal;\n font-style: normal;\n font-size: var(--_icon-size, 18px);\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* ==========================================================\n 13. RTL — opt-in directional-icon mirroring\n\n Buttons that show directional Material Symbols (arrow_forward,\n chevron_right, send, reply…) should set `mirror-icon` so the\n glyph itself flips alongside the leading/trailing slot swap that\n the logical-property layout already performs. Non-directional\n icons (add, search, favorite…) leave `mirror-icon` unset so the\n glyph stays semantically correct.\n\n Two rules cover both placements of `dir=\"rtl\"`:\n (a) on the host itself — `:host([dir=\"rtl\"])`\n (b) on any ancestor element — `:host-context([dir=\"rtl\"])`\n ========================================================== */\n:host([mirror-icon][dir=\"rtl\"]) .md-button__icon,\n:host([mirror-icon][dir=\"rtl\"]) .md-button__trailing-icon,\n:host([mirror-icon][dir=\"rtl\"]) ::slotted([slot=\"leading-icon\"]),\n:host([mirror-icon][dir=\"rtl\"]) ::slotted([slot=\"trailing-icon\"]) {\n transform: scaleX(-1);\n}\n\n:host-context([dir=\"rtl\"]):host([mirror-icon]) .md-button__icon,\n:host-context([dir=\"rtl\"]):host([mirror-icon]) .md-button__trailing-icon,\n:host-context([dir=\"rtl\"]):host([mirror-icon]) ::slotted([slot=\"leading-icon\"]),\n:host-context([dir=\"rtl\"]):host([mirror-icon]) ::slotted([slot=\"trailing-icon\"]) {\n transform: scaleX(-1);\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, AttachInternals } from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\n/**\n * Detail payload emitted by `md-button`'s `mdClick` event when the user\n * activates the button (mouse, touch, or keyboard).\n *\n * The event is **cancelable** — calling `event.preventDefault()` from a\n * listener stops the button's default side effects (toggle-state flip\n * and `href` navigation) but does NOT stop the underlying DOM click\n * event. This is the recommended hook for SPA routing and \"are you\n * sure?\" confirmation flows.\n */\nexport interface MdButtonClickDetail {\n /** The button's `value` prop (useful when grouped via `md-button-group`). */\n value: string;\n /** Whether toggle mode is enabled. */\n toggle: boolean;\n /**\n * Selected state the button WILL transition to if the click is not\n * cancelled. In non-toggle mode this is identical to `selected`.\n */\n selected: boolean;\n /** Navigation target (empty if the button is not a link). */\n href: string;\n /** Browsing context (`_self`, `_blank`, …). */\n target: string;\n /** The original DOM event that triggered the activation. */\n originalEvent: MouseEvent | KeyboardEvent;\n}\n\n/**\n * Detail payload emitted by `md-button`'s `mdChange` event when toggle\n * mode flips the selected state in response to a user activation.\n */\nexport interface MdButtonChangeDetail {\n /** New selected state. */\n selected: boolean;\n /** The button's `value` prop. */\n value: string;\n}\n\n@Component({\n tag: 'md-button',\n styleUrl: 'md-button.css',\n shadow: true,\n formAssociated: true,\n})\nexport class MdButton {\n @Element() el!: HTMLElement;\n\n /**\n * Form-association handle. Used to submit/reset the associated form when\n * `type` is `submit`/`reset` — works across shadow boundaries, unlike a\n * native `<button>` rendered in the shadow root (which can't see the\n * light-DOM `<form>` it lives in).\n */\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Activation behavior, mirroring the native `<button type>`:\n * - `button` (default): no implicit form action.\n * - `submit`: submits the associated form (`requestSubmit`, so the form's\n * `submit` event fires and constraint validation runs).\n * - `reset`: resets the associated form.\n */\n @Prop({ reflect: true }) type: 'button' | 'submit' | 'reset' = 'button';\n\n @Prop() variant: 'filled' | 'outlined' | 'text' | 'elevated' | 'tonal' = 'filled';\n @Prop() size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';\n @Prop() shape: 'round' | 'square' = 'round';\n @Prop({ reflect: true }) disabled: boolean = false;\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n @Prop() ripple: boolean = true;\n @Prop() loading: boolean = false;\n @Prop() icon: string = '';\n @Prop() trailingIcon: string = '';\n @Prop() href: string = '';\n @Prop() target: string = '_self';\n\n /** Enable toggle behavior (selected/unselected) */\n @Prop() toggle: boolean = false;\n\n /** Current selected state (toggle mode) */\n @Prop({ mutable: true }) selected: boolean = false;\n\n /** Enable M3 Expressive shape morphing on press and toggle */\n @Prop() shapeMorph: boolean = true;\n\n /**\n * Mirror leading and trailing icons horizontally when the button is\n * rendered in a right-to-left context. Set this on buttons that use\n * **directional** Material Symbols (arrows, chevrons, send, reply…)\n * — non-directional icons (add, search, favorite…) should leave it\n * `false` so the glyph stays semantically correct.\n */\n @Prop({ reflect: true, attribute: 'mirror-icon' }) mirrorIcon: boolean = false;\n\n /**\n * When true, suppresses the default 180° trailing-icon rotation while\n * `aria-expanded=\"true\"`. Use when the consumer swaps the glyph (e.g.\n * docked `md-date-picker` month/year triggers use `chevron_right`).\n */\n @Prop({ reflect: true, attribute: 'suppress-expand-icon-flip' })\n suppressExpandIconFlip: boolean = false;\n\n /**\n * Stretch the button to fill its inline-axis container.\n *\n * Switches the host from `inline-flex` to `flex` and sets\n * `inline-size: 100%` so the button consumes the full width of its\n * parent — the standard pattern for primary CTAs in forms, modals,\n * and bottom sheets. The size's `min-block-size` (touch target) is\n * preserved.\n *\n * For arbitrary fixed widths or heights, set the\n * `--md-button-width`, `--md-button-height`, `--md-button-min-width`,\n * `--md-button-min-height`, or `--md-button-max-width` CSS custom\n * properties on the host instead.\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n /** @internal Set by md-button-group — left side is connected to a neighbor */\n @Prop({ reflect: true }) connectedLeft: boolean = false;\n\n /** @internal Set by md-button-group — right side is connected to a neighbor */\n @Prop({ reflect: true }) connectedRight: boolean = false;\n\n /** @internal Value for button-group association */\n @Prop() value: string = '';\n\n /**\n * @internal Roving-tabindex override set by `md-button-group`. When the\n * button is a child of a group, the group sets this to `0` on the\n * currently-active button and `-1` on the rest, so Tab enters the group\n * once instead of stepping through every button. Outside a group, this\n * stays `null` and the button uses its normal tabindex behavior.\n */\n @Prop({ mutable: true, reflect: false }) groupTabindex: number | null = null;\n\n /**\n * Override the default `role=\"button\"`. Used by composite widgets such as\n * `md-date-picker` day cells (`role=\"gridcell\"`). Leave empty for `button`.\n */\n @Prop({ attribute: 'role-override' }) roleOverride: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fires every time the user activates the button (mouse click, touch,\n * or `Enter`/`Space` while focused). The event is **cancelable** and\n * the detail payload describes what *would* happen: the post-click\n * toggle state, the navigation `href`, and so on.\n *\n * Calling `event.preventDefault()` from a listener suppresses the\n * default side effects (toggle flip + `href` navigation) but lets\n * the underlying DOM click bubble. This is the hook to use for SPA\n * routing, \"are you sure?\" prompts, async confirmation, etc.\n *\n * The event bubbles and is composed, so listeners outside the\n * shadow tree (the typical case) receive it.\n *\n * ```ts\n * document.querySelector('md-button')!.addEventListener('mdClick', (e) => {\n * const { href, selected } = (e as CustomEvent).detail;\n * if (!confirm('Continue?')) e.preventDefault();\n * });\n * ```\n */\n @Event({ cancelable: true, bubbles: true, composed: true })\n mdClick!: EventEmitter<MdButtonClickDetail>;\n\n /**\n * Fires when toggle mode flips the `selected` state in response to a\n * user activation. Not cancelable — the state change has already\n * happened. Pair with `mdClick` (cancelable) when you need a veto.\n *\n * Bubbles and is composed.\n */\n @Event({ bubbles: true, composed: true })\n mdChange!: EventEmitter<MdButtonChangeDetail>;\n\n @State() private hasSlottedLeadingIcon = false;\n @State() private hasSlottedTrailingIcon = false;\n @State() private pressed = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled || this.loading;\n }\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const leadingSlot = shadow.querySelector('slot[name=\"leading-icon\"]') as HTMLSlotElement | null;\n const trailingSlot = shadow.querySelector('slot[name=\"trailing-icon\"]') as HTMLSlotElement | null;\n\n leadingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedLeadingIcon = leadingSlot.assignedElements().length > 0;\n });\n trailingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedTrailingIcon = trailingSlot.assignedElements().length > 0;\n });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n\n // Compute the post-click toggle state up front so the detail\n // payload describes what *would* happen — listeners can then\n // call preventDefault on the CustomEvent to veto the change.\n const nextSelected = this.toggle ? !this.selected : this.selected;\n\n const evt = this.mdClick.emit({\n value: this.value,\n toggle: this.toggle,\n selected: nextSelected,\n href: this.href,\n target: this.target,\n originalEvent: e,\n });\n\n if (evt.defaultPrevented) {\n // Suppress browser's default link navigation as well so the\n // host stays consistent. We don't flip selected and don't\n // open the href.\n e.preventDefault();\n return;\n }\n\n if (this.toggle && nextSelected !== this.selected) {\n this.selected = nextSelected;\n this.mdChange.emit({ selected: nextSelected, value: this.value });\n }\n\n /* Setting `href` makes this a link rather than a form control, so the\n branch is taken on the raw prop — an unsafe URL must not silently fall\n through to submitting the form. Only the navigation itself is refused. */\n if (this.href) {\n const href = sanitizeHref(this.href);\n if (href) window.open(href, this.target, SAFE_WINDOW_FEATURES);\n return;\n }\n\n // Implicit form action, mirroring a native submit/reset button. Uses\n // ElementInternals so the associated <form> is found across the shadow\n // boundary. requestSubmit() (not submit()) so the form's submit event\n // fires and built-in constraint validation runs.\n if (this.type === 'submit') {\n this.internals.form?.requestSubmit();\n } else if (this.type === 'reset') {\n this.internals.form?.reset();\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n this.pressed = true;\n triggerRipple(this.el);\n this.el.click();\n setTimeout(() => { this.pressed = false; }, 150);\n }\n }\n };\n\n private handlePointerDown = () => {\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n const hasLeadingIcon = !!this.icon;\n const hasTrailingIcon = !!this.trailingIcon;\n\n return (\n <Host\n class={{\n 'md-button': true,\n [`md-button--${this.variant}`]: true,\n [`md-button--${this.size}`]: true,\n [`md-button--${this.shape}`]: true,\n 'md-button--with-leading-icon': hasLeadingIcon || this.hasSlottedLeadingIcon,\n 'md-button--with-trailing-icon': hasTrailingIcon || this.hasSlottedTrailingIcon,\n 'md-button--disabled': this.disabled || this.softDisabled,\n 'md-button--loading': this.loading,\n 'md-button--toggle': this.toggle,\n 'md-button--selected': this.selected,\n 'md-button--shape-morph': this.shapeMorph,\n 'md-button--pressed': this.shapeMorph && this.pressed,\n 'md-button--connected-left': this.connectedLeft,\n 'md-button--connected-right': this.connectedRight,\n 'md-button--full-width': this.fullWidth,\n }}\n role={this.roleOverride || 'button'}\n aria-disabled={isEffectivelyDisabled ? 'true' : 'false'}\n aria-pressed={this.toggle ? String(this.selected) : undefined}\n tabindex={\n this.disabled\n ? '-1'\n : (this.groupTabindex !== null ? String(this.groupTabindex) : '0')\n }\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n {this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n <span class=\"md-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n <slot name=\"leading-icon\">\n {hasLeadingIcon && <span class=\"md-button__icon material-symbols-outlined\" part=\"icon\">{this.icon}</span>}\n </slot>\n <span class=\"md-button__label\" part=\"label\"><slot /></span>\n <slot name=\"trailing-icon\">\n {hasTrailingIcon && <span class=\"md-button__trailing-icon material-symbols-outlined\" part=\"trailing-icon\">{this.trailingIcon}</span>}\n </slot>\n {this.loading && (\n /* md-loading-indicator, not a hand-rolled ring: never ship a custom\n loading affordance where a library component exists. It is\n md-loading-indicator rather than md-progress-indicator because the\n latter clamps its circular variant to a 24dp M3 minimum, while a\n button spinner runs 10-28px -- every tier but xl would clamp up and\n lose the density taper. Same choice md-select made for its trigger.\n\n The `loader` slot lets a consumer swap it (e.g. for a circular\n md-progress-indicator). The size hooks sit on this WRAPPER so they\n cascade to whatever ends up inside it, default or slotted. */\n <span class=\"md-button__loading\" part=\"loading\" aria-hidden=\"true\">\n <slot name=\"loader\">\n <md-loading-indicator class=\"md-button__loading-default\" />\n </slot>\n </span>\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["mdButtonCss","MdButton","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","type","variant","size","shape","disabled","softDisabled","ripple","loading","icon","trailingIcon","href","target","toggle","selected","shapeMorph","mirrorIcon","suppressExpandIconFlip","fullWidth","connectedLeft","connectedRight","value","groupTabindex","roleOverride","density","hasSlottedLeadingIcon","hasSlottedTrailingIcon","pressed","handleClick","e","isDisabled","preventDefault","nextSelected","evt","mdClick","emit","originalEvent","defaultPrevented","mdChange","sanitizeHref","window","open","SAFE_WINDOW_FEATURES","internals","form","requestSubmit","reset","handleKeyDown","key","triggerRipple","el","click","setTimeout","handlePointerDown","handlePointerUp","componentDidLoad","shadow","shadowRoot","leadingSlot","querySelector","trailingSlot","addEventListener","assignedElements","length","render","isEffectivelyDisabled","hasLeadingIcon","hasTrailingIcon","h","Host","class","role","String","undefined","tabindex","onClick","onKeyDown","onPointerDown","onPointerUp","onPointerLeave","onPointerCancel","part","name"],"sources":["src/components/md-button/md-button.css?tag=md-button&encapsulation=shadow","src/components/md-button/md-button.tsx"],"sourcesContent":["/* ==========================================================\n md-button — Material Design 3 Common Button\n Spec: https://m3.material.io/components/buttons/specs\n API: https://developer.android.com/reference/kotlin/\n androidx/compose/material3/ButtonDefaults\n Supports M3 + M3 Expressive (size, shape)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-button-container-color Container background\n --md-button-label-color Label + icon text color\n --md-button-icon-color Icon-only color override\n --md-button-icon-size Icon dimensions\n --md-button-container-shape Border-radius override\n --md-button-outline-color Outlined border color\n --md-button-outline-width Outlined border width\n --md-button-width Fixed inline-size (default: auto)\n --md-button-min-width Minimum inline-size (default: per-size touch target)\n --md-button-max-width Maximum inline-size (default: none)\n --md-button-height Fixed block-size (default: auto)\n --md-button-min-height Minimum block-size (default: per-size touch target)\n\n CSS PARTS:\n state-layer State-layer overlay\n icon Leading icon (fallback)\n trailing-icon Trailing icon (fallback)\n label Label text wrapper\n loading Loading spinner\n\n SLOTS:\n leading-icon Custom leading icon (replaces icon prop)\n trailing-icon Custom trailing icon (replaces trailingIcon prop)\n\n RTL:\n Layout uses CSS logical properties throughout, so leading/\n trailing icons swap visual sides automatically in `dir=\"rtl\"`.\n Set the `mirror-icon` attribute on buttons that use directional\n glyphs (arrows, chevrons) so the icon path itself flips.\n ========================================================== */\n\n:host {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n --_container-elevation: var(--md-sys-elevation-0, none);\n --_icon-size: var(--md-button-icon-size, 18px);\n\n /* Sizing — defaults come from each size class via --_size-* tokens.\n Public --md-button-{width,min-width,max-width,height,min-height}\n custom properties override per-instance for variable / full-width\n buttons without sacrificing the spec touch-target on resize. */\n --_width: var(--md-button-width, auto);\n /* Min-width tightens with density too (floored at 40px) so short-label\n buttons narrow, not just content-wide ones. Unchanged at density 0. */\n --_min-width: var(\n --md-button-min-width,\n max(40px, calc(var(--_size-min-width, 48px) + var(--md-sys-density-scale, 0) * 4px))\n );\n --_max-width: var(--md-button-max-width, none);\n --_height: var(--md-button-height, auto);\n /* Global density: on top of the size scale, each `data-density` rung (0…-4)\n trims 4px off the touch target, floored at 24px so small buttons stay\n usable. density-scale is 0 by default so the per-size height is unchanged. */\n --_min-height: var(\n --md-button-min-height,\n max(24px, calc(var(--_size-min-height, 32px) + var(--md-sys-density-scale, 0) * 4px))\n );\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n user-select: none;\n text-decoration: none;\n border: none;\n /* Transparent resting outline; focus-visible swaps outline-color in instantly.\n Deliberately NOT transitioned — on hydration the host's pre-upgrade UA outline\n (style:none, color:currentColor) animates to solid/transparent, which renders a\n dark ring that fades out on every button. Most visible when many mount at once\n (e.g. the 42 day cells in md-date-picker). Instant focus ring matches M3. */\n outline: 3px solid transparent;\n outline-offset: 2px;\n box-sizing: border-box;\n inline-size: var(--_width);\n block-size: var(--_height);\n min-inline-size: var(--_min-width);\n min-block-size: var(--_min-height);\n max-inline-size: var(--_max-width);\n background-color: var(--_container-color);\n color: var(--_label-color);\n box-shadow: var(--_container-elevation);\n --_shape-round: 20px;\n transition:\n box-shadow var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n background-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-radius var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n -webkit-tap-highlight-color: transparent;\n vertical-align: middle;\n}\n\n/* ==========================================================\n 1. SIZE\n XS (32px) · SM (40px, default) · MD (48px) · LG (56px) · XL (96px)\n ========================================================== */\n/* Icon<->label gap tapers with density like the rest of the button: the\n container height and icon already shrink per rung, so a frozen gap made\n compact buttons read as loosely spaced. Each tier halves across the range\n (rate = base/8 per rung), floored at half its base. */\n:host(.md-button--xs) {\n --_icon-size: var(--md-button-icon-size, max(10px, calc(20px + var(--md-sys-density-scale, 0) * 2.5px)));\n --_shape-round: 16px;\n --_size-min-height: 32px;\n --_size-min-width: 48px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(6px, calc(12px + var(--md-sys-density-scale, 0) * 0.75px));\n gap: max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px));\n font-family: var(--md-sys-typescale-label-medium-font-family, Roboto, sans-serif);\n font-size: max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-medium-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-medium-letter-spacing, 0.5px);\n line-height: max(14px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n}\n\n:host(.md-button--sm) {\n --_icon-size: var(--md-button-icon-size, max(10px, calc(20px + var(--md-sys-density-scale, 0) * 2.5px)));\n --_shape-round: 20px;\n --_size-min-height: 40px;\n --_size-min-width: 58px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(8px, calc(16px + var(--md-sys-density-scale, 0) * 1px));\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n font-family: var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-large-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-large-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--md) {\n --_icon-size: var(--md-button-icon-size, max(12px, calc(24px + var(--md-sys-density-scale, 0) * 3px)));\n --_shape-round: 28px;\n --_size-min-height: 56px;\n --_size-min-width: 72px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(12px, calc(24px + var(--md-sys-density-scale, 0) * 1.5px));\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n font-family: var(--md-sys-typescale-title-small-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-title-small-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-title-small-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--lg) {\n --_icon-size: var(--md-button-icon-size, max(16px, calc(32px + var(--md-sys-density-scale, 0) * 4px)));\n --_shape-round: 48px;\n --_size-min-height: 96px;\n --_size-min-width: 88px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(24px, calc(48px + var(--md-sys-density-scale, 0) * 3px));\n gap: max(6px, calc(12px + var(--md-sys-density-scale, 0) * 1.5px));\n font-family: var(--md-sys-typescale-title-medium-font-family, Roboto, sans-serif);\n font-size: max(13px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-title-medium-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-title-medium-letter-spacing, 0.15px);\n line-height: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--xl) {\n --_icon-size: var(--md-button-icon-size, max(20px, calc(40px + var(--md-sys-density-scale, 0) * 5px)));\n --_shape-round: 68px;\n --_size-min-height: 136px;\n --_size-min-width: 120px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(32px, calc(64px + var(--md-sys-density-scale, 0) * 4px));\n gap: max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px));\n font-family: var(--md-sys-typescale-headline-small-font-family, Roboto, sans-serif);\n font-size: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n font-weight: var(--md-sys-typescale-headline-small-font-weight, 400);\n letter-spacing: var(--md-sys-typescale-headline-small-letter-spacing, 0px);\n line-height: max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px));\n}\n\n/* ==========================================================\n 1b. FULL WIDTH — block-level, fills inline axis\n `full-width` switches the host from inline-flex to flex and stretches\n inline-size to 100% of the containing block. The size's\n --_size-min-height (touch target) is still in force, so the button\n keeps its spec block-size unless --md-button-height overrides it.\n --md-button-width still wins if explicitly set.\n ========================================================== */\n:host(.md-button--full-width) {\n display: flex;\n --_width: var(--md-button-width, 100%);\n}\n\n/* ==========================================================\n 2. SHAPE\n Round (default) · Square (scaled corner radius)\n Round uses --_shape-round (height/2 per size) instead of\n corner-full (9999px) so the browser can smoothly interpolate\n border-radius transitions between resting and morphed states.\n --md-button-container-shape overrides both.\n ========================================================== */\n/* The RESTING radius is named (--_shape-rest) so the morph states below can be\n expressed as a blend back toward it. --_morph-to carries the morphed target\n and defaults to the resting value, so a button with no active morph state\n resolves to exactly its resting radius:\n\n calc(REST + FLAG * (MORPH - REST)) FLAG 1 -> MORPH, FLAG 0 -> REST\n\n That is what makes `data-shape-morph=\"off\"` / `shape-morph=\"off\"` freeze the\n shape (§13 in tokens.css) without a re-render and without :host-context,\n which Firefox does not implement. */\n:host(.md-button--round) {\n --_shape-rest: var(--md-button-container-shape, var(--_shape-round));\n border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest)));\n}\n\n:host(.md-button--square.md-button--xs) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-small, 8px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--sm) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--md) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--lg) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-large, 16px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--xl) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-extra-large, 28px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n\n/* ==========================================================\n 2b. SHAPE MORPHING — M3 Expressive\n Uses direct border-radius overrides for reliable transitions.\n\n Order: selected rules FIRST, pressed rules LAST so pressed\n always wins while the pointer is down.\n\n Asymmetric timing (M3 motion tokens):\n Release / selected : medium4 (400ms) + emphasized-decelerate\n Press-in : short4 (200ms) + standard\n ========================================================== */\n\n/* ── Selected shape — round resting → square tokens when selected ── */\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--xs) { --_morph-to: var(--md-sys-shape-corner-small, 8px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--sm) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--md) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--lg) { --_morph-to: var(--md-sys-shape-corner-large, 16px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--xl) { --_morph-to: var(--md-sys-shape-corner-extra-large, 28px); }\n\n/* ── Selected shape — square resting → round when selected ── */\n:host(.md-button--shape-morph.md-button--square.md-button--selected) {\n --_morph-to: var(--md-button-container-shape, var(--_shape-round));\n}\n\n/* ── Pressed shape — both round & square morph to more square, overrides selected ── */\n:host(.md-button--pressed.md-button--xs) {\n --_morph-to: var(--md-sys-shape-corner-extra-small, 4px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--sm) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--md) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--lg) {\n --_morph-to: var(--md-sys-shape-corner-medium, 12px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--xl) {\n --_morph-to: var(--md-sys-shape-corner-large, 16px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n 2c. CONNECTED GROUP — per-corner border-radius\n Set by md-button-group when variant=\"connected\".\n shapeMorph is disabled for connected children so these rules\n only need to beat the base shape rules (section 2, specificity 0-1-0).\n ========================================================== */\n\n:host(.md-button--connected-left.md-button--xs),\n:host(.md-button--connected-right.md-button--xs) { --_c-inner: 4px; }\n:host(.md-button--connected-left.md-button--sm),\n:host(.md-button--connected-right.md-button--sm) { --_c-inner: 8px; }\n:host(.md-button--connected-left.md-button--md),\n:host(.md-button--connected-right.md-button--md) { --_c-inner: 8px; }\n:host(.md-button--connected-left.md-button--lg),\n:host(.md-button--connected-right.md-button--lg) { --_c-inner: 16px; }\n:host(.md-button--connected-left.md-button--xl),\n:host(.md-button--connected-right.md-button--xl) { --_c-inner: 20px; }\n\n/* Middle button — all corners inner */\n:host(.md-button--connected-left.md-button--connected-right) {\n border-radius: var(--_c-inner);\n}\n\n/* `connected-left` / `connected-right` reflect DOM-order siblings (set by\n md-button-group when a previous / next sibling exists), so the radii\n here must use logical corner properties to flip correctly under\n `dir=\"rtl\"`. The outer pill always lives on the free inline-start\n (first child) or inline-end (last child) edge. */\n\n/* First button (round) — pill on inline-start edge, inner on inline-end edge */\n:host(.md-button--round.md-button--connected-right:not(.md-button--connected-left)) {\n border-start-start-radius: var(--_shape-round);\n border-end-start-radius: var(--_shape-round);\n border-start-end-radius: var(--_c-inner);\n border-end-end-radius: var(--_c-inner);\n}\n\n/* Last button (round) — inner on inline-start edge, pill on inline-end edge */\n:host(.md-button--round.md-button--connected-left:not(.md-button--connected-right)) {\n border-start-start-radius: var(--_c-inner);\n border-end-start-radius: var(--_c-inner);\n border-start-end-radius: var(--_shape-round);\n border-end-end-radius: var(--_shape-round);\n}\n\n/* Square first / last — outer equals inner */\n:host(.md-button--square.md-button--connected-right:not(.md-button--connected-left)),\n:host(.md-button--square.md-button--connected-left:not(.md-button--connected-right)) {\n border-radius: var(--_c-inner);\n}\n\n/* ==========================================================\n 3. ICON PADDING\n An icon does NOT change the button's insets. The M3 Expressive size sheet\n specifies the SAME padding on both sides whether or not a leading icon is\n present (12/12, 16/16, 24/24, 48/48, 64/64) — the third number on those\n drawings is the icon-to-label gap, not a reduced leading inset. The size's\n base padding therefore applies symmetrically and there is nothing to override.\n ========================================================== */\n\n/* ==========================================================\n 4. COLOR VARIANTS\n --md-button-container-color and --md-button-label-color\n override the variant defaults when set.\n ========================================================== */\n\n/* Filled */\n:host(.md-button--filled) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-primary));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-primary));\n --_state-layer-color: var(--md-sys-color-on-primary);\n}\n:host(.md-button--filled:hover) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--filled:active) { --_container-elevation: var(--md-sys-elevation-0, none); }\n:host(.md-button--filled:focus-visible) { --_container-elevation: var(--md-sys-elevation-0, none); }\n\n/* Outlined */\n:host(.md-button--outlined) {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n border: var(--md-button-outline-width, 1px) solid var(--md-button-outline-color, var(--md-sys-color-outline));\n}\n:host(.md-button--outlined.md-button--xs) { padding: 0 max(3px, calc(11px + var(--md-sys-density-scale, 0) * 2px)); }\n:host(.md-button--outlined.md-button--sm) { padding: 0 max(7px, calc(23px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--outlined.md-button--md) { padding: 0 max(9px, calc(27px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--outlined.md-button--lg) { padding: 0 max(10px, calc(31px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--outlined.md-button--xl) { padding: 0 max(15px, calc(47px + var(--md-sys-density-scale, 0) * 2px)); }\n:host(.md-button--outlined:hover:not(.md-button--disabled)) {\n border-color: var(--md-button-outline-color, var(--md-sys-color-primary));\n}\n:host(.md-button--outlined:focus-visible) {\n border-color: var(--md-button-outline-color, var(--md-sys-color-primary));\n}\n\n/* Text */\n:host(.md-button--text) {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n}\n:host(.md-button--text.md-button--xs) { padding: 0 max(3px, calc(8px + var(--md-sys-density-scale, 0) * 2px)); }\n:host(.md-button--text.md-button--sm) { padding: 0 max(4px, calc(12px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--text.md-button--md) { padding: 0 max(5px, calc(16px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--text.md-button--lg) { padding: 0 max(6px, calc(20px + var(--md-sys-density-scale, 0) * 4px)); }\n:host(.md-button--text.md-button--xl) { padding: 0 max(10px, calc(32px + var(--md-sys-density-scale, 0) * 2px)); }\n\n/* Elevated */\n:host(.md-button--elevated) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-low));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n --_container-elevation: var(--md-sys-elevation-1);\n}\n:host(.md-button--elevated:hover) { --_container-elevation: var(--md-sys-elevation-2); }\n:host(.md-button--elevated:focus-visible) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--elevated:active) { --_container-elevation: var(--md-sys-elevation-1); }\n\n/* Tonal */\n:host(.md-button--tonal) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-secondary-container));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-secondary-container));\n --_state-layer-color: var(--md-sys-color-on-secondary-container);\n}\n:host(.md-button--tonal:hover) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--tonal:focus-visible) { --_container-elevation: var(--md-sys-elevation-0, none); }\n:host(.md-button--tonal:active) { --_container-elevation: var(--md-sys-elevation-0, none); }\n\n/* ==========================================================\n 4b. TOGGLE SELECTED / UNSELECTED — MD3 spec\n When toggle=true, the unselected state is muted; selected\n shows the full variant color. Mirrors md-icon-button pattern.\n ========================================================== */\n\n/* The toggle-state rules below all carry `:not(.md-button--disabled)` so\n they drop out when the host becomes disabled. Without it, their higher\n specificity (4 classes vs the disabled rules' 2–3) would override the\n muted disabled palette and the button would still look enabled. */\n\n/* ── Filled toggle ── */\n:host(.md-button--filled.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n}\n\n/* ── Tonal toggle ── */\n:host(.md-button--tonal.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* ── Outlined toggle ── */\n:host(.md-button--outlined.md-button--toggle.md-button--selected:not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-secondary-container, #1E192B));\n --_state-layer-color: var(--md-sys-color-on-secondary-container, #1E192B);\n border-color: transparent;\n}\n\n/* ── Elevated toggle ── */\n:host(.md-button--elevated.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n/* ── Text toggle ── */\n:host(.md-button--text.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* ==========================================================\n 5. STATE LAYER\n ========================================================== */\n.md-button__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n:host(:hover) .md-button__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n:host(:active:not(.md-button--disabled)) .md-button__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n transition-duration: var(--md-sys-motion-duration-short1, 50ms);\n transition-timing-function: var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n:host(:focus-visible) .md-button__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 6. FOCUS RING\n `z-index: 1` raises the focused button above its siblings so the\n outline is never clipped by a neighbor — important inside\n md-button-group, where connected groups have only 2px between\n buttons and standard groups animate neighbor padding on press.\n ========================================================== */\n/* Connected children inside md-button-group sit only 2px apart, so a\n 3px-outset focus ring naturally extends across the neighbor. The\n `z-index: 1` raise lets it draw *on top* of the neighbor cleanly so\n the ring keeps its full 2px breathing room — same visual treatment\n as a stand-alone button. */\n:host(:focus-visible) {\n outline-color: var(--md-sys-color-secondary);\n z-index: 1;\n}\n\n/* ==========================================================\n 7. DISABLED\n ========================================================== */\n:host(.md-button--disabled) {\n cursor: default;\n pointer-events: none;\n --_container-elevation: var(--md-sys-elevation-0, none) !important;\n transition: none;\n}\n\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n:host([soft-disabled]) .md-button__state-layer { display: none; }\n\n:host(.md-button--filled.md-button--disabled),\n:host(.md-button--tonal.md-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n:host(.md-button--elevated.md-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-button--disabled) {\n --_label-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-button--outlined.md-button--disabled) {\n --_container-color: transparent;\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-button--text.md-button--disabled) {\n --_container-color: transparent;\n}\n\n:host(.md-button--disabled:hover) .md-button__state-layer,\n:host(.md-button--disabled:active) .md-button__state-layer,\n:host(.md-button--disabled:focus-visible) .md-button__state-layer {\n opacity: 0;\n}\n\n/* ==========================================================\n 8. ICON (prop-based fallback inside slot)\n ========================================================== */\n.md-button__icon,\n.md-button__trailing-icon {\n color: var(--md-button-icon-color, inherit);\n font-size: var(--_icon-size, 18px);\n width: var(--_icon-size, 18px);\n height: var(--_icon-size, 18px);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 9. NAMED ICON SLOTS\n Slots use display:contents so they don't create a box;\n slotted content participates directly in flex layout.\n ========================================================== */\nslot[name=\"leading-icon\"],\nslot[name=\"trailing-icon\"] {\n display: contents;\n}\n\n::slotted([slot=\"leading-icon\"]),\n::slotted([slot=\"trailing-icon\"]) {\n color: var(--md-button-icon-color, inherit);\n width: var(--_icon-size, 18px);\n height: var(--_icon-size, 18px);\n flex-shrink: 0;\n}\n\n/* ----------------------------------------------------------\n Trailing-icon rotation when this button is a popover anchor.\n\n md-menu (and any other popup component using the same ARIA\n contract) sets aria-expanded=\"true\" on its anchor element\n while the popup is open. Rotating the trailing dropdown\n indicator 180° on that signal flips arrow_drop_down to\n point up, matching MD3 select-trigger behavior, with no\n wiring needed on the consumer side.\n\n Honors prefers-reduced-motion via short2 motion duration.\n ---------------------------------------------------------- */\n.md-button__trailing-icon,\n::slotted([slot=\"trailing-icon\"]) {\n transition: transform var(--md-sys-motion-duration-short2, 150ms)\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host([aria-expanded=\"true\"]:not([suppress-expand-icon-flip])) .md-button__trailing-icon,\n:host([aria-expanded=\"true\"]:not([suppress-expand-icon-flip])) ::slotted([slot=\"trailing-icon\"]) {\n transform: rotate(180deg);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-button__state-layer {\n transition: none;\n }\n\n .md-button__trailing-icon,\n ::slotted([slot=\"trailing-icon\"]) {\n transition: none;\n }\n}\n\n/* ==========================================================\n 10. LABEL\n ========================================================== */\n.md-button__label {\n display: flex;\n align-items: center;\n white-space: nowrap;\n}\n\n/* ==========================================================\n 11. LOADING SPINNER (scales with icon size)\n ========================================================== */\n.md-button__loading {\n /* A FRACTION of the icon it stands in for. Two constraints pull against each\n other: at full --_icon-size the ring reads heavier than the glyph (a bare\n stroke has none of the internal padding a Material glyph carries), but at\n 1em it was pinned to the label and stopped scaling per tier -- sm and md\n share a 14px label, so a 40px and a 56px button drew the same 14px ring\n despite 20px vs 24px icons. 0.7 keeps it visibly lighter than a glyph while\n tracking the tier, and inherits the icon's density taper. */\n /* 10px floor: the icon token itself bottoms out at 10px on the small tiers,\n and 0.7 of that is a 7px ring — too small to read as a spinner at all. */\n --_loading-size: var(--md-button-loading-size, max(10px, calc(var(--_icon-size, 18px) * 0.7)));\n\n /* Hand the size straight to md-loading-indicator's PUBLIC hooks. These\n replace the child's whole default expression, so the button's own taper\n (and its 10px floor) survives instead of hitting the child's 32px floor.\n Not --_size / --_shape-size: those are the child's private vars and\n writing them from out here is the handoff trap. currentColor keeps the\n indicator matching each variant's label, which a token would not. */\n --md-loading-indicator-size: var(--_loading-size);\n --md-loading-indicator-shape-size: var(--_loading-size);\n --md-loading-indicator-color: currentColor;\n flex-shrink: 0;\n /* A wrapper now, so the hooks above reach a SLOTTED replacement too. It has\n to lay out like the indicator it replaced — an inline span would add a text\n baseline gap next to the label. */\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Whatever the consumer slots in gets the same box the default occupies. */\n.md-button__loading ::slotted(*) {\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 12. MATERIAL SYMBOLS (default icon font)\n ========================================================== */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-weight: normal;\n font-style: normal;\n font-size: var(--_icon-size, 18px);\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* ==========================================================\n 13. RTL — opt-in directional-icon mirroring\n\n Buttons that show directional Material Symbols (arrow_forward,\n chevron_right, send, reply…) should set `mirror-icon` so the\n glyph itself flips alongside the leading/trailing slot swap that\n the logical-property layout already performs. Non-directional\n icons (add, search, favorite…) leave `mirror-icon` unset so the\n glyph stays semantically correct.\n\n Two rules cover both placements of `dir=\"rtl\"`:\n (a) on the host itself — `:host([dir=\"rtl\"])`\n (b) on any ancestor element — `:host-context([dir=\"rtl\"])`\n ========================================================== */\n:host([mirror-icon][dir=\"rtl\"]) .md-button__icon,\n:host([mirror-icon][dir=\"rtl\"]) .md-button__trailing-icon,\n:host([mirror-icon][dir=\"rtl\"]) ::slotted([slot=\"leading-icon\"]),\n:host([mirror-icon][dir=\"rtl\"]) ::slotted([slot=\"trailing-icon\"]) {\n transform: scaleX(-1);\n}\n\n:host-context([dir=\"rtl\"]):host([mirror-icon]) .md-button__icon,\n:host-context([dir=\"rtl\"]):host([mirror-icon]) .md-button__trailing-icon,\n:host-context([dir=\"rtl\"]):host([mirror-icon]) ::slotted([slot=\"leading-icon\"]),\n:host-context([dir=\"rtl\"]):host([mirror-icon]) ::slotted([slot=\"trailing-icon\"]) {\n transform: scaleX(-1);\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, AttachInternals } from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\n/**\n * Detail payload emitted by `md-button`'s `mdClick` event when the user\n * activates the button (mouse, touch, or keyboard).\n *\n * The event is **cancelable** — calling `event.preventDefault()` from a\n * listener stops the button's default side effects (toggle-state flip\n * and `href` navigation) but does NOT stop the underlying DOM click\n * event. This is the recommended hook for SPA routing and \"are you\n * sure?\" confirmation flows.\n */\nexport interface MdButtonClickDetail {\n /** The button's `value` prop (useful when grouped via `md-button-group`). */\n value: string;\n /** Whether toggle mode is enabled. */\n toggle: boolean;\n /**\n * Selected state the button WILL transition to if the click is not\n * cancelled. In non-toggle mode this is identical to `selected`.\n */\n selected: boolean;\n /** Navigation target (empty if the button is not a link). */\n href: string;\n /** Browsing context (`_self`, `_blank`, …). */\n target: string;\n /** The original DOM event that triggered the activation. */\n originalEvent: MouseEvent | KeyboardEvent;\n}\n\n/**\n * Detail payload emitted by `md-button`'s `mdChange` event when toggle\n * mode flips the selected state in response to a user activation.\n */\nexport interface MdButtonChangeDetail {\n /** New selected state. */\n selected: boolean;\n /** The button's `value` prop. */\n value: string;\n}\n\n@Component({\n tag: 'md-button',\n styleUrl: 'md-button.css',\n shadow: true,\n formAssociated: true,\n})\nexport class MdButton {\n @Element() el!: HTMLElement;\n\n /**\n * Form-association handle. Used to submit/reset the associated form when\n * `type` is `submit`/`reset` — works across shadow boundaries, unlike a\n * native `<button>` rendered in the shadow root (which can't see the\n * light-DOM `<form>` it lives in).\n */\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Activation behavior, mirroring the native `<button type>`:\n * - `button` (default): no implicit form action.\n * - `submit`: submits the associated form (`requestSubmit`, so the form's\n * `submit` event fires and constraint validation runs).\n * - `reset`: resets the associated form.\n */\n @Prop({ reflect: true }) type: 'button' | 'submit' | 'reset' = 'button';\n\n @Prop() variant: 'filled' | 'outlined' | 'text' | 'elevated' | 'tonal' = 'filled';\n @Prop() size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';\n @Prop() shape: 'round' | 'square' = 'round';\n @Prop({ reflect: true }) disabled: boolean = false;\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n @Prop() ripple: boolean = true;\n @Prop() loading: boolean = false;\n @Prop() icon: string = '';\n @Prop() trailingIcon: string = '';\n @Prop() href: string = '';\n @Prop() target: string = '_self';\n\n /** Enable toggle behavior (selected/unselected) */\n @Prop() toggle: boolean = false;\n\n /** Current selected state (toggle mode) */\n @Prop({ mutable: true }) selected: boolean = false;\n\n /** Enable M3 Expressive shape morphing on press and toggle */\n @Prop() shapeMorph: boolean = true;\n\n /**\n * Mirror leading and trailing icons horizontally when the button is\n * rendered in a right-to-left context. Set this on buttons that use\n * **directional** Material Symbols (arrows, chevrons, send, reply…)\n * — non-directional icons (add, search, favorite…) should leave it\n * `false` so the glyph stays semantically correct.\n */\n @Prop({ reflect: true, attribute: 'mirror-icon' }) mirrorIcon: boolean = false;\n\n /**\n * When true, suppresses the default 180° trailing-icon rotation while\n * `aria-expanded=\"true\"`. Use when the consumer swaps the glyph (e.g.\n * docked `md-date-picker` month/year triggers use `chevron_right`).\n */\n @Prop({ reflect: true, attribute: 'suppress-expand-icon-flip' })\n suppressExpandIconFlip: boolean = false;\n\n /**\n * Stretch the button to fill its inline-axis container.\n *\n * Switches the host from `inline-flex` to `flex` and sets\n * `inline-size: 100%` so the button consumes the full width of its\n * parent — the standard pattern for primary CTAs in forms, modals,\n * and bottom sheets. The size's `min-block-size` (touch target) is\n * preserved.\n *\n * For arbitrary fixed widths or heights, set the\n * `--md-button-width`, `--md-button-height`, `--md-button-min-width`,\n * `--md-button-min-height`, or `--md-button-max-width` CSS custom\n * properties on the host instead.\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n /** @internal Set by md-button-group — left side is connected to a neighbor */\n @Prop({ reflect: true }) connectedLeft: boolean = false;\n\n /** @internal Set by md-button-group — right side is connected to a neighbor */\n @Prop({ reflect: true }) connectedRight: boolean = false;\n\n /** @internal Value for button-group association */\n @Prop() value: string = '';\n\n /**\n * @internal Roving-tabindex override set by `md-button-group`. When the\n * button is a child of a group, the group sets this to `0` on the\n * currently-active button and `-1` on the rest, so Tab enters the group\n * once instead of stepping through every button. Outside a group, this\n * stays `null` and the button uses its normal tabindex behavior.\n */\n @Prop({ mutable: true, reflect: false }) groupTabindex: number | null = null;\n\n /**\n * Override the default `role=\"button\"`. Used by composite widgets such as\n * `md-date-picker` day cells (`role=\"gridcell\"`). Leave empty for `button`.\n */\n @Prop({ attribute: 'role-override' }) roleOverride: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fires every time the user activates the button (mouse click, touch,\n * or `Enter`/`Space` while focused). The event is **cancelable** and\n * the detail payload describes what *would* happen: the post-click\n * toggle state, the navigation `href`, and so on.\n *\n * Calling `event.preventDefault()` from a listener suppresses the\n * default side effects (toggle flip + `href` navigation) but lets\n * the underlying DOM click bubble. This is the hook to use for SPA\n * routing, \"are you sure?\" prompts, async confirmation, etc.\n *\n * The event bubbles and is composed, so listeners outside the\n * shadow tree (the typical case) receive it.\n *\n * ```ts\n * document.querySelector('md-button')!.addEventListener('mdClick', (e) => {\n * const { href, selected } = (e as CustomEvent).detail;\n * if (!confirm('Continue?')) e.preventDefault();\n * });\n * ```\n */\n @Event({ cancelable: true, bubbles: true, composed: true })\n mdClick!: EventEmitter<MdButtonClickDetail>;\n\n /**\n * Fires when toggle mode flips the `selected` state in response to a\n * user activation. Not cancelable — the state change has already\n * happened. Pair with `mdClick` (cancelable) when you need a veto.\n *\n * Bubbles and is composed.\n */\n @Event({ bubbles: true, composed: true })\n mdChange!: EventEmitter<MdButtonChangeDetail>;\n\n @State() private hasSlottedLeadingIcon = false;\n @State() private hasSlottedTrailingIcon = false;\n @State() private pressed = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled || this.loading;\n }\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const leadingSlot = shadow.querySelector('slot[name=\"leading-icon\"]') as HTMLSlotElement | null;\n const trailingSlot = shadow.querySelector('slot[name=\"trailing-icon\"]') as HTMLSlotElement | null;\n\n leadingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedLeadingIcon = leadingSlot.assignedElements().length > 0;\n });\n trailingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedTrailingIcon = trailingSlot.assignedElements().length > 0;\n });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n\n // Compute the post-click toggle state up front so the detail\n // payload describes what *would* happen — listeners can then\n // call preventDefault on the CustomEvent to veto the change.\n const nextSelected = this.toggle ? !this.selected : this.selected;\n\n const evt = this.mdClick.emit({\n value: this.value,\n toggle: this.toggle,\n selected: nextSelected,\n href: this.href,\n target: this.target,\n originalEvent: e,\n });\n\n if (evt.defaultPrevented) {\n // Suppress browser's default link navigation as well so the\n // host stays consistent. We don't flip selected and don't\n // open the href.\n e.preventDefault();\n return;\n }\n\n if (this.toggle && nextSelected !== this.selected) {\n this.selected = nextSelected;\n this.mdChange.emit({ selected: nextSelected, value: this.value });\n }\n\n /* Setting `href` makes this a link rather than a form control, so the\n branch is taken on the raw prop — an unsafe URL must not silently fall\n through to submitting the form. Only the navigation itself is refused. */\n if (this.href) {\n const href = sanitizeHref(this.href);\n if (href) window.open(href, this.target, SAFE_WINDOW_FEATURES);\n return;\n }\n\n // Implicit form action, mirroring a native submit/reset button. Uses\n // ElementInternals so the associated <form> is found across the shadow\n // boundary. requestSubmit() (not submit()) so the form's submit event\n // fires and built-in constraint validation runs.\n if (this.type === 'submit') {\n this.internals.form?.requestSubmit();\n } else if (this.type === 'reset') {\n this.internals.form?.reset();\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n this.pressed = true;\n triggerRipple(this.el);\n this.el.click();\n setTimeout(() => { this.pressed = false; }, 150);\n }\n }\n };\n\n private handlePointerDown = () => {\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n const hasLeadingIcon = !!this.icon;\n const hasTrailingIcon = !!this.trailingIcon;\n\n return (\n <Host\n class={{\n 'md-button': true,\n [`md-button--${this.variant}`]: true,\n [`md-button--${this.size}`]: true,\n [`md-button--${this.shape}`]: true,\n 'md-button--with-leading-icon': hasLeadingIcon || this.hasSlottedLeadingIcon,\n 'md-button--with-trailing-icon': hasTrailingIcon || this.hasSlottedTrailingIcon,\n 'md-button--disabled': this.disabled || this.softDisabled,\n 'md-button--loading': this.loading,\n 'md-button--toggle': this.toggle,\n 'md-button--selected': this.selected,\n 'md-button--shape-morph': this.shapeMorph,\n 'md-button--pressed': this.shapeMorph && this.pressed,\n 'md-button--connected-left': this.connectedLeft,\n 'md-button--connected-right': this.connectedRight,\n 'md-button--full-width': this.fullWidth,\n }}\n role={this.roleOverride || 'button'}\n aria-disabled={isEffectivelyDisabled ? 'true' : 'false'}\n aria-pressed={this.toggle ? String(this.selected) : undefined}\n tabindex={\n this.disabled\n ? '-1'\n : (this.groupTabindex !== null ? String(this.groupTabindex) : '0')\n }\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n {this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n <span class=\"md-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n <slot name=\"leading-icon\">\n {hasLeadingIcon && <span class=\"md-button__icon material-symbols-outlined\" part=\"icon\">{this.icon}</span>}\n </slot>\n <span class=\"md-button__label\" part=\"label\"><slot /></span>\n <slot name=\"trailing-icon\">\n {hasTrailingIcon && <span class=\"md-button__trailing-icon material-symbols-outlined\" part=\"trailing-icon\">{this.trailingIcon}</span>}\n </slot>\n {this.loading && (\n /* md-loading-indicator, not a hand-rolled ring: never ship a custom\n loading affordance where a library component exists. It is\n md-loading-indicator rather than md-progress-indicator because the\n latter clamps its circular variant to a 24dp M3 minimum, while a\n button spinner runs 10-28px -- every tier but xl would clamp up and\n lose the density taper. Same choice md-select made for its trigger.\n\n The `loader` slot lets a consumer swap it (e.g. for a circular\n md-progress-indicator). The size hooks sit on this WRAPPER so they\n cascade to whatever ends up inside it, default or slotted. */\n <span class=\"md-button__loading\" part=\"loading\" aria-hidden=\"true\">\n <slot name=\"loader\">\n <md-loading-indicator class=\"md-button__loading-default\" />\n </slot>\n </span>\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import{p as t,H as s,c as i,h as e,d as o,t as n}from"./p-MWBNn6Lj.js";const r=()=>`:host{display:inline-block;position:relative}.md-tooltip__popup{position:fixed;z-index:var(--md-sys-z-index-tooltip, 1500);pointer-events:none;box-sizing:border-box;width:max-content;opacity:0;visibility:hidden;transform:scale(0.9);transition:opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, ease), transform var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, ease), visibility 0ms linear var(--md-sys-motion-duration-short2, 100ms)}.md-tooltip__popup--visible{opacity:1;visibility:visible;transform:scale(1);pointer-events:auto;transition:opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, ease), transform var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, ease), visibility 0ms linear 0ms}.md-tooltip__popup--plain{--_container-color:var(--md-tooltip-plain-container-color, var(--md-sys-color-inverse-surface, #313033));--_text-color:var(--md-tooltip-plain-text-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));--_shape:var(--md-tooltip-container-shape, var(--md-sys-shape-corner-extra-small, 4px));background-color:var(--_container-color);color:var(--_text-color);border-radius:var(--_shape);padding-block:var(--md-sys-spacing-inset-xs, 4px);padding-inline:var(--md-sys-spacing-inset-sm, 8px);min-block-size:max(20px, calc(24px + var(--md-sys-density-scale, 0) * 1px));max-inline-size:min(var(--md-tooltip-plain-max-inline-size, 280px), calc(100vw - 16px));font-family:var(--md-sys-typescale-body-small-font-family, Roboto, sans-serif);font-size:max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px));font-weight:var(--md-sys-typescale-body-small-font-weight, 400);line-height:max(14px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));letter-spacing:var(--md-sys-typescale-body-small-letter-spacing, 0.4px);white-space:normal;display:flex;align-items:center}.md-tooltip__text{overflow-wrap:anywhere}.md-tooltip__popup--rich{--_container-color:var(--md-tooltip-rich-container-color, var(--md-sys-color-surface-container, #F3EDF7));--_subhead-color:var(--md-tooltip-rich-subhead-color, var(--md-sys-color-on-surface-variant, #49454F));--_text-color:var(--md-tooltip-rich-text-color, var(--md-sys-color-on-surface-variant, #49454F));--_action-color:var(--md-tooltip-rich-action-color, var(--md-sys-color-primary, #6750A4));--_shape:var(--md-tooltip-rich-container-shape, var(--md-sys-shape-corner-medium, 12px));background-color:var(--_container-color);color:var(--_text-color);border-radius:var(--_shape);padding-block-start:var(--md-sys-spacing-inset-md, 12px);padding-block-end:var(--md-sys-spacing-inset-sm, 8px);padding-inline:var(--md-sys-spacing-inset-lg, 16px);min-inline-size:var(--md-tooltip-rich-min-inline-size, 120px);max-inline-size:min(var(--md-tooltip-rich-max-inline-size, 320px), calc(100vw - 16px));white-space:normal;box-shadow:var(--md-sys-elevation-2, 0 1px 3px 1px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.3))}.md-tooltip__subhead{font-family:var(--md-sys-typescale-title-small-font-family, Roboto, sans-serif);font-size:max(11px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));font-weight:var(--md-sys-typescale-title-small-font-weight, 500);line-height:max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));letter-spacing:var(--md-sys-typescale-title-small-letter-spacing, 0.1px);color:var(--_subhead-color);margin-block-end:var(--md-sys-spacing-gap-xs, 4px)}.md-tooltip__supporting-text{font-family:var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);font-size:max(11px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));font-weight:var(--md-sys-typescale-body-medium-font-weight, 400);line-height:max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));letter-spacing:var(--md-sys-typescale-body-medium-letter-spacing, 0.25px);color:var(--_text-color)}.md-tooltip__actions{display:flex;gap:var(--md-sys-spacing-gap-sm, 8px);justify-content:flex-end;margin-block-start:var(--md-sys-spacing-gap-md, 12px);color:var(--_action-color)}.md-tooltip__actions--empty{display:none}::slotted([slot="actions"]){color:var(--_action-color)}.md-tooltip__popup--top,.md-tooltip__popup--top-start,.md-tooltip__popup--top-end{transform-origin:bottom center}.md-tooltip__popup--bottom,.md-tooltip__popup--bottom-start,.md-tooltip__popup--bottom-end{transform-origin:top center}.md-tooltip__popup--left,.md-tooltip__popup--left-start,.md-tooltip__popup--left-end{transform-origin:center right}.md-tooltip__popup--right,.md-tooltip__popup--right-start,.md-tooltip__popup--right-end{transform-origin:center left}:host-context([dir="rtl"]) .md-tooltip__actions{justify-content:flex-start}@media (forced-colors: active){.md-tooltip__popup{border:1px solid CanvasText}}@media (prefers-reduced-motion: reduce){.md-tooltip__popup,.md-tooltip__popup--visible{transition:none;transform:none}}:host([density='-1']){--md-sys-density-scale:-1}:host([density='-2']){--md-sys-density-scale:-2}:host([density='-3']){--md-sys-density-scale:-3}:host([density='-4']){--md-sys-density-scale:-4}`;const a=8;const h=t(class t extends s{constructor(t){super();if(t!==false){this.__registerHost()}this.__attachShadow();this.mdOpen=i(this,"mdOpen",1);this.mdClose=i(this,"mdClose",1);this.text="";this.subhead="";this.variant="plain";this.position="top";this.autoPosition=true;this.offset=8;this.crossOffset=0;this.open=false;this.showDelay=500;this.hideDelay=200;this.disabled=false;this.density=0;this.isVisible=false;this.resolvedPlacement="top";this.hasSlottedActions=false;this.hasSlottedSubhead=false;this.tooltipId=`md-tooltip-${Math.random().toString(36).slice(2,9)}`;this.scrollListenerBound=false;this.escapeListenerBound=false;this.hostHoverBound=false;this.hasLoaded=false;this.suppressed=false;this.onTriggerSlotChange=()=>{const t=this.triggerSlot?.assignedElements();if(t&&t.length>0)this.bindTrigger(t[0])};this.handleTriggerEnter=()=>this.scheduleShow();this.handleTriggerLeave=()=>{this.suppressed=false;this.scheduleHide()};this.handleTriggerFocus=()=>this.scheduleShow();this.handleTriggerBlur=t=>{if(t.relatedTarget&&this.el.contains(t.relatedTarget))return;this.suppressed=false;this.scheduleHide()};this.handleHostFocusOut=t=>{if(this.variant!=="rich"||!this.isVisible)return;if(t.relatedTarget&&this.el.contains(t.relatedTarget))return;this.scheduleHide()};this.handlePopupEnter=()=>{this.clearTimers()};this.handlePopupLeave=()=>{this.scheduleHide()};this.handleGlobalEscape=t=>{if(t.key!=="Escape"||!this.isVisible)return;t.preventDefault();this.clearTimers();this.suppressed=true;const s=this.getDeepActiveElement();const i=!!s&&(this.el.contains(s)||s===this.triggerEl);this.open=false;if(i&&this.triggerEl)this.triggerEl.focus()};this.lastGeom={at:0,al:0,aw:0,ah:0,pw:0,ph:0,vw:0,vh:0,ex:0,ey:0};this.watchdogFrame=0;this.handleScroll=()=>{if(this.isVisible)this.updatePosition()}}componentWillLoad(){this.syncSlotFlags();if(this.open&&!this.disabled)this.isVisible=true}componentDidLoad(){this.hasLoaded=true;this.setup();if(this.open)this.showTooltip()}connectedCallback(){if(!this.hasLoaded)return;this.setup();if(this.isVisible&&!this.disabled){this.addScrollListener();this.addEscapeListener();this.schedulePositionUpdate();this.startPositionWatchdog()}else if(this.open&&!this.isVisible&&!this.disabled){this.showTooltip()}}setup(){const t=this.el.shadowRoot;if(!t)return;this.triggerSlot=t.querySelector("slot:not([name])")??undefined;this.triggerSlot?.addEventListener("slotchange",this.onTriggerSlotChange);this.el.addEventListener("focusout",this.handleHostFocusOut);this.syncSlotFlags();if(typeof MutationObserver!=="undefined"&&!this.slotObserver){this.slotObserver=new MutationObserver((()=>{this.syncSlotFlags();if(this.triggerEl)this.updateTriggerAria(this.triggerEl)}));this.slotObserver.observe(this.el,{childList:true,subtree:true,characterData:true})}const s=this.triggerSlot?.assignedElements()[0];if(s)this.bindTrigger(s)}syncSlotFlags(){const t=Array.from(this.el.children);this.hasSlottedActions=t.some((t=>t.getAttribute("slot")==="actions"));this.hasSlottedSubhead=t.some((t=>t.getAttribute("slot")==="subhead"))}disconnectedCallback(){this.clearTimers();this.stopPositionWatchdog();this.unbindTrigger();this.removeScrollListener();this.removeEscapeListener();this.el.removeEventListener("focusout",this.handleHostFocusOut);this.triggerSlot?.removeEventListener("slotchange",this.onTriggerSlotChange);this.triggerSlot=undefined;this.slotObserver?.disconnect();this.slotObserver=undefined}onOpenChange(t){if(t){this.showTooltip()}else{this.hideTooltip()}}onDisabledChange(t){if(t){this.clearTimers();if(this.open)this.open=false;this.triggerEl?.removeAttribute("aria-description")}else if(this.triggerEl){this.updateTriggerAria(this.triggerEl)}}onDescriptionChange(){if(this.triggerEl)this.updateTriggerAria(this.triggerEl)}async show(){if(this.disabled)return;this.open=true}async hide(){this.open=false}bindTrigger(t){this.unbindTrigger();this.triggerEl=t;if(this.useHostHover(t)){this.el.addEventListener("mouseenter",this.handleTriggerEnter);this.el.addEventListener("mouseleave",this.handleTriggerLeave);this.hostHoverBound=true}else{t.addEventListener("mouseenter",this.handleTriggerEnter);t.addEventListener("mouseleave",this.handleTriggerLeave)}t.addEventListener("focus",this.handleTriggerFocus);t.addEventListener("blur",this.handleTriggerBlur);this.updateTriggerAria(t)}unbindTrigger(){if(this.hostHoverBound){this.el.removeEventListener("mouseenter",this.handleTriggerEnter);this.el.removeEventListener("mouseleave",this.handleTriggerLeave);this.hostHoverBound=false}else if(this.triggerEl){this.triggerEl.removeEventListener("mouseenter",this.handleTriggerEnter);this.triggerEl.removeEventListener("mouseleave",this.handleTriggerLeave)}if(!this.triggerEl)return;this.triggerEl.removeEventListener("focus",this.handleTriggerFocus);this.triggerEl.removeEventListener("blur",this.handleTriggerBlur);this.triggerEl.removeAttribute("aria-description");this.triggerEl=undefined}useHostHover(t){const s=t.tagName.toLowerCase();if(s==="button"||s==="a"||s==="input"||s==="select"||s==="textarea"){return false}if(t.hasAttribute("tabindex")&&t.tabIndex>=0)return false;if(s.startsWith("md-"))return false;return true}updateTriggerAria(t){if(this.disabled){t.removeAttribute("aria-description");return}const s=this.computeDescription();if(s){t.setAttribute("aria-description",s)}else{t.removeAttribute("aria-description")}}computeDescription(){if(this.text)return this.text;if(this.subhead)return this.subhead;const t=[];for(const s of Array.from(this.el.children)){const i=s.getAttribute("slot");if(i==="subhead"||i==="content"){const i=(s.textContent||"").trim();if(i)t.push(i)}}return t.join(". ")}scheduleShow(){if(this.disabled||this.suppressed)return;this.clearTimers();this.showTimer=setTimeout((()=>{this.open=true}),this.showDelay)}scheduleHide(){this.clearTimers();this.hideTimer=setTimeout((()=>{this.open=false}),this.hideDelay)}getDeepActiveElement(){if(typeof document==="undefined")return null;let t=document.activeElement;while(t&&t.shadowRoot&&t.shadowRoot.activeElement)t=t.shadowRoot.activeElement;return t}addEscapeListener(){if(!this.escapeListenerBound){document.addEventListener("keydown",this.handleGlobalEscape,true);this.escapeListenerBound=true}}removeEscapeListener(){if(this.escapeListenerBound){document.removeEventListener("keydown",this.handleGlobalEscape,true);this.escapeListenerBound=false}}showTooltip(){if(this.disabled)return;if(!this.el.isConnected)return;this.isVisible=true;this.mdOpen.emit();this.addScrollListener();this.addEscapeListener();this.schedulePositionUpdate();this.startPositionWatchdog()}schedulePositionUpdate(t=0){requestAnimationFrame((()=>{const s=this.updatePosition();if(!s&&t<3){this.schedulePositionUpdate(t+1)}}))}startPositionWatchdog(){if(typeof requestAnimationFrame!=="function")return;this.stopPositionWatchdog();const t=()=>{if(!this.isVisible||!this.el.isConnected){this.watchdogFrame=0;return}const s=this.popupEl;if(s&&this.triggerEl){const t=s.offsetWidth;const i=s.offsetHeight;if(t!==0||i!==0){const e=this.getAnchorRect();const o=s.getBoundingClientRect();const n=this.lastGeom;const r=e.top!==n.at||e.left!==n.al||e.width!==n.aw||e.height!==n.ah||t!==n.pw||i!==n.ph||Math.abs(o.top-n.ey)>.5||Math.abs(o.left-n.ex)>.5||window.innerWidth!==n.vw||window.innerHeight!==n.vh;if(r)this.updatePosition()}}this.watchdogFrame=requestAnimationFrame(t)};this.watchdogFrame=requestAnimationFrame(t)}stopPositionWatchdog(){if(this.watchdogFrame&&typeof cancelAnimationFrame==="function"){cancelAnimationFrame(this.watchdogFrame)}this.watchdogFrame=0}hideTooltip(){if(!this.isVisible)return;this.isVisible=false;this.mdClose.emit();this.removeScrollListener();this.removeEscapeListener();this.stopPositionWatchdog()}clearTimers(){if(this.showTimer!=null){clearTimeout(this.showTimer);this.showTimer=undefined}if(this.hideTimer!=null){clearTimeout(this.hideTimer);this.hideTimer=undefined}}addScrollListener(){if(!this.scrollListenerBound){window.addEventListener("scroll",this.handleScroll,{capture:true,passive:true});this.scrollListenerBound=true}}removeScrollListener(){if(this.scrollListenerBound){window.removeEventListener("scroll",this.handleScroll,true);this.scrollListenerBound=false}}updatePosition(){if(!this.popupEl||!this.triggerEl)return false;const t=this.getAnchorRect();const s=this.popupEl.offsetWidth;const i=this.popupEl.offsetHeight;if(s===0&&i===0)return false;let e=this.physicalPlacement(this.position);if(this.autoPosition){e=this.findBestPlacement(t,s,i,e)}const o=this.calcCoords(t.width,t.height,s,i,e);if(e.startsWith("top")||e.startsWith("bottom")){o.left+=this.crossOffset}else{o.top+=this.crossOffset}if(this.autoPosition){const n=e.startsWith("top")||e.startsWith("bottom");const r=a;if(n){const i=t.left+o.left;const e=window.innerWidth-s-r;const n=Math.min(Math.max(i,r),Math.max(r,e));o.left+=n-i}else{const s=t.top+o.top;const e=window.innerHeight-i-r;const n=Math.min(Math.max(s,r),Math.max(r,e));o.top+=n-s}}const n=this.toFixedCoords(t.top+o.top,t.left+o.left);this.popupEl.style.top=`${n.top}px`;this.popupEl.style.left=`${n.left}px`;this.popupEl.style.insetBlockStart="";this.popupEl.style.insetInlineStart="";this.resolvedPlacement=e;this.lastGeom={at:t.top,al:t.left,aw:t.width,ah:t.height,pw:s,ph:i,vw:window.innerWidth,vh:window.innerHeight,ex:t.left+o.left,ey:t.top+o.top};return true}getAnchorRect(){if(this.triggerEl){const t=this.triggerEl.getBoundingClientRect();if(t.width>0||t.height>0)return t}return this.el.getBoundingClientRect()}toFixedCoords(t,s){const i=this.getFixedContainingBlock();if(!i){return{top:t,left:s}}const e=i.getBoundingClientRect();return{top:t-e.top,left:s-e.left}}createsFixedContainingBlock(t){const s=t;if(t.transform&&t.transform!=="none"||t.filter&&t.filter!=="none"||t.perspective&&t.perspective!=="none")return true;if(s.translate&&s.translate!=="none"||s.rotate&&s.rotate!=="none"||s.scale&&s.scale!=="none")return true;if(s.backdropFilter&&s.backdropFilter!=="none")return true;if(/\b(transform|perspective|filter|translate|rotate|scale)\b/.test(t.willChange||""))return true;if(/(layout|paint|strict|content)\b/.test(s.contain||""))return true;if(s.contentVisibility==="auto"||s.contentVisibility==="hidden")return true;if(s.containerType&&/\bsize\b/.test(s.containerType))return true;return false}getFixedContainingBlock(){let t=this.el;while(t){if(this.createsFixedContainingBlock(getComputedStyle(t))){return t}if(t.parentElement){t=t.parentElement}else if(t.parentNode instanceof ShadowRoot){t=t.parentNode.host}else{t=null}}return null}physicalPlacement(t){if(typeof window==="undefined")return t;const s=getComputedStyle(this.el).direction==="rtl";if(!s)return t;const[i,e=""]=[t.split("-")[0],t.split("-").slice(1).join("-")];const o=i==="left"?"right":i==="right"?"left":i;const n=i==="top"||i==="bottom"?e==="start"?"end":e==="end"?"start":e:e;return n?`${o}-${n}`:o}calcCoords(t,s,i,e,o){const n=this.offset;switch(o){case"top":return{top:-(e+n),left:(t-i)/2};case"top-start":return{top:-(e+n),left:0};case"top-end":return{top:-(e+n),left:t-i};case"bottom":return{top:s+n,left:(t-i)/2};case"bottom-start":return{top:s+n,left:0};case"bottom-end":return{top:s+n,left:t-i};case"left":return{top:(s-e)/2,left:-(i+n)};case"left-start":return{top:0,left:-(i+n)};case"left-end":return{top:s-e,left:-(i+n)};case"right":return{top:(s-e)/2,left:t+n};case"right-start":return{top:0,left:t+n};case"right-end":return{top:s-e,left:t+n};default:return{top:-(e+n),left:(t-i)/2}}}fitsMainAxis(t,s,i,e,o,n){const r=n.startsWith("top")||n.startsWith("bottom");if(r){const s=t.top+e;return s>=0&&s+i<=window.innerHeight}const a=t.left+o;return a>=0&&a+s<=window.innerWidth}getOppositePlacement(t){const[s,i]=[t.split("-")[0],t.split("-").slice(1).join("-")];const e={top:"bottom",bottom:"top",left:"right",right:"left"};return i?`${e[s]}-${i}`:e[s]}findBestPlacement(t,s,i,e){const o=e=>{const o=this.calcCoords(t.width,t.height,s,i,e);return this.fitsMainAxis(t,s,i,o.top,o.left,e)};if(o(e))return e;const n=this.getOppositePlacement(e);if(o(n))return n;const r=e.split("-")[1]||"";const a=["top","bottom","right","left"];for(const t of a){const s=r?`${t}-${r}`:t;if(s!==e&&s!==n&&o(s)){return s}}return e}render(){const t=this.variant==="rich";const s=!!this.subhead||this.hasSlottedSubhead;const i=this.hasSlottedActions;return e(o,{key:"18f4e3e81a7f3275e81c1a40859beab41f97104f",class:"md-tooltip-wrapper"},e("slot",{key:"ea0496dbcf3c70aad4cb72dbe3133dc97024ef30"}),e("div",{key:"8ed4c4183860370a72c9c5f14d1b9953acbf03aa",class:{"md-tooltip__popup":true,"md-tooltip__popup--plain":!t,"md-tooltip__popup--rich":t,"md-tooltip__popup--visible":this.isVisible,[`md-tooltip__popup--${this.resolvedPlacement}`]:true},id:this.tooltipId,role:"tooltip",part:"popup","aria-hidden":this.isVisible?"false":"true",ref:t=>this.popupEl=t,onMouseEnter:this.handlePopupEnter,onMouseLeave:this.handlePopupLeave},t?[s&&e("div",{class:"md-tooltip__subhead",part:"subhead",key:"subhead"},e("slot",{name:"subhead"},this.subhead)),e("div",{class:"md-tooltip__supporting-text",part:"supporting-text",key:"text"},e("slot",{name:"content"},this.text)),e("div",{class:{"md-tooltip__actions":true,"md-tooltip__actions--empty":!i},part:"actions",key:"actions"},e("slot",{name:"actions"}))]:e("span",{class:"md-tooltip__text",part:"text"},this.text)))}get el(){return this}static get watchers(){return{open:[{onOpenChange:0}],disabled:[{onDisabledChange:0}],text:[{onDescriptionChange:0}],subhead:[{onDescriptionChange:0}]}}static get style(){return r()}},[257,"md-tooltip",{text:[1],subhead:[1],variant:[513],position:[1],autoPosition:[4,"auto-position"],offset:[2],crossOffset:[2,"cross-offset"],open:[1540],showDelay:[2,"show-delay"],hideDelay:[2,"hide-delay"],disabled:[516],density:[514],isVisible:[32],resolvedPlacement:[32],hasSlottedActions:[32],hasSlottedSubhead:[32],show:[64],hide:[64]},undefined,{open:[{onOpenChange:0}],disabled:[{onDisabledChange:0}],text:[{onDescriptionChange:0}],subhead:[{onDescriptionChange:0}]}]);function l(){if(typeof customElements==="undefined"){return}const t=["md-tooltip"];t.forEach((t=>{switch(t){case"md-tooltip":if(!customElements.get(n(t))){customElements.define(n(t),h)}break}}))}l();export{h as M,l as d};
2
+ //# sourceMappingURL=p-Dp-w93ot.js.map