@svadmin/core 0.8.0 → 0.9.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/package.json +1 -1
- package/src/index.ts +2 -2
- package/src/theme.svelte.ts +82 -2
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -37,8 +37,8 @@ export { audit, setAuditHandler, setAuditLogProvider, getAuditLogProvider } from
|
|
|
37
37
|
export type { AuditLogProvider } from './audit';
|
|
38
38
|
export { setChatProvider, getChatProvider, setChatContext, getChatContext } from './chatProvider.svelte';
|
|
39
39
|
export type { ChatProvider, ChatMessage, ChatContext, ChatAction } from './chatProvider.svelte';
|
|
40
|
-
export { getTheme, setTheme, toggleTheme, getResolvedTheme, getColorTheme, setColorTheme, colorThemes } from './theme.svelte';
|
|
41
|
-
export type { ThemeMode, ColorTheme } from './theme.svelte';
|
|
40
|
+
export { getTheme, setTheme, toggleTheme, getResolvedTheme, getColorTheme, setColorTheme, colorThemes, configureTheme, getThemeConfig, clearCssOverrides } from './theme.svelte';
|
|
41
|
+
export type { ThemeMode, ColorTheme, ThemeStrategy, ThemeConfig } from './theme.svelte';
|
|
42
42
|
export { setUnsavedChanges, getUnsavedChanges, initUnsavedChangesNotifier } from './unsaved-changes.svelte';
|
|
43
43
|
export { setAdminOptions, getAdminOptions, getTextTransformers } from './options';
|
|
44
44
|
export type { AdminOptions, TextTransformers, OvertimeConfig } from './options';
|
package/src/theme.svelte.ts
CHANGED
|
@@ -1,11 +1,75 @@
|
|
|
1
1
|
// Theme — dark/light/system mode + color theme management (Svelte 5 runes)
|
|
2
|
+
//
|
|
3
|
+
// Supports two class strategies:
|
|
4
|
+
// - 'standard' (default): adds 'dark' class for dark mode (light-first)
|
|
5
|
+
// - 'dark-first': adds 'light' class for light mode (dark-first, e.g. Elygate-style)
|
|
2
6
|
|
|
3
7
|
export type ThemeMode = 'light' | 'dark' | 'system';
|
|
4
8
|
export type ColorTheme = 'blue' | 'green' | 'rose' | 'orange' | 'violet' | 'zinc';
|
|
5
9
|
|
|
10
|
+
/** Controls how the theme class is applied to <html> */
|
|
11
|
+
export type ThemeStrategy = 'standard' | 'dark-first';
|
|
12
|
+
|
|
13
|
+
export interface ThemeConfig {
|
|
14
|
+
/** Class strategy: 'standard' toggles '.dark', 'dark-first' toggles '.light' */
|
|
15
|
+
strategy?: ThemeStrategy;
|
|
16
|
+
/** Custom CSS variables to inject as overrides on <html> */
|
|
17
|
+
cssOverrides?: Record<string, string>;
|
|
18
|
+
/** Whether to disable the built-in color-scheme attribute */
|
|
19
|
+
disableColorScheme?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
6
22
|
const STORAGE_KEY = 'svadmin-theme';
|
|
7
23
|
const COLOR_STORAGE_KEY = 'svadmin-color-theme';
|
|
8
24
|
|
|
25
|
+
// ── Theme configuration ──────────────────────────────────
|
|
26
|
+
let themeConfig: ThemeConfig = {};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Configure the theme system. Must be called before setTheme() or
|
|
30
|
+
* automatically via AdminApp's themeConfig prop.
|
|
31
|
+
*/
|
|
32
|
+
export function configureTheme(config: ThemeConfig): void {
|
|
33
|
+
themeConfig = { ...config };
|
|
34
|
+
// Re-apply the current theme with new strategy
|
|
35
|
+
applyTheme(mode);
|
|
36
|
+
// Apply CSS overrides
|
|
37
|
+
if (config.cssOverrides) {
|
|
38
|
+
applyCssOverrides(config.cssOverrides);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Get current theme configuration */
|
|
43
|
+
export function getThemeConfig(): ThemeConfig {
|
|
44
|
+
return { ...themeConfig };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function applyCssOverrides(overrides: Record<string, string>): void {
|
|
48
|
+
if (typeof document === 'undefined') return;
|
|
49
|
+
const root = document.documentElement;
|
|
50
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
51
|
+
const cssVar = key.startsWith('--') ? key : `--${key}`;
|
|
52
|
+
root.style.setProperty(cssVar, value);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Remove previously applied CSS overrides */
|
|
57
|
+
export function clearCssOverrides(keys?: string[]): void {
|
|
58
|
+
if (typeof document === 'undefined') return;
|
|
59
|
+
const root = document.documentElement;
|
|
60
|
+
if (keys) {
|
|
61
|
+
for (const key of keys) {
|
|
62
|
+
const cssVar = key.startsWith('--') ? key : `--${key}`;
|
|
63
|
+
root.style.removeProperty(cssVar);
|
|
64
|
+
}
|
|
65
|
+
} else if (themeConfig.cssOverrides) {
|
|
66
|
+
for (const key of Object.keys(themeConfig.cssOverrides)) {
|
|
67
|
+
const cssVar = key.startsWith('--') ? key : `--${key}`;
|
|
68
|
+
root.style.removeProperty(cssVar);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
9
73
|
// ── Color themes (display metadata) ──────────────────────
|
|
10
74
|
export const colorThemes: { id: ColorTheme; label: string; color: string }[] = [
|
|
11
75
|
{ id: 'blue', label: 'Blue', color: '#3b82f6' },
|
|
@@ -32,8 +96,24 @@ let mode = $state<ThemeMode>(getStoredTheme());
|
|
|
32
96
|
|
|
33
97
|
function applyTheme(m: ThemeMode): void {
|
|
34
98
|
const resolved = m === 'system' ? getSystemPreference() : m;
|
|
35
|
-
if (typeof document
|
|
36
|
-
|
|
99
|
+
if (typeof document === 'undefined') return;
|
|
100
|
+
|
|
101
|
+
const strategy = themeConfig.strategy ?? 'standard';
|
|
102
|
+
const el = document.documentElement;
|
|
103
|
+
|
|
104
|
+
if (strategy === 'dark-first') {
|
|
105
|
+
// Dark-first: default is dark, add 'light' class for light mode
|
|
106
|
+
el.classList.toggle('light', resolved === 'light');
|
|
107
|
+
el.classList.remove('dark'); // ensure no conflict
|
|
108
|
+
} else {
|
|
109
|
+
// Standard: default is light, add 'dark' class for dark mode
|
|
110
|
+
el.classList.toggle('dark', resolved === 'dark');
|
|
111
|
+
el.classList.remove('light'); // ensure no conflict
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Set color-scheme attribute unless disabled
|
|
115
|
+
if (!themeConfig.disableColorScheme) {
|
|
116
|
+
el.style.colorScheme = resolved;
|
|
37
117
|
}
|
|
38
118
|
}
|
|
39
119
|
|