Package Exports
- @bettoredge/styles
- @bettoredge/styles/lib/commonjs/index.js
- @bettoredge/styles/lib/module/index.js
- @bettoredge/styles/src/index.tsx
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@bettoredge/styles) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@bettoredge/styles
Modern theming and styled components for BettorEdge applications with full dark/light mode support.
Installation
npm install @bettoredge/styles
# or
yarn add @bettoredge/stylesQuick Start
1. Wrap your app with ThemeProvider
import { ThemeProvider } from '@bettoredge/styles';
export default function App() {
return (
<ThemeProvider>
<YourApp />
</ThemeProvider>
);
}2. Use themed components
import { View, Text, Button, useTheme } from '@bettoredge/styles';
function MyScreen() {
const { isDark, setMode } = useTheme();
return (
<View variant="card" padding="lg" gap="md">
<Text variant="h1">Hello World</Text>
<Text variant="body" color="secondary">
Welcome to BettorEdge design system
</Text>
<Button
variant="primary"
onPress={() => setMode(isDark ? 'light' : 'dark')}
>
Toggle Theme
</Button>
</View>
);
}Features
- Semantic Color System: Colors adapt automatically to light/dark mode
- Modern Design: Softer colors, better contrast, accessible
- Type Safe: Full TypeScript support
- Cross-Platform: Works with Expo, React Native, and react-native-web
- Zero Config: Works out of the box with sensible defaults
- Flexible: Easy to customize and extend
Components
Text
Typography component with semantic variants and colors.
// Variants
<Text variant="h1">Heading 1</Text>
<Text variant="h2">Heading 2</Text>
<Text variant="h3">Heading 3</Text>
<Text variant="bodyLarge">Large body text</Text>
<Text variant="body">Body text</Text>
<Text variant="caption">Caption text</Text>
<Text variant="label">Label Text</Text>
// Colors
<Text color="primary">Primary text</Text>
<Text color="secondary">Secondary text</Text>
<Text color="tertiary">Tertiary text</Text>
<Text color="link">Link text</Text>
<Text color="success">Success text</Text>
<Text color="error">Error text</Text>
<Text color="warning">Warning text</Text>
// Weights
<Text bold>Bold text</Text>
<Text semibold>Semibold text</Text>
<Text medium>Medium text</Text>
// Alignment
<Text center>Centered text</Text>View
Container component with surface variants and automatic theming.
// Variants
<View variant="base">Base surface</View>
<View variant="elevated">Elevated surface</View>
<View variant="card">Card (with shadow)</View>
<View variant="header">Header surface</View>
<View variant="footer">Footer surface</View>
// Spacing
<View padding="md">Padded view</View>
<View paddingHorizontal="lg" paddingVertical="sm">Custom padding</View>
<View gap="md">View with gap between children</View>
// Border
<View rounded="lg">Rounded corners</View>
<View bordered>With border</View>
// Shadow
<View shadow="sm">Small shadow</View>
<View shadow="md">Medium shadow</View>
<View shadow="lg">Large shadow</View>Button
Interactive button with multiple variants and states.
// Variants
<Button variant="primary" onPress={handlePress}>Primary</Button>
<Button variant="secondary" onPress={handlePress}>Secondary</Button>
<Button variant="outline" onPress={handlePress}>Outline</Button>
<Button variant="ghost" onPress={handlePress}>Ghost</Button>
<Button variant="success" onPress={handlePress}>Success</Button>
<Button variant="error" onPress={handlePress}>Error</Button>
<Button variant="warning" onPress={handlePress}>Warning</Button>
// Sizes
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
// States
<Button disabled>Disabled</Button>
<Button loading>Loading</Button>
// Full width
<Button fullWidth>Full Width Button</Button>TextInput
Themed text input with labels, errors, and helper text.
// Basic
<TextInput
placeholder="Enter text"
value={value}
onChangeText={setValue}
/>
// With label
<TextInput
label="Email"
placeholder="you@example.com"
value={email}
onChangeText={setEmail}
/>
// With error
<TextInput
label="Password"
error="Password is required"
value={password}
onChangeText={setPassword}
/>
// With helper text
<TextInput
label="Username"
helperText="Choose a unique username"
value={username}
onChangeText={setUsername}
/>
// Sizes
<TextInput size="sm" />
<TextInput size="md" />
<TextInput size="lg" />
// Disabled
<TextInput disabled value="Cannot edit" />
// Full width
<TextInput fullWidth />Theme Access
useTheme Hook
import { useTheme } from '@bettoredge/styles';
function MyComponent() {
const { theme, mode, isDark, setMode } = useTheme();
// Access colors
const primaryColor = theme.colors.primary.default;
const backgroundColor = theme.colors.surface.base;
// Access spacing
const padding = theme.spacing.md; // 16
// Access typography
const fontSize = theme.typography.fontSize.lg; // 16
const fontWeight = theme.typography.fontWeight.semibold; // '600'
// Toggle theme
const toggleTheme = () => setMode(isDark ? 'light' : 'dark');
return (
<View style={{ backgroundColor, padding }}>
<Text style={{ color: primaryColor, fontSize, fontWeight }}>
Current mode: {mode}
</Text>
</View>
);
}Color System
Brand Colors (Fixed)
Your brand identity colors that remain consistent across themes:
brand.cobalt-#003566brand.midnight-#002A51brand.electric-#005FB7brand.cyan-#08A4BDbrand.slate-#6E8894brand.mint-#B2F2D6brand.yellow-#FFD60A
Semantic Colors (Theme-Adaptive)
Colors that automatically adapt to light/dark mode:
Primary
primary.default- Main action colorprimary.hover- Hover stateprimary.active- Active/pressed stateprimary.disabled- Disabled state
Surface
surface.base- Main backgroundsurface.elevated- Cards, modalssurface.header- Top navigationsurface.footer- Bottom navigationsurface.input- Input backgrounds
Text
text.primary- Main headingstext.secondary- Body texttext.tertiary- Supporting texttext.link- Linkstext.disabled- Disabled text
Status
status.success- Success statestatus.error- Error statestatus.warning- Warning statestatus.info- Info state
Spacing Scale
Consistent spacing throughout your app:
xs: 4pxsm: 8pxmd: 16pxlg: 24pxxl: 32pxxxl: 48px
Typography Scale
Font sizes:
xs: 10pxsm: 12pxmd: 14pxlg: 16pxxl: 20pxxxl: 24pxxxxl: 32px
Font weights:
regular: 400medium: 500semibold: 600bold: 700
Advanced Usage
Custom Theme Mode
// Force a specific theme
<ThemeProvider initialMode="dark">
<App />
</ThemeProvider>
// Or use 'auto' for system theme (default)
<ThemeProvider initialMode="auto">
<App />
</ThemeProvider>Accessing Raw Colors
import { colors } from '@bettoredge/styles';
// Access brand colors
const electricBlue = colors.brand.electric;
// Access neutral palette
const gray500 = colors.neutral.gray500;
// Access status colors
const successGreen = colors.status.success;Backward Compatibility
The package includes a useColors() hook for backward compatibility with your old color system:
import { useColors } from '@bettoredge/styles';
function OldComponent() {
const colors = useColors();
// Old API still works
const backgroundColor = colors.views.background;
const textColor = colors.text.h1;
}Examples
Login Form
import { View, Text, TextInput, Button } from '@bettoredge/styles';
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
<View variant="card" padding="lg" gap="md">
<Text variant="h2">Sign In</Text>
<Text variant="body" color="tertiary">
Enter your credentials to continue
</Text>
<View gap="md" style={{ marginTop: 16 }}>
<TextInput
label="Email"
placeholder="you@example.com"
value={email}
onChangeText={setEmail}
fullWidth
/>
<TextInput
label="Password"
placeholder="••••••••"
value={password}
onChangeText={setPassword}
secureTextEntry
fullWidth
/>
</View>
<Button variant="primary" fullWidth onPress={handleLogin}>
Sign In
</Button>
<Button variant="ghost" fullWidth onPress={handleForgotPassword}>
Forgot Password?
</Button>
</View>
);
}Settings Screen with Theme Toggle
import { View, Text, Button, useTheme } from '@bettoredge/styles';
function SettingsScreen() {
const { theme, isDark, setMode } = useTheme();
return (
<View variant="base" padding="lg" gap="lg">
<Text variant="h1">Settings</Text>
<View variant="card" padding="lg" gap="sm">
<Text variant="h3">Appearance</Text>
<Text variant="body" color="tertiary">
Choose your preferred theme
</Text>
<View gap="sm" style={{ marginTop: 8 }}>
<Button
variant={!isDark ? 'primary' : 'outline'}
onPress={() => setMode('light')}
fullWidth
>
☀️ Light Mode
</Button>
<Button
variant={isDark ? 'primary' : 'outline'}
onPress={() => setMode('dark')}
fullWidth
>
🌙 Dark Mode
</Button>
</View>
</View>
</View>
);
}License
Private - BettorEdge
Support
For issues, questions, or contributions, contact the BettorEdge development team.