Theme UI provides hooks for accessing theme context and color mode state, along with utility functions for theme manipulation, object access, and style generation. These tools enable advanced theme integration and programmatic theme usage outside of React components.
The useThemeUI hook provides access to the complete theme context including the theme object and color mode state.
/**
* Access the complete Theme UI context
* @returns Object containing theme, colorMode, and setColorMode
*/
function useThemeUI(): ThemeUIContextValue;
interface ThemeUIContextValue {
/** Current theme object */
theme: Theme;
/** Current color mode name */
colorMode?: string;
/** Function to change color mode */
setColorMode?: (mode: string) => void;
}Usage Examples:
import { useThemeUI } from 'theme-ui'
function ThemeInspector() {
const { theme, colorMode, setColorMode } = useThemeUI()
return (
<div>
<h3>Current Theme</h3>
<p>Color Mode: {colorMode}</p>
<p>Primary Color: {theme.colors?.primary}</p>
<p>Font Sizes: {JSON.stringify(theme.fontSizes)}</p>
<button onClick={() => setColorMode?.(colorMode === 'light' ? 'dark' : 'light')}>
Toggle Mode
</button>
</div>
)
}
// Access specific theme values
function ThemedComponent() {
const { theme } = useThemeUI()
const primaryColor = theme.colors?.primary || '#007acc'
const largeFontSize = theme.fontSizes?.[4] || '24px'
return (
<div style={{
color: primaryColor,
fontSize: largeFontSize
}}>
Programmatically styled
</div>
)
}The useColorMode hook provides direct access to color mode state management.
/**
* Get and set the current color mode
* @returns Tuple of [currentMode, setMode] similar to useState
*/
function useColorMode(): [string, (mode: string) => void];Usage Examples:
import { useColorMode } from 'theme-ui'
function ColorModeToggle() {
const [colorMode, setColorMode] = useColorMode()
const toggleMode = () => {
setColorMode(colorMode === 'light' ? 'dark' : 'light')
}
return (
<button onClick={toggleMode}>
{colorMode === 'light' ? 'π' : 'βοΈ'}
Switch to {colorMode === 'light' ? 'dark' : 'light'} mode
</button>
)
}
function MultiModeToggle() {
const [colorMode, setColorMode] = useColorMode()
const modes = ['light', 'dark', 'sepia']
const nextMode = () => {
const currentIndex = modes.indexOf(colorMode)
const nextIndex = (currentIndex + 1) % modes.length
setColorMode(modes[nextIndex])
}
return (
<button onClick={nextMode}>
Current: {colorMode} (click for next)
</button>
)
}
// Conditional rendering based on color mode
function ModeSpecificContent() {
const [colorMode] = useColorMode()
if (colorMode === 'dark') {
return <div>π Dark mode content</div>
}
return <div>βοΈ Light mode content</div>
}The css function converts theme-aware style objects to CSS for use with other styling solutions.
/**
* Convert theme-aware styles to CSS function
* @param styles - Style object with theme references and responsive values
* @returns Function that accepts theme and returns CSS object
*/
function css(styles: ThemeUIStyleObject): (theme: Theme) => CSSObject;
interface ThemeUIStyleObject {
[property: string]: ResponsiveStyleValue<any>;
}
interface CSSObject {
[property: string]: any;
}Usage Examples:
import { css } from 'theme-ui'
import styled from '@emotion/styled'
// Create CSS function from theme-aware styles
const buttonStyles = css({
bg: 'primary',
color: 'white',
fontSize: 2,
px: 4,
py: 2,
border: 'none',
borderRadius: 'default',
cursor: 'pointer',
'&:hover': {
bg: 'secondary'
},
'&:disabled': {
opacity: 0.5,
cursor: 'not-allowed'
}
})
// Use with emotion/styled-components
const StyledButton = styled.button(buttonStyles)
// Use with CSS-in-JS libraries
import { useTheme } from '@emotion/react'
function CustomComponent() {
const theme = useTheme()
const styles = css({
display: 'flex',
alignItems: 'center',
gap: 2,
p: 3,
bg: 'background',
border: '1px solid',
borderColor: 'muted',
borderRadius: 'md'
})(theme)
return <div style={styles}>Custom styled component</div>
}
// Generate responsive CSS
const responsiveStyles = css({
fontSize: [2, 3, 4], // 14px, 16px, 20px
padding: [2, 3, 4], // 8px, 16px, 32px
display: ['block', 'flex'], // block on mobile, flex on tablet+
flexDirection: [null, 'column', 'row'] // column on tablet, row on desktop
})The get function safely accesses nested object properties using dot notation with fallback support.
/**
* Get nested values from objects using dot notation
* @param object - Object to search in
* @param key - Dot-notation key path (e.g., 'colors.primary', 'fontSizes.3')
* @param fallback - Fallback value if key path not found
* @returns Retrieved value or fallback
*/
function get(object: object, key: string, fallback?: any): any;Usage Examples:
import { get, useThemeUI } from 'theme-ui'
function ComponentWithThemeAccess() {
const { theme } = useThemeUI()
// Safe theme value access with fallbacks
const primaryColor = get(theme, 'colors.primary', '#007acc')
const fontSize3 = get(theme, 'fontSizes.3', '16px')
const buttonPadding = get(theme, 'space.3', '16px')
const borderRadius = get(theme, 'radii.default', '4px')
// Access deeply nested values
const buttonVariant = get(theme, 'buttons.primary.backgroundColor', primaryColor)
const shadowLarge = get(theme, 'shadows.lg', '0 10px 25px rgba(0,0,0,0.15)')
// Array access by index
const breakpointMd = get(theme, 'breakpoints.1', '52em')
const spacingLg = get(theme, 'space.4', '32px')
return (
<div
style={{
color: primaryColor,
fontSize: fontSize3,
padding: buttonPadding,
borderRadius: borderRadius,
boxShadow: shadowLarge
}}
>
Safely accessing theme values
</div>
)
}
// Helper function for theme access
function useThemeValue(path: string, fallback?: any) {
const { theme } = useThemeUI()
return get(theme, path, fallback)
}
function ComponentWithHelper() {
const primaryColor = useThemeValue('colors.primary', '#000')
const largeFontSize = useThemeValue('fontSizes.4', '20px')
return (
<h2 style={{ color: primaryColor, fontSize: largeFontSize }}>
Using theme helper
</h2>
)
}The merge function deeply merges objects, useful for extending themes and combining configuration objects.
/**
* Deep merge two objects with Theme UI-specific logic
* @param target - Base object to merge into
* @param source - Source object to merge from
* @returns New merged object
*/
function merge(target: object, source: object): object;Usage Examples:
import { merge } from 'theme-ui'
// Extend base theme
const baseTheme = {
colors: {
text: '#000',
background: '#fff',
primary: '#007acc'
},
fonts: {
body: 'system-ui, sans-serif'
},
fontSizes: [12, 14, 16, 20, 24, 32]
}
const darkTheme = merge(baseTheme, {
colors: {
text: '#fff',
background: '#111',
secondary: '#ff6b6b' // Added new color
},
// fonts and fontSizes inherited from baseTheme
})
// Extend component variants
const baseButtons = {
primary: {
bg: 'primary',
color: 'white'
}
}
const extendedButtons = merge(baseButtons, {
primary: {
borderRadius: 'full', // Extends existing primary variant
fontWeight: 'bold'
},
secondary: { // Adds new variant
bg: 'secondary',
color: 'white'
}
})
// Theme composition
const createTheme = (overrides = {}) => {
const defaultTheme = {
colors: {
primary: '#007acc',
secondary: '#ff6b6b'
},
space: [0, 4, 8, 16, 32, 64]
}
return merge(defaultTheme, overrides)
}
const customTheme = createTheme({
colors: {
primary: '#9c27b0', // Override primary
accent: '#ffa726' // Add new color
},
radii: { // Add new scale
sm: 2,
md: 4,
lg: 8
}
})The __ThemeUIContext provides direct access to the React context for advanced use cases.
/**
* Direct access to Theme UI React context (advanced usage)
*/
const __ThemeUIContext: React.Context<ThemeUIContextValue>;
/**
* Enhanced createElement function with theme awareness
* @param type - Element type or component
* @param props - Element props
* @param children - Child elements
* @returns JSX element with theme processing
*/
function createElement(type: any, props?: any, ...children: any[]): JSX.Element;Usage Examples:
import { __ThemeUIContext, createElement } from 'theme-ui'
import { useContext } from 'react'
// Direct context access (advanced)
function AdvancedThemeComponent() {
const context = useContext(__ThemeUIContext)
if (!context) {
throw new Error('Component must be used within ThemeUIProvider')
}
const { theme, colorMode, setColorMode } = context
return (
<div>
<p>Advanced theme access</p>
<pre>{JSON.stringify(theme.colors, null, 2)}</pre>
</div>
)
}
// Custom createElement usage
function CustomComponent({ sx, ...props }) {
return createElement('div', {
...props,
sx: {
p: 3,
bg: 'background',
color: 'text',
...sx
}
})
}Utility functions for validating and debugging theme configuration.
/**
* Validate theme object structure
* @param theme - Theme object to validate
* @returns Validation result with errors/warnings
*/
interface ThemeValidationResult {
valid: boolean;
errors: string[];
warnings: string[];
}
// Note: These are conceptual - actual validation would be implementation-specific
function validateTheme(theme: Theme): ThemeValidationResult;
function debugTheme(theme: Theme): void;Usage Examples:
// Theme debugging in development
import { useThemeUI } from 'theme-ui'
function ThemeDebugger() {
const { theme } = useThemeUI()
// Log theme structure in development
React.useEffect(() => {
if (process.env.NODE_ENV === 'development') {
console.group('Theme UI Debug')
console.log('Theme object:', theme)
console.log('Available colors:', Object.keys(theme.colors || {}))
console.log('Font sizes:', theme.fontSizes)
console.log('Spacing scale:', theme.space)
console.groupEnd()
}
}, [theme])
return null
}interface ThemeUIContextValue {
theme: Theme;
colorMode?: string;
setColorMode?: (mode: string) => void;
}
interface Theme {
colors?: ColorTheme;
fonts?: { [key: string]: string };
fontSizes?: (string | number)[] | { [key: string]: string | number };
fontWeights?: { [key: string]: string | number };
lineHeights?: { [key: string]: string | number };
space?: (string | number)[] | { [key: string]: string | number };
sizes?: { [key: string]: string | number };
radii?: { [key: string]: string | number };
shadows?: { [key: string]: string };
breakpoints?: Breakpoints;
zIndices?: { [key: string]: number };
styles?: ThemeStyles;
[componentName: string]: any;
}
interface ColorTheme {
[colorName: string]: string;
modes?: {
[modeName: string]: {
[colorName: string]: string;
};
};
}
interface ThemeUIStyleObject {
[property: string]: ResponsiveStyleValue<any>;
}
type ResponsiveStyleValue<T> = T | Array<T | null | undefined>;
interface CSSObject {
[property: string]: any;
}
interface Breakpoints extends Array<string> {
[key: string]: string;
}
interface ThemeStyles {
root?: ThemeUIStyleObject;
[element: string]: ThemeUIStyleObject | undefined;
}
interface ThemeValidationResult {
valid: boolean;
errors: string[];
warnings: string[];
}