HighlightTheme¶
HighlightTheme maps hljs-* token classes to Compose SpanStyle values used by the highlight
pipeline.
Full API in Dokka:
HighlightThemerememberTomorrowThemerememberTomorrowNightThemerememberAtomOneDarkThemerememberAtomOneLightTheme
When to use each theme source¶
- Built-in themes (
tomorrow,tomorrowNight,atomOneDark,atomOneLight): fastest setup, precompiled maps, no CSS parsing at runtime. fromAsset(...): best for shipping a highlight.js CSS file with your app.fromCss(...): useful when CSS comes from network, config, or generated text.fromColorMap(...): best when you want full programmatic control, for example Material 3 dynamic color integration.
Recommended usage in Compose¶
Use remember*Theme() helpers inside composables so the theme instance stays stable across
recompositions.
import dev.hossain.highlight.ui.HighlightThemeProvider
import dev.hossain.highlight.ui.rememberTomorrowNightTheme
import dev.hossain.highlight.ui.rememberTomorrowTheme
HighlightThemeProvider(
lightHighlightTheme = rememberTomorrowTheme(),
darkHighlightTheme = rememberTomorrowNightTheme(),
) { ... }
Custom theme from asset CSS¶
import androidx.compose.ui.platform.LocalContext
import dev.hossain.highlight.engine.HighlightTheme
import dev.hossain.highlight.ui.HighlightThemeProvider
val appContext = LocalContext.current.applicationContext
val theme = HighlightTheme.fromAsset(
context = appContext,
assetPath = "themes/github.css",
name = "github",
)
HighlightThemeProvider(lightHighlightTheme = theme) { ... }
Note
fromAsset() is lazy. CSS parsing happens on first theme usage, not at factory call time.
Custom theme from raw CSS¶
Custom theme from a color map¶
val theme = HighlightTheme.fromColorMap(
name = "my-dynamic-theme",
colorMap = colorMap,
backgroundColor = Color(0xFFFFFFFF),
defaultTextColor = Color(0xFF24292E),
)
Theme identity behavior¶
HighlightTheme equality is based on both name and content identity. This gives stable
memoization while still triggering re-highlighting when CSS content changes.
- Same name and same CSS content -> equal.
- Same name and different CSS content -> not equal.
- Different names -> not equal.
val light = HighlightTheme.fromCss(lightCss, "custom")
val dark = HighlightTheme.fromCss(darkCss, "custom")
light == dark // false
val a = HighlightTheme.fromCss(css, "custom")
val b = HighlightTheme.fromCss(css, "custom")
a == b // true
Common pitfalls¶
- Passing activity context to long-lived themes in non-Compose layers.
- Expecting
fromAsset()parse failures at construction time rather than first use. - Recreating custom themes every recomposition instead of
remembering stable instances.