/** * Theme Builder — Headers panel (docs/chart-theming-scope.md §5). * * The base facet-header config (`config.header.*`) — the titles and labels that * caption each panel of a faceted chart (the `row`/`column`/`facet` channels). * The per-position variants (`headerRow`, `headerColumn`, `headerFacet`) stay in * the JSON; this is the common surface a brand tunes. Each control writes a * minimal diff through the shared setter. */ import type { JsonObject } from '@core/spec-config'; import { asNumber, asString, type ConfigPath, countSet, getConfigValue, } from '@core/theme-controls'; import { useConfigSetter } from '../stores/CustomThemeStore'; import { Accordion, type AccordionSection, ColorRow, NumberRow, WeightRow } from './ThemeFields'; const TEXT_GREY = '#888888'; const TITLE_COLOR: ConfigPath = ['header', 'titleColor']; const TITLE_SIZE: ConfigPath = ['header', 'titleFontSize']; const TITLE_WEIGHT: ConfigPath = ['header', 'titleFontWeight']; const LABEL_COLOR: ConfigPath = ['header', 'labelColor']; const LABEL_SIZE: ConfigPath = ['header', 'labelFontSize']; const LABEL_WEIGHT: ConfigPath = ['header', 'labelFontWeight']; export function HeaderControls({ config }: { config: JsonObject }) { const set = useConfigSetter(); const sections: AccordionSection[] = [ { id: 'titles', title: 'Facet titles', hint: "The caption naming each facet's field.", badge: countSet(config, [TITLE_COLOR, TITLE_SIZE, TITLE_WEIGHT]), children: ( <> set(TITLE_COLOR, hex)} onClear={() => set(TITLE_COLOR, undefined)} /> set(TITLE_SIZE, n)} /> set(TITLE_WEIGHT, w)} /> ), }, { id: 'labels', title: 'Facet labels', hint: 'The per-panel value labels.', badge: countSet(config, [LABEL_COLOR, LABEL_SIZE, LABEL_WEIGHT]), children: ( <> set(LABEL_COLOR, hex)} onClear={() => set(LABEL_COLOR, undefined)} /> set(LABEL_SIZE, n)} /> set(LABEL_WEIGHT, w)} /> ), }, ]; return ; }