@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
@@ -1,123 +0,0 @@
1
- 'use client';
2
- import { useField } from '@payloadcms/ui';
3
- import { useMemo } from 'react';
4
- import { borderRadiusPresets } from '@/providers/Theme/themeConfig';
5
- export default function RadiusField({ field, ...props }) {
6
- const { value, setValue } = useField({ path: props.path });
7
- const label = typeof field.label === 'string' ? field.label : '';
8
- const radiusOptions = useMemo(() => {
9
- const entries = Object.entries(borderRadiusPresets);
10
- return entries.map(([key, preset]) => ({
11
- key,
12
- label: preset.label,
13
- css: preset.css,
14
- }));
15
- }, []);
16
- const fallbackKey = radiusOptions[2]?.key ?? radiusOptions[0]?.key ?? 'medium';
17
- const currentKey = typeof value === 'string' && value in borderRadiusPresets
18
- ? value
19
- : fallbackKey;
20
- const description = typeof field.admin?.description === 'string'
21
- ? field.admin.description
22
- : field.admin?.description?.en || field.admin?.description?.cs || null;
23
- return (<div className="field-type">
24
- <label className="field-label" htmlFor={props.path}>
25
- {label}
26
- {field.required && <span className="required">*</span>}
27
- </label>
28
-
29
- {description && (<p style={{
30
- marginTop: '4px',
31
- fontSize: '12px',
32
- lineHeight: 1.5,
33
- color: 'var(--theme-elevation-600)',
34
- }}>
35
- {description}
36
- </p>)}
37
-
38
- <div style={{
39
- display: 'grid',
40
- gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))',
41
- gap: '16px',
42
- marginTop: '16px',
43
- }}>
44
- {radiusOptions.map((option) => {
45
- const isSelected = option.key === currentKey;
46
- const cardRadius = option.css['--radius-large'] ??
47
- option.css['--radius-default'] ??
48
- option.css['--radius-medium'];
49
- const chipRadius = option.css['--radius-default'] ?? option.css['--radius-small'];
50
- const pillRadius = option.css['--radius-xl'] ?? option.css['--radius-large'] ?? '999px';
51
- return (<button key={option.key} type="button" onClick={() => setValue(option.key)} aria-pressed={isSelected} style={{
52
- border: isSelected
53
- ? '2px solid var(--theme-success-500)'
54
- : '1px solid var(--theme-elevation-150)',
55
- borderRadius: '14px',
56
- backgroundColor: 'var(--theme-elevation-25)',
57
- padding: '16px',
58
- display: 'grid',
59
- gap: '10px',
60
- textAlign: 'left',
61
- cursor: 'pointer',
62
- transition: 'border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease',
63
- boxShadow: isSelected
64
- ? '0 10px 20px rgba(34, 197, 94, 0.18)'
65
- : '0 6px 18px rgba(15, 23, 42, 0.08)',
66
- transform: isSelected ? 'translateY(-2px)' : 'translateY(0)',
67
- }}>
68
- <div style={{
69
- display: 'flex',
70
- alignItems: 'center',
71
- justifyContent: 'space-between',
72
- fontWeight: 600,
73
- fontSize: '13px',
74
- color: 'var(--theme-elevation-800)',
75
- }}>
76
- <span>{option.label}</span>
77
- <span style={{ fontSize: '11px', opacity: 0.7 }}>{option.key}</span>
78
- </div>
79
-
80
- <div style={{
81
- display: 'grid',
82
- gap: '10px',
83
- }}>
84
- <div style={{
85
- display: 'flex',
86
- gap: '8px',
87
- alignItems: 'center',
88
- }}>
89
- <div style={{
90
- width: '50px',
91
- height: '34px',
92
- backgroundColor: 'var(--theme-elevation-100)',
93
- border: '1px solid var(--theme-elevation-200)',
94
- borderRadius: cardRadius ?? '0',
95
- }}/>
96
- <div style={{
97
- flex: 1,
98
- height: '14px',
99
- backgroundColor: 'var(--theme-primary-500)',
100
- borderRadius: pillRadius,
101
- }}/>
102
- </div>
103
-
104
- <div style={{
105
- display: 'flex',
106
- gap: '6px',
107
- flexWrap: 'wrap',
108
- fontSize: '11px',
109
- color: 'var(--theme-elevation-600)',
110
- }}>
111
- <span>Card {cardRadius ?? '—'}</span>
112
- <span>Chip {chipRadius ?? '—'}</span>
113
- <span>Pill {pillRadius}</span>
114
- </div>
115
- </div>
116
- </button>);
117
- })}
118
- </div>
119
-
120
- <input type="hidden" id={props.path} value={currentKey} readOnly/>
121
- </div>);
122
- }
123
- //# sourceMappingURL=RadiusField.jsx.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RadiusField.jsx","sourceRoot":"","sources":["../../src/fields/RadiusField.tsx"],"names":[],"mappings":"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"}
@@ -1,110 +0,0 @@
1
- 'use client';
2
- import { useField, useFormFields } from '@payloadcms/ui';
3
- import { useEffect, useMemo, useState } from 'react';
4
- import './ThemeColorPickerField.css';
5
- function resolveLocalizedValue(value, fallback) {
6
- if (typeof value === 'string') {
7
- return value;
8
- }
9
- if (typeof value === 'object' && value !== null) {
10
- const localized = value;
11
- const resolved = localized.en ?? localized.cs ?? localized[''];
12
- if (typeof resolved === 'string') {
13
- return resolved;
14
- }
15
- }
16
- return fallback;
17
- }
18
- const ThemeColorPickerField = ({ field, path }) => {
19
- const { value, setValue } = useField({ path });
20
- const [localValue, setLocalValue] = useState(value || '');
21
- const allFields = useFormFields(([fields]) => fields);
22
- const mode = path.includes('lightMode') ? 'lightMode' : 'darkMode';
23
- const modePrefix = `themeConfiguration.${mode}`;
24
- useEffect(() => {
25
- setLocalValue(value || '');
26
- }, [value]);
27
- const colorValues = useMemo(() => {
28
- if (!allFields) {
29
- return {};
30
- }
31
- const names = [
32
- 'background',
33
- 'foreground',
34
- 'card',
35
- 'cardForeground',
36
- 'popover',
37
- 'popoverForeground',
38
- 'primary',
39
- 'primaryForeground',
40
- 'secondary',
41
- 'secondaryForeground',
42
- 'muted',
43
- 'mutedForeground',
44
- 'accent',
45
- 'accentForeground',
46
- 'destructive',
47
- 'destructiveForeground',
48
- 'border',
49
- 'input',
50
- 'ring',
51
- ];
52
- return names.reduce((accumulator, name) => {
53
- const fieldState = allFields[`${modePrefix}.${name}`];
54
- const parsedValue = typeof fieldState?.value === 'string' ? fieldState.value : undefined;
55
- accumulator[name] = parsedValue ?? '';
56
- return accumulator;
57
- }, {});
58
- }, [allFields, modePrefix]);
59
- function handleChange(nextValue) {
60
- setLocalValue(nextValue);
61
- setValue(nextValue);
62
- }
63
- const fieldName = path.split('.').pop() || '';
64
- const label = resolveLocalizedValue(field.label, fieldName);
65
- const description = resolveLocalizedValue(field.admin?.description, '');
66
- return (<div className="theme-color-picker-field">
67
- <div className="field-header">
68
- <label className="field-label">{label}</label>
69
- {description && <div className="field-description">{description}</div>}
70
- </div>
71
-
72
- <div className="color-picker-container">
73
- <div className="color-input-wrapper">
74
- <input type="color" value={localValue || '#000000'} onChange={(event) => handleChange(event.target.value)} className="color-input"/>
75
- <input type="text" value={localValue || ''} onChange={(event) => handleChange(event.target.value)} placeholder="#000000" className="text-input" pattern="^#[0-9A-Fa-f]{6}$"/>
76
- </div>
77
-
78
- <div className="color-preview" style={{ backgroundColor: localValue || '#000000' }}>
79
- <span className="preview-label">{localValue || 'Not set'}</span>
80
- </div>
81
- </div>
82
-
83
- {(fieldName === 'primary' || fieldName === 'background') && (<div className="mini-preview" style={{
84
- backgroundColor: colorValues.background || '#ffffff',
85
- color: colorValues.foreground || '#000000',
86
- borderColor: colorValues.border || '#e2e8f0',
87
- }}>
88
- <div className="preview-card" style={{
89
- backgroundColor: colorValues.card || '#ffffff',
90
- color: colorValues.cardForeground || '#000000',
91
- borderColor: colorValues.border || '#e2e8f0',
92
- }}>
93
- <button className="preview-button" style={{
94
- backgroundColor: colorValues.primary || '#0070f3',
95
- color: colorValues.primaryForeground || '#ffffff',
96
- }}>
97
- Primary Button
98
- </button>
99
- <button className="preview-button secondary" style={{
100
- backgroundColor: colorValues.secondary || '#f1f5f9',
101
- color: colorValues.secondaryForeground || '#0f172a',
102
- }}>
103
- Secondary
104
- </button>
105
- </div>
106
- </div>)}
107
- </div>);
108
- };
109
- export default ThemeColorPickerField;
110
- //# sourceMappingURL=ThemeColorPickerField.jsx.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ThemeColorPickerField.jsx","sourceRoot":"","sources":["../../src/fields/ThemeColorPickerField.tsx"],"names":[],"mappings":"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"}
@@ -1,420 +0,0 @@
1
- 'use client';
2
- import { useField, useForm, useFormFields } from '@payloadcms/ui';
3
- import { useCallback, useEffect, useMemo, useRef } from 'react';
4
- import { borderRadiusPresets } from '@/providers/Theme/themeConfig';
5
- import { resolveTypographyPreview } from '../components/typographyPreviewUtils';
6
- import { defaultThemePresets } from '../index';
7
- import { darkModeDefaults, lightModeDefaults } from './colorModeFields';
8
- const FALLBACK_THEME = defaultThemePresets[0]?.name ?? 'cool';
9
- const themePresets = defaultThemePresets.reduce((acc, preset) => {
10
- acc[preset.name] = {
11
- label: preset.label,
12
- lightMode: { ...lightModeDefaults, ...(preset.lightMode ?? {}) },
13
- darkMode: { ...darkModeDefaults, ...(preset.darkMode ?? {}) },
14
- typography: preset.typography,
15
- borderRadius: preset.borderRadius,
16
- };
17
- return acc;
18
- }, {});
19
- const colorKeys = Object.keys(lightModeDefaults);
20
- function ModePreview({ icon, title, colors, typography, radius }) {
21
- const background = colors.background ?? '#ffffff';
22
- const foreground = colors.foreground ?? '#0a0a0a';
23
- const borderColor = colors.border ?? 'rgba(148, 163, 184, 0.35)';
24
- const cardBackground = colors.card ?? background;
25
- const cardForeground = colors.cardForeground ?? foreground;
26
- const primary = colors.primary ?? foreground;
27
- const primaryForeground = colors.primaryForeground ?? background;
28
- const secondary = colors.secondary ?? '#f4f4f5';
29
- const secondaryForeground = colors.secondaryForeground ?? foreground;
30
- const muted = colors.muted ?? secondary;
31
- const mutedForeground = colors.mutedForeground ?? secondaryForeground;
32
- const accent = colors.accent ?? secondary;
33
- const accentForeground = colors.accentForeground ?? secondaryForeground;
34
- const headingFont = typography.headingFont;
35
- const bodyFont = typography.bodyFont;
36
- const baseFontSize = typography.baseFontSize;
37
- const lineHeight = typography.lineHeight;
38
- return (<div style={{
39
- display: 'grid',
40
- gap: '16px',
41
- padding: '18px',
42
- borderRadius: '12px',
43
- backgroundColor: background,
44
- color: foreground,
45
- border: `1px solid ${borderColor}`,
46
- boxShadow: '0 8px 20px rgba(15, 23, 42, 0.08)',
47
- fontFamily: bodyFont,
48
- }}>
49
- <div style={{
50
- display: 'flex',
51
- alignItems: 'center',
52
- justifyContent: 'space-between',
53
- fontSize: '12px',
54
- fontWeight: 600,
55
- letterSpacing: '0.08em',
56
- textTransform: 'uppercase',
57
- opacity: 0.7,
58
- }}>
59
- <span>
60
- {icon} {title}
61
- </span>
62
- <span style={{ fontFamily: 'monospace', fontSize: '11px' }}>
63
- {background.toUpperCase()}
64
- </span>
65
- </div>
66
-
67
- <div style={{
68
- backgroundColor: cardBackground,
69
- color: cardForeground,
70
- borderRadius: radius.card,
71
- border: `1px solid ${borderColor}`,
72
- padding: '16px',
73
- display: 'flex',
74
- gap: '12px',
75
- flexWrap: 'wrap',
76
- }}>
77
- <button type="button" style={{
78
- padding: '10px 18px',
79
- borderRadius: radius.pill,
80
- border: 'none',
81
- cursor: 'pointer',
82
- fontSize: '12px',
83
- fontWeight: 600,
84
- letterSpacing: '0.02em',
85
- backgroundColor: primary,
86
- color: primaryForeground,
87
- boxShadow: '0 6px 14px rgba(15, 23, 42, 0.15)',
88
- }}>
89
- Primary Action
90
- </button>
91
- <button type="button" style={{
92
- padding: '10px 18px',
93
- borderRadius: radius.chip,
94
- border: '1px solid transparent',
95
- cursor: 'pointer',
96
- fontSize: '12px',
97
- fontWeight: 600,
98
- letterSpacing: '0.02em',
99
- backgroundColor: secondary,
100
- color: secondaryForeground,
101
- boxShadow: 'inset 0 0 0 1px rgba(15, 23, 42, 0.08)',
102
- }}>
103
- Secondary
104
- </button>
105
- </div>
106
-
107
- <div style={{
108
- display: 'grid',
109
- gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',
110
- gap: '10px',
111
- }}>
112
- <div style={{
113
- borderRadius: radius.chip,
114
- padding: '10px 12px',
115
- fontSize: '12px',
116
- fontWeight: 500,
117
- backgroundColor: muted,
118
- color: mutedForeground,
119
- }}>
120
- Muted Card
121
- </div>
122
- <div style={{
123
- borderRadius: radius.chip,
124
- padding: '10px 12px',
125
- fontSize: '12px',
126
- fontWeight: 500,
127
- backgroundColor: accent,
128
- color: accentForeground,
129
- }}>
130
- Accent Tag
131
- </div>
132
- </div>
133
-
134
- <div style={{
135
- display: 'grid',
136
- gap: '8px',
137
- borderRadius: '10px',
138
- border: `1px dashed ${borderColor}`,
139
- padding: '14px',
140
- backgroundColor: 'rgba(148, 163, 184, 0.08)',
141
- }}>
142
- <div style={{
143
- fontFamily: headingFont,
144
- fontSize: 'clamp(24px, 3vw, 32px)',
145
- fontWeight: 600,
146
- lineHeight: 1.2,
147
- }}>
148
- Nadpis / Heading preview
149
- </div>
150
- <p style={{
151
- margin: 0,
152
- fontFamily: bodyFont,
153
- fontSize: baseFontSize,
154
- lineHeight,
155
- color: foreground,
156
- opacity: 0.85,
157
- }}>
158
- Sphinx of black quartz, judge my vow. Příliš žluťoučký kůň úpěl ďábelské ódy.
159
- </p>
160
- <div style={{
161
- display: 'flex',
162
- flexWrap: 'wrap',
163
- gap: '10px',
164
- fontSize: '11px',
165
- color: 'rgba(15, 23, 42, 0.7)',
166
- }}>
167
- <span>Body: {typography.bodyLabel}</span>
168
- <span>Heading: {typography.headingLabel}</span>
169
- <span>Base size: {baseFontSize}</span>
170
- <span>Line height: {lineHeight}</span>
171
- </div>
172
- </div>
173
- </div>);
174
- }
175
- export default function ThemePreviewField(props) {
176
- const { field, path } = props;
177
- const { value: selectedTheme, setValue } = useField({ path });
178
- const { dispatchFields } = useForm();
179
- const formFields = useFormFields(([formState]) => formState);
180
- const hasAppliedInitialPresetRef = useRef(false);
181
- const applyPreset = useCallback((presetName) => {
182
- const preset = themePresets[presetName];
183
- if (!preset) {
184
- return;
185
- }
186
- colorKeys.forEach((key) => {
187
- const lightValue = preset.lightMode[key];
188
- const darkValue = preset.darkMode[key];
189
- if (lightValue) {
190
- dispatchFields({
191
- type: 'UPDATE',
192
- path: `themeConfiguration.lightMode.${key}`,
193
- value: lightValue,
194
- });
195
- }
196
- if (darkValue) {
197
- dispatchFields({
198
- type: 'UPDATE',
199
- path: `themeConfiguration.darkMode.${key}`,
200
- value: darkValue,
201
- });
202
- }
203
- });
204
- }, [dispatchFields]);
205
- const handleThemeChange = useCallback((event) => {
206
- const value = event.target.value;
207
- setValue(value);
208
- if (!value) {
209
- return;
210
- }
211
- hasAppliedInitialPresetRef.current = true;
212
- applyPreset(value);
213
- }, [applyPreset, setValue]);
214
- useEffect(() => {
215
- if (!selectedTheme) {
216
- return;
217
- }
218
- if (themePresets[selectedTheme]) {
219
- return;
220
- }
221
- hasAppliedInitialPresetRef.current = false;
222
- setValue(FALLBACK_THEME);
223
- }, [selectedTheme, setValue]);
224
- useEffect(() => {
225
- if (hasAppliedInitialPresetRef.current) {
226
- return;
227
- }
228
- if (!selectedTheme) {
229
- return;
230
- }
231
- if (!formFields) {
232
- return;
233
- }
234
- const preset = themePresets[selectedTheme];
235
- if (!preset) {
236
- hasAppliedInitialPresetRef.current = true;
237
- return;
238
- }
239
- const hasExistingValues = colorKeys.some((key) => {
240
- const lightField = formFields[`themeConfiguration.lightMode.${key}`];
241
- const darkField = formFields[`themeConfiguration.darkMode.${key}`];
242
- const lightValue = typeof lightField?.value === 'string' && lightField.value.trim().length > 0;
243
- const darkValue = typeof darkField?.value === 'string' && darkField.value.trim().length > 0;
244
- return lightValue || darkValue;
245
- });
246
- if (hasExistingValues) {
247
- hasAppliedInitialPresetRef.current = true;
248
- return;
249
- }
250
- applyPreset(selectedTheme);
251
- hasAppliedInitialPresetRef.current = true;
252
- }, [selectedTheme, formFields, applyPreset]);
253
- const lightModeColors = useMemo(() => {
254
- const presetLightMode = selectedTheme ? themePresets[selectedTheme]?.lightMode : undefined;
255
- return colorKeys.reduce((acc, key) => {
256
- const fieldState = formFields?.[`themeConfiguration.lightMode.${key}`];
257
- const rawValue = typeof fieldState?.value === 'string' && fieldState.value.trim().length > 0
258
- ? fieldState.value
259
- : undefined;
260
- acc[key] = rawValue ?? presetLightMode?.[key] ?? lightModeDefaults[key];
261
- return acc;
262
- }, {});
263
- }, [formFields, selectedTheme]);
264
- const darkModeColors = useMemo(() => {
265
- const presetDarkMode = selectedTheme ? themePresets[selectedTheme]?.darkMode : undefined;
266
- return colorKeys.reduce((acc, key) => {
267
- const fieldState = formFields?.[`themeConfiguration.darkMode.${key}`];
268
- const rawValue = typeof fieldState?.value === 'string' && fieldState.value.trim().length > 0
269
- ? fieldState.value
270
- : undefined;
271
- acc[key] = rawValue ?? presetDarkMode?.[key] ?? darkModeDefaults[key];
272
- return acc;
273
- }, {});
274
- }, [formFields, selectedTheme]);
275
- const activePreset = selectedTheme ? themePresets[selectedTheme] : undefined;
276
- const formTypographySelection = useMemo(() => {
277
- if (!formFields) {
278
- return null;
279
- }
280
- const getValue = (key) => formFields[`themeConfiguration.typography.${key}`]?.value;
281
- return {
282
- bodyFont: getValue('bodyFont') ?? undefined,
283
- headingFont: getValue('headingFont') ?? undefined,
284
- bodyFontCustom: getValue('bodyFontCustom') ?? undefined,
285
- headingFontCustom: getValue('headingFontCustom') ?? undefined,
286
- baseFontSize: getValue('baseFontSize') ?? undefined,
287
- lineHeight: getValue('lineHeight') ?? undefined,
288
- };
289
- }, [formFields]);
290
- const previewTypography = useMemo(() => {
291
- return resolveTypographyPreview(formTypographySelection, selectedTheme);
292
- }, [formTypographySelection, selectedTheme]);
293
- const borderRadiusValue = formFields?.['themeConfiguration.borderRadius']?.value;
294
- const presetRadius = activePreset?.borderRadius ?? 'medium';
295
- const resolvedBorderRadius = (typeof borderRadiusValue === 'string' && borderRadiusValue.length
296
- ? borderRadiusValue
297
- : presetRadius);
298
- const borderRadiusPreset = borderRadiusPresets[resolvedBorderRadius] ?? borderRadiusPresets.medium;
299
- const borderRadiusCSS = typeof borderRadiusPreset.css === 'string'
300
- ? { '--radius-default': borderRadiusPreset.css }
301
- : borderRadiusPreset.css;
302
- const previewRadius = {
303
- card: borderRadiusCSS['--radius-large'] ?? '1rem',
304
- chip: borderRadiusCSS['--radius-default'] ?? '0.75rem',
305
- pill: borderRadiusCSS['--radius-xl'] ?? borderRadiusCSS['--radius-large'] ?? '999px',
306
- };
307
- const fieldLabel = typeof field.label === 'string' ? field.label : field.label?.en || field.label?.cs || 'Theme';
308
- return (<div style={{ marginBottom: '24px' }}>
309
- <label style={{
310
- display: 'block',
311
- marginBottom: '10px',
312
- fontSize: '13px',
313
- fontWeight: 600,
314
- color: 'var(--theme-elevation-800)',
315
- }}>
316
- {fieldLabel}
317
- </label>
318
-
319
- <div style={{
320
- display: 'flex',
321
- flexWrap: 'wrap',
322
- gap: '24px',
323
- alignItems: 'flex-start',
324
- }}>
325
- <div style={{
326
- flex: '0 0 320px',
327
- minWidth: '260px',
328
- maxWidth: '420px',
329
- display: 'grid',
330
- gap: '12px',
331
- }}>
332
- <select value={selectedTheme || ''} onChange={handleThemeChange} style={{
333
- width: '100%',
334
- padding: '12px 14px',
335
- fontSize: '14px',
336
- borderRadius: '8px',
337
- border: '1px solid var(--theme-elevation-250)',
338
- backgroundColor: 'var(--theme-input-bg)',
339
- color: 'var(--theme-elevation-800)',
340
- cursor: 'pointer',
341
- }}>
342
- <option value="">Select a theme…</option>
343
- {Object.entries(themePresets).map(([key, preset]) => (<option key={key} value={key}>
344
- {preset.label}
345
- </option>))}
346
- </select>
347
-
348
- {activePreset && (<div style={{
349
- padding: '12px',
350
- borderRadius: '10px',
351
- border: '1px solid var(--theme-elevation-200)',
352
- backgroundColor: 'var(--theme-elevation-50)',
353
- display: 'grid',
354
- gap: '6px',
355
- fontSize: '12px',
356
- color: 'var(--theme-elevation-600)',
357
- }}>
358
- <div style={{ fontWeight: 600, color: 'var(--theme-elevation-800)' }}>
359
- {activePreset.label}
360
- </div>
361
- <div>Primary color: {activePreset.lightMode.primary}</div>
362
- <div>Accent color: {activePreset.lightMode.accent}</div>
363
- </div>)}
364
-
365
- {field.admin?.description && (<div style={{
366
- fontSize: '12px',
367
- color: 'var(--theme-elevation-600)',
368
- lineHeight: 1.5,
369
- }}>
370
- {typeof field.admin.description === 'string'
371
- ? field.admin.description
372
- : field.admin.description?.en || field.admin.description?.cs || ''}
373
- </div>)}
374
- </div>
375
-
376
- <div style={{
377
- flex: '1 1 420px',
378
- minWidth: '320px',
379
- position: 'sticky',
380
- top: '96px',
381
- alignSelf: 'flex-start',
382
- }}>
383
- <div style={{
384
- width: '100%',
385
- borderRadius: '16px',
386
- border: '1px solid var(--theme-elevation-200)',
387
- backgroundColor: 'var(--theme-elevation-25)',
388
- padding: '20px',
389
- display: 'grid',
390
- gap: '18px',
391
- maxHeight: 'calc(100vh - 140px)',
392
- overflowY: 'auto',
393
- }}>
394
- <div style={{
395
- display: 'flex',
396
- alignItems: 'center',
397
- justifyContent: 'space-between',
398
- fontWeight: 600,
399
- fontSize: '13px',
400
- color: 'var(--theme-elevation-800)',
401
- }}>
402
- <span>🎨 Live Preview</span>
403
- <span style={{ fontSize: '12px', color: 'var(--theme-elevation-600)' }}>
404
- {activePreset ? activePreset.label : 'Custom palette'}
405
- </span>
406
- </div>
407
-
408
- <div style={{
409
- display: 'grid',
410
- gap: '16px',
411
- }}>
412
- <ModePreview icon="☀️" title="Light Mode" colors={lightModeColors} typography={previewTypography} radius={previewRadius}/>
413
- <ModePreview icon="🌙" title="Dark Mode" colors={darkModeColors} typography={previewTypography} radius={previewRadius}/>
414
- </div>
415
- </div>
416
- </div>
417
- </div>
418
- </div>);
419
- }
420
- //# sourceMappingURL=ThemePreviewField.jsx.map