mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-16 02:41:05 +00:00
feat(theme): add Theme (#741)
* feat(theme): add Theme * fix(theme): fix broken type test * docs(theme): add examples * docs(theme): add description, update carbon theme link [ci skip] * docs: pre-wrap type code snippet [ci skip]
This commit is contained in:
parent
18c6f03224
commit
fac78ee4aa
18 changed files with 475 additions and 4 deletions
118
src/Theme/Theme.svelte
Normal file
118
src/Theme/Theme.svelte
Normal file
|
@ -0,0 +1,118 @@
|
|||
<script>
|
||||
/**
|
||||
* Dynamic, client-side theming using CSS variables
|
||||
* Only works with `carbon-components-svelte/css/all.css`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {"white" | "g10" | "g80" | "g90" | "g100"} CarbonTheme
|
||||
* @event {{ theme: CarbonTheme; }} update
|
||||
* @slot {{ theme: CarbonTheme; }}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the current Carbon theme
|
||||
* @type {CarbonTheme}
|
||||
*/
|
||||
export let theme = "white";
|
||||
|
||||
/**
|
||||
* Customize a theme with your own tokens
|
||||
* https://carbondesignsystem.com/guidelines/themes/overview#customizing-a-theme
|
||||
* @type {{ [token: string]: any; }}
|
||||
*/
|
||||
export let tokens = {};
|
||||
|
||||
/** Set to `true` to persist the theme using window.localStorage */
|
||||
export let persist = false;
|
||||
|
||||
/** Specify the local storage key */
|
||||
export let persistKey = "theme";
|
||||
|
||||
/**
|
||||
* Render a toggle or select dropdown to control the theme
|
||||
* @type {"toggle" | "select"}
|
||||
*/
|
||||
export let render = undefined;
|
||||
|
||||
/**
|
||||
* Override the default toggle props
|
||||
* @type {import("../Toggle/Toggle").ToggleProps & { themes?: [labelA: CarbonTheme, labelB: CarbonTheme]; }}
|
||||
*/
|
||||
export let toggle = {
|
||||
themes: ["white", "g100"],
|
||||
labelA: "",
|
||||
labelB: "",
|
||||
labelText: "Dark mode",
|
||||
hideLabel: false,
|
||||
};
|
||||
|
||||
/** @type {Record<CarbonTheme, string>} */
|
||||
const themes = {
|
||||
white: "White",
|
||||
g10: "Gray 10",
|
||||
g80: "Gray 80",
|
||||
g90: "Gray 90",
|
||||
g100: "Gray 100",
|
||||
};
|
||||
|
||||
/** @type {CarbonTheme} */
|
||||
const themeKeys = Object.keys(themes);
|
||||
|
||||
/**
|
||||
* Override the default select props
|
||||
* @type {import("../Select/Select").SelectProps & { themes?: CarbonTheme[]; }}
|
||||
*/
|
||||
export let select = {
|
||||
themes: themeKeys,
|
||||
labelText: "Themes",
|
||||
hideLabel: false,
|
||||
};
|
||||
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import Toggle from "../Toggle/Toggle.svelte";
|
||||
import Select from "../Select/Select.svelte";
|
||||
import SelectItem from "../Select/SelectItem.svelte";
|
||||
import LocalStorage from "../LocalStorage/LocalStorage.svelte";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
$: if (typeof window !== "undefined") {
|
||||
Object.entries(tokens).forEach(([token, value]) => {
|
||||
document.documentElement.style.setProperty(`--cds-${token}`, value);
|
||||
});
|
||||
|
||||
if (theme in themes) {
|
||||
document.documentElement.setAttribute("theme", theme);
|
||||
dispatch("update", { theme });
|
||||
} else {
|
||||
console.warn(
|
||||
`[Theme.svelte] invalid theme "${theme}". Value must be one of: ${JSON.stringify(
|
||||
Object.keys(themes)
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if persist}
|
||||
<LocalStorage bind:value="{theme}" key="{persistKey}" />
|
||||
{/if}
|
||||
|
||||
{#if render === "toggle"}
|
||||
<Toggle
|
||||
{...toggle}
|
||||
toggled="{theme === toggle.themes[1]}"
|
||||
on:toggle="{({ detail }) => {
|
||||
theme = detail.toggled ? toggle.themes[1] : toggle.themes[0];
|
||||
}}"
|
||||
/>
|
||||
{:else if render === "select"}
|
||||
<Select {...select} bind:selected="{theme}">
|
||||
{#each select.themes as theme (theme)}
|
||||
<SelectItem value="{theme}" text="{themes[theme]}" />
|
||||
{/each}
|
||||
</Select>
|
||||
{/if}
|
||||
|
||||
<slot theme="{theme}" />
|
Loading…
Add table
Add a link
Reference in a new issue