@kilivi/payloadcms-theme-management 0.3.1 → 0.3.3

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.
Files changed (47) hide show
  1. package/dist/fields/ColorPickerField.js +1 -1
  2. package/dist/fields/ColorPickerField.js.map +1 -1
  3. package/dist/fields/ThemeTokenSelectField.d.ts.map +1 -1
  4. package/dist/fields/ThemeTokenSelectField.js +1 -1
  5. package/dist/fields/ThemeTokenSelectField.js.map +1 -1
  6. package/dist/fields/themeConfigurationField.d.ts +3 -2
  7. package/dist/fields/themeConfigurationField.d.ts.map +1 -1
  8. package/dist/fields/themeConfigurationField.js +236 -274
  9. package/dist/fields/themeConfigurationField.js.map +1 -1
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +61 -10
  13. package/dist/index.js.map +1 -1
  14. package/package.json +1 -1
  15. package/dist/fields/ExtendedThemeAutoPopulateField.d.ts +0 -12
  16. package/dist/fields/ExtendedThemeAutoPopulateField.d.ts.map +0 -1
  17. package/dist/fields/ExtendedThemeAutoPopulateField.js +0 -176
  18. package/dist/fields/ExtendedThemeAutoPopulateField.js.map +0 -1
  19. package/dist/fields/RadiusField.d.ts +0 -3
  20. package/dist/fields/RadiusField.d.ts.map +0 -1
  21. package/dist/fields/RadiusField.js +0 -174
  22. package/dist/fields/RadiusField.js.map +0 -1
  23. package/dist/fields/ThemeLivePreview.css +0 -190
  24. package/dist/fields/ThemeLivePreview.d.ts +0 -3
  25. package/dist/fields/ThemeLivePreview.d.ts.map +0 -1
  26. package/dist/fields/ThemeLivePreview.js +0 -195
  27. package/dist/fields/ThemeLivePreview.js.map +0 -1
  28. package/dist/fields/VISUAL_EXAMPLES.d.ts +0 -153
  29. package/dist/fields/VISUAL_EXAMPLES.d.ts.map +0 -1
  30. package/dist/fields/VISUAL_EXAMPLES.js +0 -148
  31. package/dist/fields/VISUAL_EXAMPLES.js.map +0 -1
  32. package/dist/fields/extendedThemeFields.d.ts +0 -139
  33. package/dist/fields/extendedThemeFields.d.ts.map +0 -1
  34. package/dist/fields/extendedThemeFields.js +0 -489
  35. package/dist/fields/extendedThemeFields.js.map +0 -1
  36. package/dist/views/ThemePreviewLoader.d.ts +0 -7
  37. package/dist/views/ThemePreviewLoader.d.ts.map +0 -1
  38. package/dist/views/ThemePreviewLoader.js +0 -43
  39. package/dist/views/ThemePreviewLoader.js.map +0 -1
  40. package/dist/views/ThemePreviewView.d.ts +0 -10
  41. package/dist/views/ThemePreviewView.d.ts.map +0 -1
  42. package/dist/views/ThemePreviewView.js +0 -43
  43. package/dist/views/ThemePreviewView.js.map +0 -1
  44. package/dist/views/ThemePreviewViewClient.d.ts +0 -7
  45. package/dist/views/ThemePreviewViewClient.d.ts.map +0 -1
  46. package/dist/views/ThemePreviewViewClient.js +0 -12
  47. package/dist/views/ThemePreviewViewClient.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export declare const getThemePreset: (themeName: string) => ThemePreset | null;
9
9
  export declare const getAvailableThemePresets: () => ThemePreset[];
10
10
  export { defaultThemePresets } from './presets.js';
11
11
  export type { ThemePreset, ThemeTypographyPreset } from './presets.js';
12
+ export type { ThemeTab } from './fields/themeConfigurationField.js';
12
13
  export { extendedThemePresets, allExtendedThemePresets, extendedThemeToCSSVariables, } from './extended-presets.js';
13
14
  export type { ExtendedThemePreset, ShadcnColorTokens } from './extended-presets.js';
14
15
  export { applyExtendedTheme, generateExtendedThemeCSS, resetExtendedTheme, getExtendedThemeTokens, createUseExtendedTheme, getTailwindVarReferences, } from './utils/extendedThemeHelpers.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,MAAM,EAAE,MAAM,SAAS,CAAA;AAEtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,KAAK,EAAE,8BAA8B,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAA;AA2B9F,eAAO,MAAM,qBAAqB,GAAI,UAAS,4BAAiC,KAAG,MAmElF,CAAA;AAED,KAAK,iBAAiB,GAAG,MAAM,GAAG,8BAA8B,CAAA;AAEhE,eAAO,MAAM,uBAAuB,GAClC,UAAU,iBAAiB,KAC1B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CA2CvC,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,WAAW,MAAM,KAAG,WAAW,GAAG,IAEhE,CAAA;AAED,eAAO,MAAM,wBAAwB,QAAO,WAAW,EAEtD,CAAA;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAClD,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACtE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACnF,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,iCAAiC,CAAA;AACxC,YAAY,EAAE,4BAA4B,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAA;AAC9F,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,sCAAsC,CAAA;AAC7C,YAAY,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAA;AACtF,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAEvE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAG1D,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,GAChB,MAAM,4BAA4B,CAAA;AAMnC,eAAO,MAAM,qBAAqB,aAxKa,4BAA4B,KAAQ,MAwKzB,CAAA;AAC1D,oDAAoD;AACpD,eAAO,MAAM,wBAAwB,aA1KU,4BAA4B,KAAQ,MA0KtB,CAAA;AAE7D,eAAe,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,MAAM,EAAa,MAAM,SAAS,CAAA;AAGjF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,KAAK,EAAE,8BAA8B,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAA;AA6F9F,eAAO,MAAM,qBAAqB,GAAI,UAAS,4BAAiC,KAAG,MAmElF,CAAA;AAED,KAAK,iBAAiB,GAAG,MAAM,GAAG,8BAA8B,CAAA;AAEhE,eAAO,MAAM,uBAAuB,GAClC,UAAU,iBAAiB,KAC1B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CA2CvC,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,WAAW,MAAM,KAAG,WAAW,GAAG,IAEhE,CAAA;AAED,eAAO,MAAM,wBAAwB,QAAO,WAAW,EAEtD,CAAA;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAClD,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACtE,YAAY,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAA;AACnE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACnF,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,iCAAiC,CAAA;AACxC,YAAY,EAAE,4BAA4B,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAA;AAC9F,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,sCAAsC,CAAA;AAC7C,YAAY,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAA;AACtF,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAEvE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAG1D,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,GAChB,MAAM,4BAA4B,CAAA;AAMnC,eAAO,MAAM,qBAAqB,aAzKa,4BAA4B,KAAQ,MAyKzB,CAAA;AAC1D,oDAAoD;AACpD,eAAO,MAAM,wBAAwB,aA3KU,4BAA4B,KAAQ,MA2KtB,CAAA;AAE7D,eAAe,qBAAqB,CAAA"}
package/dist/index.js CHANGED
@@ -1,19 +1,70 @@
1
1
  import { createThemeConfigurationField } from './fields/themeConfigurationField.js';
2
2
  import { defaultThemePresets } from './presets.js';
3
3
  const THEME_FIELD_NAME = 'themeConfiguration';
4
- const removeExistingThemeField = (fields = [])=>fields.filter((field)=>{
4
+ /**
5
+ * Removes existing theme configuration from a group field (legacy)
6
+ */ const removeExistingThemeField = (fields = [])=>fields.filter((field)=>{
5
7
  const candidate = field;
6
8
  return candidate?.name !== THEME_FIELD_NAME;
7
9
  });
8
- const upsertThemeField = (fields, themeField, enableLogging)=>{
9
- const sanitized = removeExistingThemeField(fields ?? []);
10
- if (enableLogging) {
11
- console.log('🎨 Theme Management Plugin: injecting theme configuration field');
10
+ /**
11
+ * Finds the tabs field in the collection fields array
12
+ */ const findTabsField = (fields = [])=>{
13
+ for (const field of fields){
14
+ if (field.type === 'tabs') {
15
+ return field;
16
+ }
12
17
  }
13
- return [
14
- ...sanitized,
15
- themeField
18
+ return null;
19
+ };
20
+ /**
21
+ * Removes existing Appearance Settings tab if it exists
22
+ */ const removeExistingThemeTab = (tabs)=>{
23
+ return tabs.filter((tab)=>{
24
+ const labelEn = typeof tab.label === 'object' && tab.label !== null ? tab.label.en : tab.label;
25
+ return labelEn !== '🎨 Appearance Settings' && labelEn !== 'Appearance Settings';
26
+ });
27
+ };
28
+ /**
29
+ * Injects theme tab into existing tabs field
30
+ */ const injectThemeTab = (fields, themeTab, enableLogging)=>{
31
+ // First, remove any legacy theme field (group-based)
32
+ const sanitizedFields = removeExistingThemeField(fields ?? []);
33
+ // Find the tabs field
34
+ const tabsField = findTabsField(sanitizedFields);
35
+ if (!tabsField || !tabsField.tabs) {
36
+ if (enableLogging) {
37
+ console.warn('🎨 Theme Management Plugin: No tabs field found. Creating a new tabs structure.');
38
+ }
39
+ // If no tabs exist, create a basic tabs structure with just the theme tab
40
+ const newTabsField = {
41
+ type: 'tabs',
42
+ tabs: [
43
+ themeTab
44
+ ]
45
+ };
46
+ return [
47
+ ...sanitizedFields,
48
+ newTabsField
49
+ ];
50
+ }
51
+ // Remove existing theme tab if present
52
+ const sanitizedTabs = removeExistingThemeTab(tabsField.tabs);
53
+ // Add theme tab to the end
54
+ const updatedTabs = [
55
+ ...sanitizedTabs,
56
+ themeTab
16
57
  ];
58
+ if (enableLogging) {
59
+ console.log('🎨 Theme Management Plugin: injecting Appearance Settings tab');
60
+ }
61
+ // Update the tabs field
62
+ const updatedTabsField = {
63
+ ...tabsField,
64
+ tabs: updatedTabs
65
+ };
66
+ // Replace the old tabs field with the updated one
67
+ return sanitizedFields.map((field)=>field.type === 'tabs' ? updatedTabsField : field);
17
68
  };
18
69
  const ensureCollectionsArray = (collections)=>Array.isArray(collections) ? collections : [];
19
70
  export const themeManagementPlugin = (options = {})=>{
@@ -25,7 +76,7 @@ export const themeManagementPlugin = (options = {})=>{
25
76
  }
26
77
  return config;
27
78
  }
28
- const themeField = createThemeConfigurationField({
79
+ const themeTab = createThemeConfigurationField({
29
80
  themePresets,
30
81
  defaultTheme,
31
82
  includeColorModeToggle,
@@ -43,7 +94,7 @@ export const themeManagementPlugin = (options = {})=>{
43
94
  console.log(`🎨 Theme Management Plugin: enhancing collection "${collection.slug}"`);
44
95
  }
45
96
  const existingFields = Array.isArray(collection.fields) ? collection.fields : [];
46
- const fields = upsertThemeField(existingFields, themeField, enableLogging);
97
+ const fields = injectThemeTab(existingFields, themeTab, enableLogging);
47
98
  return {
48
99
  ...collection,
49
100
  fields
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config, Field, Plugin } from 'payload'\nimport { createThemeConfigurationField } from './fields/themeConfigurationField.js'\nimport type { SiteThemeConfiguration } from './payload-types.js'\nimport type { ThemePreset } from './presets.js'\nimport { defaultThemePresets } from './presets.js'\nimport type { FetchThemeConfigurationOptions, ThemeManagementPluginOptions } from './types.js'\n\nconst THEME_FIELD_NAME = 'themeConfiguration'\n\nconst removeExistingThemeField = (fields: Field[] = []): Field[] =>\n fields.filter((field) => {\n const candidate = field as { name?: unknown }\n return candidate?.name !== THEME_FIELD_NAME\n })\n\nconst upsertThemeField = (\n fields: Field[] | undefined,\n themeField: Field,\n enableLogging: boolean,\n): Field[] => {\n const sanitized = removeExistingThemeField(fields ?? [])\n\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: injecting theme configuration field')\n }\n\n return [...sanitized, themeField]\n}\n\nconst ensureCollectionsArray = (collections: Config['collections']): CollectionConfig[] =>\n Array.isArray(collections) ? collections : []\n\nexport const themeManagementPlugin = (options: ThemeManagementPluginOptions = {}): Plugin => {\n return (config: Config): Config => {\n const {\n enabled = true,\n targetCollection = 'site-settings',\n themePresets = defaultThemePresets,\n defaultTheme = 'cool',\n includeColorModeToggle = true,\n includeCustomCSS = true,\n includeBrandIdentity = false,\n enableAdvancedFeatures = true,\n enableLogging = false,\n } = options\n\n if (!enabled) {\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: disabled via options, skipping.')\n }\n return config\n }\n\n const themeField = createThemeConfigurationField({\n themePresets,\n defaultTheme,\n includeColorModeToggle,\n includeCustomCSS,\n includeBrandIdentity: includeBrandIdentity ?? false,\n enableAdvancedFeatures,\n })\n\n let collectionTouched = false\n\n const collections = ensureCollectionsArray(config.collections).map((collection) => {\n if (collection.slug !== targetCollection) {\n return collection\n }\n\n collectionTouched = true\n\n if (enableLogging) {\n console.log(`🎨 Theme Management Plugin: enhancing collection \"${collection.slug}\"`)\n }\n\n const existingFields = Array.isArray(collection.fields) ? collection.fields : []\n\n const fields = upsertThemeField(existingFields, themeField, enableLogging)\n\n return {\n ...collection,\n fields,\n }\n })\n\n if (!collectionTouched) {\n if (enableLogging) {\n console.warn(\n `🎨 Theme Management Plugin: collection \"${targetCollection}\" was not found, leaving config untouched.`,\n )\n }\n return config\n }\n\n return {\n ...config,\n collections,\n }\n }\n}\n\ntype FetchOptionsInput = string | FetchThemeConfigurationOptions\n\nexport const fetchThemeConfiguration = async (\n options?: FetchOptionsInput,\n): Promise<SiteThemeConfiguration | null> => {\n const normalizedOptions = typeof options === 'string' ? { tenantSlug: options } : (options ?? {})\n\n const {\n tenantSlug,\n collectionSlug = 'site-settings',\n depth,\n locale,\n draft,\n queryParams = {},\n } = normalizedOptions\n\n const params = new URLSearchParams({ limit: '1' })\n\n if (typeof depth === 'number') params.set('depth', String(depth))\n if (tenantSlug) params.set('tenant', tenantSlug)\n if (locale) params.set('locale', locale)\n if (draft) params.set('draft', 'true')\n\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value === undefined) return\n params.set(key, String(value))\n })\n\n const url = `/api/${collectionSlug}?${params.toString()}`\n\n try {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch theme configuration (status ${response.status})`)\n }\n\n const data = (await response.json()) as {\n docs?: Array<{ themeConfiguration?: SiteThemeConfiguration }>\n }\n\n const doc = data.docs?.[0]\n\n return doc?.themeConfiguration ?? null\n } catch (error) {\n console.warn('Failed to fetch theme configuration:', error)\n return null\n }\n}\n\nexport const getThemePreset = (themeName: string): ThemePreset | null => {\n return defaultThemePresets.find((preset) => preset.name === themeName) || null\n}\n\nexport const getAvailableThemePresets = (): ThemePreset[] => {\n return defaultThemePresets\n}\n\nexport { defaultThemePresets } from './presets.js'\nexport type { ThemePreset, ThemeTypographyPreset } from './presets.js'\nexport {\n extendedThemePresets,\n allExtendedThemePresets,\n extendedThemeToCSSVariables,\n} from './extended-presets.js'\nexport type { ExtendedThemePreset, ShadcnColorTokens } from './extended-presets.js'\nexport {\n applyExtendedTheme,\n generateExtendedThemeCSS,\n resetExtendedTheme,\n getExtendedThemeTokens,\n createUseExtendedTheme,\n getTailwindVarReferences,\n} from './utils/extendedThemeHelpers.js'\nexport type { ThemeManagementPluginOptions, FetchThemeConfigurationOptions } from './types.js'\nexport {\n DEFAULT_THEME_CONFIGURATION,\n resolveThemeConfiguration,\n} from './utils/resolveThemeConfiguration.js'\nexport type { ResolvedThemeConfiguration } from './utils/resolveThemeConfiguration.js'\nexport { generateThemeColorsCss, hexToHsl } from './utils/themeColors.js'\nexport { generateThemeCSS, getThemeStyles } from './utils/themeUtils.js'\nexport { getThemeHtmlAttributes } from './utils/themeHtmlAttributes.js'\n\nexport type { Mode, ThemeDefaults } from './providers/Theme/types.js'\nexport { ThemeProvider } from './providers/Theme/index.js'\n\n// Font loading utilities for Next.js integration\nexport {\n getFontLoaderCode,\n getThemeFontFamilies,\n ThemeFontProvider,\n useThemeFonts,\n FONT_IMPORT_MAP,\n} from './providers/font-loader.js'\n\n// Note: Do NOT re-export client components from the root entry to avoid\n// server-side evaluation during `payload generate:importmap`.\n// If needed, import directly from subpath: `@kilivi/payloadcms-theme-management/fields/ThemeLivePreview`\n\nexport const ThemeManagementPlugin = themeManagementPlugin\n/** @deprecated use {@link themeManagementPlugin} */\nexport const themeConfigurationPlugin = themeManagementPlugin\n\nexport default themeManagementPlugin\n"],"names":["createThemeConfigurationField","defaultThemePresets","THEME_FIELD_NAME","removeExistingThemeField","fields","filter","field","candidate","name","upsertThemeField","themeField","enableLogging","sanitized","console","log","ensureCollectionsArray","collections","Array","isArray","themeManagementPlugin","options","config","enabled","targetCollection","themePresets","defaultTheme","includeColorModeToggle","includeCustomCSS","includeBrandIdentity","enableAdvancedFeatures","collectionTouched","map","collection","slug","existingFields","warn","fetchThemeConfiguration","normalizedOptions","tenantSlug","collectionSlug","depth","locale","draft","queryParams","params","URLSearchParams","limit","set","String","Object","entries","forEach","key","value","undefined","url","toString","response","fetch","ok","Error","status","data","json","doc","docs","themeConfiguration","error","getThemePreset","themeName","find","preset","getAvailableThemePresets","extendedThemePresets","allExtendedThemePresets","extendedThemeToCSSVariables","applyExtendedTheme","generateExtendedThemeCSS","resetExtendedTheme","getExtendedThemeTokens","createUseExtendedTheme","getTailwindVarReferences","DEFAULT_THEME_CONFIGURATION","resolveThemeConfiguration","generateThemeColorsCss","hexToHsl","generateThemeCSS","getThemeStyles","getThemeHtmlAttributes","ThemeProvider","getFontLoaderCode","getThemeFontFamilies","ThemeFontProvider","useThemeFonts","FONT_IMPORT_MAP","ThemeManagementPlugin","themeConfigurationPlugin"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config, Field, Plugin, TabsField } from 'payload'\nimport { createThemeConfigurationField } from './fields/themeConfigurationField.js'\nimport type { ThemeTab } from './fields/themeConfigurationField.js'\nimport type { SiteThemeConfiguration } from './payload-types.js'\nimport type { ThemePreset } from './presets.js'\nimport { defaultThemePresets } from './presets.js'\nimport type { FetchThemeConfigurationOptions, ThemeManagementPluginOptions } from './types.js'\n\nconst THEME_FIELD_NAME = 'themeConfiguration'\n\n/**\n * Removes existing theme configuration from a group field (legacy)\n */\nconst removeExistingThemeField = (fields: Field[] = []): Field[] =>\n fields.filter((field) => {\n const candidate = field as { name?: unknown }\n return candidate?.name !== THEME_FIELD_NAME\n })\n\n/**\n * Finds the tabs field in the collection fields array\n */\nconst findTabsField = (fields: Field[] = []): TabsField | null => {\n for (const field of fields) {\n if (field.type === 'tabs') {\n return field as TabsField\n }\n }\n return null\n}\n\n/**\n * Removes existing Appearance Settings tab if it exists\n */\nconst removeExistingThemeTab = (\n tabs: NonNullable<TabsField['tabs']>,\n): NonNullable<TabsField['tabs']> => {\n return tabs.filter((tab) => {\n const labelEn =\n typeof tab.label === 'object' && tab.label !== null\n ? (tab.label as { en?: string }).en\n : tab.label\n return labelEn !== '🎨 Appearance Settings' && labelEn !== 'Appearance Settings'\n })\n}\n\n/**\n * Injects theme tab into existing tabs field\n */\nconst injectThemeTab = (\n fields: Field[] | undefined,\n themeTab: ThemeTab,\n enableLogging: boolean,\n): Field[] => {\n // First, remove any legacy theme field (group-based)\n const sanitizedFields = removeExistingThemeField(fields ?? [])\n\n // Find the tabs field\n const tabsField = findTabsField(sanitizedFields)\n\n if (!tabsField || !tabsField.tabs) {\n if (enableLogging) {\n console.warn(\n '🎨 Theme Management Plugin: No tabs field found. Creating a new tabs structure.',\n )\n }\n\n // If no tabs exist, create a basic tabs structure with just the theme tab\n const newTabsField: TabsField = {\n type: 'tabs',\n tabs: [themeTab],\n }\n\n return [...sanitizedFields, newTabsField]\n }\n\n // Remove existing theme tab if present\n const sanitizedTabs = removeExistingThemeTab(tabsField.tabs)\n\n // Add theme tab to the end\n const updatedTabs = [...sanitizedTabs, themeTab]\n\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: injecting Appearance Settings tab')\n }\n\n // Update the tabs field\n const updatedTabsField: TabsField = {\n ...tabsField,\n tabs: updatedTabs,\n }\n\n // Replace the old tabs field with the updated one\n return sanitizedFields.map((field) => (field.type === 'tabs' ? updatedTabsField : field))\n}\n\nconst ensureCollectionsArray = (collections: Config['collections']): CollectionConfig[] =>\n Array.isArray(collections) ? collections : []\n\nexport const themeManagementPlugin = (options: ThemeManagementPluginOptions = {}): Plugin => {\n return (config: Config): Config => {\n const {\n enabled = true,\n targetCollection = 'site-settings',\n themePresets = defaultThemePresets,\n defaultTheme = 'cool',\n includeColorModeToggle = true,\n includeCustomCSS = true,\n includeBrandIdentity = false,\n enableAdvancedFeatures = true,\n enableLogging = false,\n } = options\n\n if (!enabled) {\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: disabled via options, skipping.')\n }\n return config\n }\n\n const themeTab = createThemeConfigurationField({\n themePresets,\n defaultTheme,\n includeColorModeToggle,\n includeCustomCSS,\n includeBrandIdentity: includeBrandIdentity ?? false,\n enableAdvancedFeatures,\n })\n\n let collectionTouched = false\n\n const collections = ensureCollectionsArray(config.collections).map((collection) => {\n if (collection.slug !== targetCollection) {\n return collection\n }\n\n collectionTouched = true\n\n if (enableLogging) {\n console.log(`🎨 Theme Management Plugin: enhancing collection \"${collection.slug}\"`)\n }\n\n const existingFields = Array.isArray(collection.fields) ? collection.fields : []\n\n const fields = injectThemeTab(existingFields, themeTab, enableLogging)\n\n return {\n ...collection,\n fields,\n }\n })\n\n if (!collectionTouched) {\n if (enableLogging) {\n console.warn(\n `🎨 Theme Management Plugin: collection \"${targetCollection}\" was not found, leaving config untouched.`,\n )\n }\n return config\n }\n\n return {\n ...config,\n collections,\n }\n }\n}\n\ntype FetchOptionsInput = string | FetchThemeConfigurationOptions\n\nexport const fetchThemeConfiguration = async (\n options?: FetchOptionsInput,\n): Promise<SiteThemeConfiguration | null> => {\n const normalizedOptions = typeof options === 'string' ? { tenantSlug: options } : (options ?? {})\n\n const {\n tenantSlug,\n collectionSlug = 'site-settings',\n depth,\n locale,\n draft,\n queryParams = {},\n } = normalizedOptions\n\n const params = new URLSearchParams({ limit: '1' })\n\n if (typeof depth === 'number') params.set('depth', String(depth))\n if (tenantSlug) params.set('tenant', tenantSlug)\n if (locale) params.set('locale', locale)\n if (draft) params.set('draft', 'true')\n\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value === undefined) return\n params.set(key, String(value))\n })\n\n const url = `/api/${collectionSlug}?${params.toString()}`\n\n try {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch theme configuration (status ${response.status})`)\n }\n\n const data = (await response.json()) as {\n docs?: Array<{ themeConfiguration?: SiteThemeConfiguration }>\n }\n\n const doc = data.docs?.[0]\n\n return doc?.themeConfiguration ?? null\n } catch (error) {\n console.warn('Failed to fetch theme configuration:', error)\n return null\n }\n}\n\nexport const getThemePreset = (themeName: string): ThemePreset | null => {\n return defaultThemePresets.find((preset) => preset.name === themeName) || null\n}\n\nexport const getAvailableThemePresets = (): ThemePreset[] => {\n return defaultThemePresets\n}\n\nexport { defaultThemePresets } from './presets.js'\nexport type { ThemePreset, ThemeTypographyPreset } from './presets.js'\nexport type { ThemeTab } from './fields/themeConfigurationField.js'\nexport {\n extendedThemePresets,\n allExtendedThemePresets,\n extendedThemeToCSSVariables,\n} from './extended-presets.js'\nexport type { ExtendedThemePreset, ShadcnColorTokens } from './extended-presets.js'\nexport {\n applyExtendedTheme,\n generateExtendedThemeCSS,\n resetExtendedTheme,\n getExtendedThemeTokens,\n createUseExtendedTheme,\n getTailwindVarReferences,\n} from './utils/extendedThemeHelpers.js'\nexport type { ThemeManagementPluginOptions, FetchThemeConfigurationOptions } from './types.js'\nexport {\n DEFAULT_THEME_CONFIGURATION,\n resolveThemeConfiguration,\n} from './utils/resolveThemeConfiguration.js'\nexport type { ResolvedThemeConfiguration } from './utils/resolveThemeConfiguration.js'\nexport { generateThemeColorsCss, hexToHsl } from './utils/themeColors.js'\nexport { generateThemeCSS, getThemeStyles } from './utils/themeUtils.js'\nexport { getThemeHtmlAttributes } from './utils/themeHtmlAttributes.js'\n\nexport type { Mode, ThemeDefaults } from './providers/Theme/types.js'\nexport { ThemeProvider } from './providers/Theme/index.js'\n\n// Font loading utilities for Next.js integration\nexport {\n getFontLoaderCode,\n getThemeFontFamilies,\n ThemeFontProvider,\n useThemeFonts,\n FONT_IMPORT_MAP,\n} from './providers/font-loader.js'\n\n// Note: Do NOT re-export client components from the root entry to avoid\n// server-side evaluation during `payload generate:importmap`.\n// If needed, import directly from subpath: `@kilivi/payloadcms-theme-management/fields/ThemeLivePreview`\n\nexport const ThemeManagementPlugin = themeManagementPlugin\n/** @deprecated use {@link themeManagementPlugin} */\nexport const themeConfigurationPlugin = themeManagementPlugin\n\nexport default themeManagementPlugin\n"],"names":["createThemeConfigurationField","defaultThemePresets","THEME_FIELD_NAME","removeExistingThemeField","fields","filter","field","candidate","name","findTabsField","type","removeExistingThemeTab","tabs","tab","labelEn","label","en","injectThemeTab","themeTab","enableLogging","sanitizedFields","tabsField","console","warn","newTabsField","sanitizedTabs","updatedTabs","log","updatedTabsField","map","ensureCollectionsArray","collections","Array","isArray","themeManagementPlugin","options","config","enabled","targetCollection","themePresets","defaultTheme","includeColorModeToggle","includeCustomCSS","includeBrandIdentity","enableAdvancedFeatures","collectionTouched","collection","slug","existingFields","fetchThemeConfiguration","normalizedOptions","tenantSlug","collectionSlug","depth","locale","draft","queryParams","params","URLSearchParams","limit","set","String","Object","entries","forEach","key","value","undefined","url","toString","response","fetch","ok","Error","status","data","json","doc","docs","themeConfiguration","error","getThemePreset","themeName","find","preset","getAvailableThemePresets","extendedThemePresets","allExtendedThemePresets","extendedThemeToCSSVariables","applyExtendedTheme","generateExtendedThemeCSS","resetExtendedTheme","getExtendedThemeTokens","createUseExtendedTheme","getTailwindVarReferences","DEFAULT_THEME_CONFIGURATION","resolveThemeConfiguration","generateThemeColorsCss","hexToHsl","generateThemeCSS","getThemeStyles","getThemeHtmlAttributes","ThemeProvider","getFontLoaderCode","getThemeFontFamilies","ThemeFontProvider","useThemeFonts","FONT_IMPORT_MAP","ThemeManagementPlugin","themeConfigurationPlugin"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kilivi/payloadcms-theme-management",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Theme configuration plugin for Payload CMS v3",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,12 +0,0 @@
1
- import type { SelectFieldClientComponent } from 'payload';
2
- /**
3
- * Extended Theme Field with Auto-Population
4
- *
5
- * This component:
6
- * 1. Shows color swatches for each theme option
7
- * 2. Auto-populates ALL color fields when a theme is selected
8
- * 3. Fills in ALL light mode and dark mode colors with preset defaults
9
- */
10
- declare const ExtendedThemeAutoPopulateField: SelectFieldClientComponent;
11
- export default ExtendedThemeAutoPopulateField;
12
- //# sourceMappingURL=ExtendedThemeAutoPopulateField.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExtendedThemeAutoPopulateField.d.ts","sourceRoot":"","sources":["../../src/fields/ExtendedThemeAutoPopulateField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAIzD;;;;;;;GAOG;AACH,QAAA,MAAM,8BAA8B,EAAE,0BAsLrC,CAAA;AAED,eAAe,8BAA8B,CAAA"}
@@ -1,176 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useField, useForm } from '@payloadcms/ui';
4
- import { useCallback, useEffect, useRef } from 'react';
5
- import { allExtendedThemePresets } from '../extended-presets.js';
6
- /**
7
- * Extended Theme Field with Auto-Population
8
- *
9
- * This component:
10
- * 1. Shows color swatches for each theme option
11
- * 2. Auto-populates ALL color fields when a theme is selected
12
- * 3. Fills in ALL light mode and dark mode colors with preset defaults
13
- */ const ExtendedThemeAutoPopulateField = ({ field, path })=>{
14
- const { value, setValue } = useField({
15
- path
16
- });
17
- const { dispatchFields } = useForm();
18
- const hasInitializedRef = useRef(false);
19
- const options = field.options || [];
20
- const selectedOption = options.find((opt)=>opt.value === value);
21
- // Auto-populate colors when theme is selected
22
- const applyThemePreset = useCallback((presetKey)=>{
23
- const preset = allExtendedThemePresets[presetKey];
24
- if (!preset) return;
25
- // Apply all light mode colors
26
- Object.entries(preset.styles.light).forEach(([key, colorValue])=>{
27
- dispatchFields({
28
- type: 'UPDATE',
29
- path: `themeConfiguration.extendedLightMode.${key}`,
30
- value: colorValue
31
- });
32
- });
33
- // Apply all dark mode colors
34
- Object.entries(preset.styles.dark).forEach(([key, colorValue])=>{
35
- dispatchFields({
36
- type: 'UPDATE',
37
- path: `themeConfiguration.extendedDarkMode.${key}`,
38
- value: colorValue
39
- });
40
- });
41
- }, [
42
- dispatchFields
43
- ]);
44
- const handleChange = useCallback((newValue)=>{
45
- setValue(newValue);
46
- if (newValue) {
47
- applyThemePreset(newValue);
48
- }
49
- }, [
50
- setValue,
51
- applyThemePreset
52
- ]);
53
- // Auto-populate on initial load if value exists
54
- useEffect(()=>{
55
- if (!hasInitializedRef.current && value) {
56
- applyThemePreset(value);
57
- hasInitializedRef.current = true;
58
- }
59
- }, [
60
- value,
61
- applyThemePreset
62
- ]);
63
- // Get color swatches for a preset
64
- const getPresetColors = (presetValue)=>{
65
- const preset = allExtendedThemePresets[presetValue];
66
- if (!preset) return [];
67
- const colors = [
68
- preset.styles.light.primary,
69
- preset.styles.light.secondary,
70
- preset.styles.light.accent,
71
- preset.styles.light.background,
72
- preset.styles.light.foreground
73
- ].filter(Boolean);
74
- return colors.slice(0, 5);
75
- };
76
- const label = typeof field.label === 'string' ? field.label : field.label?.en || field.label?.cs || 'Theme Preset';
77
- const description = typeof field.admin?.description === 'string' ? field.admin.description : field.admin?.description?.en || field.admin?.description?.cs;
78
- return /*#__PURE__*/ _jsxs("div", {
79
- style: {
80
- marginBottom: '16px'
81
- },
82
- children: [
83
- /*#__PURE__*/ _jsx("label", {
84
- style: {
85
- display: 'block',
86
- marginBottom: '6px',
87
- fontSize: '13px',
88
- fontWeight: 600,
89
- color: 'var(--theme-elevation-800)'
90
- },
91
- children: label
92
- }),
93
- description && /*#__PURE__*/ _jsx("div", {
94
- style: {
95
- fontSize: '12px',
96
- color: 'var(--theme-elevation-500)',
97
- marginBottom: '8px'
98
- },
99
- children: description
100
- }),
101
- /*#__PURE__*/ _jsxs("select", {
102
- value: value || '',
103
- onChange: (e)=>handleChange(e.target.value),
104
- style: {
105
- width: '100%',
106
- padding: '10px 12px',
107
- borderRadius: '6px',
108
- border: '1px solid var(--theme-elevation-200)',
109
- backgroundColor: 'var(--theme-input-bg)',
110
- color: 'var(--theme-elevation-800)',
111
- fontSize: '14px',
112
- cursor: 'pointer'
113
- },
114
- children: [
115
- /*#__PURE__*/ _jsx("option", {
116
- value: "",
117
- children: "Select a theme..."
118
- }),
119
- options.map((option)=>/*#__PURE__*/ _jsx("option", {
120
- value: option.value,
121
- children: option.label
122
- }, option.value))
123
- ]
124
- }),
125
- selectedOption && /*#__PURE__*/ _jsxs("div", {
126
- style: {
127
- marginTop: '12px',
128
- padding: '12px',
129
- borderRadius: '8px',
130
- backgroundColor: 'var(--theme-elevation-50)',
131
- border: '1px solid var(--theme-elevation-200)'
132
- },
133
- children: [
134
- /*#__PURE__*/ _jsx("div", {
135
- style: {
136
- fontSize: '12px',
137
- fontWeight: 600,
138
- marginBottom: '8px',
139
- color: 'var(--theme-elevation-700)'
140
- },
141
- children: selectedOption.label
142
- }),
143
- /*#__PURE__*/ _jsx("div", {
144
- style: {
145
- display: 'flex',
146
- gap: '8px',
147
- alignItems: 'center'
148
- },
149
- children: getPresetColors(selectedOption.value).map((color, index)=>/*#__PURE__*/ _jsx("div", {
150
- style: {
151
- width: '32px',
152
- height: '32px',
153
- borderRadius: '6px',
154
- backgroundColor: color,
155
- border: '1px solid rgba(0, 0, 0, 0.1)',
156
- boxShadow: '0 2px 4px rgba(0, 0, 0, 0.05)'
157
- },
158
- title: color
159
- }, `${selectedOption.value}-${index}`))
160
- }),
161
- /*#__PURE__*/ _jsx("div", {
162
- style: {
163
- marginTop: '8px',
164
- fontSize: '11px',
165
- color: 'var(--theme-elevation-500)'
166
- },
167
- children: "✅ All colors auto-populated from this theme"
168
- })
169
- ]
170
- })
171
- ]
172
- });
173
- };
174
- export default ExtendedThemeAutoPopulateField;
175
-
176
- //# sourceMappingURL=ExtendedThemeAutoPopulateField.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/fields/ExtendedThemeAutoPopulateField.tsx"],"sourcesContent":["'use client'\n\nimport { useField, useForm } from '@payloadcms/ui'\nimport type { SelectFieldClientComponent } from 'payload'\nimport { useCallback, useEffect, useRef } from 'react'\nimport { allExtendedThemePresets } from '../extended-presets.js'\n\n/**\n * Extended Theme Field with Auto-Population\n *\n * This component:\n * 1. Shows color swatches for each theme option\n * 2. Auto-populates ALL color fields when a theme is selected\n * 3. Fills in ALL light mode and dark mode colors with preset defaults\n */\nconst ExtendedThemeAutoPopulateField: SelectFieldClientComponent = ({ field, path }) => {\n const { value, setValue } = useField<string>({ path })\n const { dispatchFields } = useForm()\n const hasInitializedRef = useRef(false)\n\n const options = (field.options as Array<{ label: string; value: string }>) || []\n const selectedOption = options.find((opt) => opt.value === value)\n\n // Auto-populate colors when theme is selected\n const applyThemePreset = useCallback(\n (presetKey: string) => {\n const preset = allExtendedThemePresets[presetKey as keyof typeof allExtendedThemePresets]\n if (!preset) return\n\n // Apply all light mode colors\n Object.entries(preset.styles.light).forEach(([key, colorValue]) => {\n dispatchFields({\n type: 'UPDATE',\n path: `themeConfiguration.extendedLightMode.${key}`,\n value: colorValue,\n })\n })\n\n // Apply all dark mode colors\n Object.entries(preset.styles.dark).forEach(([key, colorValue]) => {\n dispatchFields({\n type: 'UPDATE',\n path: `themeConfiguration.extendedDarkMode.${key}`,\n value: colorValue,\n })\n })\n },\n [dispatchFields],\n )\n\n const handleChange = useCallback(\n (newValue: string) => {\n setValue(newValue)\n if (newValue) {\n applyThemePreset(newValue)\n }\n },\n [setValue, applyThemePreset],\n )\n\n // Auto-populate on initial load if value exists\n useEffect(() => {\n if (!hasInitializedRef.current && value) {\n applyThemePreset(value)\n hasInitializedRef.current = true\n }\n }, [value, applyThemePreset])\n\n // Get color swatches for a preset\n const getPresetColors = (presetValue: string) => {\n const preset = allExtendedThemePresets[presetValue as keyof typeof allExtendedThemePresets]\n if (!preset) return []\n\n const colors = [\n preset.styles.light.primary,\n preset.styles.light.secondary,\n preset.styles.light.accent,\n preset.styles.light.background,\n preset.styles.light.foreground,\n ].filter(Boolean)\n\n return colors.slice(0, 5)\n }\n\n const label =\n typeof field.label === 'string'\n ? field.label\n : field.label?.en || field.label?.cs || 'Theme Preset'\n const description =\n typeof field.admin?.description === 'string'\n ? field.admin.description\n : field.admin?.description?.en || field.admin?.description?.cs\n\n return (\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '6px',\n fontSize: '13px',\n fontWeight: 600,\n color: 'var(--theme-elevation-800)',\n }}\n >\n {label}\n </label>\n\n {description && (\n <div\n style={{\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n marginBottom: '8px',\n }}\n >\n {description}\n </div>\n )}\n\n <select\n value={value || ''}\n onChange={(e) => handleChange(e.target.value)}\n style={{\n width: '100%',\n padding: '10px 12px',\n borderRadius: '6px',\n border: '1px solid var(--theme-elevation-200)',\n backgroundColor: 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n fontSize: '14px',\n cursor: 'pointer',\n }}\n >\n <option value=\"\">Select a theme...</option>\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n\n {/* Show color swatches for selected theme */}\n {selectedOption && (\n <div\n style={{\n marginTop: '12px',\n padding: '12px',\n borderRadius: '8px',\n backgroundColor: 'var(--theme-elevation-50)',\n border: '1px solid var(--theme-elevation-200)',\n }}\n >\n <div\n style={{\n fontSize: '12px',\n fontWeight: 600,\n marginBottom: '8px',\n color: 'var(--theme-elevation-700)',\n }}\n >\n {selectedOption.label}\n </div>\n <div\n style={{\n display: 'flex',\n gap: '8px',\n alignItems: 'center',\n }}\n >\n {getPresetColors(selectedOption.value).map((color, index) => (\n <div\n key={`${selectedOption.value}-${index}`}\n style={{\n width: '32px',\n height: '32px',\n borderRadius: '6px',\n backgroundColor: color,\n border: '1px solid rgba(0, 0, 0, 0.1)',\n boxShadow: '0 2px 4px rgba(0, 0, 0, 0.05)',\n }}\n title={color}\n />\n ))}\n </div>\n <div\n style={{\n marginTop: '8px',\n fontSize: '11px',\n color: 'var(--theme-elevation-500)',\n }}\n >\n ✅ All colors auto-populated from this theme\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default ExtendedThemeAutoPopulateField\n"],"names":["useField","useForm","useCallback","useEffect","useRef","allExtendedThemePresets","ExtendedThemeAutoPopulateField","field","path","value","setValue","dispatchFields","hasInitializedRef","options","selectedOption","find","opt","applyThemePreset","presetKey","preset","Object","entries","styles","light","forEach","key","colorValue","type","dark","handleChange","newValue","current","getPresetColors","presetValue","colors","primary","secondary","accent","background","foreground","filter","Boolean","slice","label","en","cs","description","admin","div","style","marginBottom","display","fontSize","fontWeight","color","select","onChange","e","target","width","padding","borderRadius","border","backgroundColor","cursor","option","map","marginTop","gap","alignItems","index","height","boxShadow","title"],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { SelectFieldClientProps } from 'payload';
2
- export default function RadiusField({ field, ...props }: SelectFieldClientProps): import("react").JSX.Element;
3
- //# sourceMappingURL=RadiusField.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RadiusField.d.ts","sourceRoot":"","sources":["../../src/fields/RadiusField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAYrD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,sBAAsB,+BA2J9E"}
@@ -1,174 +0,0 @@
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
@@ -1 +0,0 @@
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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"}