Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/docs/constants/docs.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,14 @@ export const COMPONENT_ROUTES: ComponentRoute[] = [
"Displays content in a column on mobile devices and in a row on desktops.",
},

{
path: "/components/system-theme-listener",
title: "System Theme Listener",

description:
"A component that listens to changes in the users system/OS theme..",
},

{
path: "/components/tag",
title: "Tag",
Expand Down
1 change: 1 addition & 0 deletions src/lib/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export { default as Spinner } from "./components/Spinner.svelte";
export { default as SplitBlock } from "./components/SplitBlock.svelte";
export { default as SplitContent } from "./components/SplitContent.svelte";
export { default as SplitPane } from "./components/SplitPane.svelte";
export { default as SystemThemeListener } from "./components/SystemThemeListener.svelte";
export { default as Tag } from "./components/Tag.svelte";
export { default as ThemeToggle } from "./components/ThemeToggle.svelte";
export { default as ThemeToggleButton } from "./components/ThemeToggleButton.svelte";
Expand Down
32 changes: 32 additions & 0 deletions src/lib/components/SystemThemeListener.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script lang="ts">
import { onDestroy, onMount } from "svelte";
import { themeStore } from "$lib";
import { LOCALSTORAGE_THEME_KEY } from "$lib/utils/theme.utils.js";

export let nnsOnChange: undefined | ((isDarkMode: boolean) => void);

// Set up our MediaQueryList
const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)");

// Update the store if OS preference changes
const updateThemeOnChange = () => {
if (nnsOnChange) {
nnsOnChange(prefersDarkMode.matches);
} else {
// Only reset to system theme if no specific preference has been selected
if (window.localStorage.getItem(LOCALSTORAGE_THEME_KEY) !== null) return;

themeStore.resetToSystemSettings();
}
};

// Register change event on mount
onMount(() =>
prefersDarkMode.addEventListener("change", updateThemeOnChange),
);

// Clean up if this component is destroyed
onDestroy(() =>
prefersDarkMode.removeEventListener("change", updateThemeOnChange),
);
</script>
27 changes: 27 additions & 0 deletions src/routes/(split)/components/system-theme-listener/+page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# System Theme Listener

A component that listens to changes in the users system/OS theme.

# Usage

```javascript
<SystemThemeListener />
```

> By default, the newly selected theme will be saved in themeStore (as long as a theme has not been explicitly selected / system setting is selected).
>
> You may also pass a custom event handler which overrides the default behavior

```javascript
<SystemThemeListener
nnsOnChange={(prefersDarkMode) =>
console.log(`User selected ${prefersDarkMode ? "dark" : "light"} mode`)
}
/>
```

## Properties

| Property | Description | Type | Default |
| ------------- | ------------------------------------------------------------------- | ------------------------------------ | ------- |
| `nnsOnChange` | Override default behavior of savng the selected theme to themeStore | `(prefersDarkMode: boolean) => void` | |
Loading