Dark Mode
Enabling Dark Mode
Section titled “Enabling Dark Mode”Set the data-theme="dark" attribute on any ancestor element. All AWC UI components within that subtree will automatically use dark color tokens.
<!-- Global dark mode --><html data-theme="dark"> <body> <md-button variant="filled">Dark Button</md-button> </body></html><!-- Scoped dark mode (only affects children) --><div data-theme="dark" style="padding: 24px; background: var(--md-sys-color-surface);"> <md-button variant="filled">Dark Section</md-button></div>JavaScript Toggle
Section titled “JavaScript Toggle”function toggleTheme() { const html = document.documentElement; const isDark = html.getAttribute('data-theme') === 'dark'; html.setAttribute('data-theme', isDark ? '' : 'dark');}With System Preference
Section titled “With System Preference”Respect the user’s OS-level theme preference:
// Check system preferenceconst prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : '');
// Listen for changeswindow.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { document.documentElement.setAttribute('data-theme', e.matches ? 'dark' : '');});With localStorage Persistence
Section titled “With localStorage Persistence”const THEME_KEY = 'awc-ui-theme';
function initTheme() { const saved = localStorage.getItem(THEME_KEY); if (saved) { document.documentElement.setAttribute('data-theme', saved); } else { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : ''); }}
function toggleTheme() { const isDark = document.documentElement.getAttribute('data-theme') === 'dark'; const newTheme = isDark ? '' : 'dark'; document.documentElement.setAttribute('data-theme', newTheme); localStorage.setItem(THEME_KEY, newTheme);}
initTheme();Dark Mode Token Overrides
Section titled “Dark Mode Token Overrides”The default dark palette is defined in @awc-ui/tokens. Key differences:
| Token | Light | Dark |
|---|---|---|
--md-sys-color-primary | #6750A4 | #D0BCFF |
--md-sys-color-on-primary | #FFFFFF | #381E72 |
--md-sys-color-surface | #FFFBFE | #1C1B1F |
--md-sys-color-on-surface | #1C1B1F | #E6E1E5 |
--md-sys-color-error | #B3261E | #F2B8B5 |
--md-sys-color-outline | #79747E | #938F99 |
Custom Dark Palette
Section titled “Custom Dark Palette”Override dark tokens by targeting the [data-theme="dark"] selector:
[data-theme="dark"] { --md-sys-color-primary: #A8D5BA; --md-sys-color-on-primary: #1B3A2A; --md-sys-color-primary-container: #2E5A3F; --md-sys-color-on-primary-container: #C4F1D5; --md-sys-color-surface: #121212; --md-sys-color-on-surface: #E0E0E0;}Technology Examples
Section titled “Technology Examples”A reusable dark-mode toggle using AWC UI’s <md-switch> — same behaviour in
every technology: track an isDark state, mirror it onto
document.documentElement as data-theme="dark", and react to changes through
the component’s mdChange event.
<script type="module">
import { defineCustomElements } from '@awc-ui/core/loader';
defineCustomElements(window);
</script>
<md-switch id="theme-toggle" icons aria-label="Toggle dark mode"></md-switch>
<script>
const toggle = document.getElementById('theme-toggle');
toggle.addEventListener('mdChange', (e) => {
document.documentElement.setAttribute(
'data-theme',
e.detail.selected ? 'dark' : ''
);
});
</script>import { useEffect, useState } from 'react';
import { MdSwitch } from '@awc-ui/react';
export function ThemeToggle() {
const [isDark, setIsDark] = useState(false);
useEffect(() => {
document.documentElement.setAttribute(
'data-theme',
isDark ? 'dark' : ''
);
}, [isDark]);
return (
<MdSwitch
selected={isDark}
icons
onMdChange={(e) => setIsDark(e.detail.selected)}
aria-label="Toggle dark mode"
/>
);
}import { Component, signal, effect, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@Component({
selector: 'theme-toggle',
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
<md-switch
[selected]="isDark()"
icons
aria-label="Toggle dark mode"
(mdChange)="onChange($event)"
></md-switch>
`,
})
export class ThemeToggleComponent {
isDark = signal(false);
constructor() {
effect(() => {
document.documentElement.setAttribute(
'data-theme',
this.isDark() ? 'dark' : ''
);
});
}
onChange(e: Event) {
const { detail } = e as CustomEvent<{ selected: boolean }>;
this.isDark.set(detail.selected);
}
}<script setup>
import { ref, watchEffect } from 'vue';
import '@awc-ui/core/define';
const isDark = ref(false);
watchEffect(() => {
document.documentElement.setAttribute(
'data-theme',
isDark.value ? 'dark' : ''
);
});
</script>
<template>
<md-switch
:selected="isDark"
icons
aria-label="Toggle dark mode"
@md-change="isDark = $event.detail.selected"
/>
</template><script>
import '@awc-ui/core/define';
let isDark = false;
$: document.documentElement.setAttribute(
'data-theme',
isDark ? 'dark' : ''
);
function onChange(e) {
isDark = e.detail.selected;
}
</script>
<md-switch
selected={isDark}
icons
aria-label="Toggle dark mode"
on:mdChange={onChange}
/>