hypnagaga/src/components/Theme/Theme.svelte
2022-08-28 10:16:15 +01:00

44 lines
1.4 KiB
Svelte

<!-- @component `Theme` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/theming-Theme--default) -->
<script context="module" lang="ts">
import light from './themes/light.js';
import dark from './themes/dark.js';
/**
* Pre-made themes you can import.
* @type {{ light, dark }}
*/
export const themes = { light, dark };
</script>
<script lang="ts">
import type { CustomTheme } from './@types/component';
/** Custom theme object. Can be a partial theme with just
* what you want to change.
*/
export let theme: CustomTheme = {};
type Base = 'light' | 'dark';
/**
* Base theme is one of `light` or `dark` and will be merged
* with your custom theme to fill in any values you don't
* explicitly set.
*/
export let base: Base = 'light';
import flatten from './utils/flatten';
import mergeThemes from './utils/merge';
/** @type {Theme} */
$: mergedTheme = mergeThemes({}, themes[base] || themes.light, theme);
$: cssVariables = Object.entries(flatten({ theme: mergedTheme }))
.map(([key, value]) => `--${key}: ${value};`)
.join(' ');
</script>
<div class="theme" style="{cssVariables}" style:display="contents">
<!-- Clients can override the theme above by attaching custom properties to this element. -->
<div class="theme-client-override" style="display: contents;">
<!-- Themed content -->
<slot />
</div>
</div>