Skip to main content

Stores

Stores

Svelte 5 runes-based state management stores

Tags: utility state store

The theme library includes reactive state stores built with Svelte 5 runes for managing common application state.

Available Stores​

Store Purpose
toastStore Toast notification management
sidebarStore Sidebar state and persistence
themeStore Theme/dark mode preference

Toast Store​

Manage toast notifications with auto-dismiss and convenience methods.

Import​

<script>
  import { toastStore } from '@classic-homes/theme-svelte';
</script>

Basic Usage​

<script>
  function handleSave() {
    // Show success toast
    toastStore.success('Changes saved successfully');
  }

  function handleError() {
    // Show error toast (persists by default)
    toastStore.error('Failed to save changes');
  }
</script>

Methods​

// Add a toast (returns toast ID)
toastStore.add({
  message: 'Hello!',
  type: 'info',
  title: 'Notification',
  duration: 5000, // 0 for persistent
});

// Convenience methods
toastStore.success('Success message');
toastStore.error('Error message');
toastStore.warning('Warning message');
toastStore.info('Info message');

// With options
toastStore.success('Saved!', { title: 'Success', duration: 3000 });

// Remove a specific toast
toastStore.remove(toastId);

// Clear all toasts
toastStore.clear();

// Update an existing toast
toastStore.update(toastId, { message: 'Updated message' });

Accessing Toasts​

<script>
  import { toastStore } from '@classic-homes/theme-svelte';
</script>

<!-- Access the reactive toasts array -->
{#each toastStore.toasts as toast}
  <div>{toast.message}</div>
{/each}

Toast Types​

interface Toast {
  id: string;
  message: string;
  type: 'success' | 'error' | 'warning' | 'info';
  title?: string;
  duration?: number;
}

Manage sidebar state with persistence to localStorage.

Import​

<script>
  import { sidebarStore } from '@classic-homes/theme-svelte';
</script>

Basic Usage​

<script>
  import { sidebarStore } from '@classic-homes/theme-svelte';

  // Initialize on mount (loads persisted state)
  $effect(() => {
    sidebarStore.initialize();
  });
</script>

<button onclick={() => sidebarStore.toggle()}>
  {sidebarStore.isOpen ? 'Close' : 'Open'} Sidebar
</button>

Methods​

// Initialize (call once, loads from localStorage)
sidebarStore.initialize();

// Toggle open/closed
sidebarStore.toggle();

// Explicit open/close
sidebarStore.open();
sidebarStore.close();

// Mobile mode
sidebarStore.setMobile(true);

// Section expansion
sidebarStore.toggleSection('section-id');
sidebarStore.isSectionExpanded('section-id');

// Item expansion (nested navigation)
sidebarStore.toggleItem('item-id');
sidebarStore.isItemExpanded('item-id');

// Set defaults (for initial render)
sidebarStore.setDefaultSections(['section1', 'section2']);
sidebarStore.setDefaultItems(['item1']);

// Force expand (for search filtering)
sidebarStore.forceExpandSections(['section1']);
sidebarStore.forceExpandItems(['item1']);

Properties​

// Reactive state
sidebarStore.isOpen; // boolean
sidebarStore.isMobile; // boolean
sidebarStore.expandedSections; // Set<string>
sidebarStore.expandedItems; // Set<string>

// Status
sidebarStore.initialized; // boolean
sidebarStore.hasPersistedState; // boolean
sidebarStore.hasPersistedExpansionState; // boolean

Persistence​

The sidebar store automatically persists to localStorage:

  • classic-theme-sidebar-open - Open/closed state
  • classic-theme-sidebar-sections - Expanded sections
  • classic-theme-sidebar-items - Expanded items

Theme Store​

Manage light/dark theme preference.

Import​

<script>
  import { themeStore } from '@classic-homes/theme-svelte';
</script>

Basic Usage​

<script>
  import { themeStore } from '@classic-homes/theme-svelte';

  $effect(() => {
    themeStore.initialize();
  });
</script>

<button onclick={() => themeStore.toggle()}>
  {themeStore.theme === 'dark' ? '☀️' : '🌙'}
</button>

Methods​

// Initialize (loads from localStorage, respects system preference)
themeStore.initialize();

// Toggle between light and dark
themeStore.toggle();

// Set specific theme
themeStore.setTheme('dark');
themeStore.setTheme('light');
themeStore.setTheme('system');

Properties​

themeStore.theme; // 'light' | 'dark' | 'system'
themeStore.resolvedTheme; // 'light' | 'dark' (actual applied theme)

Creating Custom Stores​

Build your own runes-based stores:

// stores/counter.svelte.ts
class CounterStore {
  count = $state(0);

  increment() {
    this.count++;
  }

  decrement() {
    this.count--;
  }

  reset() {
    this.count = 0;
  }
}

export const counterStore = new CounterStore();

Usage:

<script>
  import { counterStore } from './stores/counter.svelte';
</script>

<p>Count: {counterStore.count}</p>
<button onclick={() => counterStore.increment()}>+</button>

Best Practices​

  1. Initialize in layout: Call initialize() in root layout
  2. Use convenience methods: Prefer toastStore.success() over toastStore.add()
  3. Check persistence: Use hasPersistedState before setting defaults
  4. Mobile awareness: Use setMobile() based on media queries
On this page