This document describes the architecture, design patterns, and organizational structure of the Beyond-UI design system.
Beyond-UI is a production-ready design system built for React Native and Web applications. It provides:
/packages/beyond-ui/
├── src/
│ ├── components/ # All UI components
│ │ ├── Button/
│ │ │ ├── Button.tsx # Main component
│ │ │ ├── Button.types.ts # Type definitions
│ │ │ ├── Button.styles.ts # Style factory
│ │ │ └── index.ts # Public exports
│ │ ├── ListItem/
│ │ │ ├── ListItem.tsx
│ │ │ ├── ListItem.types.ts
│ │ │ ├── ListItem.styles.ts
│ │ │ ├── variants/ # Decomposed variants
│ │ │ │ ├── UserProfile01ListItem.tsx
│ │ │ │ ├── ProductListItem.tsx
│ │ │ │ └── ...
│ │ │ └── index.ts
│ │ └── ...
│ ├── tokens/ # Design tokens
│ │ ├── colors.ts # Color palette
│ │ ├── spacing.ts # Spacing scale
│ │ ├── typography.ts # Type scale
│ │ ├── borders.ts # Border radius, widths
│ │ ├── shadows.ts # Elevation system
│ │ └── index.ts
│ ├── theme/ # Theme system
│ │ ├── ThemeProvider.tsx
│ │ ├── ThemeContext.tsx
│ │ └── index.ts
│ ├── hooks/ # Shared hooks
│ ├── utils/ # Utilities
│ ├── accessibility/ # A11y utilities
│ ├── animation/ # Animation system
│ ├── platform/ # Platform utilities
│ └── index.ts # Package exports
├── docs/ # Documentation
│ ├── ARCHITECTURE.md
│ ├── STYLING_GUIDE.md
│ └── API_CONVENTIONS.md
└── MIGRATION.md
Every component follows this structure:
// Button.tsx
import { getButtonStyles } from './Button.styles'
import { useThemeContext } from '../../theme'
export function Button({ variant, size, color, ...props }: ButtonProps) {
const { theme } = useThemeContext()
const styles = getButtonStyles(variant, size, color, theme)
return (
<Pressable style={styles.container} {...props}>
<Text style={styles.text}>{children}</Text>
</Pressable>
)
}
Large components with many variants are decomposed into separate variant components:
// Instead of:
<ListItem variant="user-profile" name="John" />
// Use:
<UserProfileListItem name="John" />
Benefits:
Examples:
ListItem → 11 variant components (UserProfile01ListItem, ProductListItem, etc.)TableCell → 30+ cell type componentsDO:
// Button.styles.ts
export interface ButtonStyleConfig {
container: ViewStyle
text: TextStyle
}
export function getButtonStyles(
variant: ButtonVariant,
size: ButtonSize,
theme: ThemeMode
): ButtonStyleConfig {
const container: ViewStyle = {
paddingHorizontal: sizeConfig[size].paddingHorizontal,
backgroundColor: colors.primary[500],
}
const text: TextStyle = {
fontSize: sizeConfig[size].fontSize,
color: colors.text[theme].primary,
}
return { container, text }
}
DON’T:
// ❌ Don't use StyleSheet.create
const styles = StyleSheet.create({
button: {
padding: 16, // ❌ Hardcoded value
}
})
// ❌ Don't use inline useMemo
const styles = useMemo(() => ({
container: { ... }
}), [theme])
All design tokens are sourced from Figma Forsured Design System.
tokens/colors.ts)colors.primary[500] // Brand colors
colors.gray[100] // Neutral scale
colors.error[500] // Semantic colors
colors.text.light.primary // Text colors
colors.bg.dark.default // Background colors
colors.border.light.default // Border colors
colors.icon.dark.subtle // Icon colors
tokens/spacing.ts)spacing[4] // 4px
spacing[8] // 8px
spacing[12] // 12px
spacing[16] // 16px
// ... up to spacing[96]
tokens/typography.ts)typography.h1 // Heading styles
typography.body // Body text
typography.bodyMedium // Medium weight body
typography.small // Small text
tokens/shadows.ts)shadows.xs // Extra small shadow
shadows.button // Button shadow
boxShadows.focusPrimary // Focus ring (web only)
tokens/borders.ts)borderRadius.xxs // 2px
borderRadius.s // 6px
borderRadius.m // 12px
borderRadius.max // 9999px (pill)
borderWidth.thin // 1px
borderWidth.medium // 2px
DO:
// ✅ Use tokens
padding: spacing[16]
color: colors.text[theme].primary
borderRadius: borderRadius.m
DON’T:
// ❌ No hardcoded values
padding: 16
color: '#333333'
borderRadius: 12
import { ThemeProvider } from '@scaffald/ui'
function App() {
return (
<ThemeProvider defaultTheme="light">
<YourApp />
</ThemeProvider>
)
}
import { useThemeContext } from '@scaffald/ui'
function MyComponent() {
const { theme, setTheme } = useThemeContext()
return (
<View style=>
<Button onPress={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</Button>
</View>
)
}
The theme preference is automatically persisted to:
theme-storage-key)theme-storage-key)Components with variants use discriminated union types for type safety:
type ButtonProps =
| { variant: 'filled'; color: ColorVariant }
| { variant: 'outlined'; color: ColorVariant }
| { variant: 'text' } // No color prop
// ✅ Valid
<Button variant="filled" color="primary" />
// ❌ Type error - text variant doesn't accept color
<Button variant="text" color="primary" />
variant - Visual style variantsize - Component size (sm, md, lg)color - Color variant (primary, secondary, etc.)disabled - Disabled statestyle - Container style overridecontentStyle - Inner content style overrideerror - Boolean error stateerrorMessage - Error message textonPress - Primary action handler// Visual hidden content for screen readers
<VisuallyHidden>Accessible label</VisuallyHidden>
// Live region announcements
<LiveRegion>{dynamicMessage}</LiveRegion>
// Focus management
const { trapProps } = useFocusTrap({ enabled: isOpen })
// Skip links
<SkipLink href="#main">Skip to main content</SkipLink>
All components work on web via react-native-web. Platform-specific code is minimal:
// Platform detection
const isWeb = Platform.OS === 'web'
// Platform-specific props
{...(Platform.OS === 'web' && {
role: 'button',
'aria-label': label,
} as any)}
// Platform-specific styles
...(Platform.OS === 'web' && {
cursor: 'pointer' as any,
})
import { Grid, Show, Hide } from '@scaffald/ui'
// Responsive grid
<Grid columns= gap="lg">
<Card>Item 1</Card>
<Card>Item 2</Card>
</Grid>
// Conditional rendering
<Show above="md"><DesktopNav /></Show>
<Hide above="md"><MobileNav /></Hide>
/packages/beyond-ui/stories/