@sankhyatronics/sankhya-cms 0.1.8 → 0.1.9

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 (111) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +34 -34
  3. package/custom-elements.json +1023 -964
  4. package/dist/bento-grid/index.js +3 -3
  5. package/dist/card/index.js +2 -2
  6. package/dist/carousel/index.js +3 -3
  7. package/dist/{chunk-3JU3R22O.js → chunk-5EBWMPJS.js} +2 -2
  8. package/dist/chunk-5EBWMPJS.js.map +1 -0
  9. package/dist/{chunk-2JGWWXEI.js → chunk-76AVBQUA.js} +3 -3
  10. package/dist/chunk-76AVBQUA.js.map +1 -0
  11. package/dist/{chunk-NN3OCPDV.js → chunk-7NLZND6Q.js} +3 -3
  12. package/dist/{chunk-EMVHNAID.js → chunk-ALI26WOB.js} +3 -3
  13. package/dist/chunk-ALI26WOB.js.map +1 -0
  14. package/dist/{chunk-TLHG33MM.js → chunk-BLQV2YMO.js} +3 -3
  15. package/dist/chunk-BLQV2YMO.js.map +1 -0
  16. package/dist/{chunk-UVNBZD7R.js → chunk-BMHMNXIA.js} +3 -3
  17. package/dist/chunk-BMHMNXIA.js.map +1 -0
  18. package/dist/{chunk-ZRXYWH6C.js → chunk-DH53HZPB.js} +4 -4
  19. package/dist/{chunk-HPIQSECE.js → chunk-EMCQBT3S.js} +3 -3
  20. package/dist/{chunk-BQTDFQ4V.js → chunk-FLY7TNRT.js} +3 -3
  21. package/dist/chunk-FLY7TNRT.js.map +1 -0
  22. package/dist/{chunk-3VE6VFJ4.js → chunk-FZ36KL73.js} +1 -1
  23. package/dist/chunk-FZ36KL73.js.map +1 -0
  24. package/dist/{chunk-HGTC3LCW.js → chunk-G3CF7MBO.js} +3 -3
  25. package/dist/{chunk-CDC4P77V.js → chunk-GJO3RGOB.js} +2 -2
  26. package/dist/chunk-GJO3RGOB.js.map +1 -0
  27. package/dist/{chunk-K4ZICRZL.js → chunk-JKBWZLG4.js} +3 -3
  28. package/dist/chunk-JKBWZLG4.js.map +1 -0
  29. package/dist/{chunk-4HKSA5UT.js → chunk-JQY2G4QK.js} +2 -2
  30. package/dist/chunk-JQY2G4QK.js.map +1 -0
  31. package/dist/{chunk-RHAOQ6K4.js → chunk-KMU6ABQF.js} +1 -1
  32. package/dist/chunk-KMU6ABQF.js.map +1 -0
  33. package/dist/{chunk-IQPW3CYZ.js → chunk-LEXZKGQX.js} +3 -3
  34. package/dist/chunk-LEXZKGQX.js.map +1 -0
  35. package/dist/{chunk-MW43OS47.js → chunk-MSSH3HFK.js} +2 -2
  36. package/dist/chunk-MSSH3HFK.js.map +1 -0
  37. package/dist/{chunk-DQHMJZ6X.js → chunk-R5G6KFTJ.js} +18 -8
  38. package/dist/chunk-R5G6KFTJ.js.map +1 -0
  39. package/dist/{chunk-VYON56QO.js → chunk-SMLR736E.js} +2 -2
  40. package/dist/chunk-SMLR736E.js.map +1 -0
  41. package/dist/{chunk-HGJT24UG.js → chunk-VWS53WY4.js} +3 -3
  42. package/dist/chunk-VWS53WY4.js.map +1 -0
  43. package/dist/{chunk-VRRBMOUP.js → chunk-WT4OATGP.js} +3 -3
  44. package/dist/chunk-WT4OATGP.js.map +1 -0
  45. package/dist/{chunk-PB7ZPPLP.js → chunk-WTD2YIAA.js} +1 -1
  46. package/dist/chunk-WTD2YIAA.js.map +1 -0
  47. package/dist/{chunk-X2ALYIVT.js → chunk-XWB4CKDU.js} +20 -4
  48. package/dist/chunk-XWB4CKDU.js.map +1 -0
  49. package/dist/{chunk-XXPBFHWR.js → chunk-YQ42EBK5.js} +2 -2
  50. package/dist/chunk-YQ42EBK5.js.map +1 -0
  51. package/dist/{chunk-6H262SG6.js → chunk-YVTFQHVY.js} +2 -2
  52. package/dist/chunk-YVTFQHVY.js.map +1 -0
  53. package/dist/{chunk-7PSYCTEN.js → chunk-ZN4LIKVG.js} +2 -2
  54. package/dist/chunk-ZN4LIKVG.js.map +1 -0
  55. package/dist/cms-theme.css +26 -26
  56. package/dist/content-block/index.js +4 -4
  57. package/dist/cookie-consent/index.js +2 -2
  58. package/dist/dropdown/index.js +3 -3
  59. package/dist/feature-split/index.js +4 -4
  60. package/dist/features-section/index.js +5 -5
  61. package/dist/footer/index.js +2 -2
  62. package/dist/header/index.d.ts +7 -0
  63. package/dist/header/index.js +3 -3
  64. package/dist/hero/index.js +3 -3
  65. package/dist/icon-button/index.js +2 -2
  66. package/dist/index.js +35 -35
  67. package/dist/items-accordion/index.js +3 -3
  68. package/dist/markdown/index.js +2 -2
  69. package/dist/mega-menu/index.js +3 -3
  70. package/dist/menu-grid/index.js +2 -2
  71. package/dist/menu-grid-item/index.js +2 -2
  72. package/dist/menu-item/index.d.ts +5 -0
  73. package/dist/menu-item/index.js +3 -3
  74. package/dist/promo-banner/index.js +3 -3
  75. package/dist/schema/index.js.map +1 -1
  76. package/dist/section/index.js +3 -3
  77. package/dist/select/index.js +3 -3
  78. package/dist/shared/icons.js +1 -1
  79. package/dist/shared/styles.js +1 -1
  80. package/dist/stats/index.js +2 -2
  81. package/dist/testimonials/index.js +4 -4
  82. package/dist/theme.css +291 -291
  83. package/dist/themes.css +64 -64
  84. package/dist/theming/index.js.map +1 -1
  85. package/package.json +1 -1
  86. package/dist/chunk-2JGWWXEI.js.map +0 -1
  87. package/dist/chunk-3JU3R22O.js.map +0 -1
  88. package/dist/chunk-3VE6VFJ4.js.map +0 -1
  89. package/dist/chunk-4HKSA5UT.js.map +0 -1
  90. package/dist/chunk-6H262SG6.js.map +0 -1
  91. package/dist/chunk-7PSYCTEN.js.map +0 -1
  92. package/dist/chunk-BQTDFQ4V.js.map +0 -1
  93. package/dist/chunk-CDC4P77V.js.map +0 -1
  94. package/dist/chunk-DQHMJZ6X.js.map +0 -1
  95. package/dist/chunk-EMVHNAID.js.map +0 -1
  96. package/dist/chunk-HGJT24UG.js.map +0 -1
  97. package/dist/chunk-IQPW3CYZ.js.map +0 -1
  98. package/dist/chunk-K4ZICRZL.js.map +0 -1
  99. package/dist/chunk-MW43OS47.js.map +0 -1
  100. package/dist/chunk-PB7ZPPLP.js.map +0 -1
  101. package/dist/chunk-RHAOQ6K4.js.map +0 -1
  102. package/dist/chunk-TLHG33MM.js.map +0 -1
  103. package/dist/chunk-UVNBZD7R.js.map +0 -1
  104. package/dist/chunk-VRRBMOUP.js.map +0 -1
  105. package/dist/chunk-VYON56QO.js.map +0 -1
  106. package/dist/chunk-X2ALYIVT.js.map +0 -1
  107. package/dist/chunk-XXPBFHWR.js.map +0 -1
  108. /package/dist/{chunk-NN3OCPDV.js.map → chunk-7NLZND6Q.js.map} +0 -0
  109. /package/dist/{chunk-ZRXYWH6C.js.map → chunk-DH53HZPB.js.map} +0 -0
  110. /package/dist/{chunk-HPIQSECE.js.map → chunk-EMCQBT3S.js.map} +0 -0
  111. /package/dist/{chunk-HGTC3LCW.js.map → chunk-G3CF7MBO.js.map} +0 -0
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  chevronIcon
3
- } from "./chunk-PB7ZPPLP.js";
3
+ } from "./chunk-WTD2YIAA.js";
4
4
  import {
5
5
  buttonResetStyles,
6
6
  controlBaseStyles,
7
7
  fontFamilyStyles
8
- } from "./chunk-RHAOQ6K4.js";
8
+ } from "./chunk-KMU6ABQF.js";
9
9
  import {
10
10
  __decorateClass
11
11
  } from "./chunk-EUXUH3YW.js";
@@ -571,4 +571,4 @@ Dropdown = __decorateClass([
571
571
  export {
572
572
  Dropdown
573
573
  };
574
- //# sourceMappingURL=chunk-IQPW3CYZ.js.map
574
+ //# sourceMappingURL=chunk-LEXZKGQX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dropdown/Dropdown.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { chevronIcon } from '../shared/icons';\nimport { buttonResetStyles, controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport type { DropdownToggleEventDetail } from './DropdownEvents';\n\n/**\n * A labeled trigger + slotted dropdown panel — nav menus (typically holding an `st-menu-grid`),\n * action menus, anything \"click a trigger, show content under it\". A 1:1 port of `SankhyaUI`'s\n * React `Dropdown` (`SankhyaCMS/SankhyaUI/src/components/Dropdown`): same markup\n * (`.menu` > `.menu-title` + `.menu-dropdown`), sizes, 0.3s slide/fade, and behavior —\n *\n * - only one dropdown is open at a time (the source's `DropdownProvider`, built in here, so no\n * provider element is needed);\n * - a mousedown outside, Escape, or a click inside the panel closes it;\n * - an `href` trigger toggles the panel when it has content, and is a plain link when it doesn't;\n * - `inline` opens the panel in the flow, the source's `.touch-device` layout.\n *\n * Colors and the panel's surface come from the suite theme (the source left those to the\n * consumer's `className`/`itemGroupClassName` utility classes). Two source rules are left out\n * because they break existing suite uses (`st-source-bar`'s site/library menus): the 100vw panel\n * at <=768px (overflows the screen from wherever the trigger sits; the header uses `inline`\n * instead) and `overflow: hidden` on slotted children (clips their focus rings). Suite additions\n * kept on top: `align`, `active`, `disabled`, `inline`, and the `dropdown-toggle` event — plus\n * `mega` and `open-on-hover` for an okta.com-style mega menu (see `st-mega-menu`).\n *\n * @cssprop --st-mega-menu-max-width - Maximum width of a `mega` panel (default `1400px`).\n * @cssprop --st-mega-menu-inset - Minimum space between a `mega` panel and the header's sides (default `1rem`).\n * @cssprop --st-mega-menu-gap - Space between the header and a `mega` panel (default `12px`).\n * @cssprop --st-mega-menu-radius - Corner radius of a `mega` panel (default `24px`).\n */\n@customElement('st-dropdown')\nexport class Dropdown extends LitElement {\n /** The open dropdown, if any — the source's `DropdownContext.activeDropdown`. */\n private static openDropdown: Dropdown | null = null;\n\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: inline-block;\n position: relative;\n ${fontFamilyStyles}\n }\n\n .menu-title {\n ${buttonResetStyles}\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-height: 40px;\n padding: 12px;\n gap: 8px;\n text-align: center;\n width: fit-content;\n border-radius: var(--st-radius-sm);\n /* --st-nav-*: set by a host bar (st-header's transparent state) to recolour its nav items. */\n color: var(--st-nav-color, var(--st-color-text));\n font-size: 0.875rem;\n text-decoration: none;\n white-space: nowrap;\n transition: background-color 0.3s ease;\n }\n\n .menu-title:hover,\n .menu-title[aria-expanded='true'] {\n background: var(--st-nav-hover-bg, var(--st-color-hover));\n color: var(--st-nav-color, var(--st-color-text-strong));\n }\n\n :host([active]) .menu-title {\n background: var(--st-color-accent-subtle);\n color: var(--st-color-accent-text);\n }\n\n :host([disabled]) .menu-title {\n color: var(--st-color-text-muted);\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n }\n\n .icon[hidden] {\n display: none;\n }\n\n .arrow {\n display: inline-block;\n margin-left: 8px;\n font-size: 0.75rem;\n transition: transform 0.3s ease;\n }\n\n .menu-title[aria-expanded='true'] .arrow {\n transform: rotate(180deg);\n }\n\n .menu-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 100;\n padding: 16px;\n background: var(--st-color-surface);\n color: var(--st-color-text);\n /* The panel has its own surface: items in it never take the bar's nav colours. */\n --st-nav-color: initial;\n --st-nav-hover-bg: initial;\n border: 1px solid var(--st-color-border);\n border-radius: var(--st-radius-sm);\n box-shadow: 0 4px 16px var(--st-shadow-color-sm);\n opacity: 0;\n visibility: hidden;\n transform: translateY(-10px);\n /* visibility flips at once on open (so keyboard focus can move into the panel on the same\n frame) and only after the 0.3s fade on close. */\n transition:\n opacity 0.3s ease,\n transform 0.3s ease,\n visibility 0s linear 0.3s;\n pointer-events: none;\n }\n\n .menu-dropdown.align-right {\n left: auto;\n right: 0;\n }\n\n .menu-dropdown.show {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n pointer-events: auto;\n transition-delay: 0s;\n }\n\n /* Inline: the panel opens in the flow under its trigger and pushes what follows down, instead\n of floating — the source's .touch-device layout. st-header turns this on for its menu while\n the hamburger panel is showing. */\n :host([inline]) {\n display: block;\n }\n\n :host([inline]) .menu-title {\n width: 100%;\n justify-content: flex-start;\n }\n\n :host([inline]) .arrow {\n margin-left: auto;\n }\n\n :host([inline]) .menu-dropdown {\n display: none;\n position: relative;\n top: auto;\n left: auto;\n right: auto;\n width: 100%;\n box-sizing: border-box;\n box-shadow: none;\n opacity: 1;\n visibility: visible;\n transform: none;\n }\n\n :host([inline]) .menu-dropdown.show {\n display: block;\n pointer-events: auto;\n }\n\n /* Mega (okta.com): the panel is a large rounded card floating under the whole bar, centred on\n the nearest positioned ancestor (st-header) instead of hanging off the trigger — the host\n stops being the panel's containing block. */\n :host([mega]:not([inline])) {\n position: static;\n }\n\n :host([mega]:not([inline])) .menu-dropdown {\n top: calc(100% + var(--st-mega-menu-gap, 12px));\n left: var(--st-mega-menu-inset, 1rem);\n right: var(--st-mega-menu-inset, 1rem);\n max-width: var(--st-mega-menu-max-width, 1400px);\n margin: 0 auto;\n padding: 0;\n max-height: calc(100dvh - var(--st-mega-menu-offset, 96px));\n overflow-y: auto;\n border: 0;\n border-radius: var(--st-mega-menu-radius, 24px);\n box-shadow: 0 24px 48px var(--st-shadow-color-md);\n }\n\n /* The open section's trigger becomes an accent pill — also for a plain dropdown marked \\`bar\\`,\n so it matches the mega triggers (and st-menu-item variant=\"bar\") beside it. */\n :host([mega]:not([inline])) .menu-title,\n :host([bar]:not([inline])) .menu-title {\n border-radius: 9999px;\n }\n\n :host([mega]:not([inline])) .menu-title[aria-expanded='true'],\n :host([bar]:not([inline])) .menu-title[aria-expanded='true'] {\n background: var(--st-color-accent);\n color: var(--st-color-on-solid);\n }\n\n .mega-back-bar,\n .mega-heading {\n display: none;\n }\n\n /* Mega in st-header's hamburger panel: rather than an accordion, the panel slides in over the\n whole screen with a Back button (okta.com's phone menu). Fixed to the viewport, stacked\n inside the header's own full-screen layer, so the header's close toggle stays on top. */\n :host([mega][inline]) .menu-dropdown {\n display: block;\n position: fixed;\n inset: 0;\n z-index: 1;\n padding: 0 1.5rem 2rem;\n overflow-y: auto;\n border: 0;\n border-radius: 0;\n visibility: hidden;\n transform: translateX(100%);\n transition:\n transform 0.3s ease,\n visibility 0s linear 0.3s;\n }\n\n :host([mega][inline]) .menu-dropdown.show {\n visibility: visible;\n transform: none;\n transition-delay: 0s;\n }\n\n :host([mega][inline]) .mega-back-bar {\n display: flex;\n align-items: center;\n position: sticky;\n top: 0;\n z-index: 1;\n height: 64px;\n margin: 0 -1.5rem;\n padding: 0 1rem;\n background: inherit;\n border-bottom: 1px solid var(--st-color-border);\n }\n\n .mega-back {\n ${buttonResetStyles}\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 40px;\n padding: 0 12px 0 6px;\n border-radius: var(--st-radius-sm);\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--st-color-text-strong);\n }\n\n .mega-back:hover {\n background: var(--st-color-hover);\n }\n\n :host([mega][inline]) .mega-heading {\n display: block;\n margin: 1.25rem 0 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--st-color-text-strong);\n }\n\n /* The drill-down replaces the trigger's open state, so the caret points the way it goes. */\n :host([mega][inline]) .arrow {\n transform: rotate(-90deg);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .menu-dropdown,\n .arrow,\n :host([mega][inline]) .menu-dropdown {\n transition: none;\n }\n }\n `;\n\n /** Trigger label text (source: `title`, renamed because `title` is the native tooltip\n * attribute). Leave empty to show only `slot=\"icon\"`. */\n @property({ type: String })\n label = '';\n\n /** Renders the trigger as an `<a href>`. With panel content the click toggles the panel (as in\n * the source); with none it navigates. */\n @property({ type: String })\n href = '';\n\n @property({ type: String, attribute: 'icon-position' })\n iconPosition: 'left' | 'right' = 'left';\n\n /** Inline `width`/`height` of the `slot=\"icon\"` wrapper (source: `iconSize`, default `1.2rem`). */\n @property({ type: String, attribute: 'icon-size' })\n iconSize = '1.2rem';\n\n /** Inline `color` of the `slot=\"icon\"` wrapper (source: `iconColor`). */\n @property({ type: String, attribute: 'icon-color' })\n iconColor = 'currentColor';\n\n /** Which edge of the trigger the panel lines up with. */\n @property({ type: String })\n align: 'left' | 'right' = 'left';\n\n /** `target` of an `href` trigger (source default `_self`). */\n @property({ type: String })\n target = '_self';\n\n /** Extra class(es) on the trigger (source: `className`; a `class` on `st-dropdown` styles the host). */\n @property({ type: String, attribute: 'trigger-class-name' })\n triggerClassName = '';\n\n /** Extra class(es) on the panel (source: `itemGroupClassName`). */\n @property({ type: String, attribute: 'item-group-class-name' })\n itemGroupClassName = '';\n\n /** Unused, as in the source (`itemClassName` is never read there); kept for prop parity. */\n @property({ type: String, attribute: 'item-class-name' })\n itemClassName = '';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Highlights the trigger as the current section (e.g. the current page is one of its items). */\n @property({ type: Boolean, reflect: true })\n active = false;\n\n /** Opens the panel in the flow under the trigger instead of floating over the page (see the\n * styles). `st-header` sets this on its own menu's dropdowns while its hamburger panel shows. */\n @property({ type: Boolean, reflect: true })\n inline = false;\n\n /** Whether the panel is showing. Follows user toggles; may also be set from outside. */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /**\n * Mega-menu panel (okta.com style), typically holding an `st-mega-menu`: the panel spans the\n * full width of the nearest positioned ancestor — `st-header` — right under it, instead of\n * hanging off the trigger. In `st-header`'s hamburger layout (`inline`) it slides in over the\n * screen with a Back button rather than opening as an accordion. A click inside the panel only\n * closes it when it lands on a link.\n */\n @property({ type: Boolean, reflect: true })\n mega = false;\n\n /** Styles a non-`mega` trigger like a mega one — a pill that turns solid accent while open — so\n * a plain dropdown (e.g. \"+ New\") lines up with mega triggers in the same header bar. */\n @property({ type: Boolean, reflect: true })\n bar = false;\n\n /** Opens the panel while a mouse hovers the trigger or panel (touch and keyboard still click). Off while `inline`. */\n @property({ type: Boolean, attribute: 'open-on-hover' })\n openOnHover = false;\n\n /** Text of the Back button in the `mega` + `inline` drill-down panel. */\n @property({ type: String, attribute: 'back-label' })\n backLabel = 'Back';\n\n private hoverTimer = 0;\n\n /** When hover last opened the panel — a click right after that keeps it open instead of toggling it shut. */\n private hoverOpenedAt = 0;\n\n /** Whether the default slot has content — the source's `children` check. */\n @state() private hasContent = false;\n\n /** Whether `slot=\"icon\"` has content. */\n @state() private hasIcon = false;\n\n connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('mousedown', this.closeOnOutsideMouseDown);\n window.addEventListener('keydown', this.closeOnEscape);\n this.addEventListener('pointerenter', this.onPointerEnter);\n this.addEventListener('pointerleave', this.onPointerLeave);\n }\n\n disconnectedCallback(): void {\n document.removeEventListener('mousedown', this.closeOnOutsideMouseDown);\n window.removeEventListener('keydown', this.closeOnEscape);\n this.removeEventListener('pointerenter', this.onPointerEnter);\n this.removeEventListener('pointerleave', this.onPointerLeave);\n clearTimeout(this.hoverTimer);\n if (Dropdown.openDropdown === this) Dropdown.openDropdown = null;\n super.disconnectedCallback();\n }\n\n protected updated(changed: Map<string, unknown>): void {\n if (!changed.has('open')) return;\n if (this.open) {\n const previous = Dropdown.openDropdown;\n Dropdown.openDropdown = this;\n if (previous && previous !== this) previous.setOpen(false);\n } else if (Dropdown.openDropdown === this) {\n Dropdown.openDropdown = null;\n }\n }\n\n private setOpen(open: boolean): void {\n if (this.open === open) return;\n this.open = open;\n this.dispatchEvent(new CustomEvent<DropdownToggleEventDetail>('dropdown-toggle', { detail: { open }, bubbles: true, composed: true }));\n }\n\n private hovers(event: PointerEvent): boolean {\n return this.openOnHover && !this.inline && !this.disabled && this.hasContent && event.pointerType === 'mouse';\n }\n\n /** Short delays so a pointer crossing the gap between trigger and panel doesn't close it. */\n private onPointerEnter = (event: PointerEvent): void => {\n if (!this.hovers(event)) return;\n clearTimeout(this.hoverTimer);\n this.hoverTimer = window.setTimeout(() => {\n if (!this.open) this.hoverOpenedAt = Date.now();\n this.setOpen(true);\n }, 80);\n };\n\n private onPointerLeave = (event: PointerEvent): void => {\n if (!this.hovers(event)) return;\n clearTimeout(this.hoverTimer);\n this.hoverTimer = window.setTimeout(() => this.setOpen(false), 200);\n };\n\n private onBackClick = (event: Event): void => {\n event.stopPropagation();\n this.setOpen(false);\n this.trigger()?.focus();\n };\n\n private closeOnOutsideMouseDown = (event: Event): void => {\n if (this.open && !event.composedPath().includes(this)) this.setOpen(false);\n };\n\n private closeOnEscape = (event: KeyboardEvent): void => {\n if (!this.open || event.key !== 'Escape') return;\n const focusWasInside = event.composedPath().includes(this);\n this.setOpen(false);\n if (focusWasInside) this.trigger()?.focus();\n };\n\n private trigger(): HTMLElement | null {\n return this.renderRoot.querySelector<HTMLElement>('.menu-title');\n }\n\n /** Keyboard-reachable entries in the panel, in order: menu items (they delegate focus to their\n * own link) plus any plain links/buttons/tabbable elements a caller slots in. */\n private panelItems(): HTMLElement[] {\n const slot = this.renderRoot.querySelector<HTMLSlotElement>('.menu-dropdown slot');\n if (!slot) return [];\n const selector =\n 'st-menu-item, st-menu-grid-item, st-mega-menu-feature, a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n const items: HTMLElement[] = [];\n for (const el of slot.assignedElements({ flatten: true })) {\n if (el.matches(selector)) items.push(el as HTMLElement);\n items.push(...Array.from(el.querySelectorAll<HTMLElement>(selector)));\n }\n return items;\n }\n\n /** Moves focus into the panel once it has become visible (it is `visibility: hidden` until the\n * `show` class lands, and hidden elements can't take focus). */\n private focusItem(pick: (items: HTMLElement[]) => HTMLElement | undefined): void {\n void this.updateComplete.then(() => pick(this.panelItems())?.focus());\n }\n\n /** Enter/Space/ArrowDown open the panel and focus its first entry; ArrowUp its last. */\n private onTitleKeyDown = (event: KeyboardEvent): void => {\n if (!this.hasContent || this.disabled) return;\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.stopPropagation();\n this.setOpen(true);\n this.focusItem((items) => items[0]);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n event.stopPropagation();\n this.setOpen(true);\n this.focusItem((items) => items[items.length - 1]);\n }\n };\n\n /** Arrow keys/Home/End move between the panel's entries; Tab closes the panel and moves on. */\n private onPanelKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Tab') {\n this.setOpen(false);\n return;\n }\n if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return;\n const items = this.panelItems();\n if (items.length === 0) return;\n event.preventDefault();\n event.stopPropagation();\n const path = event.composedPath();\n const current = items.findIndex((item) => path.includes(item));\n const last = items.length - 1;\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? last\n : event.key === 'ArrowDown'\n ? current < 0 || current === last ? 0 : current + 1\n : current <= 0 ? last : current - 1;\n items[next].focus();\n };\n\n private onTitleClick = (event: Event): void => {\n event.stopPropagation();\n if (!this.hasContent) return;\n event.preventDefault();\n clearTimeout(this.hoverTimer);\n if (this.open && Date.now() - this.hoverOpenedAt < 400) return;\n this.setOpen(!this.open);\n };\n\n /** A click anywhere inside the panel closes it, as in the source — for `mega`, only a click on a\n * link: a big panel has headings and gaps, and a click there shouldn't also close st-header's\n * hamburger layer. */\n private onPanelClick = (event: Event): void => {\n if (this.mega && !event.composedPath().some((node) => node instanceof HTMLAnchorElement)) {\n event.stopPropagation();\n return;\n }\n this.setOpen(false);\n };\n\n private onContentSlotChange = (event: Event): void => {\n this.hasContent = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).some(\n (node) => node.nodeType === Node.ELEMENT_NODE || !!node.textContent?.trim()\n );\n };\n\n private onIconSlotChange = (event: Event): void => {\n this.hasIcon = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;\n };\n\n render() {\n const icon = html`<span\n class=\"icon ${this.iconPosition === 'left' ? 'icon-left' : 'icon-right'}\"\n ?hidden=${!this.hasIcon}\n style=\"width:${this.iconSize};height:${this.iconSize};color:${this.iconColor}\"\n ><slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot\n ></span>`;\n const titleContent = html`\n ${this.iconPosition === 'left' ? icon : nothing} ${this.label ? html`<span part=\"label\">${this.label}</span>` : nothing}\n ${this.iconPosition === 'right' ? icon : nothing}\n ${this.hasContent ? html`<span class=\"arrow\" part=\"caret\" aria-hidden=\"true\">▼</span>` : nothing}\n `;\n const titleClass = `menu-title ${this.triggerClassName} ${this.open ? 'active' : ''}`;\n\n return html`\n <div class=\"menu\" part=\"menu\">\n ${this.href\n ? html`\n <a\n part=\"trigger\"\n class=${titleClass}\n href=${this.href}\n target=${this.target}\n aria-haspopup=${this.hasContent ? 'true' : 'false'}\n aria-expanded=${this.open}\n aria-disabled=${this.disabled ? 'true' : nothing}\n @click=${this.onTitleClick}\n @keydown=${this.onTitleKeyDown}\n >\n ${titleContent}\n </a>\n `\n : html`\n <button\n part=\"trigger\"\n class=${titleClass}\n type=\"button\"\n aria-haspopup=\"true\"\n aria-expanded=${this.open}\n ?disabled=${this.disabled}\n @click=${this.onTitleClick}\n @keydown=${this.onTitleKeyDown}\n >\n ${titleContent}\n </button>\n `}\n <div\n part=\"panel\"\n class=\"menu-dropdown align-${this.align} ${this.itemGroupClassName} ${this.open ? 'show' : ''}\"\n role=\"menu\"\n @click=${this.onPanelClick}\n @keydown=${this.onPanelKeyDown}\n >\n ${this.mega\n ? html`\n <div class=\"mega-back-bar\" part=\"back-bar\">\n <button type=\"button\" class=\"mega-back\" part=\"back\" @click=${this.onBackClick}>\n ${chevronIcon('left', 16)} ${this.backLabel}\n </button>\n </div>\n ${this.label ? html`<p class=\"mega-heading\" part=\"mobile-heading\">${this.label}</p>` : nothing}\n `\n : nothing}\n <slot @slotchange=${this.onContentSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  buttonResetStyles,
3
3
  controlBaseStyles,
4
4
  rootFontFamilyStyles
5
- } from "./chunk-RHAOQ6K4.js";
5
+ } from "./chunk-KMU6ABQF.js";
6
6
  import {
7
7
  __decorateClass
8
8
  } from "./chunk-EUXUH3YW.js";
@@ -202,4 +202,4 @@ CookieConsent = __decorateClass([
202
202
  export {
203
203
  CookieConsent
204
204
  };
205
- //# sourceMappingURL=chunk-MW43OS47.js.map
205
+ //# sourceMappingURL=chunk-MSSH3HFK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cookie-consent/CookieConsent.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { buttonResetStyles, controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\nimport type { CookieConsentEventDetail, CookieConsentStatus } from './CookieConsentEvents';\n\nconst DEFAULT_STORAGE_KEY = 'sankhya_ui_cookie_consent';\n\n/**\n * Fixed bottom consent bar. The source read/wrote consent through a React `UserContext`; here the\n * element persists the choice itself in localStorage (`storage-key`, default the source's\n * `sankhya_ui_cookie_consent`; storage errors are ignored) and renders nothing once a choice\n * exists. Fires `cookie-consent-accept` / `cookie-consent-refuse` (detail `{ status }`). The\n * default slot replaces the message text.\n *\n * @cssprop --st-cookie-consent-padding - Overrides the bar's padding.\n */\n@customElement('st-cookie-consent')\nexport class CookieConsent extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n @keyframes st-cookie-slide-up {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n }\n\n :host {\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100%;\n box-sizing: border-box;\n z-index: 9999;\n display: flex;\n flex-direction: column;\n gap: var(--st-space-16);\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n padding; override with --st-cookie-consent-padding instead. */\n padding: var(--st-cookie-consent-padding, var(--st-space-24)) !important;\n background: var(--st-color-surface);\n color: var(--st-color-text);\n border-top: 1px solid var(--st-color-border);\n box-shadow: 0 -4px 10px var(--st-shadow-color-sm);\n animation: st-cookie-slide-up 0.3s ease-out;\n ${rootFontFamilyStyles}\n }\n\n .content {\n flex: 1;\n }\n\n .message {\n margin: 0;\n font-size: var(--st-text-md);\n line-height: 1.5;\n }\n\n .link {\n color: var(--st-color-accent-text);\n text-decoration: underline;\n margin-left: var(--st-space-4);\n }\n\n .link:hover {\n text-decoration: none;\n }\n\n .actions {\n display: flex;\n gap: var(--st-space-12);\n flex-shrink: 0;\n }\n\n .btn {\n ${buttonResetStyles}\n padding: var(--st-space-8) var(--st-space-16);\n border: 1px solid transparent;\n border-radius: var(--st-radius-xs);\n font-weight: var(--st-font-weight-medium);\n font-size: var(--st-text-md);\n transition:\n background-color 0.2s ease,\n color 0.2s ease;\n }\n\n .accept {\n background: var(--st-button-primary-bg);\n color: var(--st-button-primary-color);\n }\n\n .accept:hover {\n opacity: 0.9;\n }\n\n .refuse {\n border-color: var(--st-color-border);\n color: var(--st-color-text-muted);\n }\n\n .refuse:hover {\n background: var(--st-color-hover);\n color: var(--st-color-text-strong);\n }\n\n @media (min-width: 768px) {\n :host {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n padding: var(--st-cookie-consent-padding, var(--st-space-16) var(--st-space-32)) !important;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n :host {\n animation: none;\n }\n .btn {\n transition: none;\n }\n }\n `;\n\n @property({ type: String })\n message = '';\n\n @property({ type: String, attribute: 'accept-button-text' })\n acceptButtonText = 'Accept';\n\n @property({ type: String, attribute: 'refuse-button-text' })\n refuseButtonText = 'Refuse';\n\n @property({ type: String, attribute: 'privacy-policy-link' })\n privacyPolicyLink = '';\n\n @property({ type: String, attribute: 'privacy-policy-text' })\n privacyPolicyText = 'Privacy Policy';\n\n @property({ type: String, attribute: 'storage-key' })\n storageKey = DEFAULT_STORAGE_KEY;\n\n /** The stored choice, or `null` while undecided (the bar is only shown then). */\n @state() private consent: CookieConsentStatus | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n this.consent = this.readStored();\n }\n\n private readStored(): CookieConsentStatus | null {\n try {\n const saved = localStorage.getItem(this.storageKey);\n return saved === 'accepted' || saved === 'refused' ? saved : null;\n } catch {\n return null;\n }\n }\n\n private choose(status: CookieConsentStatus): void {\n this.consent = status;\n try {\n localStorage.setItem(this.storageKey, status);\n } catch {\n // Storage unavailable (private mode, blocked): the choice just doesn't persist.\n }\n this.dispatchEvent(\n new CustomEvent<CookieConsentEventDetail>(status === 'accepted' ? 'cookie-consent-accept' : 'cookie-consent-refuse', {\n detail: { status },\n bubbles: true,\n composed: true\n })\n );\n }\n\n render() {\n if (this.consent !== null) return nothing;\n return html`\n <div class=\"content\" part=\"content\">\n <p class=\"message\" part=\"message\">\n <slot>\n ${this.message || 'We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.'}\n ${this.privacyPolicyLink\n ? html`<a class=\"link\" part=\"link\" href=${this.privacyPolicyLink} target=\"_blank\" rel=\"noopener noreferrer\">${this.privacyPolicyText}</a>`\n : nothing}\n </slot>\n </p>\n </div>\n <div class=\"actions\" part=\"actions\">\n <button class=\"btn refuse\" part=\"refuse\" type=\"button\" @click=${() => this.choose('refused')}>${this.refuseButtonText}</button>\n <button class=\"btn accept\" part=\"accept\" type=\"button\" @click=${() => this.choose('accepted')}>${this.acceptButtonText}</button>\n </div>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  arrowUpRightIcon
3
- } from "./chunk-PB7ZPPLP.js";
3
+ } from "./chunk-WTD2YIAA.js";
4
4
  import {
5
5
  controlBaseStyles,
6
6
  fontFamilyStyles
7
- } from "./chunk-RHAOQ6K4.js";
7
+ } from "./chunk-KMU6ABQF.js";
8
8
  import {
9
9
  __decorateClass
10
10
  } from "./chunk-EUXUH3YW.js";
@@ -24,6 +24,7 @@ var MenuItem = class extends LitElement {
24
24
  this.showDescription = true;
25
25
  this.target = "_self";
26
26
  this.variant = "default";
27
+ this.iconSize = "";
27
28
  this.hasIcon = false;
28
29
  this.onIconSlotChange = (event) => {
29
30
  this.hasIcon = event.target.assignedNodes({ flatten: true }).length > 0;
@@ -60,7 +61,13 @@ var MenuItem = class extends LitElement {
60
61
  rel=${this.target === "_blank" ? "noopener noreferrer" : nothing}
61
62
  @click=${this.onClick}
62
63
  >
63
- <span class="menu-item-icon" part="icon" ?hidden=${!this.hasIcon}><slot name="icon" @slotchange=${this.onIconSlotChange}></slot></span>
64
+ <span
65
+ class="menu-item-icon"
66
+ part="icon"
67
+ ?hidden=${!this.hasIcon}
68
+ style=${this.iconSize ? `--st-menu-item-icon-size: ${this.iconSize}` : nothing}
69
+ ><slot name="icon" @slotchange=${this.onIconSlotChange}></slot
70
+ ></span>
64
71
  <span class="menu-item-content" part="content">
65
72
  <span class="menu-item-header" part="header">
66
73
  <span part="title" class="menu-item-title"
@@ -166,8 +173,8 @@ MenuItem.styles = css`
166
173
  }
167
174
 
168
175
  .menu-item-icon ::slotted(*) {
169
- width: 16px;
170
- height: 16px;
176
+ width: var(--st-menu-item-icon-size, 16px);
177
+ height: var(--st-menu-item-icon-size, 16px);
171
178
  }
172
179
 
173
180
  .menu-item-content {
@@ -222,8 +229,8 @@ MenuItem.styles = css`
222
229
  }
223
230
 
224
231
  .menu-item.compact .menu-item-icon ::slotted(*) {
225
- width: 14px;
226
- height: 14px;
232
+ width: var(--st-menu-item-icon-size, 14px);
233
+ height: var(--st-menu-item-icon-size, 14px);
227
234
  }
228
235
 
229
236
  .menu-item.compact .menu-item-title {
@@ -371,6 +378,9 @@ __decorateClass([
371
378
  __decorateClass([
372
379
  property({ type: String, reflect: true })
373
380
  ], MenuItem.prototype, "variant", 2);
381
+ __decorateClass([
382
+ property({ type: String, attribute: "icon-size" })
383
+ ], MenuItem.prototype, "iconSize", 2);
374
384
  __decorateClass([
375
385
  state()
376
386
  ], MenuItem.prototype, "hasIcon", 2);
@@ -381,4 +391,4 @@ MenuItem = __decorateClass([
381
391
  export {
382
392
  MenuItem
383
393
  };
384
- //# sourceMappingURL=chunk-DQHMJZ6X.js.map
394
+ //# sourceMappingURL=chunk-R5G6KFTJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/menu-item/MenuItem.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { arrowUpRightIcon } from '../shared/icons';\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport type { MenuItemSelectEventDetail } from './MenuItemEvents';\n\n/**\n * A single flat nav row — icon (`slot=\"icon\"`) + title + badge on one line, an optional\n * description below — as opposed to `st-menu-grid-item`'s card for a multi-column grid. A 1:1\n * port of `SankhyaUI`'s React `MenuItem` (`SankhyaCMS/SankhyaUI/src/components/Menu`): same\n * markup and CSS, with its `motion` effects redone in CSS — nudges right and scales to 1.01 on\n * hover / 0.99 while pressed, the icon tilts on hover, the badge pops in, the description fades\n * in. Colors come from the suite theme rather than per-item utility classes.\n *\n * Renders a real `<a href>` but fires a *cancelable* `menu-item-select` event (detail: `{ href }`)\n * before navigating — a host doing client-side routing calls `event.preventDefault()` on it (the\n * source used react-router's `Link` here; the suite apps have no router).\n *\n * @slot icon - The row's icon, sized to `icon-size` (16px, or 14px when `compact`).\n * @cssprop --st-menu-item-icon-size - Width and height of the slotted icon; `icon-size` sets it.\n */\n@customElement('st-menu-item')\nexport class MenuItem extends LitElement {\n /** `focus()` on the element focuses its link, so `st-dropdown` can arrow-key between items. */\n static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };\n\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n ${fontFamilyStyles}\n }\n\n @keyframes st-menu-item-badge-pop {\n from {\n transform: scale(0);\n }\n 70% {\n transform: scale(1.12);\n }\n to {\n transform: scale(1);\n }\n }\n\n @keyframes st-menu-item-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n .menu-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px 16px;\n font-size: 0.875rem;\n text-decoration: none;\n /* --st-nav-*: set by a host bar (st-header's transparent state) to recolour its nav items. */\n color: var(--st-nav-color, var(--st-color-text));\n border-radius: 6px;\n /* The source's 'all 0.15s', minus visibility: animating the visibility this link inherits\n from a dropdown panel kept it unfocusable for a frame after the panel opened. */\n transition-property: background-color, color, padding, transform, border-color;\n transition-duration: 0.15s;\n transition-timing-function: ease;\n box-sizing: border-box;\n }\n\n /* The source's hover nudge (x: 4px) is done with padding, not a transform: a transform would\n spill past a scrolling panel's edge (st-source-bar's menus) and show a horizontal scrollbar.\n Keyboard focus gets the same treatment as hover. */\n .menu-item:hover,\n .menu-item:focus-visible {\n background: var(--st-nav-hover-bg, var(--st-color-hover));\n color: var(--st-nav-color, var(--st-color-text-strong));\n padding-left: 20px;\n transition-duration: 0.1s;\n }\n\n .menu-item.compact:hover,\n .menu-item.compact:focus-visible {\n padding-left: 16px;\n }\n\n .menu-item:active {\n transform: scale(0.99);\n transition-duration: 0.1s;\n }\n\n .menu-item.active {\n background-color: var(--st-color-accent-subtle);\n color: var(--st-color-accent-text);\n border-left: 4px solid var(--st-color-accent);\n }\n\n .menu-item-icon {\n display: flex;\n flex-shrink: 0;\n margin-top: 2px;\n transition: transform 0.2s ease;\n }\n\n .menu-item-icon:hover {\n transform: rotate(5deg);\n }\n\n .menu-item-icon[hidden] {\n display: none;\n }\n\n .menu-item-icon ::slotted(*) {\n width: var(--st-menu-item-icon-size, 16px);\n height: var(--st-menu-item-icon-size, 16px);\n }\n\n .menu-item-content {\n flex: 1;\n min-width: 0;\n }\n\n .menu-item-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n }\n\n .menu-item-title {\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .menu-item-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n font-size: 0.75rem;\n font-weight: 500;\n border-radius: 9999px;\n flex-shrink: 0;\n background: var(--st-color-accent-subtle);\n color: var(--st-color-accent-text);\n animation: st-menu-item-badge-pop 0.35s ease-out;\n }\n\n .menu-item-description {\n display: -webkit-box;\n margin: 4px 0 0;\n font-size: 0.75rem;\n color: var(--st-color-text-muted);\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n animation: st-menu-item-fade-in 0.2s ease;\n }\n\n .menu-item.compact {\n padding: 8px 12px;\n gap: 8px;\n }\n\n .menu-item.compact .menu-item-icon ::slotted(*) {\n width: var(--st-menu-item-icon-size, 14px);\n height: var(--st-menu-item-icon-size, 14px);\n }\n\n .menu-item.compact .menu-item-title {\n font-size: 0.75rem;\n }\n\n .menu-item.compact .menu-item-description {\n font-size: 0.75rem;\n }\n\n /* link: a plain text link (okta.com mega-menu columns) — no box, no nudge, the badge right\n after the title, long titles wrap. */\n .menu-item.link {\n padding: 7px 0;\n gap: 10px;\n font-size: 0.9375rem;\n color: var(--st-nav-color, var(--st-color-text));\n }\n\n .menu-item.link:hover,\n .menu-item.link:focus-visible {\n padding-left: 0;\n background: transparent;\n color: var(--st-nav-color, var(--st-color-text-strong));\n }\n\n .menu-item.link:hover .menu-item-title,\n .menu-item.link:focus-visible .menu-item-title {\n text-decoration: underline;\n text-underline-offset: 4px;\n }\n\n .menu-item.link:active {\n transform: none;\n }\n\n .menu-item.link.active {\n border-left: 0;\n background: transparent;\n font-weight: 600;\n }\n\n .menu-item.link .menu-item-header {\n justify-content: flex-start;\n }\n\n .menu-item.link .menu-item-title {\n white-space: normal;\n font-weight: 400;\n }\n\n .menu-item.link .menu-item-description {\n margin-top: 2px;\n font-size: 0.8125rem;\n }\n\n /* bar: a top-level item in a header bar next to mega st-dropdowns (e.g. \"Dashboard\" beside\n \"Masters ▼\") — the same pill, size and active look as their triggers, so the row reads as\n one set. Wins over compact (declared after it). */\n .menu-item.bar {\n align-items: center;\n min-height: 40px;\n padding: 12px;\n gap: 8px;\n border-radius: 9999px;\n white-space: nowrap;\n }\n\n /* Hover fills like a mega trigger opening on hover. */\n .menu-item.bar:hover,\n .menu-item.bar:focus-visible {\n padding-left: 12px;\n background: var(--st-color-accent);\n color: var(--st-color-on-solid);\n }\n\n .menu-item.bar.active {\n border-left: 0;\n }\n\n .menu-item.bar .menu-item-icon {\n margin-top: 0;\n }\n\n .menu-item.bar .menu-item-title {\n font-size: 0.875rem;\n font-weight: 400;\n }\n\n .external {\n display: inline-flex;\n margin-left: 3px;\n vertical-align: 0.05em;\n }\n\n .menu-item.no-description {\n align-items: center;\n }\n\n .menu-item.no-description .menu-item-icon {\n margin-top: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .menu-item,\n .menu-item-icon {\n transition: none;\n }\n\n .menu-item:active,\n .menu-item-icon:hover {\n transform: none;\n }\n\n .menu-item-badge,\n .menu-item-description {\n animation: none;\n }\n }\n `;\n\n @property({ type: String })\n title = '';\n\n @property({ type: String })\n href = '';\n\n @property({ type: String })\n description = '';\n\n /** Small trailing label, e.g. a count or \"New\"/\"Beta\" — omit for none. */\n @property({ type: String })\n badge = '';\n\n /** Highlights this row as the current page (source: `isActive`). */\n @property({ type: Boolean, reflect: true })\n active = false;\n\n @property({ type: Boolean, reflect: true })\n compact = false;\n\n /** Suppresses the description even when `description` is set (source: `showDescription`, default `true`). */\n @property({ type: Boolean, attribute: 'show-description' })\n showDescription = true;\n\n /** `target` for the `<a>` (source default `_self`). */\n @property({ type: String })\n target = '_self';\n\n /** `default` (a row with a hover box), `link` (a plain text link, as in `st-mega-menu-column`;\n * marked with an arrow when it opens a new tab) or `bar` (a top-level item in a header bar,\n * shaped like a mega `st-dropdown`'s trigger pill so it lines up with the dropdowns beside it). */\n @property({ type: String, reflect: true })\n variant: 'default' | 'link' | 'bar' = 'default';\n\n /** Size of the slotted icon, any CSS length (e.g. `36px`); empty keeps 16px (14px when `compact`). */\n @property({ type: String, attribute: 'icon-size' })\n iconSize = '';\n\n /** Whether `slot=\"icon\"` has content, so an omitted icon leaves no empty box. */\n @state() private hasIcon = false;\n\n private onIconSlotChange = (event: Event): void => {\n this.hasIcon = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;\n };\n\n private onClick = (event: MouseEvent): void => {\n const selectEvent = new CustomEvent<MenuItemSelectEventDetail>('menu-item-select', {\n detail: { href: this.href },\n bubbles: true,\n composed: true,\n cancelable: true\n });\n this.dispatchEvent(selectEvent);\n if (selectEvent.defaultPrevented) event.preventDefault();\n };\n\n render() {\n const showDescription = !!this.description && this.showDescription;\n const link = this.variant === 'link';\n const classes = [\n 'menu-item',\n link ? 'link' : '',\n this.variant === 'bar' ? 'bar' : '',\n this.active ? 'active' : '',\n this.compact ? 'compact' : '',\n showDescription ? '' : 'no-description'\n ]\n .filter(Boolean)\n .join(' ');\n const external = link && this.target === '_blank';\n return html`\n <a\n part=\"item\"\n class=${classes}\n href=${this.href}\n target=${this.target}\n rel=${this.target === '_blank' ? 'noopener noreferrer' : nothing}\n @click=${this.onClick}\n >\n <span\n class=\"menu-item-icon\"\n part=\"icon\"\n ?hidden=${!this.hasIcon}\n style=${this.iconSize ? `--st-menu-item-icon-size: ${this.iconSize}` : nothing}\n ><slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot\n ></span>\n <span class=\"menu-item-content\" part=\"content\">\n <span class=\"menu-item-header\" part=\"header\">\n <span part=\"title\" class=\"menu-item-title\"\n >${this.title}${external ? html`<span class=\"external\">${arrowUpRightIcon(11)}</span>` : nothing}</span\n >\n ${this.badge ? html`<span part=\"badge\" class=\"menu-item-badge\">${this.badge}</span>` : nothing}\n </span>\n ${showDescription ? html`<p part=\"description\" class=\"menu-item-description\">${this.description}</p>` : nothing}\n </span>\n </a>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  controlBaseStyles
3
- } from "./chunk-RHAOQ6K4.js";
3
+ } from "./chunk-KMU6ABQF.js";
4
4
  import {
5
5
  __decorateClass
6
6
  } from "./chunk-EUXUH3YW.js";
@@ -87,4 +87,4 @@ MenuGrid = __decorateClass([
87
87
  export {
88
88
  MenuGrid
89
89
  };
90
- //# sourceMappingURL=chunk-VYON56QO.js.map
90
+ //# sourceMappingURL=chunk-SMLR736E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/menu-grid/MenuGrid.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles } from '../shared/styles';\n\n/**\n * A responsive grid of `st-menu-grid-item`s — the \"rich\" nav-menu layout (icon + title +\n * description per entry, arranged in columns), typically slotted into `st-dropdown`'s default\n * slot. A 1:1 port of `SankhyaUI`'s React `MenuGrid` (`SankhyaCMS/SankhyaUI/src/components/Menu`):\n * same markup (`.menu-grid-container` > `.menu-grid.columns-N`), gap and breakpoints (768px: 2–4\n * columns → 2; 480px: everything → 1; a 1-column grid stays 1).\n */\n@customElement('st-menu-grid')\nexport class MenuGrid extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n }\n\n .menu-grid-container {\n width: 100%;\n }\n\n .menu-grid {\n display: grid;\n gap: 12px;\n }\n\n .menu-grid.columns-1 {\n grid-template-columns: repeat(1, 1fr);\n }\n\n .menu-grid.columns-2 {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .menu-grid.columns-3 {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .menu-grid.columns-4 {\n grid-template-columns: repeat(4, 1fr);\n }\n\n @media (max-width: 768px) {\n .menu-grid.columns-2,\n .menu-grid.columns-3,\n .menu-grid.columns-4 {\n grid-template-columns: repeat(2, 1fr);\n }\n }\n\n @media (max-width: 480px) {\n .menu-grid.columns-1,\n .menu-grid.columns-2,\n .menu-grid.columns-3,\n .menu-grid.columns-4 {\n grid-template-columns: 1fr;\n }\n }\n `;\n\n /** Number of columns at full width (1–4, same as the source component's `columns-N` classes). */\n @property({ type: Number })\n columns = 3;\n\n /** Extra class(es) appended to the inner grid element — the source component's `gridClassName`.\n * Its outer `className` is the host element itself here: set a `class` attribute on `st-menu-grid`. */\n @property({ type: String, attribute: 'grid-class-name' })\n gridClassName = '';\n\n render() {\n const columns = Math.min(4, Math.max(1, Math.round(this.columns) || 1));\n return html`\n <div class=\"menu-grid-container\" part=\"container\">\n <div part=\"grid\" class=\"menu-grid columns-${columns} ${this.gridClassName}\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AAYjC,IAAM,WAAN,cAAuB,WAAW;AAAA,EAAlC;AAAA;AAqDL,mBAAU;AAKV,yBAAgB;AAAA;AAAA,EAEhB,SAAS;AACP,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,CAAC,CAAC;AACtE,WAAO;AAAA;AAAA,oDAEyC,OAAO,IAAI,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/E;AACF;AAtEa,SACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmDrB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GApDf,SAqDX;AAKA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB,CAAC;AAAA,GAzD7C,SA0DX;AA1DW,WAAN;AAAA,EADN,cAAc,cAAc;AAAA,GAChB;","names":[]}
@@ -2,12 +2,12 @@ import {
2
2
  ctaLinkStyles,
3
3
  sectionSubtitleStyles,
4
4
  sectionTitleStyles
5
- } from "./chunk-3VE6VFJ4.js";
5
+ } from "./chunk-FZ36KL73.js";
6
6
  import {
7
7
  buttonResetStyles,
8
8
  controlBaseStyles,
9
9
  rootFontFamilyStyles
10
- } from "./chunk-RHAOQ6K4.js";
10
+ } from "./chunk-KMU6ABQF.js";
11
11
  import {
12
12
  __decorateClass
13
13
  } from "./chunk-EUXUH3YW.js";
@@ -154,4 +154,4 @@ PromoBanner = __decorateClass([
154
154
  export {
155
155
  PromoBanner
156
156
  };
157
- //# sourceMappingURL=chunk-HGJT24UG.js.map
157
+ //# sourceMappingURL=chunk-VWS53WY4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/promo-banner/PromoBanner.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { buttonResetStyles, controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\nimport { ctaLinkStyles, sectionSubtitleStyles, sectionTitleStyles } from '../shared/section-styles';\nimport type { HeroActionEventDetail } from '../hero/HeroEvents';\n\n/**\n * Rounded call-to-action banner (title, subtitle, one outlined button) on a dark panel or a\n * background image. Port of `SankhyaUI`'s React `PromoBanner`; the button fires an `action` event\n * (detail `{ href }`, empty unless set) in place of `onAction`.\n *\n * @cssprop --st-promo-banner-margin - Overrides the banner's margin.\n * @cssprop --st-promo-banner-padding - Overrides the banner's padding.\n */\n@customElement('st-promo-banner')\nexport class PromoBanner extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n box-sizing: border-box;\n width: calc(100% - 48px);\n max-width: var(--st-cms-container-max);\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n margin/padding; override with --st-promo-banner-margin/-padding instead. */\n margin: var(--st-promo-banner-margin, var(--st-space-40) auto) !important;\n padding: var(--st-promo-banner-padding, 100px var(--st-space-24)) !important;\n border-radius: var(--st-space-24);\n background-color: var(--st-color-text-strong);\n background-size: cover;\n background-position: center;\n color: var(--st-color-on-solid);\n text-align: center;\n ${rootFontFamilyStyles}\n }\n\n :host([inverted]) {\n background-color: var(--st-color-subtle);\n color: var(--st-color-text-strong);\n }\n\n .container {\n max-width: 800px;\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--st-space-32);\n }\n\n .title {\n ${sectionTitleStyles}\n color: inherit;\n margin: 0;\n letter-spacing: -0.02em;\n }\n\n .subtitle {\n ${sectionSubtitleStyles}\n color: inherit;\n opacity: 0.8;\n margin: 0;\n }\n\n .actions {\n margin-top: var(--st-space-16);\n }\n\n .cta {\n ${buttonResetStyles}\n ${ctaLinkStyles}\n border: 1px solid currentColor;\n color: inherit;\n }\n\n .cta:hover {\n transform: scale(1.05);\n }\n\n @media (max-width: 768px) {\n :host {\n width: auto;\n margin: var(--st-promo-banner-margin, var(--st-space-24)) !important;\n padding: var(--st-promo-banner-padding, 60px var(--st-space-24)) !important;\n border-radius: var(--st-radius-lg);\n }\n .actions,\n .cta {\n width: 100%;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .cta {\n transition: none;\n }\n }\n `;\n\n @property({ type: String })\n title = '';\n\n @property({ type: String })\n subtitle = '';\n\n @property({ type: String, attribute: 'action-label' })\n actionLabel = '';\n\n @property({ type: String })\n href = '';\n\n @property({ type: String, attribute: 'image-src' })\n imageSrc = '';\n\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n protected willUpdate(): void {\n this.style.backgroundImage = this.imageSrc ? `url(${JSON.stringify(this.imageSrc)})` : '';\n }\n\n private onAction = (): void => {\n this.dispatchEvent(\n new CustomEvent<HeroActionEventDetail>('action', { detail: { href: this.href }, bubbles: true, composed: true })\n );\n };\n\n render() {\n return html`\n <div class=\"container\" part=\"container\">\n <h2 class=\"title\" part=\"title\">${this.title}</h2>\n ${this.subtitle ? html`<p class=\"subtitle\" part=\"subtitle\">${this.subtitle}</p>` : nothing}\n <slot></slot>\n ${this.actionLabel\n ? html`<div class=\"actions\" part=\"actions\">\n <button class=\"cta\" part=\"action\" type=\"button\" @click=${this.onAction}>${this.actionLabel}</button>\n </div>`\n : nothing}\n </div>\n `;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,gBAAgB;AAejC,IAAM,cAAN,cAA0B,WAAW;AAAA,EAArC;AAAA;AAsFL,iBAAQ;AAGR,oBAAW;AAGX,uBAAc;AAGd,gBAAO;AAGP,oBAAW;AAGX,oBAAW;AAMX,SAAQ,WAAW,MAAY;AAC7B,WAAK;AAAA,QACH,IAAI,YAAmC,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,KAAK,GAAG,SAAS,MAAM,UAAU,KAAK,CAAC;AAAA,MACjH;AAAA,IACF;AAAA;AAAA,EARU,aAAmB;AAC3B,SAAK,MAAM,kBAAkB,KAAK,WAAW,OAAO,KAAK,UAAU,KAAK,QAAQ,CAAC,MAAM;AAAA,EACzF;AAAA,EAQA,SAAS;AACP,WAAO;AAAA;AAAA,yCAE8B,KAAK,KAAK;AAAA,UACzC,KAAK,WAAW,2CAA2C,KAAK,QAAQ,SAAS,OAAO;AAAA;AAAA,UAExF,KAAK,cACH;AAAA,uEAC2D,KAAK,QAAQ,IAAI,KAAK,WAAW;AAAA,sBAE5F,OAAO;AAAA;AAAA;AAAA,EAGjB;AACF;AA/Ha,YACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAiBf,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAkBpB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOlB,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAWrB,iBAAiB;AAAA,QACjB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BnB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GArFf,YAsFX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAxFf,YAyFX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,eAAe,CAAC;AAAA,GA3F1C,YA4FX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA9Ff,YA+FX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GAjGvC,YAkGX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GApG/B,YAqGX;AArGW,cAAN;AAAA,EADN,cAAc,iBAAiB;AAAA,GACnB;","names":[]}
@@ -3,12 +3,12 @@ import {
3
3
  iconTileStyles,
4
4
  reducedMotionStyles,
5
5
  sectionTitleStyles
6
- } from "./chunk-3VE6VFJ4.js";
6
+ } from "./chunk-FZ36KL73.js";
7
7
  import {
8
8
  controlBaseStyles,
9
9
  ctaButtonStyles,
10
10
  fontFamilyStyles
11
- } from "./chunk-RHAOQ6K4.js";
11
+ } from "./chunk-KMU6ABQF.js";
12
12
  import {
13
13
  __decorateClass
14
14
  } from "./chunk-EUXUH3YW.js";
@@ -265,4 +265,4 @@ FeatureSplit = __decorateClass([
265
265
  export {
266
266
  FeatureSplit
267
267
  };
268
- //# sourceMappingURL=chunk-VRRBMOUP.js.map
268
+ //# sourceMappingURL=chunk-WT4OATGP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/feature-split/FeatureSplit.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport 'iconify-icon';\n\nimport { controlBaseStyles, ctaButtonStyles, fontFamilyStyles } from '../shared/styles';\nimport '../markdown';\nimport {\n cardTitleStyles,\n iconTileStyles,\n reducedMotionStyles,\n sectionTitleStyles,\n} from '../shared/section-styles';\nimport type { FeatureSplitActionEventDetail } from './FeatureSplitEvents';\n\nexport interface FeatureSplitItem {\n /** Iconify icon name, e.g. `mdi:check`. */\n icon?: string;\n title: string;\n /** Markdown. */\n description: string;\n}\n\nexport type FeatureSplitImagePosition = 'left' | 'right' | 'top';\n\n/**\n * A title/markdown-subtitle/feature-list block beside (or under) an image.\n *\n * @cssprop --st-feature-split-padding - Overrides the block's padding.\n */\n@customElement('st-feature-split')\nexport class FeatureSplit extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n padding; override with --st-feature-split-padding instead. */\n padding: var(--st-feature-split-padding, var(--st-space-24)) !important;\n background: var(--st-color-page);\n ${fontFamilyStyles}\n }\n\n :host([inverted]) {\n background: var(--st-color-text-strong);\n }\n\n .container {\n max-width: var(--st-cms-container-max);\n margin: 0 auto;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--st-space-48);\n align-items: center;\n }\n\n :host([image-position='left']) .container {\n direction: rtl;\n }\n\n :host([image-position='left']) .content {\n direction: ltr;\n }\n\n :host([image-position='top']) .container {\n grid-template-columns: 1fr;\n text-align: center;\n }\n\n :host([image-position='top']) .content {\n align-items: center;\n }\n\n :host([image-position='top']) .image-wrapper {\n order: -1;\n max-width: 800px;\n margin: 0 auto;\n }\n\n .content {\n display: flex;\n flex-direction: column;\n gap: var(--st-space-32);\n }\n\n .title {\n ${sectionTitleStyles}\n margin: 0;\n }\n\n .subtitle {\n color: var(--st-color-text-muted);\n font-size: var(--st-text-base);\n line-height: 1.6;\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: var(--st-space-24);\n margin-top: var(--st-space-16);\n }\n\n .item {\n display: flex;\n gap: var(--st-space-16);\n align-items: flex-start;\n text-align: left;\n }\n\n .icon {\n ${iconTileStyles}\n width: var(--st-space-48);\n height: var(--st-space-48);\n font-size: 24px;\n }\n\n .item-title {\n ${cardTitleStyles}\n }\n\n .item-description {\n color: var(--st-color-text-muted);\n font-size: var(--st-text-sm);\n line-height: 1.5;\n }\n\n .action {\n ${ctaButtonStyles}\n justify-self: start;\n padding: var(--st-space-16);\n border-radius: var(--st-radius-lg);\n }\n\n .image-wrapper {\n width: 100%;\n height: 100%;\n min-height: 400px;\n border-radius: var(--st-space-24);\n overflow: hidden;\n box-shadow: 0 20px 40px -12px var(--st-shadow-color-md);\n }\n\n .image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: transform 0.5s ease;\n }\n\n .image:hover {\n transform: scale(1.02);\n }\n\n :host([inverted]) .title,\n :host([inverted]) .item-title {\n color: var(--st-color-on-solid);\n }\n\n :host([inverted]) .subtitle,\n :host([inverted]) .item-description {\n color: var(--st-color-border);\n }\n\n :host([inverted]) .icon {\n background: var(--st-color-text);\n color: var(--st-color-border);\n }\n\n @media (max-width: 1024px) {\n .container {\n gap: var(--st-space-40);\n }\n }\n\n @media (max-width: 768px) {\n :host {\n padding: var(--st-feature-split-padding, var(--st-space-48) var(--st-space-24)) !important;\n }\n\n .container {\n grid-template-columns: 1fr;\n direction: ltr !important;\n }\n\n .image-wrapper {\n min-height: 300px;\n order: -1;\n }\n }\n\n ${reducedMotionStyles}\n `;\n\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n @property({ type: String })\n title = '';\n\n /** Markdown. */\n @property({ type: String })\n subtitle = '';\n\n @property({ attribute: false })\n items: FeatureSplitItem[] = [];\n\n @property({ type: String, attribute: 'image-src' })\n imageSrc = '';\n\n @property({ type: String, attribute: 'image-alt' })\n imageAlt = '';\n\n @property({ type: String, attribute: 'image-position', reflect: true })\n imagePosition: FeatureSplitImagePosition = 'right';\n\n @property({ type: String, attribute: 'action-label' })\n actionLabel = '';\n\n @property({ type: String })\n href = '';\n\n private onAction() {\n const event = new CustomEvent<FeatureSplitActionEventDetail>('feature-split-action', {\n detail: { href: this.href },\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n if (this.dispatchEvent(event)) window.location.href = this.href;\n }\n\n render() {\n return html`\n <div class=\"container\" part=\"container\">\n <div class=\"content\" part=\"content\">\n <h2 class=\"title\" part=\"title\">${this.title}</h2>\n ${this.subtitle\n ? html`<div class=\"subtitle\" part=\"subtitle\"><st-markdown .content=${this.subtitle}></st-markdown></div>`\n : nothing}\n ${this.items.length > 0\n ? html`<div class=\"list\" part=\"list\">\n ${this.items.map(\n (item) => html`\n <div class=\"item\" part=\"item\">\n ${item.icon\n ? html`<div class=\"icon\" part=\"icon\"><iconify-icon icon=${item.icon}></iconify-icon></div>`\n : nothing}\n <div>\n <h3 class=\"item-title\" part=\"item-title\">${item.title}</h3>\n <div class=\"item-description\" part=\"item-description\">\n <st-markdown .content=${item.description}></st-markdown>\n </div>\n </div>\n </div>\n `,\n )}\n </div>`\n : nothing}\n ${this.actionLabel && this.href\n ? html`<button class=\"action\" part=\"action\" type=\"button\" @click=${this.onAction}>${this.actionLabel}</button>`\n : nothing}\n </div>\n <div class=\"image-wrapper\" part=\"image-wrapper\">\n <img class=\"image\" part=\"image\" src=${this.imageSrc} alt=${this.imageAlt || this.title} />\n </div>\n </div>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -352,4 +352,4 @@ export {
352
352
  gearIcon,
353
353
  paletteIcon
354
354
  };
355
- //# sourceMappingURL=chunk-PB7ZPPLP.js.map
355
+ //# sourceMappingURL=chunk-WTD2YIAA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/icons.ts"],"sourcesContent":["import { html } from 'lit';\nimport type { TemplateResult } from 'lit';\n\n/**\n * Every inline SVG icon used across components, centralized so a glyph's\n * path data lives in exactly one place instead of being copy-pasted at each\n * call site. Each icon is a small function returning a Lit `TemplateResult`\n * (not a `css`-style fragment) so callers can size — and, where noted, class\n * — the icon per context while sharing the same markup.\n */\n\nconst FOLDER_ICON_COLOR = 'oklch(0.72 0.09 75)';\n\n/** Filled folder glyph (browse rows/tiles). Fixed 20x16 — folders don't resize per usage. */\nexport function folderIcon(): TemplateResult {\n return html`\n <svg width=\"20\" height=\"16\" viewBox=\"0 0 20 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M0 2a2 2 0 012-2h5l2 2h9a2 2 0 012 2v10a2 2 0 01-2 2H2a2 2 0 01-2-2V2z\" fill=${FOLDER_ICON_COLOR} />\n </svg>\n `;\n}\n\n/** Outlined folder glyph (breadcrumb crumb icon). `className` lets the caller hook its own layout class. */\nexport function folderOutlineIcon(size = 11, className = ''): TemplateResult {\n return html`\n <svg class=${className} width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M4 4h5l2 2h9v12H4V4z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n}\n\n/** External-link/\"open\" glyph (open site/library actions in the Templates/Data/Save-location pickers). */\nexport function externalLinkIcon(size = 15): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M18 13v5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5M15 4h5v5M20 4l-9 9\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n}\n\n/** Refresh/reload glyph (Templates/Data picker refresh buttons). */\nexport function refreshIcon(size = 15): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M17.65 6.35A7.958 7.958 0 0 0 12 4a8 8 0 1 0 8 8h-2a6 6 0 1 1-6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z\"\n fill=\"currentColor\"\n />\n </svg>\n `;\n}\n\n/** Clock glyph (the wizard's \"Recent activity\" history trigger button, Steps 1-3). */\nexport function historyIcon(size = 15): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M12 7v5l3.5 2\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n `;\n}\n\n/** Trash/delete glyph (clear-all button in the selected-chips summary badge). */\nexport function trashIcon(size = 15): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M4 4h2l1.2 12.4A2 2 0 0 0 9.2 18.2h8.1a2 2 0 0 0 1.98-1.7L20.5 8H6.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <circle cx=\"10\" cy=\"21\" r=\"1.4\" fill=\"currentColor\" />\n <circle cx=\"17\" cy=\"21\" r=\"1.4\" fill=\"currentColor\" />\n </svg>\n `;\n}\n\n/** Chevron glyph (pager prev/next buttons, the select trigger's caret). */\nexport function chevronIcon(direction: 'left' | 'right' | 'down', size = 14): TemplateResult {\n const d = { left: 'M15 18l-6-6 6-6', right: 'M9 6l6 6-6 6', down: 'M6 9l6 6 6-6' }[direction];\n\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=${d} stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n `;\n}\n\n/** Up-right arrow glyph (marks a link that leaves the site — mega-menu links and buttons). */\nexport function arrowUpRightIcon(size = 12): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M7 17L17 7M8 7h9v9\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n `;\n}\n\n/** Plus glyph (\"New folder\" action button). */\nexport function plusIcon(size = 13): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M12 4v16M4 12h16\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" />\n </svg>\n `;\n}\n\n/** Cards-view glyph (2x2 grid — view-toggle button). */\nexport function cardsViewIcon(size = 15): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"1\" y=\"1\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n <rect x=\"9\" y=\"1\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n <rect x=\"1\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n </svg>\n `;\n}\n\n/** Checkmark glyph (completed-step marker in the step indicator). */\nexport function checkIcon(size = 14): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 12l5 5L20 6\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n `;\n}\n\n/** SharePoint site glyph (globe — root \"All sites\" browser rows). */\nexport function siteIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"1.6\" />\n <path d=\"M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18\" stroke=\"currentColor\" stroke-width=\"1.6\" />\n </svg>\n `;\n}\n\n/** 3x3 dot-grid glyph (bento-menu app-switcher trigger). */\nexport function bentoGridIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M16 20h4v-4h-4m0-2h4v-4h-4m-6-2h4V4h-4m6 4h4V4h-4m-6 10h4v-4h-4m-6 4h4v-4H4m0 10h4v-4H4m6 4h4v-4h-4M4 8h4V4H4z\"\n />\n </svg>\n `;\n}\n\n/** List-view glyph (stacked rows — view-toggle button). */\nexport function listViewIcon(size = 15): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"1\" y=\"2\" width=\"3\" height=\"3\" rx=\"0.5\" fill=\"currentColor\" />\n <rect x=\"6\" y=\"2.5\" width=\"9\" height=\"2\" rx=\"1\" fill=\"currentColor\" />\n <rect x=\"1\" y=\"6.5\" width=\"3\" height=\"3\" rx=\"0.5\" fill=\"currentColor\" />\n <rect x=\"6\" y=\"7\" width=\"9\" height=\"2\" rx=\"1\" fill=\"currentColor\" />\n <rect x=\"1\" y=\"11\" width=\"3\" height=\"3\" rx=\"0.5\" fill=\"currentColor\" />\n <rect x=\"6\" y=\"11.5\" width=\"9\" height=\"2\" rx=\"1\" fill=\"currentColor\" />\n </svg>\n `;\n}\n\n/**\n * A small set of generic domain icons for `st-menu-grid-item`'s icon slot (nav \"mega menu\"\n * entries — sales/purchase/accounting/settings items) — deliberately simple line glyphs rather\n * than pixel-perfect illustrations, same fidelity level as the icons above.\n */\n\n/** Shopping-cart glyph (sales/orders). */\nexport function cartIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3 4h2l2.4 12.4A2 2 0 0 0 9.36 18h8.2a2 2 0 0 0 1.96-1.6L21 8H6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <circle cx=\"10\" cy=\"21\" r=\"1.4\" fill=\"currentColor\" />\n <circle cx=\"17\" cy=\"21\" r=\"1.4\" fill=\"currentColor\" />\n </svg>\n `;\n}\n\n/** Delivery-truck glyph (purchase orders / receiving). */\nexport function truckIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2 6h11v10H2z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\n <path d=\"M13 10h4l4 3.5V16h-8z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\n <circle cx=\"6.5\" cy=\"18\" r=\"1.8\" stroke=\"currentColor\" stroke-width=\"2\" />\n <circle cx=\"16.5\" cy=\"18\" r=\"1.8\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n `;\n}\n\n/** Package/box glyph (products, inventory). */\nexport function boxIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12 3l8 4.2v9.6L12 21l-8-4.2V7.2L12 3z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linejoin=\"round\"\n />\n <path d=\"M4.2 7.2L12 11l7.8-3.8M12 11v10\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\n </svg>\n `;\n}\n\n/** Map-pin glyph (stock locations). */\nexport function mapPinIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12 21s7-6.1 7-11.5A7 7 0 0 0 5 9.5C5 14.9 12 21 12 21z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linejoin=\"round\"\n />\n <circle cx=\"12\" cy=\"9.5\" r=\"2.4\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n `;\n}\n\n/** Two-person glyph (partners — customers/vendors/employees). */\nexport function usersIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"9\" cy=\"8\" r=\"3.2\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M3 20c0-3.3 2.7-6 6-6s6 2.7 6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n <path\n d=\"M16 5.3a3.2 3.2 0 0 1 0 6.2M19 20c0-2.8-2-5.1-4.6-5.8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n `;\n}\n\n/** Open-book glyph (journals). */\nexport function bookIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12 5.5c-1.6-1-4-1.5-6-1.5-1 0-2 .1-3 .4v13.6c1-.3 2-.4 3-.4 2 0 4.4.5 6 1.5m0-13.6c1.6-1 4-1.5 6-1.5 1 0 2 .1 3 .4v13.6c-1-.3-2-.4-3-.4-2 0-4.4.5-6 1.5m0-13.6v13.6\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n}\n\n/** Document/invoice glyph. */\nexport function documentIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6 2h9l5 5v15H6V2z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\n <path d=\"M15 2v5h5\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\n <path d=\"M9 12h6M9 16h6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n `;\n}\n\n/** Receipt glyph, zig-zag bottom edge (credit/debit notes). */\nexport function receiptIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M5 2h14v19l-2.5-1.6L14 21l-2.5-1.6L9 21l-2.5-1.6L5 21V2z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linejoin=\"round\"\n />\n <path d=\"M8 8h8M8 12h8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n `;\n}\n\n/** Percent glyph (taxes). */\nexport function percentIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M19 5L5 19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n <circle cx=\"7\" cy=\"7\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"2\" />\n <circle cx=\"17\" cy=\"17\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n `;\n}\n\n/** Stacked-coins glyph (payment terms). */\nexport function coinsIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <ellipse cx=\"8\" cy=\"7\" rx=\"5.5\" ry=\"3\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M2.5 7v10c0 1.7 2.5 3 5.5 3s5.5-1.3 5.5-3V7\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M2.5 12c0 1.7 2.5 3 5.5 3s5.5-1.3 5.5-3\" stroke=\"currentColor\" stroke-width=\"2\" />\n <ellipse cx=\"16.5\" cy=\"12\" rx=\"5\" ry=\"2.7\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M11.5 12v5c0 1.5 2.2 2.7 5 2.7s5-1.2 5-2.7v-5\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n `;\n}\n\n/** Padlock glyph (fiscal year closing / lock dates). */\nexport function lockIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"4\" y=\"11\" width=\"16\" height=\"10\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n <circle cx=\"12\" cy=\"16\" r=\"1.6\" fill=\"currentColor\" />\n </svg>\n `;\n}\n\n/**\n * Office file-type glyphs, ported from `PennyIcons` in `@sankhyatronics/sankhya-icons`\n * (FileWordIcon/FileExcelIcon/FilePowerPointIcon) — this package is Lit, so it can't import\n * the React components and carries the same path data instead. Filled, `currentColor`.\n */\nconst FILE_TYPE_ICON_PATHS = {\n word: 'm19.95 5.54-3.48-3.49A6.96 6.96 0 0 0 11.52 0H7C4.24 0 2 2.24 2 5v14c0 2.76 2.24 5 5 5h10c2.76 0 5-2.24 5-5v-8.51c0-1.87-.73-3.63-2.05-4.95Zm-1.41 1.41c.32.32.59.67.81 1.05h-4.34c-.55 0-1-.45-1-1V2.66c.38.22.73.49 1.05.81l3.48 3.49ZM20 19c0 1.65-1.35 3-3 3H7c-1.65 0-3-1.35-3-3V5c0-1.65 1.35-3 3-3h4.51c.16 0 .33 0 .49.02V7c0 1.65 1.35 3 3 3h4.98c.02.16.02.32.02.49V19Zm-3.28-5.76L15.3 18.9c-.15.61-.68 1.05-1.31 1.09-.63.04-1.21-.32-1.44-.91L12 17.7l-.55 1.38c-.22.56-.75.91-1.34.91h-.1c-.63-.04-1.15-.48-1.31-1.1l-1.41-5.66a1 1 0 0 1 1.94-.48l1 4 .85-2.13a1 1 0 0 1 1.86 0l.84 2.13 1.01-4a1 1 0 0 1 1.94.48Z',\n excel:\n 'M15.27 13.64 13.3 16l1.97 2.36a1.001 1.001 0 1 1-1.54 1.28L12 17.56l-1.73 2.08a.99.99 0 0 1-.77.36c-.23 0-.45-.08-.64-.23-.42-.35-.48-.98-.13-1.41L10.7 16l-1.97-2.36a1.001 1.001 0 1 1 1.54-1.28L12 14.44l1.73-2.08c.35-.42.98-.48 1.41-.13.42.35.48.98.13 1.41ZM22 10.49V19c0 2.76-2.24 5-5 5H7c-2.76 0-5-2.24-5-5V5c0-2.76 2.24-5 5-5h4.51c1.87 0 3.63.73 4.95 2.05l3.48 3.49a6.96 6.96 0 0 1 2.05 4.95Zm-6.95-7.03c-.32-.32-.67-.59-1.05-.81V7c0 .55.45 1 1 1h4.34c-.22-.38-.49-.73-.81-1.05l-3.48-3.49ZM20 10.48c0-.16 0-.33-.02-.49H15c-1.65 0-3-1.35-3-3V2.02C11.84 2 11.68 2 11.51 2H7C5.35 2 4 3.35 4 5v14c0 1.65 1.35 3 3 3h10c1.65 0 3-1.35 3-3v-8.51Z',\n powerpoint:\n 'm19.95 5.54-3.49-3.49A6.96 6.96 0 0 0 11.51 0H7C4.24 0 2 2.24 2 5v14c0 2.76 2.24 5 5 5h10c2.76 0 5-2.24 5-5v-8.51c0-1.87-.73-3.63-2.05-4.95Zm-1.41 1.41c.32.32.59.67.81 1.05h-4.34c-.55 0-1-.45-1-1V2.66c.38.22.73.49 1.05.81l3.49 3.49ZM20 19c0 1.65-1.35 3-3 3H7c-1.65 0-3-1.35-3-3V5c0-1.65 1.35-3 3-3h4.51c.16 0 .33 0 .49.02V7c0 1.65 1.35 3 3 3h4.98c.02.16.02.32.02.49V19Zm-10 1c-.55 0-1-.45-1-1v-5c0-1.1.9-2 2-2h1c1.65 0 3 1.35 3 3s-1.35 3-3 3h-1v1c0 .55-.45 1-1 1Zm1-4h1c.55 0 1-.45 1-1s-.45-1-1-1h-1v2Z'\n} as const;\n\n/** Word/Excel/PowerPoint file glyph (the document icon in front of template/file rows). */\nexport function fileTypeIcon(type: keyof typeof FILE_TYPE_ICON_PATHS, size = 24): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=${FILE_TYPE_ICON_PATHS[type]} />\n </svg>\n `;\n}\n\n/** Hamburger glyph (`st-header`'s mobile nav toggle, closed state). */\nexport function menuIcon(size = 20): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 6h16M4 12h16M4 18h16\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n `;\n}\n\n/** X/close glyph (`st-header`'s mobile nav toggle, open state). */\nexport function closeIcon(size = 20): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 5l14 14M19 5L5 19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n `;\n}\n\n/** Gear/cog glyph (company settings). */\nexport function gearIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path\n d=\"M12 3v2.2M12 18.8V21M21 12h-2.2M5.2 12H3M18 6l-1.6 1.6M7.6 16.4L6 18M18 18l-1.6-1.6M7.6 7.6L6 6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n `;\n}\n\n/** Paint-palette glyph (theme/color-scheme switcher). */\nexport function paletteIcon(size = 18): TemplateResult {\n return html`\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12 3a9 9 0 1 0 0 18c1.1 0 2-.9 2-2 0-.5-.2-1-.5-1.3-.3-.4-.5-.8-.5-1.2 0-1.1.9-2 2-2h2a4 4 0 0 0 4-4c0-4.4-4-7.5-9-7.5z\"\n stroke=\"currentColor\"\n stroke-width=\"1.6\"\n stroke-linejoin=\"round\"\n />\n <circle cx=\"7.5\" cy=\"10.5\" r=\"1.2\" fill=\"currentColor\" />\n <circle cx=\"11\" cy=\"7\" r=\"1.2\" fill=\"currentColor\" />\n <circle cx=\"15.5\" cy=\"7.5\" r=\"1.2\" fill=\"currentColor\" />\n <circle cx=\"17.5\" cy=\"11.5\" r=\"1.2\" fill=\"currentColor\" />\n </svg>\n `;\n}\n"],"mappings":";AAAA,SAAS,YAAY;AAWrB,IAAM,oBAAoB;AAGnB,SAAS,aAA6B;AAC3C,SAAO;AAAA;AAAA,8FAEqF,iBAAiB;AAAA;AAAA;AAG/G;AAGO,SAAS,kBAAkB,OAAO,IAAI,YAAY,IAAoB;AAC3E,SAAO;AAAA,iBACQ,SAAS,UAAU,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvD;AAGO,SAAS,iBAAiB,OAAO,IAAoB;AAC1D,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUpC;AAGO,SAAS,YAAY,OAAO,IAAoB;AACrD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOpC;AAGO,SAAS,YAAY,OAAO,IAAoB;AACrD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAKpC;AAGO,SAAS,UAAU,OAAO,IAAoB;AACnD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYpC;AAGO,SAAS,YAAY,WAAsC,OAAO,IAAoB;AAC3F,QAAM,IAAI,EAAE,MAAM,mBAAmB,OAAO,gBAAgB,MAAM,eAAe,EAAE,SAAS;AAE5F,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA,gBACpB,CAAC;AAAA;AAAA;AAGjB;AAGO,SAAS,iBAAiB,OAAO,IAAoB;AAC1D,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAIpC;AAGO,SAAS,SAAS,OAAO,IAAoB;AAClD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAIpC;AAGO,SAAS,cAAc,OAAO,IAAoB;AACvD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOpC;AAGO,SAAS,UAAU,OAAO,IAAoB;AACnD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAIpC;AAGO,SAAS,SAAS,OAAO,IAAoB;AAClD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAKpC;AAGO,SAAS,cAAc,OAAO,IAAoB;AACvD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAMpC;AAGO,SAAS,aAAa,OAAO,IAAoB;AACtD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpC;AASO,SAAS,SAAS,OAAO,IAAoB;AAClD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYpC;AAGO,SAAS,UAAU,OAAO,IAAoB;AACnD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOpC;AAGO,SAAS,QAAQ,OAAO,IAAoB;AACjD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUpC;AAGO,SAAS,WAAW,OAAO,IAAoB;AACpD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUpC;AAGO,SAAS,UAAU,OAAO,IAAoB;AACnD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWpC;AAGO,SAAS,SAAS,OAAO,IAAoB;AAClD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUpC;AAGO,SAAS,aAAa,OAAO,IAAoB;AACtD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAMpC;AAGO,SAAS,YAAY,OAAO,IAAoB;AACrD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUpC;AAGO,SAAS,YAAY,OAAO,IAAoB;AACrD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAMpC;AAGO,SAAS,UAAU,OAAO,IAAoB;AACnD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQpC;AAGO,SAAS,SAAS,OAAO,IAAoB;AAClD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAMpC;AAOA,IAAM,uBAAuB;AAAA,EAC3B,MAAM;AAAA,EACN,OACE;AAAA,EACF,YACE;AACJ;AAGO,SAAS,aAAa,MAAyC,OAAO,IAAoB;AAC/F,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA,gBACpB,qBAAqB,IAAI,CAAC;AAAA;AAAA;AAG1C;AAGO,SAAS,SAAS,OAAO,IAAoB;AAClD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAIpC;AAGO,SAAS,UAAU,OAAO,IAAoB;AACnD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAIpC;AAGO,SAAS,SAAS,OAAO,IAAoB;AAClD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUpC;AAGO,SAAS,YAAY,OAAO,IAAoB;AACrD,SAAO;AAAA,iBACQ,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAapC;","names":[]}
@@ -2,14 +2,14 @@ import {
2
2
  chevronIcon,
3
3
  closeIcon,
4
4
  menuIcon
5
- } from "./chunk-PB7ZPPLP.js";
5
+ } from "./chunk-WTD2YIAA.js";
6
6
  import {
7
7
  BREAKPOINT_TABLET,
8
8
  buttonResetStyles,
9
9
  controlBaseStyles,
10
10
  dropdownPanelStyles,
11
11
  rootFontFamilyStyles
12
- } from "./chunk-RHAOQ6K4.js";
12
+ } from "./chunk-KMU6ABQF.js";
13
13
  import {
14
14
  __decorateClass
15
15
  } from "./chunk-EUXUH3YW.js";
@@ -241,7 +241,8 @@ var Header = class extends LitElement {
241
241
  aria-expanded=${this.mobileOpen}
242
242
  @click=${() => this.mobileOpen = !this.mobileOpen}
243
243
  >
244
- ${this.mobileOpen ? closeIcon() : menuIcon()}
244
+ <slot name="menu-icon" ?hidden=${this.mobileOpen}>${menuIcon()}</slot>
245
+ <slot name="close-icon" ?hidden=${!this.mobileOpen}>${closeIcon()}</slot>
245
246
  </button>
246
247
  `;
247
248
  }
@@ -280,6 +281,21 @@ Header.styles = css`
280
281
  z-index: 100;
281
282
  }
282
283
 
284
+ /* Toggle icons: a host's slotted icon, else the built-in glyph; only the current state's shows. */
285
+ .toggle slot {
286
+ display: contents;
287
+ }
288
+
289
+ .toggle slot[hidden] {
290
+ display: none;
291
+ }
292
+
293
+ .toggle ::slotted(*) {
294
+ flex: none;
295
+ width: var(--st-header-toggle-icon-size, 20px);
296
+ height: var(--st-header-toggle-icon-size, 20px);
297
+ }
298
+
283
299
  :host([inverted]) {
284
300
  background: var(--st-color-text-strong);
285
301
  color: var(--st-color-on-solid);
@@ -689,4 +705,4 @@ Header = __decorateClass([
689
705
  export {
690
706
  Header
691
707
  };
692
- //# sourceMappingURL=chunk-X2ALYIVT.js.map
708
+ //# sourceMappingURL=chunk-XWB4CKDU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/header/Header.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { chevronIcon, closeIcon, menuIcon } from '../shared/icons';\nimport { BREAKPOINT_TABLET, buttonResetStyles, controlBaseStyles, dropdownPanelStyles, rootFontFamilyStyles } from '../shared/styles';\nimport type { LanguageChangedEventDetail } from './HeaderEvents';\n\n/**\n * The app-shell header bar — brand (image + title, or title alone) on the left, a `slot=\"menu\"`\n * for primary nav (e.g. `st-dropdown`/`st-menu-grid` mega-menus, or plain links) taking the\n * middle, and a `slot=\"utility\"` for account/app-switcher/theme controls on the right. Ported\n * from `SankhyaUI`'s React `Header` (a separate, unrelated marketing-site project) to this\n * package's Lit conventions and this workspace's actual needs — that source component takes an\n * `imageSrc` logo with no text fallback, but none of this suite's apps has a logo image today, so\n * `title` is the primary brand prop here and `brand-image-url` is optional, mirroring\n * `st-app-header`'s own brand/title split (this component's slotted-menu/utility shape is a\n * deliberately different, more generic surface than `st-app-header`'s fixed nav-links/user-menu\n * props — pick whichever fits a given app's header).\n *\n * Layout follows the source's `Header.css`: the menu starts 4rem after the brand, the utility\n * controls sit after a vertical divider, and below `BREAKPOINT_TABLET` (900px here; 768px in the\n * source) `menu`/`utility` collapse behind a hamburger toggle into a full-screen layer under the\n * toggle (closes on Escape or a click inside it), where the menu's `st-dropdown`s are switched to\n * `inline` so they open in the flow — the same two slotted elements just get repositioned by CSS\n * (`.mobile-panel`'s `display: contents` at desktop width vs. a real fixed-position box below\n * `BREAKPOINT_TABLET`), rather than the slots being duplicated in the template, since a shadow\n * root can only ever assign a given light-DOM child to the *first* slot of a given name.\n *\n * An optional `slot=\"brand-extra\"` sits right after the brand (e.g. an edition badge such as\n * \"🇮🇳 India Edition\"); unlike `menu`/`utility` it stays in the bar at every width.\n *\n * Also carries an optional built-in language switcher (`languages`/`currentLanguageCode`, fires\n * `language-change`) — ported from `st-app-header`'s own implementation verbatim rather than\n * rebuilt, since the source `Header`'s reference story shows an equivalent flag/language `Select`\n * as a first-class header utility. Hidden entirely when `languages` has fewer than two entries.\n * This component has no translation logic itself; the consuming app owns what a language `code`\n * means and which content it re-renders in response.\n *\n * @slot menu - Primary navigation.\n * @slot utility - Account, app-switcher and theme controls, after the divider.\n * @slot brand-extra - Shown right after the brand at every width (e.g. an edition badge).\n * @slot menu-icon - Replaces the hamburger on the narrow-screen toggle (the built-in glyph when empty).\n * @slot close-icon - Replaces the close (X) on the toggle while the menu is open (the built-in glyph when empty).\n * @cssprop --st-header-toggle-icon-size - Width and height of a slotted toggle icon (default 20px, the built-in glyph's size).\n */\n@customElement('st-header')\nexport class Header extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: flex;\n align-items: center;\n /* The containing block of an st-dropdown[mega] panel, which spans the bar. */\n position: relative;\n /* Spacing between brand, menu and utility controls is the rows' own margins (SankhyaUI's\n layout), not a flex gap. */\n gap: 0;\n /* !important on the box-model properties only: a shadow host's own :host rule always loses\n * to ANY rule the consuming page has for the same property on that element, regardless of\n * specificity (see st-footer's own padding/border-top for the same fix). Without\n * box-sizing: border-box pinned here, a page that also sets its own padding on this host\n * (e.g. a p-2 utility class) adds that padding on TOP of the fixed 64px height instead of\n * being absorbed inside it — which is exactly what happens in Template Hub, the one app that\n * doesn't load Tailwind Preflight (Preflight's own box-sizing: border-box reset is what\n * silently keeps every other app's header at the intended 64px). */\n box-sizing: border-box !important;\n padding: 0 2rem !important;\n height: 64px !important;\n background: var(--st-color-surface);\n border-bottom: 1px solid var(--st-color-border) !important;\n ${rootFontFamilyStyles}\n color: var(--st-color-text-strong);\n }\n\n :host([sticky]) {\n position: sticky;\n top: 0;\n z-index: 100;\n }\n\n /* Toggle icons: a host's slotted icon, else the built-in glyph; only the current state's shows. */\n .toggle slot {\n display: contents;\n }\n\n .toggle slot[hidden] {\n display: none;\n }\n\n .toggle ::slotted(*) {\n flex: none;\n width: var(--st-header-toggle-icon-size, 20px);\n height: var(--st-header-toggle-icon-size, 20px);\n }\n\n :host([inverted]) {\n background: var(--st-color-text-strong);\n color: var(--st-color-on-solid);\n border-bottom-color: transparent;\n }\n\n :host([sticky]),\n :host([transparent]),\n :host([hide-on-scroll]) {\n transition:\n background-color 0.3s ease,\n color 0.3s ease,\n box-shadow 0.3s ease,\n border-color 0.3s ease,\n transform 0.3s ease;\n }\n\n /* Once the page has scrolled, a sticky/fixed header lifts off the content. */\n :host([scrolled][sticky]),\n :host([scrolled][transparent]),\n :host([scrolled][hide-on-scroll]) {\n box-shadow: 0 4px 16px var(--st-shadow-color-md);\n border-bottom-color: transparent !important;\n }\n\n /* transparent: fixed over the top of the page (e.g. a dark hero), see-through until scrolled. */\n :host([transparent]) {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n z-index: 100;\n }\n\n :host([transparent]:not([scrolled]):not([mobile-open])) {\n background: transparent;\n border-bottom-color: transparent !important;\n color: var(--st-header-transparent-color, var(--st-color-on-solid));\n /* Read by st-menu-item / st-dropdown triggers in the bar (their panels reset them). */\n --st-nav-color: var(--st-header-transparent-color, var(--st-color-on-solid));\n --st-nav-hover-bg: color-mix(in oklch, currentColor 14%, transparent);\n }\n\n :host([transparent]:not([scrolled]):not([mobile-open])) .utility-row {\n border-left-color: color-mix(in oklch, currentColor 35%, transparent);\n }\n\n :host([transparent]:not([scrolled]):not([mobile-open])) .lang-trigger {\n color: inherit;\n }\n\n :host([transparent]:not([scrolled]):not([mobile-open])) .lang-trigger:hover,\n :host([transparent]:not([scrolled]):not([mobile-open])) .toggle:hover {\n background: color-mix(in oklch, currentColor 14%, transparent);\n }\n\n /* hide-on-scroll: slides away while scrolling down, back as soon as the user scrolls up. */\n :host([hide-on-scroll]:not([sticky]):not([transparent])) {\n position: sticky;\n top: 0;\n z-index: 100;\n }\n\n :host([scroll-hidden]:not([mobile-open])) {\n transform: translateY(-100%);\n box-shadow: none;\n }\n\n .brand {\n display: flex;\n align-items: center;\n gap: var(--st-space-10);\n flex: none;\n text-decoration: none;\n color: inherit;\n }\n\n .brand-mark {\n width: var(--st-size-28);\n height: var(--st-size-28);\n border-radius: var(--st-radius-sm);\n flex: none;\n object-fit: contain;\n }\n\n .brand-title {\n font-size: var(--st-text-xl);\n font-weight: var(--st-font-weight-bold);\n letter-spacing: var(--st-tracking-tight);\n white-space: nowrap;\n }\n\n /* Optional slot=\"brand-extra\" (e.g. an edition badge) right after the brand. Outside the\n mobile panel, so it stays beside the logo at every width; no box at all when empty. */\n .brand-extra {\n display: flex;\n align-items: center;\n gap: var(--st-space-8);\n flex: none;\n margin-left: var(--st-space-10);\n white-space: nowrap;\n }\n\n .brand-extra.empty {\n display: none;\n }\n\n /* Desktop: a transparent pass-through so .menu-row/.utility-row lay out directly as :host's\n own flex children. Mobile (see below) turns this into the actual overlay box. */\n .mobile-panel {\n display: contents;\n }\n\n /* Desktop layout from SankhyaUI's Header: the menu starts 4rem after the brand and takes the\n free width; the utility controls sit after a vertical divider. Between 901px and 1200px the\n gaps tighten so the menu still fits down to the 900px hamburger breakpoint. */\n .menu-row {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 1.5rem;\n min-width: 0;\n margin-left: 4rem;\n }\n\n .utility-row {\n flex: none;\n display: flex;\n align-items: center;\n gap: 1rem;\n margin-left: 1.5rem;\n padding-left: 1.5rem;\n border-left: 1px solid var(--st-color-border);\n }\n\n :host([inverted]) .utility-row {\n border-left-color: currentColor;\n }\n\n .utility-row.empty {\n display: none;\n }\n\n @media (max-width: 1200px) {\n :host {\n padding: 0 1rem !important;\n }\n\n .menu-row {\n margin-left: 0.5rem;\n }\n\n .utility-row {\n margin-left: 0.5rem;\n padding-left: 0.5rem;\n }\n }\n\n @keyframes st-header-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n .toggle {\n display: none;\n align-items: center;\n justify-content: center;\n flex: none;\n position: relative;\n z-index: 1002;\n width: var(--st-size-32);\n height: var(--st-size-32);\n margin-left: auto;\n padding: 0.5rem;\n border: 0;\n border-radius: var(--st-radius-sm);\n background: transparent;\n color: inherit;\n cursor: pointer;\n }\n\n .toggle:hover {\n background: var(--st-color-hover);\n }\n\n .lang-menu {\n position: relative;\n flex: none;\n }\n\n .lang-trigger {\n ${buttonResetStyles}\n display: flex;\n align-items: center;\n gap: var(--st-space-4);\n height: var(--st-size-32);\n padding: 0 var(--st-space-8);\n border-radius: var(--st-radius-sm);\n font-size: var(--st-text-base);\n font-weight: var(--st-font-weight-semibold);\n color: var(--st-color-text-muted);\n }\n\n .lang-trigger:hover {\n background: var(--st-color-hover);\n color: var(--st-color-text-strong);\n }\n\n .lang-dropdown {\n ${dropdownPanelStyles}\n min-width: 140px;\n }\n\n .lang-option {\n ${buttonResetStyles}\n display: block;\n width: 100%;\n padding: var(--st-space-10) var(--st-space-14);\n font-size: var(--st-text-base);\n font-weight: var(--st-font-weight-semibold);\n text-align: left;\n color: inherit;\n }\n\n .lang-option:hover {\n background: var(--st-color-hover);\n }\n\n .lang-option.active {\n color: var(--st-color-accent-text);\n }\n\n /* Hamburger layout from SankhyaUI's Header: a full-screen layer under the toggle, menu above\n the utility controls, the menu's dropdowns opening in the flow (see syncInlineDropdowns). */\n @media (max-width: ${BREAKPOINT_TABLET}px) {\n :host {\n padding: 0 1rem !important;\n }\n\n .mobile-panel {\n display: none;\n }\n\n .toggle {\n display: inline-flex;\n }\n\n :host([mobile-open]) .mobile-panel {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n position: fixed;\n inset: 0;\n background: var(--st-color-surface);\n padding: 5rem 1.5rem 2rem;\n overflow-y: auto;\n z-index: 1001;\n animation: st-header-fade-in 0.3s ease;\n }\n\n :host([mobile-open]) .menu-row,\n :host([mobile-open]) .utility-row {\n flex-direction: column;\n align-items: stretch;\n gap: 1.5rem;\n margin-left: 0;\n }\n\n :host([mobile-open]) .utility-row {\n padding: 1.5rem 0 0;\n border-left: 0;\n border-top: 1px solid var(--st-color-border);\n }\n\n /* Apps usually slot one flex-row wrapper per slot; stack its items as the source does. */\n :host([mobile-open]) ::slotted([slot='menu']),\n :host([mobile-open]) ::slotted([slot='utility']) {\n flex-direction: column !important;\n align-items: stretch !important;\n margin: 0 !important;\n }\n }\n\n /* The same collapsed layout, switched on by script when the menu no longer fits the bar at\n desktop width (see evaluateFit) — without it the menu spills over the utility controls. */\n :host([compact]) .mobile-panel {\n display: none;\n }\n\n :host([compact]) .toggle {\n display: inline-flex;\n }\n\n :host([compact][mobile-open]) .mobile-panel {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n position: fixed;\n inset: 0;\n background: var(--st-color-surface);\n padding: 5rem 1.5rem 2rem;\n overflow-y: auto;\n z-index: 1001;\n animation: st-header-fade-in 0.3s ease;\n }\n\n :host([compact][mobile-open]) .menu-row,\n :host([compact][mobile-open]) .utility-row {\n flex-direction: column;\n align-items: stretch;\n gap: 1.5rem;\n margin-left: 0;\n }\n\n :host([compact][mobile-open]) .utility-row {\n padding: 1.5rem 0 0;\n border-left: 0;\n border-top: 1px solid var(--st-color-border);\n }\n\n :host([compact][mobile-open]) ::slotted([slot='menu']),\n :host([compact][mobile-open]) ::slotted([slot='utility']) {\n flex-direction: column !important;\n align-items: stretch !important;\n margin: 0 !important;\n }\n\n @media (prefers-reduced-motion: reduce) {\n :host,\n .mobile-panel {\n animation: none !important;\n transition: none !important;\n }\n }\n `;\n\n @property({ type: String })\n title = '';\n\n /** Optional logo image URL, shown before `title`. Omitted entirely when empty — none of this suite's apps has one today. Matches the source component's `imageSrc` (renamed here to pair with `title`/`logoHref`, since this component's only image use is the brand mark). */\n @property({ type: String, attribute: 'brand-image-url' })\n brandImageUrl = '';\n\n /** `alt` text for the brand image — matches the source component's `altText` (default `'Logo'`). */\n @property({ type: String, attribute: 'alt-text' })\n altText = 'Logo';\n\n /** Wraps the brand in an `<a>` when set (e.g. `/`); a plain non-link `<div>` otherwise. */\n @property({ type: String })\n logoHref = '';\n\n /** `target` for the brand `<a>` — matches the source component's `logoTarget` (default `_self`). No effect when `logoHref` isn't set. */\n @property({ type: String, attribute: 'logo-target' })\n logoTarget = '_self';\n\n /** Extra class(es) appended to the brand link/div — matches the source component's `logoClassName`. */\n @property({ type: String, attribute: 'logo-class-name' })\n logoClassName = '';\n\n /** Inverts the header's color roles (light-on-dark instead of dark-on-light) — matches the\n * source component's `inverted` (from its shared `BaseProps`). */\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n @property({ type: Boolean, reflect: true })\n sticky = false;\n\n /**\n * Fixes the header over the top of the page and makes it see-through, with light text\n * (`--st-header-transparent-color`), until the page scrolls past `scroll-threshold` — for a\n * header laid over a dark hero. It then takes its normal background and a shadow. The page\n * content starts under it, so the first section should leave room for the 64px bar.\n */\n @property({ type: Boolean, reflect: true })\n transparent = false;\n\n /** Slides the header out of view while the page scrolls down and back in when it scrolls up. */\n @property({ type: Boolean, reflect: true, attribute: 'hide-on-scroll' })\n hideOnScroll = false;\n\n /** Scroll distance in px after which the header counts as `scrolled`. */\n @property({ type: Number, attribute: 'scroll-threshold' })\n scrollThreshold = 8;\n\n /** True once the page has scrolled past `scroll-threshold`; reflected so pages can style `st-header[scrolled]`. Set by the header, never from outside. */\n @property({ type: Boolean, reflect: true })\n scrolled = false;\n\n /** True while `hide-on-scroll` has slid the header away. Set by the header, never from outside. */\n @property({ type: Boolean, reflect: true, attribute: 'scroll-hidden' })\n scrollHidden = false;\n\n private lastScrollY = 0;\n private scrollFrame = 0;\n\n private onScroll = (): void => {\n if (this.scrollFrame) return;\n this.scrollFrame = requestAnimationFrame(() => {\n this.scrollFrame = 0;\n const y = Math.max(0, window.scrollY);\n this.scrolled = y > this.scrollThreshold;\n if (this.hideOnScroll) {\n const delta = y - this.lastScrollY;\n // Ignore tiny jitters; never hide while still at the top of the page or with the menu open.\n if (Math.abs(delta) > 4) this.scrollHidden = delta > 0 && y > this.offsetHeight && !this.mobileOpen;\n } else {\n this.scrollHidden = false;\n }\n this.lastScrollY = y;\n });\n };\n\n /**\n * Language switcher options, e.g. `[{ code: 'en', label: 'English' }, ...]` — hidden entirely\n * when empty or when only one language is offered (same convention as `st-app-header`'s\n * `languages`, which this reuses verbatim). This component has no translation logic itself —\n * selecting an option fires `language-change` (detail: `{ code }`), and the consuming app owns\n * what `code` actually means and which content it re-renders.\n */\n @property({ attribute: false })\n languages: { code: string; label: string }[] = [];\n\n @property({ type: String, attribute: 'current-language-code' })\n currentLanguageCode = '';\n\n @property({ type: String, attribute: 'language-menu-label' })\n languageMenuLabel = 'Language';\n\n /** Internal open/closed state for the mobile nav overlay, reflected to an attribute purely so\n * the `:host([mobile-open])` CSS selector above can react to it — not meant to be set from\n * outside. */\n @property({ type: Boolean, reflect: true, attribute: 'mobile-open' })\n mobileOpen = false;\n\n /** True while the menu doesn't fit the bar at the current width: the header then shows the same\n * hamburger layout it uses on a narrow screen. Set by `evaluateFit`, never from outside. */\n @property({ type: Boolean, reflect: true })\n compact = false;\n\n @state() private languageMenuOpen = false;\n\n /** Whether `slot=\"utility\"` has content — an empty utility row (and its divider) is hidden. */\n @state() private hasUtility = false;\n\n /** Whether `slot=\"brand-extra\"` has content — an empty one takes no room beside the brand. */\n @state() private hasBrandExtra = false;\n\n private resizeObserver?: ResizeObserver;\n\n /** Matches below BREAKPOINT_TABLET, where the hamburger layout is always on. */\n private narrowQuery?: MediaQueryList;\n\n /** The dropdowns this header switched to `inline` — only these are switched back, so a caller's\n * own `inline` setting is left alone. */\n private inlinedDropdowns = new Set<HTMLElement & { inline: boolean; open: boolean }>();\n\n /** While the hamburger layout is on, the dropdowns in the header open in the flow of the\n * full-screen panel instead of floating over it (SankhyaUI's touch-device layout). */\n private syncInlineDropdowns = (): void => {\n const collapsed = this.compact || !!this.narrowQuery?.matches;\n const dropdowns = Array.from(this.querySelectorAll('st-dropdown')) as (HTMLElement & { inline: boolean; open: boolean })[];\n if (collapsed) {\n for (const dropdown of dropdowns) {\n if (dropdown.inline) continue;\n dropdown.inline = true;\n this.inlinedDropdowns.add(dropdown);\n }\n } else {\n for (const dropdown of this.inlinedDropdowns) dropdown.inline = false;\n this.inlinedDropdowns.clear();\n }\n };\n\n private onBrandExtraSlotChange = (event: Event): void => {\n this.hasBrandExtra = (event.target as HTMLSlotElement).assignedElements({ flatten: true }).length > 0;\n this.evaluateFit();\n };\n\n private onUtilitySlotChange = (event: Event): void => {\n this.hasUtility = (event.target as HTMLSlotElement).assignedElements({ flatten: true }).length > 0;\n this.evaluateFit();\n };\n\n private onMenuSlotChange = (): void => {\n this.evaluateFit();\n this.syncInlineDropdowns();\n };\n\n protected updated(changed: Map<string, unknown>): void {\n if (changed.has('compact')) this.syncInlineDropdowns();\n // A mega dropdown's drill-down panel would otherwise still cover the menu next time it opens.\n if (changed.has('mobileOpen') && !this.mobileOpen) {\n for (const dropdown of this.inlinedDropdowns) dropdown.open = false;\n }\n }\n\n /** The bar width at which the menu last overflowed — the bar only expands again once it is\n * clearly wider than this, so it can't flip back and forth right at the threshold. */\n private collapsedAtWidth = 0;\n\n /** Collapses to the hamburger layout when the slotted menu overflows its row, and expands again\n * once there is room. The collapsed layout hides the menu, so the room it needs can't be\n * measured then; the width remembered when it collapsed stands in for it. */\n private evaluateFit = (): void => {\n const width = this.clientWidth;\n if (this.compact) {\n if (width > this.collapsedAtWidth + 24) {\n this.compact = false;\n this.mobileOpen = false;\n void this.updateComplete.then(this.evaluateFit);\n }\n return;\n }\n if (this.menuOverflows()) {\n this.collapsedAtWidth = width;\n this.compact = true;\n }\n };\n\n /** Whether the visible menu items reach past the right edge of the menu row. Measured from the\n * items' own boxes (the slotted elements and their direct children), not the row's scrollWidth:\n * a closed dropdown's absolutely positioned panel also counts towards scrollWidth, which would\n * report overflow at any width. */\n private menuOverflows(): boolean {\n const row = this.renderRoot.querySelector<HTMLElement>('.menu-row');\n const slot = this.renderRoot.querySelector<HTMLSlotElement>('slot[name=\"menu\"]');\n if (!row || !slot) return false;\n const limit = row.getBoundingClientRect().right + 1;\n let right = 0;\n for (const el of slot.assignedElements({ flatten: true })) {\n for (const box of [el, ...Array.from(el.children)]) {\n const rect = box.getBoundingClientRect();\n if (rect.width > 0) right = Math.max(right, rect.right);\n }\n }\n return right > limit;\n }\n\n protected firstUpdated(): void {\n this.resizeObserver = new ResizeObserver(this.evaluateFit);\n this.resizeObserver.observe(this);\n this.evaluateFit();\n this.syncInlineDropdowns();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n window.addEventListener('keydown', this.closeOnEscape);\n window.addEventListener('click', this.closeLanguageMenuOnOutsideClick);\n window.addEventListener('scroll', this.onScroll, { passive: true });\n this.onScroll();\n this.narrowQuery = window.matchMedia(`(max-width: ${BREAKPOINT_TABLET}px)`);\n this.narrowQuery.addEventListener('change', this.syncInlineDropdowns);\n // Menus often render their dropdowns after the header (e.g. once the user's role loads),\n // deeper than a slotchange reports.\n this.lightDomObserver = new MutationObserver(this.syncInlineDropdowns);\n this.lightDomObserver.observe(this, { childList: true, subtree: true });\n }\n\n private lightDomObserver?: MutationObserver;\n\n disconnectedCallback(): void {\n this.lightDomObserver?.disconnect();\n this.narrowQuery?.removeEventListener('change', this.syncInlineDropdowns);\n this.resizeObserver?.disconnect();\n window.removeEventListener('keydown', this.closeOnEscape);\n window.removeEventListener('click', this.closeLanguageMenuOnOutsideClick);\n window.removeEventListener('scroll', this.onScroll);\n if (this.scrollFrame) cancelAnimationFrame(this.scrollFrame);\n this.scrollFrame = 0;\n super.disconnectedCallback();\n }\n\n private closeOnEscape = (event: KeyboardEvent): void => {\n if (this.mobileOpen && event.key === 'Escape') this.mobileOpen = false;\n if (this.languageMenuOpen && event.key === 'Escape') this.languageMenuOpen = false;\n };\n\n private closeLanguageMenuOnOutsideClick = (event: Event): void => {\n if (this.languageMenuOpen && !event.composedPath().includes(this)) this.languageMenuOpen = false;\n };\n\n private renderLanguageMenu() {\n if (this.languages.length < 2) return nothing;\n const current = this.languages.find((lang) => lang.code === this.currentLanguageCode);\n return html`\n <div class=\"lang-menu\" part=\"language-menu\">\n <button\n part=\"language-menu-trigger\"\n type=\"button\"\n class=\"lang-trigger\"\n aria-label=${this.languageMenuLabel}\n aria-expanded=${this.languageMenuOpen}\n @click=${(event: Event) => {\n event.stopPropagation();\n this.languageMenuOpen = !this.languageMenuOpen;\n }}\n >\n <span part=\"language-menu-current\">${current?.label ?? this.languageMenuLabel}</span>\n ${chevronIcon('down', 10)}\n </button>\n ${this.languageMenuOpen\n ? html`\n <div part=\"language-dropdown\" class=\"lang-dropdown\">\n ${this.languages.map(\n (lang) => html`\n <button\n part=\"language-option\"\n type=\"button\"\n class=\"lang-option ${lang.code === this.currentLanguageCode ? 'active' : ''}\"\n aria-current=${lang.code === this.currentLanguageCode}\n @click=${() => this.onLanguageSelect(lang.code)}\n >\n ${lang.label}\n </button>\n `\n )}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n private onLanguageSelect(code: string): void {\n this.languageMenuOpen = false;\n if (code === this.currentLanguageCode) return;\n this.dispatchEvent(new CustomEvent<LanguageChangedEventDetail>('language-change', { detail: { code }, bubbles: true, composed: true }));\n }\n\n private renderBrand() {\n const content = html`\n ${this.brandImageUrl ? html`<img part=\"brand-mark\" class=\"brand-mark\" src=${this.brandImageUrl} alt=${this.altText} /> ` : nothing}\n <span part=\"brand-title\" class=\"brand-title\">${this.title}</span>\n `;\n return this.logoHref\n ? html`<a part=\"brand\" class=\"brand ${this.logoClassName}\" href=${this.logoHref} target=${this.logoTarget}>${content}</a>`\n : html`<div part=\"brand\" class=\"brand ${this.logoClassName}\">${content}</div>`;\n }\n\n render() {\n return html`\n ${this.renderBrand()}\n <div class=\"brand-extra ${this.hasBrandExtra ? '' : 'empty'}\" part=\"brand-extra\"><slot name=\"brand-extra\" @slotchange=${this.onBrandExtraSlotChange}></slot></div>\n\n <div class=\"mobile-panel\" part=\"mobile-panel\" @click=${() => (this.mobileOpen = false)}>\n <div class=\"menu-row\" part=\"menu-row\"><slot name=\"menu\" @slotchange=${this.onMenuSlotChange}></slot></div>\n <div class=\"utility-row ${this.hasUtility || this.languages.length >= 2 ? '' : 'empty'}\" part=\"utility-row\">\n ${this.renderLanguageMenu()}<slot name=\"utility\" @slotchange=${this.onUtilitySlotChange}></slot>\n </div>\n </div>\n\n <button\n part=\"toggle\"\n type=\"button\"\n class=\"toggle\"\n aria-label=${this.mobileOpen ? 'Close menu' : 'Open menu'}\n aria-expanded=${this.mobileOpen}\n @click=${() => (this.mobileOpen = !this.mobileOpen)}\n >\n <slot name=\"menu-icon\" ?hidden=${this.mobileOpen}>${menuIcon()}</slot>\n <slot name=\"close-icon\" ?hidden=${!this.mobileOpen}>${closeIcon()}</slot>\n </button>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  buttonResetStyles,
3
3
  controlBaseStyles,
4
4
  rootFontFamilyStyles
5
- } from "./chunk-RHAOQ6K4.js";
5
+ } from "./chunk-KMU6ABQF.js";
6
6
  import {
7
7
  __decorateClass
8
8
  } from "./chunk-EUXUH3YW.js";
@@ -67,4 +67,4 @@ IconButton = __decorateClass([
67
67
  export {
68
68
  IconButton
69
69
  };
70
- //# sourceMappingURL=chunk-XXPBFHWR.js.map
70
+ //# sourceMappingURL=chunk-YQ42EBK5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/icon-button/IconButton.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { buttonResetStyles, controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\n\n/**\n * A small, icon-only action button — ported from `SankhyaUI`'s React `IconButton` (a separate,\n * unrelated marketing-site project; that source takes an iconify string `icon` prop, this package\n * has no iconify dependency, so the icon is default-slotted content instead, same convention as\n * `st-dropdown`/`st-menu-grid-item`'s `slot=\"icon\"`).\n *\n * Fires a plain native `click` — no custom event, since a caller just wants an ordinary button.\n */\n@customElement('st-icon-button')\nexport class IconButton extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: inline-flex;\n ${rootFontFamilyStyles}\n }\n\n button {\n ${buttonResetStyles}\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--st-size-32);\n height: var(--st-size-32);\n border-radius: var(--st-radius-sm);\n color: var(--st-color-text-muted);\n }\n\n button:hover {\n background: var(--st-color-hover);\n color: var(--st-color-text-strong);\n }\n\n :host([disabled]) button {\n color: var(--st-color-text-muted);\n cursor: not-allowed;\n pointer-events: none;\n }\n `;\n\n /** Accessible name and tooltip — matches the source component's `ariaLabel` (renamed: modern\n * browsers already expose a native `ariaLabel` reflected property on every `Element`, so reusing\n * that exact name as a Lit reactive property would shadow it). Required for a control with no\n * visible text. */\n @property({ type: String })\n label = '';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n render() {\n return html`\n <button part=\"button\" type=\"button\" aria-label=${this.label} title=${this.label} ?disabled=${this.disabled}>\n <slot></slot>\n </button>\n `;\n }\n}\n"],"mappings":";;;;;;;;;;AAAA,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AAajC,IAAM,aAAN,cAAyB,WAAW;AAAA,EAApC;AAAA;AAqCL,iBAAQ;AAGR,oBAAW;AAAA;AAAA,EAEX,SAAS;AACP,WAAO;AAAA,uDAC4C,KAAK,KAAK,UAAU,KAAK,KAAK,cAAc,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,EAI9G;AACF;AAjDa,WACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIf,oBAAoB;AAAA;AAAA;AAAA;AAAA,QAIpB,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BvB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GApCf,WAqCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAvC/B,WAwCX;AAxCW,aAAN;AAAA,EADN,cAAc,gBAAgB;AAAA,GAClB;","names":[]}