@kilivi/payloadcms-theme-management 0.1.6 → 0.1.8

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.
Files changed (89) hide show
  1. package/dist/components/ServerThemeInjector.d.ts +1 -1
  2. package/dist/components/ServerThemeInjector.d.ts.map +1 -1
  3. package/dist/components/{ServerThemeInjector.jsx → ServerThemeInjector.js} +47 -34
  4. package/dist/components/ServerThemeInjector.js.map +1 -0
  5. package/dist/components/ThemePreview.js +318 -0
  6. package/dist/components/ThemePreview.js.map +1 -0
  7. package/dist/components/typographyPreviewUtils.js +12 -17
  8. package/dist/components/typographyPreviewUtils.js.map +1 -1
  9. package/dist/constants/themeFonts.js +94 -24
  10. package/dist/constants/themeFonts.js.map +1 -1
  11. package/dist/fields/ColorPickerField.js +332 -0
  12. package/dist/fields/ColorPickerField.js.map +1 -0
  13. package/dist/fields/RadiusField.js +174 -0
  14. package/dist/fields/RadiusField.js.map +1 -0
  15. package/dist/fields/ThemeColorPickerField.js +163 -0
  16. package/dist/fields/ThemeColorPickerField.js.map +1 -0
  17. package/dist/fields/ThemePreviewField.js +558 -0
  18. package/dist/fields/ThemePreviewField.js.map +1 -0
  19. package/dist/fields/ThemeTokenSelectField.js +209 -0
  20. package/dist/fields/ThemeTokenSelectField.js.map +1 -0
  21. package/dist/fields/colorModeFields.js +167 -73
  22. package/dist/fields/colorModeFields.js.map +1 -1
  23. package/dist/fields/themeConfigurationField.d.ts +1 -1
  24. package/dist/fields/themeConfigurationField.d.ts.map +1 -1
  25. package/dist/fields/themeConfigurationField.js +224 -131
  26. package/dist/fields/themeConfigurationField.js.map +1 -1
  27. package/dist/index.d.ts +17 -16
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +52 -52
  30. package/dist/index.js.map +1 -1
  31. package/dist/payload-types.js +2 -2
  32. package/dist/payload-types.js.map +1 -1
  33. package/dist/plugin.d.ts +1 -2
  34. package/dist/plugin.d.ts.map +1 -1
  35. package/dist/plugin.js +2 -1
  36. package/dist/plugin.js.map +1 -1
  37. package/dist/presets.js +66 -65
  38. package/dist/presets.js.map +1 -1
  39. package/dist/providers/Theme/index.d.ts +1 -1
  40. package/dist/providers/Theme/index.d.ts.map +1 -1
  41. package/dist/providers/Theme/{index.jsx → index.js} +61 -31
  42. package/dist/providers/Theme/index.js.map +1 -0
  43. package/dist/providers/Theme/shared.d.ts +1 -1
  44. package/dist/providers/Theme/shared.d.ts.map +1 -1
  45. package/dist/providers/Theme/shared.js +34 -9
  46. package/dist/providers/Theme/shared.js.map +1 -1
  47. package/dist/providers/Theme/themeConfig.d.ts +1 -1
  48. package/dist/providers/Theme/themeConfig.d.ts.map +1 -1
  49. package/dist/providers/Theme/themeConfig.js +37 -36
  50. package/dist/providers/Theme/themeConfig.js.map +1 -1
  51. package/dist/providers/Theme/types.js +15 -13
  52. package/dist/providers/Theme/types.js.map +1 -1
  53. package/dist/server.d.ts +2 -2
  54. package/dist/server.d.ts.map +1 -1
  55. package/dist/server.js +3 -2
  56. package/dist/server.js.map +1 -1
  57. package/dist/types.d.ts +2 -2
  58. package/dist/types.d.ts.map +1 -1
  59. package/dist/types.js +2 -1
  60. package/dist/types.js.map +1 -1
  61. package/dist/utils/resolveThemeConfiguration.d.ts +3 -3
  62. package/dist/utils/resolveThemeConfiguration.d.ts.map +1 -1
  63. package/dist/utils/resolveThemeConfiguration.js +53 -34
  64. package/dist/utils/resolveThemeConfiguration.js.map +1 -1
  65. package/dist/utils/themeAssets.d.ts +1 -1
  66. package/dist/utils/themeAssets.d.ts.map +1 -1
  67. package/dist/utils/themeAssets.js +4 -4
  68. package/dist/utils/themeAssets.js.map +1 -1
  69. package/dist/utils/themeColors.js +95 -41
  70. package/dist/utils/themeColors.js.map +1 -1
  71. package/dist/utils/themeUtils.d.ts +2 -2
  72. package/dist/utils/themeUtils.d.ts.map +1 -1
  73. package/dist/utils/themeUtils.js +32 -47
  74. package/dist/utils/themeUtils.js.map +1 -1
  75. package/package.json +13 -5
  76. package/dist/components/ServerThemeInjector.jsx.map +0 -1
  77. package/dist/components/ThemePreview.jsx +0 -231
  78. package/dist/components/ThemePreview.jsx.map +0 -1
  79. package/dist/fields/ColorPickerField.jsx +0 -205
  80. package/dist/fields/ColorPickerField.jsx.map +0 -1
  81. package/dist/fields/RadiusField.jsx +0 -123
  82. package/dist/fields/RadiusField.jsx.map +0 -1
  83. package/dist/fields/ThemeColorPickerField.jsx +0 -110
  84. package/dist/fields/ThemeColorPickerField.jsx.map +0 -1
  85. package/dist/fields/ThemePreviewField.jsx +0 -420
  86. package/dist/fields/ThemePreviewField.jsx.map +0 -1
  87. package/dist/fields/ThemeTokenSelectField.jsx +0 -151
  88. package/dist/fields/ThemeTokenSelectField.jsx.map +0 -1
  89. package/dist/providers/Theme/index.jsx.map +0 -1
@@ -0,0 +1,558 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useField, useForm, useFormFields } from '@payloadcms/ui';
4
+ import { useCallback, useEffect, useMemo, useRef } from 'react';
5
+ import { borderRadiusPresets } from '../providers/Theme/themeConfig.js';
6
+ import { resolveTypographyPreview } from '../components/typographyPreviewUtils.js';
7
+ import { defaultThemePresets } from '../index.js';
8
+ import { darkModeDefaults, lightModeDefaults } from './colorModeFields.js';
9
+ const FALLBACK_THEME = defaultThemePresets[0]?.name ?? 'cool';
10
+ const themePresets = defaultThemePresets.reduce((acc, preset)=>{
11
+ acc[preset.name] = {
12
+ label: preset.label,
13
+ lightMode: {
14
+ ...lightModeDefaults,
15
+ ...preset.lightMode ?? {}
16
+ },
17
+ darkMode: {
18
+ ...darkModeDefaults,
19
+ ...preset.darkMode ?? {}
20
+ },
21
+ typography: preset.typography,
22
+ borderRadius: preset.borderRadius
23
+ };
24
+ return acc;
25
+ }, {});
26
+ const colorKeys = Object.keys(lightModeDefaults);
27
+ function ModePreview({ icon, title, colors, typography, radius }) {
28
+ const background = colors.background ?? '#ffffff';
29
+ const foreground = colors.foreground ?? '#0a0a0a';
30
+ const borderColor = colors.border ?? 'rgba(148, 163, 184, 0.35)';
31
+ const cardBackground = colors.card ?? background;
32
+ const cardForeground = colors.cardForeground ?? foreground;
33
+ const primary = colors.primary ?? foreground;
34
+ const primaryForeground = colors.primaryForeground ?? background;
35
+ const secondary = colors.secondary ?? '#f4f4f5';
36
+ const secondaryForeground = colors.secondaryForeground ?? foreground;
37
+ const muted = colors.muted ?? secondary;
38
+ const mutedForeground = colors.mutedForeground ?? secondaryForeground;
39
+ const accent = colors.accent ?? secondary;
40
+ const accentForeground = colors.accentForeground ?? secondaryForeground;
41
+ const headingFont = typography.headingFont;
42
+ const bodyFont = typography.bodyFont;
43
+ const baseFontSize = typography.baseFontSize;
44
+ const lineHeight = typography.lineHeight;
45
+ return /*#__PURE__*/ _jsxs("div", {
46
+ style: {
47
+ display: 'grid',
48
+ gap: '16px',
49
+ padding: '18px',
50
+ borderRadius: '12px',
51
+ backgroundColor: background,
52
+ color: foreground,
53
+ border: `1px solid ${borderColor}`,
54
+ boxShadow: '0 8px 20px rgba(15, 23, 42, 0.08)',
55
+ fontFamily: bodyFont
56
+ },
57
+ children: [
58
+ /*#__PURE__*/ _jsxs("div", {
59
+ style: {
60
+ display: 'flex',
61
+ alignItems: 'center',
62
+ justifyContent: 'space-between',
63
+ fontSize: '12px',
64
+ fontWeight: 600,
65
+ letterSpacing: '0.08em',
66
+ textTransform: 'uppercase',
67
+ opacity: 0.7
68
+ },
69
+ children: [
70
+ /*#__PURE__*/ _jsxs("span", {
71
+ children: [
72
+ icon,
73
+ " ",
74
+ title
75
+ ]
76
+ }),
77
+ /*#__PURE__*/ _jsx("span", {
78
+ style: {
79
+ fontFamily: 'monospace',
80
+ fontSize: '11px'
81
+ },
82
+ children: background.toUpperCase()
83
+ })
84
+ ]
85
+ }),
86
+ /*#__PURE__*/ _jsxs("div", {
87
+ style: {
88
+ backgroundColor: cardBackground,
89
+ color: cardForeground,
90
+ borderRadius: radius.card,
91
+ border: `1px solid ${borderColor}`,
92
+ padding: '16px',
93
+ display: 'flex',
94
+ gap: '12px',
95
+ flexWrap: 'wrap'
96
+ },
97
+ children: [
98
+ /*#__PURE__*/ _jsx("button", {
99
+ type: "button",
100
+ style: {
101
+ padding: '10px 18px',
102
+ borderRadius: radius.pill,
103
+ border: 'none',
104
+ cursor: 'pointer',
105
+ fontSize: '12px',
106
+ fontWeight: 600,
107
+ letterSpacing: '0.02em',
108
+ backgroundColor: primary,
109
+ color: primaryForeground,
110
+ boxShadow: '0 6px 14px rgba(15, 23, 42, 0.15)'
111
+ },
112
+ children: "Primary Action"
113
+ }),
114
+ /*#__PURE__*/ _jsx("button", {
115
+ type: "button",
116
+ style: {
117
+ padding: '10px 18px',
118
+ borderRadius: radius.chip,
119
+ border: '1px solid transparent',
120
+ cursor: 'pointer',
121
+ fontSize: '12px',
122
+ fontWeight: 600,
123
+ letterSpacing: '0.02em',
124
+ backgroundColor: secondary,
125
+ color: secondaryForeground,
126
+ boxShadow: 'inset 0 0 0 1px rgba(15, 23, 42, 0.08)'
127
+ },
128
+ children: "Secondary"
129
+ })
130
+ ]
131
+ }),
132
+ /*#__PURE__*/ _jsxs("div", {
133
+ style: {
134
+ display: 'grid',
135
+ gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',
136
+ gap: '10px'
137
+ },
138
+ children: [
139
+ /*#__PURE__*/ _jsx("div", {
140
+ style: {
141
+ borderRadius: radius.chip,
142
+ padding: '10px 12px',
143
+ fontSize: '12px',
144
+ fontWeight: 500,
145
+ backgroundColor: muted,
146
+ color: mutedForeground
147
+ },
148
+ children: "Muted Card"
149
+ }),
150
+ /*#__PURE__*/ _jsx("div", {
151
+ style: {
152
+ borderRadius: radius.chip,
153
+ padding: '10px 12px',
154
+ fontSize: '12px',
155
+ fontWeight: 500,
156
+ backgroundColor: accent,
157
+ color: accentForeground
158
+ },
159
+ children: "Accent Tag"
160
+ })
161
+ ]
162
+ }),
163
+ /*#__PURE__*/ _jsxs("div", {
164
+ style: {
165
+ display: 'grid',
166
+ gap: '8px',
167
+ borderRadius: '10px',
168
+ border: `1px dashed ${borderColor}`,
169
+ padding: '14px',
170
+ backgroundColor: 'rgba(148, 163, 184, 0.08)'
171
+ },
172
+ children: [
173
+ /*#__PURE__*/ _jsx("div", {
174
+ style: {
175
+ fontFamily: headingFont,
176
+ fontSize: 'clamp(24px, 3vw, 32px)',
177
+ fontWeight: 600,
178
+ lineHeight: 1.2
179
+ },
180
+ children: "Nadpis / Heading preview"
181
+ }),
182
+ /*#__PURE__*/ _jsx("p", {
183
+ style: {
184
+ margin: 0,
185
+ fontFamily: bodyFont,
186
+ fontSize: baseFontSize,
187
+ lineHeight,
188
+ color: foreground,
189
+ opacity: 0.85
190
+ },
191
+ children: "Sphinx of black quartz, judge my vow. Příliš žluťoučký kůň úpěl ďábelské ódy."
192
+ }),
193
+ /*#__PURE__*/ _jsxs("div", {
194
+ style: {
195
+ display: 'flex',
196
+ flexWrap: 'wrap',
197
+ gap: '10px',
198
+ fontSize: '11px',
199
+ color: 'rgba(15, 23, 42, 0.7)'
200
+ },
201
+ children: [
202
+ /*#__PURE__*/ _jsxs("span", {
203
+ children: [
204
+ "Body: ",
205
+ typography.bodyLabel
206
+ ]
207
+ }),
208
+ /*#__PURE__*/ _jsxs("span", {
209
+ children: [
210
+ "Heading: ",
211
+ typography.headingLabel
212
+ ]
213
+ }),
214
+ /*#__PURE__*/ _jsxs("span", {
215
+ children: [
216
+ "Base size: ",
217
+ baseFontSize
218
+ ]
219
+ }),
220
+ /*#__PURE__*/ _jsxs("span", {
221
+ children: [
222
+ "Line height: ",
223
+ lineHeight
224
+ ]
225
+ })
226
+ ]
227
+ })
228
+ ]
229
+ })
230
+ ]
231
+ });
232
+ }
233
+ export default function ThemePreviewField(props) {
234
+ const { field, path } = props;
235
+ const { value: selectedTheme, setValue } = useField({
236
+ path
237
+ });
238
+ const { dispatchFields } = useForm();
239
+ const formFields = useFormFields(([formState])=>formState);
240
+ const hasAppliedInitialPresetRef = useRef(false);
241
+ const applyPreset = useCallback((presetName)=>{
242
+ const preset = themePresets[presetName];
243
+ if (!preset) {
244
+ return;
245
+ }
246
+ colorKeys.forEach((key)=>{
247
+ const lightValue = preset.lightMode[key];
248
+ const darkValue = preset.darkMode[key];
249
+ if (lightValue) {
250
+ dispatchFields({
251
+ type: 'UPDATE',
252
+ path: `themeConfiguration.lightMode.${key}`,
253
+ value: lightValue
254
+ });
255
+ }
256
+ if (darkValue) {
257
+ dispatchFields({
258
+ type: 'UPDATE',
259
+ path: `themeConfiguration.darkMode.${key}`,
260
+ value: darkValue
261
+ });
262
+ }
263
+ });
264
+ }, [
265
+ dispatchFields
266
+ ]);
267
+ const handleThemeChange = useCallback((event)=>{
268
+ const value = event.target.value;
269
+ setValue(value);
270
+ if (!value) {
271
+ return;
272
+ }
273
+ hasAppliedInitialPresetRef.current = true;
274
+ applyPreset(value);
275
+ }, [
276
+ applyPreset,
277
+ setValue
278
+ ]);
279
+ useEffect(()=>{
280
+ if (!selectedTheme) {
281
+ return;
282
+ }
283
+ if (themePresets[selectedTheme]) {
284
+ return;
285
+ }
286
+ hasAppliedInitialPresetRef.current = false;
287
+ setValue(FALLBACK_THEME);
288
+ }, [
289
+ selectedTheme,
290
+ setValue
291
+ ]);
292
+ useEffect(()=>{
293
+ if (hasAppliedInitialPresetRef.current) {
294
+ return;
295
+ }
296
+ if (!selectedTheme) {
297
+ return;
298
+ }
299
+ if (!formFields) {
300
+ return;
301
+ }
302
+ const preset = themePresets[selectedTheme];
303
+ if (!preset) {
304
+ hasAppliedInitialPresetRef.current = true;
305
+ return;
306
+ }
307
+ const hasExistingValues = colorKeys.some((key)=>{
308
+ const lightField = formFields[`themeConfiguration.lightMode.${key}`];
309
+ const darkField = formFields[`themeConfiguration.darkMode.${key}`];
310
+ const lightValue = typeof lightField?.value === 'string' && lightField.value.trim().length > 0;
311
+ const darkValue = typeof darkField?.value === 'string' && darkField.value.trim().length > 0;
312
+ return lightValue || darkValue;
313
+ });
314
+ if (hasExistingValues) {
315
+ hasAppliedInitialPresetRef.current = true;
316
+ return;
317
+ }
318
+ applyPreset(selectedTheme);
319
+ hasAppliedInitialPresetRef.current = true;
320
+ }, [
321
+ selectedTheme,
322
+ formFields,
323
+ applyPreset
324
+ ]);
325
+ const lightModeColors = useMemo(()=>{
326
+ const presetLightMode = selectedTheme ? themePresets[selectedTheme]?.lightMode : undefined;
327
+ return colorKeys.reduce((acc, key)=>{
328
+ const fieldState = formFields?.[`themeConfiguration.lightMode.${key}`];
329
+ const rawValue = typeof fieldState?.value === 'string' && fieldState.value.trim().length > 0 ? fieldState.value : undefined;
330
+ acc[key] = rawValue ?? presetLightMode?.[key] ?? lightModeDefaults[key];
331
+ return acc;
332
+ }, {});
333
+ }, [
334
+ formFields,
335
+ selectedTheme
336
+ ]);
337
+ const darkModeColors = useMemo(()=>{
338
+ const presetDarkMode = selectedTheme ? themePresets[selectedTheme]?.darkMode : undefined;
339
+ return colorKeys.reduce((acc, key)=>{
340
+ const fieldState = formFields?.[`themeConfiguration.darkMode.${key}`];
341
+ const rawValue = typeof fieldState?.value === 'string' && fieldState.value.trim().length > 0 ? fieldState.value : undefined;
342
+ acc[key] = rawValue ?? presetDarkMode?.[key] ?? darkModeDefaults[key];
343
+ return acc;
344
+ }, {});
345
+ }, [
346
+ formFields,
347
+ selectedTheme
348
+ ]);
349
+ const activePreset = selectedTheme ? themePresets[selectedTheme] : undefined;
350
+ const formTypographySelection = useMemo(()=>{
351
+ if (!formFields) {
352
+ return null;
353
+ }
354
+ const getValue = (key)=>formFields[`themeConfiguration.typography.${key}`]?.value;
355
+ return {
356
+ bodyFont: getValue('bodyFont') ?? undefined,
357
+ headingFont: getValue('headingFont') ?? undefined,
358
+ bodyFontCustom: getValue('bodyFontCustom') ?? undefined,
359
+ headingFontCustom: getValue('headingFontCustom') ?? undefined,
360
+ baseFontSize: getValue('baseFontSize') ?? undefined,
361
+ lineHeight: getValue('lineHeight') ?? undefined
362
+ };
363
+ }, [
364
+ formFields
365
+ ]);
366
+ const previewTypography = useMemo(()=>{
367
+ return resolveTypographyPreview(formTypographySelection, selectedTheme);
368
+ }, [
369
+ formTypographySelection,
370
+ selectedTheme
371
+ ]);
372
+ const borderRadiusValue = formFields?.['themeConfiguration.borderRadius']?.value;
373
+ const presetRadius = activePreset?.borderRadius ?? 'medium';
374
+ const resolvedBorderRadius = typeof borderRadiusValue === 'string' && borderRadiusValue.length ? borderRadiusValue : presetRadius;
375
+ const borderRadiusPreset = borderRadiusPresets[resolvedBorderRadius] ?? borderRadiusPresets.medium;
376
+ const borderRadiusCSS = typeof borderRadiusPreset.css === 'string' ? {
377
+ '--radius-default': borderRadiusPreset.css
378
+ } : borderRadiusPreset.css;
379
+ const previewRadius = {
380
+ card: borderRadiusCSS['--radius-large'] ?? '1rem',
381
+ chip: borderRadiusCSS['--radius-default'] ?? '0.75rem',
382
+ pill: borderRadiusCSS['--radius-xl'] ?? borderRadiusCSS['--radius-large'] ?? '999px'
383
+ };
384
+ const fieldLabel = typeof field.label === 'string' ? field.label : field.label?.en || field.label?.cs || 'Theme';
385
+ return /*#__PURE__*/ _jsxs("div", {
386
+ style: {
387
+ marginBottom: '24px'
388
+ },
389
+ children: [
390
+ /*#__PURE__*/ _jsx("label", {
391
+ style: {
392
+ display: 'block',
393
+ marginBottom: '10px',
394
+ fontSize: '13px',
395
+ fontWeight: 600,
396
+ color: 'var(--theme-elevation-800)'
397
+ },
398
+ children: fieldLabel
399
+ }),
400
+ /*#__PURE__*/ _jsxs("div", {
401
+ style: {
402
+ display: 'flex',
403
+ flexWrap: 'wrap',
404
+ gap: '24px',
405
+ alignItems: 'flex-start'
406
+ },
407
+ children: [
408
+ /*#__PURE__*/ _jsxs("div", {
409
+ style: {
410
+ flex: '0 0 320px',
411
+ minWidth: '260px',
412
+ maxWidth: '420px',
413
+ display: 'grid',
414
+ gap: '12px'
415
+ },
416
+ children: [
417
+ /*#__PURE__*/ _jsxs("select", {
418
+ value: selectedTheme || '',
419
+ onChange: handleThemeChange,
420
+ style: {
421
+ width: '100%',
422
+ padding: '12px 14px',
423
+ fontSize: '14px',
424
+ borderRadius: '8px',
425
+ border: '1px solid var(--theme-elevation-250)',
426
+ backgroundColor: 'var(--theme-input-bg)',
427
+ color: 'var(--theme-elevation-800)',
428
+ cursor: 'pointer'
429
+ },
430
+ children: [
431
+ /*#__PURE__*/ _jsx("option", {
432
+ value: "",
433
+ children: "Select a theme…"
434
+ }),
435
+ Object.entries(themePresets).map(([key, preset])=>/*#__PURE__*/ _jsx("option", {
436
+ value: key,
437
+ children: preset.label
438
+ }, key))
439
+ ]
440
+ }),
441
+ activePreset && /*#__PURE__*/ _jsxs("div", {
442
+ style: {
443
+ padding: '12px',
444
+ borderRadius: '10px',
445
+ border: '1px solid var(--theme-elevation-200)',
446
+ backgroundColor: 'var(--theme-elevation-50)',
447
+ display: 'grid',
448
+ gap: '6px',
449
+ fontSize: '12px',
450
+ color: 'var(--theme-elevation-600)'
451
+ },
452
+ children: [
453
+ /*#__PURE__*/ _jsx("div", {
454
+ style: {
455
+ fontWeight: 600,
456
+ color: 'var(--theme-elevation-800)'
457
+ },
458
+ children: activePreset.label
459
+ }),
460
+ /*#__PURE__*/ _jsxs("div", {
461
+ children: [
462
+ "Primary color: ",
463
+ activePreset.lightMode.primary
464
+ ]
465
+ }),
466
+ /*#__PURE__*/ _jsxs("div", {
467
+ children: [
468
+ "Accent color: ",
469
+ activePreset.lightMode.accent
470
+ ]
471
+ })
472
+ ]
473
+ }),
474
+ field.admin?.description && /*#__PURE__*/ _jsx("div", {
475
+ style: {
476
+ fontSize: '12px',
477
+ color: 'var(--theme-elevation-600)',
478
+ lineHeight: 1.5
479
+ },
480
+ children: typeof field.admin.description === 'string' ? field.admin.description : field.admin.description?.en || field.admin.description?.cs || ''
481
+ })
482
+ ]
483
+ }),
484
+ /*#__PURE__*/ _jsx("div", {
485
+ style: {
486
+ flex: '1 1 420px',
487
+ minWidth: '320px',
488
+ position: 'sticky',
489
+ top: '96px',
490
+ alignSelf: 'flex-start'
491
+ },
492
+ children: /*#__PURE__*/ _jsxs("div", {
493
+ style: {
494
+ width: '100%',
495
+ borderRadius: '16px',
496
+ border: '1px solid var(--theme-elevation-200)',
497
+ backgroundColor: 'var(--theme-elevation-25)',
498
+ padding: '20px',
499
+ display: 'grid',
500
+ gap: '18px',
501
+ maxHeight: 'calc(100vh - 140px)',
502
+ overflowY: 'auto'
503
+ },
504
+ children: [
505
+ /*#__PURE__*/ _jsxs("div", {
506
+ style: {
507
+ display: 'flex',
508
+ alignItems: 'center',
509
+ justifyContent: 'space-between',
510
+ fontWeight: 600,
511
+ fontSize: '13px',
512
+ color: 'var(--theme-elevation-800)'
513
+ },
514
+ children: [
515
+ /*#__PURE__*/ _jsx("span", {
516
+ children: "🎨 Live Preview"
517
+ }),
518
+ /*#__PURE__*/ _jsx("span", {
519
+ style: {
520
+ fontSize: '12px',
521
+ color: 'var(--theme-elevation-600)'
522
+ },
523
+ children: activePreset ? activePreset.label : 'Custom palette'
524
+ })
525
+ ]
526
+ }),
527
+ /*#__PURE__*/ _jsxs("div", {
528
+ style: {
529
+ display: 'grid',
530
+ gap: '16px'
531
+ },
532
+ children: [
533
+ /*#__PURE__*/ _jsx(ModePreview, {
534
+ icon: "☀️",
535
+ title: "Light Mode",
536
+ colors: lightModeColors,
537
+ typography: previewTypography,
538
+ radius: previewRadius
539
+ }),
540
+ /*#__PURE__*/ _jsx(ModePreview, {
541
+ icon: "🌙",
542
+ title: "Dark Mode",
543
+ colors: darkModeColors,
544
+ typography: previewTypography,
545
+ radius: previewRadius
546
+ })
547
+ ]
548
+ })
549
+ ]
550
+ })
551
+ })
552
+ ]
553
+ })
554
+ ]
555
+ });
556
+ }
557
+
558
+ //# sourceMappingURL=ThemePreviewField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/fields/ThemePreviewField.tsx"],"sourcesContent":["'use client'\n\nimport { useField, useForm, useFormFields } from '@payloadcms/ui'\nimport type { SelectFieldClientProps } from 'payload'\nimport { useCallback, useEffect, useMemo, useRef, type ChangeEvent } from 'react'\nimport { borderRadiusPresets } from '../providers/Theme/themeConfig.js'\nimport type {\n ResolvedTypographyPreview,\n TypographySelection,\n} from '../components/typographyPreviewUtils.js'\nimport { resolveTypographyPreview } from '../components/typographyPreviewUtils.js'\nimport { defaultThemePresets } from '../index.js'\nimport type { ThemeTypographyPreset } from '../presets.js'\nimport { darkModeDefaults, lightModeDefaults } from './colorModeFields.js'\n\ninterface ColorModeColors {\n background?: string\n foreground?: string\n card?: string\n cardForeground?: string\n popover?: string\n popoverForeground?: string\n primary?: string\n primaryForeground?: string\n secondary?: string\n secondaryForeground?: string\n muted?: string\n mutedForeground?: string\n accent?: string\n accentForeground?: string\n destructive?: string\n destructiveForeground?: string\n border?: string\n input?: string\n ring?: string\n}\n\ninterface ThemePresetDefinition {\n label: string\n lightMode: ColorModeColors\n darkMode: ColorModeColors\n typography?: ThemeTypographyPreset\n borderRadius: 'none' | 'small' | 'medium' | 'large' | 'xl'\n}\n\nconst FALLBACK_THEME = defaultThemePresets[0]?.name ?? 'cool'\n\nconst themePresets = defaultThemePresets.reduce<Record<string, ThemePresetDefinition>>(\n (acc, preset) => {\n acc[preset.name] = {\n label: preset.label,\n lightMode: { ...lightModeDefaults, ...(preset.lightMode ?? {}) },\n darkMode: { ...darkModeDefaults, ...(preset.darkMode ?? {}) },\n typography: preset.typography,\n borderRadius: preset.borderRadius,\n }\n return acc\n },\n {},\n)\n\nconst colorKeys = Object.keys(lightModeDefaults) as (keyof ColorModeColors)[]\n\ninterface ModePreviewProps {\n icon: string\n title: string\n colors: ColorModeColors\n typography: ResolvedTypographyPreview\n radius: {\n card: string\n chip: string\n pill: string\n }\n}\n\nfunction ModePreview({ icon, title, colors, typography, radius }: Readonly<ModePreviewProps>) {\n const background = colors.background ?? '#ffffff'\n const foreground = colors.foreground ?? '#0a0a0a'\n const borderColor = colors.border ?? 'rgba(148, 163, 184, 0.35)'\n const cardBackground = colors.card ?? background\n const cardForeground = colors.cardForeground ?? foreground\n const primary = colors.primary ?? foreground\n const primaryForeground = colors.primaryForeground ?? background\n const secondary = colors.secondary ?? '#f4f4f5'\n const secondaryForeground = colors.secondaryForeground ?? foreground\n const muted = colors.muted ?? secondary\n const mutedForeground = colors.mutedForeground ?? secondaryForeground\n const accent = colors.accent ?? secondary\n const accentForeground = colors.accentForeground ?? secondaryForeground\n const headingFont = typography.headingFont\n const bodyFont = typography.bodyFont\n const baseFontSize = typography.baseFontSize\n const lineHeight = typography.lineHeight\n\n return (\n <div\n style={{\n display: 'grid',\n gap: '16px',\n padding: '18px',\n borderRadius: '12px',\n backgroundColor: background,\n color: foreground,\n border: `1px solid ${borderColor}`,\n boxShadow: '0 8px 20px rgba(15, 23, 42, 0.08)',\n fontFamily: bodyFont,\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: '12px',\n fontWeight: 600,\n letterSpacing: '0.08em',\n textTransform: 'uppercase',\n opacity: 0.7,\n }}\n >\n <span>\n {icon} {title}\n </span>\n <span style={{ fontFamily: 'monospace', fontSize: '11px' }}>\n {background.toUpperCase()}\n </span>\n </div>\n\n <div\n style={{\n backgroundColor: cardBackground,\n color: cardForeground,\n borderRadius: radius.card,\n border: `1px solid ${borderColor}`,\n padding: '16px',\n display: 'flex',\n gap: '12px',\n flexWrap: 'wrap',\n }}\n >\n <button\n type=\"button\"\n style={{\n padding: '10px 18px',\n borderRadius: radius.pill,\n border: 'none',\n cursor: 'pointer',\n fontSize: '12px',\n fontWeight: 600,\n letterSpacing: '0.02em',\n backgroundColor: primary,\n color: primaryForeground,\n boxShadow: '0 6px 14px rgba(15, 23, 42, 0.15)',\n }}\n >\n Primary Action\n </button>\n <button\n type=\"button\"\n style={{\n padding: '10px 18px',\n borderRadius: radius.chip,\n border: '1px solid transparent',\n cursor: 'pointer',\n fontSize: '12px',\n fontWeight: 600,\n letterSpacing: '0.02em',\n backgroundColor: secondary,\n color: secondaryForeground,\n boxShadow: 'inset 0 0 0 1px rgba(15, 23, 42, 0.08)',\n }}\n >\n Secondary\n </button>\n </div>\n\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',\n gap: '10px',\n }}\n >\n <div\n style={{\n borderRadius: radius.chip,\n padding: '10px 12px',\n fontSize: '12px',\n fontWeight: 500,\n backgroundColor: muted,\n color: mutedForeground,\n }}\n >\n Muted Card\n </div>\n <div\n style={{\n borderRadius: radius.chip,\n padding: '10px 12px',\n fontSize: '12px',\n fontWeight: 500,\n backgroundColor: accent,\n color: accentForeground,\n }}\n >\n Accent Tag\n </div>\n </div>\n\n <div\n style={{\n display: 'grid',\n gap: '8px',\n borderRadius: '10px',\n border: `1px dashed ${borderColor}`,\n padding: '14px',\n backgroundColor: 'rgba(148, 163, 184, 0.08)',\n }}\n >\n <div\n style={{\n fontFamily: headingFont,\n fontSize: 'clamp(24px, 3vw, 32px)',\n fontWeight: 600,\n lineHeight: 1.2,\n }}\n >\n Nadpis / Heading preview\n </div>\n <p\n style={{\n margin: 0,\n fontFamily: bodyFont,\n fontSize: baseFontSize,\n lineHeight,\n color: foreground,\n opacity: 0.85,\n }}\n >\n Sphinx of black quartz, judge my vow. Příliš žluťoučký kůň úpěl ďábelské ódy.\n </p>\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: '10px',\n fontSize: '11px',\n color: 'rgba(15, 23, 42, 0.7)',\n }}\n >\n <span>Body: {typography.bodyLabel}</span>\n <span>Heading: {typography.headingLabel}</span>\n <span>Base size: {baseFontSize}</span>\n <span>Line height: {lineHeight}</span>\n </div>\n </div>\n </div>\n )\n}\n\nexport default function ThemePreviewField(props: SelectFieldClientProps) {\n const { field, path } = props\n const { value: selectedTheme, setValue } = useField<string>({ path })\n const { dispatchFields } = useForm()\n const formFields = useFormFields(([formState]) => formState)\n const hasAppliedInitialPresetRef = useRef(false)\n\n const applyPreset = useCallback(\n (presetName: string) => {\n const preset = themePresets[presetName]\n if (!preset) {\n return\n }\n\n colorKeys.forEach((key) => {\n const lightValue = preset.lightMode[key]\n const darkValue = preset.darkMode[key]\n\n if (lightValue) {\n dispatchFields({\n type: 'UPDATE',\n path: `themeConfiguration.lightMode.${key}`,\n value: lightValue,\n })\n }\n\n if (darkValue) {\n dispatchFields({\n type: 'UPDATE',\n path: `themeConfiguration.darkMode.${key}`,\n value: darkValue,\n })\n }\n })\n },\n [dispatchFields],\n )\n\n const handleThemeChange = useCallback(\n (event: ChangeEvent<HTMLSelectElement>) => {\n const value = event.target.value\n setValue(value)\n\n if (!value) {\n return\n }\n\n hasAppliedInitialPresetRef.current = true\n applyPreset(value)\n },\n [applyPreset, setValue],\n )\n\n useEffect(() => {\n if (!selectedTheme) {\n return\n }\n\n if (themePresets[selectedTheme]) {\n return\n }\n\n hasAppliedInitialPresetRef.current = false\n setValue(FALLBACK_THEME)\n }, [selectedTheme, setValue])\n\n useEffect(() => {\n if (hasAppliedInitialPresetRef.current) {\n return\n }\n\n if (!selectedTheme) {\n return\n }\n\n if (!formFields) {\n return\n }\n\n const preset = themePresets[selectedTheme]\n if (!preset) {\n hasAppliedInitialPresetRef.current = true\n return\n }\n\n const hasExistingValues = colorKeys.some((key) => {\n const lightField = formFields[`themeConfiguration.lightMode.${key}`]\n const darkField = formFields[`themeConfiguration.darkMode.${key}`]\n\n const lightValue = typeof lightField?.value === 'string' && lightField.value.trim().length > 0\n const darkValue = typeof darkField?.value === 'string' && darkField.value.trim().length > 0\n\n return lightValue || darkValue\n })\n\n if (hasExistingValues) {\n hasAppliedInitialPresetRef.current = true\n return\n }\n\n applyPreset(selectedTheme)\n hasAppliedInitialPresetRef.current = true\n }, [selectedTheme, formFields, applyPreset])\n\n const lightModeColors = useMemo(() => {\n const presetLightMode = selectedTheme ? themePresets[selectedTheme]?.lightMode : undefined\n\n return colorKeys.reduce<ColorModeColors>((acc, key) => {\n const fieldState = formFields?.[`themeConfiguration.lightMode.${key}`]\n const rawValue =\n typeof fieldState?.value === 'string' && fieldState.value.trim().length > 0\n ? fieldState.value\n : undefined\n\n acc[key] = rawValue ?? presetLightMode?.[key] ?? lightModeDefaults[key]\n return acc\n }, {} as ColorModeColors)\n }, [formFields, selectedTheme])\n\n const darkModeColors = useMemo(() => {\n const presetDarkMode = selectedTheme ? themePresets[selectedTheme]?.darkMode : undefined\n\n return colorKeys.reduce<ColorModeColors>((acc, key) => {\n const fieldState = formFields?.[`themeConfiguration.darkMode.${key}`]\n const rawValue =\n typeof fieldState?.value === 'string' && fieldState.value.trim().length > 0\n ? fieldState.value\n : undefined\n\n acc[key] = rawValue ?? presetDarkMode?.[key] ?? darkModeDefaults[key]\n return acc\n }, {} as ColorModeColors)\n }, [formFields, selectedTheme])\n\n const activePreset = selectedTheme ? themePresets[selectedTheme] : undefined\n const formTypographySelection = useMemo<TypographySelection | null>(() => {\n if (!formFields) {\n return null\n }\n\n const getValue = (key: string) => formFields[`themeConfiguration.typography.${key}`]?.value\n\n return {\n bodyFont: (getValue('bodyFont') as string | undefined) ?? undefined,\n headingFont: (getValue('headingFont') as string | undefined) ?? undefined,\n bodyFontCustom: (getValue('bodyFontCustom') as string | undefined) ?? undefined,\n headingFontCustom: (getValue('headingFontCustom') as string | undefined) ?? undefined,\n baseFontSize: (getValue('baseFontSize') as string | undefined) ?? undefined,\n lineHeight: (getValue('lineHeight') as string | undefined) ?? undefined,\n }\n }, [formFields])\n\n const previewTypography = useMemo<ResolvedTypographyPreview>(() => {\n return resolveTypographyPreview(formTypographySelection, selectedTheme)\n }, [formTypographySelection, selectedTheme])\n\n const borderRadiusValue = formFields?.['themeConfiguration.borderRadius']?.value\n const presetRadius = activePreset?.borderRadius ?? 'medium'\n const resolvedBorderRadius = (\n typeof borderRadiusValue === 'string' && borderRadiusValue.length\n ? borderRadiusValue\n : presetRadius\n ) as keyof typeof borderRadiusPresets\n const borderRadiusPreset = borderRadiusPresets[resolvedBorderRadius] ?? borderRadiusPresets.medium\n const borderRadiusCSS =\n typeof borderRadiusPreset.css === 'string'\n ? { '--radius-default': borderRadiusPreset.css }\n : (borderRadiusPreset.css as Record<string, string>)\n const previewRadius = {\n card: borderRadiusCSS['--radius-large'] ?? '1rem',\n chip: borderRadiusCSS['--radius-default'] ?? '0.75rem',\n pill:\n borderRadiusCSS['--radius-xl'] ?? borderRadiusCSS['--radius-large'] ?? '999px',\n }\n\n const fieldLabel =\n typeof field.label === 'string' ? field.label : field.label?.en || field.label?.cs || 'Theme'\n\n return (\n <div style={{ marginBottom: '24px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '10px',\n fontSize: '13px',\n fontWeight: 600,\n color: 'var(--theme-elevation-800)',\n }}\n >\n {fieldLabel}\n </label>\n\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: '24px',\n alignItems: 'flex-start',\n }}\n >\n <div\n style={{\n flex: '0 0 320px',\n minWidth: '260px',\n maxWidth: '420px',\n display: 'grid',\n gap: '12px',\n }}\n >\n <select\n value={selectedTheme || ''}\n onChange={handleThemeChange}\n style={{\n width: '100%',\n padding: '12px 14px',\n fontSize: '14px',\n borderRadius: '8px',\n border: '1px solid var(--theme-elevation-250)',\n backgroundColor: 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n }}\n >\n <option value=\"\">Select a theme…</option>\n {Object.entries(themePresets).map(([key, preset]) => (\n <option key={key} value={key}>\n {preset.label}\n </option>\n ))}\n </select>\n\n {activePreset && (\n <div\n style={{\n padding: '12px',\n borderRadius: '10px',\n border: '1px solid var(--theme-elevation-200)',\n backgroundColor: 'var(--theme-elevation-50)',\n display: 'grid',\n gap: '6px',\n fontSize: '12px',\n color: 'var(--theme-elevation-600)',\n }}\n >\n <div style={{ fontWeight: 600, color: 'var(--theme-elevation-800)' }}>\n {activePreset.label}\n </div>\n <div>Primary color: {activePreset.lightMode.primary}</div>\n <div>Accent color: {activePreset.lightMode.accent}</div>\n </div>\n )}\n\n {field.admin?.description && (\n <div\n style={{\n fontSize: '12px',\n color: 'var(--theme-elevation-600)',\n lineHeight: 1.5,\n }}\n >\n {typeof field.admin.description === 'string'\n ? field.admin.description\n : field.admin.description?.en || field.admin.description?.cs || ''}\n </div>\n )}\n </div>\n\n <div\n style={{\n flex: '1 1 420px',\n minWidth: '320px',\n position: 'sticky',\n top: '96px',\n alignSelf: 'flex-start',\n }}\n >\n <div\n style={{\n width: '100%',\n borderRadius: '16px',\n border: '1px solid var(--theme-elevation-200)',\n backgroundColor: 'var(--theme-elevation-25)',\n padding: '20px',\n display: 'grid',\n gap: '18px',\n maxHeight: 'calc(100vh - 140px)',\n overflowY: 'auto',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontWeight: 600,\n fontSize: '13px',\n color: 'var(--theme-elevation-800)',\n }}\n >\n <span>🎨 Live Preview</span>\n <span style={{ fontSize: '12px', color: 'var(--theme-elevation-600)' }}>\n {activePreset ? activePreset.label : 'Custom palette'}\n </span>\n </div>\n\n <div\n style={{\n display: 'grid',\n gap: '16px',\n }}\n >\n <ModePreview\n icon=\"☀️\"\n title=\"Light Mode\"\n colors={lightModeColors}\n typography={previewTypography}\n radius={previewRadius}\n />\n <ModePreview\n icon=\"🌙\"\n title=\"Dark Mode\"\n colors={darkModeColors}\n typography={previewTypography}\n radius={previewRadius}\n />\n </div>\n </div>\n </div>\n </div>\n </div>\n )\n}\n"],"names":["useField","useForm","useFormFields","useCallback","useEffect","useMemo","useRef","borderRadiusPresets","resolveTypographyPreview","defaultThemePresets","darkModeDefaults","lightModeDefaults","FALLBACK_THEME","name","themePresets","reduce","acc","preset","label","lightMode","darkMode","typography","borderRadius","colorKeys","Object","keys","ModePreview","icon","title","colors","radius","background","foreground","borderColor","border","cardBackground","card","cardForeground","primary","primaryForeground","secondary","secondaryForeground","muted","mutedForeground","accent","accentForeground","headingFont","bodyFont","baseFontSize","lineHeight","div","style","display","gap","padding","backgroundColor","color","boxShadow","fontFamily","alignItems","justifyContent","fontSize","fontWeight","letterSpacing","textTransform","opacity","span","toUpperCase","flexWrap","button","type","pill","cursor","chip","gridTemplateColumns","p","margin","bodyLabel","headingLabel","ThemePreviewField","props","field","path","value","selectedTheme","setValue","dispatchFields","formFields","formState","hasAppliedInitialPresetRef","applyPreset","presetName","forEach","key","lightValue","darkValue","handleThemeChange","event","target","current","hasExistingValues","some","lightField","darkField","trim","length","lightModeColors","presetLightMode","undefined","fieldState","rawValue","darkModeColors","presetDarkMode","activePreset","formTypographySelection","getValue","bodyFontCustom","headingFontCustom","previewTypography","borderRadiusValue","presetRadius","resolvedBorderRadius","borderRadiusPreset","medium","borderRadiusCSS","css","previewRadius","fieldLabel","en","cs","marginBottom","flex","minWidth","maxWidth","select","onChange","width","option","entries","map","admin","description","position","top","alignSelf","maxHeight","overflowY"],"mappings":"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"}