|
1 | 1 | --- |
2 | 2 | import type { Props } from '@astrojs/starlight/props'; |
3 | | -import Default from '@astrojs/starlight/components/ThemeSelect.astro'; |
| 3 | +import { Icon } from '@astrojs/starlight/components'; |
4 | 4 | --- |
5 | 5 |
|
6 | | -<Default {...Astro.props}><slot /></Default> |
| 6 | +<script> |
| 7 | + class ThemeSwitcher extends HTMLElement { |
| 8 | + constructor() { |
| 9 | + super(); |
| 10 | + const storedTheme = |
| 11 | + typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme'); |
| 12 | + const theme = |
| 13 | + storedTheme || |
| 14 | + (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'); |
| 15 | + document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark'; |
| 16 | + this.handleMouseDown = this.handleMouseDown.bind(this); |
| 17 | + } |
| 18 | + connectedCallback() { |
| 19 | + this.addEventListener('click', this.handleMouseDown); |
| 20 | + } |
| 21 | + disconnectedCallback() { |
| 22 | + this.removeEventListener('click', this.handleMouseDown); |
| 23 | + } |
| 24 | + private handleMouseDown(e: MouseEvent) { |
| 25 | + const theme = document.documentElement.dataset.theme === 'light' ? 'dark' : 'light'; |
| 26 | + document.documentElement.dataset.theme = theme; |
| 27 | + localStorage.setItem('starlight-theme', theme); |
| 28 | + } |
| 29 | + } |
| 30 | + customElements.define('theme-switcher', ThemeSwitcher); |
| 31 | +</script> |
| 32 | + |
| 33 | +<theme-switcher class="sl-flex"> |
| 34 | + <Icon name="sun" class="theme-selector-light" /> |
| 35 | + <Icon name="moon" class="theme-selector-dark" /> |
| 36 | +</theme-switcher> |
| 37 | + |
| 38 | +<style> |
| 39 | + theme-switcher { |
| 40 | + align-items: center; |
| 41 | + } |
| 42 | + .theme-selector-light, |
| 43 | + .theme-selector-dark { |
| 44 | + user-select: none; |
| 45 | + z-index: 999999; |
| 46 | + position: relative; |
| 47 | + cursor: pointer; |
| 48 | + } |
| 49 | + .theme-selector-light:hover, |
| 50 | + .theme-selector-dark:hover { |
| 51 | + color: var(--sl-color-accent-high); |
| 52 | + } |
| 53 | + :root { |
| 54 | + .theme-selector-light { |
| 55 | + display: none; |
| 56 | + } |
| 57 | + .theme-selector-dark { |
| 58 | + display: inline-block; |
| 59 | + } |
| 60 | + } |
| 61 | + :root[data-theme='light'] { |
| 62 | + .theme-selector-light { |
| 63 | + display: inline-block; |
| 64 | + } |
| 65 | + .theme-selector-dark { |
| 66 | + display: none; |
| 67 | + } |
| 68 | + .theme-selector-light:hover, |
| 69 | + .theme-selector-dark:hover { |
| 70 | + color: var(--sl-color-accent); |
| 71 | + } |
| 72 | + } |
| 73 | +</style> |
0 commit comments