// contexts/index.ts
import { getContext, hasContext, setContext } from 'svelte';
export const create = <Context>(identifier: string) => {
const key = Symbol();
return {
set(context: Context) {
return setContext<Context>(key, context);
},
get() {
if (hasContext(key)) {
return getContext<Context>(key);
}
throw new Error(`${identifier} context was never set`);
}
};
};
usage:
// contexts/theme/types.ts
import type { Writable } from 'svelte/store';
export type Theme = 'light' | 'dark';
export type ThemeContext = Writable<Theme>;
// contexts/theme/index.ts
import type { ThemeContext } from '$lib/contexts/theme/types.ts';
import type { Writable } from 'svelte/store';
import { create } from '$lib/contexts';
export const { get, set } = create<ThemeContext>('theme');
<!-- components/Theme.svelte -->
<script lang="ts">
import type { Theme } from '$lib/contexts/theme/types';
import { set } from '$lib/contexts/theme';
import { writable } from 'svelte/store';
const theme = writable<Theme>('light');
set(theme);
const toDark = () => { theme.set('dark'); };
<script>
<button type="button" on:click={toDark}>dark</button>
<!-- components/P.svelte -->
<script lang="ts">
import { get } from '$lib/contexts/theme';
const theme = get();
</script>
<p>{$theme}</p>
<!-- +page.svelte -->
<script lang="ts">
import P from '$lib/components/P.svelte';
import Theme from '$lib/components/Theme.svelte';
<Theme />
<P />