@kilivi/payloadcms-theme-management 0.2.6 → 0.2.7
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/LICENSE.MD +9 -0
- package/README.md +9 -9
- package/dist/components/ServerThemeInjector.d.ts +1 -1
- package/dist/components/ServerThemeInjector.d.ts.map +1 -1
- package/dist/components/ServerThemeInjector.js +1 -1
- package/dist/components/ServerThemeInjector.js.map +1 -1
- package/dist/fields/ThemePreviewField.d.ts.map +1 -1
- package/dist/fields/ThemePreviewField.js +136 -24
- package/dist/fields/ThemePreviewField.js.map +1 -1
- package/package.json +9 -2
package/LICENSE.MD
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 [Kilián Vít]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -304,7 +304,7 @@ themeManagementPlugin({
|
|
|
304
304
|
|
|
305
305
|
## Migrating from Older Versions
|
|
306
306
|
|
|
307
|
-
See [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) for detailed migration instructions.
|
|
307
|
+
See [MIGRATION_GUIDE.md](./docs/MIGRATION_GUIDE.md) for detailed migration instructions.
|
|
308
308
|
|
|
309
309
|
### Key Changes in v0.1.9+
|
|
310
310
|
|
|
@@ -320,7 +320,7 @@ See [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) for detailed migration instructio
|
|
|
320
320
|
|
|
321
321
|
## Testing
|
|
322
322
|
|
|
323
|
-
See [TEST_APP_GUIDE.md](./TEST_APP_GUIDE.md) for instructions on creating a test application.
|
|
323
|
+
See [TEST_APP_GUIDE.md](./docs/TEST_APP_GUIDE.md) for instructions on creating a test application.
|
|
324
324
|
|
|
325
325
|
## Troubleshooting
|
|
326
326
|
|
|
@@ -336,7 +336,7 @@ See [TEST_APP_GUIDE.md](./TEST_APP_GUIDE.md) for instructions on creating a test
|
|
|
336
336
|
pnpm update @kilivi/payloadcms-theme-management@latest
|
|
337
337
|
```
|
|
338
338
|
|
|
339
|
-
The plugin now accepts any compatible theme configuration structure, regardless of your Payload version or type variations. See [TYPE_INDEPENDENCE_GUIDE.md](./TYPE_INDEPENDENCE_GUIDE.md) for technical details.
|
|
339
|
+
The plugin now accepts any compatible theme configuration structure, regardless of your Payload version or type variations. See [TYPE_INDEPENDENCE_GUIDE.md](./docs/TYPE_INDEPENDENCE_GUIDE.md) for technical details.
|
|
340
340
|
|
|
341
341
|
### `Module not found: Can't resolve 'fs/promises'`
|
|
342
342
|
|
|
@@ -371,11 +371,11 @@ pnpm payload generate:types
|
|
|
371
371
|
|
|
372
372
|
## Documentation
|
|
373
373
|
|
|
374
|
-
- [Type Independence Guide](./TYPE_INDEPENDENCE_GUIDE.md) - Understanding type safety without coupling
|
|
375
|
-
- [Migration Guide](./MIGRATION_GUIDE.md) - Upgrading from older versions
|
|
376
|
-
- [Test App Guide](./TEST_APP_GUIDE.md) - Create a test application
|
|
377
|
-
- [Server/Client Separation](./SERVER_CLIENT_SEPARATION.md) - Technical details
|
|
378
|
-
- [Build Setup](./BUILD_SETUP.md) - Build configuration details
|
|
374
|
+
- [Type Independence Guide](./docs/TYPE_INDEPENDENCE_GUIDE.md) - Understanding type safety without coupling
|
|
375
|
+
- [Migration Guide](./docs/MIGRATION_GUIDE.md) - Upgrading from older versions
|
|
376
|
+
- [Test App Guide](./docs/TEST_APP_GUIDE.md) - Create a test application
|
|
377
|
+
- [Server/Client Separation](./docs/SERVER_CLIENT_SEPARATION.md) - Technical details
|
|
378
|
+
- [Build Setup](./docs/BUILD_SETUP.md) - Build configuration details
|
|
379
379
|
|
|
380
380
|
## Development
|
|
381
381
|
|
|
@@ -409,7 +409,7 @@ Contributions are welcome! Please:
|
|
|
409
409
|
|
|
410
410
|
**Error: "right-hand side of 'in' should be an object, got undefined"**
|
|
411
411
|
|
|
412
|
-
This is a known Payload CMS issue related to user preferences. See [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) for solutions.
|
|
412
|
+
This is a known Payload CMS issue related to user preferences. See [TROUBLESHOOTING.md](./docs/TROUBLESHOOTING.md) for solutions.
|
|
413
413
|
|
|
414
414
|
**Quick Fix:** Go to `/admin/account` and click "Reset Preferences" at the bottom of the page.
|
|
415
415
|
|
|
@@ -15,6 +15,6 @@ interface ServerThemeInjectorProps {
|
|
|
15
15
|
* Server-side theme CSS injector to prevent FOUC
|
|
16
16
|
* This component injects critical theme CSS directly into the HTML head during SSR
|
|
17
17
|
*/
|
|
18
|
-
export declare function ServerThemeInjector({ themeConfiguration }: Readonly<ServerThemeInjectorProps>): Promise<import("react").JSX.Element>;
|
|
18
|
+
export declare function ServerThemeInjector({ themeConfiguration, }: Readonly<ServerThemeInjectorProps>): Promise<import("react").JSX.Element>;
|
|
19
19
|
export {};
|
|
20
20
|
//# sourceMappingURL=ServerThemeInjector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerThemeInjector.d.ts","sourceRoot":"","sources":["../../src/components/ServerThemeInjector.tsx"],"names":[],"mappings":"AAcA,UAAU,wBAAwB;IAChC;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAMD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"ServerThemeInjector.d.ts","sourceRoot":"","sources":["../../src/components/ServerThemeInjector.tsx"],"names":[],"mappings":"AAcA,UAAU,wBAAwB;IAChC;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAMD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,kBAAkB,GACnB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,wCAyFpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ServerThemeInjector.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/components/ServerThemeInjector.tsx"],"sourcesContent":["import type { ThemeTypographyPreset } from '../presets.js'\nimport { getBorderRadiusConfig } from '../providers/Theme/themeConfig.js'\nimport type { BorderRadiusPreset, ThemeDefaults } from '../providers/Theme/types.js'\nimport { resolveThemeConfiguration } from '../utils/resolveThemeConfiguration.js'\nimport type { ResolvedThemeConfiguration } from '../utils/resolveThemeConfiguration.js'\nimport {\n createFallbackCriticalCSS,\n getThemeCriticalCSS,\n getThemeCSSPath,\n} from '../utils/themeAssets.js'\nimport { generateThemeColorsCss } from '../utils/themeColors.js'\nimport { generateThemeCSS } from '../utils/themeUtils.js'\nimport { InitTheme } from './InitTheme.js'\n\ninterface ServerThemeInjectorProps {\n /**\n * Theme configuration object from your site settings.\n * Pass the themeConfiguration field directly, not the entire site settings object.\n *\n * @example\n * ```tsx\n * const siteSettings = await payload.findGlobal({ slug: 'site-settings' })\n * <ServerThemeInjector themeConfiguration={siteSettings.themeConfiguration} />\n * ```\n */\n themeConfiguration?: unknown\n}\n\ntype RuntimeThemeConfiguration = Omit<ResolvedThemeConfiguration, 'typography'> & {\n typography?: ThemeTypographyPreset | null\n}\n\n/**\n * Server-side theme CSS injector to prevent FOUC\n * This component injects critical theme CSS directly into the HTML head during SSR\n */\nexport async function ServerThemeInjector({\n themeConfiguration,\n}: Readonly<ServerThemeInjectorProps>) {\n // Accept unknown type to avoid type conflicts between app's payload-types and plugin's payload-types\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const resolvedConfiguration = resolveThemeConfiguration(themeConfiguration as any)\n const {\n theme,\n borderRadius,\n customCSS,\n lightMode,\n darkMode,\n fontScale,\n spacing,\n animationLevel,\n allowColorModeToggle,\n colorMode,\n typography,\n } = resolvedConfiguration\n\n // Use resolved configuration directly\n const normalizedThemeConfiguration: RuntimeThemeConfiguration = {\n theme,\n colorMode,\n allowColorModeToggle,\n borderRadius,\n fontScale,\n spacing,\n animationLevel,\n customCSS: customCSS ?? null,\n lightMode,\n darkMode,\n typography: typography ?? undefined,\n }\n\n let criticalCSS = await getThemeCriticalCSS(theme as ThemeDefaults)\n criticalCSS ??= createFallbackCriticalCSS(theme as ThemeDefaults)\n\n const borderRadiusMap: Record<string, BorderRadiusPreset> = {\n none: 'none',\n small: 'small',\n medium: 'medium',\n large: 'large',\n xl: 'xl',\n full: 'xl',\n }\n const mappedBorderRadius = borderRadiusMap[borderRadius ?? 'medium'] ?? 'medium'\n const borderRadiusConfig = getBorderRadiusConfig(mappedBorderRadius)\n const cssRecord =\n typeof borderRadiusConfig?.css === 'string'\n ? { '--radius-default': borderRadiusConfig.css }\n : (borderRadiusConfig?.css ?? {})\n\n const borderRadiusCSS = Object.entries(cssRecord)\n .map(([property, value]) => ` ${property}: ${value};`)\n .join('\\n')\n\n const borderRadiusBlock = borderRadiusCSS\n ? `:root {\n${borderRadiusCSS}\n}`\n : ''\n\n const themeConfigurationCSS = generateThemeCSS(normalizedThemeConfiguration)\n const colorModesCSS = generateThemeColorsCss({ themeName: theme, lightMode, darkMode })\n const customCSSBlock = typeof customCSS === 'string' ? customCSS.trim() : ''\n\n const combinedCSS = [\n criticalCSS,\n borderRadiusBlock,\n themeConfigurationCSS,\n colorModesCSS,\n customCSSBlock,\n ]\n .filter((block) => Boolean(block?.trim?.().length))\n .join('\\n\\n')\n\n const themeCSSPath = getThemeCSSPath(theme as ThemeDefaults)\n return (\n <>\n <InitTheme />\n <style\n id=\"theme-critical-css\"\n dangerouslySetInnerHTML={{\n __html: combinedCSS,\n }}\n />\n <link rel=\"preload\" href={themeCSSPath} as=\"style\" />\n <link rel=\"stylesheet\" href={themeCSSPath} />\n </>\n )\n}\n"],"names":["getBorderRadiusConfig","resolveThemeConfiguration","createFallbackCriticalCSS","getThemeCriticalCSS","getThemeCSSPath","generateThemeColorsCss","generateThemeCSS","InitTheme","ServerThemeInjector","themeConfiguration","resolvedConfiguration","theme","borderRadius","customCSS","lightMode","darkMode","fontScale","spacing","animationLevel","allowColorModeToggle","colorMode","typography","normalizedThemeConfiguration","undefined","criticalCSS","borderRadiusMap","none","small","medium","large","xl","full","mappedBorderRadius","borderRadiusConfig","cssRecord","css","borderRadiusCSS","Object","entries","map","property","value","join","borderRadiusBlock","themeConfigurationCSS","colorModesCSS","themeName","customCSSBlock","trim","combinedCSS","filter","block","Boolean","length","themeCSSPath","style","id","dangerouslySetInnerHTML","__html","link","rel","href","as"],"mappings":";AACA,SAASA,qBAAqB,QAAQ,oCAAmC;AAEzE,SAASC,yBAAyB,QAAQ,wCAAuC;AAEjF,SACEC,yBAAyB,EACzBC,mBAAmB,EACnBC,eAAe,QACV,0BAAyB;AAChC,SAASC,sBAAsB,QAAQ,0BAAyB;AAChE,SAASC,gBAAgB,QAAQ,yBAAwB;AACzD,SAASC,SAAS,QAAQ,iBAAgB;AAoB1C;;;CAGC,GACD,OAAO,eAAeC,oBAAoB,EACxCC,kBAAkB,EACiB;IACnC,qGAAqG;IACrG,8DAA8D;IAC9D,MAAMC,wBAAwBT,0BAA0BQ;IACxD,MAAM,EACJE,KAAK,EACLC,YAAY,EACZC,SAAS,EACTC,SAAS,EACTC,QAAQ,EACRC,SAAS,EACTC,OAAO,EACPC,cAAc,EACdC,oBAAoB,EACpBC,SAAS,EACTC,UAAU,EACX,GAAGX;IAEJ,sCAAsC;IACtC,MAAMY,+BAA0D;QAC9DX;QACAS;QACAD;QACAP;QACAI;QACAC;QACAC;QACAL,WAAWA,aAAa;QACxBC;QACAC;QACAM,YAAYA,cAAcE;IAC5B;IAEA,IAAIC,cAAc,MAAMrB,oBAAoBQ;IAC5Ca,gBAAgBtB,0BAA0BS;IAE1C,MAAMc,kBAAsD;QAC1DC,MAAM;QACNC,OAAO;QACPC,QAAQ;QACRC,OAAO;QACPC,IAAI;QACJC,MAAM;IACR;IACA,MAAMC,qBAAqBP,eAAe,CAACb,gBAAgB,SAAS,IAAI;IACxE,MAAMqB,qBAAqBjC,sBAAsBgC;IACjD,MAAME,YACJ,OAAOD,oBAAoBE,QAAQ,WAC/B;QAAE,oBAAoBF,mBAAmBE,GAAG;IAAC,IAC5CF,oBAAoBE,OAAO,CAAC;IAEnC,MAAMC,kBAAkBC,OAAOC,OAAO,CAACJ,WACpCK,GAAG,CAAC,CAAC,CAACC,UAAUC,MAAM,GAAK,CAAC,EAAE,EAAED,SAAS,EAAE,EAAEC,MAAM,CAAC,CAAC,EACrDC,IAAI,CAAC;IAER,MAAMC,oBAAoBP,kBACtB,CAAC;AACP,EAAEA,gBAAgB;CACjB,CAAC,GACI;IAEJ,MAAMQ,wBAAwBtC,iBAAiBgB;IAC/C,MAAMuB,gBAAgBxC,uBAAuB;QAAEyC,WAAWnC;QAAOG;QAAWC;IAAS;IACrF,MAAMgC,iBAAiB,OAAOlC,cAAc,WAAWA,UAAUmC,IAAI,KAAK;IAE1E,MAAMC,cAAc;QAClBzB;QACAmB;QACAC;QACAC;QACAE;KACD,CACEG,MAAM,CAAC,CAACC,QAAUC,QAAQD,OAAOH,SAASK,SAC1CX,IAAI,CAAC;IAER,MAAMY,eAAelD,gBAAgBO;IACrC,qBACE;;0BACE,KAACJ;0BACD,KAACgD;gBACCC,IAAG;gBACHC,yBAAyB;oBACvBC,QAAQT;gBACV;;0BAEF,KAACU;gBAAKC,KAAI;gBAAUC,MAAMP;gBAAcQ,IAAG;;0BAC3C,KAACH;gBAAKC,KAAI;gBAAaC,MAAMP;;;;AAGnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemePreviewField.d.ts","sourceRoot":"","sources":["../../src/fields/ThemePreviewField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"ThemePreviewField.d.ts","sourceRoot":"","sources":["../../src/fields/ThemePreviewField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAyQrD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+BA8atE"}
|
|
@@ -24,6 +24,28 @@ const themePresets = defaultThemePresets.reduce((acc, preset)=>{
|
|
|
24
24
|
return acc;
|
|
25
25
|
}, {});
|
|
26
26
|
const colorKeys = Object.keys(lightModeDefaults);
|
|
27
|
+
const highlightSwatches = [
|
|
28
|
+
{
|
|
29
|
+
key: 'primary',
|
|
30
|
+
label: 'Primary'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
key: 'secondary',
|
|
34
|
+
label: 'Secondary'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: 'accent',
|
|
38
|
+
label: 'Accent'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
key: 'background',
|
|
42
|
+
label: 'Background'
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
key: 'foreground',
|
|
46
|
+
label: 'Foreground'
|
|
47
|
+
}
|
|
48
|
+
];
|
|
27
49
|
function ModePreview({ icon, title, colors, typography, radius }) {
|
|
28
50
|
const background = colors.background ?? '#ffffff';
|
|
29
51
|
const foreground = colors.foreground ?? '#0a0a0a';
|
|
@@ -264,8 +286,7 @@ export default function ThemePreviewField(props) {
|
|
|
264
286
|
}, [
|
|
265
287
|
dispatchFields
|
|
266
288
|
]);
|
|
267
|
-
const
|
|
268
|
-
const value = event.target.value;
|
|
289
|
+
const handleThemeSelect = useCallback((value)=>{
|
|
269
290
|
setValue(value);
|
|
270
291
|
if (!value) {
|
|
271
292
|
return;
|
|
@@ -414,29 +435,78 @@ export default function ThemePreviewField(props) {
|
|
|
414
435
|
gap: '12px'
|
|
415
436
|
},
|
|
416
437
|
children: [
|
|
417
|
-
/*#__PURE__*/
|
|
418
|
-
value: selectedTheme || '',
|
|
419
|
-
onChange: handleThemeChange,
|
|
438
|
+
/*#__PURE__*/ _jsx("div", {
|
|
420
439
|
style: {
|
|
421
|
-
|
|
422
|
-
|
|
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'
|
|
440
|
+
display: 'grid',
|
|
441
|
+
gap: '10px'
|
|
429
442
|
},
|
|
430
|
-
children: [
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
443
|
+
children: Object.entries(themePresets).map(([key, preset])=>{
|
|
444
|
+
const isSelected = key === selectedTheme;
|
|
445
|
+
const swatches = highlightSwatches.map(({ key: colorKey })=>preset.lightMode[colorKey]).filter((color)=>Boolean(color));
|
|
446
|
+
return /*#__PURE__*/ _jsxs("button", {
|
|
447
|
+
type: "button",
|
|
448
|
+
onClick: ()=>handleThemeSelect(key),
|
|
449
|
+
style: {
|
|
450
|
+
display: 'flex',
|
|
451
|
+
alignItems: 'center',
|
|
452
|
+
justifyContent: 'space-between',
|
|
453
|
+
padding: '12px 14px',
|
|
454
|
+
borderRadius: '10px',
|
|
455
|
+
border: isSelected ? '2px solid var(--theme-elevation-500)' : '1px solid var(--theme-elevation-200)',
|
|
456
|
+
backgroundColor: isSelected ? 'var(--theme-elevation-50)' : 'var(--theme-input-bg)',
|
|
457
|
+
color: 'var(--theme-elevation-800)',
|
|
458
|
+
cursor: 'pointer',
|
|
459
|
+
transition: 'border-color 120ms ease, background-color 120ms ease',
|
|
460
|
+
boxShadow: isSelected ? '0 4px 12px rgba(15, 23, 42, 0.08)' : '0 1px 3px rgba(15, 23, 42, 0.04)',
|
|
461
|
+
gap: '16px'
|
|
462
|
+
},
|
|
463
|
+
children: [
|
|
464
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
465
|
+
style: {
|
|
466
|
+
display: 'flex',
|
|
467
|
+
flexDirection: 'column',
|
|
468
|
+
alignItems: 'flex-start',
|
|
469
|
+
gap: '4px'
|
|
470
|
+
},
|
|
471
|
+
children: [
|
|
472
|
+
/*#__PURE__*/ _jsx("span", {
|
|
473
|
+
style: {
|
|
474
|
+
fontWeight: 600,
|
|
475
|
+
fontSize: '13px'
|
|
476
|
+
},
|
|
477
|
+
children: preset.label
|
|
478
|
+
}),
|
|
479
|
+
/*#__PURE__*/ _jsx("span", {
|
|
480
|
+
style: {
|
|
481
|
+
fontSize: '11px',
|
|
482
|
+
color: 'var(--theme-elevation-500)'
|
|
483
|
+
},
|
|
484
|
+
children: key
|
|
485
|
+
})
|
|
486
|
+
]
|
|
487
|
+
}),
|
|
488
|
+
/*#__PURE__*/ _jsx("div", {
|
|
489
|
+
style: {
|
|
490
|
+
display: 'grid',
|
|
491
|
+
gridAutoFlow: 'column',
|
|
492
|
+
gap: '8px',
|
|
493
|
+
alignItems: 'center'
|
|
494
|
+
},
|
|
495
|
+
"aria-hidden": "true",
|
|
496
|
+
children: swatches.map((color, index)=>/*#__PURE__*/ _jsx("span", {
|
|
497
|
+
style: {
|
|
498
|
+
width: '26px',
|
|
499
|
+
height: '26px',
|
|
500
|
+
borderRadius: '999px',
|
|
501
|
+
border: '1px solid rgba(15, 23, 42, 0.12)',
|
|
502
|
+
backgroundColor: color,
|
|
503
|
+
boxShadow: 'inset 0 1px 2px rgba(15, 23, 42, 0.08)'
|
|
504
|
+
}
|
|
505
|
+
}, `${key}-swatch-${color}-${index}`))
|
|
506
|
+
})
|
|
507
|
+
]
|
|
508
|
+
}, key);
|
|
509
|
+
})
|
|
440
510
|
}),
|
|
441
511
|
activePreset && /*#__PURE__*/ _jsxs("div", {
|
|
442
512
|
style: {
|
|
@@ -445,7 +515,7 @@ export default function ThemePreviewField(props) {
|
|
|
445
515
|
border: '1px solid var(--theme-elevation-200)',
|
|
446
516
|
backgroundColor: 'var(--theme-elevation-50)',
|
|
447
517
|
display: 'grid',
|
|
448
|
-
gap: '
|
|
518
|
+
gap: '8px',
|
|
449
519
|
fontSize: '12px',
|
|
450
520
|
color: 'var(--theme-elevation-600)'
|
|
451
521
|
},
|
|
@@ -468,6 +538,48 @@ export default function ThemePreviewField(props) {
|
|
|
468
538
|
"Accent color: ",
|
|
469
539
|
activePreset.lightMode.accent
|
|
470
540
|
]
|
|
541
|
+
}),
|
|
542
|
+
/*#__PURE__*/ _jsx("div", {
|
|
543
|
+
style: {
|
|
544
|
+
display: 'flex',
|
|
545
|
+
flexWrap: 'wrap',
|
|
546
|
+
gap: '12px',
|
|
547
|
+
marginTop: '4px'
|
|
548
|
+
},
|
|
549
|
+
children: highlightSwatches.map(({ key, label })=>{
|
|
550
|
+
const swatchValue = activePreset.lightMode[key];
|
|
551
|
+
if (!swatchValue) {
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
555
|
+
style: {
|
|
556
|
+
display: 'flex',
|
|
557
|
+
alignItems: 'center',
|
|
558
|
+
gap: '6px',
|
|
559
|
+
minWidth: 'fit-content'
|
|
560
|
+
},
|
|
561
|
+
children: [
|
|
562
|
+
/*#__PURE__*/ _jsx("span", {
|
|
563
|
+
style: {
|
|
564
|
+
width: '22px',
|
|
565
|
+
height: '22px',
|
|
566
|
+
borderRadius: '999px',
|
|
567
|
+
border: '1px solid rgba(15, 23, 42, 0.12)',
|
|
568
|
+
backgroundColor: swatchValue,
|
|
569
|
+
boxShadow: 'inset 0 1px 2px rgba(15, 23, 42, 0.08)'
|
|
570
|
+
},
|
|
571
|
+
"aria-hidden": "true"
|
|
572
|
+
}),
|
|
573
|
+
/*#__PURE__*/ _jsx("span", {
|
|
574
|
+
style: {
|
|
575
|
+
fontSize: '11px',
|
|
576
|
+
color: 'var(--theme-elevation-700)'
|
|
577
|
+
},
|
|
578
|
+
children: label
|
|
579
|
+
})
|
|
580
|
+
]
|
|
581
|
+
}, key);
|
|
582
|
+
})
|
|
471
583
|
})
|
|
472
584
|
]
|
|
473
585
|
}),
|
|
@@ -1 +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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"}
|
|
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 } 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\nconst highlightSwatches: Array<{ key: keyof ColorModeColors; label: string }> = [\n { key: 'primary', label: 'Primary' },\n { key: 'secondary', label: 'Secondary' },\n { key: 'accent', label: 'Accent' },\n { key: 'background', label: 'Background' },\n { key: 'foreground', label: 'Foreground' },\n]\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 handleThemeSelect = useCallback(\n (value: string) => {\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 <div\n style={{\n display: 'grid',\n gap: '10px',\n }}\n >\n {Object.entries(themePresets).map(([key, preset]) => {\n const isSelected = key === selectedTheme\n const swatches = highlightSwatches\n .map(({ key: colorKey }) => preset.lightMode[colorKey])\n .filter((color): color is string => Boolean(color))\n\n return (\n <button\n key={key}\n type=\"button\"\n onClick={() => handleThemeSelect(key)}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '12px 14px',\n borderRadius: '10px',\n border: isSelected\n ? '2px solid var(--theme-elevation-500)'\n : '1px solid var(--theme-elevation-200)',\n backgroundColor: isSelected\n ? 'var(--theme-elevation-50)'\n : 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n transition: 'border-color 120ms ease, background-color 120ms ease',\n boxShadow: isSelected\n ? '0 4px 12px rgba(15, 23, 42, 0.08)'\n : '0 1px 3px rgba(15, 23, 42, 0.04)',\n gap: '16px',\n }}\n >\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: '4px',\n }}\n >\n <span style={{ fontWeight: 600, fontSize: '13px' }}>{preset.label}</span>\n <span style={{ fontSize: '11px', color: 'var(--theme-elevation-500)' }}>\n {key}\n </span>\n </div>\n <div\n style={{\n display: 'grid',\n gridAutoFlow: 'column',\n gap: '8px',\n alignItems: 'center',\n }}\n aria-hidden=\"true\"\n >\n {swatches.map((color, index) => (\n <span\n key={`${key}-swatch-${color}-${index}`}\n style={{\n width: '26px',\n height: '26px',\n borderRadius: '999px',\n border: '1px solid rgba(15, 23, 42, 0.12)',\n backgroundColor: color,\n boxShadow: 'inset 0 1px 2px rgba(15, 23, 42, 0.08)',\n }}\n />\n ))}\n </div>\n </button>\n )\n })}\n </div>\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: '8px',\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 style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: '12px',\n marginTop: '4px',\n }}\n >\n {highlightSwatches.map(({ key, label }) => {\n const swatchValue = activePreset.lightMode[key]\n\n if (!swatchValue) {\n return null\n }\n\n return (\n <div\n key={key}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n minWidth: 'fit-content',\n }}\n >\n <span\n style={{\n width: '22px',\n height: '22px',\n borderRadius: '999px',\n border: '1px solid rgba(15, 23, 42, 0.12)',\n backgroundColor: swatchValue,\n boxShadow: 'inset 0 1px 2px rgba(15, 23, 42, 0.08)',\n }}\n aria-hidden=\"true\"\n />\n <span style={{ fontSize: '11px', color: 'var(--theme-elevation-700)' }}>\n {label}\n </span>\n </div>\n )\n })}\n </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","highlightSwatches","key","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","lightValue","darkValue","handleThemeSelect","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","entries","map","isSelected","swatches","colorKey","filter","Boolean","onClick","transition","flexDirection","gridAutoFlow","aria-hidden","index","width","height","marginTop","swatchValue","admin","description","position","top","alignSelf","maxHeight","overflowY"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kilivi/payloadcms-theme-management",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Theme configuration plugin for Payload CMS v3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"@swc/core": "^1.6.3",
|
|
67
67
|
"@testing-library/jest-dom": "^6.9.1",
|
|
68
68
|
"@testing-library/react": "^16.3.0",
|
|
69
|
+
"@testing-library/user-event": "^14.5.2",
|
|
69
70
|
"@types/jest": "^30.0.0",
|
|
70
71
|
"@types/node": "^22.0.0",
|
|
71
72
|
"@types/react": "^18.3.12",
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
"@vitest/ui": "^3.2.4",
|
|
75
76
|
"copyfiles": "^2.4.1",
|
|
76
77
|
"jest": "^30.2.0",
|
|
78
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
77
79
|
"mongodb-memory-server": "^10.2.3",
|
|
78
80
|
"payload": "^3.58.0",
|
|
79
81
|
"playwright": "^1.56.0",
|
|
@@ -102,10 +104,15 @@
|
|
|
102
104
|
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
103
105
|
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
104
106
|
"validate": "node validate-fields.js",
|
|
105
|
-
"test": "
|
|
107
|
+
"test": "pnpm test:jest:unit && pnpm test:vitest",
|
|
108
|
+
"test:jest": "jest --config jest.config.js",
|
|
109
|
+
"test:jest:unit": "jest --config jest.config.js --testPathIgnorePatterns=integration",
|
|
110
|
+
"test:vitest": "tsx node_modules/vitest/vitest.mjs run --config dev/vitest.simple.config.ts",
|
|
106
111
|
"test:watch": "vitest",
|
|
112
|
+
"test:watch:jest": "jest --watch",
|
|
107
113
|
"test:ui": "vitest --ui",
|
|
108
114
|
"test:coverage": "vitest run --coverage",
|
|
115
|
+
"test:coverage:jest": "jest --coverage",
|
|
109
116
|
"test:e2e": "playwright test",
|
|
110
117
|
"lint": "eslint src",
|
|
111
118
|
"lint:fix": "eslint --fix --ext .ts,.tsx src"
|