@kilivi/payloadcms-theme-management 0.2.4 → 0.2.6

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.
@@ -1,313 +1,65 @@
1
- /* Professional Color Picker Field Styles */.theme-color-picker-field {
2
-
3
- .theme-color-picker-field { margin-bottom: 1rem;
4
-
5
- margin-bottom: 1.5rem;}
6
-
1
+ .theme-color-picker-field {
2
+ margin-bottom: 1rem;
7
3
  }
8
4
 
9
5
  .theme-color-picker-field .field-header {
10
-
11
- .theme-color-picker-field .field-header { margin-bottom: 0.5rem;
12
-
13
- margin-bottom: 0.5rem;}
14
-
6
+ margin-bottom: 0.5rem;
15
7
  }
16
8
 
17
9
  .theme-color-picker-field .field-label {
18
-
19
- .theme-color-picker-field .field-label { display: block;
20
-
21
- display: block; font-weight: 500;
22
-
23
- font-weight: 600; font-size: 0.875rem;
24
-
25
- font-size: 0.875rem; color: var(--theme-text);
26
-
27
- color: var(--theme-text); margin-bottom: 0.25rem;
28
-
29
- margin-bottom: 0.25rem;}
30
-
10
+ display: block;
11
+ font-weight: 500;
12
+ font-size: 0.875rem;
13
+ color: var(--theme-text);
14
+ margin-bottom: 0.25rem;
31
15
  }
32
16
 
33
17
  .theme-color-picker-field .field-description {
18
+ font-size: 0.75rem;
19
+ color: var(--theme-elevation-400);
20
+ margin-top: 0.25rem;
21
+ }
34
22
 
35
- .theme-color-picker-field .field-description { font-size: 0.75rem;
36
-
37
- font-size: 0.75rem; color: var(--theme-elevation-400);
38
-
39
- color: var(--theme-elevation-400); margin-top: 0.25rem;
40
-
41
- margin-top: 0.25rem;}
42
-
43
- line-height: 1.4;
44
-
45
- }.theme-color-picker-field .color-picker-container {
46
-
23
+ .theme-color-picker-field .color-picker-container {
47
24
  display: flex;
48
-
49
- .theme-color-picker-field .color-picker-container { gap: 0.75rem;
50
-
51
- display: flex; align-items: center;
52
-
53
- gap: 0.75rem;}
54
-
25
+ gap: 0.75rem;
55
26
  align-items: center;
56
-
57
- position: relative;.theme-color-picker-field .color-input-wrapper {
58
-
59
- } display: flex;
60
-
61
- gap: 0.5rem;
62
-
63
- .theme-color-picker-field .color-input-wrapper { flex: 1;
64
-
65
- display: flex;}
66
-
67
- gap: 0.5rem;
68
-
69
- flex: 1;.theme-color-picker-field .color-input {
70
-
71
- align-items: center; width: 60px;
72
-
73
- position: relative; height: 38px;
74
-
75
- } border: 1px solid var(--theme-elevation-200);
76
-
77
- border-radius: 4px;
78
-
79
- /* Color Swatch Button */ cursor: pointer;
80
-
81
- .theme-color-picker-field .color-swatch { padding: 2px;
82
-
83
- width: 48px;}
84
-
85
- height: 48px;
86
-
87
- border: 2px solid var(--theme-elevation-200);.theme-color-picker-field .color-input:hover {
88
-
89
- border-radius: 8px; border-color: var(--theme-elevation-400);
90
-
91
- cursor: pointer;}
92
-
93
- padding: 0;
94
-
95
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);.theme-color-picker-field .color-input:focus {
96
-
97
- transition: all 0.2s; outline: 2px solid var(--theme-elevation-500);
98
-
99
- position: relative; outline-offset: 1px;
100
-
101
- }}
102
-
103
-
104
-
105
- .theme-color-picker-field .color-swatch::before {.theme-color-picker-field .text-input {
106
-
107
- content: ''; flex: 1;
108
-
109
- position: absolute; height: 38px;
110
-
111
- inset: 0; padding: 0 0.75rem;
112
-
113
- background: border: 1px solid var(--theme-elevation-200);
114
-
115
- linear-gradient(45deg, #ccc 25%, transparent 25%), border-radius: 4px;
116
-
117
- linear-gradient(-45deg, #ccc 25%, transparent 25%), font-family: monospace;
118
-
119
- linear-gradient(45deg, transparent 75%, #ccc 75%), font-size: 0.875rem;
120
-
121
- linear-gradient(-45deg, transparent 75%, #ccc 75%); background: var(--theme-elevation-0);
122
-
123
- background-size: 8px 8px; color: var(--theme-text);
124
-
125
- background-position: 0 0, 0 4px, 4px -4px, -4px 0px;}
126
-
127
- border-radius: 6px;
128
-
129
- z-index: -1;.theme-color-picker-field .text-input:hover {
130
-
131
- } border-color: var(--theme-elevation-400);
132
-
133
- }
134
-
135
- .theme-color-picker-field .color-swatch:hover {
136
-
137
- border-color: var(--theme-elevation-500);.theme-color-picker-field .text-input:focus {
138
-
139
- transform: scale(1.05); outline: 2px solid var(--theme-elevation-500);
140
-
141
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); outline-offset: 1px;
142
-
143
- } border-color: var(--theme-elevation-500);
144
-
145
- }
146
-
147
- .theme-color-picker-field .color-swatch:focus {
148
-
149
- outline: 2px solid var(--theme-elevation-700);.theme-color-picker-field .text-input::placeholder {
150
-
151
- outline-offset: 2px; color: var(--theme-elevation-400);
152
-
153
- }}
154
-
155
-
156
-
157
- /* Professional Color Picker Popover */.theme-color-picker-field .text-input:invalid {
158
-
159
- .theme-color-picker-field .color-picker-popover { border-color: #ef4444;
160
-
161
- position: absolute;}
162
-
163
- top: 100%;
164
-
165
- left: 0;.theme-color-picker-field .color-preview {
166
-
167
- margin-top: 8px; width: 120px;
168
-
169
- z-index: 1000; height: 38px;
170
-
171
- background: var(--theme-elevation-0); border-radius: 4px;
172
-
173
- border: 1px solid var(--theme-elevation-200); border: 1px solid var(--theme-elevation-200);
174
-
175
- border-radius: 12px; display: flex;
176
-
177
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); align-items: center;
178
-
179
- padding: 16px; justify-content: center;
180
-
181
- min-width: 280px; position: relative;
182
-
183
- } overflow: hidden;
184
-
185
- }
186
-
187
- /* react-colorful styles override */
188
-
189
- .theme-color-picker-field .react-colorful {.theme-color-picker-field .color-preview .preview-label {
190
-
191
- width: 100%; font-size: 0.75rem;
192
-
193
- height: 200px; font-family: monospace;
194
-
195
- border-radius: 8px; padding: 0.25rem 0.5rem;
196
-
197
- } background: rgba(255, 255, 255, 0.9);
198
-
199
- border-radius: 2px;
200
-
201
- .theme-color-picker-field .react-colorful__saturation { backdrop-filter: blur(4px);
202
-
203
- border-radius: 8px 8px 0 0; color: #000;
204
-
205
- } font-weight: 500;
206
-
207
27
  }
208
28
 
209
- .theme-color-picker-field .react-colorful__hue {
210
-
211
- height: 16px;.theme-color-picker-field .mini-preview {
212
-
213
- border-radius: 0 0 8px 8px; margin-top: 1rem;
214
-
215
- } padding: 1rem;
216
-
217
- border-radius: 6px;
218
-
219
- .theme-color-picker-field .react-colorful__pointer { border: 1px solid;
220
-
221
- width: 20px;}
222
-
223
- height: 20px;
224
-
225
- border: 3px solid #fff;.theme-color-picker-field .mini-preview .preview-card {
226
-
227
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); padding: 1rem;
228
-
229
- } border-radius: 4px;
230
-
231
- border: 1px solid;
232
-
233
- .theme-color-picker-field .picker-footer { display: flex;
234
-
235
- display: flex; gap: 0.5rem;
236
-
237
- gap: 8px; flex-wrap: wrap;
238
-
239
- margin-top: 12px;}
240
-
241
- align-items: center;
242
-
243
- }.theme-color-picker-field .mini-preview .preview-button {
244
-
245
- padding: 0.5rem 1rem;
246
-
247
- .theme-color-picker-field .hex-input { border-radius: 4px;
248
-
249
- flex: 1; border: none;
250
-
251
- height: 36px; font-size: 0.875rem;
252
-
253
- padding: 0 12px; font-weight: 500;
254
-
255
- border: 1px solid var(--theme-elevation-200); cursor: pointer;
256
-
257
- border-radius: 6px; transition: opacity 0.2s;
258
-
259
- font-family: monospace;}
260
-
261
- font-size: 0.875rem;
262
-
263
- background: var(--theme-elevation-50);.theme-color-picker-field .mini-preview .preview-button:hover {
264
-
265
- color: var(--theme-text); opacity: 0.9;
266
-
267
- transition: all 0.2s;}
268
-
29
+ .theme-color-picker-field .color-input-wrapper {
30
+ display: flex;
31
+ gap: 0.5rem;
32
+ flex: 1;
269
33
  }
270
34
 
271
- .theme-color-picker-field .mini-preview .preview-button.secondary {
272
-
273
- .theme-color-picker-field .hex-input:focus { border: 1px solid currentColor;
274
-
275
- outline: none;}
276
-
277
- border-color: var(--theme-elevation-600);
278
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
35
+ .theme-color-picker-field .color-input {
36
+ width: 60px;
37
+ height: 38px;
38
+ border: 1px solid var(--theme-elevation-200);
39
+ border-radius: 4px;
40
+ cursor: pointer;
41
+ padding: 2px;
279
42
  }
280
43
 
281
- .theme-color-picker-field .close-button {
282
- height: 36px;
283
- padding: 0 16px;
284
- background: var(--theme-elevation-700);
285
- color: white;
286
- border: none;
287
- border-radius: 6px;
288
- font-weight: 600;
289
- font-size: 0.875rem;
290
- cursor: pointer;
291
- transition: all 0.2s;
44
+ .theme-color-picker-field .color-input:hover {
45
+ border-color: var(--theme-elevation-400);
292
46
  }
293
47
 
294
- .theme-color-picker-field .close-button:hover {
295
- background: var(--theme-elevation-800);
296
- transform: translateY(-1px);
48
+ .theme-color-picker-field .color-input:focus {
49
+ outline: 2px solid var(--theme-elevation-500);
50
+ outline-offset: 1px;
297
51
  }
298
52
 
299
- /* Text Input */
300
53
  .theme-color-picker-field .text-input {
301
54
  flex: 1;
302
- height: 48px;
303
- padding: 0 1rem;
304
- border: 2px solid var(--theme-elevation-200);
305
- border-radius: 8px;
306
- font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
307
- font-size: 0.9rem;
55
+ height: 38px;
56
+ padding: 0 0.75rem;
57
+ border: 1px solid var(--theme-elevation-200);
58
+ border-radius: 4px;
59
+ font-family: monospace;
60
+ font-size: 0.875rem;
308
61
  background: var(--theme-elevation-0);
309
62
  color: var(--theme-text);
310
- transition: all 0.2s;
311
63
  }
312
64
 
313
65
  .theme-color-picker-field .text-input:hover {
@@ -315,109 +67,72 @@
315
67
  }
316
68
 
317
69
  .theme-color-picker-field .text-input:focus {
318
- outline: none;
319
- border-color: var(--theme-elevation-600);
320
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
70
+ outline: 2px solid var(--theme-elevation-500);
71
+ outline-offset: 1px;
72
+ border-color: var(--theme-elevation-500);
321
73
  }
322
74
 
323
75
  .theme-color-picker-field .text-input::placeholder {
324
76
  color: var(--theme-elevation-400);
325
77
  }
326
78
 
327
- /* Color Preview */
79
+ .theme-color-picker-field .text-input:invalid {
80
+ border-color: #ef4444;
81
+ }
82
+
328
83
  .theme-color-picker-field .color-preview {
329
- width: 140px;
330
- height: 48px;
331
- border-radius: 8px;
332
- border: 2px solid var(--theme-elevation-200);
84
+ width: 120px;
85
+ height: 38px;
86
+ border-radius: 4px;
87
+ border: 1px solid var(--theme-elevation-200);
333
88
  display: flex;
334
89
  align-items: center;
335
90
  justify-content: center;
336
91
  position: relative;
337
92
  overflow: hidden;
338
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
339
- }
340
-
341
- .theme-color-picker-field .color-preview::before {
342
- content: '';
343
- position: absolute;
344
- inset: 0;
345
- background:
346
- linear-gradient(45deg, #eee 25%, transparent 25%),
347
- linear-gradient(-45deg, #eee 25%, transparent 25%),
348
- linear-gradient(45deg, transparent 75%, #eee 75%),
349
- linear-gradient(-45deg, transparent 75%, #eee 75%);
350
- background-size: 10px 10px;
351
- background-position: 0 0, 0 5px, 5px -5px, -5px 0px;
352
- z-index: 0;
353
93
  }
354
94
 
355
95
  .theme-color-picker-field .color-preview .preview-label {
356
96
  font-size: 0.75rem;
357
97
  font-family: monospace;
358
- font-weight: 600;
359
- padding: 0.375rem 0.75rem;
360
- background: rgba(255, 255, 255, 0.95);
361
- border-radius: 4px;
362
- z-index: 1;
363
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
364
- max-width: 120px;
365
- overflow: hidden;
366
- text-overflow: ellipsis;
367
- white-space: nowrap;
98
+ padding: 0.25rem 0.5rem;
99
+ background: rgba(255, 255, 255, 0.9);
100
+ border-radius: 2px;
101
+ backdrop-filter: blur(4px);
102
+ color: #000;
103
+ font-weight: 500;
368
104
  }
369
105
 
370
- /* Mini Preview */
371
106
  .theme-color-picker-field .mini-preview {
372
- width: 100%;
373
107
  margin-top: 1rem;
374
108
  padding: 1rem;
109
+ border-radius: 6px;
375
110
  border: 1px solid;
376
- border-radius: 8px;
377
- background-clip: padding-box;
378
111
  }
379
112
 
380
- .theme-color-picker-field .preview-card {
113
+ .theme-color-picker-field .mini-preview .preview-card {
381
114
  padding: 1rem;
115
+ border-radius: 4px;
382
116
  border: 1px solid;
383
- border-radius: 6px;
384
117
  display: flex;
385
- gap: 0.75rem;
386
- align-items: center;
118
+ gap: 0.5rem;
119
+ flex-wrap: wrap;
387
120
  }
388
121
 
389
- .theme-color-picker-field .preview-button {
122
+ .theme-color-picker-field .mini-preview .preview-button {
390
123
  padding: 0.5rem 1rem;
124
+ border-radius: 4px;
391
125
  border: none;
392
- border-radius: 6px;
393
- font-weight: 600;
394
126
  font-size: 0.875rem;
127
+ font-weight: 500;
395
128
  cursor: pointer;
396
- transition: all 0.2s;
129
+ transition: opacity 0.2s;
397
130
  }
398
131
 
399
- .theme-color-picker-field .preview-button:hover {
132
+ .theme-color-picker-field .mini-preview .preview-button:hover {
400
133
  opacity: 0.9;
401
- transform: translateY(-1px);
402
134
  }
403
135
 
404
- .theme-color-picker-field .preview-button.secondary {
405
- opacity: 0.95;
406
- }
407
-
408
- /* Dark mode adjustments */
409
- @media (prefers-color-scheme: dark) {
410
- .theme-color-picker-field .color-preview::before,
411
- .theme-color-picker-field .color-swatch::before {
412
- background:
413
- linear-gradient(45deg, #333 25%, transparent 25%),
414
- linear-gradient(-45deg, #333 25%, transparent 25%),
415
- linear-gradient(45deg, transparent 75%, #333 75%),
416
- linear-gradient(-45deg, transparent 75%, #333 75%);
417
- }
418
-
419
- .theme-color-picker-field .color-preview .preview-label {
420
- background: rgba(0, 0, 0, 0.8);
421
- color: white;
422
- }
136
+ .theme-color-picker-field .mini-preview .preview-button.secondary {
137
+ border: 1px solid currentColor;
423
138
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeLivePreview.d.ts","sourceRoot":"","sources":["../../src/fields/ThemeLivePreview.tsx"],"names":[],"mappings":"AAUA,OAAO,wBAAwB,CAAA;AAE/B,eAAO,MAAM,gBAAgB,mCA2K5B,CAAA;AAED,eAAe,gBAAgB,CAAA"}
1
+ {"version":3,"file":"ThemeLivePreview.d.ts","sourceRoot":"","sources":["../../src/fields/ThemeLivePreview.tsx"],"names":[],"mappings":"AAUA,OAAO,wBAAwB,CAAA;AAE/B,eAAO,MAAM,gBAAgB,mCA+J5B,CAAA;AAED,eAAe,gBAAgB,CAAA"}
@@ -5,7 +5,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  * Real-time preview of theme configuration
6
6
  * Inspired by Payload CMS 3 Live Preview
7
7
  */ import { useFormFields } from '@payloadcms/ui';
8
- import { useEffect, useState } from 'react';
8
+ import { useState } from 'react';
9
9
  import './ThemeLivePreview.css';
10
10
  export const ThemeLivePreview = ()=>{
11
11
  const allFields = useFormFields(([fields])=>fields);
@@ -16,18 +16,6 @@ export const ThemeLivePreview = ()=>{
16
16
  const lightMode = themeConfig?.extendedLightMode || themeConfig?.lightMode;
17
17
  const darkMode = themeConfig?.extendedDarkMode || themeConfig?.darkMode;
18
18
  const activeMode = previewMode === 'light' ? lightMode : darkMode;
19
- // Apply theme colors to preview
20
- useEffect(()=>{
21
- if (!activeMode) return;
22
- const root = document.documentElement;
23
- Object.entries(activeMode).forEach(([key, value])=>{
24
- if (typeof value === 'string') {
25
- root.style.setProperty(`--preview-${key}`, value);
26
- }
27
- });
28
- }, [
29
- activeMode
30
- ]);
31
19
  if (!themeConfig) {
32
20
  return /*#__PURE__*/ _jsx("div", {
33
21
  className: "theme-live-preview-empty",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/fields/ThemeLivePreview.tsx"],"sourcesContent":["'use client'\n\n/**\n * Theme Live Preview Component\n * Real-time preview of theme configuration\n * Inspired by Payload CMS 3 Live Preview\n */\n\nimport { useFormFields } from '@payloadcms/ui'\nimport { useEffect, useState } from 'react'\nimport './ThemeLivePreview.css'\n\nexport const ThemeLivePreview = () => {\n const allFields = useFormFields(([fields]) => fields)\n const [previewMode, setPreviewMode] = useState<'light' | 'dark'>('light')\n\n const themeConfig = allFields?.themeConfiguration?.value as Record<string, unknown> | undefined\n\n // Extract colors from theme configuration\n // Support both basic (lightMode/darkMode) and extended (extendedLightMode/extendedDarkMode)\n const lightMode = (themeConfig?.extendedLightMode || themeConfig?.lightMode) as\n | Record<string, string>\n | undefined\n const darkMode = (themeConfig?.extendedDarkMode || themeConfig?.darkMode) as\n | Record<string, string>\n | undefined\n const activeMode = previewMode === 'light' ? lightMode : darkMode\n\n // Apply theme colors to preview\n useEffect(() => {\n if (!activeMode) return\n\n const root = document.documentElement\n Object.entries(activeMode).forEach(([key, value]) => {\n if (typeof value === 'string') {\n root.style.setProperty(`--preview-${key}`, value)\n }\n })\n }, [activeMode])\n\n if (!themeConfig) {\n return (\n <div className=\"theme-live-preview-empty\">\n <p>Configure your theme to see live preview</p>\n </div>\n )\n }\n\n return (\n <div className=\"theme-live-preview-container\" data-mode={previewMode}>\n {/* Mode Toggle */}\n <div className=\"preview-header\">\n <h3>Live Theme Preview</h3>\n <div className=\"mode-toggle\">\n <button\n type=\"button\"\n className={previewMode === 'light' ? 'active' : ''}\n onClick={() => setPreviewMode('light')}\n >\n ☀️ Light\n </button>\n <button\n type=\"button\"\n className={previewMode === 'dark' ? 'active' : ''}\n onClick={() => setPreviewMode('dark')}\n >\n 🌙 Dark\n </button>\n </div>\n </div>\n\n {/* Preview Content */}\n <div\n className=\"preview-content\"\n style={{\n backgroundColor: activeMode?.background || '#ffffff',\n color: activeMode?.foreground || '#000000',\n }}\n >\n {/* Header Section */}\n <div className=\"preview-section\">\n <h1 style={{ color: activeMode?.foreground }}>Welcome to Your Site</h1>\n <p style={{ color: activeMode?.mutedForeground }}>\n This is a live preview of your theme configuration\n </p>\n </div>\n\n {/* Card Section */}\n <div className=\"preview-cards\">\n <div\n className=\"preview-card\"\n style={{\n backgroundColor: activeMode?.card || '#ffffff',\n color: activeMode?.cardForeground || '#000000',\n borderColor: activeMode?.border || '#e2e8f0',\n }}\n >\n <h3>Featured Content</h3>\n <p style={{ color: activeMode?.mutedForeground }}>\n Card component with theme colors\n </p>\n <button\n className=\"preview-btn-primary\"\n style={{\n backgroundColor: activeMode?.primary || '#0070f3',\n color: activeMode?.primaryForeground || '#ffffff',\n }}\n >\n Primary Action\n </button>\n </div>\n\n <div\n className=\"preview-card\"\n style={{\n backgroundColor: activeMode?.card || '#ffffff',\n color: activeMode?.cardForeground || '#000000',\n borderColor: activeMode?.border || '#e2e8f0',\n }}\n >\n <h3>Secondary Card</h3>\n <p style={{ color: activeMode?.mutedForeground }}>\n Another card to showcase your theme\n </p>\n <button\n className=\"preview-btn-secondary\"\n style={{\n backgroundColor: activeMode?.secondary || '#f1f5f9',\n color: activeMode?.secondaryForeground || '#0f172a',\n }}\n >\n Secondary\n </button>\n </div>\n </div>\n\n {/* UI Elements */}\n <div className=\"preview-ui-elements\">\n <input\n type=\"text\"\n placeholder=\"Input field\"\n className=\"preview-input\"\n style={{\n backgroundColor: activeMode?.background,\n color: activeMode?.foreground,\n borderColor: activeMode?.input || activeMode?.border,\n }}\n />\n\n <div\n className=\"preview-badge\"\n style={{\n backgroundColor: activeMode?.accent || '#f1f5f9',\n color: activeMode?.accentForeground || '#0f172a',\n }}\n >\n Accent Badge\n </div>\n\n <button\n className=\"preview-btn-destructive\"\n style={{\n backgroundColor: activeMode?.destructive || '#ef4444',\n color: activeMode?.destructiveForeground || '#ffffff',\n }}\n >\n Destructive\n </button>\n </div>\n\n {/* Muted Section */}\n <div\n className=\"preview-muted\"\n style={{\n backgroundColor: activeMode?.muted || '#f1f5f9',\n color: activeMode?.mutedForeground || '#64748b',\n }}\n >\n <p>Muted background section for less prominent content</p>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ThemeLivePreview\n"],"names":["useFormFields","useEffect","useState","ThemeLivePreview","allFields","fields","previewMode","setPreviewMode","themeConfig","themeConfiguration","value","lightMode","extendedLightMode","darkMode","extendedDarkMode","activeMode","root","document","documentElement","Object","entries","forEach","key","style","setProperty","div","className","p","data-mode","h3","button","type","onClick","backgroundColor","background","color","foreground","h1","mutedForeground","card","cardForeground","borderColor","border","primary","primaryForeground","secondary","secondaryForeground","input","placeholder","accent","accentForeground","destructive","destructiveForeground","muted"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/fields/ThemeLivePreview.tsx"],"sourcesContent":["'use client'\n\n/**\n * Theme Live Preview Component\n * Real-time preview of theme configuration\n * Inspired by Payload CMS 3 Live Preview\n */\n\nimport { useFormFields } from '@payloadcms/ui'\nimport { useState } from 'react'\nimport './ThemeLivePreview.css'\n\nexport const ThemeLivePreview = () => {\n const allFields = useFormFields(([fields]) => fields)\n const [previewMode, setPreviewMode] = useState<'light' | 'dark'>('light')\n\n const themeConfig = allFields?.themeConfiguration?.value as Record<string, unknown> | undefined\n\n // Extract colors from theme configuration\n // Support both basic (lightMode/darkMode) and extended (extendedLightMode/extendedDarkMode)\n const lightMode = (themeConfig?.extendedLightMode || themeConfig?.lightMode) as\n | Record<string, string>\n | undefined\n const darkMode = (themeConfig?.extendedDarkMode || themeConfig?.darkMode) as\n | Record<string, string>\n | undefined\n const activeMode = previewMode === 'light' ? lightMode : darkMode\n\n if (!themeConfig) {\n return (\n <div className=\"theme-live-preview-empty\">\n <p>Configure your theme to see live preview</p>\n </div>\n )\n }\n\n return (\n <div className=\"theme-live-preview-container\" data-mode={previewMode}>\n {/* Mode Toggle */}\n <div className=\"preview-header\">\n <h3>Live Theme Preview</h3>\n <div className=\"mode-toggle\">\n <button\n type=\"button\"\n className={previewMode === 'light' ? 'active' : ''}\n onClick={() => setPreviewMode('light')}\n >\n ☀️ Light\n </button>\n <button\n type=\"button\"\n className={previewMode === 'dark' ? 'active' : ''}\n onClick={() => setPreviewMode('dark')}\n >\n 🌙 Dark\n </button>\n </div>\n </div>\n\n {/* Preview Content */}\n <div\n className=\"preview-content\"\n style={{\n backgroundColor: activeMode?.background || '#ffffff',\n color: activeMode?.foreground || '#000000',\n }}\n >\n {/* Header Section */}\n <div className=\"preview-section\">\n <h1 style={{ color: activeMode?.foreground }}>Welcome to Your Site</h1>\n <p style={{ color: activeMode?.mutedForeground }}>\n This is a live preview of your theme configuration\n </p>\n </div>\n\n {/* Card Section */}\n <div className=\"preview-cards\">\n <div\n className=\"preview-card\"\n style={{\n backgroundColor: activeMode?.card || '#ffffff',\n color: activeMode?.cardForeground || '#000000',\n borderColor: activeMode?.border || '#e2e8f0',\n }}\n >\n <h3>Featured Content</h3>\n <p style={{ color: activeMode?.mutedForeground }}>\n Card component with theme colors\n </p>\n <button\n className=\"preview-btn-primary\"\n style={{\n backgroundColor: activeMode?.primary || '#0070f3',\n color: activeMode?.primaryForeground || '#ffffff',\n }}\n >\n Primary Action\n </button>\n </div>\n\n <div\n className=\"preview-card\"\n style={{\n backgroundColor: activeMode?.card || '#ffffff',\n color: activeMode?.cardForeground || '#000000',\n borderColor: activeMode?.border || '#e2e8f0',\n }}\n >\n <h3>Secondary Card</h3>\n <p style={{ color: activeMode?.mutedForeground }}>\n Another card to showcase your theme\n </p>\n <button\n className=\"preview-btn-secondary\"\n style={{\n backgroundColor: activeMode?.secondary || '#f1f5f9',\n color: activeMode?.secondaryForeground || '#0f172a',\n }}\n >\n Secondary\n </button>\n </div>\n </div>\n\n {/* UI Elements */}\n <div className=\"preview-ui-elements\">\n <input\n type=\"text\"\n placeholder=\"Input field\"\n className=\"preview-input\"\n style={{\n backgroundColor: activeMode?.background,\n color: activeMode?.foreground,\n borderColor: activeMode?.input || activeMode?.border,\n }}\n />\n\n <div\n className=\"preview-badge\"\n style={{\n backgroundColor: activeMode?.accent || '#f1f5f9',\n color: activeMode?.accentForeground || '#0f172a',\n }}\n >\n Accent Badge\n </div>\n\n <button\n className=\"preview-btn-destructive\"\n style={{\n backgroundColor: activeMode?.destructive || '#ef4444',\n color: activeMode?.destructiveForeground || '#ffffff',\n }}\n >\n Destructive\n </button>\n </div>\n\n {/* Muted Section */}\n <div\n className=\"preview-muted\"\n style={{\n backgroundColor: activeMode?.muted || '#f1f5f9',\n color: activeMode?.mutedForeground || '#64748b',\n }}\n >\n <p>Muted background section for less prominent content</p>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ThemeLivePreview\n\n\n"],"names":["useFormFields","useState","ThemeLivePreview","allFields","fields","previewMode","setPreviewMode","themeConfig","themeConfiguration","value","lightMode","extendedLightMode","darkMode","extendedDarkMode","activeMode","div","className","p","data-mode","h3","button","type","onClick","style","backgroundColor","background","color","foreground","h1","mutedForeground","card","cardForeground","borderColor","border","primary","primaryForeground","secondary","secondaryForeground","input","placeholder","accent","accentForeground","destructive","destructiveForeground","muted"],"mappings":"AAAA;;AAEA;;;;CAIC,GAED,SAASA,aAAa,QAAQ,iBAAgB;AAC9C,SAASC,QAAQ,QAAQ,QAAO;AAChC,OAAO,yBAAwB;AAE/B,OAAO,MAAMC,mBAAmB;IAC9B,MAAMC,YAAYH,cAAc,CAAC,CAACI,OAAO,GAAKA;IAC9C,MAAM,CAACC,aAAaC,eAAe,GAAGL,SAA2B;IAEjE,MAAMM,cAAcJ,WAAWK,oBAAoBC;IAEnD,0CAA0C;IAC1C,4FAA4F;IAC5F,MAAMC,YAAaH,aAAaI,qBAAqBJ,aAAaG;IAGlE,MAAME,WAAYL,aAAaM,oBAAoBN,aAAaK;IAGhE,MAAME,aAAaT,gBAAgB,UAAUK,YAAYE;IAEzD,IAAI,CAACL,aAAa;QAChB,qBACE,KAACQ;YAAIC,WAAU;sBACb,cAAA,KAACC;0BAAE;;;IAGT;IAEA,qBACE,MAACF;QAAIC,WAAU;QAA+BE,aAAWb;;0BAEvD,MAACU;gBAAIC,WAAU;;kCACb,KAACG;kCAAG;;kCACJ,MAACJ;wBAAIC,WAAU;;0CACb,KAACI;gCACCC,MAAK;gCACLL,WAAWX,gBAAgB,UAAU,WAAW;gCAChDiB,SAAS,IAAMhB,eAAe;0CAC/B;;0CAGD,KAACc;gCACCC,MAAK;gCACLL,WAAWX,gBAAgB,SAAS,WAAW;gCAC/CiB,SAAS,IAAMhB,eAAe;0CAC/B;;;;;;0BAOL,MAACS;gBACCC,WAAU;gBACVO,OAAO;oBACLC,iBAAiBV,YAAYW,cAAc;oBAC3CC,OAAOZ,YAAYa,cAAc;gBACnC;;kCAGA,MAACZ;wBAAIC,WAAU;;0CACb,KAACY;gCAAGL,OAAO;oCAAEG,OAAOZ,YAAYa;gCAAW;0CAAG;;0CAC9C,KAACV;gCAAEM,OAAO;oCAAEG,OAAOZ,YAAYe;gCAAgB;0CAAG;;;;kCAMpD,MAACd;wBAAIC,WAAU;;0CACb,MAACD;gCACCC,WAAU;gCACVO,OAAO;oCACLC,iBAAiBV,YAAYgB,QAAQ;oCACrCJ,OAAOZ,YAAYiB,kBAAkB;oCACrCC,aAAalB,YAAYmB,UAAU;gCACrC;;kDAEA,KAACd;kDAAG;;kDACJ,KAACF;wCAAEM,OAAO;4CAAEG,OAAOZ,YAAYe;wCAAgB;kDAAG;;kDAGlD,KAACT;wCACCJ,WAAU;wCACVO,OAAO;4CACLC,iBAAiBV,YAAYoB,WAAW;4CACxCR,OAAOZ,YAAYqB,qBAAqB;wCAC1C;kDACD;;;;0CAKH,MAACpB;gCACCC,WAAU;gCACVO,OAAO;oCACLC,iBAAiBV,YAAYgB,QAAQ;oCACrCJ,OAAOZ,YAAYiB,kBAAkB;oCACrCC,aAAalB,YAAYmB,UAAU;gCACrC;;kDAEA,KAACd;kDAAG;;kDACJ,KAACF;wCAAEM,OAAO;4CAAEG,OAAOZ,YAAYe;wCAAgB;kDAAG;;kDAGlD,KAACT;wCACCJ,WAAU;wCACVO,OAAO;4CACLC,iBAAiBV,YAAYsB,aAAa;4CAC1CV,OAAOZ,YAAYuB,uBAAuB;wCAC5C;kDACD;;;;;;kCAOL,MAACtB;wBAAIC,WAAU;;0CACb,KAACsB;gCACCjB,MAAK;gCACLkB,aAAY;gCACZvB,WAAU;gCACVO,OAAO;oCACLC,iBAAiBV,YAAYW;oCAC7BC,OAAOZ,YAAYa;oCACnBK,aAAalB,YAAYwB,SAASxB,YAAYmB;gCAChD;;0CAGF,KAAClB;gCACCC,WAAU;gCACVO,OAAO;oCACLC,iBAAiBV,YAAY0B,UAAU;oCACvCd,OAAOZ,YAAY2B,oBAAoB;gCACzC;0CACD;;0CAID,KAACrB;gCACCJ,WAAU;gCACVO,OAAO;oCACLC,iBAAiBV,YAAY4B,eAAe;oCAC5ChB,OAAOZ,YAAY6B,yBAAyB;gCAC9C;0CACD;;;;kCAMH,KAAC5B;wBACCC,WAAU;wBACVO,OAAO;4BACLC,iBAAiBV,YAAY8B,SAAS;4BACtClB,OAAOZ,YAAYe,mBAAmB;wBACxC;kCAEA,cAAA,KAACZ;sCAAE;;;;;;;AAKb,EAAC;AAED,eAAef,iBAAgB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kilivi/payloadcms-theme-management",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Theme configuration plugin for Payload CMS v3",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -60,20 +60,33 @@
60
60
  "devDependencies": {
61
61
  "@payloadcms/db-mongodb": "^3.0.0",
62
62
  "@payloadcms/richtext-lexical": "^3.0.0",
63
+ "@payloadcms/richtext-slate": "^3.59.1",
64
+ "@playwright/test": "^1.56.0",
63
65
  "@swc/cli": "^0.1.65",
64
66
  "@swc/core": "^1.6.3",
65
67
  "@testing-library/jest-dom": "^6.9.1",
66
68
  "@testing-library/react": "^16.3.0",
67
69
  "@types/jest": "^30.0.0",
70
+ "@types/node": "^22.0.0",
68
71
  "@types/react": "^18.3.12",
72
+ "@vitejs/plugin-react": "^5.0.4",
73
+ "@vitest/browser": "^3.2.4",
74
+ "@vitest/ui": "^3.2.4",
69
75
  "copyfiles": "^2.4.1",
70
76
  "jest": "^30.2.0",
77
+ "mongodb-memory-server": "^10.2.3",
71
78
  "payload": "^3.58.0",
79
+ "playwright": "^1.56.0",
80
+ "postcss": "^8.5.0",
72
81
  "react": "^19.0.0",
73
82
  "react-dom": "^19.0.0",
74
83
  "rimraf": "^5.0.5",
75
84
  "ts-jest": "^29.4.4",
76
- "typescript": "^5.5.3"
85
+ "tsx": "^4.20.6",
86
+ "typescript": "^5.5.3",
87
+ "vite-plugin-commonjs": "^0.10.4",
88
+ "vite-plugin-static-copy": "^3.1.3",
89
+ "vitest": "^3.2.4"
77
90
  },
78
91
  "publishConfig": {
79
92
  "access": "public"
@@ -89,9 +102,11 @@
89
102
  "clean": "rimraf dist tsconfig.tsbuildinfo",
90
103
  "copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
91
104
  "validate": "node validate-fields.js",
92
- "test": "jest",
93
- "test:watch": "jest --watch",
94
- "test:coverage": "jest --coverage",
105
+ "test": "tsx node_modules/vitest/vitest.mjs run --config dev/vitest.simple.config.ts",
106
+ "test:watch": "vitest",
107
+ "test:ui": "vitest --ui",
108
+ "test:coverage": "vitest run --coverage",
109
+ "test:e2e": "playwright test",
95
110
  "lint": "eslint src",
96
111
  "lint:fix": "eslint --fix --ext .ts,.tsx src"
97
112
  }