@orion-studios/payload-admin-components 0.2.0-beta.2 → 0.2.0-beta.3
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/dist/client.d.mts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +14 -12
- package/dist/client.mjs +14 -12
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +14 -12
- package/dist/index.mjs +14 -12
- package/package.json +1 -1
- package/src/components/ThemeSwitcher.tsx +14 -8
- package/src/hooks/useTheme.ts +6 -4
package/dist/client.d.mts
CHANGED
package/dist/client.d.ts
CHANGED
package/dist/client.js
CHANGED
|
@@ -132,14 +132,13 @@ function cacheTheme(theme) {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
function useTheme() {
|
|
135
|
-
const [theme, setThemeState] = (0, import_react.useState)(
|
|
136
|
-
if (typeof window === "undefined") return DEFAULT_THEME;
|
|
137
|
-
return getCachedTheme() || DEFAULT_THEME;
|
|
138
|
-
});
|
|
135
|
+
const [theme, setThemeState] = (0, import_react.useState)(DEFAULT_THEME);
|
|
139
136
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
137
|
+
const [hasMounted, setHasMounted] = (0, import_react.useState)(false);
|
|
140
138
|
const debounceRef = (0, import_react.useRef)(null);
|
|
141
139
|
const userIdRef = (0, import_react.useRef)(null);
|
|
142
140
|
(0, import_react.useEffect)(() => {
|
|
141
|
+
setHasMounted(true);
|
|
143
142
|
const cached = getCachedTheme();
|
|
144
143
|
if (cached) {
|
|
145
144
|
applyTheme(cached);
|
|
@@ -204,6 +203,7 @@ function useTheme() {
|
|
|
204
203
|
isDark,
|
|
205
204
|
isBrand,
|
|
206
205
|
isLoading,
|
|
206
|
+
hasMounted,
|
|
207
207
|
toggleDarkMode,
|
|
208
208
|
toggleBrandMode
|
|
209
209
|
};
|
|
@@ -258,7 +258,9 @@ var buttonActive = {
|
|
|
258
258
|
color: "var(--admin-accent)"
|
|
259
259
|
};
|
|
260
260
|
function ThemeSwitcher() {
|
|
261
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
261
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
262
|
+
const showDark = hasMounted && isDark;
|
|
263
|
+
const showBrand = hasMounted && isBrand;
|
|
262
264
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
263
265
|
"div",
|
|
264
266
|
{
|
|
@@ -274,10 +276,10 @@ function ThemeSwitcher() {
|
|
|
274
276
|
{
|
|
275
277
|
type: "button",
|
|
276
278
|
onClick: toggleDarkMode,
|
|
277
|
-
style:
|
|
278
|
-
title:
|
|
279
|
-
"aria-label":
|
|
280
|
-
children:
|
|
279
|
+
style: showDark ? buttonActive : buttonBase,
|
|
280
|
+
title: showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
281
|
+
"aria-label": showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
282
|
+
children: showDark ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoonIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SunIcon, {})
|
|
281
283
|
}
|
|
282
284
|
),
|
|
283
285
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -285,9 +287,9 @@ function ThemeSwitcher() {
|
|
|
285
287
|
{
|
|
286
288
|
type: "button",
|
|
287
289
|
onClick: toggleBrandMode,
|
|
288
|
-
style:
|
|
289
|
-
title:
|
|
290
|
-
"aria-label":
|
|
290
|
+
style: showBrand ? buttonActive : buttonBase,
|
|
291
|
+
title: showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
292
|
+
"aria-label": showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
291
293
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaletteIcon, {})
|
|
292
294
|
}
|
|
293
295
|
)
|
package/dist/client.mjs
CHANGED
|
@@ -96,14 +96,13 @@ function cacheTheme(theme) {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
function useTheme() {
|
|
99
|
-
const [theme, setThemeState] = useState(
|
|
100
|
-
if (typeof window === "undefined") return DEFAULT_THEME;
|
|
101
|
-
return getCachedTheme() || DEFAULT_THEME;
|
|
102
|
-
});
|
|
99
|
+
const [theme, setThemeState] = useState(DEFAULT_THEME);
|
|
103
100
|
const [isLoading, setIsLoading] = useState(true);
|
|
101
|
+
const [hasMounted, setHasMounted] = useState(false);
|
|
104
102
|
const debounceRef = useRef(null);
|
|
105
103
|
const userIdRef = useRef(null);
|
|
106
104
|
useEffect(() => {
|
|
105
|
+
setHasMounted(true);
|
|
107
106
|
const cached = getCachedTheme();
|
|
108
107
|
if (cached) {
|
|
109
108
|
applyTheme(cached);
|
|
@@ -168,6 +167,7 @@ function useTheme() {
|
|
|
168
167
|
isDark,
|
|
169
168
|
isBrand,
|
|
170
169
|
isLoading,
|
|
170
|
+
hasMounted,
|
|
171
171
|
toggleDarkMode,
|
|
172
172
|
toggleBrandMode
|
|
173
173
|
};
|
|
@@ -222,7 +222,9 @@ var buttonActive = {
|
|
|
222
222
|
color: "var(--admin-accent)"
|
|
223
223
|
};
|
|
224
224
|
function ThemeSwitcher() {
|
|
225
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
225
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
226
|
+
const showDark = hasMounted && isDark;
|
|
227
|
+
const showBrand = hasMounted && isBrand;
|
|
226
228
|
return /* @__PURE__ */ jsxs3(
|
|
227
229
|
"div",
|
|
228
230
|
{
|
|
@@ -238,10 +240,10 @@ function ThemeSwitcher() {
|
|
|
238
240
|
{
|
|
239
241
|
type: "button",
|
|
240
242
|
onClick: toggleDarkMode,
|
|
241
|
-
style:
|
|
242
|
-
title:
|
|
243
|
-
"aria-label":
|
|
244
|
-
children:
|
|
243
|
+
style: showDark ? buttonActive : buttonBase,
|
|
244
|
+
title: showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
245
|
+
"aria-label": showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
246
|
+
children: showDark ? /* @__PURE__ */ jsx3(MoonIcon, {}) : /* @__PURE__ */ jsx3(SunIcon, {})
|
|
245
247
|
}
|
|
246
248
|
),
|
|
247
249
|
/* @__PURE__ */ jsx3(
|
|
@@ -249,9 +251,9 @@ function ThemeSwitcher() {
|
|
|
249
251
|
{
|
|
250
252
|
type: "button",
|
|
251
253
|
onClick: toggleBrandMode,
|
|
252
|
-
style:
|
|
253
|
-
title:
|
|
254
|
-
"aria-label":
|
|
254
|
+
style: showBrand ? buttonActive : buttonBase,
|
|
255
|
+
title: showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
256
|
+
"aria-label": showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
255
257
|
children: /* @__PURE__ */ jsx3(PaletteIcon, {})
|
|
256
258
|
}
|
|
257
259
|
)
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -295,14 +295,13 @@ function cacheTheme(theme) {
|
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
function useTheme() {
|
|
298
|
-
const [theme, setThemeState] = (0, import_react.useState)(
|
|
299
|
-
if (typeof window === "undefined") return DEFAULT_THEME;
|
|
300
|
-
return getCachedTheme() || DEFAULT_THEME;
|
|
301
|
-
});
|
|
298
|
+
const [theme, setThemeState] = (0, import_react.useState)(DEFAULT_THEME);
|
|
302
299
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
300
|
+
const [hasMounted, setHasMounted] = (0, import_react.useState)(false);
|
|
303
301
|
const debounceRef = (0, import_react.useRef)(null);
|
|
304
302
|
const userIdRef = (0, import_react.useRef)(null);
|
|
305
303
|
(0, import_react.useEffect)(() => {
|
|
304
|
+
setHasMounted(true);
|
|
306
305
|
const cached = getCachedTheme();
|
|
307
306
|
if (cached) {
|
|
308
307
|
applyTheme(cached);
|
|
@@ -367,6 +366,7 @@ function useTheme() {
|
|
|
367
366
|
isDark,
|
|
368
367
|
isBrand,
|
|
369
368
|
isLoading,
|
|
369
|
+
hasMounted,
|
|
370
370
|
toggleDarkMode,
|
|
371
371
|
toggleBrandMode
|
|
372
372
|
};
|
|
@@ -421,7 +421,9 @@ var buttonActive = {
|
|
|
421
421
|
color: "var(--admin-accent)"
|
|
422
422
|
};
|
|
423
423
|
function ThemeSwitcher() {
|
|
424
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
424
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
425
|
+
const showDark = hasMounted && isDark;
|
|
426
|
+
const showBrand = hasMounted && isBrand;
|
|
425
427
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
426
428
|
"div",
|
|
427
429
|
{
|
|
@@ -437,10 +439,10 @@ function ThemeSwitcher() {
|
|
|
437
439
|
{
|
|
438
440
|
type: "button",
|
|
439
441
|
onClick: toggleDarkMode,
|
|
440
|
-
style:
|
|
441
|
-
title:
|
|
442
|
-
"aria-label":
|
|
443
|
-
children:
|
|
442
|
+
style: showDark ? buttonActive : buttonBase,
|
|
443
|
+
title: showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
444
|
+
"aria-label": showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
445
|
+
children: showDark ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoonIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SunIcon, {})
|
|
444
446
|
}
|
|
445
447
|
),
|
|
446
448
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -448,9 +450,9 @@ function ThemeSwitcher() {
|
|
|
448
450
|
{
|
|
449
451
|
type: "button",
|
|
450
452
|
onClick: toggleBrandMode,
|
|
451
|
-
style:
|
|
452
|
-
title:
|
|
453
|
-
"aria-label":
|
|
453
|
+
style: showBrand ? buttonActive : buttonBase,
|
|
454
|
+
title: showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
455
|
+
"aria-label": showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
454
456
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaletteIcon, {})
|
|
455
457
|
}
|
|
456
458
|
)
|
package/dist/index.mjs
CHANGED
|
@@ -255,14 +255,13 @@ function cacheTheme(theme) {
|
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
function useTheme() {
|
|
258
|
-
const [theme, setThemeState] = useState(
|
|
259
|
-
if (typeof window === "undefined") return DEFAULT_THEME;
|
|
260
|
-
return getCachedTheme() || DEFAULT_THEME;
|
|
261
|
-
});
|
|
258
|
+
const [theme, setThemeState] = useState(DEFAULT_THEME);
|
|
262
259
|
const [isLoading, setIsLoading] = useState(true);
|
|
260
|
+
const [hasMounted, setHasMounted] = useState(false);
|
|
263
261
|
const debounceRef = useRef(null);
|
|
264
262
|
const userIdRef = useRef(null);
|
|
265
263
|
useEffect(() => {
|
|
264
|
+
setHasMounted(true);
|
|
266
265
|
const cached = getCachedTheme();
|
|
267
266
|
if (cached) {
|
|
268
267
|
applyTheme(cached);
|
|
@@ -327,6 +326,7 @@ function useTheme() {
|
|
|
327
326
|
isDark,
|
|
328
327
|
isBrand,
|
|
329
328
|
isLoading,
|
|
329
|
+
hasMounted,
|
|
330
330
|
toggleDarkMode,
|
|
331
331
|
toggleBrandMode
|
|
332
332
|
};
|
|
@@ -381,7 +381,9 @@ var buttonActive = {
|
|
|
381
381
|
color: "var(--admin-accent)"
|
|
382
382
|
};
|
|
383
383
|
function ThemeSwitcher() {
|
|
384
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
384
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
385
|
+
const showDark = hasMounted && isDark;
|
|
386
|
+
const showBrand = hasMounted && isBrand;
|
|
385
387
|
return /* @__PURE__ */ jsxs3(
|
|
386
388
|
"div",
|
|
387
389
|
{
|
|
@@ -397,10 +399,10 @@ function ThemeSwitcher() {
|
|
|
397
399
|
{
|
|
398
400
|
type: "button",
|
|
399
401
|
onClick: toggleDarkMode,
|
|
400
|
-
style:
|
|
401
|
-
title:
|
|
402
|
-
"aria-label":
|
|
403
|
-
children:
|
|
402
|
+
style: showDark ? buttonActive : buttonBase,
|
|
403
|
+
title: showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
404
|
+
"aria-label": showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
405
|
+
children: showDark ? /* @__PURE__ */ jsx3(MoonIcon, {}) : /* @__PURE__ */ jsx3(SunIcon, {})
|
|
404
406
|
}
|
|
405
407
|
),
|
|
406
408
|
/* @__PURE__ */ jsx3(
|
|
@@ -408,9 +410,9 @@ function ThemeSwitcher() {
|
|
|
408
410
|
{
|
|
409
411
|
type: "button",
|
|
410
412
|
onClick: toggleBrandMode,
|
|
411
|
-
style:
|
|
412
|
-
title:
|
|
413
|
-
"aria-label":
|
|
413
|
+
style: showBrand ? buttonActive : buttonBase,
|
|
414
|
+
title: showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
415
|
+
"aria-label": showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
414
416
|
children: /* @__PURE__ */ jsx3(PaletteIcon, {})
|
|
415
417
|
}
|
|
416
418
|
)
|
package/package.json
CHANGED
|
@@ -64,7 +64,13 @@ const buttonActive: React.CSSProperties = {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
export function ThemeSwitcher() {
|
|
67
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme()
|
|
67
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme()
|
|
68
|
+
|
|
69
|
+
// Before mount, render the default (light) state to match server HTML and avoid hydration mismatch.
|
|
70
|
+
// The ThemeProvider applies the cached theme to the document immediately on mount,
|
|
71
|
+
// so the visual flash is minimal.
|
|
72
|
+
const showDark = hasMounted && isDark
|
|
73
|
+
const showBrand = hasMounted && isBrand
|
|
68
74
|
|
|
69
75
|
return (
|
|
70
76
|
<div
|
|
@@ -78,18 +84,18 @@ export function ThemeSwitcher() {
|
|
|
78
84
|
<button
|
|
79
85
|
type="button"
|
|
80
86
|
onClick={toggleDarkMode}
|
|
81
|
-
style={
|
|
82
|
-
title={
|
|
83
|
-
aria-label={
|
|
87
|
+
style={showDark ? buttonActive : buttonBase}
|
|
88
|
+
title={showDark ? 'Switch to light mode' : 'Switch to dark mode'}
|
|
89
|
+
aria-label={showDark ? 'Switch to light mode' : 'Switch to dark mode'}
|
|
84
90
|
>
|
|
85
|
-
{
|
|
91
|
+
{showDark ? <MoonIcon /> : <SunIcon />}
|
|
86
92
|
</button>
|
|
87
93
|
<button
|
|
88
94
|
type="button"
|
|
89
95
|
onClick={toggleBrandMode}
|
|
90
|
-
style={
|
|
91
|
-
title={
|
|
92
|
-
aria-label={
|
|
96
|
+
style={showBrand ? buttonActive : buttonBase}
|
|
97
|
+
title={showBrand ? 'Switch to standard colors' : 'Switch to brand colors'}
|
|
98
|
+
aria-label={showBrand ? 'Switch to standard colors' : 'Switch to brand colors'}
|
|
93
99
|
>
|
|
94
100
|
<PaletteIcon />
|
|
95
101
|
</button>
|
package/src/hooks/useTheme.ts
CHANGED
|
@@ -32,16 +32,17 @@ function cacheTheme(theme: ThemeOption) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export function useTheme() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
})
|
|
35
|
+
// Always initialize with DEFAULT_THEME to avoid hydration mismatch.
|
|
36
|
+
// The real theme is applied in useEffect after mount.
|
|
37
|
+
const [theme, setThemeState] = useState<ThemeOption>(DEFAULT_THEME)
|
|
39
38
|
const [isLoading, setIsLoading] = useState(true)
|
|
39
|
+
const [hasMounted, setHasMounted] = useState(false)
|
|
40
40
|
const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
41
41
|
const userIdRef = useRef<string | null>(null)
|
|
42
42
|
|
|
43
43
|
// On mount: apply cached theme immediately, then sync from DB
|
|
44
44
|
useEffect(() => {
|
|
45
|
+
setHasMounted(true)
|
|
45
46
|
const cached = getCachedTheme()
|
|
46
47
|
if (cached) {
|
|
47
48
|
applyTheme(cached)
|
|
@@ -122,6 +123,7 @@ export function useTheme() {
|
|
|
122
123
|
isDark,
|
|
123
124
|
isBrand,
|
|
124
125
|
isLoading,
|
|
126
|
+
hasMounted,
|
|
125
127
|
toggleDarkMode,
|
|
126
128
|
toggleBrandMode,
|
|
127
129
|
}
|