Integration
@ponchia/ui is CSS-first and framework-agnostic. Integrating it into
any app is three concerns, the same everywhere:
- Load the CSS.
@import '@ponchia/ui';(the flattened bundle) or@import '@ponchia/ui/css';(the leaf fan-out, through a bundler). Everything is inside@layer bronto, so un-layered app CSS wins without!important— see Tailwind / cascade-layer interop. - Apply the theme before paint to avoid a flash. The persisted
theme lives in
localStorage['bronto-theme']; a tiny inline head script must set<html data-theme>before first paint. This is the single most-missed pattern — every guide below shows it. - Wire behaviors in the framework's lifecycle. Every
init*()is SSR-safe (no-ops without a DOM), idempotent, and returns a cleanup function. Call it on mount, call the cleanup on unmount.
The no-flash theme script (framework-agnostic)
Inline, render-blocking, in <head>, before any stylesheet-dependent
paint. No import — it must run before module JS:
<meta name="color-scheme" content="light dark" />
<script>
try {
var t = localStorage.getItem('bronto-theme');
if (t === 'light' || t === 'dark') document.documentElement.dataset.theme = t;
} catch (e) {}
</script>
The meta declaration lets browser-owned form controls and chrome advertise and render both supported schemes; it does not replace the stored-theme script.
applyStoredTheme() from @ponchia/ui/behaviors does exactly this
(default storageKey: 'bronto-theme') and is what initThemeToggle()
persists to — but module code runs after paint, so the inline copy
above is the FOUC fix. Use applyStoredTheme() for re-application after
client navigation.
Per-framework guides
- Astro
- SvelteKit
- Vue
- Vanilla / Vite / plain HTML
- React / Solid / Qwik (host lifecycle recipes)
- Tailwind / cascade-layer interop
All behaviors and their attributes are typed in @ponchia/ui/behaviors
(behaviors/index.d.ts); the README quick-start shows the common ones.