How to Create and Register a Custom UI Preset
This guide explains how to create a custom visual preset (e.g., frappePreset, materialPreset) and register it with Framework M's application shell (FrameworkMShell).
Step 1: Define Your UIPreset Object
Create a file for your preset (e.g. src/theme/myCustomPreset.ts) implementing the UIPreset interface from @framework-m/ui:
import type { UIPreset } from "@framework-m/ui";
export const myCustomPreset: UIPreset = {
name: "my-custom-theme",
tokens: {
color: {
primary: "#2563eb",
primaryHover: "#1d4ed8",
},
radius: {
md: 8,
},
},
themes: {
light: {
background: "#ffffff",
backgroundSecondary: "#f8fafc",
color: "#0f172a",
primary: "#111827",
primaryColor: "#ffffff",
sidebarBg: "#f8fafc",
sidebarItemActiveBg: "#ffffff",
},
dark: {
background: "#121212",
backgroundSecondary: "#18181b",
color: "#f4f4f5",
primary: "#fafafa",
primaryColor: "#121212",
sidebarBg: "#121212",
sidebarItemActiveBg: "#27272a",
},
},
};
Step 2: Pass Your Preset to FrameworkMShell or MProvider
In your application root entry point (App.tsx or index.tsx), pass the preset prop to <FrameworkMShell> or <MProvider>:
import { FrameworkMShell } from "@framework-m/desk";
import { myCustomPreset } from "./theme/myCustomPreset";
export const App = () => {
return (
<FrameworkMShell
title="My Custom App"
preset={myCustomPreset}
>
<Dashboard />
</FrameworkMShell>
);
};
Step 3: Verify Dynamic Theme Inversion
When switching between Light and Dark modes:
- Primary action buttons automatically swap background (
$primary) and foreground text/icons ($primaryColor). - Sidebar active cards inherit
$sidebarItemActiveBg. - Focus outlines receive
$focusRing.