@refine-studio/ui 0.0.0-stage → 0.1.0
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 +21 -0
- package/README.md +102 -2
- package/dist/components/accordion/accordion.d.ts +15 -0
- package/dist/components/accordion/accordion.js +58 -0
- package/dist/components/accordion/accordion.js.map +1 -0
- package/dist/components/alert/alert.d.ts +24 -0
- package/dist/components/alert/alert.js +98 -0
- package/dist/components/alert/alert.js.map +1 -0
- package/dist/components/alert-dialog/alert-dialog.d.ts +36 -0
- package/dist/components/alert-dialog/alert-dialog.js +112 -0
- package/dist/components/alert-dialog/alert-dialog.js.map +1 -0
- package/dist/components/app-shell/app-shell.d.ts +77 -0
- package/dist/components/app-shell/app-shell.js +224 -0
- package/dist/components/app-shell/app-shell.js.map +1 -0
- package/dist/components/avatar/avatar.d.ts +32 -0
- package/dist/components/avatar/avatar.js +83 -0
- package/dist/components/avatar/avatar.js.map +1 -0
- package/dist/components/badge/badge.d.ts +15 -0
- package/dist/components/badge/badge.js +50 -0
- package/dist/components/badge/badge.js.map +1 -0
- package/dist/components/breadcrumb/breadcrumb.d.ts +24 -0
- package/dist/components/breadcrumb/breadcrumb.js +82 -0
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/components/button/button.d.ts +15 -0
- package/dist/components/button/button.js +75 -0
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/card/card.d.ts +46 -0
- package/dist/components/card/card.js +124 -0
- package/dist/components/card/card.js.map +1 -0
- package/dist/components/checkbox/checkbox.d.ts +6 -0
- package/dist/components/checkbox/checkbox.js +31 -0
- package/dist/components/checkbox/checkbox.js.map +1 -0
- package/dist/components/chip/chip.d.ts +25 -0
- package/dist/components/chip/chip.js +54 -0
- package/dist/components/chip/chip.js.map +1 -0
- package/dist/components/code/code.d.ts +15 -0
- package/dist/components/code/code.js +63 -0
- package/dist/components/code/code.js.map +1 -0
- package/dist/components/collapsible/collapsible.d.ts +14 -0
- package/dist/components/collapsible/collapsible.js +55 -0
- package/dist/components/collapsible/collapsible.js.map +1 -0
- package/dist/components/combobox/combobox.d.ts +33 -0
- package/dist/components/combobox/combobox.js +244 -0
- package/dist/components/combobox/combobox.js.map +1 -0
- package/dist/components/command-menu/command-menu.d.ts +35 -0
- package/dist/components/command-menu/command-menu.js +116 -0
- package/dist/components/command-menu/command-menu.js.map +1 -0
- package/dist/components/context-menu/context-menu.d.ts +45 -0
- package/dist/components/context-menu/context-menu.js +136 -0
- package/dist/components/context-menu/context-menu.js.map +1 -0
- package/dist/components/data-table/data-table.d.ts +49 -0
- package/dist/components/data-table/data-table.js +171 -0
- package/dist/components/data-table/data-table.js.map +1 -0
- package/dist/components/data-table/sort-rows.d.ts +6 -0
- package/dist/components/data-table/sort-rows.js +33 -0
- package/dist/components/data-table/sort-rows.js.map +1 -0
- package/dist/components/dialog/dialog.d.ts +42 -0
- package/dist/components/dialog/dialog.js +118 -0
- package/dist/components/dialog/dialog.js.map +1 -0
- package/dist/components/dropdown-menu/dropdown-menu.d.ts +45 -0
- package/dist/components/dropdown-menu/dropdown-menu.js +137 -0
- package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -0
- package/dist/components/dropdown-menu/menu-styles.d.ts +10 -0
- package/dist/components/dropdown-menu/menu-styles.js +34 -0
- package/dist/components/dropdown-menu/menu-styles.js.map +1 -0
- package/dist/components/empty-state/empty-state.d.ts +12 -0
- package/dist/components/empty-state/empty-state.js +46 -0
- package/dist/components/empty-state/empty-state.js.map +1 -0
- package/dist/components/eyebrow/eyebrow.d.ts +9 -0
- package/dist/components/eyebrow/eyebrow.js +25 -0
- package/dist/components/eyebrow/eyebrow.js.map +1 -0
- package/dist/components/field/field.d.ts +56 -0
- package/dist/components/field/field.js +135 -0
- package/dist/components/field/field.js.map +1 -0
- package/dist/components/glow-border/glow-border.d.ts +9 -0
- package/dist/components/glow-border/glow-border.js +39 -0
- package/dist/components/glow-border/glow-border.js.map +1 -0
- package/dist/components/hex-field/hex-field.d.ts +12 -0
- package/dist/components/hex-field/hex-field.js +86 -0
- package/dist/components/hex-field/hex-field.js.map +1 -0
- package/dist/components/input/input.d.ts +14 -0
- package/dist/components/input/input.js +52 -0
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/kbd/kbd.d.ts +9 -0
- package/dist/components/kbd/kbd.js +26 -0
- package/dist/components/kbd/kbd.js.map +1 -0
- package/dist/components/label/label.d.ts +6 -0
- package/dist/components/label/label.js +17 -0
- package/dist/components/label/label.js.map +1 -0
- package/dist/components/logo/logo-paths.d.ts +5 -0
- package/dist/components/logo/logo-paths.js +20 -0
- package/dist/components/logo/logo-paths.js.map +1 -0
- package/dist/components/logo/logo.d.ts +18 -0
- package/dist/components/logo/logo.js +94 -0
- package/dist/components/logo/logo.js.map +1 -0
- package/dist/components/marquee/marquee.d.ts +15 -0
- package/dist/components/marquee/marquee.js +54 -0
- package/dist/components/marquee/marquee.js.map +1 -0
- package/dist/components/page-header/page-header.d.ts +15 -0
- package/dist/components/page-header/page-header.js +50 -0
- package/dist/components/page-header/page-header.js.map +1 -0
- package/dist/components/pagination/pagination.d.ts +28 -0
- package/dist/components/pagination/pagination.js +95 -0
- package/dist/components/pagination/pagination.js.map +1 -0
- package/dist/components/popover/popover.d.ts +14 -0
- package/dist/components/popover/popover.js +48 -0
- package/dist/components/popover/popover.js.map +1 -0
- package/dist/components/progress/progress.d.ts +14 -0
- package/dist/components/progress/progress.js +41 -0
- package/dist/components/progress/progress.js.map +1 -0
- package/dist/components/radio-group/radio-group.d.ts +10 -0
- package/dist/components/radio-group/radio-group.js +33 -0
- package/dist/components/radio-group/radio-group.js.map +1 -0
- package/dist/components/section-heading/section-heading.d.ts +18 -0
- package/dist/components/section-heading/section-heading.js +57 -0
- package/dist/components/section-heading/section-heading.js.map +1 -0
- package/dist/components/select/select.d.ts +32 -0
- package/dist/components/select/select.js +100 -0
- package/dist/components/select/select.js.map +1 -0
- package/dist/components/separator/separator.d.ts +10 -0
- package/dist/components/separator/separator.js +37 -0
- package/dist/components/separator/separator.js.map +1 -0
- package/dist/components/sheet/sheet.d.ts +29 -0
- package/dist/components/sheet/sheet.js +130 -0
- package/dist/components/sheet/sheet.js.map +1 -0
- package/dist/components/skeleton/skeleton.d.ts +5 -0
- package/dist/components/skeleton/skeleton.js +18 -0
- package/dist/components/skeleton/skeleton.js.map +1 -0
- package/dist/components/slider/slider.d.ts +10 -0
- package/dist/components/slider/slider.js +36 -0
- package/dist/components/slider/slider.js.map +1 -0
- package/dist/components/spinner/spinner.d.ts +9 -0
- package/dist/components/spinner/spinner.js +40 -0
- package/dist/components/spinner/spinner.js.map +1 -0
- package/dist/components/spotlight/spotlight.d.ts +9 -0
- package/dist/components/spotlight/spotlight.js +32 -0
- package/dist/components/spotlight/spotlight.js.map +1 -0
- package/dist/components/starfield/starfield.d.ts +11 -0
- package/dist/components/starfield/starfield.js +76 -0
- package/dist/components/starfield/starfield.js.map +1 -0
- package/dist/components/stat/stat.d.ts +28 -0
- package/dist/components/stat/stat.js +100 -0
- package/dist/components/stat/stat.js.map +1 -0
- package/dist/components/switch/switch.d.ts +13 -0
- package/dist/components/switch/switch.js +44 -0
- package/dist/components/switch/switch.js.map +1 -0
- package/dist/components/table/table.d.ts +52 -0
- package/dist/components/table/table.js +96 -0
- package/dist/components/table/table.js.map +1 -0
- package/dist/components/tabs/tabs.d.ts +24 -0
- package/dist/components/tabs/tabs.js +89 -0
- package/dist/components/tabs/tabs.js.map +1 -0
- package/dist/components/textarea/textarea.d.ts +5 -0
- package/dist/components/textarea/textarea.js +20 -0
- package/dist/components/textarea/textarea.js.map +1 -0
- package/dist/components/theme-switcher/theme-switcher.d.ts +7 -0
- package/dist/components/theme-switcher/theme-switcher.js +57 -0
- package/dist/components/theme-switcher/theme-switcher.js.map +1 -0
- package/dist/components/toaster/toaster.d.ts +7 -0
- package/dist/components/toaster/toaster.js +43 -0
- package/dist/components/toaster/toaster.js.map +1 -0
- package/dist/components/toggle-group/toggle-group.d.ts +24 -0
- package/dist/components/toggle-group/toggle-group.js +84 -0
- package/dist/components/toggle-group/toggle-group.js.map +1 -0
- package/dist/components/tooltip/tooltip.d.ts +19 -0
- package/dist/components/tooltip/tooltip.js +49 -0
- package/dist/components/tooltip/tooltip.js.map +1 -0
- package/dist/fonts/geist-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-cyrillic-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-symbols2-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-vietnamese-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono.LICENSE +93 -0
- package/dist/fonts/geist-vietnamese-wght-normal.woff2 +0 -0
- package/dist/fonts/geist.LICENSE +93 -0
- package/dist/icons/create-refine-icon.d.ts +13 -0
- package/dist/icons/create-refine-icon.js +37 -0
- package/dist/icons/create-refine-icon.js.map +1 -0
- package/dist/icons/icon.d.ts +10 -0
- package/dist/icons/icon.js +13 -0
- package/dist/icons/icon.js.map +1 -0
- package/dist/icons/refine-icon-names.d.ts +1857 -0
- package/dist/icons/refine-icon-names.js +471 -0
- package/dist/icons/refine-icon-names.js.map +1 -0
- package/dist/icons/refine-icons.d.ts +1852 -0
- package/dist/icons/refine-icons.js +604 -0
- package/dist/icons/refine-icons.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +61 -0
- package/dist/lib/cn.d.ts +5 -0
- package/dist/lib/cn.js +49 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/use-breakpoint.d.ts +16 -0
- package/dist/lib/use-breakpoint.js +52 -0
- package/dist/lib/use-breakpoint.js.map +1 -0
- package/dist/styles.css +697 -0
- package/dist/theme/theme-provider.d.ts +31 -0
- package/dist/theme/theme-provider.js +115 -0
- package/dist/theme/theme-provider.js.map +1 -0
- package/dist/theme/theme-scope.d.ts +12 -0
- package/dist/theme/theme-scope.js +22 -0
- package/dist/theme/theme-scope.js.map +1 -0
- package/dist/theme/theme.d.ts +20 -0
- package/dist/theme/theme.js +37 -0
- package/dist/theme/theme.js.map +1 -0
- package/package.json +92 -4
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type ThemeSettings } from './theme';
|
|
3
|
+
interface ThemeContextValue extends ThemeSettings {
|
|
4
|
+
resolvedMode: 'dark' | 'light';
|
|
5
|
+
setTheme: (settings: Partial<ThemeSettings>) => void;
|
|
6
|
+
}
|
|
7
|
+
interface ThemeProviderProps extends Partial<ThemeSettings> {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
storageKey?: string | false;
|
|
10
|
+
}
|
|
11
|
+
interface ThemeScriptOptions extends Partial<ThemeSettings> {
|
|
12
|
+
/**
|
|
13
|
+
* A key that holds `true` for dark or `false` for light. Its choice moves to `storageKey` once, then the key is removed.
|
|
14
|
+
*/
|
|
15
|
+
legacyStorageKey?: string;
|
|
16
|
+
storageKey?: string | false;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns an inline `<script>` body for the page head that applies the stored or the system theme before the first paint.
|
|
20
|
+
* Pass the same `storageKey`, `mode` and `density` as to `ThemeProvider`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const themeScript: ({ density, legacyStorageKey, mode, storageKey, }?: ThemeScriptOptions) => string;
|
|
23
|
+
/**
|
|
24
|
+
* Owns the document theme: applies mode and density to `<html>`, follows the OS in `system` mode, and persists changes under `storageKey`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const ThemeProvider: ({ children, density, mode, storageKey, }: ThemeProviderProps) => import("react").JSX.Element;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the current theme and its setter; throws outside a `ThemeProvider`.
|
|
29
|
+
*/
|
|
30
|
+
export declare const useTheme: () => ThemeContextValue;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { DEFAULT_THEME, DENSITIES, MODES, applyTheme } from "./theme.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { createContext, use, useEffect, useState, useSyncExternalStore } from "react";
|
|
5
|
+
// src/theme/theme-provider.tsx
|
|
6
|
+
var ThemeContext = createContext(null);
|
|
7
|
+
var DEFAULT_STORAGE_KEY = "refine-ui-theme";
|
|
8
|
+
var DARK_QUERY = "(prefers-color-scheme: dark)";
|
|
9
|
+
/**
|
|
10
|
+
* Reads the stored theme once on mount, keeping only the values `MODES` and `DENSITIES` allow.
|
|
11
|
+
*/
|
|
12
|
+
var readStoredTheme = (storageKey) => {
|
|
13
|
+
if (!storageKey || typeof window === "undefined") return {};
|
|
14
|
+
try {
|
|
15
|
+
const stored = JSON.parse(window.localStorage.getItem(storageKey) ?? "{}");
|
|
16
|
+
const settings = {};
|
|
17
|
+
const storedMode = MODES.find((value) => {
|
|
18
|
+
return value === stored?.mode;
|
|
19
|
+
});
|
|
20
|
+
const storedDensity = DENSITIES.find((value) => {
|
|
21
|
+
return value === stored?.density;
|
|
22
|
+
});
|
|
23
|
+
if (storedMode) settings.mode = storedMode;
|
|
24
|
+
if (storedDensity) settings.density = storedDensity;
|
|
25
|
+
return settings;
|
|
26
|
+
} catch {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Returns an inline `<script>` body for the page head that applies the stored or the system theme before the first paint.
|
|
32
|
+
* Pass the same `storageKey`, `mode` and `density` as to `ThemeProvider`.
|
|
33
|
+
*/
|
|
34
|
+
var themeScript = ({ density = DEFAULT_THEME.density, legacyStorageKey, mode = DEFAULT_THEME.mode, storageKey = DEFAULT_STORAGE_KEY } = {}) => {
|
|
35
|
+
return `(function(key,legacyKey,mode,density,modes,densities,darkQuery){var stored={};try{var storage=window.localStorage;if(key){var legacy=legacyKey&&storage.getItem(key)===null?storage.getItem(legacyKey):null;if(legacy==='true'||legacy==='false')storage.setItem(key,JSON.stringify({mode:legacy==='true'?'dark':'light'}));if(legacyKey)storage.removeItem(legacyKey);stored=JSON.parse(storage.getItem(key)||'{}')||{};}}catch(error){}if(modes.indexOf(stored.mode)>-1)mode=stored.mode;if(densities.indexOf(stored.density)>-1)density=stored.density;if(mode==='system')mode=window.matchMedia(darkQuery).matches?'dark':'light';var root=document.documentElement;root.classList.toggle('dark',mode==='dark');root.classList.toggle('light',mode==='light');root.dataset.density=density;})(${[
|
|
36
|
+
storageKey,
|
|
37
|
+
legacyStorageKey ?? null,
|
|
38
|
+
mode,
|
|
39
|
+
density,
|
|
40
|
+
MODES,
|
|
41
|
+
DENSITIES,
|
|
42
|
+
DARK_QUERY
|
|
43
|
+
].map((value) => {
|
|
44
|
+
return JSON.stringify(value).replace(/</g, "\\u003c");
|
|
45
|
+
}).join(",")});`;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Subscribes to changes of the operating system's colour preference.
|
|
49
|
+
*/
|
|
50
|
+
var subscribeToSystemMode = (onChange) => {
|
|
51
|
+
const query = window.matchMedia(DARK_QUERY);
|
|
52
|
+
query.addEventListener("change", onChange);
|
|
53
|
+
return () => {
|
|
54
|
+
query.removeEventListener("change", onChange);
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Owns the document theme: applies mode and density to `<html>`, follows the OS in `system` mode, and persists changes under `storageKey`.
|
|
59
|
+
*/
|
|
60
|
+
var ThemeProvider = ({ children, density = DEFAULT_THEME.density, mode = DEFAULT_THEME.mode, storageKey = DEFAULT_STORAGE_KEY }) => {
|
|
61
|
+
const [settings, setSettings] = useState(() => {
|
|
62
|
+
return {
|
|
63
|
+
density,
|
|
64
|
+
mode,
|
|
65
|
+
...readStoredTheme(storageKey)
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
const systemMode = useSyncExternalStore(subscribeToSystemMode, () => {
|
|
69
|
+
return window.matchMedia(DARK_QUERY).matches ? "dark" : "light";
|
|
70
|
+
}, () => {
|
|
71
|
+
return "light";
|
|
72
|
+
});
|
|
73
|
+
const resolvedMode = settings.mode === "system" ? systemMode : settings.mode;
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
applyTheme(document.documentElement, {
|
|
76
|
+
...settings,
|
|
77
|
+
mode: resolvedMode
|
|
78
|
+
});
|
|
79
|
+
if (storageKey) window.localStorage.setItem(storageKey, JSON.stringify(settings));
|
|
80
|
+
}, [
|
|
81
|
+
resolvedMode,
|
|
82
|
+
settings,
|
|
83
|
+
storageKey
|
|
84
|
+
]);
|
|
85
|
+
/**
|
|
86
|
+
* Merges a partial theme into the current one.
|
|
87
|
+
*/
|
|
88
|
+
const setTheme = (nextSettings) => {
|
|
89
|
+
setSettings((current) => {
|
|
90
|
+
return {
|
|
91
|
+
...current,
|
|
92
|
+
...nextSettings
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
return /* @__PURE__ */ jsx(ThemeContext, {
|
|
97
|
+
value: {
|
|
98
|
+
...settings,
|
|
99
|
+
resolvedMode,
|
|
100
|
+
setTheme
|
|
101
|
+
},
|
|
102
|
+
children
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Returns the current theme and its setter; throws outside a `ThemeProvider`.
|
|
107
|
+
*/
|
|
108
|
+
var useTheme = () => {
|
|
109
|
+
const context = use(ThemeContext);
|
|
110
|
+
if (!context) throw new Error("useTheme must be used inside a ThemeProvider.");
|
|
111
|
+
return context;
|
|
112
|
+
};
|
|
113
|
+
export { ThemeProvider, themeScript, useTheme };
|
|
114
|
+
|
|
115
|
+
//# sourceMappingURL=theme-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-provider.js","names":[],"sources":["../../src/theme/theme-provider.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, type ReactNode, use, useEffect, useState, useSyncExternalStore } from 'react';\n\nimport { applyTheme, DEFAULT_THEME, DENSITIES, MODES, type ThemeSettings } from './theme';\n\ninterface ThemeContextValue extends ThemeSettings {\n resolvedMode: 'dark' | 'light';\n setTheme: (settings: Partial<ThemeSettings>) => void;\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null);\n\nconst DEFAULT_STORAGE_KEY = 'refine-ui-theme';\nconst DARK_QUERY = '(prefers-color-scheme: dark)';\n\ninterface ThemeProviderProps extends Partial<ThemeSettings> {\n children: ReactNode;\n storageKey?: string | false;\n}\n\n/**\n * Reads the stored theme once on mount, keeping only the values `MODES` and `DENSITIES` allow.\n */\nconst readStoredTheme = (storageKey: string | false) => {\n if (!storageKey || typeof window === 'undefined') return {};\n\n try {\n const stored = JSON.parse(window.localStorage.getItem(storageKey) ?? '{}') as Record<string, unknown> | null;\n const settings: Partial<ThemeSettings> = {};\n const storedMode = MODES.find((value) => {\n return value === stored?.mode;\n });\n const storedDensity = DENSITIES.find((value) => {\n return value === stored?.density;\n });\n if (storedMode) settings.mode = storedMode;\n if (storedDensity) settings.density = storedDensity;\n\n return settings;\n } catch {\n // A corrupted entry falls back to the defaults rather than breaking the app.\n return {};\n }\n};\n\ninterface ThemeScriptOptions extends Partial<ThemeSettings> {\n /**\n * A key that holds `true` for dark or `false` for light. Its choice moves to `storageKey` once, then the key is removed.\n */\n legacyStorageKey?: string;\n storageKey?: string | false;\n}\n\n/**\n * Returns an inline `<script>` body for the page head that applies the stored or the system theme before the first paint.\n * Pass the same `storageKey`, `mode` and `density` as to `ThemeProvider`.\n */\nexport const themeScript = ({\n density = DEFAULT_THEME.density,\n legacyStorageKey,\n mode = DEFAULT_THEME.mode,\n storageKey = DEFAULT_STORAGE_KEY,\n}: ThemeScriptOptions = {}) => {\n const args = [storageKey, legacyStorageKey ?? null, mode, density, MODES, DENSITIES, DARK_QUERY]\n .map((value) => {\n return JSON.stringify(value).replace(/</g, '\\\\u003c');\n })\n .join(',');\n\n return `(function(key,legacyKey,mode,density,modes,densities,darkQuery){var stored={};try{var storage=window.localStorage;if(key){var legacy=legacyKey&&storage.getItem(key)===null?storage.getItem(legacyKey):null;if(legacy==='true'||legacy==='false')storage.setItem(key,JSON.stringify({mode:legacy==='true'?'dark':'light'}));if(legacyKey)storage.removeItem(legacyKey);stored=JSON.parse(storage.getItem(key)||'{}')||{};}}catch(error){}if(modes.indexOf(stored.mode)>-1)mode=stored.mode;if(densities.indexOf(stored.density)>-1)density=stored.density;if(mode==='system')mode=window.matchMedia(darkQuery).matches?'dark':'light';var root=document.documentElement;root.classList.toggle('dark',mode==='dark');root.classList.toggle('light',mode==='light');root.dataset.density=density;})(${args});`;\n};\n\n/**\n * Subscribes to changes of the operating system's colour preference.\n */\nconst subscribeToSystemMode = (onChange: () => void) => {\n const query = window.matchMedia(DARK_QUERY);\n query.addEventListener('change', onChange);\n\n return () => {\n query.removeEventListener('change', onChange);\n };\n};\n\n/**\n * Owns the document theme: applies mode and density to `<html>`, follows the OS in `system` mode, and persists changes under `storageKey`.\n */\nexport const ThemeProvider = ({\n children,\n density = DEFAULT_THEME.density,\n mode = DEFAULT_THEME.mode,\n storageKey = DEFAULT_STORAGE_KEY,\n}: ThemeProviderProps) => {\n const [settings, setSettings] = useState<ThemeSettings>(() => {\n return {\n density,\n mode,\n ...readStoredTheme(storageKey),\n };\n });\n const systemMode = useSyncExternalStore(\n subscribeToSystemMode,\n () => {\n return window.matchMedia(DARK_QUERY).matches ? 'dark' : 'light';\n },\n () => {\n return 'light' as const;\n },\n );\n const resolvedMode = settings.mode === 'system' ? systemMode : settings.mode;\n\n useEffect(() => {\n applyTheme(document.documentElement, {\n ...settings,\n mode: resolvedMode,\n });\n if (storageKey) window.localStorage.setItem(storageKey, JSON.stringify(settings));\n }, [resolvedMode, settings, storageKey]);\n\n /**\n * Merges a partial theme into the current one.\n */\n const setTheme = (nextSettings: Partial<ThemeSettings>) => {\n setSettings((current) => {\n return {\n ...current,\n ...nextSettings,\n };\n });\n };\n\n return <ThemeContext value={{ ...settings, resolvedMode, setTheme }}>{children}</ThemeContext>;\n};\n\n/**\n * Returns the current theme and its setter; throws outside a `ThemeProvider`.\n */\nexport const useTheme = () => {\n const context = use(ThemeContext);\n if (!context) throw new Error('useTheme must be used inside a ThemeProvider.');\n\n return context;\n};\n"],"mappings":";;;;;AAWA,IAAM,eAAe,cAAwC,IAAI;AAEjE,IAAM,sBAAsB;AAC5B,IAAM,aAAa;;;;AAUnB,IAAM,mBAAmB,eAA+B;CACtD,IAAI,CAAC,cAAc,OAAO,WAAW,aAAa,OAAO,CAAC;CAE1D,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,OAAO,aAAa,QAAQ,UAAU,KAAK,IAAI;EACzE,MAAM,WAAmC,CAAC;EAC1C,MAAM,aAAa,MAAM,MAAM,UAAU;GACvC,OAAO,UAAU,QAAQ;EAC3B,CAAC;EACD,MAAM,gBAAgB,UAAU,MAAM,UAAU;GAC9C,OAAO,UAAU,QAAQ;EAC3B,CAAC;EACD,IAAI,YAAY,SAAS,OAAO;EAChC,IAAI,eAAe,SAAS,UAAU;EAEtC,OAAO;CACT,QAAQ;EAEN,OAAO,CAAC;CACV;AACF;;;;;AAcA,IAAa,eAAe,EAC1B,UAAU,cAAc,SACxB,kBACA,OAAO,cAAc,MACrB,aAAa,wBACS,CAAC,MAAM;CAO7B,OAAO,qwBANM;EAAC;EAAY,oBAAoB;EAAM;EAAM;EAAS;EAAO;EAAW;CAAU,CAAC,CAC7F,KAAK,UAAU;EACd,OAAO,KAAK,UAAU,KAAK,CAAC,CAAC,QAAQ,MAAM,SAAS;CACtD,CAAC,CAAC,CACD,KAAK,GAEowB,EAAK;AACnxB;;;;AAKA,IAAM,yBAAyB,aAAyB;CACtD,MAAM,QAAQ,OAAO,WAAW,UAAU;CAC1C,MAAM,iBAAiB,UAAU,QAAQ;CAEzC,aAAa;EACX,MAAM,oBAAoB,UAAU,QAAQ;CAC9C;AACF;;;;AAKA,IAAa,iBAAiB,EAC5B,UACA,UAAU,cAAc,SACxB,OAAO,cAAc,MACrB,aAAa,0BACW;CACxB,MAAM,CAAC,UAAU,eAAe,eAA8B;EAC5D,OAAO;GACL;GACA;GACA,GAAG,gBAAgB,UAAU;EAC/B;CACF,CAAC;CACD,MAAM,aAAa,qBACjB,6BACM;EACJ,OAAO,OAAO,WAAW,UAAU,CAAC,CAAC,UAAU,SAAS;CAC1D,SACM;EACJ,OAAO;CACT,CACF;CACA,MAAM,eAAe,SAAS,SAAS,WAAW,aAAa,SAAS;CAExE,gBAAgB;EACd,WAAW,SAAS,iBAAiB;GACnC,GAAG;GACH,MAAM;EACR,CAAC;EACD,IAAI,YAAY,OAAO,aAAa,QAAQ,YAAY,KAAK,UAAU,QAAQ,CAAC;CAClF,GAAG;EAAC;EAAc;EAAU;CAAU,CAAC;;;;CAKvC,MAAM,YAAY,iBAAyC;EACzD,aAAa,YAAY;GACvB,OAAO;IACL,GAAG;IACH,GAAG;GACL;EACF,CAAC;CACH;CAEA,OAAO,oBAAC,cAAD;EAAc,OAAO;GAAE,GAAG;GAAU;GAAc;EAAS;EAAI;CAAuB,CAAA;AAC/F;;;;AAKA,IAAa,iBAAiB;CAC5B,MAAM,UAAU,IAAI,YAAY;CAChC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,+CAA+C;CAE7E,OAAO;AACT"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import type { Density } from './theme';
|
|
3
|
+
interface ThemeScopeProps extends ComponentProps<'div'> {
|
|
4
|
+
asChild?: boolean;
|
|
5
|
+
density?: Density;
|
|
6
|
+
mode?: 'dark' | 'light' | 'on-gem';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Re-themes one subtree — a dark sidebar in a light app, a brand panel on the gem gradient, a compact table — without touching the document theme.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ThemeScope: ({ asChild, className, density, mode, ...props }: ThemeScopeProps) => import("react").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { Slot } from "radix-ui";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
// src/theme/theme-scope.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Re-themes one subtree — a dark sidebar in a light app, a brand panel on the gem gradient, a compact table — without touching the document theme.
|
|
7
|
+
*/
|
|
8
|
+
var ThemeScope = ({ asChild = false, className, density, mode, ...props }) => {
|
|
9
|
+
const Component = asChild ? Slot.Root : "div";
|
|
10
|
+
return /* @__PURE__ */ jsx(Component, {
|
|
11
|
+
className: cn(mode, {
|
|
12
|
+
"bg-background text-foreground": mode === "dark" || mode === "light",
|
|
13
|
+
"bg-gem-gradient": mode === "on-gem"
|
|
14
|
+
}, className),
|
|
15
|
+
"data-density": density,
|
|
16
|
+
"data-slot": "theme-scope",
|
|
17
|
+
...props
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
export { ThemeScope };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=theme-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-scope.js","names":[],"sources":["../../src/theme/theme-scope.tsx"],"sourcesContent":["import { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport type { Density } from './theme';\n\ninterface ThemeScopeProps extends ComponentProps<'div'> {\n asChild?: boolean;\n density?: Density;\n mode?: 'dark' | 'light' | 'on-gem';\n}\n\n/**\n * Re-themes one subtree — a dark sidebar in a light app, a brand panel on the gem gradient, a compact table — without touching the document theme.\n */\nexport const ThemeScope = ({ asChild = false, className, density, mode, ...props }: ThemeScopeProps) => {\n const Component = asChild ? Slot.Root : 'div';\n\n return (\n <Component\n className={cn(\n mode,\n {\n 'bg-background text-foreground': mode === 'dark' || mode === 'light',\n 'bg-gem-gradient': mode === 'on-gem',\n },\n className,\n )}\n data-density={density}\n data-slot=\"theme-scope\"\n {...props}\n />\n );\n};\n"],"mappings":";;;;;;;AAeA,IAAa,cAAc,EAAE,UAAU,OAAO,WAAW,SAAS,MAAM,GAAG,YAA6B;CACtG,MAAM,YAAY,UAAU,KAAK,OAAO;CAExC,OACE,oBAAC,WAAD;EACE,WAAW,GACT,MACA;GACE,iCAAiC,SAAS,UAAU,SAAS;GAC7D,mBAAmB,SAAS;EAC9B,GACA,SACF;EACA,gBAAc;EACd,aAAU;EACV,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const MODES: readonly ["light", "dark", "system"];
|
|
2
|
+
export declare const DENSITIES: readonly ["compact", "comfortable", "spacious"];
|
|
3
|
+
export type Mode = (typeof MODES)[number];
|
|
4
|
+
export type Density = (typeof DENSITIES)[number];
|
|
5
|
+
export interface ThemeSettings {
|
|
6
|
+
density: Density;
|
|
7
|
+
mode: Mode;
|
|
8
|
+
}
|
|
9
|
+
export declare const DEFAULT_THEME: {
|
|
10
|
+
density: "comfortable";
|
|
11
|
+
mode: "system";
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Resolves `system` to the colour mode the operating system currently prefers, and passes `light` and `dark` through.
|
|
15
|
+
*/
|
|
16
|
+
export declare const resolveMode: (mode: Mode) => "light" | "dark";
|
|
17
|
+
/**
|
|
18
|
+
* Writes the theme onto an element as a `light`/`dark` class and a `data-density` attribute.
|
|
19
|
+
*/
|
|
20
|
+
export declare const applyTheme: (element: HTMLElement, settings: Partial<ThemeSettings>) => void;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// src/theme/theme.ts
|
|
2
|
+
var MODES = [
|
|
3
|
+
"light",
|
|
4
|
+
"dark",
|
|
5
|
+
"system"
|
|
6
|
+
];
|
|
7
|
+
var DENSITIES = [
|
|
8
|
+
"compact",
|
|
9
|
+
"comfortable",
|
|
10
|
+
"spacious"
|
|
11
|
+
];
|
|
12
|
+
var DEFAULT_THEME = {
|
|
13
|
+
density: "comfortable",
|
|
14
|
+
mode: "system"
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Resolves `system` to the colour mode the operating system currently prefers, and passes `light` and `dark` through.
|
|
18
|
+
*/
|
|
19
|
+
var resolveMode = (mode) => {
|
|
20
|
+
if (mode !== "system") return mode;
|
|
21
|
+
if (typeof window === "undefined") return "light";
|
|
22
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Writes the theme onto an element as a `light`/`dark` class and a `data-density` attribute.
|
|
26
|
+
*/
|
|
27
|
+
var applyTheme = (element, settings) => {
|
|
28
|
+
if (settings.mode) {
|
|
29
|
+
const resolvedMode = resolveMode(settings.mode);
|
|
30
|
+
element.classList.toggle("dark", resolvedMode === "dark");
|
|
31
|
+
element.classList.toggle("light", resolvedMode === "light");
|
|
32
|
+
}
|
|
33
|
+
if (settings.density) element.dataset.density = settings.density;
|
|
34
|
+
};
|
|
35
|
+
export { DEFAULT_THEME, DENSITIES, MODES, applyTheme, resolveMode };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","names":[],"sources":["../../src/theme/theme.ts"],"sourcesContent":["export const MODES = ['light', 'dark', 'system'] as const;\nexport const DENSITIES = ['compact', 'comfortable', 'spacious'] as const;\n\nexport type Mode = (typeof MODES)[number];\nexport type Density = (typeof DENSITIES)[number];\n\nexport interface ThemeSettings {\n density: Density;\n mode: Mode;\n}\n\nexport const DEFAULT_THEME = {\n density: 'comfortable',\n mode: 'system',\n} satisfies ThemeSettings;\n\n/**\n * Resolves `system` to the colour mode the operating system currently prefers, and passes `light` and `dark` through.\n */\nexport const resolveMode = (mode: Mode) => {\n if (mode !== 'system') return mode;\n if (typeof window === 'undefined') return 'light';\n\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n};\n\n/**\n * Writes the theme onto an element as a `light`/`dark` class and a `data-density` attribute.\n */\nexport const applyTheme = (element: HTMLElement, settings: Partial<ThemeSettings>) => {\n if (settings.mode) {\n const resolvedMode = resolveMode(settings.mode);\n element.classList.toggle('dark', resolvedMode === 'dark');\n element.classList.toggle('light', resolvedMode === 'light');\n }\n\n if (settings.density) element.dataset.density = settings.density;\n};\n"],"mappings":";AAAA,IAAa,QAAQ;CAAC;CAAS;CAAQ;AAAQ;AAC/C,IAAa,YAAY;CAAC;CAAW;CAAe;AAAU;AAU9D,IAAa,gBAAgB;CAC3B,SAAS;CACT,MAAM;AACR;;;;AAKA,IAAa,eAAe,SAAe;CACzC,IAAI,SAAS,UAAU,OAAO;CAC9B,IAAI,OAAO,WAAW,aAAa,OAAO;CAE1C,OAAO,OAAO,WAAW,8BAA8B,CAAC,CAAC,UAAU,SAAS;AAC9E;;;;AAKA,IAAa,cAAc,SAAsB,aAAqC;CACpF,IAAI,SAAS,MAAM;EACjB,MAAM,eAAe,YAAY,SAAS,IAAI;EAC9C,QAAQ,UAAU,OAAO,QAAQ,iBAAiB,MAAM;EACxD,QAAQ,UAAU,OAAO,SAAS,iBAAiB,OAAO;CAC5D;CAEA,IAAI,SAAS,SAAS,QAAQ,QAAQ,UAAU,SAAS;AAC3D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,94 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refine-studio/ui",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Refine UI: the design system the Diamonds use to build internal tools.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://ui.refine.studio",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/refine-studio/refine-ui.git"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"sideEffects": [
|
|
13
|
+
"**/*.css"
|
|
14
|
+
],
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"main": "./dist/index.js",
|
|
21
|
+
"module": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./styles.css": "./dist/styles.css",
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"registry": "https://registry.npmjs.org",
|
|
33
|
+
"access": "public",
|
|
34
|
+
"provenance": true
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"dev": "storybook dev -p 6006",
|
|
38
|
+
"build": "vite build && tsc -p tsconfig.build.json && node scripts/copy-styles.js",
|
|
39
|
+
"build-storybook": "storybook build -o storybook-static",
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"lint": "eslint .",
|
|
42
|
+
"format": "prettier --write .",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"prepack": "pnpm run build"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": ">=19",
|
|
48
|
+
"react-dom": ">=19",
|
|
49
|
+
"tailwindcss": ">=4.1"
|
|
50
|
+
},
|
|
51
|
+
"packageManager": "pnpm@11.25.0",
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"class-variance-authority": "0.7.1",
|
|
54
|
+
"clsx": "2.1.1",
|
|
55
|
+
"cmdk": "1.1.1",
|
|
56
|
+
"lucide-react": "1.61.0",
|
|
57
|
+
"radix-ui": "1.8.1",
|
|
58
|
+
"sonner": "2.0.8",
|
|
59
|
+
"tailwind-merge": "3.7.0",
|
|
60
|
+
"tw-animate-css": "1.4.0"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@eslint/js": "10.0.1",
|
|
64
|
+
"@fontsource-variable/geist": "5.3.0",
|
|
65
|
+
"@fontsource-variable/geist-mono": "5.3.0",
|
|
66
|
+
"@storybook/addon-a11y": "10.6.4",
|
|
67
|
+
"@storybook/addon-docs": "10.6.4",
|
|
68
|
+
"@storybook/react-vite": "10.6.4",
|
|
69
|
+
"@tailwindcss/vite": "4.3.3",
|
|
70
|
+
"@testing-library/react": "16.3.3",
|
|
71
|
+
"@testing-library/user-event": "14.6.8",
|
|
72
|
+
"@types/node": "26.6.5",
|
|
73
|
+
"@types/react": "19.3.0",
|
|
74
|
+
"@types/react-dom": "19.3.0",
|
|
75
|
+
"@types/three": "0.186.0",
|
|
76
|
+
"@vitejs/plugin-react": "6.1.2",
|
|
77
|
+
"eslint": "10.13.0",
|
|
78
|
+
"eslint-plugin-react-hooks": "7.1.1",
|
|
79
|
+
"eslint-plugin-storybook": "10.6.4",
|
|
80
|
+
"globals": "17.13.0",
|
|
81
|
+
"jsdom": "30.1.3",
|
|
82
|
+
"prettier": "3.9.10",
|
|
83
|
+
"prettier-plugin-tailwindcss": "0.8.1",
|
|
84
|
+
"react": "19.3.1",
|
|
85
|
+
"react-dom": "19.3.1",
|
|
86
|
+
"storybook": "10.6.4",
|
|
87
|
+
"tailwindcss": "4.3.3",
|
|
88
|
+
"three": "0.186.1",
|
|
89
|
+
"typescript": "5.9.3",
|
|
90
|
+
"typescript-eslint": "8.72.0",
|
|
91
|
+
"vite": "8.3.5",
|
|
92
|
+
"vitest": "5.0.5"
|
|
93
|
+
}
|
|
94
|
+
}
|