UI Controls

ThemeToggle

Dark/light mode toggle button. Works with mode-watcher for persistent theme preference.

Props

No props - uses internal state.

Import

import { ThemeToggle } from '@the-vcsi/scrolly-kit';

Usage

<script>
  import { ThemeToggle } from '@the-vcsi/scrolly-kit';
</script>

<ThemeToggle />

Full Source

💡 Components rely on --vcsi-* tokens from tokens.css. You'd need to either need to @import '@the-vcsi/scrolly-kit/styles/tokens.css'; to access the CSS variables or define equivalent variables in your app.css. We also are using types here to provide hints when users are using the components in their project.

<script lang="ts">
  import { toggleMode, mode } from 'mode-watcher';
  import { Sun, Moon } from '@lucide/svelte';
</script>

<button onclick={toggleMode} class="theme-toggle" aria-label="Toggle dark mode">
  {#if mode.current === 'dark'}
    <Sun size={20} />
  {:else}
    <Moon size={20} />
  {/if}
</button>

<style>
  .theme-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.5rem;
    background: transparent;
    color: var(--vcsi-nav-fg);
    border: none;
    cursor: pointer;
    transition: all var(--vcsi-transition-base, 200ms ease);
  }

  .theme-toggle:hover {
    background: rgba(0, 0, 0, 0.05);
    transform: scale(1.1);
  }

  :global(.dark) .theme-toggle:hover {
    background: rgba(255, 255, 255, 0.1);
  }

  /* Mobile: match icon-button sizing in Nav */
  @media (max-width: 768px) {
    .theme-toggle {
      width: 3.5rem;
      height: 3.5rem;
    }

    .theme-toggle :global(svg) {
      width: 24px;
      height: 24px;
    }
  }
</style>