@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.
- package/dist/components/ServerThemeInjector.d.ts +1 -1
- package/dist/components/ServerThemeInjector.d.ts.map +1 -1
- package/dist/components/{ServerThemeInjector.jsx → ServerThemeInjector.js} +47 -34
- package/dist/components/ServerThemeInjector.js.map +1 -0
- package/dist/components/ThemePreview.js +318 -0
- package/dist/components/ThemePreview.js.map +1 -0
- package/dist/components/typographyPreviewUtils.js +12 -17
- package/dist/components/typographyPreviewUtils.js.map +1 -1
- package/dist/constants/themeFonts.js +94 -24
- package/dist/constants/themeFonts.js.map +1 -1
- package/dist/fields/ColorPickerField.js +332 -0
- package/dist/fields/ColorPickerField.js.map +1 -0
- package/dist/fields/RadiusField.js +174 -0
- package/dist/fields/RadiusField.js.map +1 -0
- package/dist/fields/ThemeColorPickerField.js +163 -0
- package/dist/fields/ThemeColorPickerField.js.map +1 -0
- package/dist/fields/ThemePreviewField.js +558 -0
- package/dist/fields/ThemePreviewField.js.map +1 -0
- package/dist/fields/ThemeTokenSelectField.js +209 -0
- package/dist/fields/ThemeTokenSelectField.js.map +1 -0
- package/dist/fields/colorModeFields.js +167 -73
- package/dist/fields/colorModeFields.js.map +1 -1
- package/dist/fields/themeConfigurationField.d.ts +1 -1
- package/dist/fields/themeConfigurationField.d.ts.map +1 -1
- package/dist/fields/themeConfigurationField.js +224 -131
- package/dist/fields/themeConfigurationField.js.map +1 -1
- package/dist/index.d.ts +17 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -52
- package/dist/index.js.map +1 -1
- package/dist/payload-types.js +2 -2
- package/dist/payload-types.js.map +1 -1
- package/dist/plugin.d.ts +1 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +2 -1
- package/dist/plugin.js.map +1 -1
- package/dist/presets.js +66 -65
- package/dist/presets.js.map +1 -1
- package/dist/providers/Theme/index.d.ts +1 -1
- package/dist/providers/Theme/index.d.ts.map +1 -1
- package/dist/providers/Theme/{index.jsx → index.js} +61 -31
- package/dist/providers/Theme/index.js.map +1 -0
- package/dist/providers/Theme/shared.d.ts +1 -1
- package/dist/providers/Theme/shared.d.ts.map +1 -1
- package/dist/providers/Theme/shared.js +34 -9
- package/dist/providers/Theme/shared.js.map +1 -1
- package/dist/providers/Theme/themeConfig.d.ts +1 -1
- package/dist/providers/Theme/themeConfig.d.ts.map +1 -1
- package/dist/providers/Theme/themeConfig.js +37 -36
- package/dist/providers/Theme/themeConfig.js.map +1 -1
- package/dist/providers/Theme/types.js +15 -13
- package/dist/providers/Theme/types.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -2
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/resolveThemeConfiguration.d.ts +3 -3
- package/dist/utils/resolveThemeConfiguration.d.ts.map +1 -1
- package/dist/utils/resolveThemeConfiguration.js +53 -34
- package/dist/utils/resolveThemeConfiguration.js.map +1 -1
- package/dist/utils/themeAssets.d.ts +1 -1
- package/dist/utils/themeAssets.d.ts.map +1 -1
- package/dist/utils/themeAssets.js +4 -4
- package/dist/utils/themeAssets.js.map +1 -1
- package/dist/utils/themeColors.js +95 -41
- package/dist/utils/themeColors.js.map +1 -1
- package/dist/utils/themeUtils.d.ts +2 -2
- package/dist/utils/themeUtils.d.ts.map +1 -1
- package/dist/utils/themeUtils.js +32 -47
- package/dist/utils/themeUtils.js.map +1 -1
- package/package.json +13 -5
- package/dist/components/ServerThemeInjector.jsx.map +0 -1
- package/dist/components/ThemePreview.jsx +0 -231
- package/dist/components/ThemePreview.jsx.map +0 -1
- package/dist/fields/ColorPickerField.jsx +0 -205
- package/dist/fields/ColorPickerField.jsx.map +0 -1
- package/dist/fields/RadiusField.jsx +0 -123
- package/dist/fields/RadiusField.jsx.map +0 -1
- package/dist/fields/ThemeColorPickerField.jsx +0 -110
- package/dist/fields/ThemeColorPickerField.jsx.map +0 -1
- package/dist/fields/ThemePreviewField.jsx +0 -420
- package/dist/fields/ThemePreviewField.jsx.map +0 -1
- package/dist/fields/ThemeTokenSelectField.jsx +0 -151
- package/dist/fields/ThemeTokenSelectField.jsx.map +0 -1
- 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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"}
|