Theming
Introduction
To create a consistent and scalable theming system for CSS styles, you can design your theme object with a structured approach that includes scales for typography, spacing, and colors. The following example demonstrates how to define a theme object with these scales, including the use of arrays for ordinal values and plain objects for named values. This setup can be easily extended for more complex systems.
By following these three steps, you can create a scalable and consistent styling system that integrates smoothly with your components, ensuring a unified design language across your application.
1. Theme Object
Create a theme object that conforms to the type definitions.
2. Type Definitions
Define TypeScript types for different scales such as typography, spacing, and colors to ensure consistency and type safety.
3. Using the Theme
Apply the theme in components by accessing the various scales and properties defined in the theme object.
This approach helps create a consistent styling system, allowing for easy adjustments and extensions as your design needs evolve.
Setting Up
1. Configure Theme
To get typings in your editor, you should create a d.ts
file.
- theme.ts
import { createDesygnaTheme } from "@desygna/desygna";
// or
// import { createDesygnaTheme } from "@desygna/desygna-core";
export type MyAppColorSwatch = {
"100": string;
"200": string;
"300": string;
};
export type MyAppBreakpoints = {
sm?: string;
md?: string;
lg?: string;
xl?: string;
xxl?: string;
};
export interface MyAppTheme {
animations: {};
breakpoints: MyAppBreakpoints;
borders: {};
borderWidths: {};
borderStyles: {};
colors: {
text: string;
background: string;
primary: MyAppColorSwatch;
accent: MyAppColorSwatch;
neutral: MyAppColorSwatch;
success: MyAppColorSwatch;
warning: MyAppColorSwatch;
error: MyAppColorSwatch;
info: MyAppColorSwatch;
};
fonts: {
heading: string;
body: string;
monospace: string;
};
fontSizes: { sm: string; md: string; lg: string };
fontWeights: {};
lineHeights: {};
letterSpacings: {};
radii: { sm: string; md: string; lg: string };
shadows: {};
sizes: { sm: string; md: string; lg: string };
spacings: { sm: string; md: string; lg: string };
transitions: {};
zIndices: {};
}
export const myTheme = createDesygnaTheme<MyAppTheme>({
breakpoints: {
sm: "480px",
md: "640px",
lg: "768px",
xl: "1024px",
xxl: "1280px"
},
colors: {
text: "black",
background: "white",
primary: {
100: "#f9f1fe",
200: "#e3ccf4",
300: "#8e4ec6"
},
accent: {
100: "#feeef8",
200: "#f3c6e2",
300: "#d6409f"
},
neutral: {
100: "#f1f3f5",
200: "#dfe3e6",
300: "#889096"
},
success: {
100: "#e9f9ee",
200: "#b4dfc4",
300: "#30a46c"
},
warning: {
100: "#fff1e7",
200: "#ffcca7",
300: "#f76808"
},
error: {
100: "#ffefef",
200: "#f9c6c6",
300: "#e5484d"
},
info: {
100: "#edf6ff",
200: "#b7d9f8",
300: "#0091ff"
}
},
fonts: {
body: 'Open Sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif',
heading: "Open Sans, system-ui",
monospace: "monospace"
},
fontSizes: {
sm: "14px",
md: "18px",
lg: "24px"
},
radii: {
sm: "4px",
md: "8px",
lg: "16px"
},
sizes: {
sm: "4px",
md: "8px",
lg: "16px"
},
spacings: {
sm: "4px",
md: "8px",
lg: "16px"
}
});
2. Create d.ts
file
- desygna.d.ts
import "@emotion/react";
import { MyTheme } from "./desygna/theme"; // Path to your theme file
declare module "@emotion/react" {
export interface Theme extends MyTheme {}
}
3. Use DesygnaProvider
- App.tsx
import { DesygnaProvider } from "@desygna/desygna";
// or import { DesygnaProvider } from "@desygna/desygna-core";
import { myTheme } from "./theme";
export default function App() {
return (
<DesygnaProvider theme={myTheme}>
{/* ... */}>
</DesygnaProvider>
);
}
Types
export interface DesygnaTheme {
animations?: {
[key: string]: string;
};
breakpoints?: {
[key: string]: string;
};
borders?: {
[key: string]: DesygnaThemeRecord;
};
borderWidths?: {
[key: string]: DesygnaThemeRecord;
};
borderStyles?: {
[key: string]: DesygnaThemeRecord;
};
colors?: {
[key: string]: DesygnaThemeRecord;
};
fonts?: {
[key: string]: DesygnaThemeRecord;
};
fontSizes?: {
[key: string]: DesygnaThemeRecord;
};
fontWeights?: {
[key: string]: DesygnaThemeRecord;
};
lineHeights?: {
[key: string]: DesygnaThemeRecord;
};
letterSpacings?: {
[key: string]: DesygnaThemeRecord;
};
radii?: {
[key: string]: DesygnaThemeRecord;
};
shadows?: {
[key: string]: DesygnaThemeRecord;
};
sizes?: {
[key: string]: DesygnaThemeRecord;
};
spacings?: {
[key: string]: DesygnaThemeRecord;
};
transitions?: {
[key: string]: DesygnaThemeRecord;
};
zIndices?: {
[key: string]: DesygnaThemeRecord;
};
}