/**
- Design System Integration Guide
- Step-by-step guide for integrating the new design system into SubTrackr */
The SubTrackr Design System has been implemented with comprehensive tokens, components, and utilities. This guide walks you through integrating it into your existing codebase.
src/design-system/
├── index.ts # Main export
├── README.md # Quick reference
├── DESIGN_SYSTEM.md # Full documentation
├── tokens/
│ ├── index.ts
│ ├── colors.ts # Dark, Light, High Contrast themes
│ ├── spacing.ts # 8-point grid system
│ ├── typography.ts # Material Design 3 type scale
│ ├── borderRadius.ts # Semantic radius scale
│ ├── shadows.ts # Elevation system
│ └── animations.ts # Timing and easing
├── components/
│ ├── index.ts
│ ├── Button.tsx # 7 variants, 3 sizes
│ ├── Input.tsx # Labels, validation, icons
│ ├── Card.tsx # 4 variants, configurable padding
│ ├── Modal.tsx # Sizes, animations, backdrop
│ └── Toast.tsx # 4 variants, auto-dismiss
├── types/
│ └── design-tokens.ts # Complete type definitions
├── utils/
│ ├── platform.ts # iOS/Android/Web detection
│ ├── rtl.ts # RTL language support
│ ├── fontScaling.ts # WCAG font size compliance
│ └── index.ts
├── hooks/
│ └── (theme hooks to be created)
├── __tests__/
│ ├── Button.test.tsx # Unit tests
│ └── visualRegression.e2e.ts # E2E tests
└── stories/
└── Button.stories.tsx # Storybook documentation
The design system extracts and improves existing components:
Existing Components → Design System Components
src/components/common/Button.tsx→src/design-system/components/Button.tsxsrc/components/common/Card.tsx→src/design-system/components/Card.tsx- Manual Input implementations →
src/design-system/components/Input.tsx - Manual Modal implementations →
src/design-system/components/Modal.tsx - Manual Toast implementations →
src/design-system/components/Toast.tsx
Update component imports throughout the codebase:
Before:
import { Button } from '@/components/common';
import { Card } from '@/components/common';After:
import { Button, Card, Input, Modal, Toast } from '@/design-system';Replace hardcoded colors with design tokens:
Before:
const buttonStyle = {
backgroundColor: '#6366f1',
color: '#ffffff',
};After:
import { colors } from '@/design-system/tokens';
const buttonStyle = {
backgroundColor: colors.primary,
color: colors.onPrimary,
};Replace hardcoded spacing values with the spacing scale:
Before:
const styles = StyleSheet.create({
container: {
padding: 16,
marginBottom: 24,
gap: 8,
},
});After:
import { spacing } from '@/design-system/tokens';
const styles = StyleSheet.create({
container: {
padding: spacing.md,
marginBottom: spacing.lg,
gap: spacing.sm,
},
});Apply consistent typography styles:
Before:
<Text style={{ fontSize: 16, fontWeight: '600', lineHeight: 24 }}>
Heading
</Text>After:
import { typography } from '@/design-system/tokens';
<Text style={typography.h3}>Heading</Text>Ensure all interactive elements have proper accessibility labels:
Before:
<TouchableOpacity onPress={handlePress}>
<Text>Save</Text>
</TouchableOpacity>After:
<Button
label="Save"
onPress={handlePress}
accessibilityLabel="Save subscription changes"
accessibilityHint="Your changes will be applied immediately"
/>For components that use the base components, ensure they respect the design system:
import {
Button,
Card,
Input,
Modal,
Toast,
spacing,
typography,
colors,
} from '@/design-system';
export const SubscriptionCard = ({ subscription }: Props) => {
return (
<Card variant="elevated" padding="md">
<Text style={typography.h3}>{subscription.name}</Text>
<Text style={[typography.body, { color: colors.textSecondary }]}>
${subscription.price}/month
</Text>
<Button
label="Manage"
variant="primary"
onPress={() => {}}
accessibilityLabel={`Manage ${subscription.name} subscription`}
/>
</Card>
);
};Update test imports and add accessibility checks:
Before:
import { render } from '@testing-library/react-native';
import { Button } from '@/components/common';After:
import { render } from '@testing-library/react-native';
import { Button } from '@/design-system';
describe('Button', () => {
it('should have accessibility label', () => {
const { getByLabelText } = render(
<Button
label="Save"
onPress={() => {}}
accessibilityLabel="Save button"
/>
);
expect(getByLabelText('Save button')).toBeTruthy();
});
});Update all screens to use design system components:
src/screens/
├── SubscriptionList.tsx # Update imports
├── SubscriptionDetail.tsx # Update imports
├── Settings.tsx # Update imports
└── ...
Example:
import { Button, Card, Toast } from '@/design-system';
import { spacing, typography } from '@/design-system/tokens';
export const SubscriptionList = () => {
const [visible, setVisible] = useState(false);
return (
<View style={{ gap: spacing.md, padding: spacing.lg }}>
<Text style={typography.h1}>My Subscriptions</Text>
{subscriptions.map((sub) => (
<Card key={sub.id} variant="elevated" padding="md">
<Text style={typography.h3}>{sub.name}</Text>
<Button
label="Details"
onPress={() => {}}
accessibilityLabel={`View details for ${sub.name}`}
/>
</Card>
))}
<Toast
visible={visible}
message="Subscription updated"
variant="success"
onClose={() => setVisible(false)}
/>
</View>
);
};Update src/components/common/ to use design system or remove if replaced:
- Button.tsx: Remove, use
@/design-systeminstead - Card.tsx: Remove, use
@/design-systeminstead - Other components: Update to use design tokens
Update domain-specific components (subscription, home, etc.):
// src/components/subscription/SubscriptionCard.tsx
import { Card, Button, typography } from '@/design-system';
export const SubscriptionCard = ({ item }: Props) => (
<Card variant="elevated" padding="md">
<Text style={typography.h3}>{item.name}</Text>
<Button label="Manage" onPress={() => {}} />
</Card>
);Before deploying the design system migration:
npm test src/design-systemnpm test src/componentsnpm run e2e:test-ios
npm run e2e:test-androidnpm run e2e:visual:update-ios- All buttons have accessibility labels
- All inputs have labels or accessibility hints
- All modals have accessibility roles
- All text meets WCAG font size minimums
- Test with VoiceOver (iOS) and TalkBack (Android)
- Verify colors meet contrast requirements
- Test with RTL language
- Dark theme applies correctly
- Light theme applies correctly
- High Contrast theme applies correctly
- Theme persistence works
- Theme switching is smooth
- iOS rendering is correct
- Android rendering is correct
- Web rendering is correct (if applicable)
- Shadows render correctly on each platform
- Font sizes are readable on all platforms
The design system is optimized for performance:
- No unnecessary re-renders: Components use
React.memowhere appropriate - Efficient styling: StyleSheet API for optimized styles
- Lazy loading: Import only what you need
- Minimal dependencies: Core components only depend on React Native
Ensure imports are correct:
// ✓ Correct
import { Button } from '@/design-system';
// ✗ Wrong
import { Button } from '@/design-system/components';Make sure to use color tokens:
// ✓ Correct
import { colors } from '@/design-system/tokens';
const backgroundColor = colors.primary;
// ✗ Wrong
const backgroundColor = '#6366f1';Verify accessibility props are passed:
// ✓ Correct
<Button
label="Save"
accessibilityLabel="Save changes"
onPress={() => {}}
/>
// ✗ Wrong
<Button label="Save" onPress={() => {}} />- Start with screens: Begin migration with high-impact screens
- Update components: Refactor common components
- Add tests: Ensure tests cover all accessibility requirements
- Document: Add Storybook stories for all components
- Deploy: Roll out with feature flag if needed