Theme & Tokens
Learn how we structure and use our design tokens with Restyle
This document provides an overview of the structure and usage of the custom appTheme used in our application, built with @shopify/restyle. It explains how the design tokens are organized and the rationale behind the choices made for maintainability and scalability.
🧩 Theme Overview
The appTheme
defines our design system tokens for colors, spacing, radii, breakpoints, typography, strokes, and more. These tokens are used consistently across our UI components to ensure design consistency and scalability.
The theme was created using the createTheme
function from @shopify/restyle
, which allows us to define a structured theme object that can be easily extended and modified.
import { createTheme } from '@shopify/restyle'
const appTheme = createTheme({
// tokens here...
})
📦 Importing the Theme
To use the appTheme
in your components, you need to import it from the theme file:
import appTheme from '@madefordevs1999/ui-launch-native/system/theme/appTheme';
🖍️ Color Tokens
All color values are referenced via ColorChoices, which maps semantic color roles (like BackgroundNeutral, TextPrimary, IconError) to actual color values from colorPalette.
✅ Why use ColorChoices instead of direct color names?
Future-proofing: If the library or color palette changes, we only need to update the mapping—not every component.
- Semantic clarity: Names like
TextErrorStrong
are easier to understand in context thanRose_800
. - Theming flexibility: Makes it easier to implement light/dark mode or brand-specific themes.
Example
[ColorChoices.TextPrimary]: colorPalette.ChileRojo_600,
📐 Spacing choices
Spacing tokens are defined using a consistent scale, allowing for predictable and uniform spacing throughout the application. This helps maintain visual harmony and alignment across different components.
spacing: {
[Spacing.Spacing0_25]: SpacingValues.Spacing0_25,
...
}
🧊 Border Radii (Radius choices)
Border radii are defined to provide consistent corner rounding across components. This helps create a cohesive look and feel throughout the application.
borderRadii: {
[RadiusChoices.Radius1]: RadiusSpacing.Radius1,
...
}
📱 Breakpoints
breakpoints: {
[BreakpointsSpacing.Mobile]: BreakpointsSpacingValues.Mobile,
...
}
This allow support to responsive layouts and enables custom behavior across device sizes.
➖ Stroke Widths
Used for defining border thicknesses across components:
strokeWidths: {
[StrokeWidthChoices.StrokeWidth1]: StrokeWidthValues.StrokeWidth1,
...
}
🗂 Z Indices
Basic stacking context from 1 to 5.
zIndices: {
[1]: 1,
[2]: 2,
[3]: 3,
[4]: 4,
[5]: 5,
}
Example Usage
You can use the appTheme
in your components by wrapping your application with the ThemeProvider
and using useTheme
to access the theme tokens inside your components.
import {ButtonVariants} from '@madefordevs1999/ui-launch-native/system/atoms/Button';
import { ButtonSubmitProps } from '@madefordevs1999/ui-launch-native/system/molecules/ButtonSubmit';
import ButtonWithIcon from '@madefordevs1999/ui-launch-native/system/molecules/ButtonWithIcon';
import useTheme from '@madefordevs1999/ui-launch-native/system/theme/useTheme';
import {ActivityIndicator} from 'react-native';
const ButtonSubmit: React.FC<ButtonSubmitProps> = ({
disabledWhenIsLoading = true,
disabled,
isLoading = false,
...rest
}) => {
const {colors} = useTheme();
return (
<ButtonWithIcon
disabled={disabled || (disabledWhenIsLoading && isLoading)}
{...rest}
{...(isLoading
? {
renderRight: ({variant}) => (
<ActivityIndicator
size="small"
color={
isLoading && disabledWhenIsLoading
? colors.TextDisableStrong
: variant === ButtonVariants.Primary
? colors.TextStaticWhite
: colors.TextPrimary
}
/>
),
}
: {})}
/>
);
};
export default ButtonSubmit;
Results
This example shows how to use the appTheme
to access colors and other tokens in a component. The useTheme
hook provides access to the theme, allowing you to use the defined tokens for styling.