@kilivi/payloadcms-theme-management 1.0.3 → 1.0.4
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/README.md +4 -0
- package/dist/components/ThemePreview.js +1 -1
- package/dist/components/ThemePreview.js.map +1 -1
- package/dist/fields/FontSelectField.d.ts.map +1 -1
- package/dist/fields/FontSelectField.js +29 -1
- package/dist/fields/FontSelectField.js.map +1 -1
- package/dist/fields/ThemePreviewField.d.ts.map +1 -1
- package/dist/fields/ThemePreviewField.js +2 -1
- package/dist/fields/ThemePreviewField.js.map +1 -1
- package/dist/providers/font-loader.d.ts +1 -1
- package/dist/providers/font-loader.d.ts.map +1 -1
- package/dist/providers/font-loader.js.map +1 -1
- package/dist/types/jest-axe.d.js +2 -0
- package/dist/types/jest-axe.d.js.map +1 -0
- package/dist/types/payload-ui.d.js +2 -0
- package/dist/types/payload-ui.d.js.map +1 -0
- package/package.json +22 -4
package/README.md
CHANGED
|
@@ -227,6 +227,10 @@ The plugin automatically adds a **Live Preview** page to your admin panel at `/a
|
|
|
227
227
|
|
|
228
228
|
The preview automatically watches your `themeConfiguration` field and displays real-time updates without any additional setup.
|
|
229
229
|
|
|
230
|
+
## Translations / i18n
|
|
231
|
+
|
|
232
|
+
Extend or override translations at runtime with `registerTranslations`. The plugin merges your translations with English defaults, so missing keys fall back to English. See `docs/TRANSLATIONS.md` for details and examples.
|
|
233
|
+
|
|
230
234
|
## API Reference
|
|
231
235
|
|
|
232
236
|
### Main Entry Point
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ThemePreview.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport React, { useMemo } from 'react'\nimport { allThemePresets } from '../presets.js'\nimport { themeIsValid } from '../providers/Theme/types.js'\nimport { getTranslations } from '../translations.js'\nimport { getAdminLanguage } from '../utils/getAdminLanguage.js'\n\nconst DEFAULT_THEME_KEY = 'cool'\nconst basePresetMap = allThemePresets.reduce<Record<string, (typeof allThemePresets)[number]>>(\n (accumulator, preset) => {\n accumulator[preset.name] = preset\n return accumulator\n },\n {},\n)\n\nconst fallbackPreset = basePresetMap[DEFAULT_THEME_KEY] ?? allThemePresets[0]\nconst fallbackLightMode = fallbackPreset?.lightMode ?? {\n primary: '#3b82f6',\n accent: '#06b6d4',\n background: '#ffffff',\n foreground: '#1f2937',\n}\n\nexport default function ThemePreview() {\n // Get individual field values using useField hooks\n const { value: selectedTheme } = useField<string>({ path: 'themeConfiguration.theme' })\n const { value: primaryColor } = useField<string>({\n path: 'themeConfiguration.customization.primaryColor',\n })\n const { value: accentColor } = useField<string>({\n path: 'themeConfiguration.customization.accentColor',\n })\n const { value: backgroundColor } = useField<string>({\n path: 'themeConfiguration.customization.backgroundColor',\n })\n const { value: textColor } = useField<string>({\n path: 'themeConfiguration.customization.textColor',\n })\n\n // Determine current theme and if overrides are active\n const currentTheme = themeIsValid(selectedTheme)\n ? selectedTheme\n : (fallbackPreset?.name ?? 'cool')\n const hasOverrides = Boolean(primaryColor || accentColor || backgroundColor || textColor)\n\n const themeColors = useMemo(() => {\n const preset = basePresetMap[currentTheme] ?? fallbackPreset\n const lightMode = preset?.lightMode ?? fallbackLightMode\n\n return {\n primary: lightMode?.primary ?? fallbackLightMode.primary,\n accent:\n lightMode?.accent ??\n lightMode?.secondary ??\n fallbackLightMode.accent ??\n fallbackLightMode.primary,\n background: lightMode?.background ?? fallbackLightMode.background,\n text: lightMode?.foreground ?? fallbackLightMode.foreground,\n }\n }, [currentTheme])\n\n const currentColors = useMemo(\n () => ({\n primary: primaryColor || themeColors.primary,\n accent: accentColor || themeColors.accent,\n background: backgroundColor || themeColors.background,\n text: textColor || themeColors.text,\n }),\n [primaryColor, accentColor, backgroundColor, textColor, themeColors],\n )\n\n const t = getTranslations(getAdminLanguage())\n\n return (\n <div className=\"theme-preview\" style={{ marginTop: '20px' }}>\n <div\n style={{\n fontSize: '16px',\n fontWeight: '600',\n marginBottom: '16px',\n color: '#374151',\n }}\n >\n {t.livePreview.largeTitle}\n </div>\n\n <div\n className=\"preview-container\"\n style={{\n border: '2px solid #e5e7eb',\n borderRadius: '12px',\n overflow: 'hidden',\n backgroundColor: currentColors.background,\n color: currentColors.text,\n minHeight: '300px',\n }}\n >\n {/* Header */}\n <div\n style={{\n backgroundColor: currentColors.primary,\n color: currentColors.background,\n padding: '16px 24px',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <div style={{ fontSize: '20px', fontWeight: '700' }}>{t.preview.siteTitle}</div>\n <nav style={{ display: 'flex', gap: '24px', fontSize: '14px' }}>\n <span>{t.preview.nav.home}</span>\n <span>{t.preview.nav.about}</span>\n <span>{t.preview.nav.services}</span>\n <span>{t.preview.nav.contact}</span>\n </nav>\n </div>\n\n {/* Content */}\n <div style={{ padding: '32px 24px' }}>\n <h1\n style={{\n fontSize: '32px',\n fontWeight: '800',\n marginBottom: '16px',\n color: currentColors.text,\n }}\n >\n {t.preview.welcomeTitle}\n </h1>\n\n <p\n style={{\n fontSize: '16px',\n lineHeight: '1.6',\n marginBottom: '24px',\n color: currentColors.text,\n opacity: 0.8,\n }}\n >\n {t.preview.welcomeCopy}\n </p>\n <div style={{ display: 'flex', gap: '12px', marginBottom: '24px' }}>\n <button\n style={{\n backgroundColor: currentColors.primary,\n color: currentColors.background,\n border: 'none',\n padding: '12px 24px',\n borderRadius: '6px',\n fontSize: '14px',\n fontWeight: '600',\n cursor: 'pointer',\n }}\n >\n Primary Button\n </button>\n <button\n style={{\n backgroundColor: 'transparent',\n color: currentColors.primary,\n border: `2px solid ${currentColors.primary}`,\n padding: '10px 24px',\n borderRadius: '6px',\n fontSize: '14px',\n fontWeight: '600',\n cursor: 'pointer',\n }}\n >\n Secondary Button\n </button>\n </div>\n\n {/* Card */}\n <div\n style={{\n backgroundColor: currentColors.text,\n color: currentColors.background,\n padding: '24px',\n borderRadius: '8px',\n opacity: 0.05,\n marginBottom: '16px',\n }}\n />\n <div\n style={{\n border: `1px solid ${currentColors.text}`,\n padding: '20px',\n borderRadius: '8px',\n opacity: 0.1,\n }}\n >\n <h3\n style={{\n fontSize: '18px',\n fontWeight: '600',\n marginBottom: '12px',\n color: currentColors.text,\n }}\n >\n {t.preview.sampleCardTitle}\n </h3>\n <p\n style={{\n fontSize: '14px',\n color: currentColors.text,\n opacity: 0.7,\n }}\n >\n This shows how cards and content blocks will appear.\n </p>\n </div>\n </div>\n\n {/* Footer */}\n <div\n style={{\n backgroundColor: currentColors.accent,\n color: currentColors.background,\n padding: '16px 24px',\n textAlign: 'center',\n fontSize: '14px',\n marginTop: 'auto',\n }}\n >\n {t.preview.footer}\n </div>\n </div>\n\n {/* Theme info */}\n <div\n style={{\n marginTop: '12px',\n fontSize: '12px',\n color: '#6b7280',\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: '8px',\n }}\n >\n <div>\n <strong>Active Theme:</strong> {currentTheme}\n </div>\n <div>\n <strong>Primary:</strong> {currentColors.primary}\n </div>\n <div>\n <strong>Accent:</strong> {currentColors.accent}\n </div>\n <div>\n <strong>Background:</strong> {currentColors.background}\n </div>\n </div>\n\n {/* Customization indicator */}\n {hasOverrides && (\n <div\n style={{\n marginTop: '8px',\n padding: '8px 12px',\n backgroundColor: '#fef3c7',\n borderRadius: '6px',\n fontSize: '11px',\n color: '#92400e',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n }}\n >\n <span>⚡</span>\n <span>\n <strong>Custom colors applied</strong> - overriding theme defaults\n </span>\n </div>\n )}\n </div>\n )\n}\n"],"names":["useField","React","useMemo","allThemePresets","themeIsValid","getTranslations","getAdminLanguage","DEFAULT_THEME_KEY","basePresetMap","reduce","accumulator","preset","name","fallbackPreset","fallbackLightMode","lightMode","primary","accent","background","foreground","ThemePreview","value","selectedTheme","path","primaryColor","accentColor","backgroundColor","textColor","currentTheme","hasOverrides","Boolean","themeColors","secondary","text","currentColors","t","div","className","style","marginTop","fontSize","fontWeight","marginBottom","color","livePreview","largeTitle","border","borderRadius","overflow","minHeight","padding","display","justifyContent","alignItems","preview","siteTitle","nav","gap","span","home","about","services","contact","h1","welcomeTitle","p","lineHeight","opacity","welcomeCopy","button","cursor","h3","sampleCardTitle","textAlign","footer","gridTemplateColumns","strong"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ThemePreview.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport React, { useMemo } from 'react'\nimport { allThemePresets } from '../presets.js'\nimport { themeIsValid } from '../providers/Theme/types.js'\nimport { getTranslations } from '../translations.js'\nimport { getAdminLanguage } from '../utils/getAdminLanguage.js'\n\nconst DEFAULT_THEME_KEY = 'cool'\nconst basePresetMap = allThemePresets.reduce<Record<string, (typeof allThemePresets)[number]>>(\n (accumulator, preset) => {\n accumulator[preset.name] = preset\n return accumulator\n },\n {},\n)\n\nconst fallbackPreset = basePresetMap[DEFAULT_THEME_KEY] ?? allThemePresets[0]\nconst fallbackLightMode = fallbackPreset?.lightMode ?? {\n primary: '#3b82f6',\n accent: '#06b6d4',\n background: '#ffffff',\n foreground: '#1f2937',\n}\n\nexport default function ThemePreview() {\n // Get individual field values using useField hooks\n const { value: selectedTheme } = useField<string>({ path: 'themeConfiguration.theme' })\n const { value: primaryColor } = useField<string>({\n path: 'themeConfiguration.customization.primaryColor',\n })\n const { value: accentColor } = useField<string>({\n path: 'themeConfiguration.customization.accentColor',\n })\n const { value: backgroundColor } = useField<string>({\n path: 'themeConfiguration.customization.backgroundColor',\n })\n const { value: textColor } = useField<string>({\n path: 'themeConfiguration.customization.textColor',\n })\n\n // Determine current theme and if overrides are active\n const currentTheme = themeIsValid(selectedTheme)\n ? selectedTheme\n : (fallbackPreset?.name ?? 'cool')\n const hasOverrides = Boolean(primaryColor || accentColor || backgroundColor || textColor)\n\n const themeColors = useMemo(() => {\n const preset = basePresetMap[currentTheme] ?? fallbackPreset\n const lightMode = preset?.lightMode ?? fallbackLightMode\n\n return {\n primary: lightMode?.primary ?? fallbackLightMode.primary,\n accent:\n lightMode?.accent ??\n lightMode?.secondary ??\n fallbackLightMode.accent ??\n fallbackLightMode.primary,\n background: lightMode?.background ?? fallbackLightMode.background,\n text: lightMode?.foreground ?? fallbackLightMode.foreground,\n }\n }, [currentTheme])\n\n const currentColors = useMemo(\n () => ({\n primary: primaryColor || themeColors.primary,\n accent: accentColor || themeColors.accent,\n background: backgroundColor || themeColors.background,\n text: textColor || themeColors.text,\n }),\n [primaryColor, accentColor, backgroundColor, textColor, themeColors],\n )\n\n const t = getTranslations(getAdminLanguage())\n\n return (\n <div className=\"theme-preview\" style={{ marginTop: '20px' }}>\n <div\n style={{\n fontSize: '16px',\n fontWeight: '600',\n marginBottom: '16px',\n color: '#374151',\n }}\n >\n {t.livePreview.largeTitle}\n </div>\n\n <div\n className=\"preview-container\"\n style={{\n border: '2px solid #e5e7eb',\n borderRadius: '12px',\n overflow: 'hidden',\n backgroundColor: currentColors.background,\n color: currentColors.text,\n minHeight: '300px',\n }}\n >\n {/* Header */}\n <div\n style={{\n backgroundColor: currentColors.primary,\n color: currentColors.background,\n padding: '16px 24px',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <div style={{ fontSize: '20px', fontWeight: '700' }}>{t.preview.siteTitle}</div>\n <nav style={{ display: 'flex', gap: '24px', fontSize: '14px' }}>\n <span>{t.preview.nav.home}</span>\n <span>{t.preview.nav.about}</span>\n <span>{t.preview.nav.services}</span>\n <span>{t.preview.nav.contact}</span>\n </nav>\n </div>\n\n {/* Content */}\n <div style={{ padding: '32px 24px' }}>\n <h1\n style={{\n fontSize: '32px',\n fontWeight: '800',\n marginBottom: '16px',\n color: currentColors.text,\n }}\n >\n {t.preview.welcomeTitle}\n </h1>\n\n <p\n style={{\n fontSize: '16px',\n lineHeight: '1.6',\n marginBottom: '24px',\n color: currentColors.text,\n opacity: 0.8,\n }}\n >\n {t.preview.welcomeCopy}\n </p>\n <div style={{ display: 'flex', gap: '12px', marginBottom: '24px' }}>\n <button\n style={{\n backgroundColor: currentColors.primary,\n color: currentColors.background,\n border: 'none',\n padding: '12px 24px',\n borderRadius: '6px',\n fontSize: '14px',\n fontWeight: '600',\n cursor: 'pointer',\n }}\n >\n Primary Button\n </button>\n <button\n style={{\n backgroundColor: 'transparent',\n color: currentColors.primary,\n border: `2px solid ${currentColors.primary}`,\n padding: '10px 24px',\n borderRadius: '6px',\n fontSize: '14px',\n fontWeight: '600',\n cursor: 'pointer',\n }}\n >\n Secondary Button\n </button>\n </div>\n\n {/* Card */}\n <div\n style={{\n backgroundColor: currentColors.text,\n color: currentColors.background,\n padding: '24px',\n borderRadius: '8px',\n opacity: 0.05,\n marginBottom: '16px',\n }}\n />\n <div\n style={{\n border: `1px solid ${currentColors.text}`,\n padding: '20px',\n borderRadius: '8px',\n opacity: 0.1,\n }}\n >\n <h2\n style={{\n fontSize: '18px',\n fontWeight: '600',\n marginBottom: '12px',\n color: currentColors.text,\n }}\n >\n {t.preview.sampleCardTitle}\n </h2>\n <p\n style={{\n fontSize: '14px',\n color: currentColors.text,\n opacity: 0.7,\n }}\n >\n This shows how cards and content blocks will appear.\n </p>\n </div>\n </div>\n\n {/* Footer */}\n <div\n style={{\n backgroundColor: currentColors.accent,\n color: currentColors.background,\n padding: '16px 24px',\n textAlign: 'center',\n fontSize: '14px',\n marginTop: 'auto',\n }}\n >\n {t.preview.footer}\n </div>\n </div>\n\n {/* Theme info */}\n <div\n style={{\n marginTop: '12px',\n fontSize: '12px',\n color: '#6b7280',\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: '8px',\n }}\n >\n <div>\n <strong>Active Theme:</strong> {currentTheme}\n </div>\n <div>\n <strong>Primary:</strong> {currentColors.primary}\n </div>\n <div>\n <strong>Accent:</strong> {currentColors.accent}\n </div>\n <div>\n <strong>Background:</strong> {currentColors.background}\n </div>\n </div>\n\n {/* Customization indicator */}\n {hasOverrides && (\n <div\n style={{\n marginTop: '8px',\n padding: '8px 12px',\n backgroundColor: '#fef3c7',\n borderRadius: '6px',\n fontSize: '11px',\n color: '#92400e',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n }}\n >\n <span>⚡</span>\n <span>\n <strong>Custom colors applied</strong> - overriding theme defaults\n </span>\n </div>\n )}\n </div>\n )\n}\n"],"names":["useField","React","useMemo","allThemePresets","themeIsValid","getTranslations","getAdminLanguage","DEFAULT_THEME_KEY","basePresetMap","reduce","accumulator","preset","name","fallbackPreset","fallbackLightMode","lightMode","primary","accent","background","foreground","ThemePreview","value","selectedTheme","path","primaryColor","accentColor","backgroundColor","textColor","currentTheme","hasOverrides","Boolean","themeColors","secondary","text","currentColors","t","div","className","style","marginTop","fontSize","fontWeight","marginBottom","color","livePreview","largeTitle","border","borderRadius","overflow","minHeight","padding","display","justifyContent","alignItems","preview","siteTitle","nav","gap","span","home","about","services","contact","h1","welcomeTitle","p","lineHeight","opacity","welcomeCopy","button","cursor","h2","sampleCardTitle","textAlign","footer","gridTemplateColumns","strong"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontSelectField.d.ts","sourceRoot":"","sources":["../../src/fields/FontSelectField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAczD,QAAA,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"FontSelectField.d.ts","sourceRoot":"","sources":["../../src/fields/FontSelectField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAczD,QAAA,MAAM,eAAe,EAAE,0BAyOtB,CAAA;AAED,eAAe,eAAe,CAAA"}
|
|
@@ -11,11 +11,36 @@ const FontSelectField = ({ field, path })=>{
|
|
|
11
11
|
const [isOpen, setIsOpen] = useState(false);
|
|
12
12
|
const options = field.options || [];
|
|
13
13
|
const selectedOption = options.find((opt)=>opt.value === value);
|
|
14
|
+
const [loadedFonts, setLoadedFonts] = useState(new Set());
|
|
14
15
|
const getOptionLabel = (opt)=>{
|
|
15
16
|
if (typeof opt.label === 'string') return opt.label;
|
|
16
17
|
const lang = getAdminLanguage();
|
|
17
18
|
return opt.label[lang] || opt.label.en || opt.label.cs || 'Font';
|
|
18
19
|
};
|
|
20
|
+
const ensureFontLoaded = (fontValue)=>{
|
|
21
|
+
if (!fontValue || [
|
|
22
|
+
'preset',
|
|
23
|
+
'custom',
|
|
24
|
+
'system-ui'
|
|
25
|
+
].includes(fontValue)) return;
|
|
26
|
+
// Avoid duplicate loads
|
|
27
|
+
if (loadedFonts.has(fontValue)) return;
|
|
28
|
+
if (typeof document === 'undefined') return;
|
|
29
|
+
const linkId = `font-${fontValue.replace(/\s+/g, '-')}`;
|
|
30
|
+
if (document.getElementById(linkId)) {
|
|
31
|
+
setLoadedFonts((prev)=>new Set(prev).add(fontValue));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const weights = '400;700' // reasonable default weights
|
|
35
|
+
;
|
|
36
|
+
const fontUrl = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(fontValue)}:wght@${weights}&display=swap`;
|
|
37
|
+
const link = document.createElement('link');
|
|
38
|
+
link.id = linkId;
|
|
39
|
+
link.rel = 'stylesheet';
|
|
40
|
+
link.href = fontUrl;
|
|
41
|
+
link.onload = ()=>setLoadedFonts((prev)=>new Set(prev).add(fontValue));
|
|
42
|
+
document.head.appendChild(link);
|
|
43
|
+
};
|
|
19
44
|
const handleSelect = (optionValue)=>{
|
|
20
45
|
setValue(optionValue);
|
|
21
46
|
setIsOpen(false);
|
|
@@ -151,6 +176,8 @@ const FontSelectField = ({ field, path })=>{
|
|
|
151
176
|
if (!isSelected) {
|
|
152
177
|
e.currentTarget.style.backgroundColor = 'var(--theme-elevation-50)';
|
|
153
178
|
}
|
|
179
|
+
// Lazy-load a preview font when hovering
|
|
180
|
+
ensureFontLoaded(option.value);
|
|
154
181
|
},
|
|
155
182
|
onMouseLeave: (e)=>{
|
|
156
183
|
if (!isSelected) {
|
|
@@ -186,7 +213,8 @@ const FontSelectField = ({ field, path })=>{
|
|
|
186
213
|
style: {
|
|
187
214
|
fontSize: '16px',
|
|
188
215
|
color: 'var(--theme-elevation-600)',
|
|
189
|
-
fontStyle: option.value === 'preset' || option.value === 'custom' ? 'italic' : 'normal'
|
|
216
|
+
fontStyle: option.value === 'preset' || option.value === 'custom' ? 'italic' : 'normal',
|
|
217
|
+
fontFamily: option.fontFamily || undefined
|
|
190
218
|
},
|
|
191
219
|
children: (()=>{
|
|
192
220
|
if (option.value === 'preset') return t.ui.usePreset;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/FontSelectField.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport type { SelectFieldClientComponent } from 'payload'\nimport { useEffect, useState } from 'react'\nimport { getTranslations } from '../translations.js'\nimport { getAdminLanguage } from '../utils/getAdminLanguage.js'\n\ntype LocalizedLabel = Record<string, string>\n\ninterface FontOption {\n label: string | LocalizedLabel\n value: string\n fontFamily?: string\n category?: 'sans-serif' | 'serif' | 'monospace' | 'display'\n}\n\nconst FontSelectField: SelectFieldClientComponent = ({ field, path }) => {\n const { value, setValue } = useField<string>({ path })\n const [isOpen, setIsOpen] = useState(false)\n\n const options = (field.options as FontOption[]) || []\n const selectedOption = options.find((opt) => opt.value === value)\n const getOptionLabel = (opt: FontOption) => {\n if (typeof opt.label === 'string') return opt.label\n const lang = getAdminLanguage()\n return opt.label[lang] || opt.label.en || opt.label.cs || 'Font'\n }\n\n const handleSelect = (optionValue: string) => {\n setValue(optionValue)\n setIsOpen(false)\n }\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n const target = e.target as HTMLElement\n if (!target.closest('.font-select-container')) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n const t = getTranslations(getAdminLanguage())\n const label =\n typeof field.label === 'string'\n ? field.label\n : typeof field.label === 'object'\n ? field.label?.en || field.label?.cs\n : field.label || 'Font'\n\n return (\n <div className=\"font-select-container\" style={{ position: 'relative', marginBottom: '12px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '6px',\n fontSize: '13px',\n fontWeight: 600,\n color: 'var(--theme-elevation-800)',\n }}\n >\n {label}\n </label>\n\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n style={{\n width: '300px',\n padding: '10px 14px',\n borderRadius: '6px',\n border: '1px solid var(--theme-elevation-200)',\n backgroundColor: 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n textAlign: 'left',\n cursor: 'pointer',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n fontSize: '14px',\n fontFamily: selectedOption?.fontFamily || 'inherit',\n transition: 'border-color 0.2s ease',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.borderColor = 'var(--theme-elevation-400)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.borderColor = 'var(--theme-elevation-200)'\n }}\n >\n <span style={{ flex: 1 }}>\n {selectedOption ? getOptionLabel(selectedOption) : t.ui.selectFontPlaceholder}\n </span>{' '}\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n style={{\n transition: 'transform 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n >\n <path\n d=\"M3 4.5L6 7.5L9 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n\n {isOpen && (\n <div\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n right: 0,\n marginTop: '4px',\n maxHeight: '280px',\n overflowY: 'auto',\n backgroundColor: 'var(--theme-elevation-0)',\n border: '1px solid var(--theme-elevation-200)',\n borderRadius: '8px',\n boxShadow: '0 8px 24px rgba(15, 23, 42, 0.15)',\n zIndex: 1000,\n }}\n >\n {options.map((option) => {\n const isSelected = option.value === value\n\n let fontFamily = option.fontFamily\n if (!fontFamily) {\n if (option.category === 'sans-serif') fontFamily = 'system-ui, sans-serif'\n else if (option.category === 'serif') fontFamily = 'Georgia, serif'\n else if (option.category === 'monospace') fontFamily = 'monospace'\n else fontFamily = 'inherit'\n }\n\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => handleSelect(option.value)}\n style={{\n width: '250px',\n padding: '12px 14px',\n border: 'none',\n backgroundColor: isSelected ? 'var(--theme-elevation-100)' : 'transparent',\n color: 'var(--theme-elevation-800)',\n textAlign: 'left',\n cursor: 'pointer',\n fontSize: '14px',\n fontFamily,\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n transition: 'background-color 0.15s ease',\n }}\n onMouseEnter={(e) => {\n if (!isSelected) {\n e.currentTarget.style.backgroundColor = 'var(--theme-elevation-50)'\n }\n }}\n onMouseLeave={(e) => {\n if (!isSelected) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n <div\n style={{\n fontWeight: isSelected ? 600 : 500,\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n }}\n >\n {isSelected && (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path\n d=\"M11.6667 3.5L5.25 9.91667L2.33334 7\"\n stroke=\"var(--theme-elevation-500)\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n {getOptionLabel(option)}\n </div>\n <div\n style={{\n fontSize: '16px',\n color: 'var(--theme-elevation-600)',\n fontStyle:\n option.value === 'preset' || option.value === 'custom' ? 'italic' : 'normal',\n }}\n >\n {(() => {\n if (option.value === 'preset') return t.ui.usePreset\n if (option.value === 'custom') return t.ui.specifyCustom\n return t.ui.sampleSentence\n })()}\n </div>\n </button>\n )\n })}\n </div>\n )}\n </div>\n )\n}\n\nexport default FontSelectField\n"],"names":["useField","useEffect","useState","getTranslations","getAdminLanguage","FontSelectField","field","path","value","setValue","isOpen","setIsOpen","options","selectedOption","find","opt","getOptionLabel","label","lang","en","cs","handleSelect","optionValue","handleClickOutside","e","target","closest","document","addEventListener","removeEventListener","t","div","className","style","position","marginBottom","display","fontSize","fontWeight","color","button","type","onClick","width","padding","borderRadius","border","backgroundColor","textAlign","cursor","justifyContent","alignItems","fontFamily","transition","onMouseEnter","currentTarget","borderColor","onMouseLeave","span","flex","ui","selectFontPlaceholder","svg","height","viewBox","fill","transform","d","stroke","strokeWidth","strokeLinecap","strokeLinejoin","top","left","right","marginTop","maxHeight","overflowY","boxShadow","zIndex","map","option","isSelected","category","flexDirection","gap","fontStyle","usePreset","specifyCustom","sampleSentence"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/fields/FontSelectField.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport type { SelectFieldClientComponent } from 'payload'\nimport { useEffect, useState } from 'react'\nimport { getTranslations } from '../translations.js'\nimport { getAdminLanguage } from '../utils/getAdminLanguage.js'\n\ntype LocalizedLabel = Record<string, string>\n\ninterface FontOption {\n label: string | LocalizedLabel\n value: string\n fontFamily?: string\n category?: 'sans-serif' | 'serif' | 'monospace' | 'display'\n}\n\nconst FontSelectField: SelectFieldClientComponent = ({ field, path }) => {\n const { value, setValue } = useField<string>({ path })\n const [isOpen, setIsOpen] = useState(false)\n\n const options = (field.options as FontOption[]) || []\n const selectedOption = options.find((opt) => opt.value === value)\n const [loadedFonts, setLoadedFonts] = useState<Set<string>>(new Set())\n\n const getOptionLabel = (opt: FontOption) => {\n if (typeof opt.label === 'string') return opt.label\n const lang = getAdminLanguage()\n return opt.label[lang] || opt.label.en || opt.label.cs || 'Font'\n }\n\n const ensureFontLoaded = (fontValue: string | undefined) => {\n if (!fontValue || ['preset', 'custom', 'system-ui'].includes(fontValue)) return\n // Avoid duplicate loads\n if (loadedFonts.has(fontValue)) return\n\n if (typeof document === 'undefined') return\n\n const linkId = `font-${fontValue.replace(/\\s+/g, '-')}`\n if (document.getElementById(linkId)) {\n setLoadedFonts((prev) => new Set(prev).add(fontValue))\n return\n }\n\n const weights = '400;700' // reasonable default weights\n const fontUrl = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(\n fontValue,\n )}:wght@${weights}&display=swap`\n const link = document.createElement('link')\n link.id = linkId\n link.rel = 'stylesheet'\n link.href = fontUrl\n link.onload = () => setLoadedFonts((prev) => new Set(prev).add(fontValue))\n document.head.appendChild(link)\n }\n\n const handleSelect = (optionValue: string) => {\n setValue(optionValue)\n setIsOpen(false)\n }\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n const target = e.target as HTMLElement\n if (!target.closest('.font-select-container')) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n const t = getTranslations(getAdminLanguage())\n const label =\n typeof field.label === 'string'\n ? field.label\n : typeof field.label === 'object'\n ? field.label?.en || field.label?.cs\n : field.label || 'Font'\n\n return (\n <div className=\"font-select-container\" style={{ position: 'relative', marginBottom: '12px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '6px',\n fontSize: '13px',\n fontWeight: 600,\n color: 'var(--theme-elevation-800)',\n }}\n >\n {label}\n </label>\n\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n style={{\n width: '300px',\n padding: '10px 14px',\n borderRadius: '6px',\n border: '1px solid var(--theme-elevation-200)',\n backgroundColor: 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n textAlign: 'left',\n cursor: 'pointer',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n fontSize: '14px',\n fontFamily: selectedOption?.fontFamily || 'inherit',\n transition: 'border-color 0.2s ease',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.borderColor = 'var(--theme-elevation-400)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.borderColor = 'var(--theme-elevation-200)'\n }}\n >\n <span style={{ flex: 1 }}>\n {selectedOption ? getOptionLabel(selectedOption) : t.ui.selectFontPlaceholder}\n </span>{' '}\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n style={{\n transition: 'transform 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n >\n <path\n d=\"M3 4.5L6 7.5L9 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n\n {isOpen && (\n <div\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n right: 0,\n marginTop: '4px',\n maxHeight: '280px',\n overflowY: 'auto',\n backgroundColor: 'var(--theme-elevation-0)',\n border: '1px solid var(--theme-elevation-200)',\n borderRadius: '8px',\n boxShadow: '0 8px 24px rgba(15, 23, 42, 0.15)',\n zIndex: 1000,\n }}\n >\n {options.map((option) => {\n const isSelected = option.value === value\n\n let fontFamily = option.fontFamily\n if (!fontFamily) {\n if (option.category === 'sans-serif') fontFamily = 'system-ui, sans-serif'\n else if (option.category === 'serif') fontFamily = 'Georgia, serif'\n else if (option.category === 'monospace') fontFamily = 'monospace'\n else fontFamily = 'inherit'\n }\n\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => handleSelect(option.value)}\n style={{\n width: '250px',\n padding: '12px 14px',\n border: 'none',\n backgroundColor: isSelected ? 'var(--theme-elevation-100)' : 'transparent',\n color: 'var(--theme-elevation-800)',\n textAlign: 'left',\n cursor: 'pointer',\n fontSize: '14px',\n fontFamily,\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n transition: 'background-color 0.15s ease',\n }}\n onMouseEnter={(e) => {\n if (!isSelected) {\n e.currentTarget.style.backgroundColor = 'var(--theme-elevation-50)'\n }\n // Lazy-load a preview font when hovering\n ensureFontLoaded(option.value)\n }}\n onMouseLeave={(e) => {\n if (!isSelected) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n <div\n style={{\n fontWeight: isSelected ? 600 : 500,\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n }}\n >\n {isSelected && (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path\n d=\"M11.6667 3.5L5.25 9.91667L2.33334 7\"\n stroke=\"var(--theme-elevation-500)\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n {getOptionLabel(option)}\n </div>\n <div\n style={{\n fontSize: '16px',\n color: 'var(--theme-elevation-600)',\n fontStyle:\n option.value === 'preset' || option.value === 'custom' ? 'italic' : 'normal',\n fontFamily: option.fontFamily || undefined,\n }}\n >\n {(() => {\n if (option.value === 'preset') return t.ui.usePreset\n if (option.value === 'custom') return t.ui.specifyCustom\n return t.ui.sampleSentence\n })()}\n </div>\n </button>\n )\n })}\n </div>\n )}\n </div>\n )\n}\n\nexport default FontSelectField\n"],"names":["useField","useEffect","useState","getTranslations","getAdminLanguage","FontSelectField","field","path","value","setValue","isOpen","setIsOpen","options","selectedOption","find","opt","loadedFonts","setLoadedFonts","Set","getOptionLabel","label","lang","en","cs","ensureFontLoaded","fontValue","includes","has","document","linkId","replace","getElementById","prev","add","weights","fontUrl","encodeURIComponent","link","createElement","id","rel","href","onload","head","appendChild","handleSelect","optionValue","handleClickOutside","e","target","closest","addEventListener","removeEventListener","t","div","className","style","position","marginBottom","display","fontSize","fontWeight","color","button","type","onClick","width","padding","borderRadius","border","backgroundColor","textAlign","cursor","justifyContent","alignItems","fontFamily","transition","onMouseEnter","currentTarget","borderColor","onMouseLeave","span","flex","ui","selectFontPlaceholder","svg","height","viewBox","fill","transform","d","stroke","strokeWidth","strokeLinecap","strokeLinejoin","top","left","right","marginTop","maxHeight","overflowY","boxShadow","zIndex","map","option","isSelected","category","flexDirection","gap","fontStyle","undefined","usePreset","specifyCustom","sampleSentence"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemePreviewField.d.ts","sourceRoot":"","sources":["../../src/fields/ThemePreviewField.tsx"],"names":[],"mappings":"AAEA,OAAO,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAwPrD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+
|
|
1
|
+
{"version":3,"file":"ThemePreviewField.d.ts","sourceRoot":"","sources":["../../src/fields/ThemePreviewField.tsx"],"names":[],"mappings":"AAEA,OAAO,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAwPrD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+BAqatE"}
|
|
@@ -397,6 +397,7 @@ export default function ThemePreviewField(props) {
|
|
|
397
397
|
};
|
|
398
398
|
// Translate labels at runtime based on admin language
|
|
399
399
|
const t = getTranslations(getAdminLanguage());
|
|
400
|
+
// Explicitly type keys as `keyof ColorModeColors` to satisfy TypeScript when indexing `lightMode`/`darkMode`
|
|
400
401
|
const highlightSwatches = [
|
|
401
402
|
{
|
|
402
403
|
key: 'primary',
|
|
@@ -456,7 +457,7 @@ export default function ThemePreviewField(props) {
|
|
|
456
457
|
className: "theme-preset-list",
|
|
457
458
|
children: Object.entries(runtimeThemePresets).map(([key, preset])=>{
|
|
458
459
|
const isSelected = key === selectedTheme;
|
|
459
|
-
const swatches = highlightSwatches.map(({ key: colorKey })=>preset.lightMode[colorKey]).filter((
|
|
460
|
+
const swatches = highlightSwatches.map(({ key: colorKey })=>preset.lightMode[colorKey]).filter((v)=>typeof v === 'string' && v.trim().length > 0);
|
|
460
461
|
return /*#__PURE__*/ _jsxs("button", {
|
|
461
462
|
type: "button",
|
|
462
463
|
onClick: ()=>handleThemeSelect(key),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/ThemePreviewField.tsx"],"sourcesContent":["'use client'\n\nimport './ThemePreviewField.css'\nimport { useField, useForm, useFormFields } from '@payloadcms/ui'\nimport type { SelectFieldClientProps } from 'payload'\nimport { useCallback, useEffect, useMemo, useRef } from 'react'\nimport type {\n ResolvedTypographyPreview,\n TypographySelection,\n} from '../components/typographyPreviewUtils.js'\nimport { resolveTypographyPreview } from '../components/typographyPreviewUtils.js'\nimport { allThemePresets } from '../index.js'\nimport type { ThemePreset, ThemeTypographyPreset } from '../presets.js'\nimport { borderRadiusPresets } from '../providers/Theme/themeConfig.js'\nimport { getTranslations } from '../translations.js'\nimport { getAdminLanguage } from '../utils/getAdminLanguage.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\n// FALLBACK_THEME and runtime theme presets are computed inside the component\n\nconst colorKeys = Object.keys(lightModeDefaults) as (keyof ColorModeColors)[]\n\n// translations and swatches will be computed inside the component to respect admin language at runtime\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 t = getTranslations(getAdminLanguage())\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 {t.ui.primaryAction}\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 {t.ui.secondaryAction}\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 // If the plugin provided theme presets via admin config, prefer those;\n // support both `field.admin.themePresets` (legacy) and `field.admin.custom.themePresets`\n // otherwise fallback to `allThemePresets`.\n // Prefer presets passed via `admin.custom.themePresets` (set by the field factory / plugin).\n // Fall back to legacy `admin.themePresets` for backwards compatibility, then to `allThemePresets`.\n const baseThemePresets =\n (field?.admin?.custom as unknown as { themePresets?: ThemePreset[] })?.themePresets ??\n (field?.admin as unknown as { themePresets?: ThemePreset[] })?.themePresets ??\n allThemePresets\n const runtimeThemePresets = useMemo(() => {\n return (baseThemePresets as ThemePreset[]).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 }, [baseThemePresets])\n const fallbackTheme = baseThemePresets[0]?.name ?? 'cool'\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 = runtimeThemePresets[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 (runtimeThemePresets[selectedTheme]) {\n return\n }\n\n hasAppliedInitialPresetRef.current = false\n setValue(fallbackTheme)\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 = runtimeThemePresets[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\n ? runtimeThemePresets[selectedTheme]?.lightMode\n : 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 ? runtimeThemePresets[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 ? runtimeThemePresets[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: borderRadiusCSS['--radius-xl'] ?? borderRadiusCSS['--radius-large'] ?? '999px',\n }\n\n // Translate labels at runtime based on admin language\n const t = getTranslations(getAdminLanguage())\n const highlightSwatches = [\n { key: 'primary', label: t.colors.primary },\n { key: 'secondary', label: t.colors.secondary },\n { key: 'accent', label: t.colors.accent },\n { key: 'background', label: t.colors.background },\n { key: 'foreground', label: t.colors.foreground },\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 className=\"theme-preset-list\">\n {Object.entries(runtimeThemePresets).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 className={`theme-preset-button ${isSelected ? 'selected' : ''}`}\n >\n <div className=\"theme-info\">\n <span className=\"theme-label\">{preset.label}</span>\n <span className=\"theme-name\">{key}</span>\n </div>\n <div className=\"theme-swatches\" aria-hidden=\"true\">\n {swatches.map((color, index) => (\n <span\n key={`${key}-swatch-${color}-${index}`}\n className=\"color-swatch\"\n style={{ backgroundColor: color }}\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 {/* safe translations for preview header */}\n <span>{getTranslations('en').livePreview.smallTitle}</span>\n <span style={{ fontSize: '12px', color: 'var(--theme-elevation-600)' }}>\n {activePreset ? activePreset.label : getTranslations('en').preview.customPalette}\n </span>\n </div>\n\n <div\n style={{\n display: 'grid',\n gap: '16px',\n }}\n >\n <ModePreview\n icon=\"☀️\"\n title={getTranslations('en').ui.lightMode}\n colors={lightModeColors}\n typography={previewTypography}\n radius={previewRadius}\n />\n <ModePreview\n icon=\"🌙\"\n title={getTranslations('en').ui.darkMode}\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","resolveTypographyPreview","allThemePresets","borderRadiusPresets","getTranslations","getAdminLanguage","darkModeDefaults","lightModeDefaults","colorKeys","Object","keys","ModePreview","icon","title","colors","typography","radius","t","background","foreground","borderColor","border","cardBackground","card","cardForeground","primary","primaryForeground","secondary","secondaryForeground","muted","mutedForeground","accent","accentForeground","headingFont","bodyFont","baseFontSize","lineHeight","div","style","display","gap","padding","borderRadius","backgroundColor","color","boxShadow","fontFamily","alignItems","justifyContent","fontSize","fontWeight","letterSpacing","textTransform","opacity","span","toUpperCase","flexWrap","button","type","pill","cursor","ui","primaryAction","chip","secondaryAction","gridTemplateColumns","p","margin","bodyLabel","headingLabel","ThemePreviewField","props","field","path","baseThemePresets","admin","custom","themePresets","runtimeThemePresets","reduce","acc","preset","name","label","lightMode","darkMode","fallbackTheme","value","selectedTheme","setValue","dispatchFields","formFields","formState","hasAppliedInitialPresetRef","applyPreset","presetName","forEach","key","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","highlightSwatches","fieldLabel","en","cs","marginBottom","flex","minWidth","maxWidth","className","entries","map","isSelected","swatches","colorKey","filter","Boolean","onClick","aria-hidden","index","marginTop","swatchValue","width","height","description","position","top","alignSelf","maxHeight","overflowY","livePreview","smallTitle","preview","customPalette"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/fields/ThemePreviewField.tsx"],"sourcesContent":["'use client'\n\nimport './ThemePreviewField.css'\nimport { useField, useForm, useFormFields } from '@payloadcms/ui'\nimport type { SelectFieldClientProps } from 'payload'\nimport { useCallback, useEffect, useMemo, useRef } from 'react'\nimport type {\n ResolvedTypographyPreview,\n TypographySelection,\n} from '../components/typographyPreviewUtils.js'\nimport { resolveTypographyPreview } from '../components/typographyPreviewUtils.js'\nimport { allThemePresets } from '../index.js'\nimport type { ThemePreset, ThemeTypographyPreset } from '../presets.js'\nimport { borderRadiusPresets } from '../providers/Theme/themeConfig.js'\nimport { getTranslations } from '../translations.js'\nimport { getAdminLanguage } from '../utils/getAdminLanguage.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\n// FALLBACK_THEME and runtime theme presets are computed inside the component\n\nconst colorKeys = Object.keys(lightModeDefaults) as (keyof ColorModeColors)[]\n\n// translations and swatches will be computed inside the component to respect admin language at runtime\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 t = getTranslations(getAdminLanguage())\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 {t.ui.primaryAction}\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 {t.ui.secondaryAction}\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 // If the plugin provided theme presets via admin config, prefer those;\n // support both `field.admin.themePresets` (legacy) and `field.admin.custom.themePresets`\n // otherwise fallback to `allThemePresets`.\n // Prefer presets passed via `admin.custom.themePresets` (set by the field factory / plugin).\n // Fall back to legacy `admin.themePresets` for backwards compatibility, then to `allThemePresets`.\n const baseThemePresets =\n (field?.admin?.custom as unknown as { themePresets?: ThemePreset[] })?.themePresets ??\n (field?.admin as unknown as { themePresets?: ThemePreset[] })?.themePresets ??\n allThemePresets\n const runtimeThemePresets = useMemo(() => {\n return (baseThemePresets as ThemePreset[]).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 }, [baseThemePresets])\n const fallbackTheme = baseThemePresets[0]?.name ?? 'cool'\n const { value: selectedTheme, setValue } = useField<string>({ path })\n const { dispatchFields } = useForm()\n const formFields = useFormFields(([formState]: any) => formState)\n const hasAppliedInitialPresetRef = useRef(false)\n\n const applyPreset = useCallback(\n (presetName: string) => {\n const preset = runtimeThemePresets[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 (runtimeThemePresets[selectedTheme]) {\n return\n }\n\n hasAppliedInitialPresetRef.current = false\n setValue(fallbackTheme)\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 = runtimeThemePresets[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\n ? runtimeThemePresets[selectedTheme]?.lightMode\n : 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 ? runtimeThemePresets[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 ? runtimeThemePresets[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: borderRadiusCSS['--radius-xl'] ?? borderRadiusCSS['--radius-large'] ?? '999px',\n }\n\n // Translate labels at runtime based on admin language\n const t = getTranslations(getAdminLanguage())\n // Explicitly type keys as `keyof ColorModeColors` to satisfy TypeScript when indexing `lightMode`/`darkMode`\n const highlightSwatches: { key: keyof ColorModeColors; label: string }[] = [\n { key: 'primary', label: t.colors.primary },\n { key: 'secondary', label: t.colors.secondary },\n { key: 'accent', label: t.colors.accent },\n { key: 'background', label: t.colors.background },\n { key: 'foreground', label: t.colors.foreground },\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 className=\"theme-preset-list\">\n {Object.entries(runtimeThemePresets).map(([key, preset]) => {\n const isSelected = key === selectedTheme\n const swatches = highlightSwatches\n .map(({ key: colorKey }) => preset.lightMode[colorKey] as string | undefined)\n .filter((v): v is string => typeof v === 'string' && v.trim().length > 0)\n\n return (\n <button\n key={key}\n type=\"button\"\n onClick={() => handleThemeSelect(key)}\n className={`theme-preset-button ${isSelected ? 'selected' : ''}`}\n >\n <div className=\"theme-info\">\n <span className=\"theme-label\">{preset.label}</span>\n <span className=\"theme-name\">{key}</span>\n </div>\n <div className=\"theme-swatches\" aria-hidden=\"true\">\n {swatches.map((color, index) => (\n <span\n key={`${key}-swatch-${color}-${index}`}\n className=\"color-swatch\"\n style={{ backgroundColor: color }}\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 {/* safe translations for preview header */}\n <span>{getTranslations('en').livePreview.smallTitle}</span>\n <span style={{ fontSize: '12px', color: 'var(--theme-elevation-600)' }}>\n {activePreset ? activePreset.label : getTranslations('en').preview.customPalette}\n </span>\n </div>\n\n <div\n style={{\n display: 'grid',\n gap: '16px',\n }}\n >\n <ModePreview\n icon=\"☀️\"\n title={getTranslations('en').ui.lightMode}\n colors={lightModeColors}\n typography={previewTypography}\n radius={previewRadius}\n />\n <ModePreview\n icon=\"🌙\"\n title={getTranslations('en').ui.darkMode}\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","resolveTypographyPreview","allThemePresets","borderRadiusPresets","getTranslations","getAdminLanguage","darkModeDefaults","lightModeDefaults","colorKeys","Object","keys","ModePreview","icon","title","colors","typography","radius","t","background","foreground","borderColor","border","cardBackground","card","cardForeground","primary","primaryForeground","secondary","secondaryForeground","muted","mutedForeground","accent","accentForeground","headingFont","bodyFont","baseFontSize","lineHeight","div","style","display","gap","padding","borderRadius","backgroundColor","color","boxShadow","fontFamily","alignItems","justifyContent","fontSize","fontWeight","letterSpacing","textTransform","opacity","span","toUpperCase","flexWrap","button","type","pill","cursor","ui","primaryAction","chip","secondaryAction","gridTemplateColumns","p","margin","bodyLabel","headingLabel","ThemePreviewField","props","field","path","baseThemePresets","admin","custom","themePresets","runtimeThemePresets","reduce","acc","preset","name","label","lightMode","darkMode","fallbackTheme","value","selectedTheme","setValue","dispatchFields","formFields","formState","hasAppliedInitialPresetRef","applyPreset","presetName","forEach","key","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","highlightSwatches","fieldLabel","en","cs","marginBottom","flex","minWidth","maxWidth","className","entries","map","isSelected","swatches","colorKey","filter","v","onClick","aria-hidden","index","marginTop","swatchValue","width","height","description","position","top","alignSelf","maxHeight","overflowY","livePreview","smallTitle","preview","customPalette"],"mappings":"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"}
|
|
@@ -109,7 +109,7 @@ export declare function getThemeFontFamilies(config: ThemeConfig): {
|
|
|
109
109
|
* Use this to inject font CSS variables into your app
|
|
110
110
|
*/
|
|
111
111
|
export declare function ThemeFontProvider({ children, bodyFont, headingFont, bodyFontCustom, headingFontCustom, }: {
|
|
112
|
-
children: React.ReactNode;
|
|
112
|
+
children: React.ReactNode | any;
|
|
113
113
|
bodyFont?: string;
|
|
114
114
|
headingFont?: string;
|
|
115
115
|
bodyFontCustom?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"font-loader.d.ts","sourceRoot":"","sources":["../../src/providers/font-loader.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAyChF,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA+B7D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAkBA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,cAAc,EACd,iBAAiB,GAClB,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"font-loader.d.ts","sourceRoot":"","sources":["../../src/providers/font-loader.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAyChF,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA+B7D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAkBA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,cAAc,EACd,iBAAiB,GAClB,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,GAAG,GAAG,CAAA;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,+BAeA;AAED;;;GAGG;AACH,wBAAgB,aAAa;;;EAY5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/font-loader.tsx"],"sourcesContent":["/**\n * Next.js Font Loader Utilities\n *\n * This file provides utilities for loading Google Fonts in Next.js applications\n * based on theme configuration from the CMS.\n *\n * ## Usage Guide\n *\n * ### 1. Static Font Loading (Recommended)\n *\n * In your Next.js app's root layout:\n *\n * ```tsx\n * // app/layout.tsx\n * import { Inter, Playfair_Display } from 'next/font/google'\n *\n * const inter = Inter({\n * subsets: ['latin'],\n * variable: '--font-body',\n * display: 'swap',\n * })\n *\n * const playfair = Playfair_Display({\n * subsets: ['latin'],\n * variable: '--font-heading',\n * display: 'swap',\n * })\n *\n * export default function RootLayout({ children }: { children: React.ReactNode }) {\n * return (\n * <html lang=\"en\" className={`${inter.variable} ${playfair.variable}`}>\n * <body>{children}</body>\n * </html>\n * )\n * }\n * ```\n *\n * ### 2. CSS Variables Usage\n *\n * In your global CSS:\n *\n * ```css\n * :root {\n * --font-body: var(--font-inter), system-ui, sans-serif;\n * --font-heading: var(--font-playfair), Georgia, serif;\n * }\n *\n * body {\n * font-family: var(--font-body);\n * }\n *\n * h1, h2, h3, h4, h5, h6 {\n * font-family: var(--font-heading);\n * }\n * ```\n *\n * ### 3. Dynamic Font Loading\n *\n * Use the helper functions below to generate font loader code:\n *\n * ```tsx\n * import { getFontLoaderCode } from '@kilivi/payloadcms-theme-management/providers/font-loader'\n *\n * const themeConfig = await getThemeConfig()\n * const fontCode = getFontLoaderCode(themeConfig)\n * console.log(fontCode) // Copy this to your layout.tsx\n * ```\n */\n\ninterface ThemeConfig {\n bodyFont?: string\n headingFont?: string\n bodyFontCustom?: string\n headingFontCustom?: string\n}\n\n/**\n * Font mapping for next/font/google imports\n * Maps theme font values to Next.js font imports\n */\nexport const FONT_IMPORT_MAP: Record<string, { import: string; variable: string }> = {\n Inter: {\n import: `import { Inter } from 'next/font/google'\\nconst inter = Inter({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'inter.variable',\n },\n Roboto: {\n import: `import { Roboto } from 'next/font/google'\\nconst roboto = Roboto({ weight: ['400', '500', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'roboto.variable',\n },\n 'Open Sans': {\n import: `import { Open_Sans } from 'next/font/google'\\nconst openSans = Open_Sans({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'openSans.variable',\n },\n Lato: {\n import: `import { Lato } from 'next/font/google'\\nconst lato = Lato({ weight: ['400', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'lato.variable',\n },\n Montserrat: {\n import: `import { Montserrat } from 'next/font/google'\\nconst montserrat = Montserrat({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'montserrat.variable',\n },\n Poppins: {\n import: `import { Poppins } from 'next/font/google'\\nconst poppins = Poppins({ weight: ['400', '500', '600', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'poppins.variable',\n },\n 'Playfair Display': {\n import: `import { Playfair_Display } from 'next/font/google'\\nconst playfair = Playfair_Display({ subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'playfair.variable',\n },\n Merriweather: {\n import: `import { Merriweather } from 'next/font/google'\\nconst merriweather = Merriweather({ weight: ['400', '700'], subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'merriweather.variable',\n },\n Lora: {\n import: `import { Lora } from 'next/font/google'\\nconst lora = Lora({ subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'lora.variable',\n },\n 'Crimson Text': {\n import: `import { Crimson_Text } from 'next/font/google'\\nconst crimsonText = Crimson_Text({ weight: ['400', '600', '700'], subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'crimsonText.variable',\n },\n}\n\n/**\n * Generate Next.js font loader code for your layout\n *\n * @param config - Theme configuration from CMS\n * @returns String with complete Next.js font loading code\n *\n * @example\n * ```tsx\n * const code = getFontLoaderCode({ bodyFont: 'Inter', headingFont: 'Playfair Display' })\n * console.log(code)\n * // Copy the output to your app/layout.tsx file\n * ```\n */\nexport function getFontLoaderCode(config: ThemeConfig): string {\n const imports: string[] = []\n const variables: string[] = []\n\n if (config.bodyFont && config.bodyFont !== 'preset' && config.bodyFont !== 'custom') {\n const fontConfig = FONT_IMPORT_MAP[config.bodyFont]\n if (fontConfig) {\n imports.push(fontConfig.import)\n variables.push(fontConfig.variable)\n }\n }\n\n if (config.headingFont && config.headingFont !== 'preset' && config.headingFont !== 'custom') {\n const fontConfig = FONT_IMPORT_MAP[config.headingFont]\n if (fontConfig) {\n imports.push(fontConfig.import)\n variables.push(fontConfig.variable)\n }\n }\n\n return `// app/layout.tsx\n${imports.join('\\n\\n')}\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n return (\n <html lang=\"en\" className={\\`${variables.join(' ')}\\`}>\n <body>{children}</body>\n </html>\n )\n}\n`\n}\n\n/**\n * Get font family CSS strings for inline styles\n *\n * @param config - Theme configuration\n * @returns Object with bodyFont and headingFont CSS font-family strings\n */\nexport function getThemeFontFamilies(config: ThemeConfig): {\n bodyFont?: string\n headingFont?: string\n} {\n const result: { bodyFont?: string; headingFont?: string } = {}\n\n // Body font\n if (config.bodyFont === 'custom' && config.bodyFontCustom) {\n result.bodyFont = config.bodyFontCustom\n } else if (config.bodyFont && config.bodyFont !== 'preset') {\n result.bodyFont = `var(--font-body), ${config.bodyFont}, sans-serif`\n }\n\n // Heading font\n if (config.headingFont === 'custom' && config.headingFontCustom) {\n result.headingFont = config.headingFontCustom\n } else if (config.headingFont && config.headingFont !== 'preset') {\n result.headingFont = `var(--font-heading), ${config.headingFont}, serif`\n }\n\n return result\n}\n\n/**\n * React component wrapper for font variables\n * Use this to inject font CSS variables into your app\n */\nexport function ThemeFontProvider({\n children,\n bodyFont,\n headingFont,\n bodyFontCustom,\n headingFontCustom,\n}: {\n children: React.ReactNode\n bodyFont?: string\n headingFont?: string\n bodyFontCustom?: string\n headingFontCustom?: string\n}) {\n const fonts = getThemeFontFamilies({ bodyFont, headingFont, bodyFontCustom, headingFontCustom })\n\n return (\n <div\n style={\n {\n '--font-body': fonts.bodyFont,\n '--font-heading': fonts.headingFont,\n } as React.CSSProperties\n }\n >\n {children}\n </div>\n )\n}\n\n/**\n * Client-side hook for accessing theme fonts\n * Use this in client components to read font CSS variables\n */\nexport function useThemeFonts() {\n if (typeof window === 'undefined') {\n return { bodyFont: undefined, headingFont: undefined }\n }\n\n const bodyFont = getComputedStyle(document.documentElement).getPropertyValue('--font-body')\n const headingFont = getComputedStyle(document.documentElement).getPropertyValue('--font-heading')\n\n return {\n bodyFont: bodyFont || undefined,\n headingFont: headingFont || undefined,\n }\n}\n"],"names":["FONT_IMPORT_MAP","Inter","import","variable","Roboto","Lato","Montserrat","Poppins","Merriweather","Lora","getFontLoaderCode","config","imports","variables","bodyFont","fontConfig","push","headingFont","join","getThemeFontFamilies","result","bodyFontCustom","headingFontCustom","ThemeFontProvider","children","fonts","div","style","useThemeFonts","window","undefined","getComputedStyle","document","documentElement","getPropertyValue"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/font-loader.tsx"],"sourcesContent":["/**\n * Next.js Font Loader Utilities\n *\n * This file provides utilities for loading Google Fonts in Next.js applications\n * based on theme configuration from the CMS.\n *\n * ## Usage Guide\n *\n * ### 1. Static Font Loading (Recommended)\n *\n * In your Next.js app's root layout:\n *\n * ```tsx\n * // app/layout.tsx\n * import { Inter, Playfair_Display } from 'next/font/google'\n *\n * const inter = Inter({\n * subsets: ['latin'],\n * variable: '--font-body',\n * display: 'swap',\n * })\n *\n * const playfair = Playfair_Display({\n * subsets: ['latin'],\n * variable: '--font-heading',\n * display: 'swap',\n * })\n *\n * export default function RootLayout({ children }: { children: React.ReactNode }) {\n * return (\n * <html lang=\"en\" className={`${inter.variable} ${playfair.variable}`}>\n * <body>{children}</body>\n * </html>\n * )\n * }\n * ```\n *\n * ### 2. CSS Variables Usage\n *\n * In your global CSS:\n *\n * ```css\n * :root {\n * --font-body: var(--font-inter), system-ui, sans-serif;\n * --font-heading: var(--font-playfair), Georgia, serif;\n * }\n *\n * body {\n * font-family: var(--font-body);\n * }\n *\n * h1, h2, h3, h4, h5, h6 {\n * font-family: var(--font-heading);\n * }\n * ```\n *\n * ### 3. Dynamic Font Loading\n *\n * Use the helper functions below to generate font loader code:\n *\n * ```tsx\n * import { getFontLoaderCode } from '@kilivi/payloadcms-theme-management/providers/font-loader'\n *\n * const themeConfig = await getThemeConfig()\n * const fontCode = getFontLoaderCode(themeConfig)\n * console.log(fontCode) // Copy this to your layout.tsx\n * ```\n */\n\ninterface ThemeConfig {\n bodyFont?: string\n headingFont?: string\n bodyFontCustom?: string\n headingFontCustom?: string\n}\n\n/**\n * Font mapping for next/font/google imports\n * Maps theme font values to Next.js font imports\n */\nexport const FONT_IMPORT_MAP: Record<string, { import: string; variable: string }> = {\n Inter: {\n import: `import { Inter } from 'next/font/google'\\nconst inter = Inter({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'inter.variable',\n },\n Roboto: {\n import: `import { Roboto } from 'next/font/google'\\nconst roboto = Roboto({ weight: ['400', '500', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'roboto.variable',\n },\n 'Open Sans': {\n import: `import { Open_Sans } from 'next/font/google'\\nconst openSans = Open_Sans({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'openSans.variable',\n },\n Lato: {\n import: `import { Lato } from 'next/font/google'\\nconst lato = Lato({ weight: ['400', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'lato.variable',\n },\n Montserrat: {\n import: `import { Montserrat } from 'next/font/google'\\nconst montserrat = Montserrat({ subsets: ['latin'], variable: '--font-body' })`,\n variable: 'montserrat.variable',\n },\n Poppins: {\n import: `import { Poppins } from 'next/font/google'\\nconst poppins = Poppins({ weight: ['400', '500', '600', '700'], subsets: ['latin'], variable: '--font-body' })`,\n variable: 'poppins.variable',\n },\n 'Playfair Display': {\n import: `import { Playfair_Display } from 'next/font/google'\\nconst playfair = Playfair_Display({ subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'playfair.variable',\n },\n Merriweather: {\n import: `import { Merriweather } from 'next/font/google'\\nconst merriweather = Merriweather({ weight: ['400', '700'], subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'merriweather.variable',\n },\n Lora: {\n import: `import { Lora } from 'next/font/google'\\nconst lora = Lora({ subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'lora.variable',\n },\n 'Crimson Text': {\n import: `import { Crimson_Text } from 'next/font/google'\\nconst crimsonText = Crimson_Text({ weight: ['400', '600', '700'], subsets: ['latin'], variable: '--font-heading' })`,\n variable: 'crimsonText.variable',\n },\n}\n\n/**\n * Generate Next.js font loader code for your layout\n *\n * @param config - Theme configuration from CMS\n * @returns String with complete Next.js font loading code\n *\n * @example\n * ```tsx\n * const code = getFontLoaderCode({ bodyFont: 'Inter', headingFont: 'Playfair Display' })\n * console.log(code)\n * // Copy the output to your app/layout.tsx file\n * ```\n */\nexport function getFontLoaderCode(config: ThemeConfig): string {\n const imports: string[] = []\n const variables: string[] = []\n\n if (config.bodyFont && config.bodyFont !== 'preset' && config.bodyFont !== 'custom') {\n const fontConfig = FONT_IMPORT_MAP[config.bodyFont]\n if (fontConfig) {\n imports.push(fontConfig.import)\n variables.push(fontConfig.variable)\n }\n }\n\n if (config.headingFont && config.headingFont !== 'preset' && config.headingFont !== 'custom') {\n const fontConfig = FONT_IMPORT_MAP[config.headingFont]\n if (fontConfig) {\n imports.push(fontConfig.import)\n variables.push(fontConfig.variable)\n }\n }\n\n return `// app/layout.tsx\n${imports.join('\\n\\n')}\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n return (\n <html lang=\"en\" className={\\`${variables.join(' ')}\\`}>\n <body>{children}</body>\n </html>\n )\n}\n`\n}\n\n/**\n * Get font family CSS strings for inline styles\n *\n * @param config - Theme configuration\n * @returns Object with bodyFont and headingFont CSS font-family strings\n */\nexport function getThemeFontFamilies(config: ThemeConfig): {\n bodyFont?: string\n headingFont?: string\n} {\n const result: { bodyFont?: string; headingFont?: string } = {}\n\n // Body font\n if (config.bodyFont === 'custom' && config.bodyFontCustom) {\n result.bodyFont = config.bodyFontCustom\n } else if (config.bodyFont && config.bodyFont !== 'preset') {\n result.bodyFont = `var(--font-body), ${config.bodyFont}, sans-serif`\n }\n\n // Heading font\n if (config.headingFont === 'custom' && config.headingFontCustom) {\n result.headingFont = config.headingFontCustom\n } else if (config.headingFont && config.headingFont !== 'preset') {\n result.headingFont = `var(--font-heading), ${config.headingFont}, serif`\n }\n\n return result\n}\n\n/**\n * React component wrapper for font variables\n * Use this to inject font CSS variables into your app\n */\nexport function ThemeFontProvider({\n children,\n bodyFont,\n headingFont,\n bodyFontCustom,\n headingFontCustom,\n}: {\n children: React.ReactNode | any\n bodyFont?: string\n headingFont?: string\n bodyFontCustom?: string\n headingFontCustom?: string\n}) {\n const fonts = getThemeFontFamilies({ bodyFont, headingFont, bodyFontCustom, headingFontCustom })\n\n return (\n <div\n style={\n {\n '--font-body': fonts.bodyFont,\n '--font-heading': fonts.headingFont,\n } as React.CSSProperties\n }\n >\n {children}\n </div>\n )\n}\n\n/**\n * Client-side hook for accessing theme fonts\n * Use this in client components to read font CSS variables\n */\nexport function useThemeFonts() {\n if (typeof window === 'undefined') {\n return { bodyFont: undefined, headingFont: undefined }\n }\n\n const bodyFont = getComputedStyle(document.documentElement).getPropertyValue('--font-body')\n const headingFont = getComputedStyle(document.documentElement).getPropertyValue('--font-heading')\n\n return {\n bodyFont: bodyFont || undefined,\n headingFont: headingFont || undefined,\n }\n}\n"],"names":["FONT_IMPORT_MAP","Inter","import","variable","Roboto","Lato","Montserrat","Poppins","Merriweather","Lora","getFontLoaderCode","config","imports","variables","bodyFont","fontConfig","push","headingFont","join","getThemeFontFamilies","result","bodyFontCustom","headingFontCustom","ThemeFontProvider","children","fonts","div","style","useThemeFonts","window","undefined","getComputedStyle","document","documentElement","getPropertyValue"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/jest-axe.d.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/payload-ui.d.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kilivi/payloadcms-theme-management",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Theme configuration plugin for Payload CMS v3 with 60+ professional themes and standalone collection support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -52,6 +52,18 @@
|
|
|
52
52
|
],
|
|
53
53
|
"author": "Kilián Vít",
|
|
54
54
|
"license": "MIT",
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/your-org/payload-plugins.git",
|
|
58
|
+
"directory": "packages/theme-management"
|
|
59
|
+
},
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/your-org/payload-plugins/issues"
|
|
62
|
+
},
|
|
63
|
+
"homepage": "https://github.com/your-org/payload-plugins/packages/theme-management#readme",
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=18.20.0"
|
|
66
|
+
},
|
|
55
67
|
"peerDependencies": {
|
|
56
68
|
"payload": "^3.0.0",
|
|
57
69
|
"@payloadcms/ui": "^3.0.0",
|
|
@@ -69,7 +81,7 @@
|
|
|
69
81
|
"@testing-library/user-event": "^14.5.2",
|
|
70
82
|
"@types/jest": "^30.0.0",
|
|
71
83
|
"@types/node": "^22.0.0",
|
|
72
|
-
"@types/react": "^
|
|
84
|
+
"@types/react": "^19.2.1",
|
|
73
85
|
"@vitejs/plugin-react": "^5.0.4",
|
|
74
86
|
"@vitest/browser": "^3.2.4",
|
|
75
87
|
"@vitest/ui": "^3.2.4",
|
|
@@ -89,7 +101,12 @@
|
|
|
89
101
|
"typescript": "^5.5.3",
|
|
90
102
|
"vite-plugin-commonjs": "^0.10.4",
|
|
91
103
|
"vite-plugin-static-copy": "^3.1.3",
|
|
92
|
-
"vitest": "^3.2.4"
|
|
104
|
+
"vitest": "^3.2.4",
|
|
105
|
+
"standard-version": "^9.5.0",
|
|
106
|
+
"@commitlint/cli": "^20.2.0",
|
|
107
|
+
"@commitlint/config-conventional": "^20.2.0",
|
|
108
|
+
"husky": "^9.1.7",
|
|
109
|
+
"jest-axe": "^10.0.0"
|
|
93
110
|
},
|
|
94
111
|
"publishConfig": {
|
|
95
112
|
"access": "public"
|
|
@@ -116,6 +133,7 @@
|
|
|
116
133
|
"test:coverage:jest": "jest --coverage",
|
|
117
134
|
"test:e2e": "playwright test",
|
|
118
135
|
"lint": "eslint src",
|
|
119
|
-
"lint:fix": "eslint --fix --ext .ts,.tsx src"
|
|
136
|
+
"lint:fix": "eslint --fix --ext .ts,.tsx src",
|
|
137
|
+
"release": "standard-version"
|
|
120
138
|
}
|
|
121
139
|
}
|