일반 Svelte와 마찬가지로, 다크 모드 전환을 지원하기 위해 Tailwind CSS의 class 전략을 사용합니다. 자세한 내용은 Tailwind CSS 문서를 참조하세요.
html 엘리먼트에 dark 클래스를 추가하는 방법은 자유롭게 선택할 수 있습니다. 이 가이드에서는 mode-watcher를 사용하여 다크 모드 전환을 활성화하는 방법을 살펴보겠습니다.
사용법
인라인 테마 스크립트 생성
이 스크립트는 localStorage에 다크 모드 값을 저장하고 추적하며, FUOC를 방지하는 역할을 합니다.
---
import "../styles/global.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> mode-watcher 설치
ModeWatcher 컴포넌트 추가
ModeWatcher 컴포넌트를 import하고 client:load 디렉티브와 함께 페이지에서 사용하세요:
---
import "../styles/global.css";
import { ModeWatcher } from "mode-watcher";
---
<!-- inline-script -->
<html lang="en">
<body>
<h1>Astro</h1>
<ModeWatcher client:load />
</body>
</html> 모드 토글 생성
사이트에서 라이트 모드와 다크 모드를 전환할 수 있는 모드 토글을 생성하세요:
라이트 스위치
<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] scale-100 rotate-0 !transition-all dark:scale-0 dark:-rotate-90"
/>
<MoonIcon
class="absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 !transition-all dark:scale-100 dark:rotate-0"
/>
<span class="sr-only">Toggle theme</span>
</Button> 드롭다운 메뉴
<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] scale-100 rotate-0 !transition-all dark:scale-0 dark:-rotate-90"
/>
<MoonIcon
class="absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 !transition-all dark:scale-100 dark:rotate-0"
/>
<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> 페이지에 모드 토글 추가
모드 토글을 페이지에 추가하세요 (client:load 디렉티브와 함께):
---
import "../styles/global.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>