@hydrogen-ui/tokens
v0.1.0
Published
Design tokens for Hydrogen UI component library
Maintainers
Readme
@hydrogen-ui/tokens
A comprehensive design token system for Hydrogen UI built with Style Dictionary. Provides consistent design values across colors, typography, spacing, and components with full TypeScript support.
Installation
npm install @hydrogen-ui/tokens
# or
yarn add @hydrogen-ui/tokens
# or
pnpm add @hydrogen-ui/tokensFeatures
- 🎨 Comprehensive Token Set - Colors, typography, spacing, shadows, and more
- 🔧 Multiple Output Formats - CSS, JavaScript, TypeScript, and JSON
- 🎯 Semantic Tokens - Purpose-driven tokens for consistent usage
- 📦 Component Tokens - Pre-configured values for common components
- 🎭 Theme Support - Override base tokens for custom themes
- 🔒 Type Safety - Full TypeScript definitions
- 🚀 Zero Runtime - All tokens are build-time generated
- 📱 Responsive Ready - Tokens designed for responsive design
- ♿ Accessibility - WCAG compliant color combinations
Quick Start
CSS Variables
/* Import CSS variables */
@import '@hydrogen-ui/tokens/dist/css/variables.css';
.my-component {
color: var(--color-text-primary);
background-color: var(--color-background-primary);
padding: var(--spacing-md);
font-size: var(--font-size-base);
border-radius: var(--border-radius-md);
}JavaScript/TypeScript
import { tokens } from '@hydrogen-ui/tokens';
const styles = {
color: tokens.color.text.primary.value,
backgroundColor: tokens.color.background.primary.value,
padding: tokens.spacing.md.value,
fontSize: tokens.typography.fontSize.base.value,
borderRadius: tokens.border.radius.md.value
};React with TypeScript
import { tokens, TokenColors, TokenSpacing } from '@hydrogen-ui/tokens';
interface ButtonProps {
color?: keyof TokenColors;
spacing?: keyof TokenSpacing;
}
function Button({ color = 'primary', spacing = 'md' }: ButtonProps) {
return (
<button
style={{
backgroundColor: tokens.color.button[color].background.value,
padding: tokens.spacing[spacing].value
}}
>
Click me
</button>
);
}Token Categories
Global Tokens
Colors
Complete color palette with 10 shades for each color:
// Base colors
tokens.color.black // #000000
tokens.color.white // #FFFFFF
// Gray scale (50-900)
tokens.color.gray[50] // #F9FAFB
tokens.color.gray[100] // #F3F4F6
tokens.color.gray[200] // #E5E7EB
// ... up to gray[900]
// Color palettes (50-900)
tokens.color.red[500] // #EF4444
tokens.color.green[500] // #10B981
tokens.color.blue[500] // #3B82F6
tokens.color.yellow[500] // #F59E0BTypography
// Font families
tokens.typography.fontFamily.sans // 'Inter', system-ui, ...
tokens.typography.fontFamily.serif // 'Georgia', serif
tokens.typography.fontFamily.mono // 'Fira Code', monospace
// Font sizes
tokens.typography.fontSize.xs // 0.75rem (12px)
tokens.typography.fontSize.sm // 0.875rem (14px)
tokens.typography.fontSize.base // 1rem (16px)
tokens.typography.fontSize.lg // 1.125rem (18px)
tokens.typography.fontSize.xl // 1.25rem (20px)
// ... up to 9xl
// Font weights
tokens.typography.fontWeight.thin // 100
tokens.typography.fontWeight.light // 300
tokens.typography.fontWeight.normal // 400
tokens.typography.fontWeight.medium // 500
tokens.typography.fontWeight.semibold // 600
tokens.typography.fontWeight.bold // 700
tokens.typography.fontWeight.extrabold // 800
tokens.typography.fontWeight.black // 900
// Line heights
tokens.typography.lineHeight.none // 1
tokens.typography.lineHeight.tight // 1.25
tokens.typography.lineHeight.snug // 1.375
tokens.typography.lineHeight.normal // 1.5
tokens.typography.lineHeight.relaxed // 1.625
tokens.typography.lineHeight.loose // 2
// Letter spacing
tokens.typography.letterSpacing.tighter // -0.05em
tokens.typography.letterSpacing.tight // -0.025em
tokens.typography.letterSpacing.normal // 0
tokens.typography.letterSpacing.wide // 0.025em
tokens.typography.letterSpacing.wider // 0.05em
tokens.typography.letterSpacing.widest // 0.1emSpacing
Consistent spacing scale based on rem units:
tokens.spacing[0] // 0
tokens.spacing.px // 1px
tokens.spacing[0.5] // 0.125rem (2px)
tokens.spacing[1] // 0.25rem (4px)
tokens.spacing[2] // 0.5rem (8px)
tokens.spacing[3] // 0.75rem (12px)
tokens.spacing[4] // 1rem (16px)
// ... up to spacing[96]
// Named aliases
tokens.spacing.xs // 0.5rem
tokens.spacing.sm // 1rem
tokens.spacing.md // 1.5rem
tokens.spacing.lg // 2rem
tokens.spacing.xl // 3rem
tokens.spacing['2xl'] // 4remShadows
Box shadow presets:
tokens.shadow.none // none
tokens.shadow.sm // 0 1px 2px 0 rgba(0, 0, 0, 0.05)
tokens.shadow.base // 0 1px 3px 0 rgba(0, 0, 0, 0.1), ...
tokens.shadow.md // 0 4px 6px -1px rgba(0, 0, 0, 0.1), ...
tokens.shadow.lg // 0 10px 15px -3px rgba(0, 0, 0, 0.1), ...
tokens.shadow.xl // 0 20px 25px -5px rgba(0, 0, 0, 0.1), ...
tokens.shadow['2xl'] // 0 25px 50px -12px rgba(0, 0, 0, 0.25)
tokens.shadow.inner // inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)Borders
// Border widths
tokens.border.width.none // 0
tokens.border.width.thin // 1px
tokens.border.width.base // 2px
tokens.border.width.thick // 4px
tokens.border.width.heavy // 8px
// Border radius
tokens.border.radius.none // 0
tokens.border.radius.sm // 0.125rem
tokens.border.radius.base // 0.25rem
tokens.border.radius.md // 0.375rem
tokens.border.radius.lg // 0.5rem
tokens.border.radius.xl // 0.75rem
tokens.border.radius['2xl'] // 1rem
tokens.border.radius['3xl'] // 1.5rem
tokens.border.radius.full // 9999pxAnimation
// Durations
tokens.animation.duration.instant // 0ms
tokens.animation.duration.fast // 150ms
tokens.animation.duration.normal // 300ms
tokens.animation.duration.slow // 500ms
tokens.animation.duration.slower // 700ms
tokens.animation.duration.slowest // 1000ms
// Easing functions
tokens.animation.easing.linear // linear
tokens.animation.easing.easeIn // cubic-bezier(0.4, 0, 1, 1)
tokens.animation.easing.easeOut // cubic-bezier(0, 0, 0.2, 1)
tokens.animation.easing.easeInOut // cubic-bezier(0.4, 0, 0.2, 1)
tokens.animation.easing.bounce // cubic-bezier(0.68, -0.55, 0.265, 1.55)Semantic Tokens
Purpose-driven tokens that reference global tokens:
Text Colors
tokens.color.text.primary // Primary text color
tokens.color.text.secondary // Secondary/muted text
tokens.color.text.disabled // Disabled state text
tokens.color.text.inverse // Inverted text (on dark backgrounds)
tokens.color.text.link // Link color
tokens.color.text.visited // Visited link color
tokens.color.text.hover // Hover state textBackground Colors
tokens.color.background.primary // Main background
tokens.color.background.secondary // Secondary sections
tokens.color.background.tertiary // Tertiary/subtle backgrounds
tokens.color.background.inverse // Inverted backgroundsComponent Tokens
Pre-configured values for common components:
// Buttons
tokens.component.button.height.sm // 2rem
tokens.component.button.height.md // 2.5rem
tokens.component.button.height.lg // 3rem
tokens.component.button.padding.sm // 0.5rem 1rem
tokens.component.button.padding.md // 0.75rem 1.5rem
tokens.component.button.padding.lg // 1rem 2rem
tokens.component.button.fontSize.sm // 0.875rem
tokens.component.button.fontSize.md // 1rem
tokens.component.button.fontSize.lg // 1.125rem
// Inputs
tokens.component.input.height.sm // 2rem
tokens.component.input.height.md // 2.5rem
tokens.component.input.height.lg // 3rem
tokens.component.input.padding.sm // 0.5rem 0.75rem
tokens.component.input.padding.md // 0.75rem 1rem
tokens.component.input.padding.lg // 1rem 1.25rem
// Cards
tokens.component.card.padding.sm // 1rem
tokens.component.card.padding.md // 1.5rem
tokens.component.card.padding.lg // 2rem
tokens.component.card.shadow // shadow.md
tokens.component.card.borderRadius // border.radius.lg
// Modals
tokens.component.modal.padding.sm // 1rem
tokens.component.modal.padding.md // 1.5rem
tokens.component.modal.padding.lg // 2rem
tokens.component.modal.maxWidth.sm // 24rem
tokens.component.modal.maxWidth.md // 32rem
tokens.component.modal.maxWidth.lg // 48remUsage Patterns
Component Development
import { tokens } from '@hydrogen-ui/tokens';
// Consistent component styling
const Button = styled.button`
/* Size variants using component tokens */
&.sm {
height: ${tokens.component.button.height.sm.value};
padding: ${tokens.component.button.padding.sm.value};
font-size: ${tokens.component.button.fontSize.sm.value};
}
&.md {
height: ${tokens.component.button.height.md.value};
padding: ${tokens.component.button.padding.md.value};
font-size: ${tokens.component.button.fontSize.md.value};
}
/* State colors using semantic tokens */
background-color: ${tokens.color.button.primary.background.value};
color: ${tokens.color.button.primary.text.value};
&:hover {
background-color: ${tokens.color.button.primary.hover.value};
}
&:active {
background-color: ${tokens.color.button.primary.active.value};
}
&:disabled {
background-color: ${tokens.color.button.primary.disabled.value};
cursor: not-allowed;
}
/* Consistent styling */
border-radius: ${tokens.border.radius.md.value};
font-weight: ${tokens.typography.fontWeight.medium.value};
transition: all ${tokens.animation.duration.fast.value} ${tokens.animation.easing.easeOut.value};
`;Responsive Design
// Using tokens for responsive breakpoints
const ResponsiveGrid = styled.div`
display: grid;
gap: ${tokens.spacing.md.value};
/* Mobile */
grid-template-columns: 1fr;
padding: ${tokens.spacing.sm.value};
/* Tablet */
@media (min-width: 768px) {
grid-template-columns: repeat(2, 1fr);
gap: ${tokens.spacing.lg.value};
padding: ${tokens.spacing.md.value};
}
/* Desktop */
@media (min-width: 1024px) {
grid-template-columns: repeat(3, 1fr);
gap: ${tokens.spacing.xl.value};
padding: ${tokens.spacing.lg.value};
}
`;Dark Mode Support
// Define color schemes using tokens
const lightTheme = {
background: tokens.color.white.value,
text: tokens.color.gray[900].value,
border: tokens.color.gray[200].value
};
const darkTheme = {
background: tokens.color.gray[900].value,
text: tokens.color.gray[50].value,
border: tokens.color.gray[700].value
};
// Apply based on theme
const ThemedComponent = styled.div`
background-color: ${props => props.theme.background};
color: ${props => props.theme.text};
border: 1px solid ${props => props.theme.border};
`;TypeScript Support
The package includes comprehensive TypeScript definitions:
import type {
Tokens,
TokenColors,
TokenSpacing,
TokenTypography,
TokenShadows,
TokenBorders,
TokenAnimation,
TokenComponents
} from '@hydrogen-ui/tokens';
// Type-safe token access
function getSpacing(size: keyof TokenSpacing): string {
return tokens.spacing[size].value;
}
// Component prop types
interface StyledProps {
color?: keyof TokenColors;
spacing?: keyof TokenSpacing;
fontSize?: keyof TokenTypography['fontSize'];
}Custom Themes
Create custom themes by extending or overriding base tokens:
Directory Structure
src/
├── themes/
│ └── my-theme/
│ ├── color.json
│ ├── typography.json
│ └── component.jsonTheme Configuration
// src/themes/my-theme/color.json
{
"color": {
"primary": {
"50": { "value": "#E3F2FD" },
"100": { "value": "#BBDEFB" },
"500": { "value": "#2196F3" },
"900": { "value": "#0D47A1" }
},
"text": {
"primary": { "value": "{color.gray.900.value}" },
"secondary": { "value": "{color.gray.600.value}" }
}
}
}Building Custom Themes
# Add your theme to the build config
npm run build:tokens -- --theme my-theme
# Generate all formats
npm run buildBuild Configuration
The package uses Style Dictionary for token generation:
// style-dictionary.config.js
module.exports = {
source: ['src/**/*.json'],
platforms: {
css: {
transformGroup: 'css',
buildPath: 'dist/css/',
files: [{
destination: 'variables.css',
format: 'css/variables'
}]
},
js: {
transformGroup: 'js',
buildPath: 'dist/js/',
files: [{
destination: 'tokens.js',
format: 'javascript/es6'
}]
},
json: {
transformGroup: 'js',
buildPath: 'dist/json/',
files: [{
destination: 'tokens.json',
format: 'json/nested'
}]
}
}
};Integration Examples
With CSS-in-JS Libraries
// Styled Components
import styled from 'styled-components';
import { tokens } from '@hydrogen-ui/tokens';
const Card = styled.div`
background: ${tokens.color.background.primary.value};
padding: ${tokens.component.card.padding.md.value};
border-radius: ${tokens.component.card.borderRadius.value};
box-shadow: ${tokens.component.card.shadow.value};
`;
// Emotion
import { css } from '@emotion/react';
const cardStyles = css`
background: ${tokens.color.background.primary.value};
padding: ${tokens.component.card.padding.md.value};
border-radius: ${tokens.component.card.borderRadius.value};
box-shadow: ${tokens.component.card.shadow.value};
`;With Tailwind CSS
// tailwind.config.js
const { tokens } = require('@hydrogen-ui/tokens');
module.exports = {
theme: {
extend: {
colors: {
primary: tokens.color.primary,
gray: tokens.color.gray
},
spacing: tokens.spacing,
fontSize: tokens.typography.fontSize,
fontWeight: tokens.typography.fontWeight,
borderRadius: tokens.border.radius,
boxShadow: tokens.shadow
}
}
};With Sass
// Import generated Sass variables
@import '@hydrogen-ui/tokens/dist/scss/variables';
.button {
background-color: $color-button-primary-background;
color: $color-button-primary-text;
padding: $component-button-padding-md;
border-radius: $border-radius-md;
&:hover {
background-color: $color-button-primary-hover;
}
}Design Token Best Practices
Use Semantic Tokens: Prefer semantic tokens over global tokens for better maintainability
// ✅ Good color: tokens.color.text.primary.value // ❌ Avoid color: tokens.color.gray[900].valueComponent Tokens for Consistency: Use component tokens for standard UI elements
// ✅ Good height: tokens.component.button.height.md.value // ❌ Avoid height: '40px'Type Safety: Leverage TypeScript for compile-time checks
// ✅ Good function getColor(variant: keyof TokenColors): string { return tokens.color[variant].value; }Token References: Use token references in your custom tokens
{ "button": { "primary": { "background": { "value": "{color.primary.500.value}" } } } }
Browser Support
- Modern browsers with CSS Custom Properties support
- IE11 requires polyfills for CSS variables
- All JavaScript tokens work in any environment
Contributing
Adding New Tokens
- Add token definitions to appropriate category in
src/ - Follow existing naming conventions
- Include semantic aliases where appropriate
- Run
npm run buildto generate outputs - Update TypeScript definitions if needed
Token Naming Convention
- Use lowercase with dots as separators
- Start with category (color, spacing, typography)
- Include subcategories as needed
- End with specific value or variant
category.subcategory.variant.state.property
color.button.primary.hover.backgroundLicense
MIT
