@restio/design-tokens
v1.4.1
Published
A comprehensive design token system built with Style Dictionary, featuring primitives and alias architecture for scalable design systems
Maintainers
Readme
@restio/design-tokens
A comprehensive design token system built with Style Dictionary v5.1.1, featuring a primitives → alias → composite architecture for scalable design systems.
🎨 Features
- OKLCH Color Space: Modern color format for better perceptual uniformity
- Multi-Theme Support: Built-in dark and high-contrast themes with complete token sets
- Semantic Token Architecture: Primitives → Alias → Composite token hierarchy
- Style Dictionary v5.1.1: Latest design token tooling with DTCG format support
- TypeScript Support: Full type definitions included
- Framework Agnostic: Works with React, Vue, Angular, Svelte, and vanilla projects
📦 Installation
# NPM
npm install @restio/design-tokens
# Yarn
yarn add @restio/design-tokens
# PNPM
pnpm add @restio/design-tokens🚀 Quick Start
1. Import CSS Tokens
/* Import complete token system with all themes */
@import '@restio/design-tokens/dist/css/tokens.css';
/* Or import specific layers for better control */
@import '@restio/design-tokens/dist/css/primitives.css';
@import '@restio/design-tokens/dist/css/alias.css';
/* Import theme overrides */
@import '@restio/design-tokens/dist/css/themes/dark.css';
@import '@restio/design-tokens/dist/css/themes/high-contrast.css';2. Use Design Tokens
.button {
/* Semantic tokens - automatically theme-aware */
background: var(--rst-backgroundColor-primary-default);
color: var(--rst-textColor-onPrimary);
border: var(--rst-border-default);
/* Typography composite token */
font: var(--rst-font-body);
/* Spacing and layout */
padding: var(--rst-spacing-md) var(--rst-spacing-lg);
border-radius: var(--rst-borderRadius-md);
/* Interactive states */
transition: all 200ms var(--rst-easing-default);
}
.button:hover {
background: var(--rst-backgroundColor-primary-hover);
transform: translateY(-2px);
box-shadow: var(--rst-shadow-elevated);
}3. Enable Theme Switching
// Theme switching utility
function setTheme(themeName) {
document.documentElement.setAttribute('data-theme', themeName);
}
// Available themes: 'default', 'dark', 'high-contrast'
setTheme('dark');🎯 Framework Integration
React/Next.js Integration
// pages/_app.tsx or app/layout.tsx
import '@restio/design-tokens/dist/css/tokens.css';
// Theme Provider Component
import React, { createContext, useContext, useState } from 'react';
type Theme = 'default' | 'dark' | 'high-contrast';
const ThemeContext = createContext<{
theme: Theme;
setTheme: (theme: Theme) => void;
}>({
theme: 'default',
setTheme: () => {},
});
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<Theme>('default');
React.useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
}, [theme]);
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
export const useTheme = () => useContext(ThemeContext);
// Usage in components
function MyButton({ children, ...props }) {
return (
<button
className="rst-button" // Use CSS classes with design tokens
{...props}
>
{children}
</button>
);
}Vue.js Integration
<!-- App.vue -->
<template>
<div :data-theme="currentTheme">
<ThemeSwitcher @theme-change="handleThemeChange" />
<MyComponent />
</div>
</template>
<script setup>
import { ref } from 'vue';
import '@restio/design-tokens/dist/css/tokens.css';
const currentTheme = ref('default');
function handleThemeChange(newTheme) {
currentTheme.value = newTheme;
}
</script>
<style scoped>
.my-component {
background: var(--rst-backgroundColor-surface-default);
color: var(--rst-textColor-primary);
padding: var(--rst-spacing-lg);
border-radius: var(--rst-borderRadius-lg);
}
</style>Angular Integration
// app.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div [attr.data-theme]="currentTheme">
<app-theme-switcher (themeChange)="setTheme($event)"></app-theme-switcher>
<router-outlet></router-outlet>
</div>
`,
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
currentTheme = 'default';
setTheme(theme: string) {
this.currentTheme = theme;
}
}// app.component.scss
@import '@restio/design-tokens/dist/css/tokens.css';
.button {
background: var(--rst-backgroundColor-primary-default);
color: var(--rst-textColor-onPrimary);
border: var(--rst-border-default);
padding: var(--rst-spacing-md) var(--rst-spacing-lg);
border-radius: var(--rst-borderRadius-md);
&:hover {
background: var(--rst-backgroundColor-primary-hover);
}
}Svelte Integration
<!-- App.svelte -->
<script>
import '@restio/design-tokens/dist/css/tokens.css';
let currentTheme = 'default';
function setTheme(theme) {
currentTheme = theme;
}
$: {
if (typeof document !== 'undefined') {
document.documentElement.setAttribute('data-theme', currentTheme);
}
}
</script>
<div data-theme={currentTheme}>
<button
class="theme-switcher"
on:click={() => setTheme(currentTheme === 'default' ? 'dark' : 'default')}
>
Switch Theme
</button>
<main class="content">
<slot />
</main>
</div>
<style>
.content {
background: var(--rst-backgroundColor-surface-default);
color: var(--rst-textColor-primary);
padding: var(--rst-spacing-xl);
min-height: 100vh;
}
.theme-switcher {
background: var(--rst-backgroundColor-primary-default);
color: var(--rst-textColor-onPrimary);
border: var(--rst-border-default);
padding: var(--rst-spacing-sm) var(--rst-spacing-md);
border-radius: var(--rst-borderRadius-md);
font: var(--rst-font-body);
}
</style>🎨 Building Component Libraries
Creating Theme-Aware Components
// components/Button/Button.tsx
import React from 'react';
import styles from './Button.module.css';
interface ButtonProps {
variant?: 'primary' | 'secondary' | 'outline';
size?: 'sm' | 'md' | 'lg';
children: React.ReactNode;
}
export function Button({
variant = 'primary',
size = 'md',
children,
...props
}: ButtonProps) {
return (
<button
className={`${styles.button} ${styles[variant]} ${styles[size]}`}
{...props}
>
{children}
</button>
);
}/* components/Button/Button.module.css */
.button {
/* Base styles using design tokens */
font: var(--rst-font-body);
border-radius: var(--rst-borderRadius-md);
border: var(--rst-borderWidth-default) solid transparent;
cursor: pointer;
transition: all 200ms var(--rst-easing-default);
/* Focus states */
&:focus-visible {
outline: 2px solid var(--rst-borderColor-focus);
outline-offset: 2px;
}
}
.primary {
background: var(--rst-backgroundColor-primary-default);
color: var(--rst-textColor-onPrimary);
&:hover {
background: var(--rst-backgroundColor-primary-hover);
transform: translateY(-1px);
box-shadow: var(--rst-shadow-sm);
}
&:active {
transform: translateY(0);
background: var(--rst-backgroundColor-primary-pressed);
}
}
.secondary {
background: var(--rst-backgroundColor-secondary-default);
color: var(--rst-textColor-onSecondary);
&:hover {
background: var(--rst-backgroundColor-secondary-hover);
}
}
.outline {
background: transparent;
color: var(--rst-textColor-primary);
border-color: var(--rst-borderColor-default);
&:hover {
background: var(--rst-backgroundColor-surface-hover);
border-color: var(--rst-borderColor-emphasis);
}
}
/* Size variations */
.sm {
padding: var(--rst-spacing-xs) var(--rst-spacing-sm);
font-size: var(--rst-fontSize-sm);
}
.md {
padding: var(--rst-spacing-sm) var(--rst-spacing-md);
font-size: var(--rst-fontSize-md);
}
.lg {
padding: var(--rst-spacing-md) var(--rst-spacing-lg);
font-size: var(--rst-fontSize-lg);
}📚 Available Token Categories
Colors
- Primitives:
--rst-color-primary-600,--rst-color-gray-100 - Semantic:
--rst-backgroundColor-surface-default,--rst-textColor-primary
Typography
- Fonts:
--rst-font-body,--rst-font-heading,--rst-font-display - Sizes:
--rst-fontSize-xsthrough--rst-fontSize-xxl
Spacing & Layout
- Spacing:
--rst-spacing-xsthrough--rst-spacing-xxl - Dimensions:
--rst-dimension-4through--rst-dimension-96
Interactive Elements
- Borders:
--rst-border-default,--rst-borderRadius-md - Shadows:
--rst-shadow-sm,--rst-shadow-elevated - Focus States:
--rst-borderColor-focus,--rst-backgroundColor-focus
🌙 Theme System
Available Themes
- Default: Light theme with primary brand colors
- Dark: Dark theme with inverted grays and optimized contrast
- High Contrast: Maximum contrast for accessibility (WCAG AAA)
Custom Theme Creation
/* Create custom theme by overriding specific tokens */
[data-theme='brand-alt'] {
--rst-color-primary-600: oklch(60% 0.25 340); /* Custom brand color */
--rst-backgroundColor-primary-default: var(--rst-color-primary-600);
--rst-backgroundColor-primary-hover: oklch(65% 0.25 340);
}🔧 Build Tools Integration
CSS Preprocessors
// SCSS with design tokens
@import '@restio/design-tokens/dist/css/tokens.css';
.card {
background: var(--rst-backgroundColor-surface-default);
border: var(--rst-border-default);
border-radius: var(--rst-borderRadius-lg);
padding: var(--rst-spacing-lg);
// Use tokens in calculations
margin: calc(var(--rst-spacing-md) * 2);
// Combine with SCSS features
&:hover {
box-shadow: var(--rst-shadow-elevated);
transform: translateY(-2px);
}
}📊 Token Reference
Color System (OKLCH)
/* Primary colors */
--rst-color-primary-50: oklch(97% 0.02 270);
--rst-color-primary-600: oklch(55% 0.18 270);
--rst-color-primary-900: oklch(25% 0.12 270);
/* Semantic backgrounds */
--rst-backgroundColor-primary-default: var(--rst-color-primary-600);
--rst-backgroundColor-surface-default: var(--rst-color-white);
--rst-backgroundColor-surface-hover: var(--rst-color-gray-50);Typography System
/* Composite typography tokens */
--rst-font-body: normal 400 1rem/1.5 'Inter', system-ui, sans-serif;
--rst-font-heading: normal 600 1.25rem/1.2 'Inter', system-ui, sans-serif;
--rst-font-display: normal 700 2rem/1.1 'Inter', system-ui, sans-serif;📁 Package Structure
@restio/design-tokens/
├── dist/css/
│ ├── tokens.css # Complete token system
│ ├── primitives.css # Raw values (colors, dimensions)
│ ├── alias.css # Semantic tokens
│ └── themes/
│ ├── dark.css # Dark theme overrides
│ └── high-contrast.css
├── src/tokens/ # Source JSON files
│ ├── primitives/
│ ├── alias/
│ └── themes/
└── types/ # TypeScript definitions⚡ Token Structure
{
"rst": {
"tokenName": {
"$value": "actualValue | {reference}",
"$type": "color|dimension|typography|border|shadow",
"$description": "Usage context and purpose"
}
}
}📚 Documentation
Visit our Storybook documentation to explore all available tokens with live examples and theme switching.
🔧 Development
Built with Style Dictionary v5.1.1 using the Design Tokens Community Group format.
📄 License
ISC © Leonardo Signorelli
