Get Started
Migration
Components
- Accordion
- Alert Dialog
- Alert
- Aspect Ratio
- Avatar
- Badge
- Breadcrumb
- Button
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Formsnap
- Hover Card
- Input OTP
- Input
- Label
- Menubar
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Range Calendar
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Switch
- Table
- Tabs
- Textarea
- Toggle Group
- Toggle
- Tooltip
- Typography
Installation
Special sponsor
We're looking for one partner to be featured here.
Support the project and reach thousands of developers.
Reach outJust like in regular Svelte, we use the class
strategy from Tailwind CSS to support dark mode toggling. See the Tailwind CSS documentation for more information.
How you add the dark
class to the html
element is up to you. In this guide, we'll take a look at enabling dark mode toggling with mode-watcher.
Usage
Create an inline theme script
This script will, in part, keep and track the dark mode value in localStorage
and prevent FUOC.
---
import "$lib/styles/app.css";
---
<script is:inline>
const isBrowser = typeof localStorage !== 'undefined';
const getThemePreference = () => {
if (isBrowser && localStorage.getItem('theme')) {
return localStorage.getItem('theme');
}
return window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark' : 'light';
};
const isDark = getThemePreference() === 'dark';
document.documentElement.classList[isDark ? 'add' : 'remove']('dark');
if (isBrowser) {
const observer = new MutationObserver(() => {
const isDark = document.documentElement.classList.contains('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
}
</script>
<html lang="en">
<body>
<h1>Astro</h1>
</body>
</html>
</script>
Install mode-watcher
pnpm i mode-watcher@0.5.1
npm i mode-watcher@0.5.1
bun install mode-watcher@0.5.1
yarn install mode-watcher@0.5.1
Add the ModeWatcher component
Import the ModeWatcher
component and use it in your page with the client:load
directive:
---
import "$lib/styles/app.css";
import { ModeWatcher } from "mode-watcher";
---
<!-- inline-script -->
<html lang="en">
<body>
<h1>Astro</h1>
<ModeWatcher client:load />
</body>
</html>
Create a mode toggle
Create a mode toggle on your site to toggle between light and dark mode:
Light switch
<script lang="ts">
import SunIcon from "@lucide/svelte/icons/sun";
import MoonIcon from "@lucide/svelte/icons/moon";
import { toggleMode } from "mode-watcher";
import { Button } from "$lib/components/ui/button/index.js";
</script>
<Button onclick={toggleMode} variant="outline" size="icon">
<SunIcon
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
/>
<MoonIcon
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
/>
<span class="sr-only">Toggle theme</span>
</Button>
Dropdown menu
<script lang="ts">
import SunIcon from "@lucide/svelte/icons/sun";
import MoonIcon from "@lucide/svelte/icons/moon";
import { resetMode, setMode } from "mode-watcher";
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import { buttonVariants } from "$lib/components/ui/button/index.js";
</script>
<DropdownMenu.Root>
<DropdownMenu.Trigger
class={buttonVariants({ variant: "outline", size: "icon" })}
>
<SunIcon
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
/>
<MoonIcon
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
/>
<span class="sr-only">Toggle theme</span>
</DropdownMenu.Trigger>
<DropdownMenu.Content align="end">
<DropdownMenu.Item onclick={() => setMode("light")}>Light</DropdownMenu.Item
>
<DropdownMenu.Item onclick={() => setMode("dark")}>Dark</DropdownMenu.Item>
<DropdownMenu.Item onclick={() => resetMode()}>System</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
Add mode toggle to page
Add the mode toggle to the page (also with the client:load
directive):
---
import "$lib/styles/app.css";
import { ModeWatcher } from "mode-watcher";
import ModeToggle from "$lib/components/mode-toggle.svelte";
---
<!-- inline-script -->
<html lang="en">
<body>
<h1>Astro</h1>
<ModeWatcher client:load />
<ModeToggle client:load />
</body>
</html>