618 lines
14 KiB
Markdown
618 lines
14 KiB
Markdown
# Physician App - Theme System & Design Flow
|
|
|
|
## 🎨 Design System Overview
|
|
|
|
### **Project Theme Structure**
|
|
```
|
|
app/theme/
|
|
├── theme.ts # Main theme configuration
|
|
├── colors.ts # Color palette definitions
|
|
├── typography.ts # Font families, sizes, weights
|
|
├── spacing.ts # Spacing scale and breakpoints
|
|
├── shadows.ts # Shadow and elevation system
|
|
└── animations.ts # Animation durations and easing
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Color Palette - "Modern Healthcare Blue"
|
|
|
|
### **Primary Colors**
|
|
```typescript
|
|
Primary: '#2196F3' // Material Blue - Main brand color
|
|
Secondary: '#1976D2' // Darker Blue - Secondary actions
|
|
Tertiary: '#E3F2FD' // Very Light Blue - Backgrounds
|
|
Quaternary: '#0D47A1' // Deep Blue - Accents
|
|
```
|
|
|
|
### **Text Colors**
|
|
```typescript
|
|
TextPrimary: '#212121' // Dark Gray - Main text
|
|
TextSecondary: '#757575' // Medium Gray - Secondary text
|
|
TextMuted: '#9E9E9E' // Light Gray - Muted text
|
|
```
|
|
|
|
### **Background Colors**
|
|
```typescript
|
|
Background: '#FFFFFF' // White - Primary background
|
|
BackgroundAlt: '#FAFAFA' // Light Gray - Alternative background
|
|
BackgroundAccent: '#F5F5F5' // Soft Gray - Accent backgrounds
|
|
```
|
|
|
|
### **Status & Feedback Colors**
|
|
```typescript
|
|
Success: '#4CAF50' // Material Green - Success states
|
|
Warning: '#FF9800' // Material Orange - Warning states
|
|
Error: '#F44336' // Material Red - Error states
|
|
Info: '#2196F3' // Material Blue - Information states
|
|
Critical: '#F44336' // Critical alerts and emergencies
|
|
```
|
|
|
|
### **UI Elements**
|
|
```typescript
|
|
Border: '#E0E0E0' // Light Gray Border
|
|
CardBackground: '#FFFFFF' // White - Card backgrounds
|
|
Shadow: 'rgba(0, 0, 0, 0.1)' // Subtle Gray Shadow
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 Typography System
|
|
|
|
### **Font Families (Roboto)**
|
|
```typescript
|
|
// Available Font Families
|
|
fontFamily: {
|
|
bold: 'Roboto-Bold',
|
|
medium: 'Roboto-Medium',
|
|
regular: 'Roboto-Regular',
|
|
light: 'Roboto-Light',
|
|
semibold: 'Roboto-SemiBold',
|
|
extrabold: 'Roboto-ExtraBold',
|
|
}
|
|
```
|
|
|
|
### **Font Weights**
|
|
```typescript
|
|
fontWeight: {
|
|
light: '300',
|
|
regular: '400',
|
|
medium: '500',
|
|
bold: '700',
|
|
}
|
|
```
|
|
|
|
### **Font Sizes**
|
|
```typescript
|
|
fontSize: {
|
|
displayLarge: 32, // Main headings
|
|
displayMedium: 24, // Section headings
|
|
displaySmall: 20, // Subsection headings
|
|
bodyLarge: 16, // Body text
|
|
bodyMedium: 14, // Secondary text
|
|
bodySmall: 12, // Captions
|
|
caption: 10, // Small labels
|
|
}
|
|
```
|
|
|
|
### **Line Heights & Spacing**
|
|
```typescript
|
|
lineHeight: {
|
|
tight: 1.2, // Headings
|
|
normal: 1.4, // Body text
|
|
relaxed: 1.6, // Long text
|
|
}
|
|
|
|
letterSpacing: {
|
|
tight: -0.5, // Headings
|
|
normal: 0, // Body text
|
|
wide: 0.5, // Labels
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📐 Spacing & Layout
|
|
|
|
### **Spacing Scale (Base: 4px)**
|
|
```typescript
|
|
spacing: {
|
|
xs: 4, // 4px
|
|
sm: 8, // 8px
|
|
md: 16, // 16px
|
|
lg: 24, // 24px
|
|
xl: 32, // 32px
|
|
xxl: 48, // 48px
|
|
xxxl: 64 // 64px
|
|
}
|
|
```
|
|
|
|
### **Border Radius**
|
|
```typescript
|
|
borderRadius: {
|
|
small: 4,
|
|
medium: 8,
|
|
large: 12,
|
|
xlarge: 16,
|
|
round: 50,
|
|
}
|
|
```
|
|
|
|
### **Breakpoints**
|
|
```typescript
|
|
breakpoints: {
|
|
mobile: 375,
|
|
tablet: 768,
|
|
desktop: 1024,
|
|
largeDesktop: 1440,
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎨 Icon System
|
|
|
|
### **React Native Vector Icons**
|
|
|
|
#### **Available Icon Sets**
|
|
```typescript
|
|
// Primary Icon Sets
|
|
import Icon from 'react-native-vector-icons/Feather'; // Clean, minimal icons
|
|
import Icon from 'react-native-vector-icons/MaterialIcons'; // Material Design icons
|
|
import Icon from 'react-native-vector-icons/Ionicons'; // iOS-style icons
|
|
```
|
|
|
|
#### **Icon Usage Guidelines**
|
|
```typescript
|
|
// Standard Icon Implementation
|
|
<Icon
|
|
name="mail" // Icon name
|
|
size={20} // Size in pixels
|
|
color={theme.colors.textSecondary} // Color from theme
|
|
style={styles.icon} // Additional styling
|
|
/>
|
|
|
|
// Icon Sizes
|
|
IconSizes: {
|
|
xs: 12, // Extra small
|
|
sm: 16, // Small
|
|
md: 24, // Medium (default)
|
|
lg: 32, // Large
|
|
xl: 48 // Extra large
|
|
}
|
|
```
|
|
|
|
#### **Common Icon Names**
|
|
```typescript
|
|
// Navigation Icons
|
|
'home', 'menu', 'arrow-left', 'arrow-right', 'chevron-down', 'chevron-up'
|
|
|
|
// Action Icons
|
|
'plus', 'minus', 'edit', 'delete', 'save', 'cancel', 'check', 'close'
|
|
|
|
// Medical Icons
|
|
'heart', 'user', 'settings', 'bell', 'search', 'filter', 'calendar'
|
|
|
|
// Status Icons
|
|
'check-circle', 'alert-circle', 'info', 'warning', 'error'
|
|
```
|
|
|
|
---
|
|
|
|
## 🏗️ Component Design Rules
|
|
|
|
### **Button Design System**
|
|
```typescript
|
|
// Button Variants
|
|
Primary: {
|
|
backgroundColor: theme.colors.primary,
|
|
borderColor: theme.colors.primary,
|
|
borderRadius: theme.borderRadius.medium,
|
|
shadowColor: theme.colors.primary,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
shadowOpacity: 0.3,
|
|
shadowRadius: 4,
|
|
elevation: 3
|
|
}
|
|
|
|
Secondary: {
|
|
backgroundColor: 'transparent',
|
|
borderColor: theme.colors.primary,
|
|
borderRadius: theme.borderRadius.medium
|
|
}
|
|
|
|
Success: {
|
|
backgroundColor: theme.colors.success,
|
|
borderColor: theme.colors.success,
|
|
borderRadius: theme.borderRadius.medium,
|
|
shadowColor: theme.colors.success,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
shadowOpacity: 0.3,
|
|
shadowRadius: 4,
|
|
elevation: 3
|
|
}
|
|
|
|
Critical: {
|
|
backgroundColor: theme.colors.critical,
|
|
borderColor: theme.colors.critical,
|
|
borderRadius: theme.borderRadius.medium,
|
|
shadowColor: theme.colors.critical,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
shadowOpacity: 0.3,
|
|
shadowRadius: 4,
|
|
elevation: 3
|
|
}
|
|
```
|
|
|
|
### **Input Field Design**
|
|
```typescript
|
|
// Input States
|
|
Default: {
|
|
borderColor: theme.colors.border,
|
|
backgroundColor: theme.colors.background,
|
|
borderRadius: theme.borderRadius.medium,
|
|
paddingHorizontal: theme.spacing.md,
|
|
paddingVertical: theme.spacing.md
|
|
}
|
|
|
|
Focused: {
|
|
borderColor: theme.colors.primary,
|
|
backgroundColor: theme.colors.background,
|
|
borderRadius: theme.borderRadius.medium,
|
|
paddingHorizontal: theme.spacing.md,
|
|
paddingVertical: theme.spacing.md
|
|
}
|
|
|
|
Error: {
|
|
borderColor: theme.colors.critical,
|
|
backgroundColor: theme.colors.criticalBackground,
|
|
borderRadius: theme.borderRadius.medium,
|
|
paddingHorizontal: theme.spacing.md,
|
|
paddingVertical: theme.spacing.md
|
|
}
|
|
```
|
|
|
|
### **Card Design Rules**
|
|
```typescript
|
|
// Card Variants
|
|
Default: {
|
|
backgroundColor: theme.colors.cardBackground,
|
|
borderColor: theme.colors.border,
|
|
borderRadius: theme.borderRadius.large,
|
|
padding: theme.spacing.lg,
|
|
shadowColor: theme.colors.shadow,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
shadowOpacity: 0.1,
|
|
shadowRadius: 4,
|
|
elevation: 2
|
|
}
|
|
|
|
Elevated: {
|
|
backgroundColor: theme.colors.cardBackground,
|
|
borderColor: theme.colors.border,
|
|
borderRadius: theme.borderRadius.large,
|
|
padding: theme.spacing.lg,
|
|
shadowColor: theme.colors.shadow,
|
|
shadowOffset: { width: 0, height: 4 },
|
|
shadowOpacity: 0.15,
|
|
shadowRadius: 8,
|
|
elevation: 4
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🚨 Alert & Status Design
|
|
|
|
### **Alert Priority System**
|
|
```typescript
|
|
// Critical Alerts
|
|
Critical: {
|
|
backgroundColor: theme.colors.criticalBackground,
|
|
borderColor: theme.colors.critical,
|
|
borderRadius: theme.borderRadius.medium,
|
|
padding: theme.spacing.md
|
|
}
|
|
|
|
// Warning Alerts
|
|
Warning: {
|
|
backgroundColor: theme.colors.warningBackground,
|
|
borderColor: theme.colors.warning,
|
|
borderRadius: theme.borderRadius.medium,
|
|
padding: theme.spacing.md
|
|
}
|
|
|
|
// Success Alerts
|
|
Success: {
|
|
backgroundColor: theme.colors.successBackground,
|
|
borderColor: theme.colors.success,
|
|
borderRadius: theme.borderRadius.medium,
|
|
padding: theme.spacing.md
|
|
}
|
|
|
|
// Info Alerts
|
|
Info: {
|
|
backgroundColor: theme.colors.infoBackground,
|
|
borderColor: theme.colors.info,
|
|
borderRadius: theme.borderRadius.medium,
|
|
padding: theme.spacing.md
|
|
}
|
|
```
|
|
|
|
### **Status Badges**
|
|
```typescript
|
|
// Status Badges
|
|
StatusBadge: {
|
|
paddingHorizontal: theme.spacing.sm,
|
|
paddingVertical: theme.spacing.xs,
|
|
borderRadius: theme.borderRadius.round,
|
|
fontSize: theme.typography.fontSize.bodySmall,
|
|
fontWeight: theme.typography.fontWeight.medium
|
|
}
|
|
|
|
// Priority Badges
|
|
PriorityBadge: {
|
|
paddingHorizontal: theme.spacing.md,
|
|
paddingVertical: theme.spacing.sm,
|
|
borderRadius: theme.borderRadius.round,
|
|
fontSize: theme.typography.fontSize.bodySmall,
|
|
fontWeight: theme.typography.fontWeight.bold
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📱 Screen-Specific Design Rules
|
|
|
|
### **Login Screen Design**
|
|
```typescript
|
|
// Login Container
|
|
LoginContainer: {
|
|
backgroundColor: theme.colors.background,
|
|
padding: theme.spacing.lg,
|
|
borderRadius: theme.borderRadius.large,
|
|
shadowColor: theme.colors.shadow,
|
|
shadowOffset: { width: 0, height: 4 },
|
|
shadowOpacity: 0.15,
|
|
shadowRadius: 8,
|
|
elevation: 4
|
|
}
|
|
|
|
// Input Container with Icons
|
|
InputContainer: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
backgroundColor: theme.colors.backgroundAlt,
|
|
borderColor: theme.colors.border,
|
|
borderWidth: 1,
|
|
borderRadius: theme.borderRadius.medium,
|
|
paddingHorizontal: theme.spacing.md,
|
|
paddingVertical: 2,
|
|
marginBottom: theme.spacing.md
|
|
}
|
|
|
|
// Input Icon
|
|
InputIcon: {
|
|
marginRight: theme.spacing.sm,
|
|
color: theme.colors.textSecondary
|
|
}
|
|
```
|
|
|
|
### **Dashboard Screen Design**
|
|
```typescript
|
|
// Header Section
|
|
Header: {
|
|
backgroundColor: theme.colors.background,
|
|
paddingHorizontal: theme.spacing.md,
|
|
paddingVertical: theme.spacing.sm,
|
|
borderBottomColor: theme.colors.border,
|
|
borderBottomWidth: 1
|
|
}
|
|
|
|
// Critical Alerts Section
|
|
CriticalAlerts: {
|
|
backgroundColor: theme.colors.criticalBackground,
|
|
borderColor: theme.colors.critical,
|
|
borderRadius: theme.borderRadius.large,
|
|
padding: theme.spacing.lg,
|
|
marginHorizontal: theme.spacing.md,
|
|
marginVertical: theme.spacing.md,
|
|
shadowColor: theme.colors.critical,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
shadowOpacity: 0.15,
|
|
shadowRadius: 8,
|
|
elevation: 4
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 Animation & Transitions
|
|
|
|
### **Animation Rules**
|
|
```typescript
|
|
// Animation Durations
|
|
Durations: {
|
|
Fast: 150, // Quick interactions
|
|
Normal: 300, // Standard transitions
|
|
Slow: 500 // Complex animations
|
|
}
|
|
|
|
// Easing Functions
|
|
Easing: {
|
|
Standard: 'cubic-bezier(0.4, 0.0, 0.2, 1)',
|
|
Deceleration: 'cubic-bezier(0.0, 0.0, 0.2, 1)',
|
|
Acceleration: 'cubic-bezier(0.4, 0.0, 1, 1)'
|
|
}
|
|
|
|
// Transition Types
|
|
Transitions: {
|
|
Fade: { opacity: [0, 1], duration: 300 },
|
|
Slide: { transform: [{ translateY: [20, 0] }], duration: 300 },
|
|
Scale: { transform: [{ scale: [0.95, 1] }], duration: 200 }
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Usage Guidelines
|
|
|
|
### **Theme Import**
|
|
```typescript
|
|
// Import theme in components
|
|
import { theme } from '../theme/theme';
|
|
|
|
// Usage in StyleSheet
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
backgroundColor: theme.colors.background,
|
|
padding: theme.spacing.md,
|
|
borderRadius: theme.borderRadius.medium,
|
|
shadowColor: theme.colors.shadow,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
shadowOpacity: 0.1,
|
|
shadowRadius: 4,
|
|
elevation: 2
|
|
},
|
|
title: {
|
|
fontSize: theme.typography.fontSize.displayMedium,
|
|
fontWeight: theme.typography.fontWeight.bold,
|
|
color: theme.colors.textPrimary,
|
|
fontFamily: theme.typography.fontFamily.bold
|
|
}
|
|
});
|
|
```
|
|
|
|
### **Icon Implementation**
|
|
```typescript
|
|
// Import icon
|
|
import Icon from 'react-native-vector-icons/Feather';
|
|
|
|
// Usage in components
|
|
<Icon
|
|
name="mail"
|
|
size={20}
|
|
color={theme.colors.textSecondary}
|
|
style={styles.icon}
|
|
/>
|
|
```
|
|
|
|
### **Font Usage**
|
|
```typescript
|
|
// Typography with font families
|
|
const styles = StyleSheet.create({
|
|
heading: {
|
|
fontSize: theme.typography.fontSize.displayMedium,
|
|
fontWeight: theme.typography.fontWeight.bold,
|
|
fontFamily: theme.typography.fontFamily.bold,
|
|
color: theme.colors.textPrimary,
|
|
lineHeight: theme.typography.lineHeight.tight
|
|
},
|
|
body: {
|
|
fontSize: theme.typography.fontSize.bodyLarge,
|
|
fontWeight: theme.typography.fontWeight.regular,
|
|
fontFamily: theme.typography.fontFamily.regular,
|
|
color: theme.colors.textSecondary,
|
|
lineHeight: theme.typography.lineHeight.normal
|
|
}
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 Configuration Files
|
|
|
|
### **TypeScript Declaration**
|
|
```typescript
|
|
// app/types/react-native-vector-icons.d.ts
|
|
declare module 'react-native-vector-icons/Feather' {
|
|
import { Component } from 'react';
|
|
import { TextProps } from 'react-native';
|
|
|
|
interface IconProps extends TextProps {
|
|
name: string;
|
|
size?: number;
|
|
color?: string;
|
|
}
|
|
|
|
export default class Icon extends Component<IconProps> {}
|
|
}
|
|
```
|
|
|
|
### **Font Configuration**
|
|
```json
|
|
// react-native.config.js
|
|
module.exports = {
|
|
assets: ['./app/assets/fonts/'],
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 Best Practices
|
|
|
|
### **Design Consistency**
|
|
- ✅ Always use theme colors instead of hardcoded values
|
|
- ✅ Use consistent spacing from the spacing scale
|
|
- ✅ Apply proper typography hierarchy
|
|
- ✅ Use appropriate icon sizes and colors
|
|
- ✅ Maintain consistent border radius values
|
|
|
|
### **Performance**
|
|
- ✅ Use StyleSheet.create for all styles
|
|
- ✅ Minimize inline styles
|
|
- ✅ Use theme constants for repeated values
|
|
- ✅ Optimize icon usage with proper sizing
|
|
|
|
### **Accessibility**
|
|
- ✅ Maintain proper color contrast ratios
|
|
- ✅ Use semantic color names
|
|
- ✅ Provide adequate touch targets (44px minimum)
|
|
- ✅ Support dynamic text sizing
|
|
|
|
### **Maintainability**
|
|
- ✅ Keep theme centralized and well-documented
|
|
- ✅ Use semantic naming for colors and spacing
|
|
- ✅ Document any custom theme extensions
|
|
- ✅ Version control theme changes
|
|
|
|
---
|
|
|
|
## 🚀 Quick Reference
|
|
|
|
### **Common Theme Values**
|
|
```typescript
|
|
// Colors
|
|
theme.colors.primary // #2196F3
|
|
theme.colors.textPrimary // #212121
|
|
theme.colors.background // #FFFFFF
|
|
theme.colors.critical // #F44336
|
|
|
|
// Spacing
|
|
theme.spacing.md // 16px
|
|
theme.spacing.lg // 24px
|
|
theme.spacing.xl // 32px
|
|
|
|
// Typography
|
|
theme.typography.fontSize.bodyLarge // 16px
|
|
theme.typography.fontWeight.bold // 700
|
|
theme.typography.fontFamily.bold // 'Roboto-Bold'
|
|
|
|
// Border Radius
|
|
theme.borderRadius.medium // 8px
|
|
theme.borderRadius.large // 12px
|
|
theme.borderRadius.round // 50px
|
|
```
|
|
|
|
### **Icon Quick Reference**
|
|
```typescript
|
|
// Common Icons
|
|
<Icon name="mail" size={20} color={theme.colors.textSecondary} />
|
|
<Icon name="lock" size={20} color={theme.colors.textSecondary} />
|
|
<Icon name="eye" size={22} color={theme.colors.textSecondary} />
|
|
<Icon name="eye-off" size={22} color={theme.colors.textSecondary} />
|
|
<Icon name="check" size={24} color={theme.colors.success} />
|
|
<Icon name="alert-circle" size={24} color={theme.colors.critical} />
|
|
```
|
|
|
|
This comprehensive theme system ensures consistency, accessibility, and maintainability across the Physician App while providing a modern healthcare-focused design experience. |