@orion-studios/payload-admin-components 0.2.0-beta.2 → 0.2.0-beta.4
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/admin.css +624 -15
- package/dist/client.d.mts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +17 -13
- package/dist/client.mjs +17 -13
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -13
- package/dist/index.mjs +17 -13
- package/package.json +2 -2
- package/src/components/ThemeSwitcher.tsx +17 -9
- package/src/hooks/useTheme.ts +6 -4
- package/src/styles/admin.css +624 -15
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
|
};
|
|
@@ -244,7 +244,9 @@ var buttonBase = {
|
|
|
244
244
|
width: 32,
|
|
245
245
|
height: 32,
|
|
246
246
|
borderRadius: "var(--admin-radius-sm)",
|
|
247
|
-
|
|
247
|
+
borderWidth: 1,
|
|
248
|
+
borderStyle: "solid",
|
|
249
|
+
borderColor: "var(--admin-border)",
|
|
248
250
|
background: "var(--admin-surface)",
|
|
249
251
|
color: "var(--admin-text-secondary)",
|
|
250
252
|
cursor: "pointer",
|
|
@@ -258,7 +260,9 @@ var buttonActive = {
|
|
|
258
260
|
color: "var(--admin-accent)"
|
|
259
261
|
};
|
|
260
262
|
function ThemeSwitcher() {
|
|
261
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
263
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
264
|
+
const showDark = hasMounted && isDark;
|
|
265
|
+
const showBrand = hasMounted && isBrand;
|
|
262
266
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
263
267
|
"div",
|
|
264
268
|
{
|
|
@@ -274,10 +278,10 @@ function ThemeSwitcher() {
|
|
|
274
278
|
{
|
|
275
279
|
type: "button",
|
|
276
280
|
onClick: toggleDarkMode,
|
|
277
|
-
style:
|
|
278
|
-
title:
|
|
279
|
-
"aria-label":
|
|
280
|
-
children:
|
|
281
|
+
style: showDark ? buttonActive : buttonBase,
|
|
282
|
+
title: showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
283
|
+
"aria-label": showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
284
|
+
children: showDark ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoonIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SunIcon, {})
|
|
281
285
|
}
|
|
282
286
|
),
|
|
283
287
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -285,9 +289,9 @@ function ThemeSwitcher() {
|
|
|
285
289
|
{
|
|
286
290
|
type: "button",
|
|
287
291
|
onClick: toggleBrandMode,
|
|
288
|
-
style:
|
|
289
|
-
title:
|
|
290
|
-
"aria-label":
|
|
292
|
+
style: showBrand ? buttonActive : buttonBase,
|
|
293
|
+
title: showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
294
|
+
"aria-label": showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
291
295
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaletteIcon, {})
|
|
292
296
|
}
|
|
293
297
|
)
|
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
|
};
|
|
@@ -208,7 +208,9 @@ var buttonBase = {
|
|
|
208
208
|
width: 32,
|
|
209
209
|
height: 32,
|
|
210
210
|
borderRadius: "var(--admin-radius-sm)",
|
|
211
|
-
|
|
211
|
+
borderWidth: 1,
|
|
212
|
+
borderStyle: "solid",
|
|
213
|
+
borderColor: "var(--admin-border)",
|
|
212
214
|
background: "var(--admin-surface)",
|
|
213
215
|
color: "var(--admin-text-secondary)",
|
|
214
216
|
cursor: "pointer",
|
|
@@ -222,7 +224,9 @@ var buttonActive = {
|
|
|
222
224
|
color: "var(--admin-accent)"
|
|
223
225
|
};
|
|
224
226
|
function ThemeSwitcher() {
|
|
225
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
227
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
228
|
+
const showDark = hasMounted && isDark;
|
|
229
|
+
const showBrand = hasMounted && isBrand;
|
|
226
230
|
return /* @__PURE__ */ jsxs3(
|
|
227
231
|
"div",
|
|
228
232
|
{
|
|
@@ -238,10 +242,10 @@ function ThemeSwitcher() {
|
|
|
238
242
|
{
|
|
239
243
|
type: "button",
|
|
240
244
|
onClick: toggleDarkMode,
|
|
241
|
-
style:
|
|
242
|
-
title:
|
|
243
|
-
"aria-label":
|
|
244
|
-
children:
|
|
245
|
+
style: showDark ? buttonActive : buttonBase,
|
|
246
|
+
title: showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
247
|
+
"aria-label": showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
248
|
+
children: showDark ? /* @__PURE__ */ jsx3(MoonIcon, {}) : /* @__PURE__ */ jsx3(SunIcon, {})
|
|
245
249
|
}
|
|
246
250
|
),
|
|
247
251
|
/* @__PURE__ */ jsx3(
|
|
@@ -249,9 +253,9 @@ function ThemeSwitcher() {
|
|
|
249
253
|
{
|
|
250
254
|
type: "button",
|
|
251
255
|
onClick: toggleBrandMode,
|
|
252
|
-
style:
|
|
253
|
-
title:
|
|
254
|
-
"aria-label":
|
|
256
|
+
style: showBrand ? buttonActive : buttonBase,
|
|
257
|
+
title: showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
258
|
+
"aria-label": showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
255
259
|
children: /* @__PURE__ */ jsx3(PaletteIcon, {})
|
|
256
260
|
}
|
|
257
261
|
)
|
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
|
};
|
|
@@ -407,7 +407,9 @@ var buttonBase = {
|
|
|
407
407
|
width: 32,
|
|
408
408
|
height: 32,
|
|
409
409
|
borderRadius: "var(--admin-radius-sm)",
|
|
410
|
-
|
|
410
|
+
borderWidth: 1,
|
|
411
|
+
borderStyle: "solid",
|
|
412
|
+
borderColor: "var(--admin-border)",
|
|
411
413
|
background: "var(--admin-surface)",
|
|
412
414
|
color: "var(--admin-text-secondary)",
|
|
413
415
|
cursor: "pointer",
|
|
@@ -421,7 +423,9 @@ var buttonActive = {
|
|
|
421
423
|
color: "var(--admin-accent)"
|
|
422
424
|
};
|
|
423
425
|
function ThemeSwitcher() {
|
|
424
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
426
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
427
|
+
const showDark = hasMounted && isDark;
|
|
428
|
+
const showBrand = hasMounted && isBrand;
|
|
425
429
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
426
430
|
"div",
|
|
427
431
|
{
|
|
@@ -437,10 +441,10 @@ function ThemeSwitcher() {
|
|
|
437
441
|
{
|
|
438
442
|
type: "button",
|
|
439
443
|
onClick: toggleDarkMode,
|
|
440
|
-
style:
|
|
441
|
-
title:
|
|
442
|
-
"aria-label":
|
|
443
|
-
children:
|
|
444
|
+
style: showDark ? buttonActive : buttonBase,
|
|
445
|
+
title: showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
446
|
+
"aria-label": showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
447
|
+
children: showDark ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoonIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SunIcon, {})
|
|
444
448
|
}
|
|
445
449
|
),
|
|
446
450
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -448,9 +452,9 @@ function ThemeSwitcher() {
|
|
|
448
452
|
{
|
|
449
453
|
type: "button",
|
|
450
454
|
onClick: toggleBrandMode,
|
|
451
|
-
style:
|
|
452
|
-
title:
|
|
453
|
-
"aria-label":
|
|
455
|
+
style: showBrand ? buttonActive : buttonBase,
|
|
456
|
+
title: showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
457
|
+
"aria-label": showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
454
458
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaletteIcon, {})
|
|
455
459
|
}
|
|
456
460
|
)
|
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
|
};
|
|
@@ -367,7 +367,9 @@ var buttonBase = {
|
|
|
367
367
|
width: 32,
|
|
368
368
|
height: 32,
|
|
369
369
|
borderRadius: "var(--admin-radius-sm)",
|
|
370
|
-
|
|
370
|
+
borderWidth: 1,
|
|
371
|
+
borderStyle: "solid",
|
|
372
|
+
borderColor: "var(--admin-border)",
|
|
371
373
|
background: "var(--admin-surface)",
|
|
372
374
|
color: "var(--admin-text-secondary)",
|
|
373
375
|
cursor: "pointer",
|
|
@@ -381,7 +383,9 @@ var buttonActive = {
|
|
|
381
383
|
color: "var(--admin-accent)"
|
|
382
384
|
};
|
|
383
385
|
function ThemeSwitcher() {
|
|
384
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
386
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme();
|
|
387
|
+
const showDark = hasMounted && isDark;
|
|
388
|
+
const showBrand = hasMounted && isBrand;
|
|
385
389
|
return /* @__PURE__ */ jsxs3(
|
|
386
390
|
"div",
|
|
387
391
|
{
|
|
@@ -397,10 +401,10 @@ function ThemeSwitcher() {
|
|
|
397
401
|
{
|
|
398
402
|
type: "button",
|
|
399
403
|
onClick: toggleDarkMode,
|
|
400
|
-
style:
|
|
401
|
-
title:
|
|
402
|
-
"aria-label":
|
|
403
|
-
children:
|
|
404
|
+
style: showDark ? buttonActive : buttonBase,
|
|
405
|
+
title: showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
406
|
+
"aria-label": showDark ? "Switch to light mode" : "Switch to dark mode",
|
|
407
|
+
children: showDark ? /* @__PURE__ */ jsx3(MoonIcon, {}) : /* @__PURE__ */ jsx3(SunIcon, {})
|
|
404
408
|
}
|
|
405
409
|
),
|
|
406
410
|
/* @__PURE__ */ jsx3(
|
|
@@ -408,9 +412,9 @@ function ThemeSwitcher() {
|
|
|
408
412
|
{
|
|
409
413
|
type: "button",
|
|
410
414
|
onClick: toggleBrandMode,
|
|
411
|
-
style:
|
|
412
|
-
title:
|
|
413
|
-
"aria-label":
|
|
415
|
+
style: showBrand ? buttonActive : buttonBase,
|
|
416
|
+
title: showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
417
|
+
"aria-label": showBrand ? "Switch to standard colors" : "Switch to brand colors",
|
|
414
418
|
children: /* @__PURE__ */ jsx3(PaletteIcon, {})
|
|
415
419
|
}
|
|
416
420
|
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-studios/payload-admin-components",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.4",
|
|
4
4
|
"description": "Custom admin UI components for Payload CMS",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"src"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
|
-
"build": "tsup && node -e \"
|
|
26
|
+
"build": "tsup && node -e \"require('fs').copyFileSync('src/styles/admin.css','dist/admin.css')\"",
|
|
27
27
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
28
28
|
"typecheck": "tsc --noEmit"
|
|
29
29
|
},
|
|
@@ -48,7 +48,9 @@ const buttonBase: React.CSSProperties = {
|
|
|
48
48
|
width: 32,
|
|
49
49
|
height: 32,
|
|
50
50
|
borderRadius: 'var(--admin-radius-sm)',
|
|
51
|
-
|
|
51
|
+
borderWidth: 1,
|
|
52
|
+
borderStyle: 'solid',
|
|
53
|
+
borderColor: 'var(--admin-border)',
|
|
52
54
|
background: 'var(--admin-surface)',
|
|
53
55
|
color: 'var(--admin-text-secondary)',
|
|
54
56
|
cursor: 'pointer',
|
|
@@ -64,7 +66,13 @@ const buttonActive: React.CSSProperties = {
|
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
export function ThemeSwitcher() {
|
|
67
|
-
const { isDark, isBrand, toggleDarkMode, toggleBrandMode } = useTheme()
|
|
69
|
+
const { isDark, isBrand, hasMounted, toggleDarkMode, toggleBrandMode } = useTheme()
|
|
70
|
+
|
|
71
|
+
// Before mount, render the default (light) state to match server HTML and avoid hydration mismatch.
|
|
72
|
+
// The ThemeProvider applies the cached theme to the document immediately on mount,
|
|
73
|
+
// so the visual flash is minimal.
|
|
74
|
+
const showDark = hasMounted && isDark
|
|
75
|
+
const showBrand = hasMounted && isBrand
|
|
68
76
|
|
|
69
77
|
return (
|
|
70
78
|
<div
|
|
@@ -78,18 +86,18 @@ export function ThemeSwitcher() {
|
|
|
78
86
|
<button
|
|
79
87
|
type="button"
|
|
80
88
|
onClick={toggleDarkMode}
|
|
81
|
-
style={
|
|
82
|
-
title={
|
|
83
|
-
aria-label={
|
|
89
|
+
style={showDark ? buttonActive : buttonBase}
|
|
90
|
+
title={showDark ? 'Switch to light mode' : 'Switch to dark mode'}
|
|
91
|
+
aria-label={showDark ? 'Switch to light mode' : 'Switch to dark mode'}
|
|
84
92
|
>
|
|
85
|
-
{
|
|
93
|
+
{showDark ? <MoonIcon /> : <SunIcon />}
|
|
86
94
|
</button>
|
|
87
95
|
<button
|
|
88
96
|
type="button"
|
|
89
97
|
onClick={toggleBrandMode}
|
|
90
|
-
style={
|
|
91
|
-
title={
|
|
92
|
-
aria-label={
|
|
98
|
+
style={showBrand ? buttonActive : buttonBase}
|
|
99
|
+
title={showBrand ? 'Switch to standard colors' : 'Switch to brand colors'}
|
|
100
|
+
aria-label={showBrand ? 'Switch to standard colors' : 'Switch to brand colors'}
|
|
93
101
|
>
|
|
94
102
|
<PaletteIcon />
|
|
95
103
|
</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
|
}
|