npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bettoredge/styles

v0.4.2

Published

Modern theming and styled components for BettorEdge applications

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="[email protected]"
  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="[email protected]"
          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.