Переключатель темы
На этой странице
sitelo-ui сам определяет тёмный режим по prefers-color-scheme: сайту, которого устраивает следовать за операционной системой, с этой страницы не нужно ничего. Переключатель нужен, чтобы читатель мог это переопределить.
Это один из пяти компонентов, которым нужен скрипт, потому что выбор живёт в localStorage, а прочитать его может только скрипт. Кнопка сама подгружает этот скрипт при первом нажатии.
Подключение
Две вещи в head и кнопка там, где ей место:
import { styles, themeScript, themeToggle } from 'sitelo/ui'
head(
themeScript(), // применяет сохранённый выбор до первой отрисовки
styles(),
)
body(
appBar({ brand: 'Мой сайт' },
appBarSpacer(),
appBarActions(themeToggle()),
),
)Третьего файла нет. themeScript() намеренно блокирующий и встроенный — всё отложенное рисуется раньше, а это и есть та самая тёмная вспышка, ради предотвращения которой он существует, — а само переключение едет на кнопке:
<button data-su-theme-toggle
onclick="import('/su/theme.js').then(m=>m.toggle(this))">Используйте их в паре. themeScript() заодно и проставляет переключателю aria-pressed при загрузке: ведь ничего ещё не нажимали, и сама кнопка не может знать, какая тема получилась.
Сам переключатель
Иконка — чистый CSS, считанный прямо с атрибута темы, поэтому она верна уже при первой отрисовке, до запуска любого скрипта. Она показывает, на что переключит клик.
stack({ direction: 'row', gap: 'md', align: 'center' },
themeToggle(),
themeToggle({ variant: 'soft' }),
themeToggle({ variant: 'outline' }),
)Эти кнопки работают — страница подгружает рантайм. Клик выставляет data-su-theme на <html> — это собственный атрибут sitelo-ui, поэтому меняются только компоненты sitelo-ui на этой странице. Остальной сайт следует своему data-theme, который задаёт переключатель в верхней панели. На вашем сайте он был бы один.
В панели приложения
appBar({ brand: 'sitelo' },
appBarNav(navLink({ href: '#docs', current: true }, 'Документация')),
appBarSpacer(),
appBarActions(
themeToggle(),
button({ size: 'sm' }, 'Начать'),
),
)Как определяется тема
По порядку: явный data-theme или data-su-theme на любом предке побеждает; если их нет, решает prefers-color-scheme. Оба имени атрибутов учитываются, чтобы sitelo-ui мог жить внутри сайта, у которого уже есть собственный переключатель темы, — ровно так и устроена эта документация.
Управлять самому
Рантайм экспортирует те же функции, которыми пользуется кнопка, — для собственного элемента управления или переключателя из трёх положений: светлая / тёмная / системная.
import { getTheme, setTheme, toggleTheme } from 'sitelo/ui/client'
getTheme() // 'light' | 'dark' — вычисленная, не сохранённая
toggleTheme() // переключить
setTheme('dark') // закрепить
setTheme('system') // снять переопределение и снова следовать за ОСПропсы
| Проп | Тип | По умолчанию | Описание |
|---|---|---|---|
label | string | 'Toggle dark mode' | Доступное имя и всплывающая подсказка. |
variant | 'solid' | 'soft' | 'outline' | 'ghost' | 'link' | 'ghost' | Вариант кнопки. |
color | 'primary' | 'neutral' | 'success' | 'warning' | 'danger' | 'neutral' | Из какой палитры брать цвета. |
themeScript() принимает необязательный nonce — для сайта с политикой безопасности содержимого.