Summary
Sketchbook UI's theming system currently requires passing colors and typography props to every individual component. If a user wants to change the primary stroke colour of their entire UI, they must update each component usage site manually — there is no global theme that propagates to all components at once. A SketchThemeProvider using CSS custom properties (CSS variables) would allow one-time theme definition that cascades to all child components automatically, without any JavaScript prop drilling.
Problem
- Theme customisation is per-component and per-instance:
<Button colors={{ stroke: "#000" }}> must be duplicated across every Button, Input, Card, etc. in the consuming application.
- There is no documented way to set a single
primaryColor or fontFamily that applies consistently across the entire library.
- The existing
SketchProvider (mentioned in the Quick Start) may handle some context, but there is no CSS variable system documented or enforced.
- If a user switches from one hand-drawn color palette to another (e.g. pastel to dark mode), they must find and update every individual prop across their codebase.
- Competing libraries (shadcn/ui, Chakra, Radix) all offer a token-based theming system. The absence of one in sketchbook-ui is a meaningful adoption barrier for larger projects.
Impact
- Sketchbook-UI's adoption in real projects is limited to small or one-off uses where per-component props are acceptable.
- Dark mode support is impossible to implement without a global CSS variable layer.
- The library cannot be themed once and reused consistently in a design system.
Proposed Solution
Extend the existing SketchProvider (or create SketchThemeProvider) to inject CSS custom property tokens that all components read from, with per-component props as overrides.
Theme token definition (src/theme/tokens.ts):
export interface SketchTheme {
colors: {
primary: string;
stroke: string;
background: string;
text: string;
muted: string;
danger: string;
};
typography: {
fontFamily: string;
fontSize: string;
fontWeight: string;
};
sketch: {
borderWidth: string;
wobbleIntensity: string; // controls SVG path jitter
};
}
export const defaultTheme: SketchTheme = {
colors: {
primary: "#fff9c4",
stroke: "#1a1a1a",
background: "#fffef7",
text: "#1a1a1a",
muted: "#9e9e9e",
danger: "#ef4444",
},
typography: {
fontFamily: "'Caveat', cursive",
fontSize: "1rem",
fontWeight: "600",
},
sketch: {
borderWidth: "2px",
wobbleIntensity: "1",
},
};
Provider implementation (src/theme/SketchThemeProvider.tsx):
import { createContext, useContext, useEffect } from "react";
import { SketchTheme, defaultTheme } from "./tokens";
const ThemeContext = createContext<SketchTheme>(defaultTheme);
export function SketchThemeProvider({
theme = defaultTheme,
children,
}: {
theme?: Partial<SketchTheme>;
children: React.ReactNode;
}) {
const merged = { ...defaultTheme, ...theme };
useEffect(() => {
const root = document.documentElement;
Object.entries(merged.colors).forEach(([key, val]) =>
root.style.setProperty(`--sketch-color-${key}`, val)
);
Object.entries(merged.typography).forEach(([key, val]) =>
root.style.setProperty(`--sketch-typography-${key}`, val)
);
}, [merged]);
return <ThemeContext.Provider value={merged}>{children}</ThemeContext.Provider>;
}
export const useSketchTheme = () => useContext(ThemeContext);
Component usage (example in Button.tsx):
// Before: hardcoded default inline style
style={{ backgroundColor: colors?.bg ?? "#fff9c4" }}
// After: reads from CSS variable, overrideable by prop
style={{ backgroundColor: colors?.bg ?? "var(--sketch-color-primary)" }}
Scope of this PR:
src/theme/tokens.ts with SketchTheme interface and defaultTheme.
src/theme/SketchThemeProvider.tsx injecting CSS custom properties.
- Update
src/style.css to use CSS variable fallbacks throughout.
- Update
Button, Input, Card, Modal, Toast to read from CSS variables with prop overrides.
- Storybook story demonstrating a full dark-mode theme switch via
SketchThemeProvider.
- README section documenting the global theming API.
Could you please assign this issue to me?
Labels: enhancement, feature, theming, design-system, GSSoC 2026
Summary
Sketchbook UI's theming system currently requires passing
colorsandtypographyprops to every individual component. If a user wants to change the primary stroke colour of their entire UI, they must update each component usage site manually — there is no global theme that propagates to all components at once. ASketchThemeProviderusing CSS custom properties (CSS variables) would allow one-time theme definition that cascades to all child components automatically, without any JavaScript prop drilling.Problem
<Button colors={{ stroke: "#000" }}>must be duplicated across everyButton,Input,Card, etc. in the consuming application.primaryColororfontFamilythat applies consistently across the entire library.SketchProvider(mentioned in the Quick Start) may handle some context, but there is no CSS variable system documented or enforced.Impact
Proposed Solution
Extend the existing
SketchProvider(or createSketchThemeProvider) to inject CSS custom property tokens that all components read from, with per-component props as overrides.Theme token definition (
src/theme/tokens.ts):Provider implementation (
src/theme/SketchThemeProvider.tsx):Component usage (example in
Button.tsx):Scope of this PR:
src/theme/tokens.tswithSketchThemeinterface anddefaultTheme.src/theme/SketchThemeProvider.tsxinjecting CSS custom properties.src/style.cssto use CSS variable fallbacks throughout.Button,Input,Card,Modal,Toastto read from CSS variables with prop overrides.SketchThemeProvider.Could you please assign this issue to me?
Labels:
enhancement,feature,theming,design-system,GSSoC 2026