ThemeTokenInspector
Live inspector for chrome, brand, and semantic theme-token behaviour.
Live demo
01Theming convention
Theme token inspector
Chrome flips. Brand stays. Semantic stays.
Structural surfaces should change with the preview mode.
| Token | Kind | Light | Dark | Preview | Contrast-ish | Override |
|---|---|---|---|---|---|---|
--tooltip-bg Tooltip - Panel background and arrow fill | Chrome | #111827 | #f9fafb | #111827 | 17.7:1 high | |
--tooltip-fg Tooltip - Tooltip body text | Chrome | #f9fafb | #111827 | #f9fafb | 1.0:1 low | |
--kbd-bg-top KbdShortcut - Key cap bevel top | Chrome | #ffffff | #1f2937 | #ffffff | 1.0:1 low | |
--kbd-bg-bottom KbdShortcut - Key cap bevel bottom | Chrome | #f3f4f6 | #111827 | #f3f4f6 | 1.1:1 low | |
--kbd-border KbdShortcut - Key cap outline | Chrome | #d1d5db | #4b5563 | #d1d5db | 1.5:1 low | |
--rating-star-empty RatingStars - Empty star fill | Chrome | #e5e7eb | #374151 | #e5e7eb | 1.2:1 low | |
--rating-focus-ring RatingStars - Keyboard focus ring | Chrome | #3b82f6 | #60a5fa | #3b82f6 | 3.7:1 ok |
Copy override
Chrome CSS snippet
body .tooltip-wrap.tooltip-wrap {
--tooltip-bg: #111827;
--tooltip-fg: #f9fafb;
}
body .kbd.kbd {
--kbd-bg-top: #ffffff;
--kbd-bg-bottom: #f3f4f6;
--kbd-border: #d1d5db;
}
body .rating-stars.rating-stars {
--rating-star-empty: #e5e7eb;
--rating-focus-ring: #3b82f6;
}Implementation
02<script lang="ts">
import ThemeTokenInspector from '$lib/components/ThemeTokenInspector.svelte';
</script>
β
<ThemeTokenInspector initialMode="dark" />ThemeTokenInspector keeps the theming convention executable: token rows are grouped by taxonomy, preview values are resolved per light or dark mode, and override snippets are generated from the selectors that beat Svelte-scoped component defaults.
Logic explainer
03What Does It Do? (Plain English)
ThemeTokenInspector is a live reference panel for the convention in docs/THEMING.md: chrome flips, brand stays, semantic stays. It groups known theme tokens, lets maintainers preview light and dark values, shows swatches with a contrast-ish readability label, and produces copyable CSS override snippets.
How It Works (Pseudo-Code)
receive token rows or use the default theming rows
group rows by chrome / brand / semantic
pick preview mode: light or dark
for each visible token:
resolve the preview value
render light, dark, and active swatches
compare active value against the preview surface
generate CSS grouped by selector
copy snippets through the native clipboard APIState Flow Diagram
defaultThemeTokenRows
-> groupTokenRows()
-> active category filter
-> tokenValueForMode()
-> swatches + contrastLabel()
-> cssOverrideSnippet()
-> copy buttonProps Reference
| Prop | Type | Default | Description |
|---|---|---|---|
rows |
ThemeTokenRow[] |
defaultThemeTokenRows |
Token metadata to inspect. |
title |
string |
"Theme token inspector" |
Heading shown in the panel. |
initialMode |
"light" | "dark" |
"light" |
Starting preview mode. |
Helper Exports
| Export | Description |
|---|---|
groupTokenRows(rows) |
Returns chrome, brand, and semantic row arrays. |
tokenValueForMode(row, mode) |
Resolves the active token value, falling back to light when dark is intentionally stable. |
flipsInDark(row) |
Reports whether a token changes in dark mode. |
hexToRgb(value) |
Parses #rrggbb colors for testable color math. |
relativeLuminance(value) |
Computes WCAG-style luminance for hex colors. |
contrastRatio(foreground, background) |
Computes a numeric contrast ratio. |
contrastLabel(value, mode) |
Returns a high / ok / low / n/a label for the preview surface. |
cssOverrideSnippet(rows, mode) |
Builds grouped CSS override snippets by selector. |
Theming
This component is itself theme-aware, but it exists to explain the repository-wide token rule:
| Kind | Dark behavior | Examples |
|---|---|---|
| Chrome | Flips in dark mode. | --tooltip-bg, --kbd-border, --rating-star-empty |
| Brand | Stays stable unless consumers explicitly opt in. | --rating-star-filled, --fill-color, --accent |
| Semantic | Stays stable because color carries state meaning. | --success, --warning, --error, --info |
Override examples use direct selectors such as body .kbd.kbd because component-scoped CSS variables are declared on the component root. See docs/THEMING.md for the specificity rationale.
Edge Cases
- Tokens without a
darkvalue are treated as intentionally stable. - Contrast labels are a quick surface-read cue, not a full accessibility audit for every component state.
- Non-hex colors return
N/Afrom contrast helpers so generated snippets can still render. - Dark snippets for flipping chrome tokens use a
.darkselector shape to make manual mode overrides easy to copy.
Dependencies
No external dependencies. Clipboard behavior uses navigator.clipboard when available.
File Structure
src/lib/components/ThemeTokenInspector.svelte
src/lib/components/ThemeTokenInspector.test.ts
src/lib/components/ThemeTokenInspector.md
src/routes/themetokeninspector/+page.svelteAPI
04| Export | Type | Description |
|---|---|---|
rows | ThemeTokenRow[] | Optional token metadata; defaults to the theming convention reference rows. |
initialMode | "light" | "dark" | Sets the first preview mode before the user toggles it. |
groupTokenRows | (rows) => Record<ThemeTokenKind, ThemeTokenRow[]> | Groups rows into chrome, brand, and semantic buckets. |
cssOverrideSnippet | (rows, mode) => string | Builds copy-ready CSS declarations grouped by override selector. |
contrastLabel | (value, mode) => ContrastResult | Returns the preview swatch readability cue. |