UNPKG

consensys-ui

Version:

Consensys UI component library and design system

378 lines (297 loc) • 11.1 kB
# @consensys/ui-theme > 🚧 **Note**: This package is under active development. While we're working hard to make it production-ready, please be aware that APIs and features may change. We welcome your feedback and contributions as we continue to improve! šŸŽØ **Complex theming made simple** Build sophisticated, dynamic themes with a comprehensive design system that includes colors, spacing, typography, shadows, and animations. Our color system handles nested themes, mode switching, and semantic color mapping with ease. ## ✨ Standout Features šŸŽØ **Radix Colors** - Built on [Radix UI Colors](https://www.radix-ui.com/colors) for accessible, consistent color usage with semantic mapping šŸŽÆ **Design Token System** - Complete set of pre-configured tokens for colors, spacing, typography, shadows, and animations šŸŽØ **Tailwind Classes** - Use familiar Tailwind classes with our pre-configured design tokens šŸŒ“ **Mode Switching** - Toggle between light and dark modes with simple class changes šŸ”„ **Theme Switching** - Switch between different themes (default, oceanBreeze, etc.) with class combinations šŸŽ­ **Nested Themes** - Create complex theme hierarchies with parent-child relationships and inheritance šŸŽØ **Dynamic Inheritance** - Child themes inherit from parent themes while maintaining their own overrides ⚔ **Dynamic CSS Variables** - Runtime theme customization with smooth transitions and real-time updates ## šŸš€ Quick Start ### Installation ```bash pnpm add @consensys/ui-theme ``` ### Tailwind Configuration ```javascript // tailwind.config.js import { tailwindPreset } from '@consensys/ui-theme'; export default { presets: [tailwindPreset({ themes: { // Choose colors from Radix UI color palettes // See: https://www.radix-ui.com/colors default: { colors: { neutral: 'gray', primary: 'blue', secondary: 'violet', error: 'red', warning: 'amber', success: 'green', info: 'blue', } } } })], }; ``` ### Simple Usage ```html <!-- Light mode --> <div class="light"> <button class="bg-primary hover:bg-primary-7 text-white px-4 py-2 rounded"> Click me </button> </div> <!-- Dark mode --> <div class="dark"> <button class="bg-primary hover:bg-primary-7 text-white px-4 py-2 rounded"> Click me </button> </div> ``` ## šŸŽØ Creating Custom Themes Create custom themes by mapping semantic colors to different Radix colors: ```typescript // tailwind.config.js import { tailwindPreset } from '@consensys/ui-theme'; export default { presets: [tailwindPreset({ themes: { // Default theme default: { colors: { neutral: 'gray', primary: 'blue', secondary: 'violet', error: 'red', warning: 'amber', success: 'green', info: 'blue', } }, // Custom theme oceanBreeze: { colors: { neutral: 'slate', // Cooler neutral tone primary: 'cyan', // Ocean-inspired primary secondary: 'blue', // Complementary blue error: 'red', // Keep error consistent warning: 'amber', // Keep warning consistent success: 'grass', // Natural success color info: 'blue', // Match secondary } } } })], }; ``` Then use your custom theme with the appropriate mode class: ```html <!-- Ocean Breeze theme in light mode --> <div class="oceanBreeze light"> <button class="bg-primary hover:bg-primary-7 text-white"> Ocean Breeze Button </button> <p class="text-primary-11">Text using primary color</p> <div class="bg-primary-a5">Semi-transparent background</div> </div> <!-- Ocean Breeze theme in dark mode --> <div class="oceanBreeze dark"> <button class="bg-primary hover:bg-primary-7 text-white"> Ocean Breeze Button </button> <p class="text-primary-11">Text using primary color</p> <div class="bg-primary-a5">Semi-transparent background</div> </div> ``` ### Nested Themes Create different theme zones within your application: ```html <!-- Root theme (default) --> <div class="light"> <!-- Main content with default theme --> <main> <button class="bg-primary">Default Theme Button</button> </main> <!-- Nested Ocean Breeze theme --> <div class="oceanBreeze dark"> <button class="bg-primary">Ocean Breeze Dark Button</button> </div> <!-- Another nested theme --> <div class="sunset light"> <button class="bg-primary">Sunset Theme Light Button</button> </div> </div> ``` ## šŸŽÆ Design Tokens The theme package provides a complete set of design tokens through the Tailwind preset. These tokens are carefully crafted to work together and maintain consistency across your application: ```typescript // tailwind.config.js import { tailwindPreset } from '@consensys/ui-theme'; export default { presets: [tailwindPreset({ themes: { // Your theme configuration } })], }; ``` The preset includes: - **Colors**: Semantic color system built on Radix UI Colors - **Spacing**: Consistent spacing scale from 0 to 40rem - **Typography**: - Font families (Inter, Roboto, Libre Franklin) - Font sizes with line heights and weights - Heading styles (h1-h6) - Text styles (xl, lg, base, sm, xs) - **Shadows**: Theme-aware shadow tokens - **Animations**: Pre-configured animations and keyframes - **Border Radius**: Consistent border radius scale For detailed configuration options, see the [Tailwind preset source](src/tailwind.preset.ts). ## šŸ”§ How It Works ### Radix Color Foundation CUI's color system is built on top of Radix UI Colors, providing a robust foundation for accessible and consistent color usage. Each color in our system follows Radix's 12-step scale: ``` 1 - Lightest 2 - Very Light 3 - Light 4 - Light-Medium 5 - Medium-Light 6 - Medium (DEFAULT) 7 - Medium-Dark 8 - Dark-Medium 9 - Dark 10 - Very Dark 11 - Darkest 12 - Alpha variants ``` Each Radix color comes in four variants: - Base color (e.g., `blue`) - Dark mode color (e.g., `blueDark`) - Alpha color (e.g., `blueA`) - Dark mode alpha color (e.g., `blueDarkA`) ### Semantic Color Mapping | Semantic Color | Purpose | Default Mapping | |----------------|---------|----------------| | `neutral` | Base UI elements, text, borders | `gray` | | `primary` | Main actions, brand identity | `blue` | | `secondary` | Alternative actions, accents | `violet` | | `error` | Error states, destructive actions | `red` | | `warning` | Warning states, cautionary actions | `amber` | | `success` | Success states, positive actions | `green` | | `info` | Information states, neutral actions | `blue` | When you map a semantic color to a Radix color, CUI automatically generates all necessary variants: - Light mode colors (1-12 steps) - Dark mode colors (1-12 steps) - Alpha variants for both modes - CSS variables namespaced to the current theme and mode ### Generated CSS Structure The system generates CSS variables for each theme and mode combination: ```css /* Light mode (default theme) */ .light { --color-neutral-1: var(--radix-gray-1); --color-neutral-a1: var(--radix-gray-a1); /* Alpha variant for transparency */ --color-primary-1: var(--radix-blue-1); --color-primary-a1: var(--radix-blue-a1); /* Alpha variant for transparency */ /* ... */ } /* Dark mode (default theme) */ .dark { --color-neutral-1: var(--radix-gray-dark-1); --color-neutral-a1: var(--radix-gray-dark-a1); /* Alpha variant for transparency */ --color-primary-1: var(--radix-blue-dark-1); --color-primary-a1: var(--radix-blue-dark-a1); /* Alpha variant for transparency */ /* ... */ } /* Light mode (ocean breeze theme) */ .oceanBreeze.light { --color-neutral-1: var(--radix-slate-1); --color-neutral-a1: var(--radix-slate-a1); /* Alpha variant for transparency */ --color-primary-1: var(--radix-cyan-1); --color-primary-a1: var(--radix-cyan-a1); /* Alpha variant for transparency */ /* ... */ } /* Dark mode (ocean breeze theme) */ .oceanBreeze.dark { --color-neutral-1: var(--radix-slate-dark-1); --color-neutral-a1: var(--radix-slate-dark-a1); /* Alpha variant for transparency */ --color-primary-1: var(--radix-cyan-dark-1); --color-primary-a1: var(--radix-cyan-dark-a1); /* Alpha variant for transparency */ /* ... */ } ``` These CSS variables are automatically mapped to Tailwind classes: ```html <!-- Default theme in light mode --> <div class="light"> <!-- Using base colors --> <div class="bg-primary-1">Lightest primary color</div> <div class="text-neutral-1">Lightest neutral color</div> <!-- Using alpha variants --> <div class="bg-primary-a1">Semi-transparent primary color</div> <div class="text-neutral-a1">Semi-transparent neutral color</div> </div> <!-- Ocean Breeze theme in light mode --> <div class="oceanBreeze light"> <div class="bg-primary-1">Ocean Breeze lightest primary</div> <div class="bg-primary-a1">Ocean Breeze transparent primary</div> </div> <!-- Nested themes example --> <div class="light"> <div class="bg-primary-1">Default theme</div> <!-- Ocean Breeze theme in dark mode --> <div class="oceanBreeze dark"> <div class="bg-primary-1">Nested Ocean Breeze theme</div> </div> </div> ``` ### Dynamic CSS Variable Changes The theme system supports dynamic changes to CSS variables at runtime, enabling smooth transitions between themes and modes. This is particularly useful for: - Theme switching animations - User preference changes - System theme synchronization - Runtime theme customization #### Theme Switching When switching themes or modes, the system updates CSS variables in real-time: ```typescript // Example of theme switching document.documentElement.classList.remove('light'); document.documentElement.classList.add('dark'); // Or switching to a custom theme document.documentElement.classList.remove('default'); document.documentElement.classList.add('oceanBreeze'); ``` The CSS variables update automatically, maintaining all color relationships and semantic mappings. #### Runtime Customization You can also customize theme variables at runtime: ```typescript // Example of runtime color adjustment document.documentElement.style.setProperty('--color-primary-6', '#custom-color'); // Or adjusting alpha values document.documentElement.style.setProperty('--color-primary-a6', 'rgba(0, 0, 0, 0.5)'); ``` #### Smooth Transitions To enable smooth transitions between theme changes, add transition properties to your CSS: ```css /* Add to your global CSS */ :root { --theme-transition-duration: 200ms; } * { transition: background-color var(--theme-transition-duration) ease, color var(--theme-transition-duration) ease, border-color var(--theme-transition-duration) ease; } ``` This creates a smooth experience when switching between themes or modes. ## šŸ¤ Contributing Contributions welcome! ## šŸ“œ License MIT License - Copyright (c) 2024 ConsenSys Mesh