3.5 KiB
3.5 KiB
UI Theming and CM6 Highlight
Theme Variables
- Global tokens (in
src/styles.css):--color-accentmain accent color (per-theme override via[data-theme]).--cm-hl-bgcomputed background for inline highlights (theme dependent).--cm-hl-brborder 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
: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 viaStateEffect/StateField.markdown-theme-highlight.extension.ts– composes ranged + MarkdownHighlightStyleand 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 aCompartmentwith occurrences.setRanges(view, ranges)/clearRanges(view)– ranged highlights via effects.facet()– access the facet to optionally override--cm-hl-bgper-view.
Example inside editor component:
// 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:
<button class="btn btn-solid btn-sm">Save</button>
<button class="btn btn-outline btn-sm">Cancel</button>
<button class="btn btn-ghost btn-sm" aria-label="Close">✕</button>
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
StateFieldandtr.changes.mapPosto 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.