Image: Monarch Butterfly hatched from a cocoon.
A lightweight browser native way to switch color themes. ThemeIT!
follows the Modern Web implementation for css theming and leverages the awesome power of CSS
variables and HTML
link element + with Javascript
to allow theme customization inside of your web app, react app or website.
@themeit/native
Detail | Value |
---|---|
Version | 1.1.1 |
Size | 5.0 kB |
Size (gzip) | 2.0 kB |
SHASUM | 7aa83b7f67a48d3612dd535c1ec073a3c940223f |
Dependency (count) | 0 |
@themeit/react
Detail | Value |
---|---|
Version | 1.1.1 |
Size | 3.7 kB |
Size (gzip) | 1.7 kB |
SHASUM | acc3e0e127a8437e13878960917a939482b67e46 |
Dependency (count) | 2 |
npm install @themeit/native
npm install @themeit/react # If you support React
yarn add @themeit/native
yarn add @themeit/react # If you support React
- Prepare your
CSS
by separating each theme into it's ownCSS
file. - Use the
:root
pseudo-class for setting all variables. - Make sure that all variables match.
You can look at the
examples/
directory to get a visual representations of what needs to be done
- Add all CSS theme files inside of your HTML file.
- Set the
media(prefers-color-scheme: <name>)
attribute for each theme - For the main theme please set the following
(prefers-color-scheme: light)
as themedia
attribute.
Important when setting the
(prefers-color-scheme: <name>)
the<name>
will be used byThemeIT!
internally and externally. This key/name will be used by you when you want to change the theme usingThemeIT!
. Please name them accordingly.
Import ThemeIT!
and call init
method in root file before using any other methods. (Do this after Setup instructions).
- Argument #1
defaultTheme
what theme should be set as the initial theme. (Default: auto) - Argument #2
autoLoad
whatever you should load thedefaultTheme
during initialization.
import { init } from "@themeit/native";
init("my-theme", true)
import type { DefaultTheme } from "@themeit/native";
import { init } from "@themeit/native";
// DefaultTheme = "auto" | "light" | "dark";
type MyThemes = DefaultTheme | "my-theme";
init<MyThemes>("my-theme", true)
The default option of ThemeIT! is to use the system theme. This is the out-of-the-box behavior so no setup
is needed. To toggle this feature programmatically you can use useTheme("auto")
.
To change themes please use the useTheme
method. Make that the name here matches the one you used when setting media(prefers-color-scheme: <name>)
of CSS file.
// Javascript
import { useTheme } from "@themeit/native";
const myNewTheme = "my-theme";
useTheme(newTheme);
// Typescript
import { useTheme } from "@themeit/native";
type MyThemes = "auto" | "my-theme";
const myNewTheme = "my-theme";
useTheme<MyThemes>(newTheme); // Nice autocomplete :D
To get the current theme use the getTheme
method.
// Javascript
import { getTheme } from "@themeit/native";
const theme = getTheme();
// Typescript
import { getTheme } from "@themeit/native";
type MyTheme = "auto" | "dark" | "my-theme";
const theme = getTheme<MyTheme>();
To get all the themes available use the getThemeList
method.
// Javascript
import { getThemeList } from "@themeit/native";
const themeList = getThemeList();
// Typescript
import { getThemeList } from "@themeit/native";
const themeList: Array<string> = getThemeList();
Import @themeit/react
and setup the ThemeProvider
in root file before using any other methods.
Note that ThemeProvider
should be above React.StrictMode
as it won't work the other way
around. (Do this after Setup instructions).
ThemeProvider
Props:
defaultTheme
– what theme should be set as the initial theme. (Default: auto)autoLoad
– whatever you should load thedefaultTheme
during initialization.
// Javascript
import { ThemeProvider } from "@themeit/react";
ReactDOM.createRoot(document.getElementById("root")).render(
<ThemeProvider defaultTheme="my-theme" autoLoad>
<React.StrictMode>
<App />
</React.StrictMode>
</ThemeProvider>
);
// Typescript
import { ThemeProvider } from "@themeit/react";
type CustomThemes = "light" | "dark" | "my-theme";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<ThemeProvider<CustomThemes> defaultTheme="my-theme" autoLoad>
<React.StrictMode>
<App />
</React.StrictMode>
</ThemeProvider>
);
To change the theme use the useTheme
hook from @themeit/react
. The hook returns a tuple with [state, action]
we are interested in the action
here.
Action Props:
changeTheme
– Call to change the current theme of the browser.
import { useTheme } from "@themeit/react";
const MyApp = () => {
const [_, { changeTheme }] = useTheme();
return (
<button onClick={() => { changeTheme("dark") }}>
Turn of the lights!
</button>
)
}
import { useTheme } from "@themeit/react";
type MyThemes = "light" | "dark" | "my-theme";
const MyApp = () => {
const [_, { changeTheme }] = useTheme<MyThemes>();
return (
<button onClick={() => { changeTheme("dark") }}>
Turn of the lights!
</button>
)
}
To get the current theme use the useTheme
hook from @themeit/react
. The hook returns a tuple with [state, action]
we are interested in the state
here.
State Props:
theme
– Current theme ofThemeIT!
themeList
– All themes available forThemeIT!
// Javascript
import { useTheme } from "@themeit/react";
const MyApp = () => {
const [{ theme }] = useTheme();
return (
div>
<h1>
The curren theme is: {theme}
</h1>
<code>
{JSON.stringify(themeList, null, 2)}
</code>
</div>
)
}
// Typescript
import { useTheme } from "@themeit/react";
type MyThemes = "light" | "dark" | "my-theme";
const MyApp = () => {
const [{ theme, themeList }] = useTheme<MyThemes>();
return (
<div>
<h1>
The curren theme is: {theme}
</h1>
<code>
{JSON.stringify(themeList, null, 2)}
</code>
</div>
)
}
The project could use support for: Vue
, Angular
, NextJS
, Svelte
and Remix.run
. If you are willing to contribute please follow CONTRIBUTE.md for more information.