@irisui/ui 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 theteqlab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,85 @@
1
- # Temporary Holding Version
1
+ # @irisui/ui
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Accessible React components in the _Verre irisé_ style, from
4
+ [iris-ui](https://github.com/theteqlab/iris-ui).
5
+
6
+ ## Install
7
+
8
+ ```sh
9
+ npm install @irisui/ui @irisui/tokens
10
+ ```
11
+
12
+ `react` and `react-dom` (18 or 19) are peer dependencies.
13
+
14
+ Import the tokens once in your global CSS (see
15
+ [`@irisui/tokens`](https://www.npmjs.com/package/@irisui/tokens)):
16
+
17
+ ```css
18
+ @import "tailwindcss";
19
+ @import "@irisui/tokens/tailwind.css";
20
+ ```
21
+
22
+ ## Theme
23
+
24
+ The theme is driven by two attributes on `<html>`: `data-palette` (`nacre`,
25
+ `aurore`, `couchant`, `glacier`) and `data-mode` (`light`, `dark`, `system`).
26
+ Setting them by hand is enough; the helpers below are optional.
27
+
28
+ ### `ThemeProvider` and `useTheme`
29
+
30
+ `ThemeProvider` sets the attributes on `<html>` and remembers the user's choice
31
+ in `localStorage` (synced across tabs).
32
+
33
+ ```tsx
34
+ import { ThemeProvider, useTheme, PALETTES, type Palette } from "@irisui/ui";
35
+
36
+ function PaletteSwitcher() {
37
+ const { palette, setPalette } = useTheme();
38
+ return (
39
+ <select value={palette} onChange={(e) => setPalette(e.target.value as Palette)}>
40
+ {PALETTES.map((p) => (
41
+ <option key={p}>{p}</option>
42
+ ))}
43
+ </select>
44
+ );
45
+ }
46
+
47
+ <ThemeProvider defaultPalette="nacre" defaultMode="system">
48
+ <App />
49
+ </ThemeProvider>;
50
+ ```
51
+
52
+ Props: `palette` / `mode` (controlled), `defaultPalette` / `defaultMode`,
53
+ `onPaletteChange` / `onModeChange`, and `storageKey` (default
54
+ `"@irisui/theme"`, `null` disables persistence).
55
+
56
+ `useTheme()` returns `{ palette, mode, resolvedMode, setPalette, setMode }`;
57
+ `resolvedMode` is `light` or `dark`, with `system` resolved.
58
+
59
+ ### Avoiding a flash of the default theme
60
+
61
+ Render `ThemeScript` in `<head>` so the stored theme is applied before the
62
+ first paint:
63
+
64
+ ```tsx
65
+ import { ThemeScript } from "@irisui/ui";
66
+
67
+ <head>
68
+ <ThemeScript />
69
+ </head>;
70
+ ```
71
+
72
+ Outside React (a Vite plugin, a server template, a Server Component), use
73
+ `getThemeScript()` from the server-safe entry point; it returns the script as a
74
+ string:
75
+
76
+ ```ts
77
+ import { getThemeScript } from "@irisui/ui/theme-script";
78
+ ```
79
+
80
+ Pass the same `storageKey`, `defaultPalette` and `defaultMode` as to
81
+ `ThemeProvider`.
82
+
83
+ ## License
84
+
85
+ [MIT](./LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,182 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var src_exports = {};
23
+ __export(src_exports, {
24
+ DEFAULT_MODE: () => DEFAULT_MODE,
25
+ DEFAULT_PALETTE: () => DEFAULT_PALETTE,
26
+ DEFAULT_STORAGE_KEY: () => DEFAULT_STORAGE_KEY,
27
+ MODES: () => MODES,
28
+ PALETTES: () => PALETTES,
29
+ ThemeProvider: () => ThemeProvider,
30
+ ThemeScript: () => ThemeScript,
31
+ getThemeScript: () => getThemeScript,
32
+ useTheme: () => useTheme
33
+ });
34
+ module.exports = __toCommonJS(src_exports);
35
+
36
+ // src/theme/theme-provider.tsx
37
+ var import_react = require("react");
38
+
39
+ // src/theme/constants.ts
40
+ var PALETTES = ["nacre", "aurore", "couchant", "glacier"];
41
+ var MODES = ["light", "dark", "system"];
42
+ var DEFAULT_PALETTE = "nacre";
43
+ var DEFAULT_MODE = "system";
44
+ var DEFAULT_STORAGE_KEY = "@irisui/theme";
45
+ var isPalette = (value) => PALETTES.includes(value);
46
+ var isMode = (value) => MODES.includes(value);
47
+
48
+ // src/theme/theme-script.ts
49
+ function getThemeScript({
50
+ storageKey = DEFAULT_STORAGE_KEY,
51
+ defaultPalette = DEFAULT_PALETTE,
52
+ defaultMode = DEFAULT_MODE
53
+ } = {}) {
54
+ const args = [storageKey, PALETTES, MODES, defaultPalette, defaultMode].map((arg) => JSON.stringify(arg)).join(",");
55
+ return `(function(k,P,M,dp,dm){var d=document.documentElement,s={};try{s=JSON.parse(localStorage.getItem(k)||"{}")||{}}catch(e){}d.setAttribute("data-palette",P.indexOf(s.palette)>-1?s.palette:dp);d.setAttribute("data-mode",M.indexOf(s.mode)>-1?s.mode:dm)})(${args})`;
56
+ }
57
+
58
+ // src/theme/theme-provider.tsx
59
+ var import_jsx_runtime = require("react/jsx-runtime");
60
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? import_react.useEffect : import_react.useLayoutEffect;
61
+ var ThemeContext = (0, import_react.createContext)(null);
62
+ function readStorage(key) {
63
+ try {
64
+ const parsed = JSON.parse(window.localStorage.getItem(key) ?? "{}");
65
+ return parsed && typeof parsed === "object" ? parsed : {};
66
+ } catch {
67
+ return {};
68
+ }
69
+ }
70
+ function writeStorage(key, value) {
71
+ try {
72
+ window.localStorage.setItem(key, JSON.stringify(value));
73
+ } catch {
74
+ }
75
+ }
76
+ var DARK_QUERY = "(prefers-color-scheme: dark)";
77
+ function subscribeColorScheme(onChange) {
78
+ const media = window.matchMedia(DARK_QUERY);
79
+ media.addEventListener("change", onChange);
80
+ return () => media.removeEventListener("change", onChange);
81
+ }
82
+ function useSystemMode() {
83
+ return (0, import_react.useSyncExternalStore)(
84
+ subscribeColorScheme,
85
+ () => window.matchMedia(DARK_QUERY).matches ? "dark" : "light",
86
+ () => "light"
87
+ );
88
+ }
89
+ function ThemeProvider({
90
+ children,
91
+ palette: paletteProp,
92
+ defaultPalette = DEFAULT_PALETTE,
93
+ onPaletteChange,
94
+ mode: modeProp,
95
+ defaultMode = DEFAULT_MODE,
96
+ onModeChange,
97
+ storageKey = DEFAULT_STORAGE_KEY
98
+ }) {
99
+ const [paletteState, setPaletteState] = (0, import_react.useState)(defaultPalette);
100
+ const [modeState, setModeState] = (0, import_react.useState)(defaultMode);
101
+ const [restored, setRestored] = (0, import_react.useState)(false);
102
+ const palette = paletteProp ?? paletteState;
103
+ const mode = modeProp ?? modeState;
104
+ const systemMode = useSystemMode();
105
+ const resolvedMode = mode === "system" ? systemMode : mode;
106
+ useIsomorphicLayoutEffect(() => {
107
+ if (storageKey !== null) {
108
+ const stored = readStorage(storageKey);
109
+ if (isPalette(stored.palette)) setPaletteState(stored.palette);
110
+ if (isMode(stored.mode)) setModeState(stored.mode);
111
+ }
112
+ setRestored(true);
113
+ }, [storageKey]);
114
+ useIsomorphicLayoutEffect(() => {
115
+ if (!restored) return;
116
+ const root = document.documentElement;
117
+ root.setAttribute("data-palette", palette);
118
+ root.setAttribute("data-mode", mode);
119
+ }, [restored, palette, mode]);
120
+ (0, import_react.useEffect)(() => {
121
+ if (storageKey === null) return;
122
+ const onStorage = (event) => {
123
+ if (event.key !== storageKey) return;
124
+ const stored = readStorage(storageKey);
125
+ if (isPalette(stored.palette)) setPaletteState(stored.palette);
126
+ if (isMode(stored.mode)) setModeState(stored.mode);
127
+ };
128
+ window.addEventListener("storage", onStorage);
129
+ return () => window.removeEventListener("storage", onStorage);
130
+ }, [storageKey]);
131
+ const setPalette = (0, import_react.useCallback)(
132
+ (next) => {
133
+ if (paletteProp === void 0) setPaletteState(next);
134
+ if (storageKey !== null) writeStorage(storageKey, { palette: next, mode });
135
+ onPaletteChange?.(next);
136
+ },
137
+ [paletteProp, storageKey, mode, onPaletteChange]
138
+ );
139
+ const setMode = (0, import_react.useCallback)(
140
+ (next) => {
141
+ if (modeProp === void 0) setModeState(next);
142
+ if (storageKey !== null) writeStorage(storageKey, { palette, mode: next });
143
+ onModeChange?.(next);
144
+ },
145
+ [modeProp, storageKey, palette, onModeChange]
146
+ );
147
+ const value = (0, import_react.useMemo)(
148
+ () => ({ palette, mode, resolvedMode, setPalette, setMode }),
149
+ [palette, mode, resolvedMode, setPalette, setMode]
150
+ );
151
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value, children });
152
+ }
153
+ function useTheme() {
154
+ const context = (0, import_react.useContext)(ThemeContext);
155
+ if (context === null) {
156
+ throw new Error("useTheme must be used within a <ThemeProvider>.");
157
+ }
158
+ return context;
159
+ }
160
+ function ThemeScript({ nonce, ...options }) {
161
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
162
+ "script",
163
+ {
164
+ nonce,
165
+ suppressHydrationWarning: true,
166
+ dangerouslySetInnerHTML: { __html: getThemeScript(options) }
167
+ }
168
+ );
169
+ }
170
+ // Annotate the CommonJS export names for ESM import in node:
171
+ 0 && (module.exports = {
172
+ DEFAULT_MODE,
173
+ DEFAULT_PALETTE,
174
+ DEFAULT_STORAGE_KEY,
175
+ MODES,
176
+ PALETTES,
177
+ ThemeProvider,
178
+ ThemeScript,
179
+ getThemeScript,
180
+ useTheme
181
+ });
182
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/theme/theme-provider.tsx","../src/theme/constants.ts","../src/theme/theme-script.ts"],"sourcesContent":["export * from \"./theme\";\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n isMode,\n isPalette,\n type Mode,\n type Palette,\n type ResolvedMode,\n} from \"./constants\";\nimport { getThemeScript, type ThemeScriptOptions } from \"./theme-script\";\n\nconst useIsomorphicLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nexport interface ThemeContextValue {\n palette: Palette;\n /** Mode as chosen: `light`, `dark` or `system`. */\n mode: Mode;\n /** Mode actually displayed, `system` resolved through `prefers-color-scheme`. */\n resolvedMode: ResolvedMode;\n setPalette: (palette: Palette) => void;\n setMode: (mode: Mode) => void;\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null);\n\nexport interface ThemeProviderProps {\n children?: ReactNode;\n /** Controlled palette. */\n palette?: Palette;\n /** Initial palette when uncontrolled and nothing is stored. */\n defaultPalette?: Palette;\n onPaletteChange?: (palette: Palette) => void;\n /** Controlled mode. */\n mode?: Mode;\n /** Initial mode when uncontrolled and nothing is stored. */\n defaultMode?: Mode;\n onModeChange?: (mode: Mode) => void;\n /** localStorage key used to remember the user's choice. `null` disables persistence. */\n storageKey?: string | null;\n}\n\ninterface StoredTheme {\n palette?: unknown;\n mode?: unknown;\n}\n\nfunction readStorage(key: string): StoredTheme {\n try {\n const parsed: unknown = JSON.parse(window.localStorage.getItem(key) ?? \"{}\");\n return parsed && typeof parsed === \"object\" ? (parsed as StoredTheme) : {};\n } catch {\n return {};\n }\n}\n\nfunction writeStorage(key: string, value: { palette: Palette; mode: Mode }): void {\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // Storage unavailable (private mode, quota): the choice is simply not remembered.\n }\n}\n\nconst DARK_QUERY = \"(prefers-color-scheme: dark)\";\n\nfunction subscribeColorScheme(onChange: () => void): () => void {\n const media = window.matchMedia(DARK_QUERY);\n media.addEventListener(\"change\", onChange);\n return () => media.removeEventListener(\"change\", onChange);\n}\n\nfunction useSystemMode(): ResolvedMode {\n return useSyncExternalStore(\n subscribeColorScheme,\n () => (window.matchMedia(DARK_QUERY).matches ? \"dark\" : \"light\"),\n () => \"light\",\n );\n}\n\n/**\n * Optional. Sets `data-palette` and `data-mode` on `<html>` and remembers the\n * user's choice. Without it, the HTML attributes alone are enough: the\n * `system` mode is handled in CSS by the tokens.\n */\nexport function ThemeProvider({\n children,\n palette: paletteProp,\n defaultPalette = DEFAULT_PALETTE,\n onPaletteChange,\n mode: modeProp,\n defaultMode = DEFAULT_MODE,\n onModeChange,\n storageKey = DEFAULT_STORAGE_KEY,\n}: ThemeProviderProps) {\n const [paletteState, setPaletteState] = useState<Palette>(defaultPalette);\n const [modeState, setModeState] = useState<Mode>(defaultMode);\n // Stored values are read after mount so that server and client render the same tree.\n const [restored, setRestored] = useState(false);\n\n const palette = paletteProp ?? paletteState;\n const mode = modeProp ?? modeState;\n const systemMode = useSystemMode();\n const resolvedMode: ResolvedMode = mode === \"system\" ? systemMode : mode;\n\n useIsomorphicLayoutEffect(() => {\n if (storageKey !== null) {\n const stored = readStorage(storageKey);\n if (isPalette(stored.palette)) setPaletteState(stored.palette);\n if (isMode(stored.mode)) setModeState(stored.mode);\n }\n setRestored(true);\n }, [storageKey]);\n\n useIsomorphicLayoutEffect(() => {\n if (!restored) return;\n const root = document.documentElement;\n root.setAttribute(\"data-palette\", palette);\n root.setAttribute(\"data-mode\", mode);\n }, [restored, palette, mode]);\n\n // Keep several tabs in sync.\n useEffect(() => {\n if (storageKey === null) return;\n const onStorage = (event: StorageEvent) => {\n if (event.key !== storageKey) return;\n const stored = readStorage(storageKey);\n if (isPalette(stored.palette)) setPaletteState(stored.palette);\n if (isMode(stored.mode)) setModeState(stored.mode);\n };\n window.addEventListener(\"storage\", onStorage);\n return () => window.removeEventListener(\"storage\", onStorage);\n }, [storageKey]);\n\n const setPalette = useCallback(\n (next: Palette) => {\n if (paletteProp === undefined) setPaletteState(next);\n if (storageKey !== null) writeStorage(storageKey, { palette: next, mode });\n onPaletteChange?.(next);\n },\n [paletteProp, storageKey, mode, onPaletteChange],\n );\n\n const setMode = useCallback(\n (next: Mode) => {\n if (modeProp === undefined) setModeState(next);\n if (storageKey !== null) writeStorage(storageKey, { palette, mode: next });\n onModeChange?.(next);\n },\n [modeProp, storageKey, palette, onModeChange],\n );\n\n const value = useMemo<ThemeContextValue>(\n () => ({ palette, mode, resolvedMode, setPalette, setMode }),\n [palette, mode, resolvedMode, setPalette, setMode],\n );\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;\n}\n\n/** Reads and changes the current theme. Must be used inside `ThemeProvider`. */\nexport function useTheme(): ThemeContextValue {\n const context = useContext(ThemeContext);\n if (context === null) {\n throw new Error(\"useTheme must be used within a <ThemeProvider>.\");\n }\n return context;\n}\n\nexport interface ThemeScriptProps extends ThemeScriptOptions {\n nonce?: string;\n}\n\n/** Renders the anti-flash script; place it in `<head>`. */\nexport function ThemeScript({ nonce, ...options }: ThemeScriptProps) {\n return (\n <script\n nonce={nonce}\n suppressHydrationWarning\n dangerouslySetInnerHTML={{ __html: getThemeScript(options) }}\n />\n );\n}\n","export const PALETTES = [\"nacre\", \"aurore\", \"couchant\", \"glacier\"] as const;\nexport const MODES = [\"light\", \"dark\", \"system\"] as const;\n\nexport type Palette = (typeof PALETTES)[number];\nexport type Mode = (typeof MODES)[number];\nexport type ResolvedMode = Exclude<Mode, \"system\">;\n\nexport const DEFAULT_PALETTE: Palette = \"nacre\";\nexport const DEFAULT_MODE: Mode = \"system\";\nexport const DEFAULT_STORAGE_KEY = \"@irisui/theme\";\n\nexport const isPalette = (value: unknown): value is Palette =>\n (PALETTES as readonly unknown[]).includes(value);\nexport const isMode = (value: unknown): value is Mode =>\n (MODES as readonly unknown[]).includes(value);\n","import {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n MODES,\n PALETTES,\n type Mode,\n type Palette,\n} from \"./constants\";\n\nexport interface ThemeScriptOptions {\n storageKey?: string;\n defaultPalette?: Palette;\n defaultMode?: Mode;\n}\n\n/**\n * Returns an inline script that applies the stored palette and mode to\n * `<html>` before the first paint, to avoid a flash of the default theme.\n * Optional: without it the theme still works from the HTML attributes alone.\n */\nexport function getThemeScript({\n storageKey = DEFAULT_STORAGE_KEY,\n defaultPalette = DEFAULT_PALETTE,\n defaultMode = DEFAULT_MODE,\n}: ThemeScriptOptions = {}): string {\n const args = [storageKey, PALETTES, MODES, defaultPalette, defaultMode]\n .map((arg) => JSON.stringify(arg))\n .join(\",\");\n return `(function(k,P,M,dp,dm){var d=document.documentElement,s={};try{s=JSON.parse(localStorage.getItem(k)||\"{}\")||{}}catch(e){}d.setAttribute(\"data-palette\",P.indexOf(s.palette)>-1?s.palette:dp);d.setAttribute(\"data-mode\",M.indexOf(s.mode)>-1?s.mode:dm)})(${args})`;\n}\n\nexport {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n MODES,\n PALETTES,\n type Mode,\n type Palette,\n type ResolvedMode,\n} from \"./constants\";\n"],"mappings":"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","names":[]}
@@ -0,0 +1,63 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ declare const PALETTES: readonly ["nacre", "aurore", "couchant", "glacier"];
5
+ declare const MODES: readonly ["light", "dark", "system"];
6
+ type Palette = (typeof PALETTES)[number];
7
+ type Mode = (typeof MODES)[number];
8
+ type ResolvedMode = Exclude<Mode, "system">;
9
+ declare const DEFAULT_PALETTE: Palette;
10
+ declare const DEFAULT_MODE: Mode;
11
+ declare const DEFAULT_STORAGE_KEY = "@irisui/theme";
12
+
13
+ interface ThemeScriptOptions {
14
+ storageKey?: string;
15
+ defaultPalette?: Palette;
16
+ defaultMode?: Mode;
17
+ }
18
+ /**
19
+ * Returns an inline script that applies the stored palette and mode to
20
+ * `<html>` before the first paint, to avoid a flash of the default theme.
21
+ * Optional: without it the theme still works from the HTML attributes alone.
22
+ */
23
+ declare function getThemeScript({ storageKey, defaultPalette, defaultMode, }?: ThemeScriptOptions): string;
24
+
25
+ interface ThemeContextValue {
26
+ palette: Palette;
27
+ /** Mode as chosen: `light`, `dark` or `system`. */
28
+ mode: Mode;
29
+ /** Mode actually displayed, `system` resolved through `prefers-color-scheme`. */
30
+ resolvedMode: ResolvedMode;
31
+ setPalette: (palette: Palette) => void;
32
+ setMode: (mode: Mode) => void;
33
+ }
34
+ interface ThemeProviderProps {
35
+ children?: ReactNode;
36
+ /** Controlled palette. */
37
+ palette?: Palette;
38
+ /** Initial palette when uncontrolled and nothing is stored. */
39
+ defaultPalette?: Palette;
40
+ onPaletteChange?: (palette: Palette) => void;
41
+ /** Controlled mode. */
42
+ mode?: Mode;
43
+ /** Initial mode when uncontrolled and nothing is stored. */
44
+ defaultMode?: Mode;
45
+ onModeChange?: (mode: Mode) => void;
46
+ /** localStorage key used to remember the user's choice. `null` disables persistence. */
47
+ storageKey?: string | null;
48
+ }
49
+ /**
50
+ * Optional. Sets `data-palette` and `data-mode` on `<html>` and remembers the
51
+ * user's choice. Without it, the HTML attributes alone are enough: the
52
+ * `system` mode is handled in CSS by the tokens.
53
+ */
54
+ declare function ThemeProvider({ children, palette: paletteProp, defaultPalette, onPaletteChange, mode: modeProp, defaultMode, onModeChange, storageKey, }: ThemeProviderProps): react.JSX.Element;
55
+ /** Reads and changes the current theme. Must be used inside `ThemeProvider`. */
56
+ declare function useTheme(): ThemeContextValue;
57
+ interface ThemeScriptProps extends ThemeScriptOptions {
58
+ nonce?: string;
59
+ }
60
+ /** Renders the anti-flash script; place it in `<head>`. */
61
+ declare function ThemeScript({ nonce, ...options }: ThemeScriptProps): react.JSX.Element;
62
+
63
+ export { DEFAULT_MODE, DEFAULT_PALETTE, DEFAULT_STORAGE_KEY, MODES, type Mode, PALETTES, type Palette, type ResolvedMode, type ThemeContextValue, ThemeProvider, type ThemeProviderProps, ThemeScript, type ThemeScriptOptions, type ThemeScriptProps, getThemeScript, useTheme };
@@ -0,0 +1,63 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ declare const PALETTES: readonly ["nacre", "aurore", "couchant", "glacier"];
5
+ declare const MODES: readonly ["light", "dark", "system"];
6
+ type Palette = (typeof PALETTES)[number];
7
+ type Mode = (typeof MODES)[number];
8
+ type ResolvedMode = Exclude<Mode, "system">;
9
+ declare const DEFAULT_PALETTE: Palette;
10
+ declare const DEFAULT_MODE: Mode;
11
+ declare const DEFAULT_STORAGE_KEY = "@irisui/theme";
12
+
13
+ interface ThemeScriptOptions {
14
+ storageKey?: string;
15
+ defaultPalette?: Palette;
16
+ defaultMode?: Mode;
17
+ }
18
+ /**
19
+ * Returns an inline script that applies the stored palette and mode to
20
+ * `<html>` before the first paint, to avoid a flash of the default theme.
21
+ * Optional: without it the theme still works from the HTML attributes alone.
22
+ */
23
+ declare function getThemeScript({ storageKey, defaultPalette, defaultMode, }?: ThemeScriptOptions): string;
24
+
25
+ interface ThemeContextValue {
26
+ palette: Palette;
27
+ /** Mode as chosen: `light`, `dark` or `system`. */
28
+ mode: Mode;
29
+ /** Mode actually displayed, `system` resolved through `prefers-color-scheme`. */
30
+ resolvedMode: ResolvedMode;
31
+ setPalette: (palette: Palette) => void;
32
+ setMode: (mode: Mode) => void;
33
+ }
34
+ interface ThemeProviderProps {
35
+ children?: ReactNode;
36
+ /** Controlled palette. */
37
+ palette?: Palette;
38
+ /** Initial palette when uncontrolled and nothing is stored. */
39
+ defaultPalette?: Palette;
40
+ onPaletteChange?: (palette: Palette) => void;
41
+ /** Controlled mode. */
42
+ mode?: Mode;
43
+ /** Initial mode when uncontrolled and nothing is stored. */
44
+ defaultMode?: Mode;
45
+ onModeChange?: (mode: Mode) => void;
46
+ /** localStorage key used to remember the user's choice. `null` disables persistence. */
47
+ storageKey?: string | null;
48
+ }
49
+ /**
50
+ * Optional. Sets `data-palette` and `data-mode` on `<html>` and remembers the
51
+ * user's choice. Without it, the HTML attributes alone are enough: the
52
+ * `system` mode is handled in CSS by the tokens.
53
+ */
54
+ declare function ThemeProvider({ children, palette: paletteProp, defaultPalette, onPaletteChange, mode: modeProp, defaultMode, onModeChange, storageKey, }: ThemeProviderProps): react.JSX.Element;
55
+ /** Reads and changes the current theme. Must be used inside `ThemeProvider`. */
56
+ declare function useTheme(): ThemeContextValue;
57
+ interface ThemeScriptProps extends ThemeScriptOptions {
58
+ nonce?: string;
59
+ }
60
+ /** Renders the anti-flash script; place it in `<head>`. */
61
+ declare function ThemeScript({ nonce, ...options }: ThemeScriptProps): react.JSX.Element;
62
+
63
+ export { DEFAULT_MODE, DEFAULT_PALETTE, DEFAULT_STORAGE_KEY, MODES, type Mode, PALETTES, type Palette, type ResolvedMode, type ThemeContextValue, ThemeProvider, type ThemeProviderProps, ThemeScript, type ThemeScriptOptions, type ThemeScriptProps, getThemeScript, useTheme };
package/dist/index.js ADDED
@@ -0,0 +1,157 @@
1
+ "use client";
2
+
3
+ // src/theme/theme-provider.tsx
4
+ import {
5
+ createContext,
6
+ useCallback,
7
+ useContext,
8
+ useEffect,
9
+ useLayoutEffect,
10
+ useMemo,
11
+ useState,
12
+ useSyncExternalStore
13
+ } from "react";
14
+
15
+ // src/theme/constants.ts
16
+ var PALETTES = ["nacre", "aurore", "couchant", "glacier"];
17
+ var MODES = ["light", "dark", "system"];
18
+ var DEFAULT_PALETTE = "nacre";
19
+ var DEFAULT_MODE = "system";
20
+ var DEFAULT_STORAGE_KEY = "@irisui/theme";
21
+ var isPalette = (value) => PALETTES.includes(value);
22
+ var isMode = (value) => MODES.includes(value);
23
+
24
+ // src/theme/theme-script.ts
25
+ function getThemeScript({
26
+ storageKey = DEFAULT_STORAGE_KEY,
27
+ defaultPalette = DEFAULT_PALETTE,
28
+ defaultMode = DEFAULT_MODE
29
+ } = {}) {
30
+ const args = [storageKey, PALETTES, MODES, defaultPalette, defaultMode].map((arg) => JSON.stringify(arg)).join(",");
31
+ return `(function(k,P,M,dp,dm){var d=document.documentElement,s={};try{s=JSON.parse(localStorage.getItem(k)||"{}")||{}}catch(e){}d.setAttribute("data-palette",P.indexOf(s.palette)>-1?s.palette:dp);d.setAttribute("data-mode",M.indexOf(s.mode)>-1?s.mode:dm)})(${args})`;
32
+ }
33
+
34
+ // src/theme/theme-provider.tsx
35
+ import { jsx } from "react/jsx-runtime";
36
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
37
+ var ThemeContext = createContext(null);
38
+ function readStorage(key) {
39
+ try {
40
+ const parsed = JSON.parse(window.localStorage.getItem(key) ?? "{}");
41
+ return parsed && typeof parsed === "object" ? parsed : {};
42
+ } catch {
43
+ return {};
44
+ }
45
+ }
46
+ function writeStorage(key, value) {
47
+ try {
48
+ window.localStorage.setItem(key, JSON.stringify(value));
49
+ } catch {
50
+ }
51
+ }
52
+ var DARK_QUERY = "(prefers-color-scheme: dark)";
53
+ function subscribeColorScheme(onChange) {
54
+ const media = window.matchMedia(DARK_QUERY);
55
+ media.addEventListener("change", onChange);
56
+ return () => media.removeEventListener("change", onChange);
57
+ }
58
+ function useSystemMode() {
59
+ return useSyncExternalStore(
60
+ subscribeColorScheme,
61
+ () => window.matchMedia(DARK_QUERY).matches ? "dark" : "light",
62
+ () => "light"
63
+ );
64
+ }
65
+ function ThemeProvider({
66
+ children,
67
+ palette: paletteProp,
68
+ defaultPalette = DEFAULT_PALETTE,
69
+ onPaletteChange,
70
+ mode: modeProp,
71
+ defaultMode = DEFAULT_MODE,
72
+ onModeChange,
73
+ storageKey = DEFAULT_STORAGE_KEY
74
+ }) {
75
+ const [paletteState, setPaletteState] = useState(defaultPalette);
76
+ const [modeState, setModeState] = useState(defaultMode);
77
+ const [restored, setRestored] = useState(false);
78
+ const palette = paletteProp ?? paletteState;
79
+ const mode = modeProp ?? modeState;
80
+ const systemMode = useSystemMode();
81
+ const resolvedMode = mode === "system" ? systemMode : mode;
82
+ useIsomorphicLayoutEffect(() => {
83
+ if (storageKey !== null) {
84
+ const stored = readStorage(storageKey);
85
+ if (isPalette(stored.palette)) setPaletteState(stored.palette);
86
+ if (isMode(stored.mode)) setModeState(stored.mode);
87
+ }
88
+ setRestored(true);
89
+ }, [storageKey]);
90
+ useIsomorphicLayoutEffect(() => {
91
+ if (!restored) return;
92
+ const root = document.documentElement;
93
+ root.setAttribute("data-palette", palette);
94
+ root.setAttribute("data-mode", mode);
95
+ }, [restored, palette, mode]);
96
+ useEffect(() => {
97
+ if (storageKey === null) return;
98
+ const onStorage = (event) => {
99
+ if (event.key !== storageKey) return;
100
+ const stored = readStorage(storageKey);
101
+ if (isPalette(stored.palette)) setPaletteState(stored.palette);
102
+ if (isMode(stored.mode)) setModeState(stored.mode);
103
+ };
104
+ window.addEventListener("storage", onStorage);
105
+ return () => window.removeEventListener("storage", onStorage);
106
+ }, [storageKey]);
107
+ const setPalette = useCallback(
108
+ (next) => {
109
+ if (paletteProp === void 0) setPaletteState(next);
110
+ if (storageKey !== null) writeStorage(storageKey, { palette: next, mode });
111
+ onPaletteChange?.(next);
112
+ },
113
+ [paletteProp, storageKey, mode, onPaletteChange]
114
+ );
115
+ const setMode = useCallback(
116
+ (next) => {
117
+ if (modeProp === void 0) setModeState(next);
118
+ if (storageKey !== null) writeStorage(storageKey, { palette, mode: next });
119
+ onModeChange?.(next);
120
+ },
121
+ [modeProp, storageKey, palette, onModeChange]
122
+ );
123
+ const value = useMemo(
124
+ () => ({ palette, mode, resolvedMode, setPalette, setMode }),
125
+ [palette, mode, resolvedMode, setPalette, setMode]
126
+ );
127
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
128
+ }
129
+ function useTheme() {
130
+ const context = useContext(ThemeContext);
131
+ if (context === null) {
132
+ throw new Error("useTheme must be used within a <ThemeProvider>.");
133
+ }
134
+ return context;
135
+ }
136
+ function ThemeScript({ nonce, ...options }) {
137
+ return /* @__PURE__ */ jsx(
138
+ "script",
139
+ {
140
+ nonce,
141
+ suppressHydrationWarning: true,
142
+ dangerouslySetInnerHTML: { __html: getThemeScript(options) }
143
+ }
144
+ );
145
+ }
146
+ export {
147
+ DEFAULT_MODE,
148
+ DEFAULT_PALETTE,
149
+ DEFAULT_STORAGE_KEY,
150
+ MODES,
151
+ PALETTES,
152
+ ThemeProvider,
153
+ ThemeScript,
154
+ getThemeScript,
155
+ useTheme
156
+ };
157
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme/theme-provider.tsx","../src/theme/constants.ts","../src/theme/theme-script.ts"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n isMode,\n isPalette,\n type Mode,\n type Palette,\n type ResolvedMode,\n} from \"./constants\";\nimport { getThemeScript, type ThemeScriptOptions } from \"./theme-script\";\n\nconst useIsomorphicLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nexport interface ThemeContextValue {\n palette: Palette;\n /** Mode as chosen: `light`, `dark` or `system`. */\n mode: Mode;\n /** Mode actually displayed, `system` resolved through `prefers-color-scheme`. */\n resolvedMode: ResolvedMode;\n setPalette: (palette: Palette) => void;\n setMode: (mode: Mode) => void;\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null);\n\nexport interface ThemeProviderProps {\n children?: ReactNode;\n /** Controlled palette. */\n palette?: Palette;\n /** Initial palette when uncontrolled and nothing is stored. */\n defaultPalette?: Palette;\n onPaletteChange?: (palette: Palette) => void;\n /** Controlled mode. */\n mode?: Mode;\n /** Initial mode when uncontrolled and nothing is stored. */\n defaultMode?: Mode;\n onModeChange?: (mode: Mode) => void;\n /** localStorage key used to remember the user's choice. `null` disables persistence. */\n storageKey?: string | null;\n}\n\ninterface StoredTheme {\n palette?: unknown;\n mode?: unknown;\n}\n\nfunction readStorage(key: string): StoredTheme {\n try {\n const parsed: unknown = JSON.parse(window.localStorage.getItem(key) ?? \"{}\");\n return parsed && typeof parsed === \"object\" ? (parsed as StoredTheme) : {};\n } catch {\n return {};\n }\n}\n\nfunction writeStorage(key: string, value: { palette: Palette; mode: Mode }): void {\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // Storage unavailable (private mode, quota): the choice is simply not remembered.\n }\n}\n\nconst DARK_QUERY = \"(prefers-color-scheme: dark)\";\n\nfunction subscribeColorScheme(onChange: () => void): () => void {\n const media = window.matchMedia(DARK_QUERY);\n media.addEventListener(\"change\", onChange);\n return () => media.removeEventListener(\"change\", onChange);\n}\n\nfunction useSystemMode(): ResolvedMode {\n return useSyncExternalStore(\n subscribeColorScheme,\n () => (window.matchMedia(DARK_QUERY).matches ? \"dark\" : \"light\"),\n () => \"light\",\n );\n}\n\n/**\n * Optional. Sets `data-palette` and `data-mode` on `<html>` and remembers the\n * user's choice. Without it, the HTML attributes alone are enough: the\n * `system` mode is handled in CSS by the tokens.\n */\nexport function ThemeProvider({\n children,\n palette: paletteProp,\n defaultPalette = DEFAULT_PALETTE,\n onPaletteChange,\n mode: modeProp,\n defaultMode = DEFAULT_MODE,\n onModeChange,\n storageKey = DEFAULT_STORAGE_KEY,\n}: ThemeProviderProps) {\n const [paletteState, setPaletteState] = useState<Palette>(defaultPalette);\n const [modeState, setModeState] = useState<Mode>(defaultMode);\n // Stored values are read after mount so that server and client render the same tree.\n const [restored, setRestored] = useState(false);\n\n const palette = paletteProp ?? paletteState;\n const mode = modeProp ?? modeState;\n const systemMode = useSystemMode();\n const resolvedMode: ResolvedMode = mode === \"system\" ? systemMode : mode;\n\n useIsomorphicLayoutEffect(() => {\n if (storageKey !== null) {\n const stored = readStorage(storageKey);\n if (isPalette(stored.palette)) setPaletteState(stored.palette);\n if (isMode(stored.mode)) setModeState(stored.mode);\n }\n setRestored(true);\n }, [storageKey]);\n\n useIsomorphicLayoutEffect(() => {\n if (!restored) return;\n const root = document.documentElement;\n root.setAttribute(\"data-palette\", palette);\n root.setAttribute(\"data-mode\", mode);\n }, [restored, palette, mode]);\n\n // Keep several tabs in sync.\n useEffect(() => {\n if (storageKey === null) return;\n const onStorage = (event: StorageEvent) => {\n if (event.key !== storageKey) return;\n const stored = readStorage(storageKey);\n if (isPalette(stored.palette)) setPaletteState(stored.palette);\n if (isMode(stored.mode)) setModeState(stored.mode);\n };\n window.addEventListener(\"storage\", onStorage);\n return () => window.removeEventListener(\"storage\", onStorage);\n }, [storageKey]);\n\n const setPalette = useCallback(\n (next: Palette) => {\n if (paletteProp === undefined) setPaletteState(next);\n if (storageKey !== null) writeStorage(storageKey, { palette: next, mode });\n onPaletteChange?.(next);\n },\n [paletteProp, storageKey, mode, onPaletteChange],\n );\n\n const setMode = useCallback(\n (next: Mode) => {\n if (modeProp === undefined) setModeState(next);\n if (storageKey !== null) writeStorage(storageKey, { palette, mode: next });\n onModeChange?.(next);\n },\n [modeProp, storageKey, palette, onModeChange],\n );\n\n const value = useMemo<ThemeContextValue>(\n () => ({ palette, mode, resolvedMode, setPalette, setMode }),\n [palette, mode, resolvedMode, setPalette, setMode],\n );\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;\n}\n\n/** Reads and changes the current theme. Must be used inside `ThemeProvider`. */\nexport function useTheme(): ThemeContextValue {\n const context = useContext(ThemeContext);\n if (context === null) {\n throw new Error(\"useTheme must be used within a <ThemeProvider>.\");\n }\n return context;\n}\n\nexport interface ThemeScriptProps extends ThemeScriptOptions {\n nonce?: string;\n}\n\n/** Renders the anti-flash script; place it in `<head>`. */\nexport function ThemeScript({ nonce, ...options }: ThemeScriptProps) {\n return (\n <script\n nonce={nonce}\n suppressHydrationWarning\n dangerouslySetInnerHTML={{ __html: getThemeScript(options) }}\n />\n );\n}\n","export const PALETTES = [\"nacre\", \"aurore\", \"couchant\", \"glacier\"] as const;\nexport const MODES = [\"light\", \"dark\", \"system\"] as const;\n\nexport type Palette = (typeof PALETTES)[number];\nexport type Mode = (typeof MODES)[number];\nexport type ResolvedMode = Exclude<Mode, \"system\">;\n\nexport const DEFAULT_PALETTE: Palette = \"nacre\";\nexport const DEFAULT_MODE: Mode = \"system\";\nexport const DEFAULT_STORAGE_KEY = \"@irisui/theme\";\n\nexport const isPalette = (value: unknown): value is Palette =>\n (PALETTES as readonly unknown[]).includes(value);\nexport const isMode = (value: unknown): value is Mode =>\n (MODES as readonly unknown[]).includes(value);\n","import {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n MODES,\n PALETTES,\n type Mode,\n type Palette,\n} from \"./constants\";\n\nexport interface ThemeScriptOptions {\n storageKey?: string;\n defaultPalette?: Palette;\n defaultMode?: Mode;\n}\n\n/**\n * Returns an inline script that applies the stored palette and mode to\n * `<html>` before the first paint, to avoid a flash of the default theme.\n * Optional: without it the theme still works from the HTML attributes alone.\n */\nexport function getThemeScript({\n storageKey = DEFAULT_STORAGE_KEY,\n defaultPalette = DEFAULT_PALETTE,\n defaultMode = DEFAULT_MODE,\n}: ThemeScriptOptions = {}): string {\n const args = [storageKey, PALETTES, MODES, defaultPalette, defaultMode]\n .map((arg) => JSON.stringify(arg))\n .join(\",\");\n return `(function(k,P,M,dp,dm){var d=document.documentElement,s={};try{s=JSON.parse(localStorage.getItem(k)||\"{}\")||{}}catch(e){}d.setAttribute(\"data-palette\",P.indexOf(s.palette)>-1?s.palette:dp);d.setAttribute(\"data-mode\",M.indexOf(s.mode)>-1?s.mode:dm)})(${args})`;\n}\n\nexport {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n MODES,\n PALETTES,\n type Mode,\n type Palette,\n type ResolvedMode,\n} from \"./constants\";\n"],"mappings":"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","names":[]}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/theme/theme-script.ts
21
+ var theme_script_exports = {};
22
+ __export(theme_script_exports, {
23
+ DEFAULT_MODE: () => DEFAULT_MODE,
24
+ DEFAULT_PALETTE: () => DEFAULT_PALETTE,
25
+ DEFAULT_STORAGE_KEY: () => DEFAULT_STORAGE_KEY,
26
+ MODES: () => MODES,
27
+ PALETTES: () => PALETTES,
28
+ getThemeScript: () => getThemeScript
29
+ });
30
+ module.exports = __toCommonJS(theme_script_exports);
31
+
32
+ // src/theme/constants.ts
33
+ var PALETTES = ["nacre", "aurore", "couchant", "glacier"];
34
+ var MODES = ["light", "dark", "system"];
35
+ var DEFAULT_PALETTE = "nacre";
36
+ var DEFAULT_MODE = "system";
37
+ var DEFAULT_STORAGE_KEY = "@irisui/theme";
38
+
39
+ // src/theme/theme-script.ts
40
+ function getThemeScript({
41
+ storageKey = DEFAULT_STORAGE_KEY,
42
+ defaultPalette = DEFAULT_PALETTE,
43
+ defaultMode = DEFAULT_MODE
44
+ } = {}) {
45
+ const args = [storageKey, PALETTES, MODES, defaultPalette, defaultMode].map((arg) => JSON.stringify(arg)).join(",");
46
+ return `(function(k,P,M,dp,dm){var d=document.documentElement,s={};try{s=JSON.parse(localStorage.getItem(k)||"{}")||{}}catch(e){}d.setAttribute("data-palette",P.indexOf(s.palette)>-1?s.palette:dp);d.setAttribute("data-mode",M.indexOf(s.mode)>-1?s.mode:dm)})(${args})`;
47
+ }
48
+ // Annotate the CommonJS export names for ESM import in node:
49
+ 0 && (module.exports = {
50
+ DEFAULT_MODE,
51
+ DEFAULT_PALETTE,
52
+ DEFAULT_STORAGE_KEY,
53
+ MODES,
54
+ PALETTES,
55
+ getThemeScript
56
+ });
57
+ //# sourceMappingURL=theme-script.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme/theme-script.ts","../src/theme/constants.ts"],"sourcesContent":["import {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n MODES,\n PALETTES,\n type Mode,\n type Palette,\n} from \"./constants\";\n\nexport interface ThemeScriptOptions {\n storageKey?: string;\n defaultPalette?: Palette;\n defaultMode?: Mode;\n}\n\n/**\n * Returns an inline script that applies the stored palette and mode to\n * `<html>` before the first paint, to avoid a flash of the default theme.\n * Optional: without it the theme still works from the HTML attributes alone.\n */\nexport function getThemeScript({\n storageKey = DEFAULT_STORAGE_KEY,\n defaultPalette = DEFAULT_PALETTE,\n defaultMode = DEFAULT_MODE,\n}: ThemeScriptOptions = {}): string {\n const args = [storageKey, PALETTES, MODES, defaultPalette, defaultMode]\n .map((arg) => JSON.stringify(arg))\n .join(\",\");\n return `(function(k,P,M,dp,dm){var d=document.documentElement,s={};try{s=JSON.parse(localStorage.getItem(k)||\"{}\")||{}}catch(e){}d.setAttribute(\"data-palette\",P.indexOf(s.palette)>-1?s.palette:dp);d.setAttribute(\"data-mode\",M.indexOf(s.mode)>-1?s.mode:dm)})(${args})`;\n}\n\nexport {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n MODES,\n PALETTES,\n type Mode,\n type Palette,\n type ResolvedMode,\n} from \"./constants\";\n","export const PALETTES = [\"nacre\", \"aurore\", \"couchant\", \"glacier\"] as const;\nexport const MODES = [\"light\", \"dark\", \"system\"] as const;\n\nexport type Palette = (typeof PALETTES)[number];\nexport type Mode = (typeof MODES)[number];\nexport type ResolvedMode = Exclude<Mode, \"system\">;\n\nexport const DEFAULT_PALETTE: Palette = \"nacre\";\nexport const DEFAULT_MODE: Mode = \"system\";\nexport const DEFAULT_STORAGE_KEY = \"@irisui/theme\";\n\nexport const isPalette = (value: unknown): value is Palette =>\n (PALETTES as readonly unknown[]).includes(value);\nexport const isMode = (value: unknown): value is Mode =>\n (MODES as readonly unknown[]).includes(value);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,WAAW,CAAC,SAAS,UAAU,YAAY,SAAS;AAC1D,IAAM,QAAQ,CAAC,SAAS,QAAQ,QAAQ;AAMxC,IAAM,kBAA2B;AACjC,IAAM,eAAqB;AAC3B,IAAM,sBAAsB;;;ADY5B,SAAS,eAAe;AAAA,EAC7B,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,cAAc;AAChB,IAAwB,CAAC,GAAW;AAClC,QAAM,OAAO,CAAC,YAAY,UAAU,OAAO,gBAAgB,WAAW,EACnE,IAAI,CAAC,QAAQ,KAAK,UAAU,GAAG,CAAC,EAChC,KAAK,GAAG;AACX,SAAO,6PAA6P,IAAI;AAC1Q;","names":[]}
@@ -0,0 +1,22 @@
1
+ declare const PALETTES: readonly ["nacre", "aurore", "couchant", "glacier"];
2
+ declare const MODES: readonly ["light", "dark", "system"];
3
+ type Palette = (typeof PALETTES)[number];
4
+ type Mode = (typeof MODES)[number];
5
+ type ResolvedMode = Exclude<Mode, "system">;
6
+ declare const DEFAULT_PALETTE: Palette;
7
+ declare const DEFAULT_MODE: Mode;
8
+ declare const DEFAULT_STORAGE_KEY = "@irisui/theme";
9
+
10
+ interface ThemeScriptOptions {
11
+ storageKey?: string;
12
+ defaultPalette?: Palette;
13
+ defaultMode?: Mode;
14
+ }
15
+ /**
16
+ * Returns an inline script that applies the stored palette and mode to
17
+ * `<html>` before the first paint, to avoid a flash of the default theme.
18
+ * Optional: without it the theme still works from the HTML attributes alone.
19
+ */
20
+ declare function getThemeScript({ storageKey, defaultPalette, defaultMode, }?: ThemeScriptOptions): string;
21
+
22
+ export { DEFAULT_MODE, DEFAULT_PALETTE, DEFAULT_STORAGE_KEY, MODES, type Mode, PALETTES, type Palette, type ResolvedMode, type ThemeScriptOptions, getThemeScript };
@@ -0,0 +1,22 @@
1
+ declare const PALETTES: readonly ["nacre", "aurore", "couchant", "glacier"];
2
+ declare const MODES: readonly ["light", "dark", "system"];
3
+ type Palette = (typeof PALETTES)[number];
4
+ type Mode = (typeof MODES)[number];
5
+ type ResolvedMode = Exclude<Mode, "system">;
6
+ declare const DEFAULT_PALETTE: Palette;
7
+ declare const DEFAULT_MODE: Mode;
8
+ declare const DEFAULT_STORAGE_KEY = "@irisui/theme";
9
+
10
+ interface ThemeScriptOptions {
11
+ storageKey?: string;
12
+ defaultPalette?: Palette;
13
+ defaultMode?: Mode;
14
+ }
15
+ /**
16
+ * Returns an inline script that applies the stored palette and mode to
17
+ * `<html>` before the first paint, to avoid a flash of the default theme.
18
+ * Optional: without it the theme still works from the HTML attributes alone.
19
+ */
20
+ declare function getThemeScript({ storageKey, defaultPalette, defaultMode, }?: ThemeScriptOptions): string;
21
+
22
+ export { DEFAULT_MODE, DEFAULT_PALETTE, DEFAULT_STORAGE_KEY, MODES, type Mode, PALETTES, type Palette, type ResolvedMode, type ThemeScriptOptions, getThemeScript };
@@ -0,0 +1,25 @@
1
+ // src/theme/constants.ts
2
+ var PALETTES = ["nacre", "aurore", "couchant", "glacier"];
3
+ var MODES = ["light", "dark", "system"];
4
+ var DEFAULT_PALETTE = "nacre";
5
+ var DEFAULT_MODE = "system";
6
+ var DEFAULT_STORAGE_KEY = "@irisui/theme";
7
+
8
+ // src/theme/theme-script.ts
9
+ function getThemeScript({
10
+ storageKey = DEFAULT_STORAGE_KEY,
11
+ defaultPalette = DEFAULT_PALETTE,
12
+ defaultMode = DEFAULT_MODE
13
+ } = {}) {
14
+ const args = [storageKey, PALETTES, MODES, defaultPalette, defaultMode].map((arg) => JSON.stringify(arg)).join(",");
15
+ return `(function(k,P,M,dp,dm){var d=document.documentElement,s={};try{s=JSON.parse(localStorage.getItem(k)||"{}")||{}}catch(e){}d.setAttribute("data-palette",P.indexOf(s.palette)>-1?s.palette:dp);d.setAttribute("data-mode",M.indexOf(s.mode)>-1?s.mode:dm)})(${args})`;
16
+ }
17
+ export {
18
+ DEFAULT_MODE,
19
+ DEFAULT_PALETTE,
20
+ DEFAULT_STORAGE_KEY,
21
+ MODES,
22
+ PALETTES,
23
+ getThemeScript
24
+ };
25
+ //# sourceMappingURL=theme-script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme/constants.ts","../src/theme/theme-script.ts"],"sourcesContent":["export const PALETTES = [\"nacre\", \"aurore\", \"couchant\", \"glacier\"] as const;\nexport const MODES = [\"light\", \"dark\", \"system\"] as const;\n\nexport type Palette = (typeof PALETTES)[number];\nexport type Mode = (typeof MODES)[number];\nexport type ResolvedMode = Exclude<Mode, \"system\">;\n\nexport const DEFAULT_PALETTE: Palette = \"nacre\";\nexport const DEFAULT_MODE: Mode = \"system\";\nexport const DEFAULT_STORAGE_KEY = \"@irisui/theme\";\n\nexport const isPalette = (value: unknown): value is Palette =>\n (PALETTES as readonly unknown[]).includes(value);\nexport const isMode = (value: unknown): value is Mode =>\n (MODES as readonly unknown[]).includes(value);\n","import {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n MODES,\n PALETTES,\n type Mode,\n type Palette,\n} from \"./constants\";\n\nexport interface ThemeScriptOptions {\n storageKey?: string;\n defaultPalette?: Palette;\n defaultMode?: Mode;\n}\n\n/**\n * Returns an inline script that applies the stored palette and mode to\n * `<html>` before the first paint, to avoid a flash of the default theme.\n * Optional: without it the theme still works from the HTML attributes alone.\n */\nexport function getThemeScript({\n storageKey = DEFAULT_STORAGE_KEY,\n defaultPalette = DEFAULT_PALETTE,\n defaultMode = DEFAULT_MODE,\n}: ThemeScriptOptions = {}): string {\n const args = [storageKey, PALETTES, MODES, defaultPalette, defaultMode]\n .map((arg) => JSON.stringify(arg))\n .join(\",\");\n return `(function(k,P,M,dp,dm){var d=document.documentElement,s={};try{s=JSON.parse(localStorage.getItem(k)||\"{}\")||{}}catch(e){}d.setAttribute(\"data-palette\",P.indexOf(s.palette)>-1?s.palette:dp);d.setAttribute(\"data-mode\",M.indexOf(s.mode)>-1?s.mode:dm)})(${args})`;\n}\n\nexport {\n DEFAULT_MODE,\n DEFAULT_PALETTE,\n DEFAULT_STORAGE_KEY,\n MODES,\n PALETTES,\n type Mode,\n type Palette,\n type ResolvedMode,\n} from \"./constants\";\n"],"mappings":";AAAO,IAAM,WAAW,CAAC,SAAS,UAAU,YAAY,SAAS;AAC1D,IAAM,QAAQ,CAAC,SAAS,QAAQ,QAAQ;AAMxC,IAAM,kBAA2B;AACjC,IAAM,eAAqB;AAC3B,IAAM,sBAAsB;;;ACY5B,SAAS,eAAe;AAAA,EAC7B,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,cAAc;AAChB,IAAwB,CAAC,GAAW;AAClC,QAAM,OAAO,CAAC,YAAY,UAAU,OAAO,gBAAgB,WAAW,EACnE,IAAI,CAAC,QAAQ,KAAK,UAAU,GAAG,CAAC,EAChC,KAAK,GAAG;AACX,SAAO,6PAA6P,IAAI;AAC1Q;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,67 @@
1
1
  {
2
2
  "name": "@irisui/ui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.1",
4
+ "description": "Accessible React components in the Verre irisé style.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "main": "./dist/index.cjs",
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "import": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "require": {
21
+ "types": "./dist/index.d.cts",
22
+ "default": "./dist/index.cjs"
23
+ }
24
+ },
25
+ "./theme-script": {
26
+ "import": {
27
+ "types": "./dist/theme-script.d.ts",
28
+ "default": "./dist/theme-script.js"
29
+ },
30
+ "require": {
31
+ "types": "./dist/theme-script.d.cts",
32
+ "default": "./dist/theme-script.cjs"
33
+ }
34
+ }
35
+ },
36
+ "dependencies": {
37
+ "@irisui/tokens": "0.1.1",
38
+ "@irisui/utils": "0.1.1"
39
+ },
40
+ "peerDependencies": {
41
+ "react": "^18.2.0 || ^19.0.0",
42
+ "react-dom": "^18.2.0 || ^19.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/react": "19.3.0",
46
+ "@types/react-dom": "19.3.0",
47
+ "react": "19.3.0",
48
+ "react-dom": "19.3.0"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "repository": {
54
+ "type": "git",
55
+ "url": "git+https://github.com/theteqlab/iris-ui.git",
56
+ "directory": "packages/ui"
57
+ },
58
+ "homepage": "https://github.com/theteqlab/iris-ui#readme",
59
+ "bugs": {
60
+ "url": "https://github.com/theteqlab/iris-ui/issues"
61
+ },
62
+ "scripts": {
63
+ "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsup",
64
+ "dev": "tsup --watch",
65
+ "typecheck": "tsc -p tsconfig.json"
66
+ }
6
67
  }