@kilivi/payloadcms-theme-management 0.1.8 → 0.1.9
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 +97 -97
- package/dist/components/ServerThemeInjector.js +3 -3
- package/dist/components/ServerThemeInjector.js.map +1 -1
- package/dist/components/ThemePreview.js.map +1 -1
- package/dist/components/typographyPreviewUtils.js.map +1 -1
- package/dist/constants/themeFonts.js.map +1 -1
- package/dist/fields/ColorPickerField.js.map +1 -1
- package/dist/fields/RadiusField.js.map +1 -1
- package/dist/fields/ThemeColorPickerField.css +138 -138
- package/dist/fields/ThemeColorPickerField.js.map +1 -1
- package/dist/fields/ThemePreviewField.js.map +1 -1
- package/dist/fields/ThemeTokenSelectField.js.map +1 -1
- package/dist/fields/colorModeFields.js.map +1 -1
- package/dist/fields/themeConfigurationField.js +3 -3
- package/dist/fields/themeConfigurationField.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/payload-types.js +3 -3
- package/dist/payload-types.js.map +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/presets.js.map +1 -1
- package/dist/providers/Theme/index.js.map +1 -1
- package/dist/providers/Theme/shared.js.map +1 -1
- package/dist/providers/Theme/themeConfig.js.map +1 -1
- package/dist/providers/Theme/types.js.map +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/dist/src/--verbose/dist/fields/ThemeColorPickerField.scss +138 -0
- package/dist/src/dist/fields/ThemeColorPickerField.scss +138 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/resolveThemeConfiguration.js.map +1 -1
- package/dist/utils/themeAssets.js.map +1 -1
- package/dist/utils/themeColors.js.map +1 -1
- package/dist/utils/themeUtils.js +6 -6
- package/dist/utils/themeUtils.js.map +1 -1
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
# Theme Configuration Plugin for Payload CMS
|
|
2
|
-
|
|
3
|
-
A flexible theme configuration plugin for Payload CMS v3 that allows you to manage theme settings through the admin UI.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🎨 **Theme Management** - Configure primary and secondary colors
|
|
8
|
-
- 🔤 **Typography Control** - Set custom font families
|
|
9
|
-
- 📐 **Layout Settings** - Adjust header height and other layout properties
|
|
10
|
-
- 🌓 **Theme Switcher** - Optional theme switching capability (light/dark/auto)
|
|
11
|
-
- ⚙️ **Configurable** - Exclude specific collections or globals as needed
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install @payloadcms-plugins/theme-management
|
|
17
|
-
# or
|
|
18
|
-
yarn add @payloadcms-plugins/theme-management
|
|
19
|
-
# or
|
|
20
|
-
pnpm add @payloadcms-plugins/theme-management
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Usage
|
|
24
|
-
|
|
25
|
-
Add the plugin to your Payload config:
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
import { buildConfig } from 'payload';
|
|
29
|
-
import { ThemeConfigurationPlugin } from '@payloadcms-plugins/theme-management';
|
|
30
|
-
|
|
31
|
-
export default buildConfig({
|
|
32
|
-
// ... other config
|
|
33
|
-
plugins: [
|
|
34
|
-
ThemeConfigurationPlugin({
|
|
35
|
-
enableThemeSwitcher: true,
|
|
36
|
-
defaultTheme: 'auto',
|
|
37
|
-
excludedCollections: [], // Collections to exclude
|
|
38
|
-
excludedGlobals: [], // Globals to exclude
|
|
39
|
-
}),
|
|
40
|
-
],
|
|
41
|
-
});
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Configuration Options
|
|
45
|
-
|
|
46
|
-
### `ThemeConfigurationPluginConfig`
|
|
47
|
-
|
|
48
|
-
| Option | Type | Default | Description |
|
|
49
|
-
|--------|------|---------|-------------|
|
|
50
|
-
| `excludedCollections` | `string[]` | `[]` | Array of collection slugs to exclude |
|
|
51
|
-
| `excludedGlobals` | `string[]` | `[]` | Array of global slugs to exclude |
|
|
52
|
-
| `enableThemeSwitcher` | `boolean` | `true` | Enable theme switcher in admin UI |
|
|
53
|
-
| `defaultTheme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Default theme |
|
|
54
|
-
|
|
55
|
-
## Theme Configuration Fields
|
|
56
|
-
|
|
57
|
-
The plugin adds a global called `theme-management` with the following fields:
|
|
58
|
-
|
|
59
|
-
- **Primary Color** - Main theme color (e.g., #3B82F6)
|
|
60
|
-
- **Secondary Color** - Secondary theme color (e.g., #10B981)
|
|
61
|
-
- **Font Family** - Primary font family for the site
|
|
62
|
-
- **Header Height** - Height of the site header in pixels
|
|
63
|
-
|
|
64
|
-
## Accessing Theme Configuration
|
|
65
|
-
|
|
66
|
-
You can access the theme configuration in your application:
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
const payload = await getPayloadClient();
|
|
70
|
-
|
|
71
|
-
const themeConfig = await payload.findGlobal({
|
|
72
|
-
slug: 'theme-management',
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
console.log(themeConfig.primaryColor); // e.g., "#3B82F6"
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Development
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
# Install dependencies
|
|
82
|
-
pnpm install
|
|
83
|
-
|
|
84
|
-
# Build the plugin
|
|
85
|
-
pnpm build
|
|
86
|
-
|
|
87
|
-
# Watch mode for development
|
|
88
|
-
pnpm dev
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## License
|
|
92
|
-
|
|
93
|
-
Apache-2.0
|
|
94
|
-
|
|
95
|
-
## Contributing
|
|
96
|
-
|
|
97
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
1
|
+
# Theme Configuration Plugin for Payload CMS
|
|
2
|
+
|
|
3
|
+
A flexible theme configuration plugin for Payload CMS v3 that allows you to manage theme settings through the admin UI.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎨 **Theme Management** - Configure primary and secondary colors
|
|
8
|
+
- 🔤 **Typography Control** - Set custom font families
|
|
9
|
+
- 📐 **Layout Settings** - Adjust header height and other layout properties
|
|
10
|
+
- 🌓 **Theme Switcher** - Optional theme switching capability (light/dark/auto)
|
|
11
|
+
- ⚙️ **Configurable** - Exclude specific collections or globals as needed
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @payloadcms-plugins/theme-management
|
|
17
|
+
# or
|
|
18
|
+
yarn add @payloadcms-plugins/theme-management
|
|
19
|
+
# or
|
|
20
|
+
pnpm add @payloadcms-plugins/theme-management
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
Add the plugin to your Payload config:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { buildConfig } from 'payload';
|
|
29
|
+
import { ThemeConfigurationPlugin } from '@payloadcms-plugins/theme-management';
|
|
30
|
+
|
|
31
|
+
export default buildConfig({
|
|
32
|
+
// ... other config
|
|
33
|
+
plugins: [
|
|
34
|
+
ThemeConfigurationPlugin({
|
|
35
|
+
enableThemeSwitcher: true,
|
|
36
|
+
defaultTheme: 'auto',
|
|
37
|
+
excludedCollections: [], // Collections to exclude
|
|
38
|
+
excludedGlobals: [], // Globals to exclude
|
|
39
|
+
}),
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Configuration Options
|
|
45
|
+
|
|
46
|
+
### `ThemeConfigurationPluginConfig`
|
|
47
|
+
|
|
48
|
+
| Option | Type | Default | Description |
|
|
49
|
+
|--------|------|---------|-------------|
|
|
50
|
+
| `excludedCollections` | `string[]` | `[]` | Array of collection slugs to exclude |
|
|
51
|
+
| `excludedGlobals` | `string[]` | `[]` | Array of global slugs to exclude |
|
|
52
|
+
| `enableThemeSwitcher` | `boolean` | `true` | Enable theme switcher in admin UI |
|
|
53
|
+
| `defaultTheme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Default theme |
|
|
54
|
+
|
|
55
|
+
## Theme Configuration Fields
|
|
56
|
+
|
|
57
|
+
The plugin adds a global called `theme-management` with the following fields:
|
|
58
|
+
|
|
59
|
+
- **Primary Color** - Main theme color (e.g., #3B82F6)
|
|
60
|
+
- **Secondary Color** - Secondary theme color (e.g., #10B981)
|
|
61
|
+
- **Font Family** - Primary font family for the site
|
|
62
|
+
- **Header Height** - Height of the site header in pixels
|
|
63
|
+
|
|
64
|
+
## Accessing Theme Configuration
|
|
65
|
+
|
|
66
|
+
You can access the theme configuration in your application:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const payload = await getPayloadClient();
|
|
70
|
+
|
|
71
|
+
const themeConfig = await payload.findGlobal({
|
|
72
|
+
slug: 'theme-management',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
console.log(themeConfig.primaryColor); // e.g., "#3B82F6"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Install dependencies
|
|
82
|
+
pnpm install
|
|
83
|
+
|
|
84
|
+
# Build the plugin
|
|
85
|
+
pnpm build
|
|
86
|
+
|
|
87
|
+
# Watch mode for development
|
|
88
|
+
pnpm dev
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
Apache-2.0
|
|
94
|
+
|
|
95
|
+
## Contributing
|
|
96
|
+
|
|
97
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -4,9 +4,9 @@ import { resolveThemeConfiguration } from '../utils/resolveThemeConfiguration.js
|
|
|
4
4
|
import { createFallbackCriticalCSS, getThemeCriticalCSS, getThemeCSSPath } from '../utils/themeAssets.js';
|
|
5
5
|
import { generateThemeColorsCss } from '../utils/themeColors.js';
|
|
6
6
|
import { generateThemeCSS } from '../utils/themeUtils.js';
|
|
7
|
-
/**
|
|
8
|
-
* Server-side theme CSS injector to prevent FOUC
|
|
9
|
-
* This component injects critical theme CSS directly into the HTML head during SSR
|
|
7
|
+
/**
|
|
8
|
+
* Server-side theme CSS injector to prevent FOUC
|
|
9
|
+
* This component injects critical theme CSS directly into the HTML head during SSR
|
|
10
10
|
*/ export async function ServerThemeInjector({ siteSettings }) {
|
|
11
11
|
const resolvedConfiguration = resolveThemeConfiguration(siteSettings?.themeConfiguration);
|
|
12
12
|
const { theme, borderRadius, customCSS, lightMode, darkMode, fontScale, spacing, animationLevel, allowColorModeToggle, colorMode, typography } = resolvedConfiguration;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ServerThemeInjector.tsx"],"sourcesContent":["import type { SiteSetting } from '../payload-types.js'\nimport { getBorderRadiusConfig } from '../providers/Theme/themeConfig.js'\nimport type { BorderRadiusPreset, ThemeDefaults } from '../providers/Theme/types.js'\nimport type { ThemeTypographyPreset } from '../presets.js'\nimport { resolveThemeConfiguration } from '../utils/resolveThemeConfiguration.js'\nimport {\n createFallbackCriticalCSS,\n getThemeCriticalCSS,\n getThemeCSSPath,\n} from '../utils/themeAssets.js'\nimport { generateThemeColorsCss } from '../utils/themeColors.js'\nimport { generateThemeCSS } from '../utils/themeUtils.js'\n\ninterface ServerThemeInjectorProps {\n siteSettings: SiteSetting | null\n}\n\ntype RuntimeThemeConfiguration = Omit<NonNullable<SiteSetting['themeConfiguration']>, 'typography'> & {\n typography?: ThemeTypographyPreset | null\n}\n\n/**\n * Server-side theme CSS injector to prevent FOUC\n * This component injects critical theme CSS directly into the HTML head during SSR\n */\nexport async function ServerThemeInjector({ siteSettings }: Readonly<ServerThemeInjectorProps>) {\n const resolvedConfiguration = resolveThemeConfiguration(siteSettings?.themeConfiguration)\n const {\n theme,\n borderRadius,\n customCSS,\n lightMode,\n darkMode,\n fontScale,\n spacing,\n animationLevel,\n allowColorModeToggle,\n colorMode,\n typography,\n } = resolvedConfiguration\n\n const baseThemeConfiguration = { ...(siteSettings?.themeConfiguration ?? {}) }\n if ('typography' in baseThemeConfiguration) {\n delete (baseThemeConfiguration as Record<string, unknown>).typography\n }\n\n const normalizedThemeConfiguration: RuntimeThemeConfiguration = {\n ...baseThemeConfiguration,\n theme,\n colorMode,\n allowColorModeToggle,\n borderRadius,\n fontScale,\n spacing,\n animationLevel,\n customCSS: customCSS ?? undefined,\n lightMode,\n darkMode,\n typography: typography ?? undefined,\n }\n\n let criticalCSS = await getThemeCriticalCSS(theme as ThemeDefaults)\n criticalCSS ??= createFallbackCriticalCSS(theme as ThemeDefaults)\n\n const borderRadiusMap: Record<string, BorderRadiusPreset> = {\n none: 'none',\n small: 'small',\n medium: 'medium',\n large: 'large',\n xl: 'xl',\n full: 'xl',\n }\n const mappedBorderRadius = borderRadiusMap[borderRadius ?? 'medium'] ?? 'medium'\n const borderRadiusConfig = getBorderRadiusConfig(mappedBorderRadius)\n const cssRecord = typeof borderRadiusConfig?.css === 'string'\n ? { '--radius-default': borderRadiusConfig.css }\n : borderRadiusConfig?.css ?? {}\n\n const borderRadiusCSS = Object.entries(cssRecord)\n .map(([property, value]) => ` ${property}: ${value};`)\n .join('\\n')\n\n const borderRadiusBlock = borderRadiusCSS\n ? `:root {\n${borderRadiusCSS}\n}`\n : ''\n\n const themeConfigurationCSS = generateThemeCSS(normalizedThemeConfiguration)\n const colorModesCSS = generateThemeColorsCss({ themeName: theme, lightMode, darkMode })\n const customCSSBlock = typeof customCSS === 'string' ? customCSS.trim() : ''\n\n const combinedCSS = [\n criticalCSS,\n borderRadiusBlock,\n themeConfigurationCSS,\n colorModesCSS,\n customCSSBlock,\n ]\n .filter((block) => Boolean(block?.trim?.().length))\n .join('\\n\\n')\n\n const themeCSSPath = getThemeCSSPath(theme as ThemeDefaults)\n return (\n <>\n <style\n id=\"theme-critical-css\"\n dangerouslySetInnerHTML={{\n __html: combinedCSS,\n }}\n />\n <link rel=\"preload\" href={themeCSSPath} as=\"style\" />\n <link rel=\"stylesheet\" href={themeCSSPath} />\n </>\n )\n}\n"],"names":["getBorderRadiusConfig","resolveThemeConfiguration","createFallbackCriticalCSS","getThemeCriticalCSS","getThemeCSSPath","generateThemeColorsCss","generateThemeCSS","ServerThemeInjector","siteSettings","resolvedConfiguration","themeConfiguration","theme","borderRadius","customCSS","lightMode","darkMode","fontScale","spacing","animationLevel","allowColorModeToggle","colorMode","typography","baseThemeConfiguration","normalizedThemeConfiguration","undefined","criticalCSS","borderRadiusMap","none","small","medium","large","xl","full","mappedBorderRadius","borderRadiusConfig","cssRecord","css","borderRadiusCSS","Object","entries","map","property","value","join","borderRadiusBlock","themeConfigurationCSS","colorModesCSS","themeName","customCSSBlock","trim","combinedCSS","filter","block","Boolean","length","themeCSSPath","style","id","dangerouslySetInnerHTML","__html","link","rel","href","as"],"mappings":";AACA,SAASA,qBAAqB,QAAQ,oCAAmC;AAGzE,SAASC,yBAAyB,QAAQ,wCAAuC;AACjF,SACEC,yBAAyB,EACzBC,mBAAmB,EACnBC,eAAe,QACV,0BAAyB;AAChC,SAASC,sBAAsB,QAAQ,0BAAyB;AAChE,SAASC,gBAAgB,QAAQ,yBAAwB;AAUzD;;;CAGC,GACD,OAAO,eAAeC,oBAAoB,EAAEC,YAAY,EAAsC;IAC5F,MAAMC,wBAAwBR,0BAA0BO,cAAcE;IACtE,MAAM,EACJC,KAAK,EACLC,YAAY,EACZC,SAAS,EACTC,SAAS,EACTC,QAAQ,EACRC,SAAS,EACTC,OAAO,EACPC,cAAc,EACdC,oBAAoB,EACpBC,SAAS,EACTC,UAAU,EACX,GAAGZ;IAEJ,MAAMa,yBAAyB;QAAE,GAAId,cAAcE,sBAAsB,CAAC,CAAC;IAAE;IAC7E,IAAI,gBAAgBY,wBAAwB;QAC1C,OAAO,AAACA,uBAAmDD,UAAU;IACvE;IAEA,MAAME,+BAA0D;QAC9D,GAAGD,sBAAsB;QACzBX;QACAS;QACAD;QACAP;QACAI;QACAC;QACAC;QACAL,WAAWA,aAAaW;QACxBV;QACAC;QACAM,YAAYA,cAAcG;IAC5B;IAEA,IAAIC,cAAc,MAAMtB,oBAAoBQ;IAC5Cc,gBAAgBvB,0BAA0BS;IAE1C,MAAMe,kBAAsD;QAC1DC,MAAM;QACNC,OAAO;QACPC,QAAQ;QACRC,OAAO;QACPC,IAAI;QACJC,MAAM;IACR;IACA,MAAMC,qBAAqBP,eAAe,CAACd,gBAAgB,SAAS,IAAI;IACxE,MAAMsB,qBAAqBlC,sBAAsBiC;IACjD,MAAME,YAAY,OAAOD,oBAAoBE,QAAQ,WACjD;QAAE,oBAAoBF,mBAAmBE,GAAG;IAAC,IAC7CF,oBAAoBE,OAAO,CAAC;IAEhC,MAAMC,kBAAkBC,OAAOC,OAAO,CAACJ,WACpCK,GAAG,CAAC,CAAC,CAACC,UAAUC,MAAM,GAAK,CAAC,EAAE,EAAED,SAAS,EAAE,EAAEC,MAAM,CAAC,CAAC,EACrDC,IAAI,CAAC;IAER,MAAMC,oBAAoBP,kBACtB,CAAC;AACP,EAAEA,gBAAgB;CACjB,CAAC,GACI;IAEJ,MAAMQ,wBAAwBvC,iBAAiBiB;IAC/C,MAAMuB,gBAAgBzC,uBAAuB;QAAE0C,WAAWpC;QAAOG;QAAWC;IAAS;IACrF,MAAMiC,iBAAiB,OAAOnC,cAAc,WAAWA,UAAUoC,IAAI,KAAK;IAE1E,MAAMC,cAAc;QAClBzB;QACAmB;QACAC;QACAC;QACAE;KACD,CACEG,MAAM,CAAC,CAACC,QAAUC,QAAQD,OAAOH,SAASK,SAC1CX,IAAI,CAAC;IAER,MAAMY,eAAenD,gBAAgBO;IACrC,qBACE;;0BACE,KAAC6C;gBACCC,IAAG;gBACHC,yBAAyB;oBACvBC,QAAQT;gBACV;;0BAEF,KAACU;gBAAKC,KAAI;gBAAUC,MAAMP;gBAAcQ,IAAG;;0BAC3C,KAACH;gBAAKC,KAAI;gBAAaC,MAAMP;;;;AAGnC"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ServerThemeInjector.tsx"],"sourcesContent":["import type { SiteSetting } from '../payload-types.js'\r\nimport { getBorderRadiusConfig } from '../providers/Theme/themeConfig.js'\r\nimport type { BorderRadiusPreset, ThemeDefaults } from '../providers/Theme/types.js'\r\nimport type { ThemeTypographyPreset } from '../presets.js'\r\nimport { resolveThemeConfiguration } from '../utils/resolveThemeConfiguration.js'\r\nimport {\r\n createFallbackCriticalCSS,\r\n getThemeCriticalCSS,\r\n getThemeCSSPath,\r\n} from '../utils/themeAssets.js'\r\nimport { generateThemeColorsCss } from '../utils/themeColors.js'\r\nimport { generateThemeCSS } from '../utils/themeUtils.js'\r\n\r\ninterface ServerThemeInjectorProps {\r\n siteSettings: SiteSetting | null\r\n}\r\n\r\ntype RuntimeThemeConfiguration = Omit<NonNullable<SiteSetting['themeConfiguration']>, 'typography'> & {\r\n typography?: ThemeTypographyPreset | null\r\n}\r\n\r\n/**\r\n * Server-side theme CSS injector to prevent FOUC\r\n * This component injects critical theme CSS directly into the HTML head during SSR\r\n */\r\nexport async function ServerThemeInjector({ siteSettings }: Readonly<ServerThemeInjectorProps>) {\r\n const resolvedConfiguration = resolveThemeConfiguration(siteSettings?.themeConfiguration)\r\n const {\r\n theme,\r\n borderRadius,\r\n customCSS,\r\n lightMode,\r\n darkMode,\r\n fontScale,\r\n spacing,\r\n animationLevel,\r\n allowColorModeToggle,\r\n colorMode,\r\n typography,\r\n } = resolvedConfiguration\r\n\r\n const baseThemeConfiguration = { ...(siteSettings?.themeConfiguration ?? {}) }\r\n if ('typography' in baseThemeConfiguration) {\r\n delete (baseThemeConfiguration as Record<string, unknown>).typography\r\n }\r\n\r\n const normalizedThemeConfiguration: RuntimeThemeConfiguration = {\r\n ...baseThemeConfiguration,\r\n theme,\r\n colorMode,\r\n allowColorModeToggle,\r\n borderRadius,\r\n fontScale,\r\n spacing,\r\n animationLevel,\r\n customCSS: customCSS ?? undefined,\r\n lightMode,\r\n darkMode,\r\n typography: typography ?? undefined,\r\n }\r\n\r\n let criticalCSS = await getThemeCriticalCSS(theme as ThemeDefaults)\r\n criticalCSS ??= createFallbackCriticalCSS(theme as ThemeDefaults)\r\n\r\n const borderRadiusMap: Record<string, BorderRadiusPreset> = {\r\n none: 'none',\r\n small: 'small',\r\n medium: 'medium',\r\n large: 'large',\r\n xl: 'xl',\r\n full: 'xl',\r\n }\r\n const mappedBorderRadius = borderRadiusMap[borderRadius ?? 'medium'] ?? 'medium'\r\n const borderRadiusConfig = getBorderRadiusConfig(mappedBorderRadius)\r\n const cssRecord = typeof borderRadiusConfig?.css === 'string'\r\n ? { '--radius-default': borderRadiusConfig.css }\r\n : borderRadiusConfig?.css ?? {}\r\n\r\n const borderRadiusCSS = Object.entries(cssRecord)\r\n .map(([property, value]) => ` ${property}: ${value};`)\r\n .join('\\n')\r\n\r\n const borderRadiusBlock = borderRadiusCSS\r\n ? `:root {\r\n${borderRadiusCSS}\r\n}`\r\n : ''\r\n\r\n const themeConfigurationCSS = generateThemeCSS(normalizedThemeConfiguration)\r\n const colorModesCSS = generateThemeColorsCss({ themeName: theme, lightMode, darkMode })\r\n const customCSSBlock = typeof customCSS === 'string' ? customCSS.trim() : ''\r\n\r\n const combinedCSS = [\r\n criticalCSS,\r\n borderRadiusBlock,\r\n themeConfigurationCSS,\r\n colorModesCSS,\r\n customCSSBlock,\r\n ]\r\n .filter((block) => Boolean(block?.trim?.().length))\r\n .join('\\n\\n')\r\n\r\n const themeCSSPath = getThemeCSSPath(theme as ThemeDefaults)\r\n return (\r\n <>\r\n <style\r\n id=\"theme-critical-css\"\r\n dangerouslySetInnerHTML={{\r\n __html: combinedCSS,\r\n }}\r\n />\r\n <link rel=\"preload\" href={themeCSSPath} as=\"style\" />\r\n <link rel=\"stylesheet\" href={themeCSSPath} />\r\n </>\r\n )\r\n}\r\n"],"names":["getBorderRadiusConfig","resolveThemeConfiguration","createFallbackCriticalCSS","getThemeCriticalCSS","getThemeCSSPath","generateThemeColorsCss","generateThemeCSS","ServerThemeInjector","siteSettings","resolvedConfiguration","themeConfiguration","theme","borderRadius","customCSS","lightMode","darkMode","fontScale","spacing","animationLevel","allowColorModeToggle","colorMode","typography","baseThemeConfiguration","normalizedThemeConfiguration","undefined","criticalCSS","borderRadiusMap","none","small","medium","large","xl","full","mappedBorderRadius","borderRadiusConfig","cssRecord","css","borderRadiusCSS","Object","entries","map","property","value","join","borderRadiusBlock","themeConfigurationCSS","colorModesCSS","themeName","customCSSBlock","trim","combinedCSS","filter","block","Boolean","length","themeCSSPath","style","id","dangerouslySetInnerHTML","__html","link","rel","href","as"],"mappings":";AACA,SAASA,qBAAqB,QAAQ,oCAAmC;AAGzE,SAASC,yBAAyB,QAAQ,wCAAuC;AACjF,SACEC,yBAAyB,EACzBC,mBAAmB,EACnBC,eAAe,QACV,0BAAyB;AAChC,SAASC,sBAAsB,QAAQ,0BAAyB;AAChE,SAASC,gBAAgB,QAAQ,yBAAwB;AAUzD;;;CAGC,GACD,OAAO,eAAeC,oBAAoB,EAAEC,YAAY,EAAsC;IAC5F,MAAMC,wBAAwBR,0BAA0BO,cAAcE;IACtE,MAAM,EACJC,KAAK,EACLC,YAAY,EACZC,SAAS,EACTC,SAAS,EACTC,QAAQ,EACRC,SAAS,EACTC,OAAO,EACPC,cAAc,EACdC,oBAAoB,EACpBC,SAAS,EACTC,UAAU,EACX,GAAGZ;IAEJ,MAAMa,yBAAyB;QAAE,GAAId,cAAcE,sBAAsB,CAAC,CAAC;IAAE;IAC7E,IAAI,gBAAgBY,wBAAwB;QAC1C,OAAO,AAACA,uBAAmDD,UAAU;IACvE;IAEA,MAAME,+BAA0D;QAC9D,GAAGD,sBAAsB;QACzBX;QACAS;QACAD;QACAP;QACAI;QACAC;QACAC;QACAL,WAAWA,aAAaW;QACxBV;QACAC;QACAM,YAAYA,cAAcG;IAC5B;IAEA,IAAIC,cAAc,MAAMtB,oBAAoBQ;IAC5Cc,gBAAgBvB,0BAA0BS;IAE1C,MAAMe,kBAAsD;QAC1DC,MAAM;QACNC,OAAO;QACPC,QAAQ;QACRC,OAAO;QACPC,IAAI;QACJC,MAAM;IACR;IACA,MAAMC,qBAAqBP,eAAe,CAACd,gBAAgB,SAAS,IAAI;IACxE,MAAMsB,qBAAqBlC,sBAAsBiC;IACjD,MAAME,YAAY,OAAOD,oBAAoBE,QAAQ,WACjD;QAAE,oBAAoBF,mBAAmBE,GAAG;IAAC,IAC7CF,oBAAoBE,OAAO,CAAC;IAEhC,MAAMC,kBAAkBC,OAAOC,OAAO,CAACJ,WACpCK,GAAG,CAAC,CAAC,CAACC,UAAUC,MAAM,GAAK,CAAC,EAAE,EAAED,SAAS,EAAE,EAAEC,MAAM,CAAC,CAAC,EACrDC,IAAI,CAAC;IAER,MAAMC,oBAAoBP,kBACtB,CAAC;AACP,EAAEA,gBAAgB;CACjB,CAAC,GACI;IAEJ,MAAMQ,wBAAwBvC,iBAAiBiB;IAC/C,MAAMuB,gBAAgBzC,uBAAuB;QAAE0C,WAAWpC;QAAOG;QAAWC;IAAS;IACrF,MAAMiC,iBAAiB,OAAOnC,cAAc,WAAWA,UAAUoC,IAAI,KAAK;IAE1E,MAAMC,cAAc;QAClBzB;QACAmB;QACAC;QACAC;QACAE;KACD,CACEG,MAAM,CAAC,CAACC,QAAUC,QAAQD,OAAOH,SAASK,SAC1CX,IAAI,CAAC;IAER,MAAMY,eAAenD,gBAAgBO;IACrC,qBACE;;0BACE,KAAC6C;gBACCC,IAAG;gBACHC,yBAAyB;oBACvBC,QAAQT;gBACV;;0BAEF,KAACU;gBAAKC,KAAI;gBAAUC,MAAMP;gBAAcQ,IAAG;;0BAC3C,KAACH;gBAAKC,KAAI;gBAAaC,MAAMP;;;;AAGnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ThemePreview.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport React, { useMemo } from 'react'\nimport { themeIsValid } from '../providers/Theme/types.js'\nimport { defaultThemePresets } from '../presets.js'\n\nconst DEFAULT_THEME_KEY = 'cool'\nconst basePresetMap = defaultThemePresets.reduce<\n Record<string, (typeof defaultThemePresets)[number]>\n>((accumulator, preset) => {\n accumulator[preset.name] = preset\n return accumulator\n}, {})\n\nconst fallbackPreset = basePresetMap[DEFAULT_THEME_KEY] ?? defaultThemePresets[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 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 🎨 Live Theme Preview\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' }}>Your Website</div>\n <nav style={{ display: 'flex', gap: '24px', fontSize: '14px' }}>\n <span>Home</span>\n <span>About</span>\n <span>Services</span>\n <span>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 Welcome to Your Site\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 This is how your content will look with the selected theme. The colors and styling will\n be applied across your entire website.\n </p>\n\n {/* Buttons */}\n <div style={{ display: 'flex', gap: '12px', marginBottom: '32px' }}>\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 Sample Card\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 © 2025 Your Website. Powered by PayloadCMS.\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","themeIsValid","defaultThemePresets","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","div","className","style","marginTop","fontSize","fontWeight","marginBottom","color","border","borderRadius","overflow","minHeight","padding","display","justifyContent","alignItems","nav","gap","span","h1","p","lineHeight","opacity","button","cursor","h3","textAlign","gridTemplateColumns","strong"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ThemePreview.tsx"],"sourcesContent":["'use client'\r\n\r\nimport { useField } from '@payloadcms/ui'\r\nimport React, { useMemo } from 'react'\r\nimport { themeIsValid } from '../providers/Theme/types.js'\r\nimport { defaultThemePresets } from '../presets.js'\r\n\r\nconst DEFAULT_THEME_KEY = 'cool'\r\nconst basePresetMap = defaultThemePresets.reduce<\r\n Record<string, (typeof defaultThemePresets)[number]>\r\n>((accumulator, preset) => {\r\n accumulator[preset.name] = preset\r\n return accumulator\r\n}, {})\r\n\r\nconst fallbackPreset = basePresetMap[DEFAULT_THEME_KEY] ?? defaultThemePresets[0]\r\nconst fallbackLightMode = fallbackPreset?.lightMode ?? {\r\n primary: '#3b82f6',\r\n accent: '#06b6d4',\r\n background: '#ffffff',\r\n foreground: '#1f2937',\r\n}\r\n\r\nexport default function ThemePreview() {\r\n // Get individual field values using useField hooks\r\n const { value: selectedTheme } = useField<string>({ path: 'themeConfiguration.theme' })\r\n const { value: primaryColor } = useField<string>({\r\n path: 'themeConfiguration.customization.primaryColor',\r\n })\r\n const { value: accentColor } = useField<string>({\r\n path: 'themeConfiguration.customization.accentColor',\r\n })\r\n const { value: backgroundColor } = useField<string>({\r\n path: 'themeConfiguration.customization.backgroundColor',\r\n })\r\n const { value: textColor } = useField<string>({\r\n path: 'themeConfiguration.customization.textColor',\r\n })\r\n\r\n // Determine current theme and if overrides are active\r\n const currentTheme = themeIsValid(selectedTheme)\r\n ? selectedTheme\r\n : (fallbackPreset?.name ?? 'cool')\r\n const hasOverrides = Boolean(primaryColor || accentColor || backgroundColor || textColor)\r\n\r\n const themeColors = useMemo(() => {\r\n const preset = basePresetMap[currentTheme] ?? fallbackPreset\r\n const lightMode = preset?.lightMode ?? fallbackLightMode\r\n\r\n return {\r\n primary: lightMode?.primary ?? fallbackLightMode.primary,\r\n accent:\r\n lightMode?.accent ??\r\n lightMode?.secondary ??\r\n fallbackLightMode.accent ??\r\n fallbackLightMode.primary,\r\n background: lightMode?.background ?? fallbackLightMode.background,\r\n text: lightMode?.foreground ?? fallbackLightMode.foreground,\r\n }\r\n }, [currentTheme])\r\n\r\n const currentColors = useMemo(\r\n () => ({\r\n primary: primaryColor || themeColors.primary,\r\n accent: accentColor || themeColors.accent,\r\n background: backgroundColor || themeColors.background,\r\n text: textColor || themeColors.text,\r\n }),\r\n [primaryColor, accentColor, backgroundColor, textColor, themeColors],\r\n )\r\n\r\n return (\r\n <div className=\"theme-preview\" style={{ marginTop: '20px' }}>\r\n <div\r\n style={{\r\n fontSize: '16px',\r\n fontWeight: '600',\r\n marginBottom: '16px',\r\n color: '#374151',\r\n }}\r\n >\r\n 🎨 Live Theme Preview\r\n </div>\r\n\r\n <div\r\n className=\"preview-container\"\r\n style={{\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '12px',\r\n overflow: 'hidden',\r\n backgroundColor: currentColors.background,\r\n color: currentColors.text,\r\n minHeight: '300px',\r\n }}\r\n >\r\n {/* Header */}\r\n <div\r\n style={{\r\n backgroundColor: currentColors.primary,\r\n color: currentColors.background,\r\n padding: '16px 24px',\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <div style={{ fontSize: '20px', fontWeight: '700' }}>Your Website</div>\r\n <nav style={{ display: 'flex', gap: '24px', fontSize: '14px' }}>\r\n <span>Home</span>\r\n <span>About</span>\r\n <span>Services</span>\r\n <span>Contact</span>\r\n </nav>\r\n </div>\r\n\r\n {/* Content */}\r\n <div style={{ padding: '32px 24px' }}>\r\n <h1\r\n style={{\r\n fontSize: '32px',\r\n fontWeight: '800',\r\n marginBottom: '16px',\r\n color: currentColors.text,\r\n }}\r\n >\r\n Welcome to Your Site\r\n </h1>\r\n\r\n <p\r\n style={{\r\n fontSize: '16px',\r\n lineHeight: '1.6',\r\n marginBottom: '24px',\r\n color: currentColors.text,\r\n opacity: 0.8,\r\n }}\r\n >\r\n This is how your content will look with the selected theme. The colors and styling will\r\n be applied across your entire website.\r\n </p>\r\n\r\n {/* Buttons */}\r\n <div style={{ display: 'flex', gap: '12px', marginBottom: '32px' }}>\r\n <button\r\n style={{\r\n backgroundColor: currentColors.primary,\r\n color: currentColors.background,\r\n border: 'none',\r\n padding: '12px 24px',\r\n borderRadius: '6px',\r\n fontSize: '14px',\r\n fontWeight: '600',\r\n cursor: 'pointer',\r\n }}\r\n >\r\n Primary Button\r\n </button>\r\n <button\r\n style={{\r\n backgroundColor: 'transparent',\r\n color: currentColors.primary,\r\n border: `2px solid ${currentColors.primary}`,\r\n padding: '10px 24px',\r\n borderRadius: '6px',\r\n fontSize: '14px',\r\n fontWeight: '600',\r\n cursor: 'pointer',\r\n }}\r\n >\r\n Secondary Button\r\n </button>\r\n </div>\r\n\r\n {/* Card */}\r\n <div\r\n style={{\r\n backgroundColor: currentColors.text,\r\n color: currentColors.background,\r\n padding: '24px',\r\n borderRadius: '8px',\r\n opacity: 0.05,\r\n marginBottom: '16px',\r\n }}\r\n />\r\n <div\r\n style={{\r\n border: `1px solid ${currentColors.text}`,\r\n padding: '20px',\r\n borderRadius: '8px',\r\n opacity: 0.1,\r\n }}\r\n >\r\n <h3\r\n style={{\r\n fontSize: '18px',\r\n fontWeight: '600',\r\n marginBottom: '12px',\r\n color: currentColors.text,\r\n }}\r\n >\r\n Sample Card\r\n </h3>\r\n <p\r\n style={{\r\n fontSize: '14px',\r\n color: currentColors.text,\r\n opacity: 0.7,\r\n }}\r\n >\r\n This shows how cards and content blocks will appear.\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Footer */}\r\n <div\r\n style={{\r\n backgroundColor: currentColors.accent,\r\n color: currentColors.background,\r\n padding: '16px 24px',\r\n textAlign: 'center',\r\n fontSize: '14px',\r\n marginTop: 'auto',\r\n }}\r\n >\r\n © 2025 Your Website. Powered by PayloadCMS.\r\n </div>\r\n </div>\r\n\r\n {/* Theme info */}\r\n <div\r\n style={{\r\n marginTop: '12px',\r\n fontSize: '12px',\r\n color: '#6b7280',\r\n display: 'grid',\r\n gridTemplateColumns: 'repeat(2, 1fr)',\r\n gap: '8px',\r\n }}\r\n >\r\n <div>\r\n <strong>Active Theme:</strong> {currentTheme}\r\n </div>\r\n <div>\r\n <strong>Primary:</strong> {currentColors.primary}\r\n </div>\r\n <div>\r\n <strong>Accent:</strong> {currentColors.accent}\r\n </div>\r\n <div>\r\n <strong>Background:</strong> {currentColors.background}\r\n </div>\r\n </div>\r\n\r\n {/* Customization indicator */}\r\n {hasOverrides && (\r\n <div\r\n style={{\r\n marginTop: '8px',\r\n padding: '8px 12px',\r\n backgroundColor: '#fef3c7',\r\n borderRadius: '6px',\r\n fontSize: '11px',\r\n color: '#92400e',\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n }}\r\n >\r\n <span>⚡</span>\r\n <span>\r\n <strong>Custom colors applied</strong> - overriding theme defaults\r\n </span>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":["useField","React","useMemo","themeIsValid","defaultThemePresets","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","div","className","style","marginTop","fontSize","fontWeight","marginBottom","color","border","borderRadius","overflow","minHeight","padding","display","justifyContent","alignItems","nav","gap","span","h1","p","lineHeight","opacity","button","cursor","h3","textAlign","gridTemplateColumns","strong"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/typographyPreviewUtils.ts"],"sourcesContent":["import { BODY_FONT_OPTIONS, FONT_VALUE_TO_CSS, HEADING_FONT_OPTIONS } from '../constants/themeFonts.js'\nimport { defaultThemePresets } from '../presets.js'\n\nexport interface TypographySelection {\n bodyFont?: string | null\n headingFont?: string | null\n bodyFontCustom?: string | null\n headingFontCustom?: string | null\n baseFontSize?: string | null\n lineHeight?: string | null\n}\n\nexport interface ResolvedTypographyPreview {\n bodyFont: string\n headingFont: string\n baseFontSize: string\n lineHeight: string\n bodyLabel: string\n headingLabel: string\n}\n\nconst FALLBACK_THEME = defaultThemePresets[0]?.name ?? 'cool'\nconst fallbackPreset =\n defaultThemePresets.find((preset) => preset.name === FALLBACK_THEME) ?? defaultThemePresets[0]\n\nconst FONT_VAR_FALLBACK: Record<string, string> = {\n 'var(--font-geist-sans)': '\"Geist Sans\", system-ui, sans-serif',\n 'var(--font-geist-mono)': '\"Geist Mono\", SFMono-Regular, ui-monospace, monospace',\n 'var(--font-inter)': '\"Inter\", system-ui, sans-serif',\n 'var(--font-outfit)': '\"Outfit\", system-ui, sans-serif',\n 'var(--font-playfair)': '\"Playfair Display\", \"Times New Roman\", serif',\n 'var(--font-lora)': '\"Lora\", \"Times New Roman\", serif',\n 'var(--font-manrope)': '\"Manrope\", system-ui, sans-serif',\n 'var(--font-urbanist)': '\"Urbanist\", system-ui, sans-serif',\n}\n\nfunction withFallback(fontFamily: string, fallback: string): string {\n if (!fontFamily) return fallback\n\n if (fontFamily.startsWith('var(')) {\n const mappedFallback = FONT_VAR_FALLBACK[fontFamily] ?? fallback\n return `${fontFamily}, ${mappedFallback}`\n }\n\n return fontFamily\n}\n\nfunction getPresetTypography(themeName?: string) {\n const preset = defaultThemePresets.find((item) => item.name === themeName) ?? fallbackPreset\n return preset?.typography\n}\n\nfunction resolveFontFamily(\n value: string | null | undefined,\n customValue: string | null | undefined,\n fallback: string,\n): string {\n if (!value || value === 'preset') {\n return withFallback(fallback, fallbackPreset?.typography?.fontFamily ?? 'system-ui, sans-serif')\n }\n\n if (value === 'custom') {\n if (customValue && customValue.trim().length > 0) {\n return customValue.trim()\n }\n return withFallback(fallback, fallbackPreset?.typography?.fontFamily ?? 'system-ui, sans-serif')\n }\n\n const preconfigured = FONT_VALUE_TO_CSS[value]\n if (preconfigured) {\n return withFallback(\n preconfigured,\n fallbackPreset?.typography?.fontFamily ?? 'system-ui, sans-serif',\n )\n }\n\n return withFallback(fallback, fallbackPreset?.typography?.fontFamily ?? 'system-ui, sans-serif')\n}\n\nfunction resolveOptionLabel(\n options: ReadonlyArray<{ label: string | Record<string, string>; value: string }>,\n value?: string | null,\n locale: 'en' | 'cs' = 'en',\n): string {\n const option = options.find((item) => item.value === value)\n if (!option) return value ?? ''\n if (typeof option.label === 'string') {\n return option.label\n }\n return option.label?.[locale] ?? Object.values(option.label)[0] ?? option.value\n}\n\nexport function resolveTypographyPreview(\n selection: TypographySelection | null | undefined,\n themeName?: string,\n): ResolvedTypographyPreview {\n const presetTypography = getPresetTypography(themeName)\n const fallbackBody = presetTypography?.fontFamily ?? 'system-ui, sans-serif'\n const fallbackHeading = presetTypography?.headingFamily ?? fallbackBody\n const fallbackSize = presetTypography?.baseFontSize ?? '16px'\n const fallbackLineHeight = presetTypography?.lineHeight ?? '1.6'\n\n const bodyFontValue = selection?.bodyFont ?? 'preset'\n const headingFontValue = selection?.headingFont ?? 'preset'\n const bodyFontCustom = selection?.bodyFontCustom ?? undefined\n const headingFontCustom = selection?.headingFontCustom ?? undefined\n const resolvedBodyFont = resolveFontFamily(bodyFontValue, bodyFontCustom, fallbackBody)\n const resolvedHeadingFont = resolveFontFamily(\n headingFontValue,\n headingFontCustom,\n fallbackHeading,\n )\n\n const baseFontSize =\n selection?.baseFontSize && selection.baseFontSize !== 'preset'\n ? selection.baseFontSize\n : fallbackSize\n const lineHeight =\n selection?.lineHeight && selection.lineHeight !== 'preset'\n ? selection.lineHeight\n : fallbackLineHeight\n\n return {\n bodyFont: resolvedBodyFont,\n headingFont: resolvedHeadingFont,\n baseFontSize,\n lineHeight,\n bodyLabel: resolveOptionLabel(BODY_FONT_OPTIONS, bodyFontValue),\n headingLabel: resolveOptionLabel(HEADING_FONT_OPTIONS, headingFontValue),\n }\n}\n"],"names":["BODY_FONT_OPTIONS","FONT_VALUE_TO_CSS","HEADING_FONT_OPTIONS","defaultThemePresets","FALLBACK_THEME","name","fallbackPreset","find","preset","FONT_VAR_FALLBACK","withFallback","fontFamily","fallback","startsWith","mappedFallback","getPresetTypography","themeName","item","typography","resolveFontFamily","value","customValue","trim","length","preconfigured","resolveOptionLabel","options","locale","option","label","Object","values","resolveTypographyPreview","selection","presetTypography","fallbackBody","fallbackHeading","headingFamily","fallbackSize","baseFontSize","fallbackLineHeight","lineHeight","bodyFontValue","bodyFont","headingFontValue","headingFont","bodyFontCustom","undefined","headingFontCustom","resolvedBodyFont","resolvedHeadingFont","bodyLabel","headingLabel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/typographyPreviewUtils.ts"],"sourcesContent":["import { BODY_FONT_OPTIONS, FONT_VALUE_TO_CSS, HEADING_FONT_OPTIONS } from '../constants/themeFonts.js'\r\nimport { defaultThemePresets } from '../presets.js'\r\n\r\nexport interface TypographySelection {\r\n bodyFont?: string | null\r\n headingFont?: string | null\r\n bodyFontCustom?: string | null\r\n headingFontCustom?: string | null\r\n baseFontSize?: string | null\r\n lineHeight?: string | null\r\n}\r\n\r\nexport interface ResolvedTypographyPreview {\r\n bodyFont: string\r\n headingFont: string\r\n baseFontSize: string\r\n lineHeight: string\r\n bodyLabel: string\r\n headingLabel: string\r\n}\r\n\r\nconst FALLBACK_THEME = defaultThemePresets[0]?.name ?? 'cool'\r\nconst fallbackPreset =\r\n defaultThemePresets.find((preset) => preset.name === FALLBACK_THEME) ?? defaultThemePresets[0]\r\n\r\nconst FONT_VAR_FALLBACK: Record<string, string> = {\r\n 'var(--font-geist-sans)': '\"Geist Sans\", system-ui, sans-serif',\r\n 'var(--font-geist-mono)': '\"Geist Mono\", SFMono-Regular, ui-monospace, monospace',\r\n 'var(--font-inter)': '\"Inter\", system-ui, sans-serif',\r\n 'var(--font-outfit)': '\"Outfit\", system-ui, sans-serif',\r\n 'var(--font-playfair)': '\"Playfair Display\", \"Times New Roman\", serif',\r\n 'var(--font-lora)': '\"Lora\", \"Times New Roman\", serif',\r\n 'var(--font-manrope)': '\"Manrope\", system-ui, sans-serif',\r\n 'var(--font-urbanist)': '\"Urbanist\", system-ui, sans-serif',\r\n}\r\n\r\nfunction withFallback(fontFamily: string, fallback: string): string {\r\n if (!fontFamily) return fallback\r\n\r\n if (fontFamily.startsWith('var(')) {\r\n const mappedFallback = FONT_VAR_FALLBACK[fontFamily] ?? fallback\r\n return `${fontFamily}, ${mappedFallback}`\r\n }\r\n\r\n return fontFamily\r\n}\r\n\r\nfunction getPresetTypography(themeName?: string) {\r\n const preset = defaultThemePresets.find((item) => item.name === themeName) ?? fallbackPreset\r\n return preset?.typography\r\n}\r\n\r\nfunction resolveFontFamily(\r\n value: string | null | undefined,\r\n customValue: string | null | undefined,\r\n fallback: string,\r\n): string {\r\n if (!value || value === 'preset') {\r\n return withFallback(fallback, fallbackPreset?.typography?.fontFamily ?? 'system-ui, sans-serif')\r\n }\r\n\r\n if (value === 'custom') {\r\n if (customValue && customValue.trim().length > 0) {\r\n return customValue.trim()\r\n }\r\n return withFallback(fallback, fallbackPreset?.typography?.fontFamily ?? 'system-ui, sans-serif')\r\n }\r\n\r\n const preconfigured = FONT_VALUE_TO_CSS[value]\r\n if (preconfigured) {\r\n return withFallback(\r\n preconfigured,\r\n fallbackPreset?.typography?.fontFamily ?? 'system-ui, sans-serif',\r\n )\r\n }\r\n\r\n return withFallback(fallback, fallbackPreset?.typography?.fontFamily ?? 'system-ui, sans-serif')\r\n}\r\n\r\nfunction resolveOptionLabel(\r\n options: ReadonlyArray<{ label: string | Record<string, string>; value: string }>,\r\n value?: string | null,\r\n locale: 'en' | 'cs' = 'en',\r\n): string {\r\n const option = options.find((item) => item.value === value)\r\n if (!option) return value ?? ''\r\n if (typeof option.label === 'string') {\r\n return option.label\r\n }\r\n return option.label?.[locale] ?? Object.values(option.label)[0] ?? option.value\r\n}\r\n\r\nexport function resolveTypographyPreview(\r\n selection: TypographySelection | null | undefined,\r\n themeName?: string,\r\n): ResolvedTypographyPreview {\r\n const presetTypography = getPresetTypography(themeName)\r\n const fallbackBody = presetTypography?.fontFamily ?? 'system-ui, sans-serif'\r\n const fallbackHeading = presetTypography?.headingFamily ?? fallbackBody\r\n const fallbackSize = presetTypography?.baseFontSize ?? '16px'\r\n const fallbackLineHeight = presetTypography?.lineHeight ?? '1.6'\r\n\r\n const bodyFontValue = selection?.bodyFont ?? 'preset'\r\n const headingFontValue = selection?.headingFont ?? 'preset'\r\n const bodyFontCustom = selection?.bodyFontCustom ?? undefined\r\n const headingFontCustom = selection?.headingFontCustom ?? undefined\r\n const resolvedBodyFont = resolveFontFamily(bodyFontValue, bodyFontCustom, fallbackBody)\r\n const resolvedHeadingFont = resolveFontFamily(\r\n headingFontValue,\r\n headingFontCustom,\r\n fallbackHeading,\r\n )\r\n\r\n const baseFontSize =\r\n selection?.baseFontSize && selection.baseFontSize !== 'preset'\r\n ? selection.baseFontSize\r\n : fallbackSize\r\n const lineHeight =\r\n selection?.lineHeight && selection.lineHeight !== 'preset'\r\n ? selection.lineHeight\r\n : fallbackLineHeight\r\n\r\n return {\r\n bodyFont: resolvedBodyFont,\r\n headingFont: resolvedHeadingFont,\r\n baseFontSize,\r\n lineHeight,\r\n bodyLabel: resolveOptionLabel(BODY_FONT_OPTIONS, bodyFontValue),\r\n headingLabel: resolveOptionLabel(HEADING_FONT_OPTIONS, headingFontValue),\r\n }\r\n}\r\n"],"names":["BODY_FONT_OPTIONS","FONT_VALUE_TO_CSS","HEADING_FONT_OPTIONS","defaultThemePresets","FALLBACK_THEME","name","fallbackPreset","find","preset","FONT_VAR_FALLBACK","withFallback","fontFamily","fallback","startsWith","mappedFallback","getPresetTypography","themeName","item","typography","resolveFontFamily","value","customValue","trim","length","preconfigured","resolveOptionLabel","options","locale","option","label","Object","values","resolveTypographyPreview","selection","presetTypography","fallbackBody","fallbackHeading","headingFamily","fallbackSize","baseFontSize","fallbackLineHeight","lineHeight","bodyFontValue","bodyFont","headingFontValue","headingFont","bodyFontCustom","undefined","headingFontCustom","resolvedBodyFont","resolvedHeadingFont","bodyLabel","headingLabel"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/constants/themeFonts.ts"],"sourcesContent":["// Theme font constants for the plugin\nexport const BODY_FONT_OPTIONS = [\n { label: 'System', value: 'system-ui' },\n { label: 'Inter', value: 'Inter' },\n { label: 'Roboto', value: 'Roboto' },\n { label: 'Open Sans', value: 'Open Sans' },\n { label: 'Lato', value: 'Lato' },\n { label: 'Montserrat', value: 'Montserrat' },\n { label: 'Poppins', value: 'Poppins' },\n] as const;\n\nexport const HEADING_FONT_OPTIONS = [\n { label: 'System', value: 'system-ui' },\n { label: 'Inter', value: 'Inter' },\n { label: 'Playfair Display', value: 'Playfair Display' },\n { label: 'Merriweather', value: 'Merriweather' },\n { label: 'Montserrat', value: 'Montserrat' },\n { label: 'Raleway', value: 'Raleway' },\n] as const;\n\nexport const BASE_FONT_SIZE_OPTIONS = [\n { label: '14px', value: '14' },\n { label: '15px', value: '15' },\n { label: '16px', value: '16' },\n { label: '17px', value: '17' },\n { label: '18px', value: '18' },\n] as const;\n\nexport const LINE_HEIGHT_OPTIONS = [\n { label: '1.4', value: '1.4' },\n { label: '1.5', value: '1.5' },\n { label: '1.6', value: '1.6' },\n { label: '1.7', value: '1.7' },\n { label: '1.8', value: '1.8' },\n] as const;\n\nexport const FONT_VALUE_TO_CSS: Record<string, string> = {\n 'system-ui': 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n 'Inter': '\"Inter\", sans-serif',\n 'Roboto': '\"Roboto\", sans-serif',\n 'Open Sans': '\"Open Sans\", sans-serif',\n 'Lato': '\"Lato\", sans-serif',\n 'Montserrat': '\"Montserrat\", sans-serif',\n 'Poppins': '\"Poppins\", sans-serif',\n 'Playfair Display': '\"Playfair Display\", serif',\n 'Merriweather': '\"Merriweather\", serif',\n 'Raleway': '\"Raleway\", sans-serif',\n};\n"],"names":["BODY_FONT_OPTIONS","label","value","HEADING_FONT_OPTIONS","BASE_FONT_SIZE_OPTIONS","LINE_HEIGHT_OPTIONS","FONT_VALUE_TO_CSS"],"mappings":"AAAA,sCAAsC;AACtC,OAAO,MAAMA,oBAAoB;IAC/B;QAAEC,OAAO;QAAUC,OAAO;IAAY;IACtC;QAAED,OAAO;QAASC,OAAO;IAAQ;IACjC;QAAED,OAAO;QAAUC,OAAO;IAAS;IACnC;QAAED,OAAO;QAAaC,OAAO;IAAY;IACzC;QAAED,OAAO;QAAQC,OAAO;IAAO;IAC/B;QAAED,OAAO;QAAcC,OAAO;IAAa;IAC3C;QAAED,OAAO;QAAWC,OAAO;IAAU;CACtC,CAAU;AAEX,OAAO,MAAMC,uBAAuB;IAClC;QAAEF,OAAO;QAAUC,OAAO;IAAY;IACtC;QAAED,OAAO;QAASC,OAAO;IAAQ;IACjC;QAAED,OAAO;QAAoBC,OAAO;IAAmB;IACvD;QAAED,OAAO;QAAgBC,OAAO;IAAe;IAC/C;QAAED,OAAO;QAAcC,OAAO;IAAa;IAC3C;QAAED,OAAO;QAAWC,OAAO;IAAU;CACtC,CAAU;AAEX,OAAO,MAAME,yBAAyB;IACpC;QAAEH,OAAO;QAAQC,OAAO;IAAK;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAK;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAK;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAK;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAK;CAC9B,CAAU;AAEX,OAAO,MAAMG,sBAAsB;IACjC;QAAEJ,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAOC,OAAO;IAAM;CAC9B,CAAU;AAEX,OAAO,MAAMI,oBAA4C;IACvD,aAAa;IACb,SAAS;IACT,UAAU;IACV,aAAa;IACb,QAAQ;IACR,cAAc;IACd,WAAW;IACX,oBAAoB;IACpB,gBAAgB;IAChB,WAAW;AACb,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../../src/constants/themeFonts.ts"],"sourcesContent":["// Theme font constants for the plugin\r\nexport const BODY_FONT_OPTIONS = [\r\n { label: 'System', value: 'system-ui' },\r\n { label: 'Inter', value: 'Inter' },\r\n { label: 'Roboto', value: 'Roboto' },\r\n { label: 'Open Sans', value: 'Open Sans' },\r\n { label: 'Lato', value: 'Lato' },\r\n { label: 'Montserrat', value: 'Montserrat' },\r\n { label: 'Poppins', value: 'Poppins' },\r\n] as const;\r\n\r\nexport const HEADING_FONT_OPTIONS = [\r\n { label: 'System', value: 'system-ui' },\r\n { label: 'Inter', value: 'Inter' },\r\n { label: 'Playfair Display', value: 'Playfair Display' },\r\n { label: 'Merriweather', value: 'Merriweather' },\r\n { label: 'Montserrat', value: 'Montserrat' },\r\n { label: 'Raleway', value: 'Raleway' },\r\n] as const;\r\n\r\nexport const BASE_FONT_SIZE_OPTIONS = [\r\n { label: '14px', value: '14' },\r\n { label: '15px', value: '15' },\r\n { label: '16px', value: '16' },\r\n { label: '17px', value: '17' },\r\n { label: '18px', value: '18' },\r\n] as const;\r\n\r\nexport const LINE_HEIGHT_OPTIONS = [\r\n { label: '1.4', value: '1.4' },\r\n { label: '1.5', value: '1.5' },\r\n { label: '1.6', value: '1.6' },\r\n { label: '1.7', value: '1.7' },\r\n { label: '1.8', value: '1.8' },\r\n] as const;\r\n\r\nexport const FONT_VALUE_TO_CSS: Record<string, string> = {\r\n 'system-ui': 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\r\n 'Inter': '\"Inter\", sans-serif',\r\n 'Roboto': '\"Roboto\", sans-serif',\r\n 'Open Sans': '\"Open Sans\", sans-serif',\r\n 'Lato': '\"Lato\", sans-serif',\r\n 'Montserrat': '\"Montserrat\", sans-serif',\r\n 'Poppins': '\"Poppins\", sans-serif',\r\n 'Playfair Display': '\"Playfair Display\", serif',\r\n 'Merriweather': '\"Merriweather\", serif',\r\n 'Raleway': '\"Raleway\", sans-serif',\r\n};\r\n"],"names":["BODY_FONT_OPTIONS","label","value","HEADING_FONT_OPTIONS","BASE_FONT_SIZE_OPTIONS","LINE_HEIGHT_OPTIONS","FONT_VALUE_TO_CSS"],"mappings":"AAAA,sCAAsC;AACtC,OAAO,MAAMA,oBAAoB;IAC/B;QAAEC,OAAO;QAAUC,OAAO;IAAY;IACtC;QAAED,OAAO;QAASC,OAAO;IAAQ;IACjC;QAAED,OAAO;QAAUC,OAAO;IAAS;IACnC;QAAED,OAAO;QAAaC,OAAO;IAAY;IACzC;QAAED,OAAO;QAAQC,OAAO;IAAO;IAC/B;QAAED,OAAO;QAAcC,OAAO;IAAa;IAC3C;QAAED,OAAO;QAAWC,OAAO;IAAU;CACtC,CAAU;AAEX,OAAO,MAAMC,uBAAuB;IAClC;QAAEF,OAAO;QAAUC,OAAO;IAAY;IACtC;QAAED,OAAO;QAASC,OAAO;IAAQ;IACjC;QAAED,OAAO;QAAoBC,OAAO;IAAmB;IACvD;QAAED,OAAO;QAAgBC,OAAO;IAAe;IAC/C;QAAED,OAAO;QAAcC,OAAO;IAAa;IAC3C;QAAED,OAAO;QAAWC,OAAO;IAAU;CACtC,CAAU;AAEX,OAAO,MAAME,yBAAyB;IACpC;QAAEH,OAAO;QAAQC,OAAO;IAAK;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAK;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAK;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAK;IAC7B;QAAED,OAAO;QAAQC,OAAO;IAAK;CAC9B,CAAU;AAEX,OAAO,MAAMG,sBAAsB;IACjC;QAAEJ,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAOC,OAAO;IAAM;IAC7B;QAAED,OAAO;QAAOC,OAAO;IAAM;CAC9B,CAAU;AAEX,OAAO,MAAMI,oBAA4C;IACvD,aAAa;IACb,SAAS;IACT,UAAU;IACV,aAAa;IACb,QAAQ;IACR,cAAc;IACd,WAAW;IACX,oBAAoB;IACpB,gBAAgB;IAChB,WAAW;AACb,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/ColorPickerField.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport type { TextFieldClientProps } from 'payload'\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nconst colorPresets: Record<string, string[]> = {\n 'Theme Colors': ['#3b82f6', '#1e40af', '#b45309', '#78716c', '#8b5cf6', '#f97316'],\n 'Common Colors': ['#ef4444', '#10b981', '#f59e0b', '#06b6d4', '#ec4899', '#6b7280'],\n 'Neutral Tones': ['#000000', '#1f2937', '#6b7280', '#d1d5db', '#f3f4f6', '#ffffff'],\n}\n\nfunction resolveLocalizedValue(value: unknown): 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 fallback = localized.en ?? localized.cs ?? localized['']\n return typeof fallback === 'string' ? fallback : ''\n }\n\n return ''\n}\n\nexport default function ColorPickerField(props: TextFieldClientProps) {\n const { field, path } = props\n const { value = '#000000', setValue } = useField<string>({ path })\n const [isPickerOpen, setIsPickerOpen] = useState(false)\n const pickerRef = useRef<HTMLDivElement>(null)\n\n const fieldLabel = resolveLocalizedValue(field.label)\n const fieldDescription = resolveLocalizedValue(field.admin?.description)\n const placeholder = resolveLocalizedValue(field.admin?.placeholder) || 'e.g., #3b82f6, hsl(...)'\n\n const handleColorChange = useCallback(\n (color: string) => {\n setValue(color)\n },\n [setValue],\n )\n\n const handleInputChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n handleColorChange(event.target.value)\n },\n [handleColorChange],\n )\n\n const togglePicker = useCallback(() => {\n setIsPickerOpen((previous) => !previous)\n }, [])\n\n useEffect(() => {\n if (!isPickerOpen) {\n return\n }\n\n function handleClickOutside(event: MouseEvent) {\n if (!pickerRef.current) {\n return\n }\n\n if (!pickerRef.current.contains(event.target as Node)) {\n setIsPickerOpen(false)\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside)\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isPickerOpen])\n\n return (\n <div className=\"field-type color-picker-field\" style={{ position: 'relative' }}>\n {fieldLabel && (\n <label\n htmlFor={path}\n className=\"field-label\"\n style={{ display: 'block', marginBottom: '8px', fontSize: '13px', fontWeight: 600 }}\n >\n {fieldLabel}\n {field.required && (\n <span\n className=\"required\"\n style={{ color: 'var(--theme-error-500)', marginLeft: '4px' }}\n >\n *\n </span>\n )}\n </label>\n )}\n\n {fieldDescription && (\n <div\n className=\"field-description\"\n style={{\n marginBottom: '8px',\n fontSize: '13px',\n color: 'var(--theme-elevation-500)',\n lineHeight: 1.5,\n }}\n >\n {fieldDescription}\n </div>\n )}\n\n <div\n className=\"color-picker-input-group\"\n style={{ display: 'flex', alignItems: 'center', gap: '8px' }}\n >\n <button\n type=\"button\"\n onClick={togglePicker}\n className=\"color-preview-button\"\n style={{\n width: '40px',\n height: '40px',\n borderRadius: '6px',\n border: '2px solid #e5e7eb',\n backgroundColor: value || '#ffffff',\n cursor: 'pointer',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n title={value ? `Current color: ${value}` : 'Select a color'}\n >\n {!value && <span style={{ fontSize: '20px', color: '#9ca3af' }}>?</span>}\n </button>\n\n <input\n id={path}\n type=\"text\"\n value={value || ''}\n onChange={handleInputChange}\n placeholder={placeholder}\n style={{\n flex: 1,\n padding: '8px 12px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '6px',\n fontSize: '14px',\n fontFamily: 'monospace',\n backgroundColor: 'var(--theme-elevation-0)',\n color: 'var(--theme-elevation-1000)',\n }}\n />\n\n <input\n type=\"color\"\n value={value?.startsWith('#') ? value : '#3b82f6'}\n onChange={handleInputChange}\n title=\"Pick a color\"\n style={{\n width: '40px',\n height: '40px',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n }}\n />\n </div>\n\n {isPickerOpen && (\n <div\n ref={pickerRef}\n className=\"color-presets\"\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n right: 0,\n zIndex: 1000,\n marginTop: '4px',\n padding: '16px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '8px',\n backgroundColor: 'var(--theme-elevation-0)',\n boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n maxHeight: '300px',\n overflowY: 'auto',\n }}\n >\n <div\n style={{\n marginBottom: '16px',\n fontSize: '14px',\n fontWeight: 600,\n color: 'var(--theme-elevation-800)',\n }}\n >\n 🎨 Professional Color Picker\n </div>\n\n {Object.entries(colorPresets).map(([groupName, colors]) => (\n <div key={groupName} style={{ marginBottom: '16px' }}>\n <div\n style={{\n marginBottom: '8px',\n fontSize: '12px',\n fontWeight: 500,\n color: 'var(--theme-elevation-600)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n {groupName}\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: '6px' }}>\n {colors.map((color) => (\n <button\n key={color}\n type=\"button\"\n onClick={() => handleColorChange(color)}\n style={{\n width: '36px',\n height: '36px',\n borderRadius: '6px',\n border:\n value === color\n ? '3px solid var(--theme-primary-500)'\n : '1px solid var(--theme-elevation-150)',\n backgroundColor: color,\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n position: 'relative',\n overflow: 'hidden',\n boxShadow:\n value === color\n ? '0 0 0 2px var(--theme-primary-200)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)',\n }}\n title={`${color} - Click to select`}\n onMouseEnter={(event) => {\n event.currentTarget.style.transform = 'scale(1.1)'\n }}\n onMouseLeave={(event) => {\n event.currentTarget.style.transform = 'scale(1)'\n }}\n >\n {color === '#ffffff' && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'inherit',\n }}\n />\n )}\n </button>\n ))}\n </div>\n </div>\n ))}\n\n <div\n style={{\n marginTop: '16px',\n paddingTop: '16px',\n borderTop: '1px solid var(--theme-elevation-100)',\n }}\n >\n <div\n style={{\n marginBottom: '8px',\n fontSize: '12px',\n fontWeight: 500,\n color: 'var(--theme-elevation-600)',\n }}\n >\n CUSTOM COLOR\n </div>\n <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <input\n type=\"color\"\n value={value?.startsWith('#') ? value : '#3b82f6'}\n onChange={handleInputChange}\n style={{\n width: '36px',\n height: '36px',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n }}\n />\n <div style={{ fontSize: '11px', color: '#9ca3af', lineHeight: 1.3 }}>\n <div>\n <strong>Formats:</strong>\n </div>\n <div>Hex, RGB, HSL, CSS vars</div>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n"],"names":["useField","useCallback","useEffect","useRef","useState","colorPresets","resolveLocalizedValue","value","localized","fallback","en","cs","ColorPickerField","props","field","path","setValue","isPickerOpen","setIsPickerOpen","pickerRef","fieldLabel","label","fieldDescription","admin","description","placeholder","handleColorChange","color","handleInputChange","event","target","togglePicker","previous","handleClickOutside","current","contains","document","addEventListener","removeEventListener","div","className","style","position","htmlFor","display","marginBottom","fontSize","fontWeight","required","span","marginLeft","lineHeight","alignItems","gap","button","type","onClick","width","height","borderRadius","border","backgroundColor","cursor","justifyContent","title","input","id","onChange","flex","padding","fontFamily","startsWith","ref","top","left","right","zIndex","marginTop","boxShadow","maxHeight","overflowY","Object","entries","map","groupName","colors","textTransform","letterSpacing","gridTemplateColumns","transition","overflow","onMouseEnter","currentTarget","transform","onMouseLeave","inset","paddingTop","borderTop","strong"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/fields/ColorPickerField.tsx"],"sourcesContent":["'use client'\r\n\r\nimport { useField } from '@payloadcms/ui'\r\nimport type { TextFieldClientProps } from 'payload'\r\nimport { useCallback, useEffect, useRef, useState } from 'react'\r\n\r\nconst colorPresets: Record<string, string[]> = {\r\n 'Theme Colors': ['#3b82f6', '#1e40af', '#b45309', '#78716c', '#8b5cf6', '#f97316'],\r\n 'Common Colors': ['#ef4444', '#10b981', '#f59e0b', '#06b6d4', '#ec4899', '#6b7280'],\r\n 'Neutral Tones': ['#000000', '#1f2937', '#6b7280', '#d1d5db', '#f3f4f6', '#ffffff'],\r\n}\r\n\r\nfunction resolveLocalizedValue(value: unknown): string {\r\n if (typeof value === 'string') {\r\n return value\r\n }\r\n\r\n if (typeof value === 'object' && value !== null) {\r\n const localized = value as Record<string, unknown>\r\n const fallback = localized.en ?? localized.cs ?? localized['']\r\n return typeof fallback === 'string' ? fallback : ''\r\n }\r\n\r\n return ''\r\n}\r\n\r\nexport default function ColorPickerField(props: TextFieldClientProps) {\r\n const { field, path } = props\r\n const { value = '#000000', setValue } = useField<string>({ path })\r\n const [isPickerOpen, setIsPickerOpen] = useState(false)\r\n const pickerRef = useRef<HTMLDivElement>(null)\r\n\r\n const fieldLabel = resolveLocalizedValue(field.label)\r\n const fieldDescription = resolveLocalizedValue(field.admin?.description)\r\n const placeholder = resolveLocalizedValue(field.admin?.placeholder) || 'e.g., #3b82f6, hsl(...)'\r\n\r\n const handleColorChange = useCallback(\r\n (color: string) => {\r\n setValue(color)\r\n },\r\n [setValue],\r\n )\r\n\r\n const handleInputChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n handleColorChange(event.target.value)\r\n },\r\n [handleColorChange],\r\n )\r\n\r\n const togglePicker = useCallback(() => {\r\n setIsPickerOpen((previous) => !previous)\r\n }, [])\r\n\r\n useEffect(() => {\r\n if (!isPickerOpen) {\r\n return\r\n }\r\n\r\n function handleClickOutside(event: MouseEvent) {\r\n if (!pickerRef.current) {\r\n return\r\n }\r\n\r\n if (!pickerRef.current.contains(event.target as Node)) {\r\n setIsPickerOpen(false)\r\n }\r\n }\r\n\r\n document.addEventListener('mousedown', handleClickOutside)\r\n\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside)\r\n }\r\n }, [isPickerOpen])\r\n\r\n return (\r\n <div className=\"field-type color-picker-field\" style={{ position: 'relative' }}>\r\n {fieldLabel && (\r\n <label\r\n htmlFor={path}\r\n className=\"field-label\"\r\n style={{ display: 'block', marginBottom: '8px', fontSize: '13px', fontWeight: 600 }}\r\n >\r\n {fieldLabel}\r\n {field.required && (\r\n <span\r\n className=\"required\"\r\n style={{ color: 'var(--theme-error-500)', marginLeft: '4px' }}\r\n >\r\n *\r\n </span>\r\n )}\r\n </label>\r\n )}\r\n\r\n {fieldDescription && (\r\n <div\r\n className=\"field-description\"\r\n style={{\r\n marginBottom: '8px',\r\n fontSize: '13px',\r\n color: 'var(--theme-elevation-500)',\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n {fieldDescription}\r\n </div>\r\n )}\r\n\r\n <div\r\n className=\"color-picker-input-group\"\r\n style={{ display: 'flex', alignItems: 'center', gap: '8px' }}\r\n >\r\n <button\r\n type=\"button\"\r\n onClick={togglePicker}\r\n className=\"color-preview-button\"\r\n style={{\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '6px',\r\n border: '2px solid #e5e7eb',\r\n backgroundColor: value || '#ffffff',\r\n cursor: 'pointer',\r\n position: 'relative',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n }}\r\n title={value ? `Current color: ${value}` : 'Select a color'}\r\n >\r\n {!value && <span style={{ fontSize: '20px', color: '#9ca3af' }}>?</span>}\r\n </button>\r\n\r\n <input\r\n id={path}\r\n type=\"text\"\r\n value={value || ''}\r\n onChange={handleInputChange}\r\n placeholder={placeholder}\r\n style={{\r\n flex: 1,\r\n padding: '8px 12px',\r\n border: '1px solid var(--theme-elevation-150)',\r\n borderRadius: '6px',\r\n fontSize: '14px',\r\n fontFamily: 'monospace',\r\n backgroundColor: 'var(--theme-elevation-0)',\r\n color: 'var(--theme-elevation-1000)',\r\n }}\r\n />\r\n\r\n <input\r\n type=\"color\"\r\n value={value?.startsWith('#') ? value : '#3b82f6'}\r\n onChange={handleInputChange}\r\n title=\"Pick a color\"\r\n style={{\r\n width: '40px',\r\n height: '40px',\r\n border: 'none',\r\n borderRadius: '6px',\r\n cursor: 'pointer',\r\n }}\r\n />\r\n </div>\r\n\r\n {isPickerOpen && (\r\n <div\r\n ref={pickerRef}\r\n className=\"color-presets\"\r\n style={{\r\n position: 'absolute',\r\n top: '100%',\r\n left: 0,\r\n right: 0,\r\n zIndex: 1000,\r\n marginTop: '4px',\r\n padding: '16px',\r\n border: '1px solid var(--theme-elevation-150)',\r\n borderRadius: '8px',\r\n backgroundColor: 'var(--theme-elevation-0)',\r\n boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\r\n maxHeight: '300px',\r\n overflowY: 'auto',\r\n }}\r\n >\r\n <div\r\n style={{\r\n marginBottom: '16px',\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n color: 'var(--theme-elevation-800)',\r\n }}\r\n >\r\n 🎨 Professional Color Picker\r\n </div>\r\n\r\n {Object.entries(colorPresets).map(([groupName, colors]) => (\r\n <div key={groupName} style={{ marginBottom: '16px' }}>\r\n <div\r\n style={{\r\n marginBottom: '8px',\r\n fontSize: '12px',\r\n fontWeight: 500,\r\n color: 'var(--theme-elevation-600)',\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n }}\r\n >\r\n {groupName}\r\n </div>\r\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: '6px' }}>\r\n {colors.map((color) => (\r\n <button\r\n key={color}\r\n type=\"button\"\r\n onClick={() => handleColorChange(color)}\r\n style={{\r\n width: '36px',\r\n height: '36px',\r\n borderRadius: '6px',\r\n border:\r\n value === color\r\n ? '3px solid var(--theme-primary-500)'\r\n : '1px solid var(--theme-elevation-150)',\r\n backgroundColor: color,\r\n cursor: 'pointer',\r\n transition: 'all 0.2s ease',\r\n position: 'relative',\r\n overflow: 'hidden',\r\n boxShadow:\r\n value === color\r\n ? '0 0 0 2px var(--theme-primary-200)'\r\n : '0 1px 3px rgba(0, 0, 0, 0.1)',\r\n }}\r\n title={`${color} - Click to select`}\r\n onMouseEnter={(event) => {\r\n event.currentTarget.style.transform = 'scale(1.1)'\r\n }}\r\n onMouseLeave={(event) => {\r\n event.currentTarget.style.transform = 'scale(1)'\r\n }}\r\n >\r\n {color === '#ffffff' && (\r\n <div\r\n style={{\r\n position: 'absolute',\r\n inset: 0,\r\n border: '1px solid var(--theme-elevation-150)',\r\n borderRadius: 'inherit',\r\n }}\r\n />\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n ))}\r\n\r\n <div\r\n style={{\r\n marginTop: '16px',\r\n paddingTop: '16px',\r\n borderTop: '1px solid var(--theme-elevation-100)',\r\n }}\r\n >\r\n <div\r\n style={{\r\n marginBottom: '8px',\r\n fontSize: '12px',\r\n fontWeight: 500,\r\n color: 'var(--theme-elevation-600)',\r\n }}\r\n >\r\n CUSTOM COLOR\r\n </div>\r\n <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\r\n <input\r\n type=\"color\"\r\n value={value?.startsWith('#') ? value : '#3b82f6'}\r\n onChange={handleInputChange}\r\n style={{\r\n width: '36px',\r\n height: '36px',\r\n border: 'none',\r\n borderRadius: '6px',\r\n cursor: 'pointer',\r\n }}\r\n />\r\n <div style={{ fontSize: '11px', color: '#9ca3af', lineHeight: 1.3 }}>\r\n <div>\r\n <strong>Formats:</strong>\r\n </div>\r\n <div>Hex, RGB, HSL, CSS vars</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":["useField","useCallback","useEffect","useRef","useState","colorPresets","resolveLocalizedValue","value","localized","fallback","en","cs","ColorPickerField","props","field","path","setValue","isPickerOpen","setIsPickerOpen","pickerRef","fieldLabel","label","fieldDescription","admin","description","placeholder","handleColorChange","color","handleInputChange","event","target","togglePicker","previous","handleClickOutside","current","contains","document","addEventListener","removeEventListener","div","className","style","position","htmlFor","display","marginBottom","fontSize","fontWeight","required","span","marginLeft","lineHeight","alignItems","gap","button","type","onClick","width","height","borderRadius","border","backgroundColor","cursor","justifyContent","title","input","id","onChange","flex","padding","fontFamily","startsWith","ref","top","left","right","zIndex","marginTop","boxShadow","maxHeight","overflowY","Object","entries","map","groupName","colors","textTransform","letterSpacing","gridTemplateColumns","transition","overflow","onMouseEnter","currentTarget","transform","onMouseLeave","inset","paddingTop","borderTop","strong"],"mappings":"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"}
|
|
@@ -1 +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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"}
|
|
1
|
+
{"version":3,"sources":["../../src/fields/RadiusField.tsx"],"sourcesContent":["'use client'\r\n\r\nimport { useField } from '@payloadcms/ui'\r\nimport type { SelectFieldClientProps } from 'payload'\r\nimport { useMemo } from 'react'\r\nimport { borderRadiusPresets } from '../providers/Theme/themeConfig.js'\r\n\r\ntype RadiusPresetKey = Extract<keyof typeof borderRadiusPresets, string>\r\n\r\ninterface RadiusOptionCard {\r\n key: RadiusPresetKey\r\n label: string\r\n css: Record<string, string>\r\n}\r\n\r\nexport default function RadiusField({ field, ...props }: SelectFieldClientProps) {\r\n const { value, setValue } = useField<string>({ path: props.path })\r\n const label = typeof field.label === 'string' ? field.label : ''\r\n\r\n const radiusOptions = useMemo<RadiusOptionCard[]>(() => {\r\n const entries = Object.entries(borderRadiusPresets) as Array<\r\n [RadiusPresetKey, (typeof borderRadiusPresets)[RadiusPresetKey]]\r\n >\r\n return entries.map(([key, preset]) => ({\r\n key,\r\n label: preset.label,\r\n css: preset.css,\r\n }))\r\n }, [])\r\n\r\n const fallbackKey: RadiusPresetKey = radiusOptions[2]?.key ?? radiusOptions[0]?.key ?? 'medium'\r\n const currentKey =\r\n typeof value === 'string' && value in borderRadiusPresets\r\n ? (value as RadiusPresetKey)\r\n : fallbackKey\r\n\r\n const description =\r\n typeof field.admin?.description === 'string'\r\n ? field.admin.description\r\n : field.admin?.description?.en || field.admin?.description?.cs || null\r\n\r\n return (\r\n <div className=\"field-type\">\r\n <label className=\"field-label\" htmlFor={props.path}>\r\n {label}\r\n {field.required && <span className=\"required\">*</span>}\r\n </label>\r\n\r\n {description && (\r\n <p\r\n style={{\r\n marginTop: '4px',\r\n fontSize: '12px',\r\n lineHeight: 1.5,\r\n color: 'var(--theme-elevation-600)',\r\n }}\r\n >\r\n {description}\r\n </p>\r\n )}\r\n\r\n <div\r\n style={{\r\n display: 'grid',\r\n gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))',\r\n gap: '16px',\r\n marginTop: '16px',\r\n }}\r\n >\r\n {radiusOptions.map((option) => {\r\n const isSelected = option.key === currentKey\r\n const cardRadius =\r\n option.css['--radius-large'] ??\r\n option.css['--radius-default'] ??\r\n option.css['--radius-medium']\r\n const chipRadius = option.css['--radius-default'] ?? option.css['--radius-small']\r\n const pillRadius = option.css['--radius-xl'] ?? option.css['--radius-large'] ?? '999px'\r\n\r\n return (\r\n <button\r\n key={option.key}\r\n type=\"button\"\r\n onClick={() => setValue(option.key)}\r\n aria-pressed={isSelected}\r\n style={{\r\n border: isSelected\r\n ? '2px solid var(--theme-success-500)'\r\n : '1px solid var(--theme-elevation-150)',\r\n borderRadius: '14px',\r\n backgroundColor: 'var(--theme-elevation-25)',\r\n padding: '16px',\r\n display: 'grid',\r\n gap: '10px',\r\n textAlign: 'left',\r\n cursor: 'pointer',\r\n transition: 'border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease',\r\n boxShadow: isSelected\r\n ? '0 10px 20px rgba(34, 197, 94, 0.18)'\r\n : '0 6px 18px rgba(15, 23, 42, 0.08)',\r\n transform: isSelected ? 'translateY(-2px)' : 'translateY(0)',\r\n }}\r\n >\r\n <div\r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n fontWeight: 600,\r\n fontSize: '13px',\r\n color: 'var(--theme-elevation-800)',\r\n }}\r\n >\r\n <span>{option.label}</span>\r\n <span style={{ fontSize: '11px', opacity: 0.7 }}>{option.key}</span>\r\n </div>\r\n\r\n <div\r\n style={{\r\n display: 'grid',\r\n gap: '10px',\r\n }}\r\n >\r\n <div\r\n style={{\r\n display: 'flex',\r\n gap: '8px',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: '50px',\r\n height: '34px',\r\n backgroundColor: 'var(--theme-elevation-100)',\r\n border: '1px solid var(--theme-elevation-200)',\r\n borderRadius: cardRadius ?? '0',\r\n }}\r\n />\r\n <div\r\n style={{\r\n flex: 1,\r\n height: '14px',\r\n backgroundColor: 'var(--theme-primary-500)',\r\n borderRadius: pillRadius,\r\n }}\r\n />\r\n </div>\r\n\r\n <div\r\n style={{\r\n display: 'flex',\r\n gap: '6px',\r\n flexWrap: 'wrap',\r\n fontSize: '11px',\r\n color: 'var(--theme-elevation-600)',\r\n }}\r\n >\r\n <span>Card {cardRadius ?? '—'}</span>\r\n <span>Chip {chipRadius ?? '—'}</span>\r\n <span>Pill {pillRadius}</span>\r\n </div>\r\n </div>\r\n </button>\r\n )\r\n })}\r\n </div>\r\n\r\n <input type=\"hidden\" id={props.path} value={currentKey} readOnly />\r\n </div>\r\n )\r\n}\r\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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"}
|