@ds-mo/ui 2.12.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/.build-stamp +1 -1
- package/dist/components/ds-app-shell.js +1 -1
- package/dist/components/ds-banner.js +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-nav.js.map +1 -1
- package/dist/components/ds-button-filled.js +1 -1
- package/dist/components/ds-button-unfilled.js +1 -1
- package/dist/components/{ds-card-data-viz.d.ts → ds-card-data-viz-donut.d.ts} +4 -4
- package/dist/components/ds-card-data-viz-donut.js +2 -0
- package/dist/components/ds-card-data-viz-donut.js.map +1 -0
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card-setting.js.map +1 -1
- package/dist/components/{ds-header.d.ts → ds-card.d.ts} +4 -4
- package/dist/components/ds-card.js +2 -0
- package/dist/components/ds-card.js.map +1 -0
- package/dist/components/ds-chart-bar.js +1 -1
- package/dist/components/ds-chart-bar.js.map +1 -1
- package/dist/components/ds-chart-donut.js +1 -1
- package/dist/components/ds-chart-donut.js.map +1 -1
- package/dist/components/ds-chart-legend.js +1 -1
- package/dist/components/ds-chart-line.js +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/ds-chip.js +1 -1
- package/dist/components/ds-divider.js +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-empty-state.js.map +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-field.js.map +1 -1
- package/dist/components/ds-icon.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-input.js.map +1 -1
- package/dist/components/ds-loader.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-panel-tools.js.map +1 -1
- package/dist/components/ds-radio-group.js +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-select.js.map +1 -1
- package/dist/components/ds-shell-gradient-picker.js +1 -1
- package/dist/components/ds-shell-gradient-swatch.js +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-tab-group-nav.js +1 -1
- package/dist/components/ds-tab-group.js +1 -1
- package/dist/components/ds-table.js +1 -1
- package/dist/components/ds-tag.js +1 -1
- package/dist/components/ds-text.js +1 -1
- package/dist/components/ds-toggle.js +1 -1
- package/dist/components/ds-tooltip-data-viz.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/{p-BPK76IsW.js → p-1m8r0wFg.js} +2 -2
- package/dist/components/{p-BZIOTcnM.js → p-3FLHei19.js} +2 -2
- package/dist/components/p-B2_D4IDN.js +2 -0
- package/dist/components/p-B2_D4IDN.js.map +1 -0
- package/dist/components/p-B5NcWtpp.js +2 -0
- package/dist/components/p-B5NcWtpp.js.map +1 -0
- package/dist/components/{p-CyFVn2Sc.js → p-B82KZX9D.js} +2 -2
- package/dist/components/p-B_g8X0eh.js +2 -0
- package/dist/components/p-B_g8X0eh.js.map +1 -0
- package/dist/components/{p-C3ORQUOp.js → p-Be3PHv34.js} +2 -2
- package/dist/components/{p-DkcH8mRl.js → p-CQmf2CeW.js} +2 -2
- package/dist/components/{p-DRqxVEye.js → p-CtwNUCnp.js} +2 -2
- package/dist/components/p-CuRjYmBk.js +2 -0
- package/dist/components/p-CuRjYmBk.js.map +1 -0
- package/dist/components/{p-DKdI8T8v.js → p-CwARVsZQ.js} +2 -2
- package/dist/components/{p-DKdI8T8v.js.map → p-CwARVsZQ.js.map} +1 -1
- package/dist/components/{p-UbKTMQjv.js → p-DohXlNCJ.js} +2 -2
- package/dist/components/p-DuFm-ieS.js +2 -0
- package/dist/components/p-DuFm-ieS.js.map +1 -0
- package/dist/lib/nav/index.js.map +2 -2
- package/dist/lib/utils/control-width.d.ts +4 -0
- package/dist/lib/utils/index.d.ts +2 -0
- package/dist/lib/utils/index.js +14 -1
- package/dist/lib/utils/index.js.map +3 -3
- package/dist/lib/utils/token-defaults.d.ts +4 -0
- package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +4 -0
- package/dist/types/components/ButtonFilled/index.d.ts +1 -1
- package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +7 -3
- package/dist/types/components/ButtonUnfilled/index.d.ts +1 -1
- package/dist/types/components/Card/Card.d.ts +20 -0
- package/dist/types/components/Card/index.d.ts +2 -0
- package/dist/types/components/CardDataVizDonut/CardDataVizDonut.d.ts +26 -0
- package/dist/types/components/CardDataVizDonut/index.d.ts +2 -0
- package/dist/types/components/CardSetting/CardSetting.d.ts +7 -2
- package/dist/types/components/ChartDonut/ChartDonut.d.ts +24 -1
- package/dist/types/components/Select/Select.d.ts +32 -0
- package/dist/types/components/Select/index.d.ts +2 -0
- package/dist/types/components.d.ts +207 -110
- package/dist/types/utils/control-width.d.ts +5 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/token-defaults.d.ts +4 -0
- package/package.json +2 -2
- package/src/angular/index.ts +2 -3
- package/src/angular/proxies.ts +40 -56
- package/src/react/components.ts +2 -3
- package/src/react/ds-card-data-viz-donut.ts +27 -0
- package/src/react/{ds-header.ts → ds-card.ts} +7 -7
- package/src/wc/components/ButtonFilled/ButtonFilled.tsx +7 -0
- package/src/wc/components/ButtonFilled/index.ts +1 -0
- package/src/wc/components/ButtonUnfilled/ButtonUnfilled.tsx +10 -3
- package/src/wc/components/ButtonUnfilled/index.ts +1 -0
- package/src/wc/components/Card/Card.tsx +79 -0
- package/src/wc/components/Card/index.ts +1 -0
- package/src/wc/components/{CardDataViz/CardDataViz.tsx → CardDataVizDonut/CardDataVizDonut.tsx} +47 -40
- package/src/wc/components/CardDataVizDonut/index.ts +1 -0
- package/src/wc/components/CardSetting/CardSetting.tsx +22 -35
- package/src/wc/components/ChartDonut/ChartDonut.tsx +112 -11
- package/src/wc/components/Select/Select.tsx +141 -60
- package/src/wc/components/Select/index.ts +1 -0
- package/src/wc/components.d.ts +207 -113
- package/src/wc/utils/control-width.css +28 -0
- package/src/wc/utils/control-width.ts +10 -0
- package/src/wc/utils/index.ts +2 -0
- package/src/wc/utils/token-defaults.ts +4 -0
- package/dist/components/ds-card-data-viz.js +0 -2
- package/dist/components/ds-card-data-viz.js.map +0 -1
- package/dist/components/ds-header.js +0 -2
- package/dist/components/ds-header.js.map +0 -1
- package/dist/components/ds-scrollbar.d.ts +0 -11
- package/dist/components/ds-scrollbar.js +0 -2
- package/dist/components/ds-scrollbar.js.map +0 -1
- package/dist/components/p-B9dHCgY-.js +0 -2
- package/dist/components/p-B9dHCgY-.js.map +0 -1
- package/dist/components/p-BTC9Njj6.js +0 -2
- package/dist/components/p-BTC9Njj6.js.map +0 -1
- package/dist/components/p-DusYu-if.js +0 -2
- package/dist/components/p-DusYu-if.js.map +0 -1
- package/dist/types/components/CardDataViz/CardDataViz.d.ts +0 -22
- package/dist/types/components/CardDataViz/index.d.ts +0 -2
- package/dist/types/components/Header/Header.d.ts +0 -7
- package/dist/types/components/Scrollbar/Scrollbar.d.ts +0 -27
- package/src/react/ds-card-data-viz.ts +0 -26
- package/src/react/ds-scrollbar.ts +0 -26
- package/src/wc/components/CardDataViz/index.ts +0 -1
- package/src/wc/components/Header/Header.tsx +0 -33
- package/src/wc/components/Scrollbar/Scrollbar.tsx +0 -189
- /package/dist/components/{p-BPK76IsW.js.map → p-1m8r0wFg.js.map} +0 -0
- /package/dist/components/{p-BZIOTcnM.js.map → p-3FLHei19.js.map} +0 -0
- /package/dist/components/{p-CyFVn2Sc.js.map → p-B82KZX9D.js.map} +0 -0
- /package/dist/components/{p-C3ORQUOp.js.map → p-Be3PHv34.js.map} +0 -0
- /package/dist/components/{p-DkcH8mRl.js.map → p-CQmf2CeW.js.map} +0 -0
- /package/dist/components/{p-DRqxVEye.js.map → p-CtwNUCnp.js.map} +0 -0
- /package/dist/components/{p-UbKTMQjv.js.map → p-DohXlNCJ.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/wc/nav/nav-chrome.ts", "../../../src/wc/utils/resolve-css-time-ms.ts", "../../../src/wc/nav/shell-view-transition.ts", "../../../src/wc/nav/shell-gradient-presets.ts", "../../../src/wc/nav/shell-gradient.ts", "../../../src/wc/utils/token-defaults.ts", "../../../src/wc/components/Menu/menu-placement.ts", "../../../src/wc/nav/chrome-transition.ts", "../../../src/wc/nav/shell-chrome-metrics.ts", "../../../src/wc/nav/badge-gradient-ring.ts"],
|
|
4
|
-
"sourcesContent": ["/** Nav chrome style slot \u2014 dashboard vs settings. Colors unified for now; texture hooks use the class. */\nexport type NavChromeStyle = 'dashboard' | 'settings';\n\n/** Document hint for first paint before framework props land. */\nexport const NAV_STYLE_HINT_ATTR = 'data-nav-style';\n\nexport function readNavStyleAttr(attr: string | null): NavChromeStyle | undefined {\n if (attr === 'dashboard' || attr === 'settings') return attr;\n return undefined;\n}\n\nexport function setNavStyleHint(style: NavChromeStyle): void {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute(NAV_STYLE_HINT_ATTR, style);\n}\n\nexport function clearNavStyleHint(): void {\n if (typeof document === 'undefined') return;\n document.documentElement.removeAttribute(NAV_STYLE_HINT_ATTR);\n}\n\nexport function resolveNavChromeStyle(\n styleProp: NavChromeStyle,\n hostAttr: string | null,\n docHint?: string | null,\n): NavChromeStyle {\n const fromHost = readNavStyleAttr(hostAttr);\n if (fromHost) return fromHost;\n\n const hint =\n docHint !== undefined\n ? docHint\n : typeof document !== 'undefined'\n ? document.documentElement.getAttribute(NAV_STYLE_HINT_ATTR)\n : null;\n const fromHint = readNavStyleAttr(hint);\n if (fromHint) return fromHint;\n\n return styleProp;\n}\n\nexport function shouldResyncNavChromeStyle(\n renderedStyle: NavChromeStyle,\n style: NavChromeStyle,\n): boolean {\n return renderedStyle !== style;\n}\n", "/** Parse a CSS <time> value (or motion shorthand's first token) to milliseconds. */\nexport function parseCssTimeMs(value: string, fallback: number): number {\n const firstToken = value.trim().split(/\\s+/)[0] ?? '';\n const num = parseFloat(firstToken);\n if (Number.isNaN(num)) return fallback;\n if (/ms\\s*$/.test(firstToken)) return num;\n if (/s\\s*$/.test(firstToken)) return num * 1000;\n return num;\n}\n\nfunction extractCssCustomProp(ref: string): string | null {\n const varMatch = ref.match(/^var\\(\\s*(--[^),]+)/);\n if (varMatch) return varMatch[1].trim();\n if (ref.startsWith('--')) return ref.trim();\n return null;\n}\n\nfunction readTokenTimeMs(token: string, fallback: number): number {\n if (typeof document === 'undefined') return fallback;\n\n const prop = extractCssCustomProp(token);\n if (!prop) return parseCssTimeMs(token, fallback);\n\n const raw = getComputedStyle(document.documentElement).getPropertyValue(prop).trim();\n return parseCssTimeMs(raw, fallback);\n}\n\n/**\n * Resolve a duration to milliseconds for JS timers aligned with CSS motion tokens.\n * Accepts numbers (ms), raw times (`200ms`, `0.75s`), or `var(--effect-*)` references.\n */\nexport function resolveCssTimeMs(\n value: number | string | undefined,\n fallbackToken: string,\n): number {\n if (typeof value === 'number') return value;\n\n const token = typeof value === 'string' && value.trim() ? value.trim() : fallbackToken;\n const prop = extractCssCustomProp(token);\n\n if (prop) {\n return readTokenTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n }\n\n return parseCssTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n}\n", "import { parseCssTimeMs } from '../utils/resolve-css-time-ms';\n\n/** `view-transition-name` on `ds-bar-nav` \u2014 pairs with root reveal in shell apps. */\nexport const SHELL_BAR_NAV_VT_NAME = 'ds-shell-bar-nav';\n\nexport { parseCssTimeMs };\n\nconst VT_STYLE_ID = 'ds-shell-nav-vt-style';\n\n/** TokoMo tokens for the dashboard \u2194 settings radial reveal (WAAPI). */\nexport const SHELL_NAV_REVEAL_DURATION_VAR = '--effect-animation-duration-medium-3';\nexport const SHELL_NAV_REVEAL_EASING_VAR = '--effect-animation-easing-ease-in-out';\nconst SHELL_NAV_REVEAL_DURATION_FALLBACK_MS = 500;\nconst SHELL_NAV_REVEAL_EASING_FALLBACK = 'ease-in-out';\n\nfunction readCssCustomProperty(name: string, fallback: string): string {\n if (typeof document === 'undefined') return fallback;\n const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();\n return value || fallback;\n}\n\n/** Suppress default cross-fade and pin new snapshots to a 0px circle for WAAPI reveal. */\nexport function ensureShellNavVtStyle(): void {\n if (typeof document === 'undefined') return;\n\n const content = [\n '::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}',\n `::view-transition-old(${SHELL_BAR_NAV_VT_NAME}),::view-transition-new(${SHELL_BAR_NAV_VT_NAME}){animation:none;mix-blend-mode:normal}`,\n `::view-transition-old(${SHELL_BAR_NAV_VT_NAME}){z-index:1}`,\n `::view-transition-new(${SHELL_BAR_NAV_VT_NAME}){z-index:2;clip-path:circle(0px at var(--vt-x,50%) var(--vt-y,50%))}`,\n '::view-transition-new(root){clip-path:circle(0px at var(--vt-x,50%) var(--vt-y,50%))}',\n ].join('\\n');\n\n const existing = document.getElementById(VT_STYLE_ID) as HTMLStyleElement | null;\n if (existing) {\n if (existing.textContent !== content) existing.textContent = content;\n return;\n }\n\n const style = document.createElement('style');\n style.id = VT_STYLE_ID;\n style.textContent = content;\n document.head.appendChild(style);\n}\n\nexport interface ShellNavRevealOrigin {\n x: number;\n y: number;\n maxRadius: number;\n}\n\n/** Origin for the radial reveal \u2014 defaults to panel-nav footer gear, then viewport center. */\nexport function resolveShellNavRevealOrigin(originEl?: HTMLElement | null): ShellNavRevealOrigin {\n const btn =\n originEl ??\n document.querySelector<HTMLElement>('.panel-nav__footer-btn');\n const rect = btn?.getBoundingClientRect();\n const x = rect ? Math.round(rect.left + rect.width / 2) : Math.round(window.innerWidth / 2);\n const y = rect ? Math.round(rect.top + rect.height / 2) : Math.round(window.innerHeight / 2);\n const maxRadius = Math.ceil(\n Math.hypot(Math.max(x, window.innerWidth - x), Math.max(y, window.innerHeight - y)),\n );\n return { x, y, maxRadius };\n}\n\nexport function setShellNavRevealOriginVars(origin: ShellNavRevealOrigin): void {\n document.documentElement.style.setProperty('--vt-x', `${origin.x}px`);\n document.documentElement.style.setProperty('--vt-y', `${origin.y}px`);\n}\n\n/** Animate root + bar-nav snapshots with the same radial clip-path reveal. */\nexport function animateShellNavRadialReveal(\n origin: ShellNavRevealOrigin,\n durationMs?: number,\n): void {\n const duration =\n durationMs ??\n parseCssTimeMs(\n readCssCustomProperty(SHELL_NAV_REVEAL_DURATION_VAR, '400ms'),\n SHELL_NAV_REVEAL_DURATION_FALLBACK_MS,\n );\n const easing = readCssCustomProperty(\n SHELL_NAV_REVEAL_EASING_VAR,\n SHELL_NAV_REVEAL_EASING_FALLBACK,\n );\n const keyframes = {\n clipPath: [\n `circle(0px at ${origin.x}px ${origin.y}px)`,\n `circle(${origin.maxRadius}px at ${origin.x}px ${origin.y}px)`,\n ],\n };\n const options = {\n duration,\n easing,\n fill: 'forwards' as const,\n };\n\n document.documentElement.animate(keyframes, {\n ...options,\n pseudoElement: '::view-transition-new(root)',\n });\n document.documentElement.animate(keyframes, {\n ...options,\n pseudoElement: `::view-transition-new(${SHELL_BAR_NAV_VT_NAME})`,\n });\n}\n\n/** Run radial reveal when a view transition's `ready` promise settles (app/router driver). */\nexport function runShellNavStyleRevealOnReady(\n transition: { ready: Promise<void> },\n originEl?: HTMLElement | null,\n): void {\n ensureShellNavVtStyle();\n const origin = resolveShellNavRevealOrigin(originEl);\n setShellNavRevealOriginVars(origin);\n\n transition.ready\n .then(() => animateShellNavRadialReveal(origin))\n .catch(() => {\n /* transition skipped or superseded */\n });\n}\n", "/** Built-in shell chrome wash presets \u2014 none (solid secondary), cool, neutral, warm. */\nexport type ShellGradientPreset = 'none' | 'cool' | 'neutral' | 'warm';\n\nexport const SHELL_GRADIENT_PRESETS: ShellGradientPreset[] = ['none', 'cool', 'neutral', 'warm'];\n\n/** Wash presets shown after the `none` option in pickers. */\nexport const SHELL_GRADIENT_WASH_PRESETS: Exclude<ShellGradientPreset, 'none'>[] = [\n 'cool',\n 'neutral',\n 'warm',\n];\n\n/** Default wash when `gradient-preset` is omitted. */\nexport const DEFAULT_SHELL_GRADIENT_PRESET: ShellGradientPreset = 'neutral';\n\nexport const SHELL_GRADIENT_PRESET_LABELS: Record<ShellGradientPreset, string> = {\n none: 'None',\n cool: 'Cool',\n neutral: 'Neutral',\n warm: 'Warm',\n};\n\nconst SHELL_GRADIENT_PRESET_STOP: Record<Exclude<ShellGradientPreset, 'none'>, string> = {\n cool: 'var(--color-color-intent-blue-strong-background)',\n neutral: 'var(--color-color-intent-grey-strong-background)',\n warm: 'var(--color-color-intent-yellow-strong-background)',\n};\n\nconst GRADIENT_GEOMETRY = '100% 100% at 0% 0%';\n\nexport function shellGradientPresetStopToken(preset: ShellGradientPreset): string | null {\n if (preset === 'none') return null;\n return SHELL_GRADIENT_PRESET_STOP[preset];\n}\n\nexport function isShellGradientPreset(value: string): value is ShellGradientPreset {\n return (SHELL_GRADIENT_PRESETS as string[]).includes(value);\n}\n\n/**\n * Coerce unknown/absent presets to the default. Runtime values escape the\n * type: removing the reflected `gradient-preset` attribute (e.g. an Angular\n * `[attr.gradient-preset]=\"null\"` binding) drives the prop to null past its\n * field default \u2014 without normalization the stop lookup interpolates the\n * literal string \"undefined\" into CSS and the wash silently disappears.\n */\nexport function normalizeShellGradientPreset(\n value: string | null | undefined,\n): ShellGradientPreset {\n return value != null && isShellGradientPreset(value) ? value : DEFAULT_SHELL_GRADIENT_PRESET;\n}\n\n/** Radial wash for a preset \u2014 transparent at top-left into the intent stop. `none` returns no image. */\nexport function buildShellRadialGradientForPreset(preset: ShellGradientPreset): string {\n const normalized = normalizeShellGradientPreset(preset);\n if (normalized === 'none') return 'none';\n\n const stop = shellGradientPresetStopToken(normalized);\n return `radial-gradient(${GRADIENT_GEOMETRY}, var(--color-background-transparent) 0%, ${stop} 100%)`;\n}\n", "/** CSS var names consumed by `ds-panel-nav` / `ds-bar-nav` inside `ds-app-shell`. */\nimport type { ShellGradientPreset } from './shell-gradient-presets';\nimport {\n DEFAULT_SHELL_GRADIENT_PRESET,\n buildShellRadialGradientForPreset,\n} from './shell-gradient-presets';\n\nexport type { ShellGradientPreset } from './shell-gradient-presets';\nexport {\n DEFAULT_SHELL_GRADIENT_PRESET,\n SHELL_GRADIENT_PRESETS,\n SHELL_GRADIENT_PRESET_LABELS,\n buildShellRadialGradientForPreset,\n isShellGradientPreset,\n shellGradientPresetStopToken,\n} from './shell-gradient-presets';\n\nexport const SHELL_GRADIENT_IMAGE_VAR = '--ds-shell-gradient-image';\nexport const SHELL_GRADIENT_SIZE_VAR = '--ds-shell-gradient-size';\nexport const SHELL_GRADIENT_POSITION_PANEL_VAR = '--ds-shell-gradient-position-panel';\nexport const SHELL_GRADIENT_POSITION_BAR_VAR = '--ds-shell-gradient-position-bar';\nexport const SHELL_GRADIENT_OPACITY_VAR = '--ds-shell-gradient-opacity';\n/** Per chrome-surface background-position \u2014 offsets wash + grid to shell row origin. */\nexport const SHELL_CHROME_SURFACE_POSITION_VAR = '--ds-shell-chrome-surface-position';\n\n/** Layer opacity for the nav gradient wash. */\nexport const SHELL_GRADIENT_OPACITY = '0.1';\n\n/** Whether the shared chrome layer (secondary bg + optional wash) should mount. */\nexport function shellChromeLayerActive(gradient: boolean): boolean {\n return gradient;\n}\n\n/**\n * Shell radial wash \u2014 same for panel and bar nav.\n * Tokens follow `data-theme` (light/dark intent stops).\n */\nexport function buildShellRadialGradient(\n preset: ShellGradientPreset = DEFAULT_SHELL_GRADIENT_PRESET,\n): string {\n return buildShellRadialGradientForPreset(preset);\n}\n\n/** Built-in radial image (`gradientSrc` on shell overrides). */\nexport function shellGradientImage(\n preset: ShellGradientPreset = DEFAULT_SHELL_GRADIENT_PRESET,\n): string {\n return buildShellRadialGradient(preset);\n}\n\nexport interface ShellViewportDimensions {\n width: number;\n height: number;\n}\n\n/**\n * Viewport size for shell chrome with `background-attachment: fixed`.\n * Must not use the `ds-app-shell` element box \u2014 the shell can be shorter or\n * taller than the viewport when host height chains break or content overflows.\n */\nexport function readShellViewportDimensions(win?: Window): ShellViewportDimensions {\n const w = win ?? (typeof globalThis.window !== 'undefined' ? globalThis.window : undefined);\n if (!w) return { width: 0, height: 0 };\n\n const visual = w.visualViewport;\n return {\n width: Math.round(visual?.width ?? w.innerWidth),\n height: Math.round(visual?.height ?? w.innerHeight),\n };\n}\n\nexport interface ShellGradientLayout {\n width: number;\n height: number;\n panelWidth: number;\n}\n\n/** Pixel `background-size` for the fixed-attachment radial wash. */\nexport function shellGradientSize(layout: Pick<ShellGradientLayout, 'width' | 'height'>): string {\n return `${Math.round(layout.width)}px ${Math.round(layout.height)}px`;\n}\n\nexport function shellGradientPositionPanel(): string {\n return '0 0';\n}\n\nexport function shellGradientPositionBar(panelWidth: number): string {\n return `${-Math.round(panelWidth)}px 0`;\n}\n\n/** Phase-lock a chrome rect to the shell row coordinate system (wash + grid). */\nexport function shellChromeSurfacePosition(leftPx: number, topPx: number): string {\n return `${-Math.round(leftPx)}px ${-Math.round(topPx)}px`;\n}\n", "import {\n dimensionIconographyMd,\n dimensionIconographySm,\n dimensionIconographyXs,\n dimensionMenuWidthXs,\n dimensionPanelWidth2xs,\n dimensionPanelWidthLg,\n dimensionPanelWidthMd,\n dimensionRadius025,\n dimensionSize200,\n dimensionSize300,\n dimensionSize400,\n dimensionSize600,\n dimensionSize800,\n dimensionSpace050,\n dimensionSpace200,\n typographyLineheightLg,\n typographyLineheightMd,\n typographyLineheightSm,\n typographyLineheightXl,\n typographyLineheightXs,\n effectAnimationDelayLong2,\n effectAnimationDelayMedium1,\n effectAnimationDelayMedium3,\n effectAnimationDelayInstant,\n effectAnimationDelayShort2,\n effectAnimationDurationMedium1,\n effectAnimationDurationShort3,\n effectMotionShort2,\n effectMotionShort3,\n} from '@ds-mo/tokens/ts';\n\n/** TokoMo CSS custom-property names for shared component defaults (runtime resolution). */\nexport const TOKEN_DEFAULTS = {\n space050: dimensionSpace050,\n space200: dimensionSpace200,\n radius025: dimensionRadius025,\n size200: dimensionSize200,\n size300: dimensionSize300,\n size400: dimensionSize400,\n size600: dimensionSize600,\n size800: dimensionSize800,\n iconographyMd: dimensionIconographyMd,\n iconographySm: dimensionIconographySm,\n iconographyXs: dimensionIconographyXs,\n panelWidth2xs: dimensionPanelWidth2xs,\n panelWidthMd: dimensionPanelWidthMd,\n panelWidthLg: dimensionPanelWidthLg,\n menuWidthXs: dimensionMenuWidthXs,\n lineheightLg: typographyLineheightLg,\n lineheightMd: typographyLineheightMd,\n lineheightSm: typographyLineheightSm,\n lineheightXl: typographyLineheightXl,\n lineheightXs: typographyLineheightXs,\n motionShort2: effectMotionShort2,\n motionShort3: effectMotionShort3,\n animationDurationShort3: effectAnimationDurationShort3,\n animationDurationMedium1: effectAnimationDurationMedium1,\n animationDelayInstant: effectAnimationDelayInstant,\n animationDelayMedium1: effectAnimationDelayMedium1,\n animationDelayMedium3: effectAnimationDelayMedium3,\n animationDelayShort2: effectAnimationDelayShort2,\n animationDelayLong2: effectAnimationDelayLong2,\n /** Unmeasured menu height fallback: 20\u00D7 base (160px at default scale). */\n menuFallbackHeight: 'calc(var(--dimension-size-base) * 20)',\n /** Unmeasured tooltip width fallback: size-800 + size-200 (80px). */\n tooltipFallbackWidth: 'calc(var(--dimension-size-800) + var(--dimension-size-200))',\n} as const;\n\nexport type TokenDefaultKey = keyof typeof TOKEN_DEFAULTS;\n\n/** Valid CSS length strings for overlay offset props \u2014 bind on `sideOffset` / `alignOffset` in hosts. */\nexport const TOKEN_CSS_LENGTHS = {\n space050: `var(${dimensionSpace050})`,\n space200: `var(${dimensionSpace200})`,\n menuWidthXs: `var(${dimensionMenuWidthXs})`,\n} as const;\n", "import { TOKEN_CSS_LENGTHS } from '../../utils/token-defaults';\nimport type { MenuAlign, MenuSide } from './menu-position';\n\n/** Placement props bindable on `ds-menu` (side, align, offsets). */\nexport interface MenuPlacement {\n side: MenuSide;\n align: MenuAlign;\n sideOffset: number | string;\n alignOffset: number | string;\n}\n\n/**\n * Canonical `ds-menu` placement for the **panel-nav footer user menu**.\n * Anchor from `dsNavUserAction` detail `{ anchor }` (id `ds-panel-nav-user-menu-anchor`).\n *\n * Not for BarNav overflow menus \u2014 those use `side=\"bottom\"` / `align=\"end\"` internally.\n * `align: 'end'` bottom-aligns on the anchor; offsets nudge into the content area:\n * - `sideOffset` space-100 + space-050 (12px): 4px past the panel-nav outer edge (anchor is ~8px inset).\n * - `alignOffset` space-050 (4px): 4px below the footer user row.\n */\nexport const PANEL_NAV_USER_MENU_PLACEMENT = {\n side: 'right',\n align: 'end',\n sideOffset: 'calc(var(--dimension-space-100) + var(--dimension-space-050))',\n alignOffset: TOKEN_CSS_LENGTHS.space050,\n} as const satisfies MenuPlacement;\n", "/** Bubbling/composed events \u2014 `ds-app-shell` and `ds-bar-nav` coordinate during width motion. */\n\nexport const CHROME_TRANSITION_START = 'dsChromeTransitionStart';\nexport const CHROME_TRANSITION_END = 'dsChromeTransitionEnd';\n\nexport type ChromeTransitionSource = 'panel-nav' | 'panel-tools';\n\nexport interface ChromeTransitionDetail {\n source: ChromeTransitionSource;\n /** Panel-tools drawer motion direction; omitted for panel-nav. */\n phase?: 'opening' | 'closing';\n}\n\n/** Reference-counted gate \u2014 used while panel-nav width is transitioning. */\nexport class ChromeTransitionDepth {\n private depth = 0;\n\n enter(): void {\n this.depth += 1;\n }\n\n exit(): void {\n this.depth = Math.max(0, this.depth - 1);\n }\n\n get isActive(): boolean {\n return this.depth > 0;\n }\n}\n\nexport interface RafCoalescer {\n schedule(): void;\n cancel(): void;\n}\n\n/** Coalesce bursty layout work (ResizeObserver, prop churn) to one callback per frame. */\nexport function createRafCoalescer(onFrame: () => void): RafCoalescer {\n let rafId = 0;\n return {\n schedule() {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(() => {\n rafId = 0;\n onFrame();\n });\n },\n cancel() {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n },\n };\n}\n\nexport function readChromeTransitionSource(event: Event): ChromeTransitionSource | undefined {\n return (event as CustomEvent<ChromeTransitionDetail>).detail?.source;\n}\n\nexport function readChromeTransitionPhase(event: Event): ChromeTransitionDetail['phase'] {\n return (event as CustomEvent<ChromeTransitionDetail>).detail?.phase;\n}\n", "import { shellGradientPositionBar } from './shell-gradient';\n\n/** Read a `var(--token)` width in px using a hidden probe (works with calc() tokens). */\nexport function readCssVarWidthPx(context: HTMLElement, cssVarName: string): number {\n if (typeof document === 'undefined') return 0;\n\n const probe = document.createElement('div');\n probe.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;height:0;width:var(' +\n cssVarName +\n ');';\n context.appendChild(probe);\n const width = probe.getBoundingClientRect().width;\n context.removeChild(probe);\n return width;\n}\n\nexport interface PanelNavWidthTokens {\n expandedPx: number;\n collapsedPx: number;\n}\n\n/** Resolve panel-nav expanded/collapsed widths from scoped CSS vars on `.panel-nav`. */\nexport function readPanelNavWidthTokens(navRoot: HTMLElement): PanelNavWidthTokens {\n return {\n expandedPx: readCssVarWidthPx(navRoot, '--_nav-width'),\n collapsedPx: readCssVarWidthPx(navRoot, '--_nav-width-collapsed'),\n };\n}\n\nexport function isPanelNavCollapsed(\n panelNavHost: HTMLElement | null,\n navRoot: HTMLElement | null,\n): boolean {\n if (navRoot?.classList.contains('panel-nav--collapsed')) return true;\n const collapsedProp = (panelNavHost as (HTMLElement & { collapsed?: boolean }) | null)?.collapsed;\n return collapsedProp === true;\n}\n\nexport function panelWidthPxFromTokens(\n tokens: PanelNavWidthTokens,\n collapsed: boolean,\n): number {\n return collapsed ? tokens.collapsedPx : tokens.expandedPx;\n}\n\nexport function barGradientPositionFromPanelWidth(panelWidthPx: number): string {\n return shellGradientPositionBar(panelWidthPx);\n}\n", "import {\n SHELL_GRADIENT_POSITION_BAR_VAR,\n SHELL_GRADIENT_POSITION_PANEL_VAR,\n} from './shell-gradient';\n\n/** Per-badge background-position for shell gradient ring sampling. */\nexport const BADGE_GRADIENT_POSITION_VAR = '--_badge-gradient-position';\n\nexport interface GradientSurface {\n element: HTMLElement;\n chromeHost: HTMLElement;\n positionVar: string;\n}\n\n/** Whether the badge sits under `ds-app-shell[gradient]`. */\nexport function isShellGradientActive(from: HTMLElement): boolean {\n // Explicit <HTMLElement>: the inferred HTMLDsAppShellElement type only\n // resolves where @stencil/core types are installed \u2014 consumers importing\n // `@ds-mo/ui/nav` (raw TS) compile this without them.\n const shell = from.closest<HTMLElement>('ds-app-shell');\n return shell?.hasAttribute('gradient') === true;\n}\n\n/** Bar or panel chrome surface that owns the shell gradient stack. */\nexport function findGradientSurface(from: HTMLElement): GradientSurface | null {\n const barHost = from.closest('ds-bar-nav') as HTMLElement | null;\n if (barHost) {\n const root = barHost.shadowRoot ?? barHost;\n const element = root.querySelector('.bar-nav');\n if (element) {\n return {\n element: element as HTMLElement,\n chromeHost: barHost,\n positionVar: SHELL_GRADIENT_POSITION_BAR_VAR,\n };\n }\n }\n\n const panelHost = from.closest('ds-panel-nav') as HTMLElement | null;\n if (panelHost) {\n const root = panelHost.shadowRoot ?? panelHost;\n const element = root.querySelector('.panel-nav');\n if (element) {\n return {\n element: element as HTMLElement,\n chromeHost: panelHost,\n positionVar: SHELL_GRADIENT_POSITION_PANEL_VAR,\n };\n }\n }\n\n return null;\n}\n\ninterface ParsedPosition {\n x: number;\n y: number;\n}\n\n/** Parse a two-value CSS background-position (e.g. `-200px 0`). */\nexport function parseCssBackgroundPosition(value: string): ParsedPosition {\n const trimmed = value.trim();\n if (!trimmed) return { x: 0, y: 0 };\n\n const parts = trimmed.split(/\\s+/);\n const x = parseLength(parts[0] ?? '0');\n const y = parseLength(parts[1] ?? '0');\n return { x, y };\n}\n\nfunction parseLength(token: string): number {\n const px = token.match(/^(-?[\\d.]+)px$/);\n if (px) return Number(px[1]);\n return 0;\n}\n\n/**\n * Background position for a badge ring so the shell gradient aligns with nav chrome.\n * Uses badge center relative to the painted chrome surface.\n */\nexport function badgeGradientPosition(\n badgeHost: HTMLElement,\n surface: GradientSurface,\n shellPosition: string,\n): string {\n const badgeRect = badgeHost.getBoundingClientRect();\n const surfaceRect = surface.element.getBoundingClientRect();\n const anchorX = badgeRect.left + badgeRect.width / 2 - surfaceRect.left;\n const anchorY = badgeRect.top + badgeRect.height / 2 - surfaceRect.top;\n const { x, y } = parseCssBackgroundPosition(shellPosition);\n\n return `${Math.round(x - anchorX)}px ${Math.round(y - anchorY)}px`;\n}\n\n/** Resolve shell gradient position from chrome host custom properties. */\nexport function readShellGradientPosition(surface: GradientSurface): string {\n const styles = getComputedStyle(surface.chromeHost);\n return styles.getPropertyValue(surface.positionVar).trim() || '0 0';\n}\n\n/** Stamp `--_badge-gradient-position` on the badge host (fixed viewport chrome). */\nexport function syncBadgeGradientPosition(badgeHost: HTMLElement): void {\n if (!isShellGradientActive(badgeHost)) {\n badgeHost.style.removeProperty(BADGE_GRADIENT_POSITION_VAR);\n return;\n }\n\n badgeHost.style.setProperty(BADGE_GRADIENT_POSITION_VAR, '0 0');\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/** Nav chrome style slot \u2014 dashboard vs settings. Colors unified for now; texture hooks use the class. */\nexport type NavChromeStyle = 'dashboard' | 'settings';\n\n/** Document hint for first paint before framework props land. */\nexport const NAV_STYLE_HINT_ATTR = 'data-nav-style';\n\nexport function readNavStyleAttr(attr: string | null): NavChromeStyle | undefined {\n if (attr === 'dashboard' || attr === 'settings') return attr;\n return undefined;\n}\n\nexport function setNavStyleHint(style: NavChromeStyle): void {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute(NAV_STYLE_HINT_ATTR, style);\n}\n\nexport function clearNavStyleHint(): void {\n if (typeof document === 'undefined') return;\n document.documentElement.removeAttribute(NAV_STYLE_HINT_ATTR);\n}\n\nexport function resolveNavChromeStyle(\n styleProp: NavChromeStyle,\n hostAttr: string | null,\n docHint?: string | null,\n): NavChromeStyle {\n const fromHost = readNavStyleAttr(hostAttr);\n if (fromHost) return fromHost;\n\n const hint =\n docHint !== undefined\n ? docHint\n : typeof document !== 'undefined'\n ? document.documentElement.getAttribute(NAV_STYLE_HINT_ATTR)\n : null;\n const fromHint = readNavStyleAttr(hint);\n if (fromHint) return fromHint;\n\n return styleProp;\n}\n\nexport function shouldResyncNavChromeStyle(\n renderedStyle: NavChromeStyle,\n style: NavChromeStyle,\n): boolean {\n return renderedStyle !== style;\n}\n", "/** Parse a CSS <time> value (or motion shorthand's first token) to milliseconds. */\nexport function parseCssTimeMs(value: string, fallback: number): number {\n const firstToken = value.trim().split(/\\s+/)[0] ?? '';\n const num = parseFloat(firstToken);\n if (Number.isNaN(num)) return fallback;\n if (/ms\\s*$/.test(firstToken)) return num;\n if (/s\\s*$/.test(firstToken)) return num * 1000;\n return num;\n}\n\nfunction extractCssCustomProp(ref: string): string | null {\n const varMatch = ref.match(/^var\\(\\s*(--[^),]+)/);\n if (varMatch) return varMatch[1].trim();\n if (ref.startsWith('--')) return ref.trim();\n return null;\n}\n\nfunction readTokenTimeMs(token: string, fallback: number): number {\n if (typeof document === 'undefined') return fallback;\n\n const prop = extractCssCustomProp(token);\n if (!prop) return parseCssTimeMs(token, fallback);\n\n const raw = getComputedStyle(document.documentElement).getPropertyValue(prop).trim();\n return parseCssTimeMs(raw, fallback);\n}\n\n/**\n * Resolve a duration to milliseconds for JS timers aligned with CSS motion tokens.\n * Accepts numbers (ms), raw times (`200ms`, `0.75s`), or `var(--effect-*)` references.\n */\nexport function resolveCssTimeMs(\n value: number | string | undefined,\n fallbackToken: string,\n): number {\n if (typeof value === 'number') return value;\n\n const token = typeof value === 'string' && value.trim() ? value.trim() : fallbackToken;\n const prop = extractCssCustomProp(token);\n\n if (prop) {\n return readTokenTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n }\n\n return parseCssTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n}\n", "import { parseCssTimeMs } from '../utils/resolve-css-time-ms';\n\n/** `view-transition-name` on `ds-bar-nav` \u2014 pairs with root reveal in shell apps. */\nexport const SHELL_BAR_NAV_VT_NAME = 'ds-shell-bar-nav';\n\nexport { parseCssTimeMs };\n\nconst VT_STYLE_ID = 'ds-shell-nav-vt-style';\n\n/** TokoMo tokens for the dashboard \u2194 settings radial reveal (WAAPI). */\nexport const SHELL_NAV_REVEAL_DURATION_VAR = '--effect-animation-duration-medium-3';\nexport const SHELL_NAV_REVEAL_EASING_VAR = '--effect-animation-easing-ease-in-out';\nconst SHELL_NAV_REVEAL_DURATION_FALLBACK_MS = 500;\nconst SHELL_NAV_REVEAL_EASING_FALLBACK = 'ease-in-out';\n\nfunction readCssCustomProperty(name: string, fallback: string): string {\n if (typeof document === 'undefined') return fallback;\n const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();\n return value || fallback;\n}\n\n/** Suppress default cross-fade and pin new snapshots to a 0px circle for WAAPI reveal. */\nexport function ensureShellNavVtStyle(): void {\n if (typeof document === 'undefined') return;\n\n const content = [\n '::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}',\n `::view-transition-old(${SHELL_BAR_NAV_VT_NAME}),::view-transition-new(${SHELL_BAR_NAV_VT_NAME}){animation:none;mix-blend-mode:normal}`,\n `::view-transition-old(${SHELL_BAR_NAV_VT_NAME}){z-index:1}`,\n `::view-transition-new(${SHELL_BAR_NAV_VT_NAME}){z-index:2;clip-path:circle(0px at var(--vt-x,50%) var(--vt-y,50%))}`,\n '::view-transition-new(root){clip-path:circle(0px at var(--vt-x,50%) var(--vt-y,50%))}',\n ].join('\\n');\n\n const existing = document.getElementById(VT_STYLE_ID) as HTMLStyleElement | null;\n if (existing) {\n if (existing.textContent !== content) existing.textContent = content;\n return;\n }\n\n const style = document.createElement('style');\n style.id = VT_STYLE_ID;\n style.textContent = content;\n document.head.appendChild(style);\n}\n\nexport interface ShellNavRevealOrigin {\n x: number;\n y: number;\n maxRadius: number;\n}\n\n/** Origin for the radial reveal \u2014 defaults to panel-nav footer gear, then viewport center. */\nexport function resolveShellNavRevealOrigin(originEl?: HTMLElement | null): ShellNavRevealOrigin {\n const btn =\n originEl ??\n document.querySelector<HTMLElement>('.panel-nav__footer-btn');\n const rect = btn?.getBoundingClientRect();\n const x = rect ? Math.round(rect.left + rect.width / 2) : Math.round(window.innerWidth / 2);\n const y = rect ? Math.round(rect.top + rect.height / 2) : Math.round(window.innerHeight / 2);\n const maxRadius = Math.ceil(\n Math.hypot(Math.max(x, window.innerWidth - x), Math.max(y, window.innerHeight - y)),\n );\n return { x, y, maxRadius };\n}\n\nexport function setShellNavRevealOriginVars(origin: ShellNavRevealOrigin): void {\n document.documentElement.style.setProperty('--vt-x', `${origin.x}px`);\n document.documentElement.style.setProperty('--vt-y', `${origin.y}px`);\n}\n\n/** Animate root + bar-nav snapshots with the same radial clip-path reveal. */\nexport function animateShellNavRadialReveal(\n origin: ShellNavRevealOrigin,\n durationMs?: number,\n): void {\n const duration =\n durationMs ??\n parseCssTimeMs(\n readCssCustomProperty(SHELL_NAV_REVEAL_DURATION_VAR, '400ms'),\n SHELL_NAV_REVEAL_DURATION_FALLBACK_MS,\n );\n const easing = readCssCustomProperty(\n SHELL_NAV_REVEAL_EASING_VAR,\n SHELL_NAV_REVEAL_EASING_FALLBACK,\n );\n const keyframes = {\n clipPath: [\n `circle(0px at ${origin.x}px ${origin.y}px)`,\n `circle(${origin.maxRadius}px at ${origin.x}px ${origin.y}px)`,\n ],\n };\n const options = {\n duration,\n easing,\n fill: 'forwards' as const,\n };\n\n document.documentElement.animate(keyframes, {\n ...options,\n pseudoElement: '::view-transition-new(root)',\n });\n document.documentElement.animate(keyframes, {\n ...options,\n pseudoElement: `::view-transition-new(${SHELL_BAR_NAV_VT_NAME})`,\n });\n}\n\n/** Run radial reveal when a view transition's `ready` promise settles (app/router driver). */\nexport function runShellNavStyleRevealOnReady(\n transition: { ready: Promise<void> },\n originEl?: HTMLElement | null,\n): void {\n ensureShellNavVtStyle();\n const origin = resolveShellNavRevealOrigin(originEl);\n setShellNavRevealOriginVars(origin);\n\n transition.ready\n .then(() => animateShellNavRadialReveal(origin))\n .catch(() => {\n /* transition skipped or superseded */\n });\n}\n", "/** Built-in shell chrome wash presets \u2014 none (solid secondary), cool, neutral, warm. */\nexport type ShellGradientPreset = 'none' | 'cool' | 'neutral' | 'warm';\n\nexport const SHELL_GRADIENT_PRESETS: ShellGradientPreset[] = ['none', 'cool', 'neutral', 'warm'];\n\n/** Wash presets shown after the `none` option in pickers. */\nexport const SHELL_GRADIENT_WASH_PRESETS: Exclude<ShellGradientPreset, 'none'>[] = [\n 'cool',\n 'neutral',\n 'warm',\n];\n\n/** Default wash when `gradient-preset` is omitted. */\nexport const DEFAULT_SHELL_GRADIENT_PRESET: ShellGradientPreset = 'neutral';\n\nexport const SHELL_GRADIENT_PRESET_LABELS: Record<ShellGradientPreset, string> = {\n none: 'None',\n cool: 'Cool',\n neutral: 'Neutral',\n warm: 'Warm',\n};\n\nconst SHELL_GRADIENT_PRESET_STOP: Record<Exclude<ShellGradientPreset, 'none'>, string> = {\n cool: 'var(--color-color-intent-blue-strong-background)',\n neutral: 'var(--color-color-intent-grey-strong-background)',\n warm: 'var(--color-color-intent-yellow-strong-background)',\n};\n\nconst GRADIENT_GEOMETRY = '100% 100% at 0% 0%';\n\nexport function shellGradientPresetStopToken(preset: ShellGradientPreset): string | null {\n if (preset === 'none') return null;\n return SHELL_GRADIENT_PRESET_STOP[preset];\n}\n\nexport function isShellGradientPreset(value: string): value is ShellGradientPreset {\n return (SHELL_GRADIENT_PRESETS as string[]).includes(value);\n}\n\n/**\n * Coerce unknown/absent presets to the default. Runtime values escape the\n * type: removing the reflected `gradient-preset` attribute (e.g. an Angular\n * `[attr.gradient-preset]=\"null\"` binding) drives the prop to null past its\n * field default \u2014 without normalization the stop lookup interpolates the\n * literal string \"undefined\" into CSS and the wash silently disappears.\n */\nexport function normalizeShellGradientPreset(\n value: string | null | undefined,\n): ShellGradientPreset {\n return value != null && isShellGradientPreset(value) ? value : DEFAULT_SHELL_GRADIENT_PRESET;\n}\n\n/** Radial wash for a preset \u2014 transparent at top-left into the intent stop. `none` returns no image. */\nexport function buildShellRadialGradientForPreset(preset: ShellGradientPreset): string {\n const normalized = normalizeShellGradientPreset(preset);\n if (normalized === 'none') return 'none';\n\n const stop = shellGradientPresetStopToken(normalized);\n return `radial-gradient(${GRADIENT_GEOMETRY}, var(--color-background-transparent) 0%, ${stop} 100%)`;\n}\n", "/** CSS var names consumed by `ds-panel-nav` / `ds-bar-nav` inside `ds-app-shell`. */\nimport type { ShellGradientPreset } from './shell-gradient-presets';\nimport {\n DEFAULT_SHELL_GRADIENT_PRESET,\n buildShellRadialGradientForPreset,\n} from './shell-gradient-presets';\n\nexport type { ShellGradientPreset } from './shell-gradient-presets';\nexport {\n DEFAULT_SHELL_GRADIENT_PRESET,\n SHELL_GRADIENT_PRESETS,\n SHELL_GRADIENT_PRESET_LABELS,\n buildShellRadialGradientForPreset,\n isShellGradientPreset,\n shellGradientPresetStopToken,\n} from './shell-gradient-presets';\n\nexport const SHELL_GRADIENT_IMAGE_VAR = '--ds-shell-gradient-image';\nexport const SHELL_GRADIENT_SIZE_VAR = '--ds-shell-gradient-size';\nexport const SHELL_GRADIENT_POSITION_PANEL_VAR = '--ds-shell-gradient-position-panel';\nexport const SHELL_GRADIENT_POSITION_BAR_VAR = '--ds-shell-gradient-position-bar';\nexport const SHELL_GRADIENT_OPACITY_VAR = '--ds-shell-gradient-opacity';\n/** Per chrome-surface background-position \u2014 offsets wash + grid to shell row origin. */\nexport const SHELL_CHROME_SURFACE_POSITION_VAR = '--ds-shell-chrome-surface-position';\n\n/** Layer opacity for the nav gradient wash. */\nexport const SHELL_GRADIENT_OPACITY = '0.1';\n\n/** Whether the shared chrome layer (secondary bg + optional wash) should mount. */\nexport function shellChromeLayerActive(gradient: boolean): boolean {\n return gradient;\n}\n\n/**\n * Shell radial wash \u2014 same for panel and bar nav.\n * Tokens follow `data-theme` (light/dark intent stops).\n */\nexport function buildShellRadialGradient(\n preset: ShellGradientPreset = DEFAULT_SHELL_GRADIENT_PRESET,\n): string {\n return buildShellRadialGradientForPreset(preset);\n}\n\n/** Built-in radial image (`gradientSrc` on shell overrides). */\nexport function shellGradientImage(\n preset: ShellGradientPreset = DEFAULT_SHELL_GRADIENT_PRESET,\n): string {\n return buildShellRadialGradient(preset);\n}\n\nexport interface ShellViewportDimensions {\n width: number;\n height: number;\n}\n\n/**\n * Viewport size for shell chrome with `background-attachment: fixed`.\n * Must not use the `ds-app-shell` element box \u2014 the shell can be shorter or\n * taller than the viewport when host height chains break or content overflows.\n */\nexport function readShellViewportDimensions(win?: Window): ShellViewportDimensions {\n const w = win ?? (typeof globalThis.window !== 'undefined' ? globalThis.window : undefined);\n if (!w) return { width: 0, height: 0 };\n\n const visual = w.visualViewport;\n return {\n width: Math.round(visual?.width ?? w.innerWidth),\n height: Math.round(visual?.height ?? w.innerHeight),\n };\n}\n\nexport interface ShellGradientLayout {\n width: number;\n height: number;\n panelWidth: number;\n}\n\n/** Pixel `background-size` for the fixed-attachment radial wash. */\nexport function shellGradientSize(layout: Pick<ShellGradientLayout, 'width' | 'height'>): string {\n return `${Math.round(layout.width)}px ${Math.round(layout.height)}px`;\n}\n\nexport function shellGradientPositionPanel(): string {\n return '0 0';\n}\n\nexport function shellGradientPositionBar(panelWidth: number): string {\n return `${-Math.round(panelWidth)}px 0`;\n}\n\n/** Phase-lock a chrome rect to the shell row coordinate system (wash + grid). */\nexport function shellChromeSurfacePosition(leftPx: number, topPx: number): string {\n return `${-Math.round(leftPx)}px ${-Math.round(topPx)}px`;\n}\n", "import {\n dimensionIconographyMd,\n dimensionIconographySm,\n dimensionIconographyXs,\n dimensionMenuWidthXs,\n dimensionPanelWidth2xs,\n dimensionPanelWidthLg,\n dimensionPanelWidthMd,\n dimensionRadius025,\n dimensionSize200,\n dimensionSize300,\n dimensionSize400,\n dimensionSize600,\n dimensionSize800,\n dimensionSpace050,\n dimensionSpace200,\n typographyLineheightLg,\n typographyLineheightMd,\n typographyLineheightSm,\n typographyLineheightXl,\n typographyLineheightXs,\n effectAnimationDelayLong2,\n effectAnimationDelayMedium1,\n effectAnimationDelayMedium3,\n effectAnimationDelayInstant,\n effectAnimationDelayShort2,\n effectAnimationDurationMedium1,\n effectAnimationDurationShort3,\n effectMotionShort2,\n effectMotionShort3,\n} from '@ds-mo/tokens/ts';\n\n/** TokoMo CSS custom-property names for shared component defaults (runtime resolution). */\nexport const TOKEN_DEFAULTS = {\n space050: dimensionSpace050,\n space200: dimensionSpace200,\n radius025: dimensionRadius025,\n size200: dimensionSize200,\n size300: dimensionSize300,\n size400: dimensionSize400,\n size600: dimensionSize600,\n size800: dimensionSize800,\n iconographyMd: dimensionIconographyMd,\n iconographySm: dimensionIconographySm,\n iconographyXs: dimensionIconographyXs,\n panelWidth2xs: dimensionPanelWidth2xs,\n panelWidthMd: dimensionPanelWidthMd,\n panelWidthLg: dimensionPanelWidthLg,\n menuWidthXs: dimensionMenuWidthXs,\n lineheightLg: typographyLineheightLg,\n lineheightMd: typographyLineheightMd,\n lineheightSm: typographyLineheightSm,\n lineheightXl: typographyLineheightXl,\n lineheightXs: typographyLineheightXs,\n motionShort2: effectMotionShort2,\n motionShort3: effectMotionShort3,\n animationDurationShort3: effectAnimationDurationShort3,\n animationDurationMedium1: effectAnimationDurationMedium1,\n animationDelayInstant: effectAnimationDelayInstant,\n animationDelayMedium1: effectAnimationDelayMedium1,\n animationDelayMedium3: effectAnimationDelayMedium3,\n animationDelayShort2: effectAnimationDelayShort2,\n animationDelayLong2: effectAnimationDelayLong2,\n /** Unmeasured menu height fallback: 20\u00D7 base (160px at default scale). */\n menuFallbackHeight: 'calc(var(--dimension-size-base) * 20)',\n /** Unmeasured tooltip width fallback: size-800 + size-200 (80px). */\n tooltipFallbackWidth: 'calc(var(--dimension-size-800) + var(--dimension-size-200))',\n /** Fill-mode donut diameter floor: 16\u00D7 size-base (128px). */\n donutFillMin: 'calc(var(--dimension-size-base) * 16)',\n /** Fill-mode donut diameter ceiling: 24\u00D7 size-base (192px). */\n donutFillMax: 'calc(var(--dimension-size-base) * 24)',\n} as const;\n\nexport type TokenDefaultKey = keyof typeof TOKEN_DEFAULTS;\n\n/** Valid CSS length strings for overlay offset props \u2014 bind on `sideOffset` / `alignOffset` in hosts. */\nexport const TOKEN_CSS_LENGTHS = {\n space050: `var(${dimensionSpace050})`,\n space200: `var(${dimensionSpace200})`,\n menuWidthXs: `var(${dimensionMenuWidthXs})`,\n} as const;\n", "import { TOKEN_CSS_LENGTHS } from '../../utils/token-defaults';\nimport type { MenuAlign, MenuSide } from './menu-position';\n\n/** Placement props bindable on `ds-menu` (side, align, offsets). */\nexport interface MenuPlacement {\n side: MenuSide;\n align: MenuAlign;\n sideOffset: number | string;\n alignOffset: number | string;\n}\n\n/**\n * Canonical `ds-menu` placement for the **panel-nav footer user menu**.\n * Anchor from `dsNavUserAction` detail `{ anchor }` (id `ds-panel-nav-user-menu-anchor`).\n *\n * Not for BarNav overflow menus \u2014 those use `side=\"bottom\"` / `align=\"end\"` internally.\n * `align: 'end'` bottom-aligns on the anchor; offsets nudge into the content area:\n * - `sideOffset` space-100 + space-050 (12px): 4px past the panel-nav outer edge (anchor is ~8px inset).\n * - `alignOffset` space-050 (4px): 4px below the footer user row.\n */\nexport const PANEL_NAV_USER_MENU_PLACEMENT = {\n side: 'right',\n align: 'end',\n sideOffset: 'calc(var(--dimension-space-100) + var(--dimension-space-050))',\n alignOffset: TOKEN_CSS_LENGTHS.space050,\n} as const satisfies MenuPlacement;\n", "/** Bubbling/composed events \u2014 `ds-app-shell` and `ds-bar-nav` coordinate during width motion. */\n\nexport const CHROME_TRANSITION_START = 'dsChromeTransitionStart';\nexport const CHROME_TRANSITION_END = 'dsChromeTransitionEnd';\n\nexport type ChromeTransitionSource = 'panel-nav' | 'panel-tools';\n\nexport interface ChromeTransitionDetail {\n source: ChromeTransitionSource;\n /** Panel-tools drawer motion direction; omitted for panel-nav. */\n phase?: 'opening' | 'closing';\n}\n\n/** Reference-counted gate \u2014 used while panel-nav width is transitioning. */\nexport class ChromeTransitionDepth {\n private depth = 0;\n\n enter(): void {\n this.depth += 1;\n }\n\n exit(): void {\n this.depth = Math.max(0, this.depth - 1);\n }\n\n get isActive(): boolean {\n return this.depth > 0;\n }\n}\n\nexport interface RafCoalescer {\n schedule(): void;\n cancel(): void;\n}\n\n/** Coalesce bursty layout work (ResizeObserver, prop churn) to one callback per frame. */\nexport function createRafCoalescer(onFrame: () => void): RafCoalescer {\n let rafId = 0;\n return {\n schedule() {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(() => {\n rafId = 0;\n onFrame();\n });\n },\n cancel() {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n },\n };\n}\n\nexport function readChromeTransitionSource(event: Event): ChromeTransitionSource | undefined {\n return (event as CustomEvent<ChromeTransitionDetail>).detail?.source;\n}\n\nexport function readChromeTransitionPhase(event: Event): ChromeTransitionDetail['phase'] {\n return (event as CustomEvent<ChromeTransitionDetail>).detail?.phase;\n}\n", "import { shellGradientPositionBar } from './shell-gradient';\n\n/** Read a `var(--token)` width in px using a hidden probe (works with calc() tokens). */\nexport function readCssVarWidthPx(context: HTMLElement, cssVarName: string): number {\n if (typeof document === 'undefined') return 0;\n\n const probe = document.createElement('div');\n probe.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;height:0;width:var(' +\n cssVarName +\n ');';\n context.appendChild(probe);\n const width = probe.getBoundingClientRect().width;\n context.removeChild(probe);\n return width;\n}\n\nexport interface PanelNavWidthTokens {\n expandedPx: number;\n collapsedPx: number;\n}\n\n/** Resolve panel-nav expanded/collapsed widths from scoped CSS vars on `.panel-nav`. */\nexport function readPanelNavWidthTokens(navRoot: HTMLElement): PanelNavWidthTokens {\n return {\n expandedPx: readCssVarWidthPx(navRoot, '--_nav-width'),\n collapsedPx: readCssVarWidthPx(navRoot, '--_nav-width-collapsed'),\n };\n}\n\nexport function isPanelNavCollapsed(\n panelNavHost: HTMLElement | null,\n navRoot: HTMLElement | null,\n): boolean {\n if (navRoot?.classList.contains('panel-nav--collapsed')) return true;\n const collapsedProp = (panelNavHost as (HTMLElement & { collapsed?: boolean }) | null)?.collapsed;\n return collapsedProp === true;\n}\n\nexport function panelWidthPxFromTokens(\n tokens: PanelNavWidthTokens,\n collapsed: boolean,\n): number {\n return collapsed ? tokens.collapsedPx : tokens.expandedPx;\n}\n\nexport function barGradientPositionFromPanelWidth(panelWidthPx: number): string {\n return shellGradientPositionBar(panelWidthPx);\n}\n", "import {\n SHELL_GRADIENT_POSITION_BAR_VAR,\n SHELL_GRADIENT_POSITION_PANEL_VAR,\n} from './shell-gradient';\n\n/** Per-badge background-position for shell gradient ring sampling. */\nexport const BADGE_GRADIENT_POSITION_VAR = '--_badge-gradient-position';\n\nexport interface GradientSurface {\n element: HTMLElement;\n chromeHost: HTMLElement;\n positionVar: string;\n}\n\n/** Whether the badge sits under `ds-app-shell[gradient]`. */\nexport function isShellGradientActive(from: HTMLElement): boolean {\n // Explicit <HTMLElement>: the inferred HTMLDsAppShellElement type only\n // resolves where @stencil/core types are installed \u2014 consumers importing\n // `@ds-mo/ui/nav` (raw TS) compile this without them.\n const shell = from.closest<HTMLElement>('ds-app-shell');\n return shell?.hasAttribute('gradient') === true;\n}\n\n/** Bar or panel chrome surface that owns the shell gradient stack. */\nexport function findGradientSurface(from: HTMLElement): GradientSurface | null {\n const barHost = from.closest('ds-bar-nav') as HTMLElement | null;\n if (barHost) {\n const root = barHost.shadowRoot ?? barHost;\n const element = root.querySelector('.bar-nav');\n if (element) {\n return {\n element: element as HTMLElement,\n chromeHost: barHost,\n positionVar: SHELL_GRADIENT_POSITION_BAR_VAR,\n };\n }\n }\n\n const panelHost = from.closest('ds-panel-nav') as HTMLElement | null;\n if (panelHost) {\n const root = panelHost.shadowRoot ?? panelHost;\n const element = root.querySelector('.panel-nav');\n if (element) {\n return {\n element: element as HTMLElement,\n chromeHost: panelHost,\n positionVar: SHELL_GRADIENT_POSITION_PANEL_VAR,\n };\n }\n }\n\n return null;\n}\n\ninterface ParsedPosition {\n x: number;\n y: number;\n}\n\n/** Parse a two-value CSS background-position (e.g. `-200px 0`). */\nexport function parseCssBackgroundPosition(value: string): ParsedPosition {\n const trimmed = value.trim();\n if (!trimmed) return { x: 0, y: 0 };\n\n const parts = trimmed.split(/\\s+/);\n const x = parseLength(parts[0] ?? '0');\n const y = parseLength(parts[1] ?? '0');\n return { x, y };\n}\n\nfunction parseLength(token: string): number {\n const px = token.match(/^(-?[\\d.]+)px$/);\n if (px) return Number(px[1]);\n return 0;\n}\n\n/**\n * Background position for a badge ring so the shell gradient aligns with nav chrome.\n * Uses badge center relative to the painted chrome surface.\n */\nexport function badgeGradientPosition(\n badgeHost: HTMLElement,\n surface: GradientSurface,\n shellPosition: string,\n): string {\n const badgeRect = badgeHost.getBoundingClientRect();\n const surfaceRect = surface.element.getBoundingClientRect();\n const anchorX = badgeRect.left + badgeRect.width / 2 - surfaceRect.left;\n const anchorY = badgeRect.top + badgeRect.height / 2 - surfaceRect.top;\n const { x, y } = parseCssBackgroundPosition(shellPosition);\n\n return `${Math.round(x - anchorX)}px ${Math.round(y - anchorY)}px`;\n}\n\n/** Resolve shell gradient position from chrome host custom properties. */\nexport function readShellGradientPosition(surface: GradientSurface): string {\n const styles = getComputedStyle(surface.chromeHost);\n return styles.getPropertyValue(surface.positionVar).trim() || '0 0';\n}\n\n/** Stamp `--_badge-gradient-position` on the badge host (fixed viewport chrome). */\nexport function syncBadgeGradientPosition(badgeHost: HTMLElement): void {\n if (!isShellGradientActive(badgeHost)) {\n badgeHost.style.removeProperty(BADGE_GRADIENT_POSITION_VAR);\n return;\n }\n\n badgeHost.style.setProperty(BADGE_GRADIENT_POSITION_VAR, '0 0');\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,3 +7,5 @@ export { SCROLL_EDGE_FADE_DEFAULT_SIZE, SCROLL_EDGE_FADE_SIZE_VAR, isScrollAtEdg
|
|
|
7
7
|
export type { ScrollEdgeFadeEdge, ScrollEdgeFadeOptions, ScrollEdgeFadeSize, ScrollEdgeFadeSizeToken, } from './scroll-edge-fade';
|
|
8
8
|
export { TOKEN_DEFAULTS, TOKEN_CSS_LENGTHS } from './token-defaults';
|
|
9
9
|
export type { TokenDefaultKey } from './token-defaults';
|
|
10
|
+
export { controlWidthClass } from './control-width';
|
|
11
|
+
export type { ControlWidth } from './control-width';
|
package/dist/lib/utils/index.js
CHANGED
|
@@ -282,19 +282,32 @@ var TOKEN_DEFAULTS = {
|
|
|
282
282
|
/** Unmeasured menu height fallback: 20× base (160px at default scale). */
|
|
283
283
|
menuFallbackHeight: "calc(var(--dimension-size-base) * 20)",
|
|
284
284
|
/** Unmeasured tooltip width fallback: size-800 + size-200 (80px). */
|
|
285
|
-
tooltipFallbackWidth: "calc(var(--dimension-size-800) + var(--dimension-size-200))"
|
|
285
|
+
tooltipFallbackWidth: "calc(var(--dimension-size-800) + var(--dimension-size-200))",
|
|
286
|
+
/** Fill-mode donut diameter floor: 16× size-base (128px). */
|
|
287
|
+
donutFillMin: "calc(var(--dimension-size-base) * 16)",
|
|
288
|
+
/** Fill-mode donut diameter ceiling: 24× size-base (192px). */
|
|
289
|
+
donutFillMax: "calc(var(--dimension-size-base) * 24)"
|
|
286
290
|
};
|
|
287
291
|
var TOKEN_CSS_LENGTHS = {
|
|
288
292
|
space050: `var(${dimensionSpace050})`,
|
|
289
293
|
space200: `var(${dimensionSpace200})`,
|
|
290
294
|
menuWidthXs: `var(${dimensionMenuWidthXs})`
|
|
291
295
|
};
|
|
296
|
+
|
|
297
|
+
// src/wc/utils/control-width.ts
|
|
298
|
+
function controlWidthClass(width) {
|
|
299
|
+
return {
|
|
300
|
+
"ds-control-width--hug": width === "hug",
|
|
301
|
+
"ds-control-width--fill": width === "fill"
|
|
302
|
+
};
|
|
303
|
+
}
|
|
292
304
|
export {
|
|
293
305
|
SCROLL_EDGE_FADE_DEFAULT_SIZE,
|
|
294
306
|
SCROLL_EDGE_FADE_SIZE_VAR,
|
|
295
307
|
TOKEN_CSS_LENGTHS,
|
|
296
308
|
TOKEN_DEFAULTS,
|
|
297
309
|
clearCssLengthPxCache,
|
|
310
|
+
controlWidthClass,
|
|
298
311
|
formatCompactNumber,
|
|
299
312
|
isScrollAtEdge,
|
|
300
313
|
parseCssTimeMs,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/wc/components/Icon/icon-cache.ts", "../../../src/wc/utils/resolve-css-length-px.ts", "../../../src/wc/utils/format-compact-number.ts", "../../../src/wc/utils/truncate-svg-text.ts", "../../../src/wc/utils/resolve-css-time-ms.ts", "../../../src/wc/utils/scroll-edge-fade.ts", "../../../src/wc/utils/token-defaults.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Shared SVG glyph cache for ds-icon.\n *\n * Keyed on a global symbol so every module instance (the compiled Stencil chunk\n * inside dist/components and any direct source import, e.g. via `@ds-mo/ui/utils`)\n * reads and writes the same cache. Without this, `registerIcons` called from an\n * app would fill a different Map than the one ds-icon resolves from.\n */\nconst CACHE_KEY = Symbol.for('ds-mo.icon-svg-cache');\n\ntype IconCacheMap = Map<string, string>;\n\ntype GlobalWithIconCache = { [CACHE_KEY]?: IconCacheMap };\n\nexport function iconCacheKey(name: string, flag: boolean): string {\n return flag ? `flag:${name}` : `system:${name}`;\n}\n\nexport function iconCache(): IconCacheMap {\n const g = globalThis as GlobalWithIconCache;\n return (g[CACHE_KEY] ??= new Map());\n}\n\n/**\n * Pre-register glyphs so ds-icon renders them synchronously \u2014 no lazy-chunk\n * fetch, no first-paint pop-in. Import the SVG strings from `@ds-mo/icons`\n * in the app (statically, so they ship in the app's own bundle):\n *\n * ```ts\n * import { Bell } from '@ds-mo/icons/svg/Bell';\n * import { US } from '@ds-mo/icons/svg/flags/US';\n * import { registerIcons } from '@ds-mo/ui/utils';\n *\n * registerIcons({ Bell });\n * registerIcons({ US }, { flag: true });\n * ```\n *\n * Icons that are not registered still work \u2014 they lazy-load on first render\n * and stay cached afterwards.\n */\nexport function registerIcons(icons: Record<string, string>, options?: { flag?: boolean }): void {\n const cache = iconCache();\n const flag = options?.flag === true;\n for (const [name, svg] of Object.entries(icons)) {\n cache.set(iconCacheKey(name, flag), svg);\n }\n}\n", "const lengthPxCache = new Map<string, number>();\n\nlet probeEl: HTMLElement | null = null;\n\nfunction getProbeElement(): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n\n if (!probeEl) {\n probeEl = document.createElement('div');\n probeEl.setAttribute('aria-hidden', 'true');\n probeEl.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;top:0;left:0;width:0;height:0;overflow:hidden;';\n document.documentElement.appendChild(probeEl);\n }\n\n return probeEl;\n}\n\n/** Clear session cache (tests only). */\nexport function clearCssLengthPxCache(): void {\n lengthPxCache.clear();\n}\n\n/**\n * Resolve a CSS length to pixels for layout math.\n * Numbers pass through; `var(--dimension-*)`, `calc(...)`, and `16px` resolve via a hidden probe.\n */\nexport function resolveCssLengthPx(\n value: number | string | undefined,\n fallback: number | string,\n): number {\n const resolved = value === undefined || value === null || value === '' ? fallback : value;\n if (typeof resolved === 'number') return resolved;\n\n const trimmed = resolved.trim();\n if (!trimmed) return resolveCssLengthPx(fallback, 0);\n\n const cached = lengthPxCache.get(trimmed);\n if (cached !== undefined) return cached;\n\n if (/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n const n = Number(trimmed);\n lengthPxCache.set(trimmed, n);\n return n;\n }\n\n const pxMatch = trimmed.match(/^(-?\\d+(\\.\\d+)?)px$/);\n if (pxMatch) {\n const px = parseFloat(pxMatch[1]);\n lengthPxCache.set(trimmed, px);\n return px;\n }\n\n const cssLength = /^--[\\w-]+$/.test(trimmed) ? `var(${trimmed})` : trimmed;\n\n const probe = getProbeElement();\n if (!probe) {\n return typeof fallback === 'number' ? fallback : 0;\n }\n\n probe.style.width = cssLength;\n const px = probe.getBoundingClientRect().width;\n probe.style.width = '';\n lengthPxCache.set(trimmed, px);\n return px;\n}\n", "const COMPACT_UNITS: { threshold: number; suffix: string }[] = [\n { threshold: 1_000_000_000, suffix: 'b' },\n { threshold: 1_000_000, suffix: 'm' },\n { threshold: 1_000, suffix: 'k' },\n];\n\n/** Compact large numbers for display: 1000 -> \"1k\", 1500 -> \"1.5k\", 110100 -> \"110.1k\", 1000000 -> \"1m\". */\nexport function formatCompactNumber(value: number): string {\n const sign = value < 0 ? '-' : '';\n const abs = Math.abs(value);\n if (abs < 1000) return String(value);\n\n for (let i = 0; i < COMPACT_UNITS.length; i++) {\n const unit = COMPACT_UNITS[i];\n if (abs < unit.threshold) continue;\n\n let scaled = Math.round((abs / unit.threshold) * 10) / 10;\n // Carry over, e.g. 999.96k rounds to \"1000k\" \u2014 bump to the next unit instead.\n if (scaled >= 1000 && i > 0) {\n const next = COMPACT_UNITS[i - 1];\n scaled = Math.round((abs / next.threshold) * 10) / 10;\n return `${sign}${scaled}${next.suffix}`;\n }\n return `${sign}${scaled}${unit.suffix}`;\n }\n return String(value);\n}\n", "/**\n * Binary-searches the longest prefix of `text` (plus an ellipsis) that fits within `maxWidth`\n * px when rendered by `el`, using the SVG `getComputedTextLength()` API for exact measurement \u2014\n * `text-overflow: ellipsis` doesn't apply to raw SVG `<text>` nodes.\n *\n * Mutates `el.textContent` during measurement; the caller's next render (driven by the\n * returned string going into state) overwrites it with the final value.\n */\nexport function truncateSvgTextToWidth(el: SVGTextElement, text: string, maxWidth: number): string {\n el.textContent = text;\n if (maxWidth <= 0 || el.getComputedTextLength() <= maxWidth) return text;\n\n let lo = 0;\n let hi = text.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n el.textContent = `${text.slice(0, mid)}\u2026`;\n if (el.getComputedTextLength() <= maxWidth) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return lo > 0 ? `${text.slice(0, lo)}\u2026` : '\u2026';\n}\n", "/** Parse a CSS <time> value (or motion shorthand's first token) to milliseconds. */\nexport function parseCssTimeMs(value: string, fallback: number): number {\n const firstToken = value.trim().split(/\\s+/)[0] ?? '';\n const num = parseFloat(firstToken);\n if (Number.isNaN(num)) return fallback;\n if (/ms\\s*$/.test(firstToken)) return num;\n if (/s\\s*$/.test(firstToken)) return num * 1000;\n return num;\n}\n\nfunction extractCssCustomProp(ref: string): string | null {\n const varMatch = ref.match(/^var\\(\\s*(--[^),]+)/);\n if (varMatch) return varMatch[1].trim();\n if (ref.startsWith('--')) return ref.trim();\n return null;\n}\n\nfunction readTokenTimeMs(token: string, fallback: number): number {\n if (typeof document === 'undefined') return fallback;\n\n const prop = extractCssCustomProp(token);\n if (!prop) return parseCssTimeMs(token, fallback);\n\n const raw = getComputedStyle(document.documentElement).getPropertyValue(prop).trim();\n return parseCssTimeMs(raw, fallback);\n}\n\n/**\n * Resolve a duration to milliseconds for JS timers aligned with CSS motion tokens.\n * Accepts numbers (ms), raw times (`200ms`, `0.75s`), or `var(--effect-*)` references.\n */\nexport function resolveCssTimeMs(\n value: number | string | undefined,\n fallbackToken: string,\n): number {\n if (typeof value === 'number') return value;\n\n const token = typeof value === 'string' && value.trim() ? value.trim() : fallbackToken;\n const prop = extractCssCustomProp(token);\n\n if (prop) {\n return readTokenTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n }\n\n return parseCssTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n}\n", "/** CSS custom property for scroll-edge fade depth (dimension token or length). */\nexport const SCROLL_EDGE_FADE_SIZE_VAR = '--ds-scroll-edge-fade-size';\n\nexport const SCROLL_EDGE_FADE_DEFAULT_SIZE = 'var(--dimension-size-600)';\n\nexport type ScrollEdgeFadeEdge = 'top' | 'bottom' | 'left' | 'right';\n\nexport type ScrollEdgeFadeSizeToken =\n | 'size-000'\n | 'size-050'\n | 'size-075'\n | 'size-100'\n | 'size-150'\n | 'size-200'\n | 'size-250'\n | 'size-300'\n | 'size-400'\n | 'size-500'\n | 'size-600'\n | 'size-800';\n\nexport type ScrollEdgeFadeSize = ScrollEdgeFadeSizeToken | (string & {});\n\nconst SIZE_VALUE: Record<ScrollEdgeFadeSizeToken, string> = {\n 'size-000': 'var(--dimension-size-000)',\n 'size-050': 'var(--dimension-size-050)',\n 'size-075': 'var(--dimension-size-075)',\n 'size-100': 'var(--dimension-size-100)',\n 'size-150': 'var(--dimension-size-150)',\n 'size-200': 'var(--dimension-size-200)',\n 'size-250': 'var(--dimension-size-250)',\n 'size-300': 'var(--dimension-size-300)',\n 'size-400': 'var(--dimension-size-400)',\n 'size-500': 'var(--dimension-size-500)',\n 'size-600': 'var(--dimension-size-600)',\n 'size-800': 'var(--dimension-size-800)',\n};\n\nconst SIZE_REF = `var(${SCROLL_EDGE_FADE_SIZE_VAR}, ${SCROLL_EDGE_FADE_DEFAULT_SIZE})`;\n\nexport interface ScrollEdgeFadeOptions {\n /** One or more edges to fade. */\n edges: ScrollEdgeFadeEdge | ScrollEdgeFadeEdge[];\n /**\n * When true, or when every listed edge is at its scroll limit, removes the mask.\n * Pass a per-edge map to hide only the edges that are flush (panel-nav bottom fade).\n */\n atEnd?: boolean | Partial<Record<ScrollEdgeFadeEdge, boolean>>;\n /** Force the mask off regardless of scroll position (`ds-fade` `visible={false}`). */\n hidden?: boolean;\n}\n\n/** Resolve a dimension size token name or raw CSS length for `--ds-scroll-edge-fade-size`. */\nexport function resolveScrollEdgeFadeSize(\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): string {\n if (height) return height;\n return Object.prototype.hasOwnProperty.call(SIZE_VALUE, size)\n ? SIZE_VALUE[size as ScrollEdgeFadeSizeToken]\n : size;\n}\n\n/** Inline style map setting fade depth on a scroll container. */\nexport function scrollEdgeFadeSizeStyle(\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): Record<string, string> {\n return {\n [SCROLL_EDGE_FADE_SIZE_VAR]: resolveScrollEdgeFadeSize(size, height),\n };\n}\n\n/**\n * Alpha mask for a scroll container edge \u2014 content fades to transparent so\n * textured backgrounds (shell gradients, images) show through.\n */\nexport function scrollEdgeFadeMaskImage(edge: ScrollEdgeFadeEdge): string {\n switch (edge) {\n case 'top':\n return `linear-gradient(to bottom, #000 0, #000 50%, transparent 100%)`;\n case 'bottom':\n return `linear-gradient(to bottom, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n case 'left':\n return `linear-gradient(to right, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n case 'right':\n return `linear-gradient(to left, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n }\n}\n\n/** Inline style map for a masked scroll region (single edge). */\nexport function scrollEdgeFadeMaskStyle(\n edge: ScrollEdgeFadeEdge,\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): Record<string, string> {\n const mask = scrollEdgeFadeMaskImage(edge);\n return {\n ...scrollEdgeFadeSizeStyle(size, height),\n WebkitMaskImage: mask,\n maskImage: mask,\n WebkitMaskSize: '100% 100%',\n maskSize: '100% 100%',\n };\n}\n\n/** Class map for `scroll-edge-fade` modifiers \u2014 pair with `scroll-edge-fade.css`. */\nexport function scrollEdgeFadeClassMap(opts: ScrollEdgeFadeOptions): Record<string, boolean> {\n const edges = Array.isArray(opts.edges) ? opts.edges : [opts.edges];\n const classes: Record<string, boolean> = {\n 'scroll-edge-fade': true,\n 'scroll-edge-fade--hidden': opts.hidden === true,\n };\n\n for (const edge of edges) {\n classes[`scroll-edge-fade--${edge}`] = true;\n }\n\n const { atEnd } = opts;\n if (atEnd === true) {\n classes['scroll-edge-fade--at-end'] = true;\n } else if (atEnd && typeof atEnd === 'object') {\n const allAtEnd = edges.every(edge => atEnd[edge]);\n if (allAtEnd) {\n classes['scroll-edge-fade--at-end'] = true;\n }\n }\n\n return classes;\n}\n\n/** Whether a scroll container is flush with the given edge (within `threshold` px). */\nexport function isScrollAtEdge(\n el: HTMLElement,\n edge: ScrollEdgeFadeEdge,\n threshold = 2,\n): boolean {\n switch (edge) {\n case 'top':\n return el.scrollTop <= threshold;\n case 'bottom':\n return el.scrollHeight - el.scrollTop - el.clientHeight <= threshold;\n case 'left':\n return el.scrollLeft <= threshold;\n case 'right':\n return el.scrollWidth - el.scrollLeft - el.clientWidth <= threshold;\n }\n}\n", "import {\n dimensionIconographyMd,\n dimensionIconographySm,\n dimensionIconographyXs,\n dimensionMenuWidthXs,\n dimensionPanelWidth2xs,\n dimensionPanelWidthLg,\n dimensionPanelWidthMd,\n dimensionRadius025,\n dimensionSize200,\n dimensionSize300,\n dimensionSize400,\n dimensionSize600,\n dimensionSize800,\n dimensionSpace050,\n dimensionSpace200,\n typographyLineheightLg,\n typographyLineheightMd,\n typographyLineheightSm,\n typographyLineheightXl,\n typographyLineheightXs,\n effectAnimationDelayLong2,\n effectAnimationDelayMedium1,\n effectAnimationDelayMedium3,\n effectAnimationDelayInstant,\n effectAnimationDelayShort2,\n effectAnimationDurationMedium1,\n effectAnimationDurationShort3,\n effectMotionShort2,\n effectMotionShort3,\n} from '@ds-mo/tokens/ts';\n\n/** TokoMo CSS custom-property names for shared component defaults (runtime resolution). */\nexport const TOKEN_DEFAULTS = {\n space050: dimensionSpace050,\n space200: dimensionSpace200,\n radius025: dimensionRadius025,\n size200: dimensionSize200,\n size300: dimensionSize300,\n size400: dimensionSize400,\n size600: dimensionSize600,\n size800: dimensionSize800,\n iconographyMd: dimensionIconographyMd,\n iconographySm: dimensionIconographySm,\n iconographyXs: dimensionIconographyXs,\n panelWidth2xs: dimensionPanelWidth2xs,\n panelWidthMd: dimensionPanelWidthMd,\n panelWidthLg: dimensionPanelWidthLg,\n menuWidthXs: dimensionMenuWidthXs,\n lineheightLg: typographyLineheightLg,\n lineheightMd: typographyLineheightMd,\n lineheightSm: typographyLineheightSm,\n lineheightXl: typographyLineheightXl,\n lineheightXs: typographyLineheightXs,\n motionShort2: effectMotionShort2,\n motionShort3: effectMotionShort3,\n animationDurationShort3: effectAnimationDurationShort3,\n animationDurationMedium1: effectAnimationDurationMedium1,\n animationDelayInstant: effectAnimationDelayInstant,\n animationDelayMedium1: effectAnimationDelayMedium1,\n animationDelayMedium3: effectAnimationDelayMedium3,\n animationDelayShort2: effectAnimationDelayShort2,\n animationDelayLong2: effectAnimationDelayLong2,\n /** Unmeasured menu height fallback: 20\u00D7 base (160px at default scale). */\n menuFallbackHeight: 'calc(var(--dimension-size-base) * 20)',\n /** Unmeasured tooltip width fallback: size-800 + size-200 (80px). */\n tooltipFallbackWidth: 'calc(var(--dimension-size-800) + var(--dimension-size-200))',\n} as const;\n\nexport type TokenDefaultKey = keyof typeof TOKEN_DEFAULTS;\n\n/** Valid CSS length strings for overlay offset props \u2014 bind on `sideOffset` / `alignOffset` in hosts. */\nexport const TOKEN_CSS_LENGTHS = {\n space050: `var(${dimensionSpace050})`,\n space200: `var(${dimensionSpace200})`,\n menuWidthXs: `var(${dimensionMenuWidthXs})`,\n} as const;\n"],
|
|
5
|
-
"mappings": "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
|
|
3
|
+
"sources": ["../../../src/wc/components/Icon/icon-cache.ts", "../../../src/wc/utils/resolve-css-length-px.ts", "../../../src/wc/utils/format-compact-number.ts", "../../../src/wc/utils/truncate-svg-text.ts", "../../../src/wc/utils/resolve-css-time-ms.ts", "../../../src/wc/utils/scroll-edge-fade.ts", "../../../src/wc/utils/token-defaults.ts", "../../../src/wc/utils/control-width.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Shared SVG glyph cache for ds-icon.\n *\n * Keyed on a global symbol so every module instance (the compiled Stencil chunk\n * inside dist/components and any direct source import, e.g. via `@ds-mo/ui/utils`)\n * reads and writes the same cache. Without this, `registerIcons` called from an\n * app would fill a different Map than the one ds-icon resolves from.\n */\nconst CACHE_KEY = Symbol.for('ds-mo.icon-svg-cache');\n\ntype IconCacheMap = Map<string, string>;\n\ntype GlobalWithIconCache = { [CACHE_KEY]?: IconCacheMap };\n\nexport function iconCacheKey(name: string, flag: boolean): string {\n return flag ? `flag:${name}` : `system:${name}`;\n}\n\nexport function iconCache(): IconCacheMap {\n const g = globalThis as GlobalWithIconCache;\n return (g[CACHE_KEY] ??= new Map());\n}\n\n/**\n * Pre-register glyphs so ds-icon renders them synchronously \u2014 no lazy-chunk\n * fetch, no first-paint pop-in. Import the SVG strings from `@ds-mo/icons`\n * in the app (statically, so they ship in the app's own bundle):\n *\n * ```ts\n * import { Bell } from '@ds-mo/icons/svg/Bell';\n * import { US } from '@ds-mo/icons/svg/flags/US';\n * import { registerIcons } from '@ds-mo/ui/utils';\n *\n * registerIcons({ Bell });\n * registerIcons({ US }, { flag: true });\n * ```\n *\n * Icons that are not registered still work \u2014 they lazy-load on first render\n * and stay cached afterwards.\n */\nexport function registerIcons(icons: Record<string, string>, options?: { flag?: boolean }): void {\n const cache = iconCache();\n const flag = options?.flag === true;\n for (const [name, svg] of Object.entries(icons)) {\n cache.set(iconCacheKey(name, flag), svg);\n }\n}\n", "const lengthPxCache = new Map<string, number>();\n\nlet probeEl: HTMLElement | null = null;\n\nfunction getProbeElement(): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n\n if (!probeEl) {\n probeEl = document.createElement('div');\n probeEl.setAttribute('aria-hidden', 'true');\n probeEl.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;top:0;left:0;width:0;height:0;overflow:hidden;';\n document.documentElement.appendChild(probeEl);\n }\n\n return probeEl;\n}\n\n/** Clear session cache (tests only). */\nexport function clearCssLengthPxCache(): void {\n lengthPxCache.clear();\n}\n\n/**\n * Resolve a CSS length to pixels for layout math.\n * Numbers pass through; `var(--dimension-*)`, `calc(...)`, and `16px` resolve via a hidden probe.\n */\nexport function resolveCssLengthPx(\n value: number | string | undefined,\n fallback: number | string,\n): number {\n const resolved = value === undefined || value === null || value === '' ? fallback : value;\n if (typeof resolved === 'number') return resolved;\n\n const trimmed = resolved.trim();\n if (!trimmed) return resolveCssLengthPx(fallback, 0);\n\n const cached = lengthPxCache.get(trimmed);\n if (cached !== undefined) return cached;\n\n if (/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n const n = Number(trimmed);\n lengthPxCache.set(trimmed, n);\n return n;\n }\n\n const pxMatch = trimmed.match(/^(-?\\d+(\\.\\d+)?)px$/);\n if (pxMatch) {\n const px = parseFloat(pxMatch[1]);\n lengthPxCache.set(trimmed, px);\n return px;\n }\n\n const cssLength = /^--[\\w-]+$/.test(trimmed) ? `var(${trimmed})` : trimmed;\n\n const probe = getProbeElement();\n if (!probe) {\n return typeof fallback === 'number' ? fallback : 0;\n }\n\n probe.style.width = cssLength;\n const px = probe.getBoundingClientRect().width;\n probe.style.width = '';\n lengthPxCache.set(trimmed, px);\n return px;\n}\n", "const COMPACT_UNITS: { threshold: number; suffix: string }[] = [\n { threshold: 1_000_000_000, suffix: 'b' },\n { threshold: 1_000_000, suffix: 'm' },\n { threshold: 1_000, suffix: 'k' },\n];\n\n/** Compact large numbers for display: 1000 -> \"1k\", 1500 -> \"1.5k\", 110100 -> \"110.1k\", 1000000 -> \"1m\". */\nexport function formatCompactNumber(value: number): string {\n const sign = value < 0 ? '-' : '';\n const abs = Math.abs(value);\n if (abs < 1000) return String(value);\n\n for (let i = 0; i < COMPACT_UNITS.length; i++) {\n const unit = COMPACT_UNITS[i];\n if (abs < unit.threshold) continue;\n\n let scaled = Math.round((abs / unit.threshold) * 10) / 10;\n // Carry over, e.g. 999.96k rounds to \"1000k\" \u2014 bump to the next unit instead.\n if (scaled >= 1000 && i > 0) {\n const next = COMPACT_UNITS[i - 1];\n scaled = Math.round((abs / next.threshold) * 10) / 10;\n return `${sign}${scaled}${next.suffix}`;\n }\n return `${sign}${scaled}${unit.suffix}`;\n }\n return String(value);\n}\n", "/**\n * Binary-searches the longest prefix of `text` (plus an ellipsis) that fits within `maxWidth`\n * px when rendered by `el`, using the SVG `getComputedTextLength()` API for exact measurement \u2014\n * `text-overflow: ellipsis` doesn't apply to raw SVG `<text>` nodes.\n *\n * Mutates `el.textContent` during measurement; the caller's next render (driven by the\n * returned string going into state) overwrites it with the final value.\n */\nexport function truncateSvgTextToWidth(el: SVGTextElement, text: string, maxWidth: number): string {\n el.textContent = text;\n if (maxWidth <= 0 || el.getComputedTextLength() <= maxWidth) return text;\n\n let lo = 0;\n let hi = text.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n el.textContent = `${text.slice(0, mid)}\u2026`;\n if (el.getComputedTextLength() <= maxWidth) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return lo > 0 ? `${text.slice(0, lo)}\u2026` : '\u2026';\n}\n", "/** Parse a CSS <time> value (or motion shorthand's first token) to milliseconds. */\nexport function parseCssTimeMs(value: string, fallback: number): number {\n const firstToken = value.trim().split(/\\s+/)[0] ?? '';\n const num = parseFloat(firstToken);\n if (Number.isNaN(num)) return fallback;\n if (/ms\\s*$/.test(firstToken)) return num;\n if (/s\\s*$/.test(firstToken)) return num * 1000;\n return num;\n}\n\nfunction extractCssCustomProp(ref: string): string | null {\n const varMatch = ref.match(/^var\\(\\s*(--[^),]+)/);\n if (varMatch) return varMatch[1].trim();\n if (ref.startsWith('--')) return ref.trim();\n return null;\n}\n\nfunction readTokenTimeMs(token: string, fallback: number): number {\n if (typeof document === 'undefined') return fallback;\n\n const prop = extractCssCustomProp(token);\n if (!prop) return parseCssTimeMs(token, fallback);\n\n const raw = getComputedStyle(document.documentElement).getPropertyValue(prop).trim();\n return parseCssTimeMs(raw, fallback);\n}\n\n/**\n * Resolve a duration to milliseconds for JS timers aligned with CSS motion tokens.\n * Accepts numbers (ms), raw times (`200ms`, `0.75s`), or `var(--effect-*)` references.\n */\nexport function resolveCssTimeMs(\n value: number | string | undefined,\n fallbackToken: string,\n): number {\n if (typeof value === 'number') return value;\n\n const token = typeof value === 'string' && value.trim() ? value.trim() : fallbackToken;\n const prop = extractCssCustomProp(token);\n\n if (prop) {\n return readTokenTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n }\n\n return parseCssTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n}\n", "/** CSS custom property for scroll-edge fade depth (dimension token or length). */\nexport const SCROLL_EDGE_FADE_SIZE_VAR = '--ds-scroll-edge-fade-size';\n\nexport const SCROLL_EDGE_FADE_DEFAULT_SIZE = 'var(--dimension-size-600)';\n\nexport type ScrollEdgeFadeEdge = 'top' | 'bottom' | 'left' | 'right';\n\nexport type ScrollEdgeFadeSizeToken =\n | 'size-000'\n | 'size-050'\n | 'size-075'\n | 'size-100'\n | 'size-150'\n | 'size-200'\n | 'size-250'\n | 'size-300'\n | 'size-400'\n | 'size-500'\n | 'size-600'\n | 'size-800';\n\nexport type ScrollEdgeFadeSize = ScrollEdgeFadeSizeToken | (string & {});\n\nconst SIZE_VALUE: Record<ScrollEdgeFadeSizeToken, string> = {\n 'size-000': 'var(--dimension-size-000)',\n 'size-050': 'var(--dimension-size-050)',\n 'size-075': 'var(--dimension-size-075)',\n 'size-100': 'var(--dimension-size-100)',\n 'size-150': 'var(--dimension-size-150)',\n 'size-200': 'var(--dimension-size-200)',\n 'size-250': 'var(--dimension-size-250)',\n 'size-300': 'var(--dimension-size-300)',\n 'size-400': 'var(--dimension-size-400)',\n 'size-500': 'var(--dimension-size-500)',\n 'size-600': 'var(--dimension-size-600)',\n 'size-800': 'var(--dimension-size-800)',\n};\n\nconst SIZE_REF = `var(${SCROLL_EDGE_FADE_SIZE_VAR}, ${SCROLL_EDGE_FADE_DEFAULT_SIZE})`;\n\nexport interface ScrollEdgeFadeOptions {\n /** One or more edges to fade. */\n edges: ScrollEdgeFadeEdge | ScrollEdgeFadeEdge[];\n /**\n * When true, or when every listed edge is at its scroll limit, removes the mask.\n * Pass a per-edge map to hide only the edges that are flush (panel-nav bottom fade).\n */\n atEnd?: boolean | Partial<Record<ScrollEdgeFadeEdge, boolean>>;\n /** Force the mask off regardless of scroll position (`ds-fade` `visible={false}`). */\n hidden?: boolean;\n}\n\n/** Resolve a dimension size token name or raw CSS length for `--ds-scroll-edge-fade-size`. */\nexport function resolveScrollEdgeFadeSize(\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): string {\n if (height) return height;\n return Object.prototype.hasOwnProperty.call(SIZE_VALUE, size)\n ? SIZE_VALUE[size as ScrollEdgeFadeSizeToken]\n : size;\n}\n\n/** Inline style map setting fade depth on a scroll container. */\nexport function scrollEdgeFadeSizeStyle(\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): Record<string, string> {\n return {\n [SCROLL_EDGE_FADE_SIZE_VAR]: resolveScrollEdgeFadeSize(size, height),\n };\n}\n\n/**\n * Alpha mask for a scroll container edge \u2014 content fades to transparent so\n * textured backgrounds (shell gradients, images) show through.\n */\nexport function scrollEdgeFadeMaskImage(edge: ScrollEdgeFadeEdge): string {\n switch (edge) {\n case 'top':\n return `linear-gradient(to bottom, #000 0, #000 50%, transparent 100%)`;\n case 'bottom':\n return `linear-gradient(to bottom, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n case 'left':\n return `linear-gradient(to right, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n case 'right':\n return `linear-gradient(to left, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n }\n}\n\n/** Inline style map for a masked scroll region (single edge). */\nexport function scrollEdgeFadeMaskStyle(\n edge: ScrollEdgeFadeEdge,\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): Record<string, string> {\n const mask = scrollEdgeFadeMaskImage(edge);\n return {\n ...scrollEdgeFadeSizeStyle(size, height),\n WebkitMaskImage: mask,\n maskImage: mask,\n WebkitMaskSize: '100% 100%',\n maskSize: '100% 100%',\n };\n}\n\n/** Class map for `scroll-edge-fade` modifiers \u2014 pair with `scroll-edge-fade.css`. */\nexport function scrollEdgeFadeClassMap(opts: ScrollEdgeFadeOptions): Record<string, boolean> {\n const edges = Array.isArray(opts.edges) ? opts.edges : [opts.edges];\n const classes: Record<string, boolean> = {\n 'scroll-edge-fade': true,\n 'scroll-edge-fade--hidden': opts.hidden === true,\n };\n\n for (const edge of edges) {\n classes[`scroll-edge-fade--${edge}`] = true;\n }\n\n const { atEnd } = opts;\n if (atEnd === true) {\n classes['scroll-edge-fade--at-end'] = true;\n } else if (atEnd && typeof atEnd === 'object') {\n const allAtEnd = edges.every(edge => atEnd[edge]);\n if (allAtEnd) {\n classes['scroll-edge-fade--at-end'] = true;\n }\n }\n\n return classes;\n}\n\n/** Whether a scroll container is flush with the given edge (within `threshold` px). */\nexport function isScrollAtEdge(\n el: HTMLElement,\n edge: ScrollEdgeFadeEdge,\n threshold = 2,\n): boolean {\n switch (edge) {\n case 'top':\n return el.scrollTop <= threshold;\n case 'bottom':\n return el.scrollHeight - el.scrollTop - el.clientHeight <= threshold;\n case 'left':\n return el.scrollLeft <= threshold;\n case 'right':\n return el.scrollWidth - el.scrollLeft - el.clientWidth <= threshold;\n }\n}\n", "import {\n dimensionIconographyMd,\n dimensionIconographySm,\n dimensionIconographyXs,\n dimensionMenuWidthXs,\n dimensionPanelWidth2xs,\n dimensionPanelWidthLg,\n dimensionPanelWidthMd,\n dimensionRadius025,\n dimensionSize200,\n dimensionSize300,\n dimensionSize400,\n dimensionSize600,\n dimensionSize800,\n dimensionSpace050,\n dimensionSpace200,\n typographyLineheightLg,\n typographyLineheightMd,\n typographyLineheightSm,\n typographyLineheightXl,\n typographyLineheightXs,\n effectAnimationDelayLong2,\n effectAnimationDelayMedium1,\n effectAnimationDelayMedium3,\n effectAnimationDelayInstant,\n effectAnimationDelayShort2,\n effectAnimationDurationMedium1,\n effectAnimationDurationShort3,\n effectMotionShort2,\n effectMotionShort3,\n} from '@ds-mo/tokens/ts';\n\n/** TokoMo CSS custom-property names for shared component defaults (runtime resolution). */\nexport const TOKEN_DEFAULTS = {\n space050: dimensionSpace050,\n space200: dimensionSpace200,\n radius025: dimensionRadius025,\n size200: dimensionSize200,\n size300: dimensionSize300,\n size400: dimensionSize400,\n size600: dimensionSize600,\n size800: dimensionSize800,\n iconographyMd: dimensionIconographyMd,\n iconographySm: dimensionIconographySm,\n iconographyXs: dimensionIconographyXs,\n panelWidth2xs: dimensionPanelWidth2xs,\n panelWidthMd: dimensionPanelWidthMd,\n panelWidthLg: dimensionPanelWidthLg,\n menuWidthXs: dimensionMenuWidthXs,\n lineheightLg: typographyLineheightLg,\n lineheightMd: typographyLineheightMd,\n lineheightSm: typographyLineheightSm,\n lineheightXl: typographyLineheightXl,\n lineheightXs: typographyLineheightXs,\n motionShort2: effectMotionShort2,\n motionShort3: effectMotionShort3,\n animationDurationShort3: effectAnimationDurationShort3,\n animationDurationMedium1: effectAnimationDurationMedium1,\n animationDelayInstant: effectAnimationDelayInstant,\n animationDelayMedium1: effectAnimationDelayMedium1,\n animationDelayMedium3: effectAnimationDelayMedium3,\n animationDelayShort2: effectAnimationDelayShort2,\n animationDelayLong2: effectAnimationDelayLong2,\n /** Unmeasured menu height fallback: 20\u00D7 base (160px at default scale). */\n menuFallbackHeight: 'calc(var(--dimension-size-base) * 20)',\n /** Unmeasured tooltip width fallback: size-800 + size-200 (80px). */\n tooltipFallbackWidth: 'calc(var(--dimension-size-800) + var(--dimension-size-200))',\n /** Fill-mode donut diameter floor: 16\u00D7 size-base (128px). */\n donutFillMin: 'calc(var(--dimension-size-base) * 16)',\n /** Fill-mode donut diameter ceiling: 24\u00D7 size-base (192px). */\n donutFillMax: 'calc(var(--dimension-size-base) * 24)',\n} as const;\n\nexport type TokenDefaultKey = keyof typeof TOKEN_DEFAULTS;\n\n/** Valid CSS length strings for overlay offset props \u2014 bind on `sideOffset` / `alignOffset` in hosts. */\nexport const TOKEN_CSS_LENGTHS = {\n space050: `var(${dimensionSpace050})`,\n space200: `var(${dimensionSpace200})`,\n menuWidthXs: `var(${dimensionMenuWidthXs})`,\n} as const;\n", "/** Shared width fit for interactive controls (buttons, select, \u2026). */\nexport type ControlWidth = 'hug' | 'fill';\n\n/** Host / control class map for `width=\"hug\" | \"fill\"`. */\nexport function controlWidthClass(width: ControlWidth): Record<string, boolean> {\n return {\n 'ds-control-width--hug': width === 'hug',\n 'ds-control-width--fill': width === 'fill',\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["px"]
|
|
7
7
|
}
|
|
@@ -33,6 +33,10 @@ export declare const TOKEN_DEFAULTS: {
|
|
|
33
33
|
readonly menuFallbackHeight: "calc(var(--dimension-size-base) * 20)";
|
|
34
34
|
/** Unmeasured tooltip width fallback: size-800 + size-200 (80px). */
|
|
35
35
|
readonly tooltipFallbackWidth: "calc(var(--dimension-size-800) + var(--dimension-size-200))";
|
|
36
|
+
/** Fill-mode donut diameter floor: 16× size-base (128px). */
|
|
37
|
+
readonly donutFillMin: "calc(var(--dimension-size-base) * 16)";
|
|
38
|
+
/** Fill-mode donut diameter ceiling: 24× size-base (192px). */
|
|
39
|
+
readonly donutFillMax: "calc(var(--dimension-size-base) * 24)";
|
|
36
40
|
};
|
|
37
41
|
export type TokenDefaultKey = keyof typeof TOKEN_DEFAULTS;
|
|
38
42
|
/** Valid CSS length strings for overlay offset props — bind on `sideOffset` / `alignOffset` in hosts. */
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
+
import { type ControlWidth } from '../../utils/control-width';
|
|
2
3
|
export type ButtonFilledIntent = 'neutral' | 'brand' | 'ai' | 'negative' | 'warning' | 'caution' | 'positive' | 'guide' | 'walkthrough';
|
|
3
4
|
export type ButtonFilledContrast = 'bold' | 'strong' | 'medium' | 'faint';
|
|
4
5
|
export type ButtonFilledVariant = 'icon' | 'label' | 'icon-label';
|
|
5
6
|
export type ButtonFilledSize = 'md' | 'sm' | 'xs';
|
|
7
|
+
export type ButtonFilledWidth = ControlWidth;
|
|
6
8
|
export declare class ButtonFilled {
|
|
7
9
|
el: HTMLElement;
|
|
8
10
|
/**
|
|
@@ -12,6 +14,8 @@ export declare class ButtonFilled {
|
|
|
12
14
|
variant: ButtonFilledVariant;
|
|
13
15
|
/** Control density (height, padding, icon, type). */
|
|
14
16
|
size: ButtonFilledSize;
|
|
17
|
+
/** Width fit — hug content (default) or fill the parent. */
|
|
18
|
+
width: ButtonFilledWidth;
|
|
15
19
|
/** Visible text for `label` / `icon-label` variants. */
|
|
16
20
|
label: string;
|
|
17
21
|
/** Icon name passed to <ds-icon> for `icon` / `icon-label` variants. */
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { ButtonFilledContrast, ButtonFilledIntent, ButtonFilledSize, ButtonFilledVariant, } from './ButtonFilled';
|
|
1
|
+
export type { ButtonFilledContrast, ButtonFilledIntent, ButtonFilledSize, ButtonFilledVariant, ButtonFilledWidth, } from './ButtonFilled';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
+
import { type ControlWidth } from '../../utils/control-width';
|
|
2
3
|
export type ButtonUnfilledOnBackgroundContrast = 'default' | 'medium' | 'bold' | 'strong';
|
|
3
4
|
export type ButtonUnfilledBackground = 'always-dark' | 'navigation';
|
|
4
5
|
export type ButtonUnfilledVariant = 'icon' | 'label' | 'icon-label';
|
|
5
6
|
export type ButtonUnfilledSize = 'md' | 'sm' | 'xs';
|
|
7
|
+
export type ButtonUnfilledWidth = ControlWidth;
|
|
6
8
|
export declare class ButtonUnfilled {
|
|
7
9
|
el: HTMLElement;
|
|
8
10
|
/**
|
|
@@ -12,19 +14,21 @@ export declare class ButtonUnfilled {
|
|
|
12
14
|
variant: ButtonUnfilledVariant;
|
|
13
15
|
/** Control density (height, padding, icon, type). */
|
|
14
16
|
size: ButtonUnfilledSize;
|
|
17
|
+
/** Width fit — hug content (default) or fill the parent. */
|
|
18
|
+
width: ButtonUnfilledWidth;
|
|
15
19
|
/** Visible text for `label` / `icon-label` variants. */
|
|
16
20
|
label: string;
|
|
17
21
|
/** Icon name passed to <ds-icon> for `icon` / `icon-label` variants. */
|
|
18
22
|
icon: string;
|
|
19
|
-
/** Active/selected visual state. */
|
|
23
|
+
/** Active/selected visual state. Always promotes foreground to primary. */
|
|
20
24
|
isActive: boolean;
|
|
21
25
|
/**
|
|
22
26
|
* When active, render the selected interaction fill.
|
|
23
27
|
* Default `true` for general UI. Shell chrome (nav / tool rails) should pass
|
|
24
|
-
* `false` so selection is foreground-only.
|
|
28
|
+
* `false` so selection is foreground-only (primary color, no fill).
|
|
25
29
|
*/
|
|
26
30
|
activeFill: boolean;
|
|
27
|
-
/** Show a 1px
|
|
31
|
+
/** Show a 1px secondary inset border. Default on; shell chrome can pass `false`. */
|
|
28
32
|
hasBorder: boolean;
|
|
29
33
|
/** Show a notification dot at the top-right of the icon zone (icon variant only). */
|
|
30
34
|
dot: boolean;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { ButtonUnfilledBackground, ButtonUnfilledOnBackgroundContrast, ButtonUnfilledSize, ButtonUnfilledVariant, } from './ButtonUnfilled';
|
|
1
|
+
export type { ButtonUnfilledBackground, ButtonUnfilledOnBackgroundContrast, ButtonUnfilledSize, ButtonUnfilledVariant, ButtonUnfilledWidth, } from './ButtonUnfilled';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type CardWidth = 'sm' | 'md' | 'lg';
|
|
2
|
+
/** Visual chrome recipe — default app surface, or settings edit wash. */
|
|
3
|
+
export type CardAppearance = 'default' | 'editing';
|
|
4
|
+
/**
|
|
5
|
+
* Shared card chrome — width + matching min-height tokens, header (title + actions),
|
|
6
|
+
* and a flex body that fills leftover space. Compose this from settings / data-viz cards.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Card {
|
|
9
|
+
/** Section heading shown in the card header. */
|
|
10
|
+
heading: string;
|
|
11
|
+
/**
|
|
12
|
+
* Card width token (`sm` / `md` / `lg`). Also sets host `min-height` to the
|
|
13
|
+
* matching `--dimension-card-height-*` so empty bodies still fill the card.
|
|
14
|
+
*/
|
|
15
|
+
cardWidth: CardWidth;
|
|
16
|
+
/** Chrome recipe — `editing` applies the settings edit wash. */
|
|
17
|
+
appearance: CardAppearance;
|
|
18
|
+
render(): any;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=Card.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
+
import type { CardWidth } from '../Card/Card';
|
|
3
|
+
export type CardDataVizDonutWidth = CardWidth;
|
|
4
|
+
/**
|
|
5
|
+
* Donut data-viz card — shared `ds-card` chrome with a fill chart region and
|
|
6
|
+
* content-sized legend. Hover sync between chart and legend stays here.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CardDataVizDonut {
|
|
9
|
+
el: HTMLElement;
|
|
10
|
+
/** Widget heading shown in the card header. */
|
|
11
|
+
heading: string;
|
|
12
|
+
/** Card width token — also sets matching min-height. */
|
|
13
|
+
cardWidth: CardDataVizDonutWidth;
|
|
14
|
+
/** Emits when the header filter control is activated. */
|
|
15
|
+
dsFilterClick: EventEmitter<void>;
|
|
16
|
+
private hasChartSlot;
|
|
17
|
+
private hasLegendSlot;
|
|
18
|
+
componentWillRender(): void;
|
|
19
|
+
componentDidLoad(): void;
|
|
20
|
+
disconnectedCallback(): void;
|
|
21
|
+
private handleChartHover;
|
|
22
|
+
private handleLegendHover;
|
|
23
|
+
private handleFilterClick;
|
|
24
|
+
render(): any;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=CardDataVizDonut.d.ts.map
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
-
|
|
2
|
+
import type { CardWidth } from '../Card/Card';
|
|
3
|
+
export type CardSettingWidth = CardWidth;
|
|
3
4
|
export declare class CardSetting {
|
|
4
5
|
/** Section heading shown in the card header. */
|
|
5
6
|
heading: string;
|
|
6
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Card width token (`sm` / `md` / `lg`). Also sets host `min-height` to the
|
|
9
|
+
* matching `--dimension-card-height-*` so the body fills available space
|
|
10
|
+
* even when the slot is empty.
|
|
11
|
+
*/
|
|
7
12
|
cardWidth: CardSettingWidth;
|
|
8
13
|
/** Controlled edit state — parent owns single-edit orchestration. */
|
|
9
14
|
editing: boolean;
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
2
|
import type { ChartDatum } from '../../utils/chart-types';
|
|
3
3
|
export declare class ChartDonut {
|
|
4
|
+
el: HTMLElement;
|
|
4
5
|
/** Slices to render. Set as a JS property (not an HTML attribute). */
|
|
5
6
|
data: ChartDatum[];
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Explicit diameter in px. When unset, the donut sizes to its container
|
|
9
|
+
* (ResizeObserver) clamped between `--dimension-size-base * 16` (128px) and
|
|
10
|
+
* `* 24` (192px), and stays centered in the leftover space. Prefer unset
|
|
11
|
+
* inside card layouts.
|
|
12
|
+
*/
|
|
13
|
+
size: number | undefined;
|
|
7
14
|
/** Ring thickness — number (px) or TokoMo length. Defaults to `--dimension-size-200` (16px). */
|
|
8
15
|
thickness: number | string;
|
|
9
16
|
/** Corner radius on each slice — number (px) or TokoMo length. Defaults to `--dimension-radius-025` (2px). */
|
|
@@ -28,11 +35,27 @@ export declare class ChartDonut {
|
|
|
28
35
|
/** Center text, truncated with an ellipsis if it doesn't fit inside the inner circle. */
|
|
29
36
|
private displayedValueText;
|
|
30
37
|
private displayedCaptionText;
|
|
38
|
+
/** Measured fill diameter when `size` is unset. */
|
|
39
|
+
private measuredSize;
|
|
31
40
|
/** Fires with the hovered/focused slice's datum, or `null` on leave/blur. */
|
|
32
41
|
dsSliceHover: EventEmitter<ChartDatum | null>;
|
|
33
42
|
private valueTextEl?;
|
|
34
43
|
private captionTextEl?;
|
|
35
44
|
private wrapperEl?;
|
|
45
|
+
private resizeObserver;
|
|
46
|
+
private get isFillMode();
|
|
47
|
+
private get fillMinPx();
|
|
48
|
+
private get fillMaxPx();
|
|
49
|
+
/** Clamp available square side into the fill min/max band. */
|
|
50
|
+
private clampFillSize;
|
|
51
|
+
private get resolvedSize();
|
|
52
|
+
componentDidLoad(): void;
|
|
53
|
+
onSizePropChange(): void;
|
|
54
|
+
disconnectedCallback(): void;
|
|
55
|
+
private syncResizeObserver;
|
|
56
|
+
private measureHost;
|
|
57
|
+
private applyAvailableSize;
|
|
58
|
+
private teardownResizeObserver;
|
|
36
59
|
private handleHover;
|
|
37
60
|
private handleSliceMove;
|
|
38
61
|
private updateTooltip;
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
+
import { type ControlWidth } from '../../utils/control-width';
|
|
2
3
|
export interface SelectOption {
|
|
3
4
|
label: string;
|
|
4
5
|
value: string;
|
|
5
6
|
}
|
|
7
|
+
export type SelectSize = 'md' | 'sm' | 'xs';
|
|
8
|
+
export type SelectWidth = ControlWidth;
|
|
9
|
+
/**
|
|
10
|
+
* Dropdown select — unfilled-button chrome (label + trailing ChevronDown) in
|
|
11
|
+
* control-density sizes, with `ds-menu` for the option list.
|
|
12
|
+
*/
|
|
6
13
|
export declare class Select {
|
|
7
14
|
el: HTMLElement;
|
|
8
15
|
/**
|
|
@@ -14,8 +21,21 @@ export declare class Select {
|
|
|
14
21
|
value: string;
|
|
15
22
|
/** Placeholder shown when no value is selected. */
|
|
16
23
|
placeholder: string;
|
|
24
|
+
/** Control density (height, padding, icon, type). */
|
|
25
|
+
size: SelectSize;
|
|
26
|
+
/** Width fit — fill the parent (default) or hug content. */
|
|
27
|
+
width: SelectWidth;
|
|
17
28
|
/** Disables interaction (25% opacity via ds-control-inactive). */
|
|
18
29
|
isInactive: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* When a value is selected, render the selected interaction fill (same recipe
|
|
32
|
+
* as unfilled-button `activeFill`). Default `true`. Pass `false` for
|
|
33
|
+
* foreground-only selection (primary label, no fill).
|
|
34
|
+
* Selected/open promotes the label to primary; chevron stays secondary.
|
|
35
|
+
*/
|
|
36
|
+
activeFill: boolean;
|
|
37
|
+
/** Show a 1px secondary inset border. Default on (matches unfilled button). */
|
|
38
|
+
hasBorder: boolean;
|
|
19
39
|
ariaLabel: string | undefined;
|
|
20
40
|
ariaLabelledby: string | undefined;
|
|
21
41
|
/** Emits the selected value string. */
|
|
@@ -23,11 +43,23 @@ export declare class Select {
|
|
|
23
43
|
private isOpen;
|
|
24
44
|
private triggerEl;
|
|
25
45
|
private menuEl;
|
|
46
|
+
/** True when the open was keyboard-driven — menu shows initial focus ring. */
|
|
47
|
+
private openWithFocusVisible;
|
|
26
48
|
componentDidLoad(): void;
|
|
49
|
+
disconnectedCallback(): void;
|
|
27
50
|
onIsOpenChange(open: boolean): void;
|
|
28
51
|
onOptionsChange(): void;
|
|
29
52
|
onValueChange(): void;
|
|
53
|
+
private handleMenuSelect;
|
|
54
|
+
private handleMenuClose;
|
|
30
55
|
private syncMenuItems;
|
|
56
|
+
/**
|
|
57
|
+
* Size/place the menu so option labels line up with the select label.
|
|
58
|
+
* Menu section padding insets items; we expand min-width by that chrome and
|
|
59
|
+
* shift left by the same amount (`alignOffset`). Menu can grow wider than
|
|
60
|
+
* the field (left-bottom / `align="start"`) when labels need more room.
|
|
61
|
+
*/
|
|
62
|
+
private syncMenuLayout;
|
|
31
63
|
private open;
|
|
32
64
|
private close;
|
|
33
65
|
private toggle;
|