bp-design-system
v1.2.8
Published
BP 3.0 Design System - A comprehensive React component library with BP 3.0 design tokens
Maintainers
Readme
BP 3.0 Design System
A comprehensive React component library built with BP 3.0 design tokens, Tailwind CSS, and TypeScript.
Current Version: 1.0.4
Installation
npm install bp-design-systemUsage
Basic Setup
- Install Tailwind CSS v4 (if not already installed):
npm install -D tailwindcss@^4.1.14 @tailwindcss/vite@^4.1.14- Configure your Tailwind config to use BP 3.0 theme:
// tailwind.config.ts
import type { Config } from 'tailwindcss'
import { bpTheme } from 'bp-design-system/tailwind.theme'
export default {
content: [
'./index.html',
'./src/**/*.{js,ts,jsx,tsx}',
'./node_modules/bp-design-system/**/*.{js,ts,jsx,tsx,mjs}'
],
theme: {
extend: bpTheme,
},
plugins: [],
} satisfies Config- Import the CSS tokens in your main CSS file:
/* src/index.css */
@import "tailwindcss";
@config "../tailwind.config.ts";
@import "bp-design-system/tokens.css";Important: The @config directive tells Tailwind v4 to use your tailwind.config.ts file, which extends the BP 3.0 theme. Without it, utility classes won't be generated correctly.
- Import components:
import { Button, Input, Dropdown, Modal, ModalTrigger, ModalContent, ModalHeader, ModalTitle, ModalBody, ModalFooter, Alert } from "bp-design-system";Example
import { Button, Input, Modal, ModalTrigger, ModalContent, ModalHeader, ModalTitle, ModalBody, ModalFooter, ModalClose } from "bp-design-system";
// tokens.css is imported in your main CSS file
function App() {
return (
<>
<Modal>
<ModalTrigger asChild>
<Button variant="primary">Open Modal</Button>
</ModalTrigger>
<ModalContent size="medium" showCloseIcon={true}>
<ModalHeader>
<ModalTitle>Sample Modal</ModalTitle>
</ModalHeader>
<ModalBody>
<Input label="Email" placeholder="Enter your email" />
</ModalBody>
<ModalFooter>
<ModalClose asChild>
<Button variant="primary" size="small">Save</Button>
</ModalClose>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
}Themes
The BP 3.0 Design System supports multi-theme functionality for 90+ careers. Most careers will use the default theme, but you can create custom themes based on career-specific requirements.
📖 For a complete setup guide with examples, see the Custom Theme Setup Story in Storybook.
Quick Setup (3 Steps)
Step 1: Wrap Your App
import { ThemeProvider } from "bp-design-system";
function App() {
return (
<ThemeProvider defaultThemeId="default" storageKey="my-app-theme">
{/* Your app components */}
</ThemeProvider>
);
}Step 2: Create and Register Theme
import { useThemeContext, createTheme } from "bp-design-system";
import { useEffect } from "react";
function ThemeInitializer() {
const { registerTheme } = useThemeContext();
useEffect(() => {
const myTheme = createTheme({
id: 'my-theme',
name: 'My Theme',
code: 'MT',
colors: {
primary: '#1E88E5',
'primary-hover': '#1976D2',
'primary-pressed': '#1565C0',
}
});
registerTheme(myTheme);
}, [registerTheme]);
return null;
}Step 3: Switch Themes
import { useThemeContext } from "bp-design-system";
function ThemeSelector() {
const { currentTheme, setTheme, availableThemes } = useThemeContext();
return (
<select
value={currentTheme?.id}
onChange={(e) => setTheme(e.target.value)}
>
{availableThemes.map(theme => (
<option key={theme.id} value={theme.id}>
{theme.name}
</option>
))}
</select>
);
}Complete Example
import { ThemeProvider, useThemeContext, createTheme } from "bp-design-system";
import { useEffect } from "react";
// App Component
function App() {
return (
<ThemeProvider defaultThemeId="default" storageKey="my-app-theme">
<ThemeInitializer />
<MyComponent />
</ThemeProvider>
);
}
// Register Custom Themes
function ThemeInitializer() {
const { registerTheme } = useThemeContext();
useEffect(() => {
const engineerTheme = createTheme({
id: 'engineer',
name: 'Engineer',
code: 'ENG',
colors: {
primary: '#FF6F00',
'primary-hover': '#E65100',
'primary-pressed': '#BF360C',
secondary: '#00497A',
'secondary-hover': '#ECFAFF',
'secondary-pressed': '#ECFAFF',
linen: '#FFF4E6',
columbia: '#FFE0B2',
},
typography: {
foreground: '#1A1A1A',
secondary: '#5A6B7A',
},
backgrounds: {
default: '#F8F9FA',
surface: '#F0F2F5',
}
});
registerTheme(engineerTheme);
}, [registerTheme]);
return null;
}
// Use Theme in Components
function MyComponent() {
const { currentTheme, setTheme, availableThemes } = useThemeContext();
return (
<div>
<p>Current: {currentTheme?.name}</p>
<select
value={currentTheme?.id}
onChange={(e) => setTheme(e.target.value)}
>
{availableThemes.map(theme => (
<option key={theme.id} value={theme.id}>
{theme.name}
</option>
))}
</select>
</div>
);
}Simple Theme (Primary Colors Only)
const simpleTheme = createTheme({
id: 'simple',
name: 'Simple Theme',
code: 'ST',
colors: {
primary: '#1E88E5',
'primary-hover': '#1976D2',
'primary-pressed': '#1565C0',
}
});Complex Theme (Multiple Categories)
const complexTheme = createTheme({
id: 'complex',
name: 'Complex Theme',
code: 'CT',
colors: {
primary: '#FF6F00',
'primary-hover': '#E65100',
'primary-pressed': '#BF360C',
secondary: '#00497A',
'secondary-hover': '#ECFAFF',
'secondary-pressed': '#ECFAFF',
linen: '#FFF4E6',
columbia: '#FFE0B2',
},
typography: {
foreground: '#1A1A1A',
secondary: '#5A6B7A',
},
backgrounds: {
default: '#F8F9FA',
surface: '#F0F2F5',
}
});Registering Themes at Runtime
Themes can be registered dynamically at runtime:
import { ThemeProvider, useThemeContext, createTheme } from "bp-design-system";
function App() {
return (
<ThemeProvider>
<ThemeManager />
{/* Your app components */}
</ThemeProvider>
);
}
function ThemeManager() {
const { registerTheme, setTheme } = useThemeContext();
useEffect(() => {
// Register multiple themes
const customThemes = [
createTheme({
id: 'career1',
name: 'Career 1',
code: 'C1',
colors: { primary: '#FF0000' }
}),
createTheme({
id: 'career2',
name: 'Career 2',
code: 'C2',
colors: { primary: '#00FF00' }
}),
];
customThemes.forEach(theme => registerTheme(theme));
// Set initial theme based on user/career
const userCareer = getUserCareer(); // Your logic
if (userCareer) {
setTheme(userCareer);
}
}, [registerTheme, setTheme]);
return null;
}Theme Structure
Each theme extends the base theme and can override:
- Colors:
primary,primary-hover,primary-pressed,secondary,secondary-hover,secondary-pressed,linen,columbia - Typography:
foreground,secondary,disabled,on-primary,woodsmoke,nevada,cadet - Backgrounds:
default,surface,muted,white,porcelain,athens - Borders:
default,silver,bright-gray
Theme Persistence
The selected theme is automatically persisted to localStorage (default key: 'bp-theme'). You can customize the storage key:
<ThemeProvider storageKey="my-app-theme">
{/* Your app */}
</ThemeProvider>Available Theme Functions
import {
ThemeProvider,
useThemeContext,
createTheme,
getTheme,
getAllThemes,
hasTheme,
addTheme,
removeTheme,
baseTheme
} from "bp-design-system";
// Get a specific theme
const theme = getTheme('doctor');
// Get all available themes
const allThemes = getAllThemes();
// Check if a theme exists
if (hasTheme('doctor')) {
// Theme exists
}
// Add a theme programmatically (outside React)
addTheme(customTheme);
// Remove a theme (cannot remove 'default')
removeTheme('doctor');Components
Atoms
- Button - Primary, secondary, tertiary, and hyperlink variants
- Icon - SVG icon component backed by a generated registry (~349 icons)
- Input - Text input with floating labels and validation
- Checkbox - Checkbox with label support
- RadioButton / RadioGroup - Radio button groups
- Switch - Toggle switch component
- ToggleButton / ToggleGroup - Toggle button groups
- Pill - Pill/tag component with variants
- Tooltip - Tooltip with all placement options
- Alert - Alert messages with variants (success, error, warning, info)
- Progress - Progress bar component
- Dropdown - Dropdown/select component with multiple variants
- Modal - Modal dialog component
Utilities
cn()- Class name utility (clsx + tailwind-merge)formatCurrency()- Format numbers as currencyformatDate()- Format datesformatNumber()- Format numberstoTitleCase()- Convert text to title casetruncateText()- Truncate text with ellipsis
Types
All component props are exported as TypeScript types:
import type { ButtonProps, InputProps, ModalContentProps, ModalHeaderProps } from "bp-design-system";Icons
The Icon component renders SVG icons from the BP 3.0 icon set by name:
import { Icon } from "bp-design-system/lib/components/ui/Icon";
export function Example() {
return (
<>
<Icon name="calendar" size={24} />
<Icon name="caret-down-regular" size={16} className="text-secondary" />
<Icon name="warning-circle" size={20} alt="Warning" />
</>
);
}- Names are kebab‑case versions of the SVG filenames under
src/assets/Icons. - Use
getAvailableIcons()(and theUI/Icons → GalleryStorybook story) to discover all available icon names. - For more details, see
src/lib/components/ui/Icon/README.mdin this repo.
Developer-Friendly Features
All components support:
className- Custom Tailwind CSS classesslotClassNames- Granular styling of internal partsdata-testid- Test identifiersrefforwarding - React ref support- Full TypeScript support with JSDoc comments
Styling
This package uses Tailwind CSS v4 and custom design tokens.
Setup Steps:
Install Tailwind CSS v4 with the Vite plugin:
npm install -D tailwindcss@^4.1.14 @tailwindcss/vite@^4.1.14Configure Vite to use the Tailwind plugin:
// vite.config.ts import tailwindcss from '@tailwindcss/vite' export default { plugins: [react(), tailwindcss()], }Import BP 3.0 theme in your
tailwind.config.ts:import { bpTheme } from 'bp-design-system/tailwind.theme' export default { theme: { extend: bpTheme } }Import tokens in your CSS file:
@import "tailwindcss"; @config "../tailwind.config.ts"; @import "bp-design-system/tokens.css";Important: The
@configdirective tells Tailwind v4 to use yourtailwind.config.tsfile. Without it, utility classes won't be generated correctly.
The design tokens (CSS variables) are defined in tokens.css, and the Tailwind utility class mappings are provided by tailwind.theme.ts.
Fonts
This design system uses Proxima Nova as the primary font family. For detailed font setup instructions (Adobe Fonts or self-hosted), see FONT_SETUP.md.
The font is automatically loaded when you import tokens.css in your project.
Peer Dependencies
react^18.0.0 || ^19.0.0react-dom^18.0.0 || ^19.0.0
Development
# Install dependencies
npm install
# Start Storybook (for component development)
npm run storybook
# Build the package
npm run build
# Run tests
npm test
# Lint code
npm run lint
# Test package locally (creates .tgz file)
npm packVersion History
See CHANGELOG.md for detailed version history and changes.
License
MIT
