@sankhyatronics/sankhya-cms 0.1.7 → 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.
- package/LICENSE +21 -21
- package/README.md +34 -34
- package/custom-elements.json +717 -643
- package/dist/bento-grid/index.js +3 -3
- package/dist/card/index.js +2 -2
- package/dist/carousel/index.js +3 -3
- package/dist/{chunk-3JU3R22O.js → chunk-5EBWMPJS.js} +2 -2
- package/dist/chunk-5EBWMPJS.js.map +1 -0
- package/dist/{chunk-2JGWWXEI.js → chunk-76AVBQUA.js} +3 -3
- package/dist/chunk-76AVBQUA.js.map +1 -0
- package/dist/{chunk-NN3OCPDV.js → chunk-7NLZND6Q.js} +3 -3
- package/dist/{chunk-EMVHNAID.js → chunk-ALI26WOB.js} +3 -3
- package/dist/chunk-ALI26WOB.js.map +1 -0
- package/dist/{chunk-TLHG33MM.js → chunk-BLQV2YMO.js} +3 -3
- package/dist/chunk-BLQV2YMO.js.map +1 -0
- package/dist/{chunk-UVNBZD7R.js → chunk-BMHMNXIA.js} +3 -3
- package/dist/chunk-BMHMNXIA.js.map +1 -0
- package/dist/{chunk-ZRXYWH6C.js → chunk-DH53HZPB.js} +4 -4
- package/dist/{chunk-HPIQSECE.js → chunk-EMCQBT3S.js} +3 -3
- package/dist/{chunk-BQTDFQ4V.js → chunk-FLY7TNRT.js} +3 -3
- package/dist/chunk-FLY7TNRT.js.map +1 -0
- package/dist/{chunk-3VE6VFJ4.js → chunk-FZ36KL73.js} +1 -1
- package/dist/chunk-FZ36KL73.js.map +1 -0
- package/dist/{chunk-HGTC3LCW.js → chunk-G3CF7MBO.js} +3 -3
- package/dist/{chunk-CDC4P77V.js → chunk-GJO3RGOB.js} +2 -2
- package/dist/chunk-GJO3RGOB.js.map +1 -0
- package/dist/{chunk-K4ZICRZL.js → chunk-JKBWZLG4.js} +3 -3
- package/dist/chunk-JKBWZLG4.js.map +1 -0
- package/dist/{chunk-4HKSA5UT.js → chunk-JQY2G4QK.js} +2 -2
- package/dist/chunk-JQY2G4QK.js.map +1 -0
- package/dist/{chunk-RHAOQ6K4.js → chunk-KMU6ABQF.js} +1 -1
- package/dist/chunk-KMU6ABQF.js.map +1 -0
- package/dist/{chunk-IQPW3CYZ.js → chunk-LEXZKGQX.js} +3 -3
- package/dist/chunk-LEXZKGQX.js.map +1 -0
- package/dist/{chunk-MW43OS47.js → chunk-MSSH3HFK.js} +2 -2
- package/dist/chunk-MSSH3HFK.js.map +1 -0
- package/dist/{chunk-DQHMJZ6X.js → chunk-R5G6KFTJ.js} +18 -8
- package/dist/chunk-R5G6KFTJ.js.map +1 -0
- package/dist/{chunk-VYON56QO.js → chunk-SMLR736E.js} +2 -2
- package/dist/chunk-SMLR736E.js.map +1 -0
- package/dist/{chunk-HGJT24UG.js → chunk-VWS53WY4.js} +3 -3
- package/dist/chunk-VWS53WY4.js.map +1 -0
- package/dist/{chunk-VRRBMOUP.js → chunk-WT4OATGP.js} +3 -3
- package/dist/chunk-WT4OATGP.js.map +1 -0
- package/dist/{chunk-PB7ZPPLP.js → chunk-WTD2YIAA.js} +1 -1
- package/dist/chunk-WTD2YIAA.js.map +1 -0
- package/dist/{chunk-5KHI36M5.js → chunk-XWB4CKDU.js} +44 -4
- package/dist/chunk-XWB4CKDU.js.map +1 -0
- package/dist/{chunk-XXPBFHWR.js → chunk-YQ42EBK5.js} +2 -2
- package/dist/chunk-YQ42EBK5.js.map +1 -0
- package/dist/{chunk-6H262SG6.js → chunk-YVTFQHVY.js} +2 -2
- package/dist/chunk-YVTFQHVY.js.map +1 -0
- package/dist/{chunk-7PSYCTEN.js → chunk-ZN4LIKVG.js} +2 -2
- package/dist/chunk-ZN4LIKVG.js.map +1 -0
- package/dist/cms-theme.css +26 -26
- package/dist/content-block/index.js +4 -4
- package/dist/cookie-consent/index.js +2 -2
- package/dist/dropdown/index.js +3 -3
- package/dist/feature-split/index.js +4 -4
- package/dist/features-section/index.js +5 -5
- package/dist/footer/index.js +2 -2
- package/dist/header/index.d.ts +13 -0
- package/dist/header/index.js +3 -3
- package/dist/hero/index.js +3 -3
- package/dist/icon-button/index.js +2 -2
- package/dist/index.js +35 -35
- package/dist/items-accordion/index.js +3 -3
- package/dist/markdown/index.js +2 -2
- package/dist/mega-menu/index.js +3 -3
- package/dist/menu-grid/index.js +2 -2
- package/dist/menu-grid-item/index.js +2 -2
- package/dist/menu-item/index.d.ts +5 -0
- package/dist/menu-item/index.js +3 -3
- package/dist/promo-banner/index.js +3 -3
- package/dist/schema/index.js.map +1 -1
- package/dist/section/index.js +3 -3
- package/dist/select/index.js +3 -3
- package/dist/shared/icons.js +1 -1
- package/dist/shared/styles.js +1 -1
- package/dist/stats/index.js +2 -2
- package/dist/testimonials/index.js +4 -4
- package/dist/theme.css +291 -291
- package/dist/themes.css +64 -64
- package/dist/theming/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-2JGWWXEI.js.map +0 -1
- package/dist/chunk-3JU3R22O.js.map +0 -1
- package/dist/chunk-3VE6VFJ4.js.map +0 -1
- package/dist/chunk-4HKSA5UT.js.map +0 -1
- package/dist/chunk-5KHI36M5.js.map +0 -1
- package/dist/chunk-6H262SG6.js.map +0 -1
- package/dist/chunk-7PSYCTEN.js.map +0 -1
- package/dist/chunk-BQTDFQ4V.js.map +0 -1
- package/dist/chunk-CDC4P77V.js.map +0 -1
- package/dist/chunk-DQHMJZ6X.js.map +0 -1
- package/dist/chunk-EMVHNAID.js.map +0 -1
- package/dist/chunk-HGJT24UG.js.map +0 -1
- package/dist/chunk-IQPW3CYZ.js.map +0 -1
- package/dist/chunk-K4ZICRZL.js.map +0 -1
- package/dist/chunk-MW43OS47.js.map +0 -1
- package/dist/chunk-PB7ZPPLP.js.map +0 -1
- package/dist/chunk-RHAOQ6K4.js.map +0 -1
- package/dist/chunk-TLHG33MM.js.map +0 -1
- package/dist/chunk-UVNBZD7R.js.map +0 -1
- package/dist/chunk-VRRBMOUP.js.map +0 -1
- package/dist/chunk-VYON56QO.js.map +0 -1
- package/dist/chunk-XXPBFHWR.js.map +0 -1
- /package/dist/{chunk-NN3OCPDV.js.map → chunk-7NLZND6Q.js.map} +0 -0
- /package/dist/{chunk-ZRXYWH6C.js.map → chunk-DH53HZPB.js.map} +0 -0
- /package/dist/{chunk-HPIQSECE.js.map → chunk-EMCQBT3S.js.map} +0 -0
- /package/dist/{chunk-HGTC3LCW.js.map → chunk-G3CF7MBO.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dropdown/Dropdown.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\r\nimport { customElement, property, state } from 'lit/decorators.js';\r\n\r\nimport { chevronIcon } from '../shared/icons';\r\nimport { buttonResetStyles, controlBaseStyles, fontFamilyStyles } from '../shared/styles';\r\nimport type { DropdownToggleEventDetail } from './DropdownEvents';\r\n\r\n/**\r\n * A labeled trigger + slotted dropdown panel — nav menus (typically holding an `st-menu-grid`),\r\n * action menus, anything \"click a trigger, show content under it\". A 1:1 port of `SankhyaUI`'s\r\n * React `Dropdown` (`SankhyaCMS/SankhyaUI/src/components/Dropdown`): same markup\r\n * (`.menu` > `.menu-title` + `.menu-dropdown`), sizes, 0.3s slide/fade, and behavior —\r\n *\r\n * - only one dropdown is open at a time (the source's `DropdownProvider`, built in here, so no\r\n * provider element is needed);\r\n * - a mousedown outside, Escape, or a click inside the panel closes it;\r\n * - an `href` trigger toggles the panel when it has content, and is a plain link when it doesn't;\r\n * - `inline` opens the panel in the flow, the source's `.touch-device` layout.\r\n *\r\n * Colors and the panel's surface come from the suite theme (the source left those to the\r\n * consumer's `className`/`itemGroupClassName` utility classes). Two source rules are left out\r\n * because they break existing suite uses (`st-source-bar`'s site/library menus): the 100vw panel\r\n * at <=768px (overflows the screen from wherever the trigger sits; the header uses `inline`\r\n * instead) and `overflow: hidden` on slotted children (clips their focus rings). Suite additions\r\n * kept on top: `align`, `active`, `disabled`, `inline`, and the `dropdown-toggle` event — plus\r\n * `mega` and `open-on-hover` for an okta.com-style mega menu (see `st-mega-menu`).\r\n *\r\n * @cssprop --st-mega-menu-max-width - Maximum width of a `mega` panel (default `1400px`).\r\n * @cssprop --st-mega-menu-inset - Minimum space between a `mega` panel and the header's sides (default `1rem`).\r\n * @cssprop --st-mega-menu-gap - Space between the header and a `mega` panel (default `12px`).\r\n * @cssprop --st-mega-menu-radius - Corner radius of a `mega` panel (default `24px`).\r\n */\r\n@customElement('st-dropdown')\r\nexport class Dropdown extends LitElement {\r\n /** The open dropdown, if any — the source's `DropdownContext.activeDropdown`. */\r\n private static openDropdown: Dropdown | null = null;\r\n\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: inline-block;\r\n position: relative;\r\n ${fontFamilyStyles}\r\n }\r\n\r\n .menu-title {\r\n ${buttonResetStyles}\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-sizing: border-box;\r\n min-height: 40px;\r\n padding: 12px;\r\n gap: 8px;\r\n text-align: center;\r\n width: fit-content;\r\n border-radius: var(--st-radius-sm);\r\n /* --st-nav-*: set by a host bar (st-header's transparent state) to recolour its nav items. */\r\n color: var(--st-nav-color, var(--st-color-text));\r\n font-size: 0.875rem;\r\n text-decoration: none;\r\n white-space: nowrap;\r\n transition: background-color 0.3s ease;\r\n }\r\n\r\n .menu-title:hover,\r\n .menu-title[aria-expanded='true'] {\r\n background: var(--st-nav-hover-bg, var(--st-color-hover));\r\n color: var(--st-nav-color, var(--st-color-text-strong));\r\n }\r\n\r\n :host([active]) .menu-title {\r\n background: var(--st-color-accent-subtle);\r\n color: var(--st-color-accent-text);\r\n }\r\n\r\n :host([disabled]) .menu-title {\r\n color: var(--st-color-text-muted);\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n }\r\n\r\n .icon {\r\n display: inline-flex;\r\n flex: none;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n .icon[hidden] {\r\n display: none;\r\n }\r\n\r\n .arrow {\r\n display: inline-block;\r\n margin-left: 8px;\r\n font-size: 0.75rem;\r\n transition: transform 0.3s ease;\r\n }\r\n\r\n .menu-title[aria-expanded='true'] .arrow {\r\n transform: rotate(180deg);\r\n }\r\n\r\n .menu-dropdown {\r\n position: absolute;\r\n top: 100%;\r\n left: 0;\r\n z-index: 100;\r\n padding: 16px;\r\n background: var(--st-color-surface);\r\n color: var(--st-color-text);\r\n /* The panel has its own surface: items in it never take the bar's nav colours. */\r\n --st-nav-color: initial;\r\n --st-nav-hover-bg: initial;\r\n border: 1px solid var(--st-color-border);\r\n border-radius: var(--st-radius-sm);\r\n box-shadow: 0 4px 16px var(--st-shadow-color-sm);\r\n opacity: 0;\r\n visibility: hidden;\r\n transform: translateY(-10px);\r\n /* visibility flips at once on open (so keyboard focus can move into the panel on the same\r\n frame) and only after the 0.3s fade on close. */\r\n transition:\r\n opacity 0.3s ease,\r\n transform 0.3s ease,\r\n visibility 0s linear 0.3s;\r\n pointer-events: none;\r\n }\r\n\r\n .menu-dropdown.align-right {\r\n left: auto;\r\n right: 0;\r\n }\r\n\r\n .menu-dropdown.show {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateY(0);\r\n pointer-events: auto;\r\n transition-delay: 0s;\r\n }\r\n\r\n /* Inline: the panel opens in the flow under its trigger and pushes what follows down, instead\r\n of floating — the source's .touch-device layout. st-header turns this on for its menu while\r\n the hamburger panel is showing. */\r\n :host([inline]) {\r\n display: block;\r\n }\r\n\r\n :host([inline]) .menu-title {\r\n width: 100%;\r\n justify-content: flex-start;\r\n }\r\n\r\n :host([inline]) .arrow {\r\n margin-left: auto;\r\n }\r\n\r\n :host([inline]) .menu-dropdown {\r\n display: none;\r\n position: relative;\r\n top: auto;\r\n left: auto;\r\n right: auto;\r\n width: 100%;\r\n box-sizing: border-box;\r\n box-shadow: none;\r\n opacity: 1;\r\n visibility: visible;\r\n transform: none;\r\n }\r\n\r\n :host([inline]) .menu-dropdown.show {\r\n display: block;\r\n pointer-events: auto;\r\n }\r\n\r\n /* Mega (okta.com): the panel is a large rounded card floating under the whole bar, centred on\r\n the nearest positioned ancestor (st-header) instead of hanging off the trigger — the host\r\n stops being the panel's containing block. */\r\n :host([mega]:not([inline])) {\r\n position: static;\r\n }\r\n\r\n :host([mega]:not([inline])) .menu-dropdown {\r\n top: calc(100% + var(--st-mega-menu-gap, 12px));\r\n left: var(--st-mega-menu-inset, 1rem);\r\n right: var(--st-mega-menu-inset, 1rem);\r\n max-width: var(--st-mega-menu-max-width, 1400px);\r\n margin: 0 auto;\r\n padding: 0;\r\n max-height: calc(100dvh - var(--st-mega-menu-offset, 96px));\r\n overflow-y: auto;\r\n border: 0;\r\n border-radius: var(--st-mega-menu-radius, 24px);\r\n box-shadow: 0 24px 48px var(--st-shadow-color-md);\r\n }\r\n\r\n /* The open section's trigger becomes an accent pill — also for a plain dropdown marked \\`bar\\`,\r\n so it matches the mega triggers (and st-menu-item variant=\"bar\") beside it. */\r\n :host([mega]:not([inline])) .menu-title,\r\n :host([bar]:not([inline])) .menu-title {\r\n border-radius: 9999px;\r\n }\r\n\r\n :host([mega]:not([inline])) .menu-title[aria-expanded='true'],\r\n :host([bar]:not([inline])) .menu-title[aria-expanded='true'] {\r\n background: var(--st-color-accent);\r\n color: var(--st-color-on-solid);\r\n }\r\n\r\n .mega-back-bar,\r\n .mega-heading {\r\n display: none;\r\n }\r\n\r\n /* Mega in st-header's hamburger panel: rather than an accordion, the panel slides in over the\r\n whole screen with a Back button (okta.com's phone menu). Fixed to the viewport, stacked\r\n inside the header's own full-screen layer, so the header's close toggle stays on top. */\r\n :host([mega][inline]) .menu-dropdown {\r\n display: block;\r\n position: fixed;\r\n inset: 0;\r\n z-index: 1;\r\n padding: 0 1.5rem 2rem;\r\n overflow-y: auto;\r\n border: 0;\r\n border-radius: 0;\r\n visibility: hidden;\r\n transform: translateX(100%);\r\n transition:\r\n transform 0.3s ease,\r\n visibility 0s linear 0.3s;\r\n }\r\n\r\n :host([mega][inline]) .menu-dropdown.show {\r\n visibility: visible;\r\n transform: none;\r\n transition-delay: 0s;\r\n }\r\n\r\n :host([mega][inline]) .mega-back-bar {\r\n display: flex;\r\n align-items: center;\r\n position: sticky;\r\n top: 0;\r\n z-index: 1;\r\n height: 64px;\r\n margin: 0 -1.5rem;\r\n padding: 0 1rem;\r\n background: inherit;\r\n border-bottom: 1px solid var(--st-color-border);\r\n }\r\n\r\n .mega-back {\r\n ${buttonResetStyles}\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n height: 40px;\r\n padding: 0 12px 0 6px;\r\n border-radius: var(--st-radius-sm);\r\n font-size: 0.875rem;\r\n font-weight: 600;\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n .mega-back:hover {\r\n background: var(--st-color-hover);\r\n }\r\n\r\n :host([mega][inline]) .mega-heading {\r\n display: block;\r\n margin: 1.25rem 0 0.75rem;\r\n font-size: 1.375rem;\r\n font-weight: 600;\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n /* The drill-down replaces the trigger's open state, so the caret points the way it goes. */\r\n :host([mega][inline]) .arrow {\r\n transform: rotate(-90deg);\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .menu-dropdown,\r\n .arrow,\r\n :host([mega][inline]) .menu-dropdown {\r\n transition: none;\r\n }\r\n }\r\n `;\r\n\r\n /** Trigger label text (source: `title`, renamed because `title` is the native tooltip\r\n * attribute). Leave empty to show only `slot=\"icon\"`. */\r\n @property({ type: String })\r\n label = '';\r\n\r\n /** Renders the trigger as an `<a href>`. With panel content the click toggles the panel (as in\r\n * the source); with none it navigates. */\r\n @property({ type: String })\r\n href = '';\r\n\r\n @property({ type: String, attribute: 'icon-position' })\r\n iconPosition: 'left' | 'right' = 'left';\r\n\r\n /** Inline `width`/`height` of the `slot=\"icon\"` wrapper (source: `iconSize`, default `1.2rem`). */\r\n @property({ type: String, attribute: 'icon-size' })\r\n iconSize = '1.2rem';\r\n\r\n /** Inline `color` of the `slot=\"icon\"` wrapper (source: `iconColor`). */\r\n @property({ type: String, attribute: 'icon-color' })\r\n iconColor = 'currentColor';\r\n\r\n /** Which edge of the trigger the panel lines up with. */\r\n @property({ type: String })\r\n align: 'left' | 'right' = 'left';\r\n\r\n /** `target` of an `href` trigger (source default `_self`). */\r\n @property({ type: String })\r\n target = '_self';\r\n\r\n /** Extra class(es) on the trigger (source: `className`; a `class` on `st-dropdown` styles the host). */\r\n @property({ type: String, attribute: 'trigger-class-name' })\r\n triggerClassName = '';\r\n\r\n /** Extra class(es) on the panel (source: `itemGroupClassName`). */\r\n @property({ type: String, attribute: 'item-group-class-name' })\r\n itemGroupClassName = '';\r\n\r\n /** Unused, as in the source (`itemClassName` is never read there); kept for prop parity. */\r\n @property({ type: String, attribute: 'item-class-name' })\r\n itemClassName = '';\r\n\r\n @property({ type: Boolean, reflect: true })\r\n disabled = false;\r\n\r\n /** Highlights the trigger as the current section (e.g. the current page is one of its items). */\r\n @property({ type: Boolean, reflect: true })\r\n active = false;\r\n\r\n /** Opens the panel in the flow under the trigger instead of floating over the page (see the\r\n * styles). `st-header` sets this on its own menu's dropdowns while its hamburger panel shows. */\r\n @property({ type: Boolean, reflect: true })\r\n inline = false;\r\n\r\n /** Whether the panel is showing. Follows user toggles; may also be set from outside. */\r\n @property({ type: Boolean, reflect: true })\r\n open = false;\r\n\r\n /**\r\n * Mega-menu panel (okta.com style), typically holding an `st-mega-menu`: the panel spans the\r\n * full width of the nearest positioned ancestor — `st-header` — right under it, instead of\r\n * hanging off the trigger. In `st-header`'s hamburger layout (`inline`) it slides in over the\r\n * screen with a Back button rather than opening as an accordion. A click inside the panel only\r\n * closes it when it lands on a link.\r\n */\r\n @property({ type: Boolean, reflect: true })\r\n mega = false;\r\n\r\n /** Styles a non-`mega` trigger like a mega one — a pill that turns solid accent while open — so\r\n * a plain dropdown (e.g. \"+ New\") lines up with mega triggers in the same header bar. */\r\n @property({ type: Boolean, reflect: true })\r\n bar = false;\r\n\r\n /** Opens the panel while a mouse hovers the trigger or panel (touch and keyboard still click). Off while `inline`. */\r\n @property({ type: Boolean, attribute: 'open-on-hover' })\r\n openOnHover = false;\r\n\r\n /** Text of the Back button in the `mega` + `inline` drill-down panel. */\r\n @property({ type: String, attribute: 'back-label' })\r\n backLabel = 'Back';\r\n\r\n private hoverTimer = 0;\r\n\r\n /** When hover last opened the panel — a click right after that keeps it open instead of toggling it shut. */\r\n private hoverOpenedAt = 0;\r\n\r\n /** Whether the default slot has content — the source's `children` check. */\r\n @state() private hasContent = false;\r\n\r\n /** Whether `slot=\"icon\"` has content. */\r\n @state() private hasIcon = false;\r\n\r\n connectedCallback(): void {\r\n super.connectedCallback();\r\n document.addEventListener('mousedown', this.closeOnOutsideMouseDown);\r\n window.addEventListener('keydown', this.closeOnEscape);\r\n this.addEventListener('pointerenter', this.onPointerEnter);\r\n this.addEventListener('pointerleave', this.onPointerLeave);\r\n }\r\n\r\n disconnectedCallback(): void {\r\n document.removeEventListener('mousedown', this.closeOnOutsideMouseDown);\r\n window.removeEventListener('keydown', this.closeOnEscape);\r\n this.removeEventListener('pointerenter', this.onPointerEnter);\r\n this.removeEventListener('pointerleave', this.onPointerLeave);\r\n clearTimeout(this.hoverTimer);\r\n if (Dropdown.openDropdown === this) Dropdown.openDropdown = null;\r\n super.disconnectedCallback();\r\n }\r\n\r\n protected updated(changed: Map<string, unknown>): void {\r\n if (!changed.has('open')) return;\r\n if (this.open) {\r\n const previous = Dropdown.openDropdown;\r\n Dropdown.openDropdown = this;\r\n if (previous && previous !== this) previous.setOpen(false);\r\n } else if (Dropdown.openDropdown === this) {\r\n Dropdown.openDropdown = null;\r\n }\r\n }\r\n\r\n private setOpen(open: boolean): void {\r\n if (this.open === open) return;\r\n this.open = open;\r\n this.dispatchEvent(new CustomEvent<DropdownToggleEventDetail>('dropdown-toggle', { detail: { open }, bubbles: true, composed: true }));\r\n }\r\n\r\n private hovers(event: PointerEvent): boolean {\r\n return this.openOnHover && !this.inline && !this.disabled && this.hasContent && event.pointerType === 'mouse';\r\n }\r\n\r\n /** Short delays so a pointer crossing the gap between trigger and panel doesn't close it. */\r\n private onPointerEnter = (event: PointerEvent): void => {\r\n if (!this.hovers(event)) return;\r\n clearTimeout(this.hoverTimer);\r\n this.hoverTimer = window.setTimeout(() => {\r\n if (!this.open) this.hoverOpenedAt = Date.now();\r\n this.setOpen(true);\r\n }, 80);\r\n };\r\n\r\n private onPointerLeave = (event: PointerEvent): void => {\r\n if (!this.hovers(event)) return;\r\n clearTimeout(this.hoverTimer);\r\n this.hoverTimer = window.setTimeout(() => this.setOpen(false), 200);\r\n };\r\n\r\n private onBackClick = (event: Event): void => {\r\n event.stopPropagation();\r\n this.setOpen(false);\r\n this.trigger()?.focus();\r\n };\r\n\r\n private closeOnOutsideMouseDown = (event: Event): void => {\r\n if (this.open && !event.composedPath().includes(this)) this.setOpen(false);\r\n };\r\n\r\n private closeOnEscape = (event: KeyboardEvent): void => {\r\n if (!this.open || event.key !== 'Escape') return;\r\n const focusWasInside = event.composedPath().includes(this);\r\n this.setOpen(false);\r\n if (focusWasInside) this.trigger()?.focus();\r\n };\r\n\r\n private trigger(): HTMLElement | null {\r\n return this.renderRoot.querySelector<HTMLElement>('.menu-title');\r\n }\r\n\r\n /** Keyboard-reachable entries in the panel, in order: menu items (they delegate focus to their\r\n * own link) plus any plain links/buttons/tabbable elements a caller slots in. */\r\n private panelItems(): HTMLElement[] {\r\n const slot = this.renderRoot.querySelector<HTMLSlotElement>('.menu-dropdown slot');\r\n if (!slot) return [];\r\n const selector =\r\n 'st-menu-item, st-menu-grid-item, st-mega-menu-feature, a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\r\n const items: HTMLElement[] = [];\r\n for (const el of slot.assignedElements({ flatten: true })) {\r\n if (el.matches(selector)) items.push(el as HTMLElement);\r\n items.push(...Array.from(el.querySelectorAll<HTMLElement>(selector)));\r\n }\r\n return items;\r\n }\r\n\r\n /** Moves focus into the panel once it has become visible (it is `visibility: hidden` until the\r\n * `show` class lands, and hidden elements can't take focus). */\r\n private focusItem(pick: (items: HTMLElement[]) => HTMLElement | undefined): void {\r\n void this.updateComplete.then(() => pick(this.panelItems())?.focus());\r\n }\r\n\r\n /** Enter/Space/ArrowDown open the panel and focus its first entry; ArrowUp its last. */\r\n private onTitleKeyDown = (event: KeyboardEvent): void => {\r\n if (!this.hasContent || this.disabled) return;\r\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.setOpen(true);\r\n this.focusItem((items) => items[0]);\r\n } else if (event.key === 'ArrowUp') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.setOpen(true);\r\n this.focusItem((items) => items[items.length - 1]);\r\n }\r\n };\r\n\r\n /** Arrow keys/Home/End move between the panel's entries; Tab closes the panel and moves on. */\r\n private onPanelKeyDown = (event: KeyboardEvent): void => {\r\n if (event.key === 'Tab') {\r\n this.setOpen(false);\r\n return;\r\n }\r\n if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return;\r\n const items = this.panelItems();\r\n if (items.length === 0) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n const path = event.composedPath();\r\n const current = items.findIndex((item) => path.includes(item));\r\n const last = items.length - 1;\r\n const next =\r\n event.key === 'Home'\r\n ? 0\r\n : event.key === 'End'\r\n ? last\r\n : event.key === 'ArrowDown'\r\n ? current < 0 || current === last ? 0 : current + 1\r\n : current <= 0 ? last : current - 1;\r\n items[next].focus();\r\n };\r\n\r\n private onTitleClick = (event: Event): void => {\r\n event.stopPropagation();\r\n if (!this.hasContent) return;\r\n event.preventDefault();\r\n clearTimeout(this.hoverTimer);\r\n if (this.open && Date.now() - this.hoverOpenedAt < 400) return;\r\n this.setOpen(!this.open);\r\n };\r\n\r\n /** A click anywhere inside the panel closes it, as in the source — for `mega`, only a click on a\r\n * link: a big panel has headings and gaps, and a click there shouldn't also close st-header's\r\n * hamburger layer. */\r\n private onPanelClick = (event: Event): void => {\r\n if (this.mega && !event.composedPath().some((node) => node instanceof HTMLAnchorElement)) {\r\n event.stopPropagation();\r\n return;\r\n }\r\n this.setOpen(false);\r\n };\r\n\r\n private onContentSlotChange = (event: Event): void => {\r\n this.hasContent = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).some(\r\n (node) => node.nodeType === Node.ELEMENT_NODE || !!node.textContent?.trim()\r\n );\r\n };\r\n\r\n private onIconSlotChange = (event: Event): void => {\r\n this.hasIcon = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;\r\n };\r\n\r\n render() {\r\n const icon = html`<span\r\n class=\"icon ${this.iconPosition === 'left' ? 'icon-left' : 'icon-right'}\"\r\n ?hidden=${!this.hasIcon}\r\n style=\"width:${this.iconSize};height:${this.iconSize};color:${this.iconColor}\"\r\n ><slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot\r\n ></span>`;\r\n const titleContent = html`\r\n ${this.iconPosition === 'left' ? icon : nothing} ${this.label ? html`<span part=\"label\">${this.label}</span>` : nothing}\r\n ${this.iconPosition === 'right' ? icon : nothing}\r\n ${this.hasContent ? html`<span class=\"arrow\" part=\"caret\" aria-hidden=\"true\">▼</span>` : nothing}\r\n `;\r\n const titleClass = `menu-title ${this.triggerClassName} ${this.open ? 'active' : ''}`;\r\n\r\n return html`\r\n <div class=\"menu\" part=\"menu\">\r\n ${this.href\r\n ? html`\r\n <a\r\n part=\"trigger\"\r\n class=${titleClass}\r\n href=${this.href}\r\n target=${this.target}\r\n aria-haspopup=${this.hasContent ? 'true' : 'false'}\r\n aria-expanded=${this.open}\r\n aria-disabled=${this.disabled ? 'true' : nothing}\r\n @click=${this.onTitleClick}\r\n @keydown=${this.onTitleKeyDown}\r\n >\r\n ${titleContent}\r\n </a>\r\n `\r\n : html`\r\n <button\r\n part=\"trigger\"\r\n class=${titleClass}\r\n type=\"button\"\r\n aria-haspopup=\"true\"\r\n aria-expanded=${this.open}\r\n ?disabled=${this.disabled}\r\n @click=${this.onTitleClick}\r\n @keydown=${this.onTitleKeyDown}\r\n >\r\n ${titleContent}\r\n </button>\r\n `}\r\n <div\r\n part=\"panel\"\r\n class=\"menu-dropdown align-${this.align} ${this.itemGroupClassName} ${this.open ? 'show' : ''}\"\r\n role=\"menu\"\r\n @click=${this.onPanelClick}\r\n @keydown=${this.onPanelKeyDown}\r\n >\r\n ${this.mega\r\n ? html`\r\n <div class=\"mega-back-bar\" part=\"back-bar\">\r\n <button type=\"button\" class=\"mega-back\" part=\"back\" @click=${this.onBackClick}>\r\n ${chevronIcon('left', 16)} ${this.backLabel}\r\n </button>\r\n </div>\r\n ${this.label ? html`<p class=\"mega-heading\" part=\"mobile-heading\">${this.label}</p>` : nothing}\r\n `\r\n : nothing}\r\n <slot @slotchange=${this.onContentSlotChange}></slot>\r\n </div>\r\n </div>\r\n `;\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hero/Hero.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\n\r\nimport { controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\r\nimport { ctaLinkStyles, paddingScaleStyles } from '../shared/section-styles';\r\nimport type { HeroActionEventDetail } from './HeroEvents';\r\n\r\n/**\r\n * Full-width hero banner: background image with a darkening overlay, optional eyebrow, title,\r\n * optional subtitle and up to two call-to-action links. Port of `SankhyaUI`'s React `Hero`; the\r\n * framer-motion entrance is redone as CSS keyframes (skipped under `prefers-reduced-motion`).\r\n *\r\n * `size`, `content-position` and `overlay=\"gradient\"` give the large editorial layout (copy on the\r\n * lower left over a gradient that darkens towards it) used by enterprise marketing heroes; the\r\n * defaults keep the original centered banner. Put several heroes in an `st-carousel` with\r\n * `indicator-style=\"tabs\"` for a tabbed hero carousel.\r\n *\r\n * @fires action - Cancelable, before navigating. Detail `{ href, kind }`, `kind` being `primary` or `secondary`.\r\n * @cssprop --st-hero-text-color - Text colour over the image.\r\n * @cssprop --st-hero-min-height - Minimum height when `size` is `large` (default `640px`).\r\n * @csspart eyebrow - The small label above the title.\r\n * @csspart secondary-action - The outlined second button.\r\n */\r\n@customElement('st-hero')\r\nexport class Hero extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n ${paddingScaleStyles}\r\n\r\n @keyframes st-hero-zoom {\r\n from { opacity: 0; transform: scale(1.1); }\r\n to { opacity: 1; transform: scale(1); }\r\n }\r\n @keyframes st-hero-rise {\r\n from { opacity: 0; transform: translateY(30px); }\r\n to { opacity: 1; transform: none; }\r\n }\r\n @keyframes st-hero-fade {\r\n from { opacity: 0; }\r\n to { opacity: 1; }\r\n }\r\n\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n position: relative;\r\n overflow: hidden;\r\n width: 100%;\r\n box-sizing: border-box;\r\n background-color: var(--st-color-text-strong);\r\n background-repeat: no-repeat;\r\n background-size: cover;\r\n background-position: var(--st-hero-position, center center);\r\n color: var(--st-color-on-solid);\r\n ${rootFontFamilyStyles}\r\n animation: st-hero-zoom 1.5s ease-out;\r\n }\r\n\r\n :host([inverted]) {\r\n background-color: var(--st-color-surface);\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n .overlay {\r\n position: absolute;\r\n inset: 0;\r\n z-index: 1;\r\n background: linear-gradient(\r\n to bottom,\r\n color-mix(in oklch, var(--st-color-text-strong) 40%, transparent),\r\n color-mix(in oklch, var(--st-color-text-strong) 20%, transparent),\r\n color-mix(in oklch, var(--st-color-text-strong) 40%, transparent)\r\n );\r\n }\r\n\r\n :host([inverted]) .overlay {\r\n display: none;\r\n }\r\n\r\n .content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: var(--st-space-20);\r\n position: relative;\r\n z-index: 2;\r\n width: 80%;\r\n margin: 0 auto;\r\n text-align: center;\r\n align-items: center;\r\n /* Set here, not only on :host: text sits on the image/overlay, so a colour class the page puts\r\n on the host (e.g. a theme text colour) must not turn it dark. */\r\n color: var(--st-hero-text-color, var(--st-color-on-solid));\r\n }\r\n\r\n :host([inverted]) .content {\r\n color: var(--st-hero-text-color, var(--st-color-text-strong));\r\n }\r\n\r\n :host([text-alignment='left']) .content { text-align: left; align-items: flex-start; }\r\n :host([text-alignment='right']) .content { text-align: right; align-items: flex-end; }\r\n :host([text-alignment='justify']) .content { text-align: justify; align-items: stretch; }\r\n\r\n .title {\r\n font-size: var(--st-cms-text-display);\r\n font-weight: var(--st-font-weight-bold);\r\n line-height: 1.1;\r\n color: inherit;\r\n margin: 0;\r\n animation: st-hero-rise 0.8s 0.3s ease-out backwards;\r\n }\r\n\r\n .subtitle {\r\n font-size: var(--st-cms-text-xl);\r\n line-height: 1.5;\r\n color: inherit;\r\n margin: 0;\r\n animation: st-hero-fade 0.8s 0.5s ease-out backwards;\r\n }\r\n\r\n .actions {\r\n display: flex;\r\n justify-content: center;\r\n width: 100%;\r\n }\r\n\r\n .cta {\r\n ${ctaLinkStyles}\r\n background: var(--st-button-primary-bg);\r\n color: var(--st-button-primary-color);\r\n font-weight: var(--st-button-font-weight);\r\n font-size: var(--st-text-md);\r\n animation: st-hero-rise 0.6s 0.7s ease-out backwards;\r\n }\r\n\r\n .cta:hover {\r\n transform: scale(1.05);\r\n }\r\n\r\n .cta:active {\r\n transform: scale(0.98);\r\n }\r\n\r\n .eyebrow {\r\n margin: 0;\r\n font-size: var(--st-text-sm);\r\n font-weight: var(--st-font-weight-bold);\r\n letter-spacing: 0.12em;\r\n text-transform: uppercase;\r\n color: inherit;\r\n opacity: 0.85;\r\n animation: st-hero-fade 0.8s 0.2s ease-out backwards;\r\n }\r\n\r\n .actions {\r\n flex-wrap: wrap;\r\n gap: var(--st-space-12);\r\n }\r\n\r\n .cta.secondary {\r\n background: transparent;\r\n color: inherit;\r\n box-shadow: inset 0 0 0 1.5px currentColor;\r\n }\r\n\r\n .cta.secondary:hover {\r\n background: color-mix(in oklch, currentColor 12%, transparent);\r\n }\r\n\r\n /* size=\"large\" / \"full\": a tall editorial hero. */\r\n :host([size='large']) {\r\n min-height: var(--st-hero-min-height, 640px);\r\n }\r\n\r\n :host([size='full']) {\r\n min-height: 100svh;\r\n }\r\n\r\n :host([size='large']) .title,\r\n :host([size='full']) .title {\r\n font-size: clamp(2.5rem, 6vw, 5rem);\r\n letter-spacing: -0.02em;\r\n line-height: 1.05;\r\n }\r\n\r\n /* content-position=\"bottom\": copy sits in the lower part of the hero, on the container grid. */\r\n :host([content-position='bottom']) {\r\n align-items: flex-end;\r\n }\r\n\r\n :host([content-position='bottom']) .content {\r\n width: 100%;\r\n max-width: var(--st-cms-container-max);\r\n box-sizing: border-box;\r\n padding: var(--st-space-48) var(--st-space-24);\r\n }\r\n\r\n :host([content-position='bottom']) .title,\r\n :host([content-position='bottom']) .subtitle {\r\n max-width: 18ch;\r\n }\r\n\r\n :host([content-position='bottom']) .subtitle {\r\n max-width: 48ch;\r\n }\r\n\r\n :host([content-position='bottom']:not([text-alignment='center']):not([text-alignment='right'])) .actions {\r\n justify-content: flex-start;\r\n }\r\n\r\n :host([content-position='bottom'][text-alignment='center']) .title,\r\n :host([content-position='bottom'][text-alignment='center']) .subtitle {\r\n margin-inline: auto;\r\n }\r\n\r\n /* overlay=\"gradient\": darkest behind the copy, clearing towards the far side of the image. */\r\n :host([overlay='gradient']) .overlay {\r\n background:\r\n linear-gradient(to top, color-mix(in oklch, var(--st-color-text-strong) 85%, transparent), transparent 70%),\r\n linear-gradient(to right, color-mix(in oklch, var(--st-color-text-strong) 70%, transparent), transparent 75%);\r\n }\r\n\r\n :host([overlay='gradient'][text-alignment='right']) .overlay {\r\n background:\r\n linear-gradient(to top, color-mix(in oklch, var(--st-color-text-strong) 85%, transparent), transparent 70%),\r\n linear-gradient(to left, color-mix(in oklch, var(--st-color-text-strong) 70%, transparent), transparent 75%);\r\n }\r\n\r\n :host([overlay='none']) .overlay {\r\n display: none;\r\n }\r\n\r\n @media (min-width: 768px) {\r\n .content { padding: var(--st-space-32); }\r\n }\r\n @media (min-width: 1024px) {\r\n .content { padding: var(--st-space-48); }\r\n :host([content-position='bottom']) .content { padding: var(--st-space-48) var(--st-space-32) 6rem; }\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n :host, .eyebrow, .title, .subtitle, .cta { animation: none; }\r\n .cta { transition: none; }\r\n }\r\n `;\r\n\r\n @property({ type: String })\r\n title = '';\r\n\r\n @property({ type: String })\r\n subtitle = '';\r\n\r\n @property({ type: String, attribute: 'image-src' })\r\n imageSrc = '';\r\n\r\n @property({ type: String, attribute: 'action-label' })\r\n actionLabel = '';\r\n\r\n @property({ type: String })\r\n href = '';\r\n\r\n @property({ type: String, reflect: true, attribute: 'text-alignment' })\r\n textAlignment: 'left' | 'center' | 'right' | 'justify' = 'left';\r\n\r\n @property({ type: String, reflect: true })\r\n padding: 'none' | 'small' | 'medium' | 'large' = 'none';\r\n\r\n @property({ type: Boolean, reflect: true })\r\n inverted = false;\r\n\r\n @property({ type: String, attribute: 'focal-point' })\r\n focalPoint: 'top' | 'left' | 'right' | 'bottom' | 'center' = 'center';\r\n\r\n /** Small uppercase label above the title (e.g. an event or product name). */\r\n @property({ type: String })\r\n eyebrow = '';\r\n\r\n /** Label of an outlined second button next to the primary one. */\r\n @property({ type: String, attribute: 'secondary-action-label' })\r\n secondaryActionLabel = '';\r\n\r\n @property({ type: String, attribute: 'secondary-href' })\r\n secondaryHref = '';\r\n\r\n /** `auto` sizes to the content; `large` is a tall editorial hero (`--st-hero-min-height`); `full` fills the viewport. */\r\n @property({ type: String, reflect: true })\r\n size: 'auto' | 'large' | 'full' = 'auto';\r\n\r\n /** `center` keeps the copy in the middle; `bottom` puts it in the lower part of the hero, on the page container. */\r\n @property({ type: String, reflect: true, attribute: 'content-position' })\r\n contentPosition: 'center' | 'bottom' = 'center';\r\n\r\n /** `even` darkens the whole image; `gradient` darkens behind the copy only; `none` shows the image as is. */\r\n @property({ type: String, reflect: true })\r\n overlay: 'even' | 'gradient' | 'none' = 'even';\r\n\r\n private static positions = {\r\n top: 'center top',\r\n left: 'left center',\r\n right: 'right center',\r\n bottom: 'center bottom',\r\n center: 'center center'\r\n } as const;\r\n\r\n protected willUpdate(): void {\r\n this.style.backgroundImage = this.imageSrc ? `url(${JSON.stringify(this.imageSrc)})` : '';\r\n this.style.setProperty('--st-hero-position', Hero.positions[this.focalPoint] ?? Hero.positions.center);\r\n }\r\n\r\n private emitAction(event: MouseEvent, href: string, kind: 'primary' | 'secondary'): void {\r\n const action = new CustomEvent<HeroActionEventDetail>('action', {\r\n detail: { href, kind },\r\n bubbles: true,\r\n composed: true,\r\n cancelable: true\r\n });\r\n this.dispatchEvent(action);\r\n if (action.defaultPrevented) event.preventDefault();\r\n }\r\n\r\n private onClick = (event: MouseEvent): void => this.emitAction(event, this.href, 'primary');\r\n\r\n private onSecondaryClick = (event: MouseEvent): void => this.emitAction(event, this.secondaryHref, 'secondary');\r\n\r\n render() {\r\n return html`\r\n <div class=\"overlay\" part=\"overlay\"></div>\r\n <div class=\"content\" part=\"content\">\r\n ${this.eyebrow ? html`<p class=\"eyebrow\" part=\"eyebrow\">${this.eyebrow}</p>` : nothing}\r\n <h1 class=\"title\" part=\"title\">${this.title}</h1>\r\n ${this.subtitle ? html`<p class=\"subtitle\" part=\"subtitle\">${this.subtitle}</p>` : nothing}\r\n ${this.actionLabel || this.secondaryActionLabel\r\n ? html`<div class=\"actions\" part=\"actions\">\r\n ${this.actionLabel\r\n ? html`<a class=\"cta\" part=\"action\" href=${this.href || nothing} @click=${this.onClick}>${this.actionLabel}</a>`\r\n : nothing}\r\n ${this.secondaryActionLabel\r\n ? html`<a class=\"cta secondary\" part=\"secondary-action\" href=${this.secondaryHref || nothing} @click=${this.onSecondaryClick}\r\n >${this.secondaryActionLabel}</a\r\n >`\r\n : nothing}\r\n </div>`\r\n : nothing}\r\n <slot></slot>\r\n </div>\r\n `;\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cookie-consent/CookieConsent.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\r\nimport { customElement, property, state } from 'lit/decorators.js';\r\n\r\nimport { buttonResetStyles, controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\r\nimport type { CookieConsentEventDetail, CookieConsentStatus } from './CookieConsentEvents';\r\n\r\nconst DEFAULT_STORAGE_KEY = 'sankhya_ui_cookie_consent';\r\n\r\n/**\r\n * Fixed bottom consent bar. The source read/wrote consent through a React `UserContext`; here the\r\n * element persists the choice itself in localStorage (`storage-key`, default the source's\r\n * `sankhya_ui_cookie_consent`; storage errors are ignored) and renders nothing once a choice\r\n * exists. Fires `cookie-consent-accept` / `cookie-consent-refuse` (detail `{ status }`). The\r\n * default slot replaces the message text.\r\n *\r\n * @cssprop --st-cookie-consent-padding - Overrides the bar's padding.\r\n */\r\n@customElement('st-cookie-consent')\r\nexport class CookieConsent extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n @keyframes st-cookie-slide-up {\r\n from {\r\n transform: translateY(100%);\r\n }\r\n to {\r\n transform: translateY(0);\r\n }\r\n }\r\n\r\n :host {\r\n position: fixed;\r\n bottom: 0;\r\n left: 0;\r\n width: 100%;\r\n box-sizing: border-box;\r\n z-index: 9999;\r\n display: flex;\r\n flex-direction: column;\r\n gap: var(--st-space-16);\r\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\r\n padding; override with --st-cookie-consent-padding instead. */\r\n padding: var(--st-cookie-consent-padding, var(--st-space-24)) !important;\r\n background: var(--st-color-surface);\r\n color: var(--st-color-text);\r\n border-top: 1px solid var(--st-color-border);\r\n box-shadow: 0 -4px 10px var(--st-shadow-color-sm);\r\n animation: st-cookie-slide-up 0.3s ease-out;\r\n ${rootFontFamilyStyles}\r\n }\r\n\r\n .content {\r\n flex: 1;\r\n }\r\n\r\n .message {\r\n margin: 0;\r\n font-size: var(--st-text-md);\r\n line-height: 1.5;\r\n }\r\n\r\n .link {\r\n color: var(--st-color-accent-text);\r\n text-decoration: underline;\r\n margin-left: var(--st-space-4);\r\n }\r\n\r\n .link:hover {\r\n text-decoration: none;\r\n }\r\n\r\n .actions {\r\n display: flex;\r\n gap: var(--st-space-12);\r\n flex-shrink: 0;\r\n }\r\n\r\n .btn {\r\n ${buttonResetStyles}\r\n padding: var(--st-space-8) var(--st-space-16);\r\n border: 1px solid transparent;\r\n border-radius: var(--st-radius-xs);\r\n font-weight: var(--st-font-weight-medium);\r\n font-size: var(--st-text-md);\r\n transition:\r\n background-color 0.2s ease,\r\n color 0.2s ease;\r\n }\r\n\r\n .accept {\r\n background: var(--st-button-primary-bg);\r\n color: var(--st-button-primary-color);\r\n }\r\n\r\n .accept:hover {\r\n opacity: 0.9;\r\n }\r\n\r\n .refuse {\r\n border-color: var(--st-color-border);\r\n color: var(--st-color-text-muted);\r\n }\r\n\r\n .refuse:hover {\r\n background: var(--st-color-hover);\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n @media (min-width: 768px) {\r\n :host {\r\n flex-direction: row;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: var(--st-cookie-consent-padding, var(--st-space-16) var(--st-space-32)) !important;\r\n }\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n :host {\r\n animation: none;\r\n }\r\n .btn {\r\n transition: none;\r\n }\r\n }\r\n `;\r\n\r\n @property({ type: String })\r\n message = '';\r\n\r\n @property({ type: String, attribute: 'accept-button-text' })\r\n acceptButtonText = 'Accept';\r\n\r\n @property({ type: String, attribute: 'refuse-button-text' })\r\n refuseButtonText = 'Refuse';\r\n\r\n @property({ type: String, attribute: 'privacy-policy-link' })\r\n privacyPolicyLink = '';\r\n\r\n @property({ type: String, attribute: 'privacy-policy-text' })\r\n privacyPolicyText = 'Privacy Policy';\r\n\r\n @property({ type: String, attribute: 'storage-key' })\r\n storageKey = DEFAULT_STORAGE_KEY;\r\n\r\n /** The stored choice, or `null` while undecided (the bar is only shown then). */\r\n @state() private consent: CookieConsentStatus | null = null;\r\n\r\n connectedCallback(): void {\r\n super.connectedCallback();\r\n this.consent = this.readStored();\r\n }\r\n\r\n private readStored(): CookieConsentStatus | null {\r\n try {\r\n const saved = localStorage.getItem(this.storageKey);\r\n return saved === 'accepted' || saved === 'refused' ? saved : null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n private choose(status: CookieConsentStatus): void {\r\n this.consent = status;\r\n try {\r\n localStorage.setItem(this.storageKey, status);\r\n } catch {\r\n // Storage unavailable (private mode, blocked): the choice just doesn't persist.\r\n }\r\n this.dispatchEvent(\r\n new CustomEvent<CookieConsentEventDetail>(status === 'accepted' ? 'cookie-consent-accept' : 'cookie-consent-refuse', {\r\n detail: { status },\r\n bubbles: true,\r\n composed: true\r\n })\r\n );\r\n }\r\n\r\n render() {\r\n if (this.consent !== null) return nothing;\r\n return html`\r\n <div class=\"content\" part=\"content\">\r\n <p class=\"message\" part=\"message\">\r\n <slot>\r\n ${this.message || 'We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.'}\r\n ${this.privacyPolicyLink\r\n ? html`<a class=\"link\" part=\"link\" href=${this.privacyPolicyLink} target=\"_blank\" rel=\"noopener noreferrer\">${this.privacyPolicyText}</a>`\r\n : nothing}\r\n </slot>\r\n </p>\r\n </div>\r\n <div class=\"actions\" part=\"actions\">\r\n <button class=\"btn refuse\" part=\"refuse\" type=\"button\" @click=${() => this.choose('refused')}>${this.refuseButtonText}</button>\r\n <button class=\"btn accept\" part=\"accept\" type=\"button\" @click=${() => this.choose('accepted')}>${this.acceptButtonText}</button>\r\n </div>\r\n `;\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/icons.ts"],"sourcesContent":["import { html } from 'lit';\r\nimport type { TemplateResult } from 'lit';\r\n\r\n/**\r\n * Every inline SVG icon used across components, centralized so a glyph's\r\n * path data lives in exactly one place instead of being copy-pasted at each\r\n * call site. Each icon is a small function returning a Lit `TemplateResult`\r\n * (not a `css`-style fragment) so callers can size — and, where noted, class\r\n * — the icon per context while sharing the same markup.\r\n */\r\n\r\nconst FOLDER_ICON_COLOR = 'oklch(0.72 0.09 75)';\r\n\r\n/** Filled folder glyph (browse rows/tiles). Fixed 20x16 — folders don't resize per usage. */\r\nexport function folderIcon(): TemplateResult {\r\n return html`\r\n <svg width=\"20\" height=\"16\" viewBox=\"0 0 20 16\" fill=\"none\" aria-hidden=\"true\">\r\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} />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Outlined folder glyph (breadcrumb crumb icon). `className` lets the caller hook its own layout class. */\r\nexport function folderOutlineIcon(size = 11, className = ''): TemplateResult {\r\n return html`\r\n <svg class=${className} width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M4 4h5l2 2h9v12H4V4z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** External-link/\"open\" glyph (open site/library actions in the Templates/Data/Save-location pickers). */\r\nexport function externalLinkIcon(size = 15): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\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\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.8\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Refresh/reload glyph (Templates/Data picker refresh buttons). */\r\nexport function refreshIcon(size = 15): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\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\"\r\n fill=\"currentColor\"\r\n />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Clock glyph (the wizard's \"Recent activity\" history trigger button, Steps 1-3). */\r\nexport function historyIcon(size = 15): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M12 7v5l3.5 2\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Trash/delete glyph (clear-all button in the selected-chips summary badge). */\r\nexport function trashIcon(size = 15): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\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\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <circle cx=\"10\" cy=\"21\" r=\"1.4\" fill=\"currentColor\" />\r\n <circle cx=\"17\" cy=\"21\" r=\"1.4\" fill=\"currentColor\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Chevron glyph (pager prev/next buttons, the select trigger's caret). */\r\nexport function chevronIcon(direction: 'left' | 'right' | 'down', size = 14): TemplateResult {\r\n const d = { left: 'M15 18l-6-6 6-6', right: 'M9 6l6 6-6 6', down: 'M6 9l6 6 6-6' }[direction];\r\n\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=${d} stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Up-right arrow glyph (marks a link that leaves the site — mega-menu links and buttons). */\r\nexport function arrowUpRightIcon(size = 12): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M7 17L17 7M8 7h9v9\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Plus glyph (\"New folder\" action button). */\r\nexport function plusIcon(size = 13): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M12 4v16M4 12h16\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Cards-view glyph (2x2 grid — view-toggle button). */\r\nexport function cardsViewIcon(size = 15): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\r\n <rect x=\"1\" y=\"1\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\r\n <rect x=\"9\" y=\"1\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\r\n <rect x=\"1\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\r\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Checkmark glyph (completed-step marker in the step indicator). */\r\nexport function checkIcon(size = 14): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M4 12l5 5L20 6\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** SharePoint site glyph (globe — root \"All sites\" browser rows). */\r\nexport function siteIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"1.6\" />\r\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\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** 3x3 dot-grid glyph (bento-menu app-switcher trigger). */\r\nexport function bentoGridIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\r\n <path\r\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\"\r\n />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** List-view glyph (stacked rows — view-toggle button). */\r\nexport function listViewIcon(size = 15): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\r\n <rect x=\"1\" y=\"2\" width=\"3\" height=\"3\" rx=\"0.5\" fill=\"currentColor\" />\r\n <rect x=\"6\" y=\"2.5\" width=\"9\" height=\"2\" rx=\"1\" fill=\"currentColor\" />\r\n <rect x=\"1\" y=\"6.5\" width=\"3\" height=\"3\" rx=\"0.5\" fill=\"currentColor\" />\r\n <rect x=\"6\" y=\"7\" width=\"9\" height=\"2\" rx=\"1\" fill=\"currentColor\" />\r\n <rect x=\"1\" y=\"11\" width=\"3\" height=\"3\" rx=\"0.5\" fill=\"currentColor\" />\r\n <rect x=\"6\" y=\"11.5\" width=\"9\" height=\"2\" rx=\"1\" fill=\"currentColor\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/**\r\n * A small set of generic domain icons for `st-menu-grid-item`'s icon slot (nav \"mega menu\"\r\n * entries — sales/purchase/accounting/settings items) — deliberately simple line glyphs rather\r\n * than pixel-perfect illustrations, same fidelity level as the icons above.\r\n */\r\n\r\n/** Shopping-cart glyph (sales/orders). */\r\nexport function cartIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M3 4h2l2.4 12.4A2 2 0 0 0 9.36 18h8.2a2 2 0 0 0 1.96-1.6L21 8H6\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <circle cx=\"10\" cy=\"21\" r=\"1.4\" fill=\"currentColor\" />\r\n <circle cx=\"17\" cy=\"21\" r=\"1.4\" fill=\"currentColor\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Delivery-truck glyph (purchase orders / receiving). */\r\nexport function truckIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M2 6h11v10H2z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\r\n <path d=\"M13 10h4l4 3.5V16h-8z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\r\n <circle cx=\"6.5\" cy=\"18\" r=\"1.8\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <circle cx=\"16.5\" cy=\"18\" r=\"1.8\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Package/box glyph (products, inventory). */\r\nexport function boxIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M12 3l8 4.2v9.6L12 21l-8-4.2V7.2L12 3z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path d=\"M4.2 7.2L12 11l7.8-3.8M12 11v10\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Map-pin glyph (stock locations). */\r\nexport function mapPinIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M12 21s7-6.1 7-11.5A7 7 0 0 0 5 9.5C5 14.9 12 21 12 21z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <circle cx=\"12\" cy=\"9.5\" r=\"2.4\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Two-person glyph (partners — customers/vendors/employees). */\r\nexport function usersIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <circle cx=\"9\" cy=\"8\" r=\"3.2\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M3 20c0-3.3 2.7-6 6-6s6 2.7 6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n <path\r\n d=\"M16 5.3a3.2 3.2 0 0 1 0 6.2M19 20c0-2.8-2-5.1-4.6-5.8\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Open-book glyph (journals). */\r\nexport function bookIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\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\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.8\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Document/invoice glyph. */\r\nexport function documentIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M6 2h9l5 5v15H6V2z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\r\n <path d=\"M15 2v5h5\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\r\n <path d=\"M9 12h6M9 16h6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Receipt glyph, zig-zag bottom edge (credit/debit notes). */\r\nexport function receiptIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M5 2h14v19l-2.5-1.6L14 21l-2.5-1.6L9 21l-2.5-1.6L5 21V2z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path d=\"M8 8h8M8 12h8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Percent glyph (taxes). */\r\nexport function percentIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M19 5L5 19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n <circle cx=\"7\" cy=\"7\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <circle cx=\"17\" cy=\"17\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Stacked-coins glyph (payment terms). */\r\nexport function coinsIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <ellipse cx=\"8\" cy=\"7\" rx=\"5.5\" ry=\"3\" stroke=\"currentColor\" stroke-width=\"2\" />\r\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\" />\r\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\" />\r\n <ellipse cx=\"16.5\" cy=\"12\" rx=\"5\" ry=\"2.7\" stroke=\"currentColor\" stroke-width=\"2\" />\r\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\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Padlock glyph (fiscal year closing / lock dates). */\r\nexport function lockIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <rect x=\"4\" y=\"11\" width=\"16\" height=\"10\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n <circle cx=\"12\" cy=\"16\" r=\"1.6\" fill=\"currentColor\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/**\r\n * Office file-type glyphs, ported from `PennyIcons` in `@sankhyatronics/sankhya-icons`\r\n * (FileWordIcon/FileExcelIcon/FilePowerPointIcon) — this package is Lit, so it can't import\r\n * the React components and carries the same path data instead. Filled, `currentColor`.\r\n */\r\nconst FILE_TYPE_ICON_PATHS = {\r\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',\r\n excel:\r\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',\r\n powerpoint:\r\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'\r\n} as const;\r\n\r\n/** Word/Excel/PowerPoint file glyph (the document icon in front of template/file rows). */\r\nexport function fileTypeIcon(type: keyof typeof FILE_TYPE_ICON_PATHS, size = 24): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\r\n <path d=${FILE_TYPE_ICON_PATHS[type]} />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Hamburger glyph (`st-header`'s mobile nav toggle, closed state). */\r\nexport function menuIcon(size = 20): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M4 6h16M4 12h16M4 18h16\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** X/close glyph (`st-header`'s mobile nav toggle, open state). */\r\nexport function closeIcon(size = 20): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M5 5l14 14M19 5L5 19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Gear/cog glyph (company settings). */\r\nexport function gearIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path\r\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\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n `;\r\n}\r\n\r\n/** Paint-palette glyph (theme/color-scheme switcher). */\r\nexport function paletteIcon(size = 18): TemplateResult {\r\n return html`\r\n <svg width=${size} height=${size} viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\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\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.6\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <circle cx=\"7.5\" cy=\"10.5\" r=\"1.2\" fill=\"currentColor\" />\r\n <circle cx=\"11\" cy=\"7\" r=\"1.2\" fill=\"currentColor\" />\r\n <circle cx=\"15.5\" cy=\"7.5\" r=\"1.2\" fill=\"currentColor\" />\r\n <circle cx=\"17.5\" cy=\"11.5\" r=\"1.2\" fill=\"currentColor\" />\r\n </svg>\r\n `;\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/styles.ts"],"sourcesContent":["import { css } from 'lit';\r\n\r\n/**\r\n * Reusable `css` fragments shared across component `static styles` blocks.\r\n *\r\n * Lit's `css` tag allows interpolating another `CSSResult` anywhere inside a\r\n * template, including mid-rule — `${fragment}` below expands to raw CSS\r\n * text, so these compose into a component's own selectors without forcing a\r\n * shared class name or touching `render()`. Each component keeps its own\r\n * selectors; only the duplicated property lists move here. Layout details\r\n * that genuinely vary per component (padding, gap, font-size, ...) stay\r\n * local, declared after a fragment so the cascade lets them override it.\r\n *\r\n * Add a fragment here only once a pattern is byte-identical (or near enough\r\n * that the deltas are better expressed as local overrides) across 3+\r\n * components — see `packages/suite-components/README.md#shared-style-fragments`.\r\n */\r\n\r\n/** Truncates overflowing text to a single line with an ellipsis. */\r\nexport const truncateStyles = css`\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n`;\r\n\r\n/**\r\n * Base for an unstyled, click-through interactive element (icon buttons,\r\n * menu triggers, link-like buttons) before component-specific padding,\r\n * font-size, and color are layered on.\r\n */\r\nexport const buttonResetStyles = css`\r\n border: 0;\r\n background: transparent;\r\n font: inherit;\r\n cursor: pointer;\r\n`;\r\n\r\n/**\r\n * The dark-filled primary-action button look (wizard Next/Generate/Run/Save,\r\n * active toggle buttons, ...). Pair with `ctaButtonDisabledStyles` on the\r\n * same selector's `:disabled` state.\r\n */\r\nexport const ctaButtonStyles = css`\r\n border: 0;\r\n border-radius: var(--st-button-radius);\r\n background: var(--st-button-primary-bg);\r\n color: var(--st-button-primary-color);\r\n font-weight: var(--st-button-font-weight);\r\n cursor: pointer;\r\n`;\r\n\r\nexport const ctaButtonDisabledStyles = css`\r\n background: var(--st-color-subtle);\r\n cursor: not-allowed;\r\n`;\r\n\r\n/**\r\n * Just the fill (background + color) from `ctaButtonStyles`, for selectors\r\n * that only need to swap an already-bordered/sized button into the CTA look\r\n * on an active/pressed/selected state (`[aria-pressed='true']`, `.active`,\r\n * ...) rather than defining the button from scratch.\r\n */\r\nexport const ctaButtonFillStyles = css`\r\n background: var(--st-button-primary-bg);\r\n color: var(--st-button-primary-color);\r\n`;\r\n\r\n/** Floating menu/dropdown panel chrome (user menu, language menu, ...). */\r\nexport const dropdownPanelStyles = css`\r\n position: absolute;\r\n top: 38px;\r\n right: 0;\r\n background: var(--st-color-surface);\r\n border: 1px solid var(--st-color-border);\r\n border-radius: var(--st-radius-sm);\r\n box-shadow: 0 4px 16px var(--st-shadow-color-sm);\r\n z-index: 30;\r\n overflow: hidden;\r\n`;\r\n\r\n/** \"No results\" / \"Nothing here.\" empty-state text. Padding stays local. */\r\nexport const emptyStateStyles = css`\r\n text-align: center;\r\n color: var(--st-color-text-muted);\r\n font-size: var(--st-text-base);\r\n`;\r\n\r\n/** Bordered, rounded shell wrapping a data table (browse/list views). */\r\nexport const tableShellStyles = css`\r\n background: var(--st-color-surface);\r\n border: 1px solid var(--st-color-border);\r\n border-radius: var(--st-radius-md);\r\n overflow: hidden;\r\n`;\r\n\r\n/** A single bordered result row with a name (truncated) + trailing link. */\r\nexport const resultRowStyles = css`\r\n display: flex;\r\n align-items: center;\r\n gap: var(--st-space-12);\r\n padding: var(--st-space-12) var(--st-space-14);\r\n border: 1px solid var(--st-color-border);\r\n border-radius: var(--st-radius-sm);\r\n`;\r\n\r\nexport const resultNameStyles = css`\r\n flex: 1;\r\n min-width: 120px;\r\n font-size: var(--st-text-base);\r\n font-weight: var(--st-font-weight-medium);\r\n ${truncateStyles}\r\n`;\r\n\r\nexport const resultLinkStyles = css`\r\n font-size: var(--st-text-sm);\r\n font-weight: var(--st-font-weight-semibold);\r\n color: var(--st-color-accent-text);\r\n`;\r\n\r\n/**\r\n * Uppercase, letter-spaced section/field \"eyebrow\" label (card headings,\r\n * table headers, field labels, ...). Font-size stays local since it varies\r\n * (11–12px) by context.\r\n */\r\nexport const eyebrowLabelStyles = css`\r\n font-weight: var(--st-font-weight-bold);\r\n color: var(--st-color-text-muted);\r\n text-transform: uppercase;\r\n letter-spacing: var(--st-tracking-wide);\r\n`;\r\n\r\n/** Top border separating stacked rows in a list/table (folder rows, data rows, table rows, ...). */\r\nexport const rowDividerStyles = css`\r\n border-top: 1px solid var(--st-color-divider);\r\n`;\r\n\r\n/**\r\n * Bordered, rounded surface shell for a card/tile/panel (as opposed to\r\n * `tableShellStyles`, which additionally clips overflow for tabular content).\r\n * Padding, gap, and cursor stay local since they vary by component.\r\n */\r\nexport const cardShellStyles = css`\r\n background: var(--st-color-surface);\r\n border: 1px solid var(--st-color-border);\r\n border-radius: var(--st-radius-md);\r\n`;\r\n\r\n/** A card/tile/row's bold primary name line (folder tiles/rows, template cards, ...). */\r\nexport const itemNameStyles = css`\r\n font-size: var(--st-text-base);\r\n font-weight: var(--st-font-weight-semibold);\r\n color: var(--st-color-text-strong);\r\n`;\r\n\r\n/** A card/tile/row's muted secondary caption line, paired with `itemNameStyles`. */\r\nexport const itemCaptionStyles = css`\r\n font-size: var(--st-text-xs);\r\n color: var(--st-color-text-muted);\r\n`;\r\n\r\n/**\r\n * Whole rules (not a property list) every component's stylesheet starts\r\n * with: routes keyboard focus rings and native checkbox/radio tint through\r\n * `--st-focus-ring` / `--st-checkbox-color`, whose defaults (`auto`) keep\r\n * the browser's own look until a host app themes them.\r\n */\r\nexport const controlBaseStyles = css`\r\n :is(button, a, input, select, textarea, [tabindex]):focus-visible {\r\n outline: var(--st-focus-ring);\r\n outline-offset: var(--st-focus-ring-offset);\r\n }\r\n\r\n input[type='checkbox'],\r\n input[type='radio'] {\r\n accent-color: var(--st-checkbox-color);\r\n }\r\n`;\r\n\r\n/** Default font stack, used by nearly every component. */\r\nexport const fontFamilyStyles = css`\r\n font-family: var(--st-font-family);\r\n`;\r\n\r\n/**\r\n * Font stack for page-root/chrome components (`st-template-hub`, the admin\r\n * and configuration pages, `st-app-header`, ...). Identical to\r\n * `fontFamilyStyles` now that `--st-font-family` always resolves via\r\n * `theme.css` (no per-usage fallback) — kept as a separate export so those\r\n * call sites stay semantically distinct if the two ever need to diverge\r\n * again.\r\n */\r\nexport const rootFontFamilyStyles = css`\r\n font-family: var(--st-font-family);\r\n`;\r\n\r\n/** Canonical responsive breakpoints (px). Interpolate as `${BREAKPOINT_TABLET}px`. */\r\nexport const BREAKPOINT_TABLET = 900;\r\nexport const BREAKPOINT_MOBILE = 500;\r\n"],"mappings":";AAAA,SAAS,WAAW;AAmBb,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAWvB,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAY1B,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASxB,IAAM,0BAA0B;AAAA;AAAA;AAAA;AAWhC,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAM5B,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAa5B,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAOzB,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAQzB,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASxB,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,IAK5B,cAAc;AAAA;AAGX,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAWzB,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ3B,IAAM,mBAAmB;AAAA;AAAA;AASzB,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAOxB,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAOvB,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAW1B,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAa1B,IAAM,mBAAmB;AAAA;AAAA;AAYzB,IAAM,uBAAuB;AAAA;AAAA;AAK7B,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/select/Select.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\r\nimport type { PropertyValues } from 'lit';\r\nimport { customElement, property, query } from 'lit/decorators.js';\r\n\r\nimport { chevronIcon, externalLinkIcon } from '../shared/icons';\r\nimport { controlBaseStyles, eyebrowLabelStyles, fontFamilyStyles } from '../shared/styles';\r\nimport type { SelectOption } from './SelectEvents';\r\nimport type { SelectChangedEventDetail } from './SelectEvents';\r\n\r\nlet instanceCounter = 0;\r\n\r\n/**\r\n * A fully custom-styled replacement for native `<select>`, used everywhere\r\n * the wizard needs a single-choice dropdown (template source, list, document\r\n * library, admin roles, ...).\r\n *\r\n * Built on the CSS Customizable Select API (`appearance: base-select`) —\r\n * still a real `<select>`/`<option>` element tree, so focus, keyboard\r\n * (arrows/Home/End/typeahead), and ARIA all come from the browser for free,\r\n * but the trigger (`<button>`/`<selectedcontent>`) and popup\r\n * (`::picker(select)`) are fully styleable instead of OS-rendered. Chromium\r\n * only for now (Firefox/Safari fall back to an unstyled native `<select>` —\r\n * the extra `<button>`/`<selectedcontent>` markup is simply not rendered by\r\n * browsers that don't support the parsing/CSS additions, so the control\r\n * still works there, just without the custom look).\r\n *\r\n * `options` intentionally has no \"unselected\" placeholder entry — set\r\n * `value=\"\"` (or any value with no matching option) and it falls back to\r\n * showing `placeholder` in the trigger instead, letting callers swap the\r\n * placeholder text dynamically (e.g. \"Select a list\" vs \"Select a list\r\n * first\") without needing a synthetic option in the list. Internally this is\r\n * a real hidden/disabled `<option value=\"\">`, since a native `<select>`\r\n * always has *some* option selected.\r\n *\r\n * Fires `select-change` (detail: `{ value }`) only when the value actually\r\n * changes, matching native `<select>`'s `change` event semantics.\r\n *\r\n * `link-href` optionally renders an external-link button in front of\r\n * `field-label` — the same glyph/placement as the \"open library\" links\r\n * placed next to the Templates/Save-location breadcrumbs — for callers that\r\n * want a one-click way to open whatever the current selection points at\r\n * (e.g. the SharePoint site or library) in a new tab.\r\n */\r\n@customElement('st-select')\r\nexport class Select extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: inline-flex;\r\n flex-direction: column;\r\n gap: var(--st-space-4);\r\n min-width: 0;\r\n ${fontFamilyStyles}\r\n }\r\n\r\n .field-label-row {\r\n display: flex;\r\n align-items: center;\r\n gap: var(--st-space-6);\r\n min-width: 0;\r\n }\r\n\r\n .field-label {\r\n font-size: var(--st-text-xs);\r\n ${eyebrowLabelStyles}\r\n }\r\n\r\n .field-label-link {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex: none;\r\n color: var(--st-color-text-faint);\r\n }\r\n\r\n .field-label-link:hover {\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n select {\r\n appearance: base-select;\r\n width: 100%;\r\n min-width: 0;\r\n border: 0;\r\n padding: 0;\r\n background: transparent;\r\n font: inherit;\r\n color: inherit;\r\n }\r\n\r\n select::picker(select) {\r\n appearance: base-select;\r\n margin-top: var(--st-space-4);\r\n background: var(--st-color-surface);\r\n border: 1px solid var(--st-color-border);\r\n border-radius: var(--st-radius-sm);\r\n box-shadow: 0 4px 16px var(--st-shadow-color-sm);\r\n padding: var(--st-space-4) 0;\r\n }\r\n\r\n .trigger {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: var(--st-space-8);\r\n width: 100%;\r\n padding: var(--st-space-8) var(--st-space-10);\r\n border-radius: var(--st-radius-sm);\r\n border: 1px solid var(--st-color-border);\r\n background: var(--st-color-surface);\r\n color: var(--st-color-text-strong);\r\n font: inherit;\r\n font-size: var(--st-text-base);\r\n box-sizing: border-box;\r\n text-align: left;\r\n cursor: pointer;\r\n }\r\n\r\n .trigger:hover,\r\n .trigger:focus-visible {\r\n background: var(--st-color-hover);\r\n }\r\n\r\n /* Borderless variant for a header/toolbar utility slot, so it reads as the same kind of\r\n * hover-only control as st-icon-button and st-header's own language trigger (same fixed\r\n * height, no permanent visible border) instead of a form-field box. */\r\n :host([ghost]) .trigger {\r\n height: var(--st-size-32);\r\n padding: 0 var(--st-space-8);\r\n border: none;\r\n background: transparent;\r\n }\r\n\r\n :host([ghost]) .trigger:hover,\r\n :host([ghost]) .trigger:focus-visible {\r\n background: var(--st-color-hover);\r\n }\r\n\r\n select:disabled .trigger {\r\n color: var(--st-color-text-muted);\r\n cursor: not-allowed;\r\n }\r\n\r\n selectedcontent {\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n }\r\n\r\n select:has(option[value='']:checked) selectedcontent {\r\n color: var(--st-color-text-muted);\r\n }\r\n\r\n select::picker-icon {\r\n display: none;\r\n }\r\n\r\n .caret {\r\n display: flex;\r\n flex: none;\r\n color: var(--st-color-text-muted);\r\n }\r\n\r\n option {\r\n display: block;\r\n padding: var(--st-space-8) var(--st-space-10);\r\n font-size: var(--st-text-base);\r\n color: var(--st-color-text);\r\n cursor: pointer;\r\n }\r\n\r\n option[hidden] {\r\n display: none;\r\n }\r\n\r\n option:hover,\r\n option:focus {\r\n background: var(--st-color-hover);\r\n }\r\n\r\n option:checked {\r\n color: var(--st-color-text-strong);\r\n font-weight: var(--st-font-weight-semibold);\r\n }\r\n\r\n option::checkmark {\r\n display: none;\r\n }\r\n `;\r\n\r\n @property({ attribute: false })\r\n options: SelectOption[] = [];\r\n\r\n @property({ type: String })\r\n value = '';\r\n\r\n @property({ type: String })\r\n placeholder = 'Select…';\r\n\r\n /** Renders an internal `<label>` above the trigger, associated via `aria-labelledby`. Leave empty when the field is labeled some other way (e.g. context alone). */\r\n @property({ type: String, attribute: 'field-label' })\r\n fieldLabel = '';\r\n\r\n /**\r\n * Optional URL for an external-link button rendered in front of\r\n * `field-label` (same glyph/placement as the \"open library\" links next to\r\n * the Templates/Save-location breadcrumbs) — e.g. a link to the\r\n * SharePoint site or library the current selection points at. Ignored\r\n * when `field-label` is empty, since there'd be nothing to place it in\r\n * front of.\r\n */\r\n @property({ type: String, attribute: 'link-href' })\r\n linkHref = '';\r\n\r\n /** Accessible name/title for the `link-href` button. */\r\n @property({ type: String, attribute: 'link-label' })\r\n linkLabel = 'Open';\r\n\r\n /** Accessible name for the trigger when there's no visible `field-label` (e.g. a filter-row select). Ignored when `field-label` is set. */\r\n @property({ type: String, attribute: 'select-label' })\r\n selectLabel = '';\r\n\r\n @property({ type: Boolean, reflect: true })\r\n disabled = false;\r\n\r\n /** Borderless variant for a header/toolbar utility slot — see the `:host([ghost])` styles. */\r\n @property({ type: Boolean, reflect: true })\r\n ghost = false;\r\n\r\n @query('select')\r\n private readonly selectEl!: HTMLSelectElement;\r\n\r\n private readonly instanceId = ++instanceCounter;\r\n private readonly fieldLabelId = `st-select-label-${this.instanceId}`;\r\n\r\n protected updated(changed: PropertyValues): void {\r\n if (changed.has('value') || changed.has('options')) {\r\n const hasValue = this.options.some((option) => option.value === this.value);\r\n const nextValue = hasValue ? this.value : '';\r\n if (this.selectEl.value !== nextValue) this.selectEl.value = nextValue;\r\n }\r\n }\r\n\r\n render() {\r\n const hasValue = this.options.some((option) => option.value === this.value);\r\n\r\n return html`\r\n ${this.fieldLabel\r\n ? html`\r\n <span class=\"field-label-row\">\r\n ${this.linkHref\r\n ? html`\r\n <a\r\n part=\"field-label-link\"\r\n class=\"field-label-link\"\r\n href=${this.linkHref}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n title=${this.linkLabel}\r\n aria-label=${this.linkLabel}\r\n >\r\n ${externalLinkIcon(11)}\r\n </a>\r\n `\r\n : nothing}\r\n <span part=\"field-label\" id=${this.fieldLabelId} class=\"field-label\">${this.fieldLabel}</span>\r\n </span>\r\n `\r\n : nothing}\r\n <select\r\n part=\"select\"\r\n aria-label=${!this.fieldLabel && this.selectLabel ? this.selectLabel : nothing}\r\n aria-labelledby=${this.fieldLabel ? this.fieldLabelId : nothing}\r\n ?disabled=${this.disabled}\r\n @change=${this.onChange}\r\n >\r\n <button part=\"trigger\" class=\"trigger\" type=\"button\">\r\n <selectedcontent></selectedcontent>\r\n <span class=\"caret\">${chevronIcon('down', 10)}</span>\r\n </button>\r\n <option value=\"\" ?selected=${!hasValue} disabled hidden>${this.placeholder}</option>\r\n ${this.options.map(\r\n (option) => html`<option part=\"option\" value=${option.value} ?selected=${option.value === this.value}>${option.label}</option>`\r\n )}\r\n </select>\r\n `;\r\n }\r\n\r\n private onChange = (event: Event): void => {\r\n const newValue = (event.target as HTMLSelectElement).value;\r\n if (newValue === this.value) return;\r\n\r\n this.value = newValue;\r\n this.dispatchEvent(new CustomEvent<SelectChangedEventDetail>('select-change', { detail: { value: newValue }, bubbles: true, composed: true }));\r\n };\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/content-block/ContentBlock.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\n\r\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\r\nimport { sectionSubtitleStyles, sectionTitleStyles, sectionHeaderStyles } from '../shared/section-styles';\r\nimport '../markdown';\r\n\r\n/**\r\n * A long-form article section: centered title/subtitle, an optional featured image with caption,\r\n * then Markdown body text. Ports `SankhyaUI`'s React `ContentBlock`. The body comes from\r\n * `content-src` (a Markdown URL, as in the source) or an inline `content` string (added so the\r\n * block works without a fetch); `content-src` wins when both are set.\r\n *\r\n * @cssprop --st-content-block-padding - Overrides the block's padding.\r\n */\r\n@customElement('st-content-block')\r\nexport class ContentBlock extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: block;\r\n ${fontFamilyStyles}\r\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\r\n padding; override with --st-content-block-padding instead. */\r\n padding: var(--st-content-block-padding, var(--st-space-24)) !important;\r\n background: var(--st-color-surface);\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n :host([inverted]) {\r\n background: var(--st-color-text-strong);\r\n color: var(--st-color-on-solid);\r\n }\r\n\r\n .container {\r\n max-width: var(--st-cms-container-max);\r\n padding: 0 var(--st-space-48);\r\n margin: 0 auto;\r\n }\r\n\r\n .header {\r\n ${sectionHeaderStyles}\r\n }\r\n\r\n .title {\r\n ${sectionTitleStyles}\r\n line-height: 1.1;\r\n }\r\n\r\n .subtitle {\r\n ${sectionSubtitleStyles}\r\n }\r\n\r\n :host([inverted]) .title,\r\n :host([inverted]) .subtitle {\r\n color: inherit;\r\n }\r\n\r\n .featured-image {\r\n margin: 0 0 var(--st-space-48);\r\n border-radius: var(--st-radius-lg);\r\n overflow: hidden;\r\n }\r\n\r\n .featured-image img {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n\r\n figcaption {\r\n padding: var(--st-space-12);\r\n text-align: center;\r\n color: var(--st-color-text-muted);\r\n font-size: var(--st-text-xs);\r\n }\r\n\r\n st-markdown {\r\n color: var(--st-color-text);\r\n font-size: var(--st-text-xl);\r\n }\r\n\r\n :host([inverted]) st-markdown {\r\n color: inherit;\r\n }\r\n\r\n @media (max-width: 768px) {\r\n :host {\r\n padding: var(--st-content-block-padding, var(--st-space-48) var(--st-space-24)) !important;\r\n }\r\n\r\n .container {\r\n padding: 0;\r\n }\r\n }\r\n `;\r\n\r\n @property({ type: String })\r\n title = '';\r\n\r\n @property({ type: String })\r\n subtitle = '';\r\n\r\n /** URL of a Markdown file. */\r\n @property({ type: String, attribute: 'content-src' })\r\n contentSrc = '';\r\n\r\n /** Inline Markdown, used when `content-src` is not set. */\r\n @property({ type: String })\r\n content = '';\r\n\r\n @property({ type: String, attribute: 'image-src' })\r\n imageSrc = '';\r\n\r\n @property({ type: String, attribute: 'image-alt' })\r\n imageAlt = '';\r\n\r\n @property({ type: String, attribute: 'image-caption' })\r\n imageCaption = '';\r\n\r\n @property({ type: Boolean, reflect: true })\r\n inverted = false;\r\n\r\n render() {\r\n return html`\r\n <section class=\"container\" part=\"container\">\r\n <div class=\"header\" part=\"header\">\r\n ${this.title ? html`<div class=\"title\" part=\"title\">${this.title}</div>` : nothing}\r\n ${this.subtitle ? html`<div class=\"subtitle\" part=\"subtitle\">${this.subtitle}</div>` : nothing}\r\n </div>\r\n ${this.imageSrc\r\n ? html`\r\n <figure class=\"featured-image\" part=\"image\">\r\n <img src=${this.imageSrc} alt=${this.imageAlt || this.title} />\r\n ${this.imageCaption ? html`<figcaption>${this.imageCaption}</figcaption>` : nothing}\r\n </figure>\r\n `\r\n : nothing}\r\n <st-markdown part=\"body\" .src=${this.contentSrc} .content=${this.content}></st-markdown>\r\n </section>\r\n `;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,gBAAgB;AAejC,IAAM,eAAN,cAA2B,WAAW;AAAA,EAAtC;AAAA;AAmFL,iBAAQ;AAGR,oBAAW;AAIX,sBAAa;AAIb,mBAAU;AAGV,oBAAW;AAGX,oBAAW;AAGX,wBAAe;AAGf,oBAAW;AAAA;AAAA,EAEX,SAAS;AACP,WAAO;AAAA;AAAA;AAAA,YAGC,KAAK,QAAQ,uCAAuC,KAAK,KAAK,WAAW,OAAO;AAAA,YAChF,KAAK,WAAW,6CAA6C,KAAK,QAAQ,WAAW,OAAO;AAAA;AAAA,UAE9F,KAAK,WACH;AAAA;AAAA,2BAEe,KAAK,QAAQ,QAAQ,KAAK,YAAY,KAAK,KAAK;AAAA,kBACzD,KAAK,eAAe,mBAAmB,KAAK,YAAY,kBAAkB,OAAO;AAAA;AAAA,gBAGvF,OAAO;AAAA,wCACqB,KAAK,UAAU,aAAa,KAAK,OAAO;AAAA;AAAA;AAAA,EAG9E;AACF;AA/Ha,aACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIf,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAoBhB,mBAAmB;AAAA;AAAA;AAAA;AAAA,QAInB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKlB,qBAAqB;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;AAgD3B;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAlFf,aAmFX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GArFf,aAsFX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,cAAc,CAAC;AAAA,GAzFzC,aA0FX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA7Ff,aA8FX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GAhGvC,aAiGX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GAnGvC,aAoGX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,gBAAgB,CAAC;AAAA,GAtG3C,aAuGX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAzG/B,aA0GX;AA1GW,eAAN;AAAA,EADN,cAAc,kBAAkB;AAAA,GACpB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/feature-split/FeatureSplit.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\nimport 'iconify-icon';\r\n\r\nimport { controlBaseStyles, ctaButtonStyles, fontFamilyStyles } from '../shared/styles';\r\nimport '../markdown';\r\nimport {\r\n cardTitleStyles,\r\n iconTileStyles,\r\n reducedMotionStyles,\r\n sectionTitleStyles,\r\n} from '../shared/section-styles';\r\nimport type { FeatureSplitActionEventDetail } from './FeatureSplitEvents';\r\n\r\nexport interface FeatureSplitItem {\r\n /** Iconify icon name, e.g. `mdi:check`. */\r\n icon?: string;\r\n title: string;\r\n /** Markdown. */\r\n description: string;\r\n}\r\n\r\nexport type FeatureSplitImagePosition = 'left' | 'right' | 'top';\r\n\r\n/**\r\n * A title/markdown-subtitle/feature-list block beside (or under) an image.\r\n *\r\n * @cssprop --st-feature-split-padding - Overrides the block's padding.\r\n */\r\n@customElement('st-feature-split')\r\nexport class FeatureSplit extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: block;\r\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\r\n padding; override with --st-feature-split-padding instead. */\r\n padding: var(--st-feature-split-padding, var(--st-space-24)) !important;\r\n background: var(--st-color-page);\r\n ${fontFamilyStyles}\r\n }\r\n\r\n :host([inverted]) {\r\n background: var(--st-color-text-strong);\r\n }\r\n\r\n .container {\r\n max-width: var(--st-cms-container-max);\r\n margin: 0 auto;\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: var(--st-space-48);\r\n align-items: center;\r\n }\r\n\r\n :host([image-position='left']) .container {\r\n direction: rtl;\r\n }\r\n\r\n :host([image-position='left']) .content {\r\n direction: ltr;\r\n }\r\n\r\n :host([image-position='top']) .container {\r\n grid-template-columns: 1fr;\r\n text-align: center;\r\n }\r\n\r\n :host([image-position='top']) .content {\r\n align-items: center;\r\n }\r\n\r\n :host([image-position='top']) .image-wrapper {\r\n order: -1;\r\n max-width: 800px;\r\n margin: 0 auto;\r\n }\r\n\r\n .content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: var(--st-space-32);\r\n }\r\n\r\n .title {\r\n ${sectionTitleStyles}\r\n margin: 0;\r\n }\r\n\r\n .subtitle {\r\n color: var(--st-color-text-muted);\r\n font-size: var(--st-text-base);\r\n line-height: 1.6;\r\n }\r\n\r\n .list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: var(--st-space-24);\r\n margin-top: var(--st-space-16);\r\n }\r\n\r\n .item {\r\n display: flex;\r\n gap: var(--st-space-16);\r\n align-items: flex-start;\r\n text-align: left;\r\n }\r\n\r\n .icon {\r\n ${iconTileStyles}\r\n width: var(--st-space-48);\r\n height: var(--st-space-48);\r\n font-size: 24px;\r\n }\r\n\r\n .item-title {\r\n ${cardTitleStyles}\r\n }\r\n\r\n .item-description {\r\n color: var(--st-color-text-muted);\r\n font-size: var(--st-text-sm);\r\n line-height: 1.5;\r\n }\r\n\r\n .action {\r\n ${ctaButtonStyles}\r\n justify-self: start;\r\n padding: var(--st-space-16);\r\n border-radius: var(--st-radius-lg);\r\n }\r\n\r\n .image-wrapper {\r\n width: 100%;\r\n height: 100%;\r\n min-height: 400px;\r\n border-radius: var(--st-space-24);\r\n overflow: hidden;\r\n box-shadow: 0 20px 40px -12px var(--st-shadow-color-md);\r\n }\r\n\r\n .image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n transition: transform 0.5s ease;\r\n }\r\n\r\n .image:hover {\r\n transform: scale(1.02);\r\n }\r\n\r\n :host([inverted]) .title,\r\n :host([inverted]) .item-title {\r\n color: var(--st-color-on-solid);\r\n }\r\n\r\n :host([inverted]) .subtitle,\r\n :host([inverted]) .item-description {\r\n color: var(--st-color-border);\r\n }\r\n\r\n :host([inverted]) .icon {\r\n background: var(--st-color-text);\r\n color: var(--st-color-border);\r\n }\r\n\r\n @media (max-width: 1024px) {\r\n .container {\r\n gap: var(--st-space-40);\r\n }\r\n }\r\n\r\n @media (max-width: 768px) {\r\n :host {\r\n padding: var(--st-feature-split-padding, var(--st-space-48) var(--st-space-24)) !important;\r\n }\r\n\r\n .container {\r\n grid-template-columns: 1fr;\r\n direction: ltr !important;\r\n }\r\n\r\n .image-wrapper {\r\n min-height: 300px;\r\n order: -1;\r\n }\r\n }\r\n\r\n ${reducedMotionStyles}\r\n `;\r\n\r\n @property({ type: Boolean, reflect: true })\r\n inverted = false;\r\n\r\n @property({ type: String })\r\n title = '';\r\n\r\n /** Markdown. */\r\n @property({ type: String })\r\n subtitle = '';\r\n\r\n @property({ attribute: false })\r\n items: FeatureSplitItem[] = [];\r\n\r\n @property({ type: String, attribute: 'image-src' })\r\n imageSrc = '';\r\n\r\n @property({ type: String, attribute: 'image-alt' })\r\n imageAlt = '';\r\n\r\n @property({ type: String, attribute: 'image-position', reflect: true })\r\n imagePosition: FeatureSplitImagePosition = 'right';\r\n\r\n @property({ type: String, attribute: 'action-label' })\r\n actionLabel = '';\r\n\r\n @property({ type: String })\r\n href = '';\r\n\r\n private onAction() {\r\n const event = new CustomEvent<FeatureSplitActionEventDetail>('feature-split-action', {\r\n detail: { href: this.href },\r\n bubbles: true,\r\n composed: true,\r\n cancelable: true,\r\n });\r\n if (this.dispatchEvent(event)) window.location.href = this.href;\r\n }\r\n\r\n render() {\r\n return html`\r\n <div class=\"container\" part=\"container\">\r\n <div class=\"content\" part=\"content\">\r\n <h2 class=\"title\" part=\"title\">${this.title}</h2>\r\n ${this.subtitle\r\n ? html`<div class=\"subtitle\" part=\"subtitle\"><st-markdown .content=${this.subtitle}></st-markdown></div>`\r\n : nothing}\r\n ${this.items.length > 0\r\n ? html`<div class=\"list\" part=\"list\">\r\n ${this.items.map(\r\n (item) => html`\r\n <div class=\"item\" part=\"item\">\r\n ${item.icon\r\n ? html`<div class=\"icon\" part=\"icon\"><iconify-icon icon=${item.icon}></iconify-icon></div>`\r\n : nothing}\r\n <div>\r\n <h3 class=\"item-title\" part=\"item-title\">${item.title}</h3>\r\n <div class=\"item-description\" part=\"item-description\">\r\n <st-markdown .content=${item.description}></st-markdown>\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n )}\r\n </div>`\r\n : nothing}\r\n ${this.actionLabel && this.href\r\n ? html`<button class=\"action\" part=\"action\" type=\"button\" @click=${this.onAction}>${this.actionLabel}</button>`\r\n : nothing}\r\n </div>\r\n <div class=\"image-wrapper\" part=\"image-wrapper\">\r\n <img class=\"image\" part=\"image\" src=${this.imageSrc} alt=${this.imageAlt || this.title} />\r\n </div>\r\n </div>\r\n `;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,gBAAgB;AACxC,OAAO;AA4BA,IAAM,eAAN,cAA2B,WAAW;AAAA,EAAtC;AAAA;AAqKL,oBAAW;AAGX,iBAAQ;AAIR,oBAAW;AAGX,iBAA4B,CAAC;AAG7B,oBAAW;AAGX,oBAAW;AAGX,yBAA2C;AAG3C,uBAAc;AAGd,gBAAO;AAAA;AAAA,EAEC,WAAW;AACjB,UAAM,QAAQ,IAAI,YAA2C,wBAAwB;AAAA,MACnF,QAAQ,EAAE,MAAM,KAAK,KAAK;AAAA,MAC1B,SAAS;AAAA,MACT,UAAU;AAAA,MACV,YAAY;AAAA,IACd,CAAC;AACD,QAAI,KAAK,cAAc,KAAK,EAAG,QAAO,SAAS,OAAO,KAAK;AAAA,EAC7D;AAAA,EAEA,SAAS;AACP,WAAO;AAAA;AAAA;AAAA,2CAGgC,KAAK,KAAK;AAAA,YACzC,KAAK,WACH,mEAAmE,KAAK,QAAQ,0BAChF,OAAO;AAAA,YACT,KAAK,MAAM,SAAS,IAClB;AAAA,kBACI,KAAK,MAAM;AAAA,MACX,CAAC,SAAS;AAAA;AAAA,wBAEJ,KAAK,OACH,wDAAwD,KAAK,IAAI,2BACjE,OAAO;AAAA;AAAA,mEAEkC,KAAK,KAAK;AAAA;AAAA,kDAE3B,KAAK,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,IAKlD,CAAC;AAAA,wBAEH,OAAO;AAAA,YACT,KAAK,eAAe,KAAK,OACvB,iEAAiE,KAAK,QAAQ,IAAI,KAAK,WAAW,cAClG,OAAO;AAAA;AAAA;AAAA,gDAG2B,KAAK,QAAQ,QAAQ,KAAK,YAAY,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA,EAI9F;AACF;AA/Oa,aACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQf,gBAAgB;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,QA8ChB,kBAAkB;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,QAyBlB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOd,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAUf,eAAe;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MA+DjB,mBAAmB;AAAA;AAIvB;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GApK/B,aAqKX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAvKf,aAwKX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA3Kf,aA4KX;AAGA;AAAA,EADC,SAAS,EAAE,WAAW,MAAM,CAAC;AAAA,GA9KnB,aA+KX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GAjLvC,aAkLX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GApLvC,aAqLX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB,SAAS,KAAK,CAAC;AAAA,GAvL3D,aAwLX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,eAAe,CAAC;AAAA,GA1L1C,aA2LX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA7Lf,aA8LX;AA9LW,eAAN;AAAA,EADN,cAAc,kBAAkB;AAAA,GACpB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/menu-grid/MenuGrid.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\n\r\nimport { controlBaseStyles } from '../shared/styles';\r\n\r\n/**\r\n * A responsive grid of `st-menu-grid-item`s — the \"rich\" nav-menu layout (icon + title +\r\n * description per entry, arranged in columns), typically slotted into `st-dropdown`'s default\r\n * slot. A 1:1 port of `SankhyaUI`'s React `MenuGrid` (`SankhyaCMS/SankhyaUI/src/components/Menu`):\r\n * same markup (`.menu-grid-container` > `.menu-grid.columns-N`), gap and breakpoints (768px: 2–4\r\n * columns → 2; 480px: everything → 1; a 1-column grid stays 1).\r\n */\r\n@customElement('st-menu-grid')\r\nexport class MenuGrid extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: block;\r\n }\r\n\r\n .menu-grid-container {\r\n width: 100%;\r\n }\r\n\r\n .menu-grid {\r\n display: grid;\r\n gap: 12px;\r\n }\r\n\r\n .menu-grid.columns-1 {\r\n grid-template-columns: repeat(1, 1fr);\r\n }\r\n\r\n .menu-grid.columns-2 {\r\n grid-template-columns: repeat(2, 1fr);\r\n }\r\n\r\n .menu-grid.columns-3 {\r\n grid-template-columns: repeat(3, 1fr);\r\n }\r\n\r\n .menu-grid.columns-4 {\r\n grid-template-columns: repeat(4, 1fr);\r\n }\r\n\r\n @media (max-width: 768px) {\r\n .menu-grid.columns-2,\r\n .menu-grid.columns-3,\r\n .menu-grid.columns-4 {\r\n grid-template-columns: repeat(2, 1fr);\r\n }\r\n }\r\n\r\n @media (max-width: 480px) {\r\n .menu-grid.columns-1,\r\n .menu-grid.columns-2,\r\n .menu-grid.columns-3,\r\n .menu-grid.columns-4 {\r\n grid-template-columns: 1fr;\r\n }\r\n }\r\n `;\r\n\r\n /** Number of columns at full width (1–4, same as the source component's `columns-N` classes). */\r\n @property({ type: Number })\r\n columns = 3;\r\n\r\n /** Extra class(es) appended to the inner grid element — the source component's `gridClassName`.\r\n * Its outer `className` is the host element itself here: set a `class` attribute on `st-menu-grid`. */\r\n @property({ type: String, attribute: 'grid-class-name' })\r\n gridClassName = '';\r\n\r\n render() {\r\n const columns = Math.min(4, Math.max(1, Math.round(this.columns) || 1));\r\n return html`\r\n <div class=\"menu-grid-container\" part=\"container\">\r\n <div part=\"grid\" class=\"menu-grid columns-${columns} ${this.gridClassName}\">\r\n <slot></slot>\r\n </div>\r\n </div>\r\n `;\r\n }\r\n}\r\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":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/icon-button/IconButton.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\n\r\nimport { buttonResetStyles, controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\r\n\r\n/**\r\n * A small, icon-only action button — ported from `SankhyaUI`'s React `IconButton` (a separate,\r\n * unrelated marketing-site project; that source takes an iconify string `icon` prop, this package\r\n * has no iconify dependency, so the icon is default-slotted content instead, same convention as\r\n * `st-dropdown`/`st-menu-grid-item`'s `slot=\"icon\"`).\r\n *\r\n * Fires a plain native `click` — no custom event, since a caller just wants an ordinary button.\r\n */\r\n@customElement('st-icon-button')\r\nexport class IconButton extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: inline-flex;\r\n ${rootFontFamilyStyles}\r\n }\r\n\r\n button {\r\n ${buttonResetStyles}\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: var(--st-size-32);\r\n height: var(--st-size-32);\r\n border-radius: var(--st-radius-sm);\r\n color: var(--st-color-text-muted);\r\n }\r\n\r\n button:hover {\r\n background: var(--st-color-hover);\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n :host([disabled]) button {\r\n color: var(--st-color-text-muted);\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n }\r\n `;\r\n\r\n /** Accessible name and tooltip — matches the source component's `ariaLabel` (renamed: modern\r\n * browsers already expose a native `ariaLabel` reflected property on every `Element`, so reusing\r\n * that exact name as a Lit reactive property would shadow it). Required for a control with no\r\n * visible text. */\r\n @property({ type: String })\r\n label = '';\r\n\r\n @property({ type: Boolean, reflect: true })\r\n disabled = false;\r\n\r\n render() {\r\n return html`\r\n <button part=\"button\" type=\"button\" aria-label=${this.label} title=${this.label} ?disabled=${this.disabled}>\r\n <slot></slot>\r\n </button>\r\n `;\r\n }\r\n}\r\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":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|