npm package: @hydrogen-ui/core
Description: Core utilities and hooks for Hydrogen UI
Latest version: 0.1.0

# @hydrogen-ui/core

The foundational package for Hydrogen UI that provides theme management, design token system, and core utilities for building Shopify Hydrogen storefronts.

## Installation

```bash
npm install @hydrogen-ui/core
# or
yarn add @hydrogen-ui/core
# or
pnpm add @hydrogen-ui/core
```

## Features

- 🎨 **Theme System** - Built-in themes with runtime switching
- 🎯 **Design Tokens** - Comprehensive token system with dot notation access
- ⚡ **Performance** - Advanced caching with LRU and stale-while-revalidate
- 🔧 **TypeScript** - Full type safety and autocompletion
- 🌗 **Dark Mode** - System preference detection and persistence
- 💾 **SSR Support** - Server-side rendering compatible
- 🎭 **CSS Variables** - Automatic CSS custom property generation

## Quick Start

```tsx
import { HydrogenUIProvider } from '@hydrogen-ui/core';
import { tokens } from '@hydrogen-ui/tokens';
import { dawn } from '@hydrogen-ui/themes';

function App() {
  return (
    <HydrogenUIProvider tokens={tokens} theme={dawn}>
      <YourApp />
    </HydrogenUIProvider>
  );
}
```

## Provider System

### HydrogenUIProvider

The root provider that sets up the entire Hydrogen UI system.

```tsx
<HydrogenUIProvider
  tokens={tokens}           // Design tokens object
  theme="dawn"              // Theme name or theme object
  themes={customThemes}     // Additional custom themes
  cache={customCache}       // Custom token cache instance
  onThemeChange={handler}   // Theme change callback
>
  <App />
</HydrogenUIProvider>
```

**Props:**
- `tokens` (required) - Base design tokens object
- `theme` - Theme name (string) or theme object
- `themes` - Object containing additional custom themes
- `cache` - Custom TokenCache instance
- `onThemeChange` - Callback fired when theme changes
- `children` - React children

### ThemeProvider

Lower-level provider for theme management (used internally by HydrogenUIProvider).

```tsx
<ThemeProvider
  theme="studio"
  themes={themes}
  tokens={mergedTokens}
  onThemeChange={(newTheme) => console.log('Theme changed to:', newTheme)}
>
  <App />
</ThemeProvider>
```

### TokenProvider

Lower-level provider for token access (used internally by HydrogenUIProvider).

```tsx
<TokenProvider tokens={tokens} cache={cache}>
  <App />
</TokenProvider>
```

## Hooks

### useToken

Access full token objects with metadata.

```tsx
import { useToken } from '@hydrogen-ui/core';

function Component() {
  const colorToken = useToken('color.primary.500');
  // Returns: { value: '#FF6B6B', type: 'color', description: '...' }
  
  const spacingToken = useToken('spacing.md');
  // Returns: { value: '16px' } or just '16px' if direct value
  
  return <div style={{ color: colorToken.value }}>Content</div>;
}
```

### useTokenValue

Access token values directly (most common use case).

```tsx
import { useTokenValue } from '@hydrogen-ui/core';

function Component() {
  const primaryColor = useTokenValue('color.primary.500');
  // Returns: '#FF6B6B'
  
  const spacing = useTokenValue('spacing.lg');
  // Returns: '24px'
  
  // Also accepts token objects
  const token = { value: '#000', type: 'color' };
  const value = useTokenValue(token);
  // Returns: '#000'
  
  return (
    <div style={{ 
      color: primaryColor,
      padding: spacing 
    }}>
      Styled content
    </div>
  );
}
```

### useTheme

Manage themes with persistence and system preferences.

```tsx
import { useTheme } from '@hydrogen-ui/core';

function ThemeSelector() {
  const { 
    theme,              // Current theme name
    setTheme,           // Theme setter function
    availableThemes,    // Array of available theme names
    tokens              // Current theme's tokens
  } = useTheme();
  
  return (
    <select value={theme} onChange={(e) => setTheme(e.target.value)}>
      {availableThemes.map((themeName) => (
        <option key={themeName} value={themeName}>
          {themeName}
        </option>
      ))}
    </select>
  );
}
```

## Design Tokens

### Token Structure

Tokens follow a hierarchical structure with dot notation access:

```typescript
{
  color: {
    primary: {
      50: '#FFF5F5',
      100: '#FED7D7',
      500: '#FF6B6B',
      900: '#742A2A'
    },
    text: {
      primary: '#1A202C',
      secondary: '#718096'
    }
  },
  spacing: {
    xs: '4px',
    sm: '8px',
    md: '16px',
    lg: '24px'
  },
  typography: {
    fontSize: {
      sm: '14px',
      base: '16px',
      lg: '18px'
    }
  }
}
```

### Token References

Tokens can reference other tokens using the `{token.path}` syntax:

```javascript
{
  color: {
    primary: {
      base: '#FF6B6B'
    },
    button: {
      background: '{color.primary.base}',  // References primary color
      hover: '{color.primary.700}'
    }
  }
}
```

### Token Objects

Tokens can be simple values or objects with metadata:

```javascript
{
  color: {
    primary: {
      // Simple value
      500: '#FF6B6B',
      
      // Object with metadata
      600: {
        value: '#E53E3E',
        type: 'color',
        description: 'Primary brand color - hover state'
      }
    }
  }
}
```

## Caching System

### Built-in Cache Strategies

```tsx
import { 
  createTokenCacheShort,
  createTokenCacheLong,
  createTokenCacheCustom 
} from '@hydrogen-ui/core';

// Short-lived cache (1 second + 9 seconds SWR)
const shortCache = createTokenCacheShort();

// Long-lived cache (1 hour + 24 hours SWR)
const longCache = createTokenCacheLong();

// Custom cache configuration
const customCache = createTokenCacheCustom({
  maxAge: 300000,      // 5 minutes
  staleWhileRevalidate: 600000,  // 10 minutes
  maxSize: 1000        // Maximum entries
});

// Use with provider
<HydrogenUIProvider tokens={tokens} cache={customCache}>
  <App />
</HydrogenUIProvider>
```

### TokenCache API

```tsx
import { TokenCache } from '@hydrogen-ui/core';

const cache = new TokenCache({
  maxAge: 60000,              // Max age in milliseconds
  staleWhileRevalidate: 300000,  // SWR period
  maxSize: 500                // Maximum cache entries
});

// Get cached value
const value = cache.get('color.primary.500');

// Set value
cache.set('color.primary.500', '#FF6B6B');

// Clear cache
cache.clear();

// Get cache statistics
const stats = cache.getStats();
// { hits: 150, misses: 20, size: 45 }
```

## CSS Integration

### CSS Variable Generation

Tokens are automatically converted to CSS custom properties:

```tsx
// Token: color.primary.500 = '#FF6B6B'
// CSS Variable: --color-primary-500: #FF6B6B

// Usage in CSS
.button {
  background-color: var(--color-primary-500);
  padding: var(--spacing-md);
}
```

### Inline Styles Helper

```tsx
import { createTokenStyle, createInlineTokenStyle } from '@hydrogen-ui/core';

// Create style object from tokens
const styles = createTokenStyle({
  color: 'color.text.primary',
  padding: 'spacing.md',
  fontSize: 'typography.fontSize.lg'
});
// Returns: { color: '#1A202C', padding: '16px', fontSize: '18px' }

// Create inline style string
const inlineStyle = createInlineTokenStyle({
  backgroundColor: 'color.surface.secondary',
  borderRadius: 'radius.md'
});
// Returns: "background-color: #F7FAFC; border-radius: 8px;"
```

### CSS Classes

```tsx
import { createTokenClasses } from '@hydrogen-ui/core';

const classes = createTokenClasses({
  text: 'color.primary.500',
  bg: 'color.surface.primary',
  p: 'spacing.lg'
});
// Returns: "text-primary-500 bg-surface-primary p-lg"
```

## Theme System

### Built-in Themes

The package includes five professionally designed themes:

- **dawn** - Clean and minimal design with excellent readability
- **craft** - Artisanal feel with warm colors and organic shapes
- **studio** - Modern and bold with high contrast
- **b2b** - Professional theme for business applications
- **thnk** - Creative and playful with vibrant colors

### Theme Structure

```typescript
interface Theme {
  name: string;
  tokens: {
    color?: Record<string, any>;
    typography?: Record<string, any>;
    spacing?: Record<string, any>;
    // ... other token categories
  };
}
```

### Custom Themes

Create custom themes by extending base tokens:

```tsx
const myCustomTheme = {
  name: 'my-brand',
  tokens: {
    color: {
      primary: {
        50: '#F0F9FF',
        500: '#3B82F6',
        900: '#1E3A8A'
      },
      text: {
        primary: '#0F172A',
        secondary: '#64748B'
      }
    },
    typography: {
      fontFamily: {
        body: '"Inter", system-ui, sans-serif',
        heading: '"Playfair Display", serif'
      }
    }
  }
};

// Use custom theme
<HydrogenUIProvider 
  tokens={baseTokens} 
  theme={myCustomTheme}
>
  <App />
</HydrogenUIProvider>
```

### Theme Persistence

Themes are automatically persisted to localStorage and restored on page load:

```tsx
// Theme preference saved as 'hydrogen-ui-theme'
localStorage.getItem('hydrogen-ui-theme'); // 'studio'

// Disable persistence
<HydrogenUIProvider 
  tokens={tokens} 
  theme="dawn"
  persistTheme={false}
>
  <App />
</HydrogenUIProvider>
```

## Server-Side Rendering

The package is SSR-safe with proper hydration support:

```tsx
// app/root.tsx (Remix example)
export default function App() {
  return (
    <html>
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <HydrogenUIProvider tokens={tokens} theme="dawn">
          <Outlet />
        </HydrogenUIProvider>
        <Scripts />
      </body>
    </html>
  );
}
```

## TypeScript Support

### Token Type Safety

```typescript
import type { TokenPath, TokenValue } from '@hydrogen-ui/core';

// Type-safe token paths
const getColor = (path: TokenPath): TokenValue => {
  return useTokenValue(path);
};

// Custom token types
interface MyTokens {
  color: {
    brand: string;
    accent: string;
  };
}

const tokens: MyTokens = {
  color: {
    brand: '#FF6B6B',
    accent: '#4ECDC4'
  }
};
```

### Provider Types

```typescript
import type { 
  HydrogenUIProviderProps,
  Theme,
  ThemeContextValue,
  TokenCache 
} from '@hydrogen-ui/core';

// Custom provider wrapper
const MyProvider: React.FC<HydrogenUIProviderProps> = (props) => {
  return <HydrogenUIProvider {...props} />;
};
```

## Performance Optimization

### Memoization

Token lookups are memoized at multiple levels:

1. **Provider level** - Merged tokens are memoized
2. **Hook level** - Token paths are memoized with useMemo
3. **Cache level** - LRU cache with configurable TTL

### Bundle Size

The core package is optimized for tree-shaking:

```javascript
// Only import what you need
import { useTokenValue } from '@hydrogen-ui/core';

// Tree-shakeable theme imports
import { dawn } from '@hydrogen-ui/themes/dawn';
```

## Migration Guide

### From CSS Variables

```css
/* Before */
:root {
  --primary-color: #FF6B6B;
  --spacing-md: 16px;
}

.button {
  background: var(--primary-color);
  padding: var(--spacing-md);
}
```

```tsx
// After
const tokens = {
  color: { primary: { base: '#FF6B6B' } },
  spacing: { md: '16px' }
};

function Button() {
  const bg = useTokenValue('color.primary.base');
  const padding = useTokenValue('spacing.md');
  
  return <button style={{ background: bg, padding }}>Click</button>;
}
```

### From Theme Context

```tsx
// Before
const theme = useContext(ThemeContext);
const color = theme.colors.primary;

// After
const color = useTokenValue('color.primary');
```

## Best Practices

1. **Use Token Values** - Prefer `useTokenValue` over `useToken` for simple value access
2. **Cache Strategy** - Use long cache for static tokens, short cache for dynamic values
3. **Theme Structure** - Keep theme tokens flat for better performance
4. **Token Naming** - Use consistent naming: category.property.variant
5. **Type Safety** - Define custom token types for better TypeScript support

## Contributing

See [Contributing Guide](../../CONTRIBUTING.md)

## License

MIT