bitcoin-ui
v1.1.4
Published
Accessible React component library for Bitcoin applications
Downloads
3
Maintainers
Readme
Bitcoin UI
Modern, accessible React component library for Bitcoin applications. Built with TypeScript and designed following the Bitcoin Design Guide and Bitcoin Universal Design Accessibility Standards.
🌐 Live Website & Documentation → 📚 Live Storybook →
✨ Features
- 🎨 Beautiful by Default - Clean, modern styling
- ♿ Fully Accessible - WCAG 2.1 AA compliant with screen reader support
- 🎯 Minimal Dependencies - Only requires React, Radix UI, react-copy-to-clipboard-ts, and qrcode.react
- 🌙 Dark Mode Ready - Automatic dark mode support via CSS custom properties
- 🌍 Locale-Aware - Support for US, EU number formatting
- ₿ Bitcoin-Specific - Designed for Bitcoin applications
- 📱 Mobile-First - Responsive and touch-friendly
- 🔒 Security-Focused - Secure handling of sensitive data
- 🧪 Thoroughly Tested - 64+ tests including accessibility & story tests
- 🚀 Lightweight - Minimal bundle size impact
📦 Installation
npm install bitcoin-ui
# or
yarn add bitcoin-ui
# or
pnpm add bitcoin-ui🎨 Interactive Examples
Explore all components interactively with different props, styling examples, and live code examples.
For local development with Storybook:
# Clone the repository
git clone <repository-url>
cd bitcoin-ui
pnpm install
# Start Storybook
pnpm storybookThen open http://localhost:6006 for local development.
🚀 Quick Start
import { Secret, PasswordInput, QRCode, ExpandableText, CurrencyInput } from 'bitcoin-ui'
function App() {
const [password, setPassword] = useState('')
const [amount, setAmount] = useState('')
return (
<div>
{/* Secure display of sensitive information */}
<Secret
secret="abandon ability able about above absent absorb abstract absurd abuse access accident"
label="Seed Phrase"
/>
{/* Password input with reveal/hide toggle */}
<PasswordInput
label="Wallet Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
{/* Currency input with locale-aware formatting */}
<CurrencyInput
currency="BTC"
value={amount}
onChange={(e) => setAmount(e.target.value)}
label="Bitcoin Amount"
/>
{/* QR code with copy functionality */}
<QRCode
value="bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
label="Bitcoin Address QR"
size={200}
/>
{/* Expandable text for long addresses */}
<ExpandableText
text="bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
type="address"
label="Bitcoin Address"
/>
</div>
)
}🧩 Components
🔐 Secret
Securely display and copy sensitive information like seed phrases and private keys.
<Secret
secret="correct horse battery staple"
label="Seed Phrase"
maskChar="•"
showCopyButton={true}
/>Props:
secret: string- The sensitive text to displaylabel?: string- Accessible label for the secretmaskChar?: string- Character to use for masking (default: "•")showCopyButton?: boolean- Whether to show copy button (default: true)
🔑 PasswordInput
Accessible password input with reveal/hide toggle functionality.
<PasswordInput
label="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Enter your password"
autoComplete="new-password"
/>Props:
label?: string- Accessible label for the input- All standard HTML input props (value, onChange, placeholder, etc.)
📱 QRCode
Generate and display QR codes with copy functionality.
<QRCode
value="bitcoin:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
label="Bitcoin Address QR"
size={200}
errorCorrectionLevel="M"
description="Scan to send Bitcoin"
/>Props:
value: string- The data to encode in the QR codelabel: string- Accessible label for the QR codesize?: number- Size of the QR code in pixels (default: 200)errorCorrectionLevel?: "L" | "M" | "Q" | "H"- Error correction level (default: "M")description?: string- Additional description for accessibility
📄 ExpandableText
Display long text with expand/collapse and copy functionality.
<ExpandableText
text="bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
type="address"
label="Bitcoin Address"
startChars={6}
endChars={8}
showCopyButton={true}
/>Props:
text: string- The text to displaytype?: "address" | "invoice" | "text"- Type of text for accessibilitylabel?: string- Accessible labelstartChars?: number- Characters to show at start when truncated (default: 6)endChars?: number- Characters to show at end when truncated (default: 8)showCopyButton?: boolean- Whether to show copy button (default: true)
💰 CurrencyInput
Locale-aware currency input with real-time formatting and validation.
<CurrencyInput
currency="BTC"
locale="US"
value={amount}
onChange={(e) => setAmount(e.target.value)}
label="Bitcoin Amount"
placeholder="0.021"
/>Props:
currency: "BTC" | "USD" | "EUR"- Currency typelocale?: "US" | "EU"- Locale for number formatting (default: "US")label?: string- Accessible label for the input- All standard HTML input props (value, onChange, placeholder, etc.)
Locale Formatting:
- US:
1,234.56(comma thousands, dot decimal) - EU:
1.234,56(dot thousands, comma decimal)
🎨 Styling & Customization
All components are flexible by default and come with beautiful styling using modern design tokens.
Default Styling
Components include beautiful default styling that you can optionally use:
// Import default styles (optional)
import 'bitcoin-ui/styles.css';Custom Theming
Override CSS custom properties to customize the design:
:root {
/* Colors */
--btc-gray-50: #your-color;
--btc-gray-900: #your-color;
--btc-orange-500: #your-accent-color;
/* Typography */
--btc-font-family: 'Your Font', sans-serif;
--btc-font-mono: 'Your Mono Font', monospace;
/* Spacing */
--btc-space-4: 1.5rem;
/* Border radius */
--btc-radius-lg: 0.75rem;
}Component-Specific CSS Classes
Each component exposes specific CSS classes for styling:
/* Secret component */
.secret { /* wrapper */ }
.secret__text { /* text display */ }
.secret__toggle { /* reveal/hide button */ }
.secret__copy { /* copy button */ }
/* Password input */
.password-input { /* wrapper */ }
.password-input__input { /* input field */ }
.password-input__toggle { /* visibility toggle */ }
/* QR code */
.qr-code { /* wrapper */ }
.qr-code__svg { /* QR code SVG */ }
.qr-code__copy { /* copy button */ }
/* Expandable text */
.expandable-text { /* wrapper */ }
.expandable-text__content { /* text content */ }
.expandable-text__toggle { /* expand/collapse button */ }
/* Currency input */
.currency-input { /* wrapper */ }
.currency-input__symbol { /* currency symbol */ }
.currency-input__input { /* input field */ }Dark Mode
Components automatically support dark mode through CSS custom properties:
@media (prefers-color-scheme: dark) {
:root {
--btc-gray-50: #111827;
--btc-gray-900: #f9fafb;
/* Colors are automatically inverted */
}
}Inline Styles
Pass styles directly to components:
<Secret
secret="my secret"
style={{ padding: '1rem', backgroundColor: 'white' }}
/>CSS-in-JS
Use your preferred CSS-in-JS solution:
const StyledSecret = styled(Secret)`
padding: 1rem;
background: white;
border-radius: 8px;
`🔧 TypeScript Support
Full TypeScript support with exported types:
import type {
SecretProps,
PasswordInputProps,
QRCodeProps,
ExpandableTextProps,
CurrencyInputProps,
Currency,
Locale
} from 'bitcoin-ui'🚀 Advanced Usage
Custom Toast Notifications
import { showToast } from 'bitcoin-ui';
// Success notification
showToast('Bitcoin address copied!');
// Error notification
showToast('Failed to copy address', { type: 'error' });
// Custom duration
showToast('Copied!', { duration: 5000 });Utility Functions
import {
truncateText,
isValidAmount,
formatCurrencyValue
} from 'bitcoin-ui';
// Truncate long text
const short = truncateText('very long text here', 10, 5);
// Validate currency amounts
const isValid = isValidAmount('123.45', 'USD');
// Format currency values
const formatted = formatCurrencyValue('1234.56', 'US');📱 Mobile Considerations
All components are designed mobile-first with:
- Touch-friendly interactive areas (minimum 44px)
- Responsive typography and spacing
- Optimized for small screens
- Proper viewport handling for iOS Safari
🔒 Security Best Practices
When handling sensitive Bitcoin data:
- Clear sensitive data - Clear form values when appropriate
- Validate inputs - Use provided validation utilities
- Secure clipboard - Components handle clipboard securely
- Screen recording protection - Consider
user-select: nonefor sensitive data
🧪 Development
Setup
git clone <repository-url>
cd bitcoin-ui
pnpm installScripts
# Start Storybook (component playground)
pnpm storybook
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run accessibility tests
pnpm test:a11y
# Run test coverage
pnpm test:coverage
# Run story tests (verify all Storybook stories render)
pnpm test:stories
# Run story tests in watch mode
pnpm test:stories:watch
# Run linting
pnpm lint
# Type checking
pnpm typecheck
# Build for production
pnpm build
# Development with hot reload
pnpm devViewing Components
The best way to explore and test components is through our live website and storybook:
🌐 Visit bitcoinui.org → 📚 Visit Storybook →
For local development with Storybook:
# Start the interactive component playground
pnpm storybookThen open http://localhost:6006 to:
- Test components with different props and styling
- View all component variations and examples
- Copy implementation code for your projects
- Test accessibility features and keyboard navigation
- Experiment with styling approaches for design-flexible components
♿ Accessibility
All components follow Bitcoin Universal Design Accessibility Standards and include:
- Screen Reader Support - ARIA labels, descriptions, and live regions
- Keyboard Navigation - Full keyboard accessibility with proper focus management
- High Contrast - Supports high contrast mode and custom focus indicators
- Semantic HTML - Proper HTML structure and roles
- Clear Feedback - Accessible announcements for all user actions
- Responsive Design - Works across all device sizes and orientations
Testing Accessibility
# Run accessibility tests
pnpm test:a11y
# Test with screen readers
# - NVDA (Windows)
# - JAWS (Windows)
# - VoiceOver (macOS)
# - TalkBack (Android)🔧 Testing
The library includes comprehensive tests:
- 55+ Unit Tests - Component functionality and edge cases
- 32 Story Tests - Verify all Storybook stories render correctly
- Accessibility Tests - Automated a11y testing with jest-axe
- Type Tests - TypeScript type checking
- Integration Tests - Component interaction testing
# Run all tests
pnpm test
# Run specific test suites
pnpm test src/components/secret
pnpm test src/components/password-input
pnpm test src/components/qr-code
pnpm test src/components/expandable-text
pnpm test src/components/currency-input
# Run with coverage
pnpm test:coverage🌟 Design Principles
This library follows the Bitcoin Design Guide principles:
- Clarity - Clear, unambiguous interfaces
- Consistency - Consistent patterns across components
- Accessibility - Inclusive design for all users
- Security - Secure handling of sensitive Bitcoin data
- Simplicity - Focus on essential functionality
- Trust - Building user confidence through good UX
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Component Guidelines
When contributing new components:
- Follow Bitcoin Design Guide principles
- Implement full accessibility with ARIA support
- Write comprehensive tests (unit + a11y)
- Use TypeScript with proper type definitions
- Keep components flexible - minimize styling
- Document thoroughly with examples
📄 License
MIT © Bitcoin UI
🔗 Links
- 🌐 Live Website & Documentation - Interactive examples and complete docs
- 🎮 Component Playground - Try components live
- 📚 Getting Started Guide - Quick start tutorial
- 🧩 All Components - Complete component library
- Bitcoin Design Guide
- Bitcoin Universal Design Accessibility Standards
- GitHub Repository
- Component Examples
- Contributing Guidelines
