@davaux/scoped-css
v0.8.1
Published
Location-based CSS scoping plugin for Davaux
Readme
@davaux/scoped-css
Location-based CSS scoping for Davaux islands.
Installation
npm install @davaux/scoped-cssSetup
// davaux.config.ts
import { defineConfig } from 'davaux/config'
import { scopedCss } from '@davaux/scoped-css'
export default defineConfig({
plugins: [scopedCss()],
})Add the ambient type declaration so TypeScript accepts CSS default imports:
// src/env.d.ts
/// <reference types="@davaux/scoped-css/env" />How it works
CSS files imported from src/islands/ are automatically scoped at build time. Every class name gets a short deterministic hash suffix so styles never leak across island boundaries:
/* Button.css — authored */
.button { background: blue; }
/* emitted to the bundle */
.button-a1b2c { background: blue; }Importing the CSS file returns a Record<string, string> mapping original → scoped names:
// src/islands/Button.tsx
import styles from './Button.css'
// styles.button === 'button-a1b2c'
export const Button = island('Button', () => (
<button class={styles.button}>Click me</button>
))CSS outside src/islands/ is never scoped. Append ?global to opt any import out:
import './reset.css?global'cx() — class name composition
import { cx } from '@davaux/scoped-css/client'
cx(styles.button, styles.large)
// → 'button-a1b2c large-a1b2c'
cx(styles.button, { [styles.active]: isActive })
// → 'button-a1b2c active-a1b2c' or 'button-a1b2c'When any condition is a signal getter, cx returns a reactive () => string so the JSX runtime surgically updates only the class attribute:
const [active, setActive] = createSignal(false)
<button class={cx(styles.button, { [styles.active]: active })} />Notes
- Class names are hashed from the absolute file path — stable across builds
- Works with SCSS/SASS when combined with an esbuild preprocessor plugin
- The scoped CSS and JS shim are emitted into the existing bundle — no per-component CSS files
