Multipliers
Multiplier constants that define the base units for spacing and border radius calculations, enabling consistent scaling and responsive design throughout your healthcare application.
Quick Example
import React from "react";
import { useAppTheme, DEFAULT_MULTIPLIERS } from "@ovok/mobile";
import { View, Text } from "react-native";
export const MultiplierExample = () => {
const theme = useAppTheme();
return (
<View
style={{
padding: theme.spacing(4), // 16px (4 * 4)
marginBottom: theme.spacing(3), // 12px (3 * 4)
gap: theme.spacing(2), // 8px (2 * 4)
borderRadius: theme.borderRadius(3), // 12px (3 * 4)
}}
>
<Text>Consistent spacing using multipliers</Text>
</View>
);
};
Default Multipliers
export const DEFAULT_MULTIPLIERS = {
spacing: 4, // Base spacing unit in pixels
borderRadius: 4, // Base border radius unit in pixels
} as const;
Spacing Multiplier
The spacing multiplier defines the base unit for all spacing calculations:
- Default:
4pixels - Usage:
theme.spacing(value)returnsvalue * spacingMultiplier - Purpose: Consistent padding, margins, gaps, and layout spacing
Border Radius Multiplier
The border radius multiplier defines the base unit for border radius calculations:
- Default:
4pixels - Usage:
theme.borderRadius(value)returnsvalue * borderRadiusMultiplier - Purpose: Consistent corner rounding across UI elements
Spacing System
Common Spacing Values
With the default 4px multiplier:
theme.spacing(0.5); // 2px - Minimal spacing
theme.spacing(1); // 4px - Tight spacing
theme.spacing(2); // 8px - Small gaps
theme.spacing(3); // 12px - Medium spacing
theme.spacing(4); // 16px - Standard padding
theme.spacing(5); // 20px - Large spacing
theme.spacing(6); // 24px - Section spacing
theme.spacing(8); // 32px - Component separation
theme.spacing(12); // 48px - Page margins
theme.spacing(16); // 64px - Large sections
Spacing Usage Patterns
Component Internal Spacing
export const HealthCard = ({ children }) => {
const theme = useAppTheme();
return (
<View
style={{
padding: theme.spacing(4), // 16px internal padding
gap: theme.spacing(3), // 12px between elements
}}
>
{children}
</View>
);
};
Layout and Margins
export const HealthDashboard = () => {
const theme = useAppTheme();
return (
<ScrollView
contentContainerStyle={{
padding: theme.spacing(4), // 16px screen padding
paddingBottom: theme.spacing(8), // 32px bottom padding
}}
>
<View style={{ gap: theme.spacing(6) }}>
{" "}
{/* 24px between sections */}
<HealthCard />
<HealthCard />
<HealthCard />
</View>
</ScrollView>
);
};
Form Elements
export const MedicalForm = () => {
const theme = useAppTheme();
return (
<View
style={{
padding: theme.spacing(4), // 16px form padding
gap: theme.spacing(4), // 16px between form fields
}}
>
<TextInput
style={{
paddingHorizontal: theme.spacing(3), // 12px input padding
paddingVertical: theme.spacing(2), // 8px input padding
}}
/>
<Button
style={{
marginTop: theme.spacing(6), // 24px button spacing
}}
/>
</View>
);
};
Border Radius System
Common Border Radius Values
With the default 4px multiplier:
theme.borderRadius(0); // 0px - No rounding (sharp corners)
theme.borderRadius(1); // 4px - Subtle rounding
theme.borderRadius(2); // 8px - Standard rounding
theme.borderRadius(3); // 12px - Medium rounding
theme.borderRadius(4); // 16px - Prominent rounding
theme.borderRadius(6); // 24px - Large rounding
theme.borderRadius(8); // 32px - Very large rounding
theme.borderRadius(12); // 48px - Extreme rounding
Border Radius Usage Patterns
UI Element Hierarchy
export const UIElementsExample = () => {
const theme = useAppTheme();
return (
<View>
{/* Subtle elements */}
<View
style={{
borderRadius: theme.borderRadius(1), // 4px - Input fields, small buttons
backgroundColor: theme.colors.surface,
}}
/>
{/* Standard elements */}
<View
style={{
borderRadius: theme.borderRadius(2), // 8px - Cards, standard buttons
backgroundColor: theme.colors.surface,
}}
/>
{/* Prominent elements */}
<View
style={{
borderRadius: theme.borderRadius(3), // 12px - Feature cards, modals
backgroundColor: theme.colors.surface,
}}
/>
{/* Large elements */}
<View
style={{
borderRadius: theme.borderRadius(4), // 16px - Hero sections, large cards
backgroundColor: theme.colors.surface,
}}
/>
</View>
);
};
Healthcare Component Styling
export const VitalSignCard = ({ title, value, status }) => {
const theme = useAppTheme();
return (
<View
style={{
backgroundColor: theme.colors.surface,
borderRadius: theme.borderRadius(3), // 12px - Card rounding
padding: theme.spacing(4), // 16px - Card padding
marginBottom: theme.spacing(3), // 12px - Card spacing
shadowRadius: theme.borderRadius(2), // 8px - Shadow rounding
}}
>
<View
style={{
backgroundColor: theme.colors.primary,
borderRadius: theme.borderRadius(2), // 8px - Badge rounding
padding: theme.spacing(2), // 8px - Badge padding
alignSelf: "flex-start",
}}
>
<Text style={{ color: "white" }}>{status}</Text>
</View>
<Text style={{ fontSize: 24, marginTop: theme.spacing(2) }}>{value}</Text>
</View>
);
};
Responsive Multipliers
Device-Specific Scaling
import { useWindowDimensions } from "react-native";
export const useResponsiveMultipliers = () => {
const { width } = useWindowDimensions();
// Determine device type
const isTablet = width > 768;
const isLargeTablet = width > 1024;
return React.useMemo(() => {
if (isLargeTablet) {
return {
spacing: 6, // 6px base unit for large tablets
borderRadius: 8, // 8px base unit for large tablets
};
} else if (isTablet) {
return {
spacing: 5, // 5px base unit for tablets
borderRadius: 6, // 6px base unit for tablets
};
} else {
return {
spacing: 4, // 4px base unit for mobile
borderRadius: 4, // 4px base unit for mobile
};
}
}, [isLargeTablet, isTablet]);
};
Accessibility Scaling
import { PixelRatio } from "react-native";
export const useAccessibilityMultipliers = () => {
const fontScale = PixelRatio.getFontScale();
return React.useMemo(() => {
// Scale multipliers based on user's font size preferences
const scaleFactor = Math.min(fontScale, 1.3); // Cap at 130%
return {
spacing: Math.round(4 * scaleFactor),
borderRadius: 4, // Keep border radius constant for visual consistency
};
}, [fontScale]);
};
Dynamic Theme Configuration
export const ResponsiveThemeProvider = ({ children }) => {
const { width } = useWindowDimensions();
const isTablet = width > 768;
const themeConfig = React.useMemo(
() => ({
colors: DEFAULT_COLORS,
dark: false,
spacingMultiplier: isTablet ? 6 : 4, // Larger spacing on tablets
borderRadiusMultiplier: isTablet ? 8 : 4, // More pronounced rounding on tablets
}),
[isTablet],
);
return <ThemeProvider theme={themeConfig}>{children}</ThemeProvider>;
};
Custom Multiplier Configurations
Compact Design
const compactMultipliers = {
spacing: 3, // Tighter spacing for dense layouts
borderRadius: 2, // Less rounding for compact design
};
Spacious Design
const spaciousMultipliers = {
spacing: 6, // Generous spacing for comfortable layouts
borderRadius: 8, // More pronounced rounding
};
Medical Device Interface
const medicalDeviceMultipliers = {
spacing: 8, // Large touch targets for medical environments
borderRadius: 12, // High visibility rounding
};
Healthcare-Specific Configurations
const healthcareConfigurations = {
// Emergency room - high visibility
emergency: {
spacing: 8,
borderRadius: 6,
},
// Patient room - comfortable
patient: {
spacing: 6,
borderRadius: 8,
},
// Mobile clinic - compact
mobile: {
spacing: 3,
borderRadius: 2,
},
// Elderly care - accessibility-focused
elderly: {
spacing: 10,
borderRadius: 4,
},
};
Best Practices
Consistent Spacing Hierarchy
// ✅ Good - Use consistent spacing hierarchy
<View
style={{
padding: theme.spacing(4), // Container padding
gap: theme.spacing(3), // Element spacing
marginBottom: theme.spacing(6), // Section spacing
}}
>
<Text style={{ marginBottom: theme.spacing(2) }}> {/* Text spacing */}
Title
</Text>
<Text style={{ marginBottom: theme.spacing(1) }}> {/* Tight spacing */}
Subtitle
</Text>
</View>
// ❌ Avoid - Arbitrary spacing values
<View
style={{
padding: 13, // Arbitrary value
gap: 7, // Arbitrary value
marginBottom: 23, // Arbitrary value
}}
>
Semantic Spacing
// Define semantic spacing constants
const SPACING = {
tight: 1, // theme.spacing(1) = 4px
small: 2, // theme.spacing(2) = 8px
medium: 3, // theme.spacing(3) = 12px
standard: 4, // theme.spacing(4) = 16px
large: 6, // theme.spacing(6) = 24px
section: 8, // theme.spacing(8) = 32px
} as const;
// Usage with semantic meaning
<View
style={{
padding: theme.spacing(SPACING.standard), // Standard padding
gap: theme.spacing(SPACING.medium), // Medium element gaps
marginBottom: theme.spacing(SPACING.section), // Section separation
}}
>
Component-Specific Constants
// Define component-specific spacing
const CARD_SPACING = {
padding: 4, // Internal card padding
gap: 3, // Between card elements
margin: 3, // Between cards
} as const;
const FORM_SPACING = {
padding: 4, // Form padding
fieldGap: 4, // Between form fields
buttonMargin: 6, // Above form buttons
} as const;
Performance Considerations
Memoization
// ✅ Good - Memoize multiplier-dependent calculations
const useComponentStyles = () => {
const theme = useAppTheme();
return React.useMemo(
() => ({
container: {
padding: theme.spacing(4),
borderRadius: theme.borderRadius(2),
},
content: {
gap: theme.spacing(3),
marginBottom: theme.spacing(6),
},
}),
[theme.spacing, theme.borderRadius],
);
};
Static References
// ✅ Good - Use multiplier constants for configuration
const COMPONENT_CONFIG = {
containerPadding: 4, // Will be multiplied by theme.spacing
contentGap: 3, // Will be multiplied by theme.spacing
borderRadius: 2, // Will be multiplied by theme.borderRadius
} as const;
// Usage in component
const styles = {
container: {
padding: theme.spacing(COMPONENT_CONFIG.containerPadding),
borderRadius: theme.borderRadius(COMPONENT_CONFIG.borderRadius),
},
};
Related Components
- ThemeProvider - Configures multipliers via theme props
- useAppTheme - Provides access to spacing and borderRadius functions