@unpunnyfuns/swatchbook-addon 0.1.3 → 0.1.5

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/dist/manager.mjs CHANGED
@@ -321,6 +321,7 @@ function DesignTokensPanel({ active }) {
321
321
  style: searchInputStyle,
322
322
  type: "search",
323
323
  placeholder: `Search ${tokenCount} tokens in ${themeName}…`,
324
+ "aria-label": "Search tokens",
324
325
  value: query,
325
326
  onChange: (e) => setQuery(e.target.value)
326
327
  })), h$1(DiagnosticsSection, { diagnostics: payload.diagnostics }), h$1(ScrollArea, { vertical: true }, filtered.length === 0 ? h$1(Placeholder, null, query ? "No tokens match this filter." : "No tokens in this theme.") : h$1("div", { style: treeWrapperStyle }, h$1("ul", {
@@ -844,6 +845,24 @@ function AxesToolbar() {
844
845
  document.addEventListener("keydown", onDocKey);
845
846
  return () => document.removeEventListener("keydown", onDocKey);
846
847
  }, [open]);
848
+ /**
849
+ * `WithTooltipPure`'s built-in `closeOnOutsideClick` misses some cases
850
+ * (portaled popover + manager iframe boundaries). Belt-and-suspenders:
851
+ * close when the user mouses down anywhere that isn't the trigger wrapper
852
+ * or the popover body.
853
+ */
854
+ useEffect(() => {
855
+ if (!open) return;
856
+ const onDocMouseDown = (e) => {
857
+ const target = e.target;
858
+ if (!(target instanceof Element)) return;
859
+ if (bodyRef.current?.contains(target)) return;
860
+ if (target.closest("[data-testid=\"swatchbook-toolbar-popover\"]")) return;
861
+ setOpen(false);
862
+ };
863
+ document.addEventListener("mousedown", onDocMouseDown);
864
+ return () => document.removeEventListener("mousedown", onDocMouseDown);
865
+ }, [open]);
847
866
  if (axes.length === 0) return h(IconButton, {
848
867
  key: TOOL_ID,
849
868
  title: "Swatchbook theme (loading…)",
@@ -1 +1 @@
1
- {"version":3,"file":"manager.mjs","names":["h"],"sources":["../src/panel.tsx","../src/manager.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactElement,\n} from 'react';\nimport { Placeholder, ScrollArea } from 'storybook/internal/components';\nimport { addons, useGlobals } from 'storybook/manager-api';\nimport { AXES_GLOBAL_KEY, GLOBAL_KEY, INIT_EVENT } from '#/constants.ts';\n\n/** `React.createElement` alias so the manager bundle avoids `react/jsx-runtime`. */\nconst h = React.createElement;\n\ninterface VirtualToken {\n $type?: string;\n $value?: unknown;\n $description?: string;\n}\n\ninterface VirtualTheme {\n name: string;\n input: Record<string, string>;\n sources: string[];\n}\n\ninterface VirtualAxis {\n name: string;\n contexts: readonly string[];\n default: string;\n description?: string;\n source: 'resolver' | 'synthetic';\n}\n\ntype DiagnosticSeverity = 'error' | 'warn' | 'info';\n\ninterface VirtualDiagnostic {\n severity: DiagnosticSeverity;\n group: string;\n message: string;\n filename?: string;\n line?: number;\n column?: number;\n}\n\ninterface InitPayload {\n axes: VirtualAxis[];\n disabledAxes: readonly string[];\n themes: VirtualTheme[];\n defaultTheme: string | null;\n themesResolved: Record<string, Record<string, VirtualToken>>;\n diagnostics: VirtualDiagnostic[];\n cssVarPrefix: string;\n}\n\nfunction usePayload(): InitPayload | null {\n const [payload, setPayload] = useState<InitPayload | null>(null);\n useEffect(() => {\n const channel = addons.getChannel();\n const onInit = (next: InitPayload): void => setPayload(next);\n channel.on(INIT_EVENT, onInit);\n return () => {\n channel.off(INIT_EVENT, onInit);\n };\n }, []);\n return payload;\n}\n\nfunction makeCssVarName(path: string, prefix: string): string {\n const tail = path.replaceAll('.', '-');\n return prefix ? `--${prefix}-${tail}` : `--${tail}`;\n}\n\nasync function copy(text: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n /* clipboard access denied — no fallback, the user can read the var name from the row */\n }\n}\n\n/** Format a token `$value` into a short display string. */\nfunction formatValue(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'string' || typeof value === 'number') return String(value);\n if (typeof value === 'object') {\n const v = value as Record<string, unknown>;\n if (typeof v['hex'] === 'string') return v['hex'] as string;\n if ('value' in v && 'unit' in v) return `${String(v['value'])}${String(v['unit'])}`;\n return JSON.stringify(value).slice(0, 80);\n }\n return String(value);\n}\n\nconst containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n};\n\nconst headerStyle: CSSProperties = {\n padding: '8px 12px',\n borderBottom: '1px solid rgba(128,128,128,0.2)',\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n};\n\nconst axisIndicatorStyle: CSSProperties = {\n fontSize: 11,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, \"Liberation Mono\", monospace',\n opacity: 0.7,\n};\n\nconst treeWrapperStyle: CSSProperties = {\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 12,\n padding: 8,\n};\n\nconst groupRowStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 6px',\n borderRadius: 4,\n cursor: 'pointer',\n userSelect: 'none',\n outline: 'none',\n};\n\nconst leafRowStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '4px 6px',\n borderRadius: 4,\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: 'inherit',\n width: '100%',\n textAlign: 'left',\n fontFamily: 'inherit',\n fontSize: 'inherit',\n outline: 'none',\n};\n\nconst caretStyle: CSSProperties = {\n display: 'inline-block',\n width: 12,\n textAlign: 'center',\n opacity: 0.6,\n};\n\nconst treeUlStyle: CSSProperties = { listStyle: 'none', margin: 0, padding: 0 };\n\nconst nestedUlStyle: CSSProperties = {\n listStyle: 'none',\n margin: 0,\n paddingLeft: 18,\n borderLeft: '1px solid rgba(128,128,128,0.2)',\n};\n\nconst typePillStyle: CSSProperties = {\n display: 'inline-block',\n padding: '1px 6px',\n borderRadius: 4,\n fontSize: 10,\n letterSpacing: 0.5,\n textTransform: 'uppercase',\n background: 'rgba(128,128,128,0.15)',\n};\n\nconst valueStyle: CSSProperties = {\n marginLeft: 'auto',\n opacity: 0.7,\n fontSize: 11,\n maxWidth: '40%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n};\n\nconst countStyle: CSSProperties = {\n marginLeft: 'auto',\n fontSize: 11,\n opacity: 0.7,\n};\n\nconst swatchStyle: CSSProperties = {\n display: 'inline-block',\n width: 14,\n height: 14,\n borderRadius: 3,\n border: '1px solid rgba(128,128,128,0.3)',\n marginLeft: 8,\n};\n\nconst searchInputStyle: CSSProperties = {\n width: '100%',\n padding: '4px 8px',\n fontSize: 12,\n border: '1px solid rgba(128,128,128,0.3)',\n borderRadius: 4,\n background: 'transparent',\n color: 'inherit',\n};\n\ninterface LeafNode {\n kind: 'leaf';\n segment: string;\n path: string;\n token: VirtualToken;\n}\n\ninterface GroupNode {\n kind: 'group';\n segment: string;\n path: string;\n children: TreeNode[];\n}\n\ntype TreeNode = LeafNode | GroupNode;\n\nfunction buildTree(resolved: Record<string, VirtualToken>): TreeNode[] {\n const rootNode: GroupNode = { kind: 'group', segment: '', path: '', children: [] };\n for (const [path, token] of Object.entries(resolved)) {\n const segments = path.split('.');\n let node: GroupNode = rootNode;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const seg = segments[i] as string;\n const prefix = segments.slice(0, i + 1).join('.');\n let child = node.children.find(\n (c): c is GroupNode => c.kind === 'group' && c.segment === seg,\n );\n if (!child) {\n child = { kind: 'group', segment: seg, path: prefix, children: [] };\n node.children.push(child);\n }\n node = child;\n }\n const leafSegment = segments[segments.length - 1] as string;\n node.children.push({ kind: 'leaf', segment: leafSegment, path, token });\n }\n sortTree(rootNode);\n return rootNode.children;\n}\n\nfunction sortTree(node: GroupNode): void {\n node.children.sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'group' ? -1 : 1;\n return a.segment.localeCompare(b.segment);\n });\n for (const c of node.children) {\n if (c.kind === 'group') sortTree(c);\n }\n}\n\nfunction collectInitialExpanded(nodes: TreeNode[], remainingDepth: number, out: Set<string>): void {\n if (remainingDepth <= 0) return;\n for (const node of nodes) {\n if (node.kind !== 'group') continue;\n out.add(node.path);\n collectInitialExpanded(node.children, remainingDepth - 1, out);\n }\n}\n\nfunction countLeaves(node: TreeNode): number {\n if (node.kind === 'leaf') return 1;\n let n = 0;\n for (const c of node.children) n += countLeaves(c);\n return n;\n}\n\nfunction filterTree(nodes: TreeNode[], query: string): TreeNode[] {\n if (!query) return nodes;\n const out: TreeNode[] = [];\n for (const node of nodes) {\n if (node.kind === 'leaf') {\n if (node.path.toLowerCase().includes(query)) out.push(node);\n continue;\n }\n const filteredChildren = filterTree(node.children, query);\n if (filteredChildren.length > 0) {\n out.push({ ...node, children: filteredChildren });\n }\n }\n return out;\n}\n\nfunction collectAllGroupPaths(nodes: TreeNode[], out: Set<string>): void {\n for (const node of nodes) {\n if (node.kind === 'group') {\n out.add(node.path);\n collectAllGroupPaths(node.children, out);\n }\n }\n}\n\ninterface PanelProps {\n active: boolean;\n}\n\nexport function DesignTokensPanel({ active }: PanelProps): ReactElement | null {\n const payload = usePayload();\n const [globals] = useGlobals();\n const [query, setQuery] = useState('');\n\n const axes = useMemo(() => payload?.axes ?? [], [payload]);\n const themes = useMemo(() => payload?.themes ?? [], [payload]);\n const globalAxes = globals[AXES_GLOBAL_KEY] as Record<string, string> | undefined;\n const globalTheme = globals[GLOBAL_KEY] as string | undefined;\n\n const tuple: Record<string, string> = useMemo(() => {\n const out: Record<string, string> = {};\n for (const axis of axes) out[axis.name] = axis.default;\n if (globalAxes && typeof globalAxes === 'object') {\n for (const axis of axes) {\n const candidate = globalAxes[axis.name];\n if (candidate && axis.contexts.includes(candidate)) out[axis.name] = candidate;\n }\n return out;\n }\n if (globalTheme) {\n const match = themes.find((t) => t.name === globalTheme);\n if (match) {\n for (const axis of axes) {\n const candidate = match.input[axis.name];\n if (candidate && axis.contexts.includes(candidate)) out[axis.name] = candidate;\n }\n }\n }\n return out;\n }, [axes, themes, globalAxes, globalTheme]);\n\n const themeName = useMemo(() => {\n const match = themes.find((t) => {\n const input = t.input;\n return Object.keys(input).every((k) => input[k] === tuple[k]);\n });\n return match?.name ?? globalTheme ?? payload?.defaultTheme ?? '';\n }, [themes, tuple, globalTheme, payload]);\n\n const prefix = payload?.cssVarPrefix ?? '';\n const tokens = useMemo(() => payload?.themesResolved[themeName] ?? {}, [payload, themeName]);\n const tokenCount = Object.keys(tokens).length;\n\n const tree = useMemo(() => buildTree(tokens), [tokens]);\n const lowerQuery = query.toLowerCase();\n const filtered = useMemo(() => filterTree(tree, lowerQuery), [tree, lowerQuery]);\n\n const initialExpanded = useMemo(() => {\n const out = new Set<string>();\n collectInitialExpanded(tree, 1, out);\n return out;\n }, [tree]);\n\n const [expanded, setExpanded] = useState<Set<string>>(initialExpanded);\n useEffect(() => {\n setExpanded(initialExpanded);\n }, [initialExpanded]);\n\n // When searching, expand every matching group so hits are visible.\n const displayExpanded = useMemo(() => {\n if (!lowerQuery) return expanded;\n const all = new Set<string>();\n collectAllGroupPaths(filtered, all);\n return all;\n }, [expanded, filtered, lowerQuery]);\n\n const toggle = useCallback((path: string): void => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n return next;\n });\n }, []);\n\n const handleLeafClick = useCallback(\n (path: string) => {\n const varName = makeCssVarName(path, prefix);\n void copy(`var(${varName})`);\n },\n [prefix],\n );\n\n if (!active) return null;\n\n if (!payload) {\n return h(Placeholder, null, 'Waiting for swatchbook preview…');\n }\n\n const showAxisIndicator =\n axes.length > 1 || (axes.length === 1 && axes[0]?.source !== 'synthetic');\n const axisIndicatorText = axes\n .map((axis) => `${axis.name}: ${tuple[axis.name] ?? axis.default}`)\n .join(' · ');\n const disabledAxes = payload?.disabledAxes ?? [];\n const pinnedSample = themes[0]?.input ?? {};\n const disabledIndicatorText = disabledAxes\n .map((name) => `${name}: ${pinnedSample[name] ?? '?'} · pinned`)\n .join(' · ');\n\n return h(\n 'div',\n { style: containerStyle },\n h(\n 'div',\n { style: headerStyle },\n showAxisIndicator &&\n h(\n 'div',\n {\n style: axisIndicatorStyle,\n 'data-testid': 'design-tokens-panel-axis-indicator',\n },\n axisIndicatorText,\n ),\n disabledAxes.length > 0 &&\n h(\n 'div',\n {\n style: { ...axisIndicatorStyle, opacity: 0.5 },\n 'data-testid': 'design-tokens-panel-disabled-axes-indicator',\n },\n disabledIndicatorText,\n ),\n h('input', {\n style: searchInputStyle,\n type: 'search',\n placeholder: `Search ${tokenCount} tokens in ${themeName}…`,\n value: query,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => setQuery(e.target.value),\n }),\n ),\n h(DiagnosticsSection, { diagnostics: payload.diagnostics }),\n h(\n ScrollArea,\n { vertical: true },\n filtered.length === 0\n ? h(Placeholder, null, query ? 'No tokens match this filter.' : 'No tokens in this theme.')\n : h(\n 'div',\n { style: treeWrapperStyle },\n h(\n 'ul',\n { style: treeUlStyle, role: 'tree' },\n filtered.map((node) =>\n h(TreeRow, {\n key: node.path || node.segment,\n node,\n expanded: displayExpanded,\n onToggle: toggle,\n onLeafClick: handleLeafClick,\n prefix,\n }),\n ),\n ),\n ),\n ),\n );\n}\n\ninterface TreeRowProps {\n node: TreeNode;\n expanded: Set<string>;\n onToggle(path: string): void;\n onLeafClick(path: string): void;\n prefix: string;\n}\n\nfunction TreeRow({ node, expanded, onToggle, onLeafClick, prefix }: TreeRowProps): ReactElement {\n if (node.kind === 'leaf') {\n return h(LeafRow, { node, onLeafClick, prefix });\n }\n const isOpen = expanded.has(node.path);\n const onKey = (e: KeyboardEvent<HTMLDivElement>): void => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onToggle(node.path);\n }\n };\n return h(\n 'li',\n { role: 'treeitem', 'aria-expanded': isOpen },\n h(\n 'div',\n {\n role: 'button',\n tabIndex: 0,\n style: groupRowStyle,\n onClick: () => onToggle(node.path),\n onKeyDown: onKey,\n 'data-path': node.path,\n 'data-testid': 'design-tokens-panel-group',\n },\n h('span', { style: caretStyle, 'aria-hidden': true }, isOpen ? '▾' : '▸'),\n h('span', null, node.segment),\n h('span', { style: countStyle }, countLeaves(node)),\n ),\n isOpen &&\n h(\n 'ul',\n { style: nestedUlStyle, role: 'group' },\n node.children.map((c) =>\n h(TreeRow, {\n key: c.path || c.segment,\n node: c,\n expanded,\n onToggle,\n onLeafClick,\n prefix,\n }),\n ),\n ),\n );\n}\n\ninterface LeafRowProps {\n node: LeafNode;\n onLeafClick(path: string): void;\n prefix: string;\n}\n\nfunction LeafRow({ node, onLeafClick, prefix }: LeafRowProps): ReactElement {\n const type = node.token.$type ?? '';\n const value = node.token.$value;\n const displayValue = formatValue(value);\n const isColor = type === 'color' && typeof value === 'object' && value !== null;\n const colorPreview =\n isColor && typeof (value as Record<string, unknown>)['hex'] === 'string'\n ? ((value as Record<string, unknown>)['hex'] as string)\n : null;\n\n const varName = makeCssVarName(node.path, prefix);\n\n return h(\n 'li',\n { role: 'treeitem' },\n h(\n 'button',\n {\n type: 'button',\n style: leafRowStyle,\n onClick: () => onLeafClick(node.path),\n title: `Click to copy var(${varName})`,\n 'data-path': node.path,\n 'data-testid': 'design-tokens-panel-leaf',\n },\n h('span', { style: caretStyle, 'aria-hidden': true }, '•'),\n h('span', null, node.segment),\n type && h('span', { style: typePillStyle }, type),\n h('span', { style: valueStyle }, displayValue),\n colorPreview &&\n h('span', {\n style: { ...swatchStyle, background: colorPreview },\n 'aria-hidden': true,\n }),\n ),\n );\n}\n\nconst severityStyle: Record<DiagnosticSeverity, CSSProperties> = {\n error: { color: '#d64545' },\n warn: { color: '#b08900' },\n info: { opacity: 0.6 },\n};\n\nconst severityLabel: Record<DiagnosticSeverity, string> = {\n error: 'ERROR',\n warn: 'WARN',\n info: 'INFO',\n};\n\nconst diagnosticsSectionStyle: CSSProperties = {\n borderBottom: '1px solid rgba(128,128,128,0.2)',\n};\n\nconst diagnosticsSummaryStyle: CSSProperties = {\n padding: '10px 12px',\n fontSize: 12,\n cursor: 'pointer',\n userSelect: 'none',\n listStyle: 'none',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n};\n\nconst diagnosticRowStyle: CSSProperties = {\n display: 'grid',\n gridTemplateColumns: '60px 1fr',\n gap: 12,\n padding: '8px 12px',\n fontSize: 12,\n borderTop: '1px solid rgba(128,128,128,0.12)',\n};\n\ninterface DiagnosticsSectionProps {\n diagnostics: readonly VirtualDiagnostic[];\n}\n\nfunction DiagnosticsSection({ diagnostics }: DiagnosticsSectionProps): ReactElement {\n const counts = diagnostics.reduce(\n (acc, d) => {\n acc[d.severity] = (acc[d.severity] ?? 0) + 1;\n return acc;\n },\n { error: 0, warn: 0, info: 0 } as Record<DiagnosticSeverity, number>,\n );\n\n const hasErrorsOrWarnings = counts.error > 0 || counts.warn > 0;\n\n const summaryText = (() => {\n if (diagnostics.length === 0) return '✔ OK · no diagnostics';\n const parts: string[] = [];\n if (counts.error > 0) parts.push(`✖ ${counts.error} error${counts.error === 1 ? '' : 's'}`);\n if (counts.warn > 0) parts.push(`⚠ ${counts.warn} warning${counts.warn === 1 ? '' : 's'}`);\n if (counts.info > 0) parts.push(`${counts.info} info`);\n return parts.join(' · ');\n })();\n\n const summaryColor = (() => {\n if (diagnostics.length === 0) return '#30a46c';\n if (counts.error > 0) return '#d64545';\n if (counts.warn > 0) return '#b08900';\n return 'inherit';\n })();\n\n return h(\n 'details',\n {\n style: diagnosticsSectionStyle,\n open: hasErrorsOrWarnings,\n 'data-testid': 'design-tokens-panel-diagnostics',\n },\n h(\n 'summary',\n { style: { ...diagnosticsSummaryStyle, color: summaryColor, fontWeight: 600 } },\n h('span', null, 'Diagnostics'),\n h('span', { style: { fontWeight: 400 } }, summaryText),\n ),\n diagnostics.length === 0\n ? null\n : h(\n 'div',\n null,\n diagnostics.map((d, i) =>\n h(\n 'div',\n { key: `${d.group}-${i}`, style: diagnosticRowStyle },\n h(\n 'span',\n { style: { ...severityStyle[d.severity], fontWeight: 600, fontSize: 10 } },\n severityLabel[d.severity],\n ),\n h(\n 'div',\n null,\n h('div', null, d.message),\n (d.filename || d.group) &&\n h(\n 'div',\n { style: { opacity: 0.5, fontSize: 10, marginTop: 4 } },\n [d.group, d.filename, d.line ? `:${d.line}` : ''].filter(Boolean).join(' · '),\n ),\n ),\n ),\n ),\n ),\n );\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState, type ReactElement } from 'react';\nimport { IconButton, WithTooltipPure } from 'storybook/internal/components';\nimport { addons, types, useGlobals, useStorybookApi } from 'storybook/manager-api';\nimport {\n ADDON_ID,\n AXES_GLOBAL_KEY,\n COLOR_FORMAT_GLOBAL_KEY,\n GLOBAL_KEY,\n INIT_EVENT,\n PANEL_ID,\n TOOL_ID,\n} from '#/constants.ts';\nimport { DesignTokensPanel } from '#/panel.tsx';\n\n/**\n * Use explicit `React.createElement` rather than JSX so the manager bundle\n * doesn't take a hard dependency on `react/jsx-runtime`. Storybook's manager\n * page injects its own React as a runtime global; `react/jsx-runtime` isn't\n * always part of that exposure, which breaks JSX with\n * \"Cannot read properties of undefined (reading 'recentlyCreatedOwnerStacks')\".\n * Mirrors the pattern `@storybook/addon-a11y` uses in its manager.\n */\nconst h = React.createElement;\n\ninterface AxisEntry {\n name: string;\n contexts: readonly string[];\n default: string;\n description?: string;\n source: 'resolver' | 'synthetic';\n}\n\ninterface ThemeEntry {\n name: string;\n input: Record<string, string>;\n sources: string[];\n}\n\ninterface PresetEntry {\n name: string;\n axes: Partial<Record<string, string>>;\n description?: string;\n}\n\ninterface InitPayload {\n axes: readonly AxisEntry[];\n presets: readonly PresetEntry[];\n themes: ThemeEntry[];\n defaultTheme: string | null;\n}\n\nconst EMPTY_AXES: readonly AxisEntry[] = [];\nconst EMPTY_PRESETS: readonly PresetEntry[] = [];\nconst EMPTY_THEMES: ThemeEntry[] = [];\n\n/**\n * Root toolbar glyph — a split-circle (\"yinyang\") mark: a faint filled\n * disc for the full-swatch silhouette, with a darker half-and-inset-disc\n * path reading as a pair of theme variants swapped in place.\n */\nfunction SwatchbookIcon(): ReactElement {\n return h(\n 'svg',\n { width: 14, height: 14, viewBox: '0 0 14 14', 'aria-hidden': true },\n h('circle', { cx: 7, cy: 7, r: 6, fill: 'currentColor', opacity: 0.15 }),\n h('path', {\n d: 'M7 1a6 6 0 0 0 0 12 3 3 0 0 0 0-6 3 3 0 0 1 0-6Z',\n fill: 'currentColor',\n }),\n );\n}\n\nfunction tupleMatchesInput(\n tuple: Readonly<Record<string, string>>,\n input: Readonly<Record<string, string>>,\n): boolean {\n const keys = Object.keys(input);\n if (keys.length === 0) return false;\n return keys.every((k) => input[k] === tuple[k]);\n}\n\nfunction composedNameFor(\n tuple: Readonly<Record<string, string>>,\n themes: readonly ThemeEntry[],\n fallback: string,\n): string {\n const match = themes.find((t) => tupleMatchesInput(tuple, t.input));\n return match?.name ?? fallback;\n}\n\nfunction defaultTupleFor(axes: readonly AxisEntry[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (const axis of axes) out[axis.name] = axis.default;\n return out;\n}\n\n/**\n * Treat the `{ name: 'theme', source: 'synthetic' }` axis — the one core\n * fabricates for single-theme projects with no resolver — as a special case\n * that uses the label \"Theme\" instead of the axis name. Authored single-axis\n * resolvers keep their real axis name (e.g. `mode`).\n */\nfunction displayLabelFor(axis: AxisEntry): string {\n if (axis.source === 'synthetic' && axis.name === 'theme') return 'Theme';\n return axis.name;\n}\n\n/**\n * Compose a preset's sanitized partial tuple with the axis defaults, so\n * applying a preset that only names some axes leaves the omitted ones at\n * their defaults (not blank). Matches the preview decorator's own fallback\n * logic so what the toolbar sends out is what the decorator honors.\n */\nfunction presetTuple(\n preset: PresetEntry,\n axes: readonly AxisEntry[],\n defaults: Readonly<Record<string, string>>,\n): Record<string, string> {\n const out: Record<string, string> = { ...defaults };\n for (const axis of axes) {\n const candidate = preset.axes[axis.name];\n if (candidate !== undefined && axis.contexts.includes(candidate)) {\n out[axis.name] = candidate;\n }\n }\n return out;\n}\n\nfunction tuplesEqual(\n a: Readonly<Record<string, string>>,\n b: Readonly<Record<string, string>>,\n axes: readonly AxisEntry[],\n): boolean {\n for (const axis of axes) {\n if (a[axis.name] !== b[axis.name]) return false;\n }\n return true;\n}\n\nconst SECTION_LABEL_STYLE: React.CSSProperties = {\n padding: '8px 12px 4px',\n fontSize: 11,\n textTransform: 'uppercase',\n letterSpacing: 0.5,\n opacity: 0.6,\n};\n\nconst SECTION_BODY_STYLE: React.CSSProperties = {\n padding: '0 12px 10px',\n display: 'flex',\n flexWrap: 'wrap',\n gap: 4,\n};\n\nconst AXIS_ROW_STYLE: React.CSSProperties = {\n padding: '0 12px 10px',\n display: 'grid',\n gridTemplateColumns: 'max-content 1fr',\n columnGap: 12,\n rowGap: 4,\n alignItems: 'center',\n};\n\nconst AXIS_LABEL_STYLE: React.CSSProperties = {\n fontSize: 12,\n fontWeight: 600,\n opacity: 0.85,\n};\n\nconst AXIS_PILLS_STYLE: React.CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 4,\n};\n\nconst OPTION_PILL_BASE: React.CSSProperties = {\n padding: '3px 8px',\n borderRadius: 4,\n fontSize: 12,\n lineHeight: '18px',\n // Longhand border properties (not the `border` shorthand) so\n // active → inactive only updates `borderColor`'s value instead of\n // *removing* the key from inline style. Removing it lets Storybook's\n // theme paint a stray border-color on the previously-selected pill.\n borderWidth: 1,\n borderStyle: 'solid',\n borderColor: 'transparent',\n background: 'transparent',\n cursor: 'pointer',\n color: 'inherit',\n outline: 'none',\n boxShadow: 'none',\n};\n\nconst OPTION_PILL_ACTIVE: React.CSSProperties = {\n ...OPTION_PILL_BASE,\n fontWeight: 600,\n background: 'rgba(0, 122, 255, 0.12)',\n borderColor: 'rgba(0, 122, 255, 0.45)',\n};\n\nconst PRESET_PILL_MODIFIED: React.CSSProperties = {\n display: 'inline-block',\n width: 6,\n height: 6,\n marginLeft: 6,\n borderRadius: '50%',\n background: 'currentColor',\n opacity: 0.6,\n verticalAlign: 'middle',\n};\n\nconst DIVIDER_STYLE: React.CSSProperties = {\n height: 1,\n background: 'currentColor',\n opacity: 0.1,\n margin: '2px 8px',\n};\n\ninterface OptionPillProps {\n label: string;\n active: boolean;\n title?: string;\n onClick: () => void;\n trailing?: ReactElement | null;\n}\n\nfunction OptionPill({ label, active, title, onClick, trailing }: OptionPillProps): ReactElement {\n return h(\n 'button',\n {\n type: 'button',\n title,\n onClick,\n // Skip focus on mouse click so Storybook's `:focus` border-color\n // theming doesn't stick on the previously-clicked pill. Keyboard\n // tabbing still lands focus normally — preventDefault on mousedown\n // only blocks the implicit focus-on-click behavior.\n onMouseDown: (event) => event.preventDefault(),\n style: active ? OPTION_PILL_ACTIVE : OPTION_PILL_BASE,\n },\n label,\n trailing ?? null,\n );\n}\n\ninterface PresetsSectionProps {\n presets: readonly PresetEntry[];\n axes: readonly AxisEntry[];\n defaults: Readonly<Record<string, string>>;\n activeTuple: Readonly<Record<string, string>>;\n lastApplied: string | null;\n onApply: (preset: PresetEntry) => void;\n}\n\nfunction PresetsSection({\n presets,\n axes,\n defaults,\n activeTuple,\n lastApplied,\n onApply,\n}: PresetsSectionProps): ReactElement {\n return h(\n 'div',\n null,\n h('div', { style: SECTION_LABEL_STYLE }, 'Presets'),\n h(\n 'div',\n { style: SECTION_BODY_STYLE },\n ...presets.map((preset) => {\n const tuple = presetTuple(preset, axes, defaults);\n const matches = tuplesEqual(tuple, activeTuple, axes);\n const modified = !matches && preset.name === lastApplied;\n const title = preset.description ? `${preset.name} — ${preset.description}` : preset.name;\n return h(OptionPill, {\n key: `${TOOL_ID}/preset/${preset.name}`,\n label: preset.name,\n active: matches,\n title,\n onClick: () => onApply(preset),\n trailing: modified\n ? h('span', { 'aria-hidden': true, style: PRESET_PILL_MODIFIED })\n : null,\n });\n }),\n ),\n );\n}\n\ninterface AxisSectionProps {\n axis: AxisEntry;\n active: string;\n onSelect: (next: string) => void;\n}\n\nfunction AxisSection({ axis, active, onSelect }: AxisSectionProps): ReactElement {\n const label = displayLabelFor(axis);\n return h(\n 'div',\n { style: AXIS_ROW_STYLE },\n h('div', { style: AXIS_LABEL_STYLE, title: axis.description }, label),\n h(\n 'div',\n { style: AXIS_PILLS_STYLE },\n ...axis.contexts.map((ctx) =>\n h(OptionPill, {\n key: `${TOOL_ID}/${axis.name}/${ctx}`,\n label: ctx,\n active: ctx === active,\n onClick: () => onSelect(ctx),\n }),\n ),\n ),\n );\n}\n\nconst COLOR_FORMAT_OPTIONS: readonly { id: string; label: string }[] = [\n { id: 'hex', label: 'Hex' },\n { id: 'rgb', label: 'RGB' },\n { id: 'hsl', label: 'HSL' },\n { id: 'oklch', label: 'OKLCH' },\n { id: 'raw', label: 'Raw (JSON)' },\n];\n\ninterface ColorFormatSectionProps {\n active: string;\n onSelect: (next: string) => void;\n}\n\nfunction ColorFormatSection({ active, onSelect }: ColorFormatSectionProps): ReactElement {\n return h(\n 'div',\n null,\n h('div', { style: SECTION_LABEL_STYLE }, 'Color format'),\n h(\n 'div',\n { style: SECTION_BODY_STYLE },\n ...COLOR_FORMAT_OPTIONS.map((opt) =>\n h(OptionPill, {\n key: `${TOOL_ID}/color-format/${opt.id}`,\n label: opt.label,\n active: opt.id === active,\n onClick: () => onSelect(opt.id),\n }),\n ),\n ),\n );\n}\n\ninterface PopoverBodyProps {\n axes: readonly AxisEntry[];\n presets: readonly PresetEntry[];\n defaults: Readonly<Record<string, string>>;\n activeTuple: Readonly<Record<string, string>>;\n activeColorFormat: string;\n lastApplied: string | null;\n onApplyPreset: (preset: PresetEntry) => void;\n onSelectAxis: (axisName: string, next: string) => void;\n onSelectColorFormat: (next: string) => void;\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;\n}\n\nfunction PopoverBody(props: PopoverBodyProps): ReactElement {\n const {\n axes,\n presets,\n defaults,\n activeTuple,\n activeColorFormat,\n lastApplied,\n onApplyPreset,\n onSelectAxis,\n onSelectColorFormat,\n onKeyDown,\n } = props;\n const sections: ReactElement[] = [];\n if (presets.length > 0) {\n sections.push(\n h(PresetsSection, {\n key: 'presets',\n presets,\n axes,\n defaults,\n activeTuple,\n lastApplied,\n onApply: onApplyPreset,\n }),\n h('div', { key: 'presets-divider', style: DIVIDER_STYLE }),\n );\n }\n axes.forEach((axis, idx) => {\n sections.push(\n h(AxisSection, {\n key: `axis-${axis.name}`,\n axis,\n active: activeTuple[axis.name] ?? axis.default,\n onSelect: (next) => onSelectAxis(axis.name, next),\n }),\n );\n if (idx === axes.length - 1) {\n sections.push(h('div', { key: 'axes-divider', style: DIVIDER_STYLE }));\n }\n });\n sections.push(\n h(ColorFormatSection, {\n key: 'color-format',\n active: activeColorFormat,\n onSelect: onSelectColorFormat,\n }),\n );\n return h(\n 'div',\n {\n role: 'menu',\n tabIndex: -1,\n onKeyDown,\n style: { minWidth: 260, padding: '4px 0', outline: 'none' },\n 'data-testid': 'swatchbook-toolbar-popover',\n },\n ...sections,\n );\n}\n\nfunction AxesToolbar(): ReactElement {\n const [globals, updateGlobals] = useGlobals();\n const api = useStorybookApi();\n const [payload, setPayload] = useState<InitPayload | null>(null);\n const [open, setOpen] = useState(false);\n const bodyRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n const channel = addons.getChannel();\n const onInit = (next: InitPayload): void => setPayload(next);\n channel.on(INIT_EVENT, onInit);\n return () => {\n channel.off(INIT_EVENT, onInit);\n };\n }, []);\n\n const axes = payload?.axes ?? EMPTY_AXES;\n const presets = payload?.presets ?? EMPTY_PRESETS;\n const themes = payload?.themes ?? EMPTY_THEMES;\n const defaults = useMemo(() => defaultTupleFor(axes), [axes]);\n const [lastApplied, setLastApplied] = useState<string | null>(null);\n const globalTuple = globals[AXES_GLOBAL_KEY] as Record<string, string> | undefined;\n const activeColorFormat = (globals[COLOR_FORMAT_GLOBAL_KEY] as string | undefined) ?? 'hex';\n\n const activeTuple = useMemo<Record<string, string>>(() => {\n const out: Record<string, string> = { ...defaults };\n if (globalTuple) {\n for (const axis of axes) {\n const candidate = globalTuple[axis.name];\n if (candidate !== undefined && axis.contexts.includes(candidate)) {\n out[axis.name] = candidate;\n }\n }\n }\n return out;\n }, [axes, defaults, globalTuple]);\n\n const setAxis = useCallback(\n (axisName: string, next: string): void => {\n const tuple: Record<string, string> = { ...activeTuple, [axisName]: next };\n const fallback = payload?.defaultTheme ?? themes[0]?.name ?? '';\n const composed = composedNameFor(tuple, themes, fallback);\n updateGlobals({ [AXES_GLOBAL_KEY]: tuple, [GLOBAL_KEY]: composed });\n },\n [activeTuple, themes, payload?.defaultTheme, updateGlobals],\n );\n\n const applyPreset = useCallback(\n (preset: PresetEntry): void => {\n const tuple = presetTuple(preset, axes, defaults);\n const fallback = payload?.defaultTheme ?? themes[0]?.name ?? '';\n const composed = composedNameFor(tuple, themes, fallback);\n updateGlobals({ [AXES_GLOBAL_KEY]: tuple, [GLOBAL_KEY]: composed });\n setLastApplied(preset.name);\n },\n [axes, defaults, themes, payload?.defaultTheme, updateGlobals],\n );\n\n useEffect(() => {\n if (axes.length === 0) return;\n /**\n * alt+T cycles the primary (first) axis's contexts, keeping the rest\n * of the tuple pinned. With multi-axis projects this makes the shortcut\n * predictable — you always know which wheel you're spinning. For\n * single-axis projects the behavior is identical to the pre-N-dropdown\n * toolbar (cycle through every theme).\n */\n const primary = axes[0];\n if (!primary) return;\n api.setAddonShortcut(ADDON_ID, {\n label: `Cycle swatchbook ${displayLabelFor(primary)}`,\n defaultShortcut: ['alt', 'T'],\n actionName: 'cycleAxis',\n showInMenu: true,\n action: () => {\n const current = activeTuple[primary.name] ?? primary.default;\n const idx = primary.contexts.indexOf(current);\n const next = primary.contexts[(idx + 1) % primary.contexts.length];\n if (next !== undefined) setAxis(primary.name, next);\n },\n });\n }, [api, axes, activeTuple, setAxis]);\n\n const handleKeyDown = useCallback((event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n setOpen(false);\n }\n }, []);\n\n /**\n * Escape closes even when focus hasn't entered the popover yet (e.g. the\n * user opened it via click and the mouse is still over the canvas). We\n * attach a document-level listener when open.\n */\n useEffect(() => {\n if (!open) return;\n const onDocKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') setOpen(false);\n };\n document.addEventListener('keydown', onDocKey);\n return () => document.removeEventListener('keydown', onDocKey);\n }, [open]);\n\n if (axes.length === 0) {\n return h(\n IconButton,\n { key: TOOL_ID, title: 'Swatchbook theme (loading…)', disabled: true },\n h(SwatchbookIcon),\n );\n }\n\n const summary = axes.map((a) => activeTuple[a.name] ?? a.default).join(' · ');\n const title = `Swatchbook · ${summary}`;\n\n const button = h(\n IconButton,\n {\n key: TOOL_ID,\n title,\n active: open,\n onClick: () => setOpen((prev) => !prev),\n },\n h(SwatchbookIcon),\n );\n\n const tooltipBody = h(PopoverBody, {\n axes,\n presets,\n defaults,\n activeTuple,\n activeColorFormat,\n lastApplied,\n onApplyPreset: applyPreset,\n onSelectAxis: setAxis,\n onSelectColorFormat: (next: string) => updateGlobals({ [COLOR_FORMAT_GLOBAL_KEY]: next }),\n onKeyDown: handleKeyDown,\n });\n\n return h(\n 'span',\n { ref: bodyRef, style: { display: 'inline-flex', alignItems: 'center' } },\n h(WithTooltipPure, {\n placement: 'bottom',\n trigger: 'click',\n visible: open,\n onVisibleChange: (next: boolean) => setOpen(next),\n closeOnOutsideClick: true,\n tooltip: tooltipBody,\n children: button,\n }),\n );\n}\n\naddons.register(ADDON_ID, () => {\n addons.add(TOOL_ID, {\n type: types.TOOL,\n title: 'Swatchbook theme',\n match: ({ viewMode, tabId }) => !tabId && (viewMode === 'story' || viewMode === 'docs'),\n render: () => h(AxesToolbar),\n });\n\n addons.add(PANEL_ID, {\n type: types.PANEL,\n title: 'Design Tokens',\n match: ({ viewMode }) => viewMode === 'story',\n render: ({ active }) => h(DesignTokensPanel, { active: !!active }),\n });\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"manager.mjs","names":["h"],"sources":["../src/panel.tsx","../src/manager.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactElement,\n} from 'react';\nimport { Placeholder, ScrollArea } from 'storybook/internal/components';\nimport { addons, useGlobals } from 'storybook/manager-api';\nimport { AXES_GLOBAL_KEY, GLOBAL_KEY, INIT_EVENT } from '#/constants.ts';\n\n/** `React.createElement` alias so the manager bundle avoids `react/jsx-runtime`. */\nconst h = React.createElement;\n\ninterface VirtualToken {\n $type?: string;\n $value?: unknown;\n $description?: string;\n}\n\ninterface VirtualTheme {\n name: string;\n input: Record<string, string>;\n sources: string[];\n}\n\ninterface VirtualAxis {\n name: string;\n contexts: readonly string[];\n default: string;\n description?: string;\n source: 'resolver' | 'synthetic';\n}\n\ntype DiagnosticSeverity = 'error' | 'warn' | 'info';\n\ninterface VirtualDiagnostic {\n severity: DiagnosticSeverity;\n group: string;\n message: string;\n filename?: string;\n line?: number;\n column?: number;\n}\n\ninterface InitPayload {\n axes: VirtualAxis[];\n disabledAxes: readonly string[];\n themes: VirtualTheme[];\n defaultTheme: string | null;\n themesResolved: Record<string, Record<string, VirtualToken>>;\n diagnostics: VirtualDiagnostic[];\n cssVarPrefix: string;\n}\n\nfunction usePayload(): InitPayload | null {\n const [payload, setPayload] = useState<InitPayload | null>(null);\n useEffect(() => {\n const channel = addons.getChannel();\n const onInit = (next: InitPayload): void => setPayload(next);\n channel.on(INIT_EVENT, onInit);\n return () => {\n channel.off(INIT_EVENT, onInit);\n };\n }, []);\n return payload;\n}\n\nfunction makeCssVarName(path: string, prefix: string): string {\n const tail = path.replaceAll('.', '-');\n return prefix ? `--${prefix}-${tail}` : `--${tail}`;\n}\n\nasync function copy(text: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n /* clipboard access denied — no fallback, the user can read the var name from the row */\n }\n}\n\n/** Format a token `$value` into a short display string. */\nfunction formatValue(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'string' || typeof value === 'number') return String(value);\n if (typeof value === 'object') {\n const v = value as Record<string, unknown>;\n if (typeof v['hex'] === 'string') return v['hex'] as string;\n if ('value' in v && 'unit' in v) return `${String(v['value'])}${String(v['unit'])}`;\n return JSON.stringify(value).slice(0, 80);\n }\n return String(value);\n}\n\nconst containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n};\n\nconst headerStyle: CSSProperties = {\n padding: '8px 12px',\n borderBottom: '1px solid rgba(128,128,128,0.2)',\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n};\n\nconst axisIndicatorStyle: CSSProperties = {\n fontSize: 11,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, \"Liberation Mono\", monospace',\n opacity: 0.7,\n};\n\nconst treeWrapperStyle: CSSProperties = {\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 12,\n padding: 8,\n};\n\nconst groupRowStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 6px',\n borderRadius: 4,\n cursor: 'pointer',\n userSelect: 'none',\n outline: 'none',\n};\n\nconst leafRowStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '4px 6px',\n borderRadius: 4,\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: 'inherit',\n width: '100%',\n textAlign: 'left',\n fontFamily: 'inherit',\n fontSize: 'inherit',\n outline: 'none',\n};\n\nconst caretStyle: CSSProperties = {\n display: 'inline-block',\n width: 12,\n textAlign: 'center',\n opacity: 0.6,\n};\n\nconst treeUlStyle: CSSProperties = { listStyle: 'none', margin: 0, padding: 0 };\n\nconst nestedUlStyle: CSSProperties = {\n listStyle: 'none',\n margin: 0,\n paddingLeft: 18,\n borderLeft: '1px solid rgba(128,128,128,0.2)',\n};\n\nconst typePillStyle: CSSProperties = {\n display: 'inline-block',\n padding: '1px 6px',\n borderRadius: 4,\n fontSize: 10,\n letterSpacing: 0.5,\n textTransform: 'uppercase',\n background: 'rgba(128,128,128,0.15)',\n};\n\nconst valueStyle: CSSProperties = {\n marginLeft: 'auto',\n opacity: 0.7,\n fontSize: 11,\n maxWidth: '40%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n};\n\nconst countStyle: CSSProperties = {\n marginLeft: 'auto',\n fontSize: 11,\n opacity: 0.7,\n};\n\nconst swatchStyle: CSSProperties = {\n display: 'inline-block',\n width: 14,\n height: 14,\n borderRadius: 3,\n border: '1px solid rgba(128,128,128,0.3)',\n marginLeft: 8,\n};\n\nconst searchInputStyle: CSSProperties = {\n width: '100%',\n padding: '4px 8px',\n fontSize: 12,\n border: '1px solid rgba(128,128,128,0.3)',\n borderRadius: 4,\n background: 'transparent',\n color: 'inherit',\n};\n\ninterface LeafNode {\n kind: 'leaf';\n segment: string;\n path: string;\n token: VirtualToken;\n}\n\ninterface GroupNode {\n kind: 'group';\n segment: string;\n path: string;\n children: TreeNode[];\n}\n\ntype TreeNode = LeafNode | GroupNode;\n\nfunction buildTree(resolved: Record<string, VirtualToken>): TreeNode[] {\n const rootNode: GroupNode = { kind: 'group', segment: '', path: '', children: [] };\n for (const [path, token] of Object.entries(resolved)) {\n const segments = path.split('.');\n let node: GroupNode = rootNode;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const seg = segments[i] as string;\n const prefix = segments.slice(0, i + 1).join('.');\n let child = node.children.find(\n (c): c is GroupNode => c.kind === 'group' && c.segment === seg,\n );\n if (!child) {\n child = { kind: 'group', segment: seg, path: prefix, children: [] };\n node.children.push(child);\n }\n node = child;\n }\n const leafSegment = segments[segments.length - 1] as string;\n node.children.push({ kind: 'leaf', segment: leafSegment, path, token });\n }\n sortTree(rootNode);\n return rootNode.children;\n}\n\nfunction sortTree(node: GroupNode): void {\n node.children.sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'group' ? -1 : 1;\n return a.segment.localeCompare(b.segment);\n });\n for (const c of node.children) {\n if (c.kind === 'group') sortTree(c);\n }\n}\n\nfunction collectInitialExpanded(nodes: TreeNode[], remainingDepth: number, out: Set<string>): void {\n if (remainingDepth <= 0) return;\n for (const node of nodes) {\n if (node.kind !== 'group') continue;\n out.add(node.path);\n collectInitialExpanded(node.children, remainingDepth - 1, out);\n }\n}\n\nfunction countLeaves(node: TreeNode): number {\n if (node.kind === 'leaf') return 1;\n let n = 0;\n for (const c of node.children) n += countLeaves(c);\n return n;\n}\n\nfunction filterTree(nodes: TreeNode[], query: string): TreeNode[] {\n if (!query) return nodes;\n const out: TreeNode[] = [];\n for (const node of nodes) {\n if (node.kind === 'leaf') {\n if (node.path.toLowerCase().includes(query)) out.push(node);\n continue;\n }\n const filteredChildren = filterTree(node.children, query);\n if (filteredChildren.length > 0) {\n out.push({ ...node, children: filteredChildren });\n }\n }\n return out;\n}\n\nfunction collectAllGroupPaths(nodes: TreeNode[], out: Set<string>): void {\n for (const node of nodes) {\n if (node.kind === 'group') {\n out.add(node.path);\n collectAllGroupPaths(node.children, out);\n }\n }\n}\n\ninterface PanelProps {\n active: boolean;\n}\n\nexport function DesignTokensPanel({ active }: PanelProps): ReactElement | null {\n const payload = usePayload();\n const [globals] = useGlobals();\n const [query, setQuery] = useState('');\n\n const axes = useMemo(() => payload?.axes ?? [], [payload]);\n const themes = useMemo(() => payload?.themes ?? [], [payload]);\n const globalAxes = globals[AXES_GLOBAL_KEY] as Record<string, string> | undefined;\n const globalTheme = globals[GLOBAL_KEY] as string | undefined;\n\n const tuple: Record<string, string> = useMemo(() => {\n const out: Record<string, string> = {};\n for (const axis of axes) out[axis.name] = axis.default;\n if (globalAxes && typeof globalAxes === 'object') {\n for (const axis of axes) {\n const candidate = globalAxes[axis.name];\n if (candidate && axis.contexts.includes(candidate)) out[axis.name] = candidate;\n }\n return out;\n }\n if (globalTheme) {\n const match = themes.find((t) => t.name === globalTheme);\n if (match) {\n for (const axis of axes) {\n const candidate = match.input[axis.name];\n if (candidate && axis.contexts.includes(candidate)) out[axis.name] = candidate;\n }\n }\n }\n return out;\n }, [axes, themes, globalAxes, globalTheme]);\n\n const themeName = useMemo(() => {\n const match = themes.find((t) => {\n const input = t.input;\n return Object.keys(input).every((k) => input[k] === tuple[k]);\n });\n return match?.name ?? globalTheme ?? payload?.defaultTheme ?? '';\n }, [themes, tuple, globalTheme, payload]);\n\n const prefix = payload?.cssVarPrefix ?? '';\n const tokens = useMemo(() => payload?.themesResolved[themeName] ?? {}, [payload, themeName]);\n const tokenCount = Object.keys(tokens).length;\n\n const tree = useMemo(() => buildTree(tokens), [tokens]);\n const lowerQuery = query.toLowerCase();\n const filtered = useMemo(() => filterTree(tree, lowerQuery), [tree, lowerQuery]);\n\n const initialExpanded = useMemo(() => {\n const out = new Set<string>();\n collectInitialExpanded(tree, 1, out);\n return out;\n }, [tree]);\n\n const [expanded, setExpanded] = useState<Set<string>>(initialExpanded);\n useEffect(() => {\n setExpanded(initialExpanded);\n }, [initialExpanded]);\n\n // When searching, expand every matching group so hits are visible.\n const displayExpanded = useMemo(() => {\n if (!lowerQuery) return expanded;\n const all = new Set<string>();\n collectAllGroupPaths(filtered, all);\n return all;\n }, [expanded, filtered, lowerQuery]);\n\n const toggle = useCallback((path: string): void => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n return next;\n });\n }, []);\n\n const handleLeafClick = useCallback(\n (path: string) => {\n const varName = makeCssVarName(path, prefix);\n void copy(`var(${varName})`);\n },\n [prefix],\n );\n\n if (!active) return null;\n\n if (!payload) {\n return h(Placeholder, null, 'Waiting for swatchbook preview…');\n }\n\n const showAxisIndicator =\n axes.length > 1 || (axes.length === 1 && axes[0]?.source !== 'synthetic');\n const axisIndicatorText = axes\n .map((axis) => `${axis.name}: ${tuple[axis.name] ?? axis.default}`)\n .join(' · ');\n const disabledAxes = payload?.disabledAxes ?? [];\n const pinnedSample = themes[0]?.input ?? {};\n const disabledIndicatorText = disabledAxes\n .map((name) => `${name}: ${pinnedSample[name] ?? '?'} · pinned`)\n .join(' · ');\n\n return h(\n 'div',\n { style: containerStyle },\n h(\n 'div',\n { style: headerStyle },\n showAxisIndicator &&\n h(\n 'div',\n {\n style: axisIndicatorStyle,\n 'data-testid': 'design-tokens-panel-axis-indicator',\n },\n axisIndicatorText,\n ),\n disabledAxes.length > 0 &&\n h(\n 'div',\n {\n style: { ...axisIndicatorStyle, opacity: 0.5 },\n 'data-testid': 'design-tokens-panel-disabled-axes-indicator',\n },\n disabledIndicatorText,\n ),\n h('input', {\n style: searchInputStyle,\n type: 'search',\n placeholder: `Search ${tokenCount} tokens in ${themeName}…`,\n 'aria-label': 'Search tokens',\n value: query,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => setQuery(e.target.value),\n }),\n ),\n h(DiagnosticsSection, { diagnostics: payload.diagnostics }),\n h(\n ScrollArea,\n { vertical: true },\n filtered.length === 0\n ? h(Placeholder, null, query ? 'No tokens match this filter.' : 'No tokens in this theme.')\n : h(\n 'div',\n { style: treeWrapperStyle },\n h(\n 'ul',\n { style: treeUlStyle, role: 'tree' },\n filtered.map((node) =>\n h(TreeRow, {\n key: node.path || node.segment,\n node,\n expanded: displayExpanded,\n onToggle: toggle,\n onLeafClick: handleLeafClick,\n prefix,\n }),\n ),\n ),\n ),\n ),\n );\n}\n\ninterface TreeRowProps {\n node: TreeNode;\n expanded: Set<string>;\n onToggle(path: string): void;\n onLeafClick(path: string): void;\n prefix: string;\n}\n\nfunction TreeRow({ node, expanded, onToggle, onLeafClick, prefix }: TreeRowProps): ReactElement {\n if (node.kind === 'leaf') {\n return h(LeafRow, { node, onLeafClick, prefix });\n }\n const isOpen = expanded.has(node.path);\n const onKey = (e: KeyboardEvent<HTMLDivElement>): void => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onToggle(node.path);\n }\n };\n return h(\n 'li',\n { role: 'treeitem', 'aria-expanded': isOpen },\n h(\n 'div',\n {\n role: 'button',\n tabIndex: 0,\n style: groupRowStyle,\n onClick: () => onToggle(node.path),\n onKeyDown: onKey,\n 'data-path': node.path,\n 'data-testid': 'design-tokens-panel-group',\n },\n h('span', { style: caretStyle, 'aria-hidden': true }, isOpen ? '▾' : '▸'),\n h('span', null, node.segment),\n h('span', { style: countStyle }, countLeaves(node)),\n ),\n isOpen &&\n h(\n 'ul',\n { style: nestedUlStyle, role: 'group' },\n node.children.map((c) =>\n h(TreeRow, {\n key: c.path || c.segment,\n node: c,\n expanded,\n onToggle,\n onLeafClick,\n prefix,\n }),\n ),\n ),\n );\n}\n\ninterface LeafRowProps {\n node: LeafNode;\n onLeafClick(path: string): void;\n prefix: string;\n}\n\nfunction LeafRow({ node, onLeafClick, prefix }: LeafRowProps): ReactElement {\n const type = node.token.$type ?? '';\n const value = node.token.$value;\n const displayValue = formatValue(value);\n const isColor = type === 'color' && typeof value === 'object' && value !== null;\n const colorPreview =\n isColor && typeof (value as Record<string, unknown>)['hex'] === 'string'\n ? ((value as Record<string, unknown>)['hex'] as string)\n : null;\n\n const varName = makeCssVarName(node.path, prefix);\n\n return h(\n 'li',\n { role: 'treeitem' },\n h(\n 'button',\n {\n type: 'button',\n style: leafRowStyle,\n onClick: () => onLeafClick(node.path),\n title: `Click to copy var(${varName})`,\n 'data-path': node.path,\n 'data-testid': 'design-tokens-panel-leaf',\n },\n h('span', { style: caretStyle, 'aria-hidden': true }, '•'),\n h('span', null, node.segment),\n type && h('span', { style: typePillStyle }, type),\n h('span', { style: valueStyle }, displayValue),\n colorPreview &&\n h('span', {\n style: { ...swatchStyle, background: colorPreview },\n 'aria-hidden': true,\n }),\n ),\n );\n}\n\nconst severityStyle: Record<DiagnosticSeverity, CSSProperties> = {\n error: { color: '#d64545' },\n warn: { color: '#b08900' },\n info: { opacity: 0.6 },\n};\n\nconst severityLabel: Record<DiagnosticSeverity, string> = {\n error: 'ERROR',\n warn: 'WARN',\n info: 'INFO',\n};\n\nconst diagnosticsSectionStyle: CSSProperties = {\n borderBottom: '1px solid rgba(128,128,128,0.2)',\n};\n\nconst diagnosticsSummaryStyle: CSSProperties = {\n padding: '10px 12px',\n fontSize: 12,\n cursor: 'pointer',\n userSelect: 'none',\n listStyle: 'none',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n};\n\nconst diagnosticRowStyle: CSSProperties = {\n display: 'grid',\n gridTemplateColumns: '60px 1fr',\n gap: 12,\n padding: '8px 12px',\n fontSize: 12,\n borderTop: '1px solid rgba(128,128,128,0.12)',\n};\n\ninterface DiagnosticsSectionProps {\n diagnostics: readonly VirtualDiagnostic[];\n}\n\nfunction DiagnosticsSection({ diagnostics }: DiagnosticsSectionProps): ReactElement {\n const counts = diagnostics.reduce(\n (acc, d) => {\n acc[d.severity] = (acc[d.severity] ?? 0) + 1;\n return acc;\n },\n { error: 0, warn: 0, info: 0 } as Record<DiagnosticSeverity, number>,\n );\n\n const hasErrorsOrWarnings = counts.error > 0 || counts.warn > 0;\n\n const summaryText = (() => {\n if (diagnostics.length === 0) return '✔ OK · no diagnostics';\n const parts: string[] = [];\n if (counts.error > 0) parts.push(`✖ ${counts.error} error${counts.error === 1 ? '' : 's'}`);\n if (counts.warn > 0) parts.push(`⚠ ${counts.warn} warning${counts.warn === 1 ? '' : 's'}`);\n if (counts.info > 0) parts.push(`${counts.info} info`);\n return parts.join(' · ');\n })();\n\n const summaryColor = (() => {\n if (diagnostics.length === 0) return '#30a46c';\n if (counts.error > 0) return '#d64545';\n if (counts.warn > 0) return '#b08900';\n return 'inherit';\n })();\n\n return h(\n 'details',\n {\n style: diagnosticsSectionStyle,\n open: hasErrorsOrWarnings,\n 'data-testid': 'design-tokens-panel-diagnostics',\n },\n h(\n 'summary',\n { style: { ...diagnosticsSummaryStyle, color: summaryColor, fontWeight: 600 } },\n h('span', null, 'Diagnostics'),\n h('span', { style: { fontWeight: 400 } }, summaryText),\n ),\n diagnostics.length === 0\n ? null\n : h(\n 'div',\n null,\n diagnostics.map((d, i) =>\n h(\n 'div',\n { key: `${d.group}-${i}`, style: diagnosticRowStyle },\n h(\n 'span',\n { style: { ...severityStyle[d.severity], fontWeight: 600, fontSize: 10 } },\n severityLabel[d.severity],\n ),\n h(\n 'div',\n null,\n h('div', null, d.message),\n (d.filename || d.group) &&\n h(\n 'div',\n { style: { opacity: 0.5, fontSize: 10, marginTop: 4 } },\n [d.group, d.filename, d.line ? `:${d.line}` : ''].filter(Boolean).join(' · '),\n ),\n ),\n ),\n ),\n ),\n );\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState, type ReactElement } from 'react';\nimport { IconButton, WithTooltipPure } from 'storybook/internal/components';\nimport { addons, types, useGlobals, useStorybookApi } from 'storybook/manager-api';\nimport {\n ADDON_ID,\n AXES_GLOBAL_KEY,\n COLOR_FORMAT_GLOBAL_KEY,\n GLOBAL_KEY,\n INIT_EVENT,\n PANEL_ID,\n TOOL_ID,\n} from '#/constants.ts';\nimport { DesignTokensPanel } from '#/panel.tsx';\n\n/**\n * Use explicit `React.createElement` rather than JSX so the manager bundle\n * doesn't take a hard dependency on `react/jsx-runtime`. Storybook's manager\n * page injects its own React as a runtime global; `react/jsx-runtime` isn't\n * always part of that exposure, which breaks JSX with\n * \"Cannot read properties of undefined (reading 'recentlyCreatedOwnerStacks')\".\n * Mirrors the pattern `@storybook/addon-a11y` uses in its manager.\n */\nconst h = React.createElement;\n\ninterface AxisEntry {\n name: string;\n contexts: readonly string[];\n default: string;\n description?: string;\n source: 'resolver' | 'synthetic';\n}\n\ninterface ThemeEntry {\n name: string;\n input: Record<string, string>;\n sources: string[];\n}\n\ninterface PresetEntry {\n name: string;\n axes: Partial<Record<string, string>>;\n description?: string;\n}\n\ninterface InitPayload {\n axes: readonly AxisEntry[];\n presets: readonly PresetEntry[];\n themes: ThemeEntry[];\n defaultTheme: string | null;\n}\n\nconst EMPTY_AXES: readonly AxisEntry[] = [];\nconst EMPTY_PRESETS: readonly PresetEntry[] = [];\nconst EMPTY_THEMES: ThemeEntry[] = [];\n\n/**\n * Root toolbar glyph — a split-circle (\"yinyang\") mark: a faint filled\n * disc for the full-swatch silhouette, with a darker half-and-inset-disc\n * path reading as a pair of theme variants swapped in place.\n */\nfunction SwatchbookIcon(): ReactElement {\n return h(\n 'svg',\n { width: 14, height: 14, viewBox: '0 0 14 14', 'aria-hidden': true },\n h('circle', { cx: 7, cy: 7, r: 6, fill: 'currentColor', opacity: 0.15 }),\n h('path', {\n d: 'M7 1a6 6 0 0 0 0 12 3 3 0 0 0 0-6 3 3 0 0 1 0-6Z',\n fill: 'currentColor',\n }),\n );\n}\n\nfunction tupleMatchesInput(\n tuple: Readonly<Record<string, string>>,\n input: Readonly<Record<string, string>>,\n): boolean {\n const keys = Object.keys(input);\n if (keys.length === 0) return false;\n return keys.every((k) => input[k] === tuple[k]);\n}\n\nfunction composedNameFor(\n tuple: Readonly<Record<string, string>>,\n themes: readonly ThemeEntry[],\n fallback: string,\n): string {\n const match = themes.find((t) => tupleMatchesInput(tuple, t.input));\n return match?.name ?? fallback;\n}\n\nfunction defaultTupleFor(axes: readonly AxisEntry[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (const axis of axes) out[axis.name] = axis.default;\n return out;\n}\n\n/**\n * Treat the `{ name: 'theme', source: 'synthetic' }` axis — the one core\n * fabricates for single-theme projects with no resolver — as a special case\n * that uses the label \"Theme\" instead of the axis name. Authored single-axis\n * resolvers keep their real axis name (e.g. `mode`).\n */\nfunction displayLabelFor(axis: AxisEntry): string {\n if (axis.source === 'synthetic' && axis.name === 'theme') return 'Theme';\n return axis.name;\n}\n\n/**\n * Compose a preset's sanitized partial tuple with the axis defaults, so\n * applying a preset that only names some axes leaves the omitted ones at\n * their defaults (not blank). Matches the preview decorator's own fallback\n * logic so what the toolbar sends out is what the decorator honors.\n */\nfunction presetTuple(\n preset: PresetEntry,\n axes: readonly AxisEntry[],\n defaults: Readonly<Record<string, string>>,\n): Record<string, string> {\n const out: Record<string, string> = { ...defaults };\n for (const axis of axes) {\n const candidate = preset.axes[axis.name];\n if (candidate !== undefined && axis.contexts.includes(candidate)) {\n out[axis.name] = candidate;\n }\n }\n return out;\n}\n\nfunction tuplesEqual(\n a: Readonly<Record<string, string>>,\n b: Readonly<Record<string, string>>,\n axes: readonly AxisEntry[],\n): boolean {\n for (const axis of axes) {\n if (a[axis.name] !== b[axis.name]) return false;\n }\n return true;\n}\n\nconst SECTION_LABEL_STYLE: React.CSSProperties = {\n padding: '8px 12px 4px',\n fontSize: 11,\n textTransform: 'uppercase',\n letterSpacing: 0.5,\n opacity: 0.6,\n};\n\nconst SECTION_BODY_STYLE: React.CSSProperties = {\n padding: '0 12px 10px',\n display: 'flex',\n flexWrap: 'wrap',\n gap: 4,\n};\n\nconst AXIS_ROW_STYLE: React.CSSProperties = {\n padding: '0 12px 10px',\n display: 'grid',\n gridTemplateColumns: 'max-content 1fr',\n columnGap: 12,\n rowGap: 4,\n alignItems: 'center',\n};\n\nconst AXIS_LABEL_STYLE: React.CSSProperties = {\n fontSize: 12,\n fontWeight: 600,\n opacity: 0.85,\n};\n\nconst AXIS_PILLS_STYLE: React.CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 4,\n};\n\nconst OPTION_PILL_BASE: React.CSSProperties = {\n padding: '3px 8px',\n borderRadius: 4,\n fontSize: 12,\n lineHeight: '18px',\n // Longhand border properties (not the `border` shorthand) so\n // active → inactive only updates `borderColor`'s value instead of\n // *removing* the key from inline style. Removing it lets Storybook's\n // theme paint a stray border-color on the previously-selected pill.\n borderWidth: 1,\n borderStyle: 'solid',\n borderColor: 'transparent',\n background: 'transparent',\n cursor: 'pointer',\n color: 'inherit',\n outline: 'none',\n boxShadow: 'none',\n};\n\nconst OPTION_PILL_ACTIVE: React.CSSProperties = {\n ...OPTION_PILL_BASE,\n fontWeight: 600,\n background: 'rgba(0, 122, 255, 0.12)',\n borderColor: 'rgba(0, 122, 255, 0.45)',\n};\n\nconst PRESET_PILL_MODIFIED: React.CSSProperties = {\n display: 'inline-block',\n width: 6,\n height: 6,\n marginLeft: 6,\n borderRadius: '50%',\n background: 'currentColor',\n opacity: 0.6,\n verticalAlign: 'middle',\n};\n\nconst DIVIDER_STYLE: React.CSSProperties = {\n height: 1,\n background: 'currentColor',\n opacity: 0.1,\n margin: '2px 8px',\n};\n\ninterface OptionPillProps {\n label: string;\n active: boolean;\n title?: string;\n onClick: () => void;\n trailing?: ReactElement | null;\n}\n\nfunction OptionPill({ label, active, title, onClick, trailing }: OptionPillProps): ReactElement {\n return h(\n 'button',\n {\n type: 'button',\n title,\n onClick,\n // Skip focus on mouse click so Storybook's `:focus` border-color\n // theming doesn't stick on the previously-clicked pill. Keyboard\n // tabbing still lands focus normally — preventDefault on mousedown\n // only blocks the implicit focus-on-click behavior.\n onMouseDown: (event) => event.preventDefault(),\n style: active ? OPTION_PILL_ACTIVE : OPTION_PILL_BASE,\n },\n label,\n trailing ?? null,\n );\n}\n\ninterface PresetsSectionProps {\n presets: readonly PresetEntry[];\n axes: readonly AxisEntry[];\n defaults: Readonly<Record<string, string>>;\n activeTuple: Readonly<Record<string, string>>;\n lastApplied: string | null;\n onApply: (preset: PresetEntry) => void;\n}\n\nfunction PresetsSection({\n presets,\n axes,\n defaults,\n activeTuple,\n lastApplied,\n onApply,\n}: PresetsSectionProps): ReactElement {\n return h(\n 'div',\n null,\n h('div', { style: SECTION_LABEL_STYLE }, 'Presets'),\n h(\n 'div',\n { style: SECTION_BODY_STYLE },\n ...presets.map((preset) => {\n const tuple = presetTuple(preset, axes, defaults);\n const matches = tuplesEqual(tuple, activeTuple, axes);\n const modified = !matches && preset.name === lastApplied;\n const title = preset.description ? `${preset.name} — ${preset.description}` : preset.name;\n return h(OptionPill, {\n key: `${TOOL_ID}/preset/${preset.name}`,\n label: preset.name,\n active: matches,\n title,\n onClick: () => onApply(preset),\n trailing: modified\n ? h('span', { 'aria-hidden': true, style: PRESET_PILL_MODIFIED })\n : null,\n });\n }),\n ),\n );\n}\n\ninterface AxisSectionProps {\n axis: AxisEntry;\n active: string;\n onSelect: (next: string) => void;\n}\n\nfunction AxisSection({ axis, active, onSelect }: AxisSectionProps): ReactElement {\n const label = displayLabelFor(axis);\n return h(\n 'div',\n { style: AXIS_ROW_STYLE },\n h('div', { style: AXIS_LABEL_STYLE, title: axis.description }, label),\n h(\n 'div',\n { style: AXIS_PILLS_STYLE },\n ...axis.contexts.map((ctx) =>\n h(OptionPill, {\n key: `${TOOL_ID}/${axis.name}/${ctx}`,\n label: ctx,\n active: ctx === active,\n onClick: () => onSelect(ctx),\n }),\n ),\n ),\n );\n}\n\nconst COLOR_FORMAT_OPTIONS: readonly { id: string; label: string }[] = [\n { id: 'hex', label: 'Hex' },\n { id: 'rgb', label: 'RGB' },\n { id: 'hsl', label: 'HSL' },\n { id: 'oklch', label: 'OKLCH' },\n { id: 'raw', label: 'Raw (JSON)' },\n];\n\ninterface ColorFormatSectionProps {\n active: string;\n onSelect: (next: string) => void;\n}\n\nfunction ColorFormatSection({ active, onSelect }: ColorFormatSectionProps): ReactElement {\n return h(\n 'div',\n null,\n h('div', { style: SECTION_LABEL_STYLE }, 'Color format'),\n h(\n 'div',\n { style: SECTION_BODY_STYLE },\n ...COLOR_FORMAT_OPTIONS.map((opt) =>\n h(OptionPill, {\n key: `${TOOL_ID}/color-format/${opt.id}`,\n label: opt.label,\n active: opt.id === active,\n onClick: () => onSelect(opt.id),\n }),\n ),\n ),\n );\n}\n\ninterface PopoverBodyProps {\n axes: readonly AxisEntry[];\n presets: readonly PresetEntry[];\n defaults: Readonly<Record<string, string>>;\n activeTuple: Readonly<Record<string, string>>;\n activeColorFormat: string;\n lastApplied: string | null;\n onApplyPreset: (preset: PresetEntry) => void;\n onSelectAxis: (axisName: string, next: string) => void;\n onSelectColorFormat: (next: string) => void;\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;\n}\n\nfunction PopoverBody(props: PopoverBodyProps): ReactElement {\n const {\n axes,\n presets,\n defaults,\n activeTuple,\n activeColorFormat,\n lastApplied,\n onApplyPreset,\n onSelectAxis,\n onSelectColorFormat,\n onKeyDown,\n } = props;\n const sections: ReactElement[] = [];\n if (presets.length > 0) {\n sections.push(\n h(PresetsSection, {\n key: 'presets',\n presets,\n axes,\n defaults,\n activeTuple,\n lastApplied,\n onApply: onApplyPreset,\n }),\n h('div', { key: 'presets-divider', style: DIVIDER_STYLE }),\n );\n }\n axes.forEach((axis, idx) => {\n sections.push(\n h(AxisSection, {\n key: `axis-${axis.name}`,\n axis,\n active: activeTuple[axis.name] ?? axis.default,\n onSelect: (next) => onSelectAxis(axis.name, next),\n }),\n );\n if (idx === axes.length - 1) {\n sections.push(h('div', { key: 'axes-divider', style: DIVIDER_STYLE }));\n }\n });\n sections.push(\n h(ColorFormatSection, {\n key: 'color-format',\n active: activeColorFormat,\n onSelect: onSelectColorFormat,\n }),\n );\n return h(\n 'div',\n {\n role: 'menu',\n tabIndex: -1,\n onKeyDown,\n style: { minWidth: 260, padding: '4px 0', outline: 'none' },\n 'data-testid': 'swatchbook-toolbar-popover',\n },\n ...sections,\n );\n}\n\nfunction AxesToolbar(): ReactElement {\n const [globals, updateGlobals] = useGlobals();\n const api = useStorybookApi();\n const [payload, setPayload] = useState<InitPayload | null>(null);\n const [open, setOpen] = useState(false);\n const bodyRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n const channel = addons.getChannel();\n const onInit = (next: InitPayload): void => setPayload(next);\n channel.on(INIT_EVENT, onInit);\n return () => {\n channel.off(INIT_EVENT, onInit);\n };\n }, []);\n\n const axes = payload?.axes ?? EMPTY_AXES;\n const presets = payload?.presets ?? EMPTY_PRESETS;\n const themes = payload?.themes ?? EMPTY_THEMES;\n const defaults = useMemo(() => defaultTupleFor(axes), [axes]);\n const [lastApplied, setLastApplied] = useState<string | null>(null);\n const globalTuple = globals[AXES_GLOBAL_KEY] as Record<string, string> | undefined;\n const activeColorFormat = (globals[COLOR_FORMAT_GLOBAL_KEY] as string | undefined) ?? 'hex';\n\n const activeTuple = useMemo<Record<string, string>>(() => {\n const out: Record<string, string> = { ...defaults };\n if (globalTuple) {\n for (const axis of axes) {\n const candidate = globalTuple[axis.name];\n if (candidate !== undefined && axis.contexts.includes(candidate)) {\n out[axis.name] = candidate;\n }\n }\n }\n return out;\n }, [axes, defaults, globalTuple]);\n\n const setAxis = useCallback(\n (axisName: string, next: string): void => {\n const tuple: Record<string, string> = { ...activeTuple, [axisName]: next };\n const fallback = payload?.defaultTheme ?? themes[0]?.name ?? '';\n const composed = composedNameFor(tuple, themes, fallback);\n updateGlobals({ [AXES_GLOBAL_KEY]: tuple, [GLOBAL_KEY]: composed });\n },\n [activeTuple, themes, payload?.defaultTheme, updateGlobals],\n );\n\n const applyPreset = useCallback(\n (preset: PresetEntry): void => {\n const tuple = presetTuple(preset, axes, defaults);\n const fallback = payload?.defaultTheme ?? themes[0]?.name ?? '';\n const composed = composedNameFor(tuple, themes, fallback);\n updateGlobals({ [AXES_GLOBAL_KEY]: tuple, [GLOBAL_KEY]: composed });\n setLastApplied(preset.name);\n },\n [axes, defaults, themes, payload?.defaultTheme, updateGlobals],\n );\n\n useEffect(() => {\n if (axes.length === 0) return;\n /**\n * alt+T cycles the primary (first) axis's contexts, keeping the rest\n * of the tuple pinned. With multi-axis projects this makes the shortcut\n * predictable — you always know which wheel you're spinning. For\n * single-axis projects the behavior is identical to the pre-N-dropdown\n * toolbar (cycle through every theme).\n */\n const primary = axes[0];\n if (!primary) return;\n api.setAddonShortcut(ADDON_ID, {\n label: `Cycle swatchbook ${displayLabelFor(primary)}`,\n defaultShortcut: ['alt', 'T'],\n actionName: 'cycleAxis',\n showInMenu: true,\n action: () => {\n const current = activeTuple[primary.name] ?? primary.default;\n const idx = primary.contexts.indexOf(current);\n const next = primary.contexts[(idx + 1) % primary.contexts.length];\n if (next !== undefined) setAxis(primary.name, next);\n },\n });\n }, [api, axes, activeTuple, setAxis]);\n\n const handleKeyDown = useCallback((event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n setOpen(false);\n }\n }, []);\n\n /**\n * Escape closes even when focus hasn't entered the popover yet (e.g. the\n * user opened it via click and the mouse is still over the canvas). We\n * attach a document-level listener when open.\n */\n useEffect(() => {\n if (!open) return;\n const onDocKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') setOpen(false);\n };\n document.addEventListener('keydown', onDocKey);\n return () => document.removeEventListener('keydown', onDocKey);\n }, [open]);\n\n /**\n * `WithTooltipPure`'s built-in `closeOnOutsideClick` misses some cases\n * (portaled popover + manager iframe boundaries). Belt-and-suspenders:\n * close when the user mouses down anywhere that isn't the trigger wrapper\n * or the popover body.\n */\n useEffect(() => {\n if (!open) return;\n const onDocMouseDown = (e: MouseEvent): void => {\n const target = e.target;\n if (!(target instanceof Element)) return;\n if (bodyRef.current?.contains(target)) return;\n if (target.closest('[data-testid=\"swatchbook-toolbar-popover\"]')) return;\n setOpen(false);\n };\n document.addEventListener('mousedown', onDocMouseDown);\n return () => document.removeEventListener('mousedown', onDocMouseDown);\n }, [open]);\n\n if (axes.length === 0) {\n return h(\n IconButton,\n { key: TOOL_ID, title: 'Swatchbook theme (loading…)', disabled: true },\n h(SwatchbookIcon),\n );\n }\n\n const summary = axes.map((a) => activeTuple[a.name] ?? a.default).join(' · ');\n const title = `Swatchbook · ${summary}`;\n\n const button = h(\n IconButton,\n {\n key: TOOL_ID,\n title,\n active: open,\n onClick: () => setOpen((prev) => !prev),\n },\n h(SwatchbookIcon),\n );\n\n const tooltipBody = h(PopoverBody, {\n axes,\n presets,\n defaults,\n activeTuple,\n activeColorFormat,\n lastApplied,\n onApplyPreset: applyPreset,\n onSelectAxis: setAxis,\n onSelectColorFormat: (next: string) => updateGlobals({ [COLOR_FORMAT_GLOBAL_KEY]: next }),\n onKeyDown: handleKeyDown,\n });\n\n return h(\n 'span',\n { ref: bodyRef, style: { display: 'inline-flex', alignItems: 'center' } },\n h(WithTooltipPure, {\n placement: 'bottom',\n trigger: 'click',\n visible: open,\n onVisibleChange: (next: boolean) => setOpen(next),\n closeOnOutsideClick: true,\n tooltip: tooltipBody,\n children: button,\n }),\n );\n}\n\naddons.register(ADDON_ID, () => {\n addons.add(TOOL_ID, {\n type: types.TOOL,\n title: 'Swatchbook theme',\n match: ({ viewMode, tabId }) => !tabId && (viewMode === 'story' || viewMode === 'docs'),\n render: () => h(AxesToolbar),\n });\n\n addons.add(PANEL_ID, {\n type: types.PANEL,\n title: 'Design Tokens',\n match: ({ viewMode }) => viewMode === 'story',\n render: ({ active }) => h(DesignTokensPanel, { active: !!active }),\n });\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unpunnyfuns/swatchbook-addon",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Storybook addon for DTCG design tokens — toolbar, panel, and useToken hook.",
5
5
  "license": "MIT",
6
6
  "author": "unpunnyfuns <unpunnyfuns@gmail.com>",
@@ -12,12 +12,13 @@
12
12
  "directory": "packages/addon"
13
13
  },
14
14
  "keywords": [
15
- "storybook",
16
15
  "storybook-addon",
17
- "storybook-addons",
16
+ "storybook",
18
17
  "design-tokens",
19
18
  "dtcg",
20
19
  "design-system",
20
+ "design",
21
+ "style",
21
22
  "tokens"
22
23
  ],
23
24
  "type": "module",
@@ -55,6 +56,7 @@
55
56
  "files": [
56
57
  "dist"
57
58
  ],
59
+ "sideEffects": false,
58
60
  "publishConfig": {
59
61
  "access": "public"
60
62
  },
@@ -67,8 +69,8 @@
67
69
  },
68
70
  "dependencies": {
69
71
  "jiti": "^2.4.0",
70
- "@unpunnyfuns/swatchbook-blocks": "0.1.3",
71
- "@unpunnyfuns/swatchbook-core": "0.1.3"
72
+ "@unpunnyfuns/swatchbook-blocks": "0.1.5",
73
+ "@unpunnyfuns/swatchbook-core": "0.1.5"
72
74
  },
73
75
  "peerDependencies": {
74
76
  "react": ">=18",