Theme Configuration
Configure preset palettes, mode, accent tuning, density, shell sizing, and token overrides from one nested theme object.
Start with `neutral`, `dusk`, `ocean`, or `sqlos`, then tune mode, accent hue, accent strength, and surface style.
Control density, shell width, content width, sidebar width, and TOC width without creating new layout components.
Override semantic shell tokens last when a preset gets you close but not all the way to your product's visual language.
import type { DocsThemeConfig } from "@emcy/docs";
const docsTheme: DocsThemeConfig = {
color: {
preset: "ocean",
mode: "dark",
accentHue: 188,
accentStrength: "bold",
surfaceStyle: "elevated",
},
layout: {
density: "compact",
layoutWidth: "1480px",
contentWidth: "50rem",
sidebarWidth: "272px",
tocWidth: "232px",
},
shape: {
radius: "xl",
},
};
<DocsLayout
navigation={docsSource.getNavigation()}
theme={docsTheme}
/>DocsLayout reads theme state from DocsThemeProvider when present and falls back to its own theme prop otherwise. Use the prop for fixed themes and the provider for a studio, persisted preferences, or share URLs.
import {
DocsLayout,
DocsThemeProvider,
useDocsTheme,
type DocsThemeConfig,
} from "@emcy/docs";
const initialTheme: DocsThemeConfig = {
color: {
preset: "neutral",
mode: "light",
},
};
function ThemeModeToggle() {
const { resolvedTheme, updateTheme } = useDocsTheme();
const nextMode =
resolvedTheme.config.color.mode === "light" ? "dark" : "light";
return (
<button onClick={() => updateTheme({ color: { mode: nextMode } })}>
Toggle mode
</button>
);
}
export default function Layout({ children }) {
return (
<DocsThemeProvider initialTheme={initialTheme}>
<DocsLayout
navigation={docsSource.getNavigation()}
themeSwitcher={<ThemeModeToggle />}
>
{children}
</DocsLayout>
</DocsThemeProvider>
);
}Use this as the balanced baseline for product docs, design systems, and app-embedded help centers. It works well in both light and dark.
preset selects the base palette family. mode forces light or dark, and every preset now supports both.
accentHue re-centers the brand hue without abandoning the preset. accentStrength decides how hard that hue pushes primary buttons, focus rings, accent surfaces, and soft-highlight states.
flat, tinted, and elevated change how much panel tint, border contrast, and shadow depth the shell uses.
density changes spacing rhythm across navigation, cards, TOC items, and page gutters. layoutWidth, contentWidth, sidebarWidth, and tocWidth let one layout cover wide product docs, denser references, and narrower reading-focused pages.
Choose md, lg, or xl to tighten or soften the surface language across cards, banners, tabs, dialogs, and shell chrome.
tokens are semantic overrides applied last. Use them when the preset plus knobs gets close, but you need exact background, border, card, accent, code, or shadow values to match a product brand.
DocsThemeStudio only ships inside /site. The library ships the headless primitives: resolveDocsTheme(theme), DocsThemeProvider, and useDocsTheme(). Build your own switcher UI around them, or keep the theme fixed and skip runtime controls entirely.
The example docs route uses those primitives to power preset switching, live token overrides, shareable URLs, and persisted preferences without requiring a bundled library switcher component.