Global design constants for consistent spacing, sizing, and styling across your React Native app components.

Installation

pnpm dlx bna-ui add globals

Usage

import { HEIGHT, FONT_SIZE, BORDER_RADIUS, CORNERS } from '@/theme/globals';
export function StyledButton({ title, onPress }) {
  return (
    <TouchableOpacity
      style={{
        height: HEIGHT,
        backgroundColor: '#007AFF',
        borderRadius: BORDER_RADIUS,
        justifyContent: 'center',
        alignItems: 'center',
        paddingHorizontal: 16,
      }}
      onPress={onPress}
    >
      <Text
        style={{
          color: 'white',
          fontSize: FONT_SIZE,
          fontWeight: '600',
        }}
      >
        {title}
      </Text>
    </TouchableOpacity>
  );
}

Constants

HEIGHT

Standard height for interactive elements like buttons, input fields, and list items.

ValueDescription
48Standard height in pixels for consistent touch targets

Usage:

const buttonStyle = {
  height: HEIGHT,
  minHeight: HEIGHT,
};

FONT_SIZE

Standard font size for body text and interactive elements.

ValueDescription
17Base font size in pixels following iOS design guidelines

Usage:

const textStyle = {
  fontSize: FONT_SIZE,
  lineHeight: FONT_SIZE * 1.4, // 23.8px line height
};

BORDER_RADIUS

Standard border radius for rounded elements like buttons and cards.

ValueDescription
26Border radius in pixels for moderately rounded corners

Usage:

const cardStyle = {
  borderRadius: BORDER_RADIUS,
  backgroundColor: '#F2F2F7',
};

CORNERS

Maximum border radius for fully rounded elements like circular buttons or pills.

ValueDescription
999Large border radius value for fully rounded elements

Usage:

const pillStyle = {
  borderRadius: CORNERS,
  paddingHorizontal: 16,
  paddingVertical: 8,
};

Usage Examples

Standard Button Component

import { HEIGHT, FONT_SIZE, BORDER_RADIUS } from '@/theme/globals';
import { Colors } from '@/theme/colors';
 
export function Button({ title, variant = 'primary', onPress, disabled }) {
  const colors = Colors.light; // or use useColorScheme hook
 
  const getButtonStyle = () => {
    const baseStyle = {
      height: HEIGHT,
      borderRadius: BORDER_RADIUS,
      justifyContent: 'center',
      alignItems: 'center',
      paddingHorizontal: 24,
    };
 
    switch (variant) {
      case 'primary':
        return {
          ...baseStyle,
          backgroundColor: disabled ? colors.muted : colors.primary,
        };
      case 'secondary':
        return {
          ...baseStyle,
          backgroundColor: colors.secondary,
          borderWidth: 1,
          borderColor: colors.border,
        };
      default:
        return baseStyle;
    }
  };
 
  const getTextStyle = () => ({
    fontSize: FONT_SIZE,
    fontWeight: '600',
    color: variant === 'primary' ? colors.primaryForeground : colors.text,
  });
 
  return (
    <TouchableOpacity
      style={getButtonStyle()}
      onPress={onPress}
      disabled={disabled}
    >
      <Text style={getTextStyle()}>{title}</Text>
    </TouchableOpacity>
  );
}

Input Field Component

import { HEIGHT, FONT_SIZE, BORDER_RADIUS } from '@/theme/globals';
import { Colors } from '@/theme/colors';
 
export function TextInput({ placeholder, value, onChangeText, ...props }) {
  const colors = Colors.light;
 
  return (
    <View
      style={{
        height: HEIGHT,
        borderRadius: BORDER_RADIUS,
        backgroundColor: colors.input,
        borderWidth: 1,
        borderColor: colors.border,
        paddingHorizontal: 16,
        justifyContent: 'center',
      }}
    >
      <TextInput
        style={{
          fontSize: FONT_SIZE,
          color: colors.text,
          flex: 1,
        }}
        placeholder={placeholder}
        placeholderTextColor={colors.mutedForeground}
        value={value}
        onChangeText={onChangeText}
        {...props}
      />
    </View>
  );
}

Best Practices

Consistency

Always use the global constants instead of hardcoded values to ensure consistency across your app.

// ✅ Good - uses global constants
const styles = StyleSheet.create({
  button: {
    height: HEIGHT,
    borderRadius: BORDER_RADIUS,
  },
  text: {
    fontSize: FONT_SIZE,
  },
});
 
// ❌ Bad - hardcoded values
const styles = StyleSheet.create({
  button: {
    height: 48,
    borderRadius: 26,
  },
  text: {
    fontSize: 17,
  },
});

Variations

Use the constants as a base and create variations when needed.

// Standard size
const normalButton = {
  height: HEIGHT,
  fontSize: FONT_SIZE,
};
 
// Large size
const largeButton = {
  height: HEIGHT * 1.25, // 60px
  fontSize: FONT_SIZE + 2, // 19px
};
 
// Small size
const smallButton = {
  height: HEIGHT * 0.75, // 36px
  fontSize: FONT_SIZE - 2, // 15px
};

Responsive Design

Consider using these constants as a base for responsive design calculations.

import { Dimensions } from 'react-native';
import { HEIGHT, FONT_SIZE } from '@/theme/globals';
 
const { width } = Dimensions.get('window');
const isTablet = width > 768;
 
const responsiveStyles = {
  button: {
    height: isTablet ? HEIGHT * 1.2 : HEIGHT,
    fontSize: isTablet ? FONT_SIZE + 1 : FONT_SIZE,
  },
};

Design System Integration

These constants form the foundation of your design system and should be used alongside your color system for consistent theming.

import { HEIGHT, FONT_SIZE, BORDER_RADIUS, CORNERS } from '@/theme/globals';
import { Colors } from '@/theme/colors';
 
export const designSystem = {
  spacing: {
    xs: 4,
    sm: 8,
    md: 16,
    lg: 24,
    xl: 32,
  },
  sizing: {
    height: HEIGHT,
    borderRadius: BORDER_RADIUS,
    corners: CORNERS,
  },
  typography: {
    fontSize: FONT_SIZE,
    lineHeight: FONT_SIZE * 1.4,
  },
  colors: Colors,
};

Platform Considerations

The global constants follow iOS design guidelines and provide optimal touch targets and readability across different screen sizes and densities. The 48px height ensures comfortable interaction on both phones and tablets.

Accessibility

The HEIGHT constant (48px) meets accessibility guidelines for minimum touch target size, ensuring comfortable interaction for users with motor impairments. The FONT_SIZE (17px) provides good readability while maintaining the platform's design language.