managarten/packages/shared-theme-ui/README.md
Till-JS 96e0aceb93 feat: implement unified theme system across all web apps
SUMMARY:
Create a unified theming architecture with two new shared packages
(@manacore/shared-theme and @manacore/shared-theme-ui) that provides
consistent theming across all 4 web applications while allowing
app-specific primary color customization.

NEW PACKAGES:

@manacore/shared-theme:
- Svelte 5 Runes-based theme store factory
- 4 theme variants: Lume (Gold), Nature (Green), Stone (Blue Gray), Ocean (Blue)
- 3 theme modes: Light, Dark, System (auto-detect)
- HSL-based color system with 18 semantic tokens
- localStorage persistence per app
- System preference detection via matchMedia
- Pre-defined configs for all apps (memoro, manacore, manadeck, maerchenzauber)

@manacore/shared-theme-ui:
- ThemeToggle: Light/dark mode toggle button
- ThemeSelector: Visual theme variant selector with color dots
- ThemeModeSelector: Segmented control for light/dark/system

UPDATED PACKAGES:

@manacore/shared-tailwind:
- Converted from HEX to HSL-based CSS variables
- Updated preset.js with hsl(var(--color-*)) syntax
- themes.css now contains all 4 theme variants with light/dark modes

APP MIGRATIONS:

memoro/web:
- Replaced 145 LOC theme store with 25 LOC shared implementation
- Deleted local ThemeSelector.svelte and ThemeToggle.svelte
- Primary color: Gold (47 95% 58%)

manacore/web:
- Replaced 80 LOC theme store with 25 LOC shared implementation
- Deleted local ThemeToggle.svelte
- Primary color: Indigo (239 84% 67%)

manadeck/web:
- Added new theme store using shared package
- Primary color: Indigo (239 84% 67%)

maerchenzauber/web:
- Added new theme store using shared package
- Primary color: Purple (280 60% 55%)

All app layouts updated with theme.initialize() in onMount.

BENEFITS:
- ~225 LOC of app-specific code reduced to ~100 LOC total
- Single source of truth for theme logic
- Consistent theming experience across all apps
- Easy to add new theme variants
- App-specific primary colors preserved

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 21:51:24 +01:00

170 lines
3.7 KiB
Markdown

# @manacore/shared-theme-ui
Svelte UI components for theme switching. Works with `@manacore/shared-theme`.
## Features
- **ThemeToggle**: Simple light/dark mode toggle button
- **ThemeSelector**: Visual selector for theme variants
- **ThemeModeSelector**: Segmented control for light/dark/system
## Installation
```bash
pnpm add @manacore/shared-theme-ui
```
## Prerequisites
- `@manacore/shared-theme` - Theme store
- `@manacore/shared-icons` - Icon components
## Components
### ThemeToggle
A simple button that toggles between light and dark mode.
```svelte
<script lang="ts">
import { theme } from '$lib/stores/theme';
import { ThemeToggle } from '@manacore/shared-theme-ui';
</script>
<ThemeToggle {theme} />
<!-- With options -->
<ThemeToggle
{theme}
size={24}
showTooltip={true}
class="my-custom-class"
/>
```
#### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `theme` | `ThemeStore` | required | Theme store instance |
| `size` | `number` | `20` | Icon size in pixels |
| `showTooltip` | `boolean` | `false` | Show tooltip on hover |
| `class` | `string` | `''` | Additional CSS classes |
### ThemeSelector
A visual selector showing all theme variants with color dots.
```svelte
<script lang="ts">
import { theme } from '$lib/stores/theme';
import { ThemeSelector } from '@manacore/shared-theme-ui';
</script>
<ThemeSelector {theme} />
<!-- With options -->
<ThemeSelector
{theme}
showLabels={true}
showEmoji={true}
compact={false}
class="my-custom-class"
/>
```
#### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `theme` | `ThemeStore` | required | Theme store instance |
| `showLabels` | `boolean` | `true` | Show variant labels |
| `showEmoji` | `boolean` | `true` | Show variant emojis |
| `compact` | `boolean` | `false` | Compact mode (smaller buttons) |
| `class` | `string` | `''` | Additional CSS classes |
### ThemeModeSelector
A segmented control for selecting light, dark, or system mode.
```svelte
<script lang="ts">
import { theme } from '$lib/stores/theme';
import { ThemeModeSelector } from '@manacore/shared-theme-ui';
</script>
<ThemeModeSelector {theme} />
<!-- With options -->
<ThemeModeSelector
{theme}
class="my-custom-class"
/>
```
#### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `theme` | `ThemeStore` | required | Theme store instance |
| `class` | `string` | `''` | Additional CSS classes |
## Complete Example
```svelte
<script lang="ts">
import { theme } from '$lib/stores/theme';
import {
ThemeToggle,
ThemeSelector,
ThemeModeSelector
} from '@manacore/shared-theme-ui';
</script>
<div class="settings-panel">
<h3>Appearance</h3>
<!-- Quick toggle in header -->
<div class="header">
<ThemeToggle {theme} showTooltip />
</div>
<!-- Mode selection -->
<section>
<label>Mode</label>
<ThemeModeSelector {theme} />
</section>
<!-- Variant selection -->
<section>
<label>Color Theme</label>
<ThemeSelector {theme} />
</section>
</div>
```
## Styling
All components use CSS variables from `@manacore/shared-tailwind/themes.css` and are fully theme-aware. They automatically adapt to the current theme variant and mode.
### Custom Styling
You can override styles using the `class` prop or by targeting the component classes:
```css
/* Custom toggle button */
.theme-toggle {
background-color: var(--my-custom-bg);
}
/* Custom selector buttons */
.variant-button.active {
box-shadow: 0 0 0 2px var(--my-custom-ring);
}
```
## Related Packages
- `@manacore/shared-theme` - Theme store and utilities
- `@manacore/shared-tailwind` - Tailwind preset with theme CSS
- `@manacore/shared-icons` - Icon components