npm.io
0.1.3 • Published yesterday

burne-ui-devtools

Licence
Version
0.1.3
Deps
2
Size
322 kB
Vulns
0
Weekly
0

burne-ui-devtools

Runtime theme editor for applications using BurneUIProvider.

Compatibility

burne-ui-devtools requires burne-ui >=1.5.10 <2. Earlier releases do not provide the runtime theme API and custom-token support used by the editor.

Both stylesheets are required:

import "burne-ui/styles.css";
import "burne-ui-devtools/styles.css";

The component must be rendered inside BurneUIProvider.

Vite: lazy, development-only loading

This keeps the devtools JavaScript out of production builds. Put the required stylesheet imports in the application entry file.

import { lazy, Suspense } from "react";
import { BurneUIProvider } from "burne-ui";
import "burne-ui/styles.css";
import "burne-ui-devtools/styles.css";

import burneTheme from "./burne-theme";

const BurneThemeDevtools = import.meta.env.DEV
  ? lazy(() =>
      import("burne-ui-devtools").then(({ BurneThemeDevtools }) => ({
        default: BurneThemeDevtools,
      })),
    )
  : null;

export function App() {
  return (
    <BurneUIProvider config={burneTheme}>
      <YourApp />
      {BurneThemeDevtools ? (
        <Suspense fallback={null}>
          <BurneThemeDevtools />
        </Suspense>
      ) : null}
    </BurneUIProvider>
  );
}

Next.js: dynamic, development-only loading

Import the global styles from app/layout.tsx:

import "burne-ui/styles.css";
import "burne-ui-devtools/styles.css";

Create a client component such as app/BurneDevtools.tsx:

"use client";

import dynamic from "next/dynamic";

const DevelopmentDevtools =
  process.env.NODE_ENV === "development"
    ? dynamic(
        () =>
          import("burne-ui-devtools").then(
            ({ BurneThemeDevtools }) => BurneThemeDevtools,
          ),
        { ssr: false },
      )
    : null;

export function BurneDevtools() {
  return DevelopmentDevtools ? <DevelopmentDevtools /> : null;
}

Render <BurneDevtools /> anywhere below the client-side BurneUIProvider. The production branch does not request the devtools module.

Custom tokens

All customTokens from the provider config appear in the editor. Primitive shorthand values infer a suitable control:

import type { BurneThemeConfig } from "burne-ui";

export const burneTheme: BurneThemeConfig = {
  theme: "system",
  customTokens: {
    "--app-sidebar-width": "18rem",
    "--app-dense-mode": false,
    "--app-card-opacity": 0.9,
  },
};

Use metadata to control the label, group, description, input type, and range:

export const burneTheme: BurneThemeConfig = {
  customTokens: {
    "--app-card-opacity": {
      value: 0.9,
      label: "Card opacity",
      group: "Application",
      description: "Opacity used by elevated application cards.",
      control: "slider",
      min: 0.5,
      max: 1,
      step: 0.05,
      unit: "×",
    },
    "--app-density": {
      value: "comfortable",
      label: "Density",
      group: "Application",
      control: "select",
      options: [
        { label: "Compact", value: "compact" },
        { label: "Comfortable", value: "comfortable" },
      ],
    },
  },
};

Use values for mode-specific values. The active light or dark value is edited without replacing the other mode:

export const burneTheme: BurneThemeConfig = {
  theme: "system",
  customTokens: {
    "--app-hero-surface": {
      values: {
        light: "#f7f8ff",
        dark: "#111522",
      },
      label: "Hero surface",
      group: "Application colors",
      control: "color",
    },
  },
};

Font presets (Google Fonts)

Choosing a sans/mono preset only writes --font-family-* tokens. The matching Google Font file is lazy-loaded by the editor when you select the preset or when a persisted snapshot is restored:

  1. preconnect to fonts.googleapis.com / fonts.gstatic.com (once).
  2. Inject a stylesheet for that family only (data-burne-theme-font).
  3. Skip system stacks and unknown custom CSS stacks (no network request).

Helpers you can reuse outside the panel:

import {
  ensureThemeFontLoaded,
  FONT_PRESETS,
  THEME_SANS_FONTS_URL,
  THEME_MONO_FONTS_URL,
} from "burne-ui-devtools";

ensureThemeFontLoaded(FONT_PRESETS.find((p) => p.id === "inter"));
// or preload every preset family in docs layout:
// <link rel="stylesheet" href={THEME_SANS_FONTS_URL} />

Production: do not rely on the editor to load fonts. After you pick a face, ship it yourself (self-host, next/font, or a single Google Fonts <link> for the families you keep in burne-theme.ts). Copy/Download config only exports the CSS stack string — not font files.

Actions

  • Reset clears the preview and persisted editor snapshot, then restores the provider's base theme preference (including system) and token values.
  • Shuffle picks a random color preset, Scale slider values, and sans/mono fonts. Motion and animation toggles are left unchanged.
  • Copy CSS copies the current theme as CSS custom properties.
  • Copy config copies a serializable BurneThemeConfig source.
  • Download config downloads the current configuration as burne-theme.ts.

Control ranges (min / max / step)

Edit slider bounds in src/BurneThemeDevtools/burneThemeDevtoolsData.ts:

  • SCALE_CONTROLS — spacing, size, radius, border, type scale (also used by Shuffle)
  • SHADOW_CONTROLS — shadow / toast scrim
  • MOTION_DURATION_CONTROLS / MOTION_SCALE_CONTROLS — motion section

Custom token sliders use min / max / step from the token metadata in your burne-theme.ts customTokens entry.

Props

  • enabled?: boolean — explicit runtime switch, default true. A detected process.env.NODE_ENV === "production" always disables the component.
  • persist?: boolean — localStorage persistence, default true.
  • storageKey?: string — persistence key, default burne-ui-devtools.
  • defaultOpen?: boolean — render the editor open initially.
  • className?: string — class added to the fixed portal root.

For browser builds that do not expose process.env.NODE_ENV, pass the application's own development flag to enabled.