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

3.7 KiB

@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

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.

<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.

<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.

<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

<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:

/* 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);
}
  • @manacore/shared-theme - Theme store and utilities
  • @manacore/shared-tailwind - Tailwind preset with theme CSS
  • @manacore/shared-icons - Icon components