The Cherry theme is a TypeScript object that defines various aspects of your project. Whether you’re working on media queries, spacing sizes, colors, font sizes, or line heights, the Cherry theme has got you covered. Additionally, Cherry offers a Figma plugin to extract design tokens—check out the Design documentation for details on that integration.
To use the theme correctly make sure you are wrapping your entire application with the CherryThemeProvider
. This will ensure that all the components in your application have access to the theme.
This component provides the theme to all React components underneath itself via the context API. Ensure that your theme prop is passed down correctly.
import { CherryThemeProvider, theme } from "cherry-styled-components";
export default function App({ Component, pageProps }) {
return <CherryThemeProvider theme={theme}>
<Component {...pageProps} />
</CherryThemeProvider>;
}
The theme object is type safe and uses TypeScript to define the various aspects of the theme. The theme object is divided into the following sections:
"use client";
export const breakpoints: Breakpoints = {
xs: 0,
sm: 576,
md: 768,
lg: 992,
xl: 1200,
xxl: 1440,
xxxl: 1920,
};
export function mq(minWidth: keyof Breakpoints) {
return `@media screen and (min-width: ${breakpoints[minWidth]}px)`;
}
export const spacing: Spacing = {
maxWidth: { xs: "1280px", xxxl: "1440px" },
padding: { xs: "20px", lg: "40px" },
radius: { xs: "6px", lg: "12px", xl: "30px" },
gridGap: { xs: "20px", lg: "40px" },
};
export const colors: Colors = {
primaryLight: "#91aec4",
primary: "#4d6f8b",
primaryDark: "#194569",
secondaryLight: "#a4b17b",
secondary: "#5c6e46",
secondaryDark: "#354c2b",
tertiaryLight: "#ebccb9",
tertiary: "#816b5a",
tertiaryDark: "#675445",
grayLight: "#e5e7eb",
gray: "#9ca3af",
grayDark: "#4b5563",
success: "#84cc16",
error: "#ef4444",
warning: "#eab308",
info: "#06b6d4",
dark: "#000000",
light: "#ffffff",
};
export const colorsDark: Colors = {
primaryLight: "#79C5FF",
primary: "#6198C6",
primaryDark: "#339DF4",
secondaryLight: "#a4b17b",
secondary: "#5c6e46",
secondaryDark: "#354c2b",
tertiaryLight: "#ebccb9",
tertiary: "#816b5a",
tertiaryDark: "#675445",
grayLight: "#1A1A1A",
gray: "#454444",
grayDark: "#808080",
success: "#84cc16",
error: "#ef4444",
warning: "#eab308",
info: "#06b6d4",
dark: "#ffffff",
light: "#000000",
};
export const shadows: Shadows = {
xs: "0px 4px 4px 0px rgba(18, 18, 18, 0.04), 0px 1px 3px 0px rgba(39, 41, 45, 0.02)",
sm: "0px 4px 4px 0px rgba(18, 18, 18, 0.08), 0px 1px 3px 0px rgba(39, 41, 45, 0.04)",
md: "0px 8px 8px 0px rgba(18, 18, 18, 0.16), 0px 2px 3px 0px rgba(39, 41, 45, 0.06)",
lg: "0px 16px 24px 0px rgba(18, 18, 18, 0.20), 0px 2px 3px 0px rgba(39, 41, 45, 0.08)",
xl: "0px 24px 32px 0px rgba(18, 18, 18, 0.24), 0px 2px 3px 0px rgba(39, 41, 45, 0.12)",
};
export const shadowsDark: Shadows = {
xs: "0px 4px 4px 0px rgba(255, 255, 255, 0.04), 0px 1px 3px 0px rgba(255, 255, 255, 0.02)",
sm: "0px 4px 4px 0px rgba(255, 255, 255, 0.08), 0px 1px 3px 0px rgba(255, 255, 255, 0.04)",
md: "0px 8px 8px 0px rgba(255, 255, 255, 0.16), 0px 2px 3px 0px rgba(255, 255, 255, 0.06)",
lg: "0px 16px 24px 0px rgba(255, 255, 255, 0.20), 0px 2px 3px 0px rgba(255, 255, 255, 0.08)",
xl: "0px 24px 32px 0px rgba(255, 255, 255, 0.24), 0px 2px 3px 0px rgba(255, 255, 255, 0.12)",
};
export const fonts: Fonts = {
text: "Inter",
head: "Inter",
mono: "monospace",
};
export const fontSizes: FontSizes = {
hero1: { xs: "72px", lg: "128px" },
hero2: { xs: "60px", lg: "96px" },
hero3: { xs: "36px", lg: "72px" },
h1: { xs: "40px", lg: "60px" },
h2: { xs: "30px", lg: "36px" },
h3: { xs: "28px", lg: "30px" },
h4: { xs: "26px", lg: "24px" },
h5: { xs: "18px", lg: "20px" },
h6: { xs: "16px", lg: "18px" },
text: { xs: "14px", lg: "16px" },
strong: { xs: "14px", lg: "16px" },
small: { xs: "12px", lg: "14px" },
blockquote: { xs: "16px", lg: "18px" },
code: { xs: "14px", lg: "16px" },
button: { xs: "16px", lg: "16px" },
buttonBig: { xs: "18px", lg: "18px" },
input: { xs: "16px", lg: "16px" },
inputBig: { xs: "18px", lg: "18px" },
};
export const lineHeights: LineHeights = {
hero1: { xs: "1.10", lg: "1.10" },
hero2: { xs: "1.10", lg: "1.10" },
hero3: { xs: "1.20", lg: "1.10" },
h1: { xs: "1.50", lg: "1.40" },
h2: { xs: "1.50", lg: "1.50" },
h3: { xs: "1.30", lg: "1.50" },
h4: { xs: "1.30", lg: "1.50" },
h5: { xs: "1.60", lg: "1.50" },
h6: { xs: "1.60", lg: "1.60" },
text: { xs: "1.70", lg: "1.70" },
strong: { xs: "1.70", lg: "1.70" },
small: { xs: "1.70", lg: "1.70" },
blockquote: { xs: "1.70", lg: "1.70" },
code: { xs: "1.70", lg: "1.70" },
button: { xs: "1.00", lg: "1.00" },
buttonBig: { xs: "1.00", lg: "1.00" },
input: { xs: "1.00", lg: "1.00" },
inputBig: { xs: "1.00", lg: "1.00" },
};
export const theme: Theme = {
breakpoints,
spacing,
colors,
shadows,
fonts,
fontSizes,
lineHeights,
isDark: false,
};
export const themeDark: Theme = {
breakpoints,
spacing,
colors: colorsDark,
shadows: shadowsDark,
fonts,
fontSizes,
lineHeights,
isDark: true,
};
export interface Breakpoints<TNumber = number> {
xs: TNumber;
sm: TNumber;
md: TNumber;
lg: TNumber;
xl: TNumber;
xxl: TNumber;
xxxl: TNumber;
}
export interface Spacing<TString = string> {
maxWidth: { xs: TString; xxxl: TString };
padding: { xs: TString; lg: TString };
radius: { xs: TString; lg: TString; xl: TString };
gridGap: { xs: TString; lg: TString };
}
export interface Colors<TString = string> {
primaryLight: TString;
primary: TString;
primaryDark: TString;
secondaryLight: TString;
secondary: TString;
secondaryDark: TString;
tertiaryLight: TString;
tertiary: TString;
tertiaryDark: TString;
grayLight: TString;
gray: TString;
grayDark: TString;
success: TString;
error: TString;
warning: TString;
info: TString;
dark: TString;
light: TString;
}
interface Shadows<TString = string> {
xs: TString;
sm: TString;
md: TString;
lg: TString;
xl: TString;
}
export interface Fonts<TString = string> {
head: TString;
text: TString;
mono: TString;
}
export interface FontSizes<TString = string> {
hero1: { xs: TString; lg: TString };
hero2: { xs: TString; lg: TString };
hero3: { xs: TString; lg: TString };
h1: { xs: TString; lg: TString };
h2: { xs: TString; lg: TString };
h3: { xs: TString; lg: TString };
h4: { xs: TString; lg: TString };
h5: { xs: TString; lg: TString };
h6: { xs: TString; lg: TString };
text: { xs: TString; lg: TString };
strong: { xs: TString; lg: TString };
small: { xs: TString; lg: TString };
blockquote: { xs: TString; lg: TString };
code: { xs: TString; lg: TString };
button: { xs: TString; lg: TString };
buttonBig: { xs: TString; lg: TString };
input: { xs: TString; lg: TString };
inputBig: { xs: TString; lg: TString };
}
export interface LineHeights<TString = string> {
hero1: { xs: TString; lg: TString };
hero2: { xs: TString; lg: TString };
hero3: { xs: TString; lg: TString };
h1: { xs: TString; lg: TString };
h2: { xs: TString; lg: TString };
h3: { xs: TString; lg: TString };
h4: { xs: TString; lg: TString };
h5: { xs: TString; lg: TString };
h6: { xs: TString; lg: TString };
text: { xs: TString; lg: TString };
strong: { xs: TString; lg: TString };
small: { xs: TString; lg: TString };
blockquote: { xs: TString; lg: TString };
code: { xs: TString; lg: TString };
button: { xs: TString; lg: TString };
buttonBig: { xs: TString; lg: TString };
input: { xs: TString; lg: TString };
inputBig: { xs: TString; lg: TString };
}
export interface Theme {
breakpoints: Breakpoints;
spacing: Spacing;
colors: Colors;
shadows: Shadows;
fonts: Fonts;
fontSizes: FontSizes;
lineHeights: LineHeights;
isDark: boolean;
}
When extending the Cherry theme, it’s essential to adhere to established patterns. For instance:
We utilize the following size patterns: xs
, sm
, md
, lg
, xl
, xxl
, and xxxl
. These patterns define not only media queries but also various other sizes.
If you extend the theme, ensure that you add the necessary type definitions to maintain consistency and clarity. Happy theming! 🍒🎨
Explore the source code on GitHub: