A custom element that allows you to toggle between light, dark and system theme.
Below are examples of different configurations and use cases of the <theme-toggle>
component.
This is the default configuration. The element will use the system theme by default.
<theme-toggle></theme-toggle>
You can customize the slots to display your own labels and icons.
<theme-toggle>
<span slot="icon-light" aria-hidden="true">☀️</span>
<span slot="label-light">Light</span>
<span slot="icon-dark" aria-hidden="true">🌙</span>
<span slot="label-dark">Dark</span>
<span slot="icon-system" aria-hidden="true">🌓</span>
<span slot="label-system">System</span>
</theme-toggle>
You can hide the label using the no-label
attribute.
For accessibility reasons, the label is visually hidden but still available to screen readers.
<theme-toggle no-label></theme-toggle>
You can hide the icon using the no-icon
attribute.
<theme-toggle no-icon></theme-toggle>
You can customize the styling of the element by using CSS Parts. The following example uses Water.css for styling.
<style>
theme-toggle.custom-toggle::part(base) {
border: 1px solid var(--border);
border-radius: var(--border-radius);
padding: 0.5rem 0.75rem;
background-color: var(--button-base);
font-size: 1.5rem;
transition: background-color var(--animation-duration) ease-in-out;
}
@media (hover: hover) {
theme-toggle.custom-toggle::part(base):hover {
background-color: var(--button-hover);
}
}
</style>
<theme-toggle class="custom-toggle"></theme-toggle>
You can listen for the tt-theme-change
event to get notified when the theme changes.
The event will contain the newly selected theme in the detail
property.
<theme-toggle></theme-toggle>
<script>
const themeToggle = document.querySelector('theme-toggle');
themeToggle.addEventListener('tt-theme-change', event => {
console.log(event.detail); // => {theme: 'light' | 'dark' | 'system'}
});
</script>