Color Theme Matters
Why
- Consistency: If you reference Colors.primary everywhere rather than hard‐coding #4A90E2, you guarantee uniform look.
- Maintainability: When your designer says “Change primary from blue to purple,” you change one file instead of hunting through hundreds of styles.
- Light/Dark Mode: By defining both a “light” palette and a “dark” palette, your UI can automatically adapt when the user switches their device theme (iOS or Android).
- Accessibility & Contrast: A well‐designed theme makes it easier to ensure your text has enough contrast against your backgrounds in both modes.
- Semantic Usage: You think “This is a primary button,” “This is a background surface,” “This is error text,” etc. rather than “This is #E53935,” which clarifies intent.
2. Building Blocks: Color “Slots” or Tokens
Most apps follow a pattern similar to Material Design’s color roles. You can simplify or expand as needed, but here is a common set:
type ThemeColors = {
/** Primary brand color (buttons, links, active elements) */
primary: string
/** Secondary accent color (for highlights, toggles, UI accents) */
secondary: string
/** Background color of app screens */
background: string
/** Surface color: card backgrounds, sheets, etc. */
surface: string
/** Default text color on a “surface” background */
text: string
/** Subheading or secondary text (less emphasis) */
textSecondary: string
/** Borders and dividers */
border: string
/** Error states (form errors, destructive buttons) */
error: string
/** Success states (toast messages, success badges) */
success: string
/** Warning states (alerts) */
warning: string
/** Disabled / inactive elements */
disabled: string
}
Why These Tokens?
- primary: Used for your main call‐to‐action, interactive elements, and highlights.
- secondary: A contrasting accent you can use sparingly (for example, in badges or secondary buttons).
- background: The “canvas” behind the entire screen (often a very light gray in light mode, or near‐black in dark mode).
- surface: Used for “cards,” “sheets,” “modals,” anything that sits on top of the background.
- text & textSecondary: Ensure your main text is high‐contrast, while secondary text can be a bit lighter.
- border: For hairline dividers, input outlines, separators between list items.
- error, success, warning: Dedicated semantic colors for form validation, status badges, or snackbars.
- disabled: A semi‐transparent or low‐contrast color to show that a button or input is not interactive.
3. Coding the Theme: Light & Dark Palettes
Create a file app/constants/Colors.ts (or app/theme/Colors.ts). In there, define two objects—light and dark—that conform to ThemeColors.
// app/constants/Colors.ts
export interface ThemeColors {
primary: string
secondary: string
background: string
surface: string
text: string
textSecondary: string
border: string
error: string
success: string
warning: string
disabled: string
}
// A sample Light Theme palette
export const light: ThemeColors = {
primary: '#4A90E2', // a pleasant medium‐blue
secondary: '#D81B60', // a striking magenta accent
background: '#F7F7F7', // very light gray
surface: '#FFFFFF', // pure white cards/sheets
text: '#212121', // nearly black, high contrast on white
textSecondary: '#666666', // mid‐gray for subheadings
border: '#E0E0E0', // light gray border
error: '#E53935', // red
success: '#43A047', // green
warning: '#FB8C00', // orange
disabled: '#BDBDBD', // light gray for disabled
}
// A sample Dark Theme palette
export const dark: ThemeColors = {
primary: '#64B5F6', // lighter blue for dark backgrounds
secondary: '#F48FB1', // lighter accent
background: '#121212', // near‐black background
surface: '#1E1E1E', // dark gray for cards/sheets
text: '#FFFFFF', // white text on dark surfaces
textSecondary: '#A0A0A0', // light‐gray for secondary text
border: '#272727', // slightly lighter than surface
error: '#EF5350', // red
success: '#66BB6A', // green
warning: '#FFA726', // orange
disabled: '#555555', // gray for disabled controls
}
// A small helper to pick the right theme
export const Colors = { light, dark }- Notice how the dark palette always picks slightly lighter versions (so that buttons/pop‐ups stand out on a near‐black background).
