@kilivi/payloadcms-theme-management 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ServerThemeInjector.d.ts +1 -1
- package/dist/components/ServerThemeInjector.d.ts.map +1 -1
- package/dist/components/{ServerThemeInjector.jsx → ServerThemeInjector.js} +47 -34
- package/dist/components/ServerThemeInjector.js.map +1 -0
- package/dist/components/ThemePreview.js +318 -0
- package/dist/components/ThemePreview.js.map +1 -0
- package/dist/components/typographyPreviewUtils.js +12 -17
- package/dist/components/typographyPreviewUtils.js.map +1 -1
- package/dist/constants/themeFonts.js +94 -24
- package/dist/constants/themeFonts.js.map +1 -1
- package/dist/fields/ColorPickerField.js +332 -0
- package/dist/fields/ColorPickerField.js.map +1 -0
- package/dist/fields/RadiusField.js +174 -0
- package/dist/fields/RadiusField.js.map +1 -0
- package/dist/fields/ThemeColorPickerField.js +163 -0
- package/dist/fields/ThemeColorPickerField.js.map +1 -0
- package/dist/fields/ThemePreviewField.js +558 -0
- package/dist/fields/ThemePreviewField.js.map +1 -0
- package/dist/fields/ThemeTokenSelectField.js +209 -0
- package/dist/fields/ThemeTokenSelectField.js.map +1 -0
- package/dist/fields/colorModeFields.js +167 -73
- package/dist/fields/colorModeFields.js.map +1 -1
- package/dist/fields/themeConfigurationField.d.ts +1 -1
- package/dist/fields/themeConfigurationField.d.ts.map +1 -1
- package/dist/fields/themeConfigurationField.js +224 -131
- package/dist/fields/themeConfigurationField.js.map +1 -1
- package/dist/index.d.ts +17 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -52
- package/dist/index.js.map +1 -1
- package/dist/payload-types.js +2 -2
- package/dist/payload-types.js.map +1 -1
- package/dist/plugin.d.ts +1 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +2 -1
- package/dist/plugin.js.map +1 -1
- package/dist/presets.js +66 -65
- package/dist/presets.js.map +1 -1
- package/dist/providers/Theme/index.d.ts +1 -1
- package/dist/providers/Theme/index.d.ts.map +1 -1
- package/dist/providers/Theme/{index.jsx → index.js} +61 -31
- package/dist/providers/Theme/index.js.map +1 -0
- package/dist/providers/Theme/shared.d.ts +1 -1
- package/dist/providers/Theme/shared.d.ts.map +1 -1
- package/dist/providers/Theme/shared.js +34 -9
- package/dist/providers/Theme/shared.js.map +1 -1
- package/dist/providers/Theme/themeConfig.d.ts +1 -1
- package/dist/providers/Theme/themeConfig.d.ts.map +1 -1
- package/dist/providers/Theme/themeConfig.js +37 -36
- package/dist/providers/Theme/themeConfig.js.map +1 -1
- package/dist/providers/Theme/types.js +15 -13
- package/dist/providers/Theme/types.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -2
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/resolveThemeConfiguration.d.ts +3 -3
- package/dist/utils/resolveThemeConfiguration.d.ts.map +1 -1
- package/dist/utils/resolveThemeConfiguration.js +53 -34
- package/dist/utils/resolveThemeConfiguration.js.map +1 -1
- package/dist/utils/themeAssets.d.ts +1 -1
- package/dist/utils/themeAssets.d.ts.map +1 -1
- package/dist/utils/themeAssets.js +4 -4
- package/dist/utils/themeAssets.js.map +1 -1
- package/dist/utils/themeColors.js +95 -41
- package/dist/utils/themeColors.js.map +1 -1
- package/dist/utils/themeUtils.d.ts +2 -2
- package/dist/utils/themeUtils.d.ts.map +1 -1
- package/dist/utils/themeUtils.js +32 -47
- package/dist/utils/themeUtils.js.map +1 -1
- package/package.json +13 -5
- package/dist/components/ServerThemeInjector.jsx.map +0 -1
- package/dist/components/ThemePreview.jsx +0 -231
- package/dist/components/ThemePreview.jsx.map +0 -1
- package/dist/fields/ColorPickerField.jsx +0 -205
- package/dist/fields/ColorPickerField.jsx.map +0 -1
- package/dist/fields/RadiusField.jsx +0 -123
- package/dist/fields/RadiusField.jsx.map +0 -1
- package/dist/fields/ThemeColorPickerField.jsx +0 -110
- package/dist/fields/ThemeColorPickerField.jsx.map +0 -1
- package/dist/fields/ThemePreviewField.jsx +0 -420
- package/dist/fields/ThemePreviewField.jsx.map +0 -1
- package/dist/fields/ThemeTokenSelectField.jsx +0 -151
- package/dist/fields/ThemeTokenSelectField.jsx.map +0 -1
- package/dist/providers/Theme/index.jsx.map +0 -1
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useField } from '@payloadcms/ui';
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
import { borderRadiusPresets } from '../providers/Theme/themeConfig.js';
|
|
6
|
+
export default function RadiusField({ field, ...props }) {
|
|
7
|
+
const { value, setValue } = useField({
|
|
8
|
+
path: props.path
|
|
9
|
+
});
|
|
10
|
+
const label = typeof field.label === 'string' ? field.label : '';
|
|
11
|
+
const radiusOptions = useMemo(()=>{
|
|
12
|
+
const entries = Object.entries(borderRadiusPresets);
|
|
13
|
+
return entries.map(([key, preset])=>({
|
|
14
|
+
key,
|
|
15
|
+
label: preset.label,
|
|
16
|
+
css: preset.css
|
|
17
|
+
}));
|
|
18
|
+
}, []);
|
|
19
|
+
const fallbackKey = radiusOptions[2]?.key ?? radiusOptions[0]?.key ?? 'medium';
|
|
20
|
+
const currentKey = typeof value === 'string' && value in borderRadiusPresets ? value : fallbackKey;
|
|
21
|
+
const description = typeof field.admin?.description === 'string' ? field.admin.description : field.admin?.description?.en || field.admin?.description?.cs || null;
|
|
22
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
23
|
+
className: "field-type",
|
|
24
|
+
children: [
|
|
25
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
26
|
+
className: "field-label",
|
|
27
|
+
htmlFor: props.path,
|
|
28
|
+
children: [
|
|
29
|
+
label,
|
|
30
|
+
field.required && /*#__PURE__*/ _jsx("span", {
|
|
31
|
+
className: "required",
|
|
32
|
+
children: "*"
|
|
33
|
+
})
|
|
34
|
+
]
|
|
35
|
+
}),
|
|
36
|
+
description && /*#__PURE__*/ _jsx("p", {
|
|
37
|
+
style: {
|
|
38
|
+
marginTop: '4px',
|
|
39
|
+
fontSize: '12px',
|
|
40
|
+
lineHeight: 1.5,
|
|
41
|
+
color: 'var(--theme-elevation-600)'
|
|
42
|
+
},
|
|
43
|
+
children: description
|
|
44
|
+
}),
|
|
45
|
+
/*#__PURE__*/ _jsx("div", {
|
|
46
|
+
style: {
|
|
47
|
+
display: 'grid',
|
|
48
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))',
|
|
49
|
+
gap: '16px',
|
|
50
|
+
marginTop: '16px'
|
|
51
|
+
},
|
|
52
|
+
children: radiusOptions.map((option)=>{
|
|
53
|
+
const isSelected = option.key === currentKey;
|
|
54
|
+
const cardRadius = option.css['--radius-large'] ?? option.css['--radius-default'] ?? option.css['--radius-medium'];
|
|
55
|
+
const chipRadius = option.css['--radius-default'] ?? option.css['--radius-small'];
|
|
56
|
+
const pillRadius = option.css['--radius-xl'] ?? option.css['--radius-large'] ?? '999px';
|
|
57
|
+
return /*#__PURE__*/ _jsxs("button", {
|
|
58
|
+
type: "button",
|
|
59
|
+
onClick: ()=>setValue(option.key),
|
|
60
|
+
"aria-pressed": isSelected,
|
|
61
|
+
style: {
|
|
62
|
+
border: isSelected ? '2px solid var(--theme-success-500)' : '1px solid var(--theme-elevation-150)',
|
|
63
|
+
borderRadius: '14px',
|
|
64
|
+
backgroundColor: 'var(--theme-elevation-25)',
|
|
65
|
+
padding: '16px',
|
|
66
|
+
display: 'grid',
|
|
67
|
+
gap: '10px',
|
|
68
|
+
textAlign: 'left',
|
|
69
|
+
cursor: 'pointer',
|
|
70
|
+
transition: 'border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease',
|
|
71
|
+
boxShadow: isSelected ? '0 10px 20px rgba(34, 197, 94, 0.18)' : '0 6px 18px rgba(15, 23, 42, 0.08)',
|
|
72
|
+
transform: isSelected ? 'translateY(-2px)' : 'translateY(0)'
|
|
73
|
+
},
|
|
74
|
+
children: [
|
|
75
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
76
|
+
style: {
|
|
77
|
+
display: 'flex',
|
|
78
|
+
alignItems: 'center',
|
|
79
|
+
justifyContent: 'space-between',
|
|
80
|
+
fontWeight: 600,
|
|
81
|
+
fontSize: '13px',
|
|
82
|
+
color: 'var(--theme-elevation-800)'
|
|
83
|
+
},
|
|
84
|
+
children: [
|
|
85
|
+
/*#__PURE__*/ _jsx("span", {
|
|
86
|
+
children: option.label
|
|
87
|
+
}),
|
|
88
|
+
/*#__PURE__*/ _jsx("span", {
|
|
89
|
+
style: {
|
|
90
|
+
fontSize: '11px',
|
|
91
|
+
opacity: 0.7
|
|
92
|
+
},
|
|
93
|
+
children: option.key
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
}),
|
|
97
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
98
|
+
style: {
|
|
99
|
+
display: 'grid',
|
|
100
|
+
gap: '10px'
|
|
101
|
+
},
|
|
102
|
+
children: [
|
|
103
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
104
|
+
style: {
|
|
105
|
+
display: 'flex',
|
|
106
|
+
gap: '8px',
|
|
107
|
+
alignItems: 'center'
|
|
108
|
+
},
|
|
109
|
+
children: [
|
|
110
|
+
/*#__PURE__*/ _jsx("div", {
|
|
111
|
+
style: {
|
|
112
|
+
width: '50px',
|
|
113
|
+
height: '34px',
|
|
114
|
+
backgroundColor: 'var(--theme-elevation-100)',
|
|
115
|
+
border: '1px solid var(--theme-elevation-200)',
|
|
116
|
+
borderRadius: cardRadius ?? '0'
|
|
117
|
+
}
|
|
118
|
+
}),
|
|
119
|
+
/*#__PURE__*/ _jsx("div", {
|
|
120
|
+
style: {
|
|
121
|
+
flex: 1,
|
|
122
|
+
height: '14px',
|
|
123
|
+
backgroundColor: 'var(--theme-primary-500)',
|
|
124
|
+
borderRadius: pillRadius
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
]
|
|
128
|
+
}),
|
|
129
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
130
|
+
style: {
|
|
131
|
+
display: 'flex',
|
|
132
|
+
gap: '6px',
|
|
133
|
+
flexWrap: 'wrap',
|
|
134
|
+
fontSize: '11px',
|
|
135
|
+
color: 'var(--theme-elevation-600)'
|
|
136
|
+
},
|
|
137
|
+
children: [
|
|
138
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
139
|
+
children: [
|
|
140
|
+
"Card ",
|
|
141
|
+
cardRadius ?? '—'
|
|
142
|
+
]
|
|
143
|
+
}),
|
|
144
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
145
|
+
children: [
|
|
146
|
+
"Chip ",
|
|
147
|
+
chipRadius ?? '—'
|
|
148
|
+
]
|
|
149
|
+
}),
|
|
150
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
151
|
+
children: [
|
|
152
|
+
"Pill ",
|
|
153
|
+
pillRadius
|
|
154
|
+
]
|
|
155
|
+
})
|
|
156
|
+
]
|
|
157
|
+
})
|
|
158
|
+
]
|
|
159
|
+
})
|
|
160
|
+
]
|
|
161
|
+
}, option.key);
|
|
162
|
+
})
|
|
163
|
+
}),
|
|
164
|
+
/*#__PURE__*/ _jsx("input", {
|
|
165
|
+
type: "hidden",
|
|
166
|
+
id: props.path,
|
|
167
|
+
value: currentKey,
|
|
168
|
+
readOnly: true
|
|
169
|
+
})
|
|
170
|
+
]
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
//# sourceMappingURL=RadiusField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/fields/RadiusField.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport type { SelectFieldClientProps } from 'payload'\nimport { useMemo } from 'react'\nimport { borderRadiusPresets } from '../providers/Theme/themeConfig.js'\n\ntype RadiusPresetKey = Extract<keyof typeof borderRadiusPresets, string>\n\ninterface RadiusOptionCard {\n key: RadiusPresetKey\n label: string\n css: Record<string, string>\n}\n\nexport default function RadiusField({ field, ...props }: SelectFieldClientProps) {\n const { value, setValue } = useField<string>({ path: props.path })\n const label = typeof field.label === 'string' ? field.label : ''\n\n const radiusOptions = useMemo<RadiusOptionCard[]>(() => {\n const entries = Object.entries(borderRadiusPresets) as Array<\n [RadiusPresetKey, (typeof borderRadiusPresets)[RadiusPresetKey]]\n >\n return entries.map(([key, preset]) => ({\n key,\n label: preset.label,\n css: preset.css,\n }))\n }, [])\n\n const fallbackKey: RadiusPresetKey = radiusOptions[2]?.key ?? radiusOptions[0]?.key ?? 'medium'\n const currentKey =\n typeof value === 'string' && value in borderRadiusPresets\n ? (value as RadiusPresetKey)\n : fallbackKey\n\n const description =\n typeof field.admin?.description === 'string'\n ? field.admin.description\n : field.admin?.description?.en || field.admin?.description?.cs || null\n\n return (\n <div className=\"field-type\">\n <label className=\"field-label\" htmlFor={props.path}>\n {label}\n {field.required && <span className=\"required\">*</span>}\n </label>\n\n {description && (\n <p\n style={{\n marginTop: '4px',\n fontSize: '12px',\n lineHeight: 1.5,\n color: 'var(--theme-elevation-600)',\n }}\n >\n {description}\n </p>\n )}\n\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))',\n gap: '16px',\n marginTop: '16px',\n }}\n >\n {radiusOptions.map((option) => {\n const isSelected = option.key === currentKey\n const cardRadius =\n option.css['--radius-large'] ??\n option.css['--radius-default'] ??\n option.css['--radius-medium']\n const chipRadius = option.css['--radius-default'] ?? option.css['--radius-small']\n const pillRadius = option.css['--radius-xl'] ?? option.css['--radius-large'] ?? '999px'\n\n return (\n <button\n key={option.key}\n type=\"button\"\n onClick={() => setValue(option.key)}\n aria-pressed={isSelected}\n style={{\n border: isSelected\n ? '2px solid var(--theme-success-500)'\n : '1px solid var(--theme-elevation-150)',\n borderRadius: '14px',\n backgroundColor: 'var(--theme-elevation-25)',\n padding: '16px',\n display: 'grid',\n gap: '10px',\n textAlign: 'left',\n cursor: 'pointer',\n transition: 'border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease',\n boxShadow: isSelected\n ? '0 10px 20px rgba(34, 197, 94, 0.18)'\n : '0 6px 18px rgba(15, 23, 42, 0.08)',\n transform: isSelected ? 'translateY(-2px)' : 'translateY(0)',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontWeight: 600,\n fontSize: '13px',\n color: 'var(--theme-elevation-800)',\n }}\n >\n <span>{option.label}</span>\n <span style={{ fontSize: '11px', opacity: 0.7 }}>{option.key}</span>\n </div>\n\n <div\n style={{\n display: 'grid',\n gap: '10px',\n }}\n >\n <div\n style={{\n display: 'flex',\n gap: '8px',\n alignItems: 'center',\n }}\n >\n <div\n style={{\n width: '50px',\n height: '34px',\n backgroundColor: 'var(--theme-elevation-100)',\n border: '1px solid var(--theme-elevation-200)',\n borderRadius: cardRadius ?? '0',\n }}\n />\n <div\n style={{\n flex: 1,\n height: '14px',\n backgroundColor: 'var(--theme-primary-500)',\n borderRadius: pillRadius,\n }}\n />\n </div>\n\n <div\n style={{\n display: 'flex',\n gap: '6px',\n flexWrap: 'wrap',\n fontSize: '11px',\n color: 'var(--theme-elevation-600)',\n }}\n >\n <span>Card {cardRadius ?? '—'}</span>\n <span>Chip {chipRadius ?? '—'}</span>\n <span>Pill {pillRadius}</span>\n </div>\n </div>\n </button>\n )\n })}\n </div>\n\n <input type=\"hidden\" id={props.path} value={currentKey} readOnly />\n </div>\n )\n}\n"],"names":["useField","useMemo","borderRadiusPresets","RadiusField","field","props","value","setValue","path","label","radiusOptions","entries","Object","map","key","preset","css","fallbackKey","currentKey","description","admin","en","cs","div","className","htmlFor","required","span","p","style","marginTop","fontSize","lineHeight","color","display","gridTemplateColumns","gap","option","isSelected","cardRadius","chipRadius","pillRadius","button","type","onClick","aria-pressed","border","borderRadius","backgroundColor","padding","textAlign","cursor","transition","boxShadow","transform","alignItems","justifyContent","fontWeight","opacity","width","height","flex","flexWrap","input","id","readOnly"],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useField, useFormFields } from '@payloadcms/ui';
|
|
4
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
5
|
+
import './ThemeColorPickerField.css';
|
|
6
|
+
function resolveLocalizedValue(value, fallback) {
|
|
7
|
+
if (typeof value === 'string') {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
if (typeof value === 'object' && value !== null) {
|
|
11
|
+
const localized = value;
|
|
12
|
+
const resolved = localized.en ?? localized.cs ?? localized[''];
|
|
13
|
+
if (typeof resolved === 'string') {
|
|
14
|
+
return resolved;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return fallback;
|
|
18
|
+
}
|
|
19
|
+
const ThemeColorPickerField = ({ field, path })=>{
|
|
20
|
+
const { value, setValue } = useField({
|
|
21
|
+
path
|
|
22
|
+
});
|
|
23
|
+
const [localValue, setLocalValue] = useState(value || '');
|
|
24
|
+
const allFields = useFormFields(([fields])=>fields);
|
|
25
|
+
const mode = path.includes('lightMode') ? 'lightMode' : 'darkMode';
|
|
26
|
+
const modePrefix = `themeConfiguration.${mode}`;
|
|
27
|
+
useEffect(()=>{
|
|
28
|
+
setLocalValue(value || '');
|
|
29
|
+
}, [
|
|
30
|
+
value
|
|
31
|
+
]);
|
|
32
|
+
const colorValues = useMemo(()=>{
|
|
33
|
+
if (!allFields) {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
const names = [
|
|
37
|
+
'background',
|
|
38
|
+
'foreground',
|
|
39
|
+
'card',
|
|
40
|
+
'cardForeground',
|
|
41
|
+
'popover',
|
|
42
|
+
'popoverForeground',
|
|
43
|
+
'primary',
|
|
44
|
+
'primaryForeground',
|
|
45
|
+
'secondary',
|
|
46
|
+
'secondaryForeground',
|
|
47
|
+
'muted',
|
|
48
|
+
'mutedForeground',
|
|
49
|
+
'accent',
|
|
50
|
+
'accentForeground',
|
|
51
|
+
'destructive',
|
|
52
|
+
'destructiveForeground',
|
|
53
|
+
'border',
|
|
54
|
+
'input',
|
|
55
|
+
'ring'
|
|
56
|
+
];
|
|
57
|
+
return names.reduce((accumulator, name)=>{
|
|
58
|
+
const fieldState = allFields[`${modePrefix}.${name}`];
|
|
59
|
+
const parsedValue = typeof fieldState?.value === 'string' ? fieldState.value : undefined;
|
|
60
|
+
accumulator[name] = parsedValue ?? '';
|
|
61
|
+
return accumulator;
|
|
62
|
+
}, {});
|
|
63
|
+
}, [
|
|
64
|
+
allFields,
|
|
65
|
+
modePrefix
|
|
66
|
+
]);
|
|
67
|
+
function handleChange(nextValue) {
|
|
68
|
+
setLocalValue(nextValue);
|
|
69
|
+
setValue(nextValue);
|
|
70
|
+
}
|
|
71
|
+
const fieldName = path.split('.').pop() || '';
|
|
72
|
+
const label = resolveLocalizedValue(field.label, fieldName);
|
|
73
|
+
const description = resolveLocalizedValue(field.admin?.description, '');
|
|
74
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
75
|
+
className: "theme-color-picker-field",
|
|
76
|
+
children: [
|
|
77
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
78
|
+
className: "field-header",
|
|
79
|
+
children: [
|
|
80
|
+
/*#__PURE__*/ _jsx("label", {
|
|
81
|
+
className: "field-label",
|
|
82
|
+
children: label
|
|
83
|
+
}),
|
|
84
|
+
description && /*#__PURE__*/ _jsx("div", {
|
|
85
|
+
className: "field-description",
|
|
86
|
+
children: description
|
|
87
|
+
})
|
|
88
|
+
]
|
|
89
|
+
}),
|
|
90
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
91
|
+
className: "color-picker-container",
|
|
92
|
+
children: [
|
|
93
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
94
|
+
className: "color-input-wrapper",
|
|
95
|
+
children: [
|
|
96
|
+
/*#__PURE__*/ _jsx("input", {
|
|
97
|
+
type: "color",
|
|
98
|
+
value: localValue || '#000000',
|
|
99
|
+
onChange: (event)=>handleChange(event.target.value),
|
|
100
|
+
className: "color-input"
|
|
101
|
+
}),
|
|
102
|
+
/*#__PURE__*/ _jsx("input", {
|
|
103
|
+
type: "text",
|
|
104
|
+
value: localValue || '',
|
|
105
|
+
onChange: (event)=>handleChange(event.target.value),
|
|
106
|
+
placeholder: "#000000",
|
|
107
|
+
className: "text-input",
|
|
108
|
+
pattern: "^#[0-9A-Fa-f]{6}$"
|
|
109
|
+
})
|
|
110
|
+
]
|
|
111
|
+
}),
|
|
112
|
+
/*#__PURE__*/ _jsx("div", {
|
|
113
|
+
className: "color-preview",
|
|
114
|
+
style: {
|
|
115
|
+
backgroundColor: localValue || '#000000'
|
|
116
|
+
},
|
|
117
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
118
|
+
className: "preview-label",
|
|
119
|
+
children: localValue || 'Not set'
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
]
|
|
123
|
+
}),
|
|
124
|
+
(fieldName === 'primary' || fieldName === 'background') && /*#__PURE__*/ _jsx("div", {
|
|
125
|
+
className: "mini-preview",
|
|
126
|
+
style: {
|
|
127
|
+
backgroundColor: colorValues.background || '#ffffff',
|
|
128
|
+
color: colorValues.foreground || '#000000',
|
|
129
|
+
borderColor: colorValues.border || '#e2e8f0'
|
|
130
|
+
},
|
|
131
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
132
|
+
className: "preview-card",
|
|
133
|
+
style: {
|
|
134
|
+
backgroundColor: colorValues.card || '#ffffff',
|
|
135
|
+
color: colorValues.cardForeground || '#000000',
|
|
136
|
+
borderColor: colorValues.border || '#e2e8f0'
|
|
137
|
+
},
|
|
138
|
+
children: [
|
|
139
|
+
/*#__PURE__*/ _jsx("button", {
|
|
140
|
+
className: "preview-button",
|
|
141
|
+
style: {
|
|
142
|
+
backgroundColor: colorValues.primary || '#0070f3',
|
|
143
|
+
color: colorValues.primaryForeground || '#ffffff'
|
|
144
|
+
},
|
|
145
|
+
children: "Primary Button"
|
|
146
|
+
}),
|
|
147
|
+
/*#__PURE__*/ _jsx("button", {
|
|
148
|
+
className: "preview-button secondary",
|
|
149
|
+
style: {
|
|
150
|
+
backgroundColor: colorValues.secondary || '#f1f5f9',
|
|
151
|
+
color: colorValues.secondaryForeground || '#0f172a'
|
|
152
|
+
},
|
|
153
|
+
children: "Secondary"
|
|
154
|
+
})
|
|
155
|
+
]
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
]
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
export default ThemeColorPickerField;
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=ThemeColorPickerField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/fields/ThemeColorPickerField.tsx"],"sourcesContent":["'use client'\n\nimport { useField, useFormFields } from '@payloadcms/ui'\nimport type { TextFieldClientComponent } from 'payload'\nimport { useEffect, useMemo, useState } from 'react'\nimport './ThemeColorPickerField.css'\n\nfunction resolveLocalizedValue(value: unknown, fallback: string) {\n if (typeof value === 'string') {\n return value\n }\n\n if (typeof value === 'object' && value !== null) {\n const localized = value as Record<string, unknown>\n const resolved = localized.en ?? localized.cs ?? localized['']\n if (typeof resolved === 'string') {\n return resolved\n }\n }\n\n return fallback\n}\n\nconst ThemeColorPickerField: TextFieldClientComponent = ({ field, path }) => {\n const { value, setValue } = useField<string>({ path })\n const [localValue, setLocalValue] = useState(value || '')\n const allFields = useFormFields(([fields]) => fields)\n\n const mode = path.includes('lightMode') ? 'lightMode' : 'darkMode'\n const modePrefix = `themeConfiguration.${mode}`\n\n useEffect(() => {\n setLocalValue(value || '')\n }, [value])\n\n const colorValues = useMemo(() => {\n if (!allFields) {\n return {}\n }\n\n const names = [\n 'background',\n 'foreground',\n 'card',\n 'cardForeground',\n 'popover',\n 'popoverForeground',\n 'primary',\n 'primaryForeground',\n 'secondary',\n 'secondaryForeground',\n 'muted',\n 'mutedForeground',\n 'accent',\n 'accentForeground',\n 'destructive',\n 'destructiveForeground',\n 'border',\n 'input',\n 'ring',\n ]\n\n return names.reduce<Record<string, string>>((accumulator, name) => {\n const fieldState = allFields[`${modePrefix}.${name}`]\n const parsedValue = typeof fieldState?.value === 'string' ? fieldState.value : undefined\n accumulator[name] = parsedValue ?? ''\n return accumulator\n }, {})\n }, [allFields, modePrefix])\n\n function handleChange(nextValue: string) {\n setLocalValue(nextValue)\n setValue(nextValue)\n }\n\n const fieldName = path.split('.').pop() || ''\n const label = resolveLocalizedValue(field.label, fieldName)\n const description = resolveLocalizedValue(field.admin?.description, '')\n\n return (\n <div className=\"theme-color-picker-field\">\n <div className=\"field-header\">\n <label className=\"field-label\">{label}</label>\n {description && <div className=\"field-description\">{description}</div>}\n </div>\n\n <div className=\"color-picker-container\">\n <div className=\"color-input-wrapper\">\n <input\n type=\"color\"\n value={localValue || '#000000'}\n onChange={(event) => handleChange(event.target.value)}\n className=\"color-input\"\n />\n <input\n type=\"text\"\n value={localValue || ''}\n onChange={(event) => handleChange(event.target.value)}\n placeholder=\"#000000\"\n className=\"text-input\"\n pattern=\"^#[0-9A-Fa-f]{6}$\"\n />\n </div>\n\n <div className=\"color-preview\" style={{ backgroundColor: localValue || '#000000' }}>\n <span className=\"preview-label\">{localValue || 'Not set'}</span>\n </div>\n </div>\n\n {(fieldName === 'primary' || fieldName === 'background') && (\n <div\n className=\"mini-preview\"\n style={{\n backgroundColor: colorValues.background || '#ffffff',\n color: colorValues.foreground || '#000000',\n borderColor: colorValues.border || '#e2e8f0',\n }}\n >\n <div\n className=\"preview-card\"\n style={{\n backgroundColor: colorValues.card || '#ffffff',\n color: colorValues.cardForeground || '#000000',\n borderColor: colorValues.border || '#e2e8f0',\n }}\n >\n <button\n className=\"preview-button\"\n style={{\n backgroundColor: colorValues.primary || '#0070f3',\n color: colorValues.primaryForeground || '#ffffff',\n }}\n >\n Primary Button\n </button>\n <button\n className=\"preview-button secondary\"\n style={{\n backgroundColor: colorValues.secondary || '#f1f5f9',\n color: colorValues.secondaryForeground || '#0f172a',\n }}\n >\n Secondary\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default ThemeColorPickerField\n"],"names":["useField","useFormFields","useEffect","useMemo","useState","resolveLocalizedValue","value","fallback","localized","resolved","en","cs","ThemeColorPickerField","field","path","setValue","localValue","setLocalValue","allFields","fields","mode","includes","modePrefix","colorValues","names","reduce","accumulator","name","fieldState","parsedValue","undefined","handleChange","nextValue","fieldName","split","pop","label","description","admin","div","className","input","type","onChange","event","target","placeholder","pattern","style","backgroundColor","span","background","color","foreground","borderColor","border","card","cardForeground","button","primary","primaryForeground","secondary","secondaryForeground"],"mappings":"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"}
|