# UI Theming and CM6 Highlight ## Theme Variables - **Global tokens** (in `src/styles.css`): - `--color-accent` main accent color (per-theme override via `[data-theme]`). - `--cm-hl-bg` computed background for inline highlights (theme dependent). - `--cm-hl-br` border radius for highlights (default 3px). - **Button tokens**: - `--btn-radius`, `--btn-padding-y`, `--btn-padding-x`, `--btn-font`, `--btn-shadow`, `--btn-ring`, `--btn-speed`. - `--btn-bg`, `--btn-fg`, `--btn-bg-hover`, `--btn-bg-active`, `--btn-outline`. ### Defaults ```css :root { --color-accent: #3b82f6; --cm-hl-bg: color-mix(in srgb, var(--color-accent) 28%, transparent); --cm-hl-br: 3px; } [data-theme="dark"], .dark { --cm-hl-bg: color-mix(in srgb, var(--color-accent) 22%, transparent); } [data-theme="nimbus"] { --color-accent: #7c3aed; } [data-theme="emerald"] { --color-accent: #10b981; } ``` ## CodeMirror 6 Highlight Extensions Files in `src/app/shared/editor/extensions/`: - `highlight-occurrences.extension.ts` – inline dynamic occurrences via regex. - `ranged-highlights.extension.ts` – ranged highlights via `StateEffect`/`StateField`. - `markdown-theme-highlight.extension.ts` – composes ranged + Markdown `HighlightStyle` and facet-driven CSS variable. ### CSS class - `.cm-md-highlight { background: var(--cm-hl-bg); border-radius: var(--cm-hl-br, 3px); transition: background var(--btn-speed) ease; }` ## Angular Integration Service: `EditorHighlightService` (`src/app/shared/editor/editor-highlight.service.ts`) - `extensions: Extension[]` – base markdown theme highlight extensions to add at editor creation. - `occurrencesExtension(pattern)` – build occurrences extension. - `applyOccurrences(view, compartment, pattern)` – reconfigure a `Compartment` with occurrences. - `setRanges(view, ranges)` / `clearRanges(view)` – ranged highlights via effects. - `facet()` – access the facet to optionally override `--cm-hl-bg` per-view. Example inside editor component: ```ts // compartments occurrencesCompartment = new Compartment(); highlightFacetCompartment = new Compartment(); // in EditorState.create extensions ...highlightService.extensions, occurrencesCompartment.of([]), highlightFacetCompartment.of([]), // API usage highlightOccurrences("TODO"); setHighlights([{ from: 10, to: 24 }]); clearHighlights(); // optional color override view.dispatch({ effects: highlightFacetCompartment.reconfigure([ highlightService.facet().of('color-mix(in srgb, var(--color-accent) 40%, transparent)') ])}); ``` Live theme changes are applied by reconfiguring the theme compartment and calling `EditorView.requestMeasure(...)` to refresh decorations that rely on CSS variables. ## Button Utilities Classes in `src/styles.css`: - Base: `btn` - Variants: `btn-solid`, `btn-outline`, `btn-ghost` - Sizes: `btn-sm`, `btn-md`, `btn-lg` Example: ```html ``` ## Accessibility - Buttons use focus ring via `--btn-outline`. - Ensure icon-only buttons have `aria-label`. ## Performance Notes - Occurrence highlights compute decorations only over visible ranges; cost is O(visibleText) per viewport update. - Ranged highlights use a `StateField` and `tr.changes.mapPos` to keep ranges aligned after edits; updates are incremental. - For large docs (≥5k lines), prefer ranged highlights for bulk operations; occurrences are fine for quick regex patterns like `TODO`.