JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 12
  • Score
    100M100P100Q60788F
  • License UNLICENSED

Modern theming and styled components for BettorEdge applications

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/styles

Quick 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 - #003566
  • brand.midnight - #002A51
  • brand.electric - #005FB7
  • brand.cyan - #08A4BD
  • brand.slate - #6E8894
  • brand.mint - #B2F2D6
  • brand.yellow - #FFD60A

Semantic Colors (Theme-Adaptive)

Colors that automatically adapt to light/dark mode:

Primary

  • primary.default - Main action color
  • primary.hover - Hover state
  • primary.active - Active/pressed state
  • primary.disabled - Disabled state

Surface

  • surface.base - Main background
  • surface.elevated - Cards, modals
  • surface.header - Top navigation
  • surface.footer - Bottom navigation
  • surface.input - Input backgrounds

Text

  • text.primary - Main headings
  • text.secondary - Body text
  • text.tertiary - Supporting text
  • text.link - Links
  • text.disabled - Disabled text

Status

  • status.success - Success state
  • status.error - Error state
  • status.warning - Warning state
  • status.info - Info state

Spacing Scale

Consistent spacing throughout your app:

  • xs: 4px
  • sm: 8px
  • md: 16px
  • lg: 24px
  • xl: 32px
  • xxl: 48px

Typography Scale

Font sizes:

  • xs: 10px
  • sm: 12px
  • md: 14px
  • lg: 16px
  • xl: 20px
  • xxl: 24px
  • xxxl: 32px

Font weights:

  • regular: 400
  • medium: 500
  • semibold: 600
  • bold: 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.