@kilivi/payloadcms-theme-management 2.0.0 → 2.1.0

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 (214) hide show
  1. package/README.md +318 -847
  2. package/dist/components/AppearanceSessionControls.d.ts +15 -0
  3. package/dist/components/AppearanceSessionControls.d.ts.map +1 -0
  4. package/dist/components/AppearanceSessionControls.js +152 -0
  5. package/dist/components/AppearanceSessionControls.js.map +1 -0
  6. package/dist/components/ColorModeToggle.css +42 -0
  7. package/dist/components/ColorModeToggle.d.ts +40 -0
  8. package/dist/components/ColorModeToggle.d.ts.map +1 -0
  9. package/dist/components/ColorModeToggle.js +111 -0
  10. package/dist/components/ColorModeToggle.js.map +1 -0
  11. package/dist/components/ServerThemeInjector.d.ts.map +1 -1
  12. package/dist/components/ServerThemeInjector.js +41 -14
  13. package/dist/components/ServerThemeInjector.js.map +1 -1
  14. package/dist/components/ThemeLivePreviewSync.d.ts +1 -0
  15. package/dist/components/ThemeLivePreviewSync.d.ts.map +1 -1
  16. package/dist/components/ThemeLivePreviewSync.js +1 -1
  17. package/dist/components/ThemeLivePreviewSync.js.map +1 -1
  18. package/dist/components/ThemeSwitcher.d.ts +36 -0
  19. package/dist/components/ThemeSwitcher.d.ts.map +1 -0
  20. package/dist/components/ThemeSwitcher.js +89 -0
  21. package/dist/components/ThemeSwitcher.js.map +1 -0
  22. package/dist/components/typographyPreviewUtils.d.ts.map +1 -1
  23. package/dist/components/typographyPreviewUtils.js +8 -1
  24. package/dist/components/typographyPreviewUtils.js.map +1 -1
  25. package/dist/constants/devicePreviews.d.ts +35 -0
  26. package/dist/constants/devicePreviews.d.ts.map +1 -0
  27. package/dist/constants/devicePreviews.js +43 -0
  28. package/dist/constants/devicePreviews.js.map +1 -0
  29. package/dist/constants/themeFonts.js +9 -9
  30. package/dist/constants/themeFonts.js.map +1 -1
  31. package/dist/extended-presets.d.ts +0 -4
  32. package/dist/extended-presets.d.ts.map +1 -1
  33. package/dist/extended-presets.js +1 -18
  34. package/dist/extended-presets.js.map +1 -1
  35. package/dist/extended-themes.d.ts.map +1 -1
  36. package/dist/extended-themes.js +428 -0
  37. package/dist/extended-themes.js.map +1 -1
  38. package/dist/fields/AccessibilityAuditField.d.ts +2 -0
  39. package/dist/fields/AccessibilityAuditField.d.ts.map +1 -0
  40. package/dist/fields/AccessibilityAuditField.js +303 -0
  41. package/dist/fields/AccessibilityAuditField.js.map +1 -0
  42. package/dist/fields/AppearancePreviewField.d.ts +2 -0
  43. package/dist/fields/AppearancePreviewField.d.ts.map +1 -0
  44. package/dist/fields/AppearancePreviewField.js +763 -0
  45. package/dist/fields/AppearancePreviewField.js.map +1 -0
  46. package/dist/fields/ColorPickerField.d.ts.map +1 -1
  47. package/dist/fields/ColorPickerField.js +89 -85
  48. package/dist/fields/ColorPickerField.js.map +1 -1
  49. package/dist/fields/FontSelectField.d.ts +6 -0
  50. package/dist/fields/FontSelectField.d.ts.map +1 -1
  51. package/dist/fields/FontSelectField.js +195 -122
  52. package/dist/fields/FontSelectField.js.map +1 -1
  53. package/dist/fields/PaletteGeneratorField.d.ts +7 -0
  54. package/dist/fields/PaletteGeneratorField.d.ts.map +1 -0
  55. package/dist/fields/PaletteGeneratorField.js +327 -0
  56. package/dist/fields/PaletteGeneratorField.js.map +1 -0
  57. package/dist/fields/StylePresetField.d.ts +3 -0
  58. package/dist/fields/StylePresetField.d.ts.map +1 -0
  59. package/dist/fields/StylePresetField.js +462 -0
  60. package/dist/fields/StylePresetField.js.map +1 -0
  61. package/dist/fields/ThemeColorPickerField.css +115 -35
  62. package/dist/fields/ThemeColorPickerField.d.ts.map +1 -1
  63. package/dist/fields/ThemeColorPickerField.js +204 -70
  64. package/dist/fields/ThemeColorPickerField.js.map +1 -1
  65. package/dist/fields/ThemeExportField.d.ts +6 -0
  66. package/dist/fields/ThemeExportField.d.ts.map +1 -0
  67. package/dist/fields/ThemeExportField.js +202 -0
  68. package/dist/fields/ThemeExportField.js.map +1 -0
  69. package/dist/fields/ThemePresetImportField.d.ts.map +1 -1
  70. package/dist/fields/ThemePresetImportField.js +56 -25
  71. package/dist/fields/ThemePresetImportField.js.map +1 -1
  72. package/dist/fields/ThemePreviewField.css +382 -5
  73. package/dist/fields/ThemePreviewField.d.ts.map +1 -1
  74. package/dist/fields/ThemePreviewField.js +268 -170
  75. package/dist/fields/ThemePreviewField.js.map +1 -1
  76. package/dist/fields/ThemeTokenSelectField.d.ts.map +1 -1
  77. package/dist/fields/ThemeTokenSelectField.js +278 -80
  78. package/dist/fields/ThemeTokenSelectField.js.map +1 -1
  79. package/dist/fields/colorFieldHelpers.d.ts +90 -0
  80. package/dist/fields/colorFieldHelpers.d.ts.map +1 -0
  81. package/dist/fields/colorFieldHelpers.js +133 -0
  82. package/dist/fields/colorFieldHelpers.js.map +1 -0
  83. package/dist/fields/colorModeFields.d.ts +1 -1
  84. package/dist/fields/colorModeFields.d.ts.map +1 -1
  85. package/dist/fields/colorModeFields.js +49 -7
  86. package/dist/fields/colorModeFields.js.map +1 -1
  87. package/dist/fields/themeConfigurationField.d.ts +8 -1
  88. package/dist/fields/themeConfigurationField.d.ts.map +1 -1
  89. package/dist/fields/themeConfigurationField.js +961 -29
  90. package/dist/fields/themeConfigurationField.js.map +1 -1
  91. package/dist/globals/ThemeSettings/FontPicker/FontPreview.d.ts.map +1 -1
  92. package/dist/globals/ThemeSettings/FontPicker/FontPreview.js +8 -4
  93. package/dist/globals/ThemeSettings/FontPicker/FontPreview.js.map +1 -1
  94. package/dist/globals/ThemeSettings/FontPicker/index.d.ts.map +1 -1
  95. package/dist/globals/ThemeSettings/FontPicker/index.js +81 -26
  96. package/dist/globals/ThemeSettings/FontPicker/index.js.map +1 -1
  97. package/dist/globals/ThemeSettings/FontPicker/styles.css +98 -41
  98. package/dist/globals/ThemeSettings/FontPicker/translations.d.ts +6 -0
  99. package/dist/globals/ThemeSettings/FontPicker/translations.d.ts.map +1 -1
  100. package/dist/globals/ThemeSettings/FontPicker/translations.js +14 -2
  101. package/dist/globals/ThemeSettings/FontPicker/translations.js.map +1 -1
  102. package/dist/globals/ThemeSettings/config.d.ts.map +1 -1
  103. package/dist/globals/ThemeSettings/config.js +76 -79
  104. package/dist/globals/ThemeSettings/config.js.map +1 -1
  105. package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.d.ts.map +1 -1
  106. package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.js +63 -62
  107. package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.js.map +1 -1
  108. package/dist/globals/ThemeSettings/fields/TypographyInfoField.d.ts.map +1 -1
  109. package/dist/globals/ThemeSettings/fields/TypographyInfoField.js +22 -25
  110. package/dist/globals/ThemeSettings/fields/TypographyInfoField.js.map +1 -1
  111. package/dist/hooks/useAppearanceSession.d.ts +50 -0
  112. package/dist/hooks/useAppearanceSession.d.ts.map +1 -0
  113. package/dist/hooks/useAppearanceSession.js +91 -0
  114. package/dist/hooks/useAppearanceSession.js.map +1 -0
  115. package/dist/hooks/useThemeTranslations.d.ts +13 -0
  116. package/dist/hooks/useThemeTranslations.d.ts.map +1 -0
  117. package/dist/hooks/useThemeTranslations.js +22 -0
  118. package/dist/hooks/useThemeTranslations.js.map +1 -0
  119. package/dist/i18n.d.ts +53 -0
  120. package/dist/i18n.d.ts.map +1 -0
  121. package/dist/i18n.js +53 -0
  122. package/dist/i18n.js.map +1 -0
  123. package/dist/index.d.ts +10 -4
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +50 -29
  126. package/dist/index.js.map +1 -1
  127. package/dist/payload-types.d.ts +24 -0
  128. package/dist/payload-types.d.ts.map +1 -1
  129. package/dist/payload-types.js.map +1 -1
  130. package/dist/presets.d.ts +8 -0
  131. package/dist/presets.d.ts.map +1 -1
  132. package/dist/presets.js.map +1 -1
  133. package/dist/providers/Theme/index.d.ts.map +1 -1
  134. package/dist/providers/Theme/index.js +75 -11
  135. package/dist/providers/Theme/index.js.map +1 -1
  136. package/dist/providers/Theme/themeConfig.d.ts.map +1 -1
  137. package/dist/providers/Theme/themeConfig.js +104 -0
  138. package/dist/providers/Theme/themeConfig.js.map +1 -1
  139. package/dist/providers/Theme/types.d.ts +1 -1
  140. package/dist/providers/Theme/types.d.ts.map +1 -1
  141. package/dist/providers/Theme/types.js +10 -1
  142. package/dist/providers/Theme/types.js.map +1 -1
  143. package/dist/style-presets.d.ts +66 -0
  144. package/dist/style-presets.d.ts.map +1 -0
  145. package/dist/style-presets.js +556 -0
  146. package/dist/style-presets.js.map +1 -0
  147. package/dist/translations.d.ts +159 -1
  148. package/dist/translations.d.ts.map +1 -1
  149. package/dist/translations.js +310 -9
  150. package/dist/translations.js.map +1 -1
  151. package/dist/tweakcn-special-themes.d.ts.map +1 -1
  152. package/dist/tweakcn-special-themes.js +585 -9
  153. package/dist/tweakcn-special-themes.js.map +1 -1
  154. package/dist/types/css.d.js +3 -0
  155. package/dist/types/css.d.js.map +1 -0
  156. package/dist/types.d.ts +26 -0
  157. package/dist/types.d.ts.map +1 -1
  158. package/dist/types.js +1 -1
  159. package/dist/types.js.map +1 -1
  160. package/dist/utilities/getThemeSettings.d.ts.map +1 -1
  161. package/dist/utilities/getThemeSettings.js +2 -14
  162. package/dist/utilities/getThemeSettings.js.map +1 -1
  163. package/dist/utils/contrast.d.ts +63 -0
  164. package/dist/utils/contrast.d.ts.map +1 -0
  165. package/dist/utils/contrast.js +158 -0
  166. package/dist/utils/contrast.js.map +1 -0
  167. package/dist/utils/exportTokens.d.ts +30 -0
  168. package/dist/utils/exportTokens.d.ts.map +1 -0
  169. package/dist/utils/exportTokens.js +183 -0
  170. package/dist/utils/exportTokens.js.map +1 -0
  171. package/dist/utils/generatePalette.d.ts +46 -0
  172. package/dist/utils/generatePalette.d.ts.map +1 -0
  173. package/dist/utils/generatePalette.js +127 -0
  174. package/dist/utils/generatePalette.js.map +1 -0
  175. package/dist/utils/generateThemeCSS.d.ts.map +1 -1
  176. package/dist/utils/generateThemeCSS.js +2 -40
  177. package/dist/utils/generateThemeCSS.js.map +1 -1
  178. package/dist/utils/livePreviewThemeRuntime.d.ts +16 -2
  179. package/dist/utils/livePreviewThemeRuntime.d.ts.map +1 -1
  180. package/dist/utils/livePreviewThemeRuntime.js +37 -14
  181. package/dist/utils/livePreviewThemeRuntime.js.map +1 -1
  182. package/dist/utils/localizedText.d.ts +8 -0
  183. package/dist/utils/localizedText.d.ts.map +1 -0
  184. package/dist/utils/localizedText.js +21 -0
  185. package/dist/utils/localizedText.js.map +1 -0
  186. package/dist/utils/resolveThemeConfiguration.d.ts +45 -1
  187. package/dist/utils/resolveThemeConfiguration.d.ts.map +1 -1
  188. package/dist/utils/resolveThemeConfiguration.js +12 -5
  189. package/dist/utils/resolveThemeConfiguration.js.map +1 -1
  190. package/dist/utils/themeColors.d.ts +3 -0
  191. package/dist/utils/themeColors.d.ts.map +1 -1
  192. package/dist/utils/themeColors.js +30 -1
  193. package/dist/utils/themeColors.js.map +1 -1
  194. package/dist/utils/themeHtmlAttributes.d.ts +32 -12
  195. package/dist/utils/themeHtmlAttributes.d.ts.map +1 -1
  196. package/dist/utils/themeHtmlAttributes.js +38 -5
  197. package/dist/utils/themeHtmlAttributes.js.map +1 -1
  198. package/dist/utils/themeUtils.d.ts +3 -5
  199. package/dist/utils/themeUtils.d.ts.map +1 -1
  200. package/dist/utils/themeUtils.js +416 -6
  201. package/dist/utils/themeUtils.js.map +1 -1
  202. package/dist/utils/tweakcnConverter.d.ts +1 -3
  203. package/dist/utils/tweakcnConverter.d.ts.map +1 -1
  204. package/dist/utils/tweakcnConverter.js +1 -3
  205. package/dist/utils/tweakcnConverter.js.map +1 -1
  206. package/package.json +11 -5
  207. package/dist/components/ThemePreview.d.ts +0 -3
  208. package/dist/components/ThemePreview.d.ts.map +0 -1
  209. package/dist/components/ThemePreview.js +0 -321
  210. package/dist/components/ThemePreview.js.map +0 -1
  211. package/dist/plugin.d.ts +0 -2
  212. package/dist/plugin.d.ts.map +0 -1
  213. package/dist/plugin.js +0 -3
  214. package/dist/plugin.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/fields/themeConfigurationField.ts"],"sourcesContent":["import type { Field, TabsField } from 'payload'\nimport {\n BASE_FONT_SIZE_OPTIONS,\n BODY_FONT_OPTIONS,\n HEADING_FONT_OPTIONS,\n LINE_HEIGHT_OPTIONS,\n} from '../constants/themeFonts.js'\nimport type { ThemePreset } from '../index.js'\nimport { darkModeField, lightModeField } from './colorModeFields.js'\n\ninterface ThemeConfigurationFieldOptions {\n themePresets: ThemePreset[]\n defaultTheme: string\n includeColorModeToggle: boolean\n includeCustomCSS: boolean\n includeBrandIdentity: boolean\n enableAdvancedFeatures?: boolean\n useThemePreviewField?: boolean\n}\n\n// Type for admin.custom property to avoid ts-expect-error\ninterface ThemeAdminCustom {\n themePresets?: ThemePreset[]\n useThemePreviewField?: boolean\n}\n\n// Type for a single tab (not the full TabsField)\nexport type ThemeTab = NonNullable<TabsField['tabs']>[number]\n\n/**\n * Theme Configuration Field with Theme Selection as default value setter\n * Theme Selection populates lightMode/darkMode colors automatically\n */\nexport function createThemeConfigurationField(options: ThemeConfigurationFieldOptions): ThemeTab {\n const {\n themePresets,\n defaultTheme,\n includeColorModeToggle,\n includeCustomCSS,\n enableAdvancedFeatures = true,\n useThemePreviewField = true,\n } = options\n\n const fields: Field[] = [\n {\n name: 'theme',\n type: 'text',\n required: true,\n defaultValue: defaultTheme,\n label: {\n en: '🎨 Theme Selection',\n cs: '🎨 Výběr tématu',\n },\n validate: (value: unknown) => {\n if (typeof value === 'string' && value.trim().length > 0) {\n return true\n }\n return 'Select a theme'\n },\n admin: {\n description: {\n en: 'Select a theme to auto-populate color values. You can customize colors after selection.',\n cs: 'Vyberte téma pro automatické předvyplnění barev. Po výběru můžete barvy upravit.',\n },\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/ThemePreviewField',\n },\n custom: {\n themePresets,\n useThemePreviewField,\n } as ThemeAdminCustom,\n },\n },\n ]\n\n // Border Radius Configuration - Always visible\n fields.push({\n type: 'row',\n fields: [\n {\n name: 'borderRadius',\n type: 'select',\n label: {\n en: '📐 Border Radius',\n cs: '📐 Zaoblení rohů',\n },\n defaultValue: 'medium',\n options: [\n { label: { en: 'None (0px)', cs: 'Žádné (0px)' }, value: 'none' },\n { label: { en: 'Small (0.25rem)', cs: 'Malé (0.25rem)' }, value: 'small' },\n { label: { en: 'Medium (0.5rem)', cs: 'Střední (0.5rem)' }, value: 'medium' },\n { label: { en: 'Large (0.75rem)', cs: 'Velké (0.75rem)' }, value: 'large' },\n { label: { en: 'XL (1rem)', cs: 'XL (1rem)' }, value: 'xl' },\n ],\n admin: {\n description: {\n en: 'Default corner rounding for UI elements',\n cs: 'Výchozí zaoblení rohů pro UI prvky',\n },\n width: '50%',\n },\n dbName: 'border_radius',\n },\n {\n name: 'spacing',\n type: 'select',\n label: {\n en: '📏 Spacing Scale',\n cs: '📏 Škála rozestupů',\n },\n defaultValue: 'medium',\n options: [\n { label: { en: 'Compact', cs: 'Kompaktní' }, value: 'compact' },\n { label: { en: 'Medium', cs: 'Střední' }, value: 'medium' },\n { label: { en: 'Comfortable', cs: 'Pohodlné' }, value: 'comfortable' },\n ],\n admin: {\n description: {\n en: 'Global spacing between elements',\n cs: 'Globální rozestupy mezi prvky',\n },\n width: '50%',\n },\n dbName: 'spacing',\n },\n ],\n })\n\n // Color Mode Settings\n if (includeColorModeToggle) {\n fields.push({\n type: 'collapsible',\n label: {\n en: '🌗 Color Mode Settings',\n cs: '🌗 Nastavení barevného režimu',\n },\n admin: {\n initCollapsed: false,\n description: {\n en: 'Configure light and dark mode colors. Changes here override theme selection.',\n cs: 'Nakonfigurujte barvy světlého a tmavého režimu. Změny zde přepíší výběr tématu.',\n },\n },\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'colorMode',\n type: 'select',\n label: {\n en: 'Default Color Mode',\n cs: 'Výchozí barevný režim',\n },\n defaultValue: 'auto',\n options: [\n {\n label: {\n en: 'Auto (System)',\n cs: 'Automaticky (Systém)',\n },\n value: 'auto',\n },\n {\n label: { en: 'Light', cs: 'Světlý' },\n value: 'light',\n },\n {\n label: { en: 'Dark', cs: 'Tmavý' },\n value: 'dark',\n },\n ],\n admin: {\n description: {\n en: 'Default color mode for visitors',\n cs: 'Výchozí barevný režim pro návštěvníky',\n },\n width: '50%',\n },\n dbName: 'color_mode',\n },\n {\n name: 'allowColorModeToggle',\n type: 'checkbox',\n label: {\n en: 'Enable Mode Toggle',\n cs: 'Povolit přepínač režimu',\n },\n defaultValue: true,\n admin: {\n description: {\n en: 'Let visitors switch modes',\n cs: 'Umožnit návštěvníkům přepínat režimy',\n },\n width: '50%',\n },\n },\n ],\n },\n lightModeField,\n darkModeField,\n ],\n })\n }\n\n // Typography - Always visible\n fields.push({\n type: 'collapsible',\n label: {\n en: '🅰️ Typography',\n cs: '🅰️ Typografie',\n },\n admin: {\n initCollapsed: true,\n description: {\n en: 'Choose font families and base typography settings. Leave fields on \"Use preset\" to inherit the theme defaults.',\n cs: 'Zvolte rodiny písem a základní typografické nastavení. Hodnota \"Použít výchozí\" zachová nastavení motivu.',\n },\n },\n fields: [\n {\n name: 'typography',\n type: 'group',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'bodyFont',\n type: 'select',\n label: {\n en: 'Body font',\n cs: 'Písmo pro text',\n },\n defaultValue: 'preset',\n options: [...BODY_FONT_OPTIONS],\n admin: {\n width: '50%',\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/FontSelectField',\n },\n },\n dbName: 'body_font',\n },\n {\n name: 'headingFont',\n type: 'select',\n label: {\n en: 'Heading font',\n cs: 'Písmo pro nadpisy',\n },\n defaultValue: 'preset',\n options: [...HEADING_FONT_OPTIONS],\n admin: {\n width: '50%',\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/FontSelectField',\n },\n },\n dbName: 'heading_font',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'bodyFontCustom',\n type: 'text',\n label: {\n en: 'Custom body font stack',\n cs: 'Vlastní písmo pro text',\n },\n admin: {\n width: '50%',\n placeholder: '\"IBM Plex Sans\", sans-serif',\n description: {\n en: 'Provide full CSS font-family stack when using a custom font.',\n cs: 'Při volbě vlastního písma zadejte celý CSS zápis font-family.',\n },\n condition: (_, siblingData) => siblingData?.bodyFont === 'custom',\n },\n },\n {\n name: 'headingFontCustom',\n type: 'text',\n label: {\n en: 'Custom heading font stack',\n cs: 'Vlastní písmo pro nadpisy',\n },\n admin: {\n width: '50%',\n placeholder: '\"Cormorant Garamond\", serif',\n description: {\n en: 'Provide full CSS font-family stack when using a custom heading font.',\n cs: 'Při volbě vlastního nadpisového písma zadejte celý CSS zápis font-family.',\n },\n condition: (_, siblingData) => siblingData?.headingFont === 'custom',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'baseFontSize',\n type: 'select',\n label: {\n en: 'Base font size',\n cs: 'Základní velikost písma',\n },\n defaultValue: 'preset',\n options: BASE_FONT_SIZE_OPTIONS.map((option) => ({\n label: option.label,\n value: option.value,\n })),\n admin: {\n width: '50%',\n },\n dbName: 'base_font_size',\n },\n {\n name: 'lineHeight',\n type: 'select',\n label: {\n en: 'Line height',\n cs: 'Řádkování',\n },\n defaultValue: 'preset',\n options: LINE_HEIGHT_OPTIONS.map((option) => ({\n label: option.label,\n value: option.value,\n })),\n admin: {\n width: '50%',\n },\n dbName: 'line_height',\n },\n ],\n },\n ],\n },\n ],\n })\n\n const customPresetsField: Field = {\n type: 'collapsible',\n label: {\n en: '🧩 Custom Theme Presets',\n cs: '🧩 Vlastní motivy',\n },\n admin: {\n initCollapsed: true,\n description: {\n en: 'Import additional theme presets via JSON to extend or override the defaults. These presets become available instantly in the Theme Selection above.',\n cs: 'Importujte další motivy pomocí JSONu a rozšiřte nebo přepište výchozí nabídku. Motivy budou ihned k dispozici ve výběru výše.',\n },\n },\n fields: [\n {\n name: 'customThemePresets',\n type: 'json',\n label: {\n en: 'Custom Preset JSON',\n cs: 'JSON s vlastními motivy',\n },\n admin: {\n description: {\n en: 'Paste or import an array (or object map) of theme presets. Each entry should include at least a unique \"name\" and \"label\" with optional lightMode/darkMode colors.',\n cs: 'Vložte nebo importujte pole (či objekt) motivů. Každý motiv musí mít unikátní „name“ a „label“ a volitelně barvy pro světly/tmavý režim.',\n },\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/ThemePresetImportField',\n },\n },\n },\n ],\n }\n\n fields.push(customPresetsField)\n\n // Advanced Settings (when using extended theme configuration)\n if (enableAdvancedFeatures) {\n const advancedFields: Field[] = [\n {\n name: 'animationLevel',\n type: 'select',\n label: {\n en: 'Animation Level',\n cs: 'Úroveň animací',\n },\n defaultValue: 'medium',\n options: [\n { label: { en: 'None', cs: 'Žádné' }, value: 'none' },\n { label: { en: 'Reduced', cs: 'Snížené' }, value: 'reduced' },\n { label: { en: 'Medium', cs: 'Střední' }, value: 'medium' },\n { label: { en: 'High', cs: 'Vysoké' }, value: 'high' },\n ],\n admin: {\n description: {\n en: 'Control website animations and transitions',\n cs: 'Kontrola animací a přechodů na webu',\n },\n width: '50%',\n },\n dbName: 'animation_level',\n },\n ]\n\n if (includeCustomCSS) {\n advancedFields.push({\n name: 'customCSS',\n type: 'code',\n label: {\n en: 'Custom CSS',\n cs: 'Vlastní CSS',\n },\n admin: {\n language: 'css',\n description: {\n en: 'Add custom CSS to override default styles',\n cs: 'Přidejte vlastní CSS pro přepsání výchozích stylů',\n },\n // placeholder:\n // ':root {\\n --primary: #your-color;\\n --border-radius: 8px;\\n --font-family: \"Your Font\";\\n}\\n\\n.custom-class {\\n /* Your custom styles */\\n}',\n // rows: 8,\n },\n })\n }\n\n fields.push({\n type: 'collapsible',\n label: {\n en: '⚙️ Advanced Settings',\n cs: '⚙️ Pokročilé nastavení',\n },\n admin: {\n initCollapsed: true,\n },\n fields: advancedFields,\n })\n }\n\n // Return as tab configuration to be injected into tabs structure\n return {\n label: {\n en: '🎨 Appearance Settings',\n cs: '🎨 Nastavení vzhledu',\n },\n fields: [\n {\n name: 'themeConfiguration',\n type: 'group',\n admin: {\n description: {\n en: 'Configure website appearance and styling',\n cs: 'Nakonfigurujte vzhled a stylování webu',\n },\n },\n fields,\n },\n ],\n }\n}\n"],"names":["BASE_FONT_SIZE_OPTIONS","BODY_FONT_OPTIONS","HEADING_FONT_OPTIONS","LINE_HEIGHT_OPTIONS","darkModeField","lightModeField","createThemeConfigurationField","options","themePresets","defaultTheme","includeColorModeToggle","includeCustomCSS","enableAdvancedFeatures","useThemePreviewField","fields","name","type","required","defaultValue","label","en","cs","validate","value","trim","length","admin","description","components","Field","custom","push","width","dbName","initCollapsed","placeholder","condition","_","siblingData","bodyFont","headingFont","map","option","customPresetsField","advancedFields","language"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/fields/themeConfigurationField.ts"],"sourcesContent":["import type { Field, TabsField } from 'payload'\nimport {\n BASE_FONT_SIZE_OPTIONS,\n BODY_FONT_OPTIONS,\n HEADING_FONT_OPTIONS,\n LINE_HEIGHT_OPTIONS,\n} from '../constants/themeFonts.js'\nimport type { ThemePreset } from '../index.js'\nimport { getTranslations } from '../translations.js'\nimport { darkModeField, lightModeField } from './colorModeFields.js'\n\ninterface ThemeConfigurationFieldOptions {\n themePresets: ThemePreset[]\n defaultTheme: string\n includeColorModeToggle: boolean\n includeCustomCSS: boolean\n includeBrandIdentity: boolean\n enableAdvancedFeatures?: boolean\n useThemePreviewField?: boolean\n customThemeConfigurationFields?: Field[]\n customThemeConfigurationSections?: Array<{\n label: string | Record<string, string>\n fields: Field[]\n initCollapsed?: boolean\n description?: string | Record<string, string>\n }>\n}\n\n// Type for admin.custom property to avoid ts-expect-error\ninterface ThemeAdminCustom {\n themePresets?: ThemePreset[]\n useThemePreviewField?: boolean\n}\n\n// Type for a single tab (not the full TabsField)\nexport type ThemeTab = NonNullable<TabsField['tabs']>[number]\n\n/**\n * Theme Configuration Field with Theme Selection as default value setter\n * Theme Selection populates lightMode/darkMode colors automatically\n */\nexport function createThemeConfigurationField(options: ThemeConfigurationFieldOptions): ThemeTab {\n const {\n themePresets,\n defaultTheme,\n includeColorModeToggle,\n includeCustomCSS,\n enableAdvancedFeatures = true,\n useThemePreviewField = true,\n customThemeConfigurationFields,\n customThemeConfigurationSections,\n } = options\n\n const fields: Field[] = [\n // NOTE: the palette generator is rendered *inside* ThemePreviewField (in the\n // preset column, above the preset list) — it is not a separate UI field.\n {\n name: 'theme',\n type: 'text',\n required: true,\n defaultValue: defaultTheme,\n label: {\n en: 'Theme Selection',\n cs: 'Výběr motivu',\n },\n validate: (value: unknown, options?: { req?: { i18n?: { language?: string } } }) => {\n if (typeof value === 'string' && value.trim().length > 0) {\n return true\n }\n return getTranslations(options?.req?.i18n?.language ?? 'en').ui.selectThemeError\n },\n admin: {\n description: {\n en: 'Pick a theme to fill in the colours. You can fine-tune them afterwards.',\n cs: 'Vyberte motiv a barvy se předvyplní. Potom je můžete dál upravovat.',\n },\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/ThemePreviewField',\n },\n custom: {\n themePresets,\n useThemePreviewField,\n } as ThemeAdminCustom,\n },\n },\n ]\n\n // Live preview: colours, fonts and component styles in one place. On wide admins\n // it occupies a sticky right-hand column spanning the whole tab (see\n // ThemePreviewField.css, `.tm-appearance`); on narrow ones it follows the theme picker.\n fields.push({\n name: 'appearancePreview',\n type: 'ui',\n admin: {\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/AppearancePreviewField',\n },\n },\n })\n\n // Style Preset - visual style selection independent of colors\n fields.push({\n type: 'collapsible',\n label: {\n en: 'Style Preset',\n cs: 'Styl vzhledu',\n },\n admin: {\n initCollapsed: true,\n className: 'tm-section-style-preset',\n description: {\n en: 'Choose a visual style (Brutalism, Swiss, Glassmorphism …) without changing the colour palette.',\n cs: 'Zvolte vizuální styl (Brutalismus, Švýcarský, Glassmorphism …) bez změny barevné palety.',\n },\n },\n fields: [\n {\n name: 'stylePreset',\n type: 'text',\n label: {\n en: 'Active Style Preset',\n cs: 'Aktivní styl vzhledu',\n },\n defaultValue: '',\n admin: {\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/StylePresetField',\n },\n },\n },\n ],\n })\n\n // Border Radius Configuration - Always visible\n fields.push({\n type: 'row',\n fields: [\n {\n name: 'borderRadius',\n type: 'select',\n label: {\n en: 'Border Radius',\n cs: 'Zaoblení rohů',\n },\n defaultValue: 'medium',\n options: [\n { label: { en: 'None (0px)', cs: 'Žádné (0px)' }, value: 'none' },\n { label: { en: 'Small (0.25rem)', cs: 'Malé (0.25rem)' }, value: 'small' },\n { label: { en: 'Medium (0.5rem)', cs: 'Střední (0.5rem)' }, value: 'medium' },\n { label: { en: 'Large (0.75rem)', cs: 'Velké (0.75rem)' }, value: 'large' },\n { label: { en: 'XL (1rem)', cs: 'XL (1rem)' }, value: 'xl' },\n ],\n admin: {\n description: {\n en: 'Default corner rounding for UI elements',\n cs: 'Výchozí zaoblení rohů pro UI prvky',\n },\n width: '50%',\n },\n dbName: 'border_radius',\n },\n {\n name: 'spacing',\n type: 'select',\n label: {\n en: 'Spacing Scale',\n cs: 'Škála rozestupů',\n },\n defaultValue: 'medium',\n options: [\n { label: { en: 'Compact', cs: 'Kompaktní' }, value: 'compact' },\n { label: { en: 'Medium', cs: 'Střední' }, value: 'medium' },\n { label: { en: 'Comfortable', cs: 'Pohodlné' }, value: 'comfortable' },\n ],\n admin: {\n description: {\n en: 'Global spacing between elements',\n cs: 'Globální rozestupy mezi prvky',\n },\n width: '50%',\n },\n dbName: 'spacing',\n },\n ],\n })\n\n // Color Mode Settings\n if (includeColorModeToggle) {\n fields.push({\n type: 'collapsible',\n label: {\n en: 'Color Mode Settings',\n cs: 'Nastavení barevného režimu',\n },\n admin: {\n // Fine-tuning: collapsed by default so presets and the preview lead the tab.\n initCollapsed: true,\n description: {\n en: 'Individual light and dark mode colours. Edits here take precedence over the theme.',\n cs: 'Jednotlivé barvy světlého a tmavého režimu. Úpravy zde mají přednost před motivem.',\n },\n },\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'colorMode',\n type: 'select',\n label: {\n en: 'Default Color Mode',\n cs: 'Výchozí barevný režim',\n },\n defaultValue: 'auto',\n options: [\n {\n label: {\n en: 'Auto (System)',\n cs: 'Automaticky (Systém)',\n },\n value: 'auto',\n },\n {\n label: { en: 'Light', cs: 'Světlý' },\n value: 'light',\n },\n {\n label: { en: 'Dark', cs: 'Tmavý' },\n value: 'dark',\n },\n ],\n admin: {\n description: {\n en: 'Default color mode for visitors',\n cs: 'Výchozí barevný režim pro návštěvníky',\n },\n width: '50%',\n },\n dbName: 'color_mode',\n },\n {\n name: 'allowColorModeToggle',\n type: 'checkbox',\n label: {\n en: 'Enable Mode Toggle',\n cs: 'Povolit přepínač režimu',\n },\n defaultValue: true,\n admin: {\n description: {\n en: 'Let visitors switch modes',\n cs: 'Umožnit návštěvníkům přepínat režimy',\n },\n width: '50%',\n },\n },\n ],\n },\n lightModeField,\n darkModeField,\n {\n name: 'accessibilityAudit',\n type: 'ui',\n admin: {\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/AccessibilityAuditField',\n },\n },\n },\n {\n name: 'themeExport',\n type: 'ui',\n admin: {\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/ThemeExportField',\n },\n },\n },\n ],\n })\n }\n\n // Typography - Always visible\n fields.push({\n type: 'collapsible',\n label: {\n en: 'Typography',\n cs: 'Typografie',\n },\n admin: {\n initCollapsed: true,\n className: 'tm-section-typography',\n description: {\n en: 'Choose font families and base typography settings. Leave fields on \"Use preset\" to inherit the theme defaults.',\n cs: 'Zvolte rodiny písem a základní typografické nastavení. Hodnota \"Použít výchozí\" zachová nastavení motivu.',\n },\n },\n fields: [\n {\n name: 'typography',\n type: 'group',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'bodyFont',\n type: 'select',\n label: {\n en: 'Body font',\n cs: 'Písmo pro text',\n },\n defaultValue: 'preset',\n options: [...BODY_FONT_OPTIONS],\n admin: {\n width: '50%',\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/FontSelectField',\n },\n },\n dbName: 'body_font',\n },\n {\n name: 'headingFont',\n type: 'select',\n label: {\n en: 'Heading font',\n cs: 'Písmo pro nadpisy',\n },\n defaultValue: 'preset',\n options: [...HEADING_FONT_OPTIONS],\n admin: {\n width: '50%',\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/FontSelectField',\n },\n },\n dbName: 'heading_font',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'bodyFontCustom',\n type: 'text',\n label: {\n en: 'Custom body font stack',\n cs: 'Vlastní písmo pro text',\n },\n admin: {\n width: '50%',\n placeholder: '\"IBM Plex Sans\", sans-serif',\n description: {\n en: 'Provide full CSS font-family stack when using a custom font.',\n cs: 'Při volbě vlastního písma zadejte celý CSS zápis font-family.',\n },\n condition: (_, siblingData) => siblingData?.bodyFont === 'custom',\n },\n },\n {\n name: 'headingFontCustom',\n type: 'text',\n label: {\n en: 'Custom heading font stack',\n cs: 'Vlastní písmo pro nadpisy',\n },\n admin: {\n width: '50%',\n placeholder: '\"Cormorant Garamond\", serif',\n description: {\n en: 'Provide full CSS font-family stack when using a custom heading font.',\n cs: 'Při volbě vlastního nadpisového písma zadejte celý CSS zápis font-family.',\n },\n condition: (_, siblingData) => siblingData?.headingFont === 'custom',\n },\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'baseFontSize',\n type: 'select',\n label: {\n en: 'Base font size',\n cs: 'Základní velikost písma',\n },\n defaultValue: 'preset',\n options: BASE_FONT_SIZE_OPTIONS.map((option) => ({\n label: option.label,\n value: option.value,\n })),\n admin: {\n width: '50%',\n },\n dbName: 'base_font_size',\n },\n {\n name: 'lineHeight',\n type: 'select',\n label: {\n en: 'Line height',\n cs: 'Řádkování',\n },\n defaultValue: 'preset',\n options: LINE_HEIGHT_OPTIONS.map((option) => ({\n label: option.label,\n value: option.value,\n })),\n admin: {\n width: '50%',\n },\n dbName: 'line_height',\n },\n ],\n },\n ],\n },\n ],\n })\n\n const customPresetsField: Field = {\n type: 'collapsible',\n label: {\n en: 'Custom Theme Presets',\n cs: 'Vlastní motivy',\n },\n admin: {\n initCollapsed: true,\n className: 'tm-section-custom-presets',\n description: {\n en: 'Import additional theme presets via JSON to extend or override the defaults. These presets become available instantly in the Theme Selection above.',\n cs: 'Importujte další motivy pomocí JSONu a rozšiřte nebo přepište výchozí nabídku. Motivy budou ihned k dispozici ve výběru výše.',\n },\n },\n fields: [\n {\n name: 'customThemePresets',\n type: 'json',\n label: {\n en: 'Custom Preset JSON',\n cs: 'JSON s vlastními motivy',\n },\n admin: {\n description: {\n en: 'Paste or import an array (or object map) of theme presets. Each entry should include at least a unique \"name\" and \"label\" with optional lightMode/darkMode colors.',\n cs: 'Vložte nebo importujte pole (či objekt) motivů. Každý motiv musí mít unikátní „name“ a „label“ a volitelně barvy pro světlý a tmavý režim.',\n },\n components: {\n Field: '@kilivi/payloadcms-theme-management/fields/ThemePresetImportField',\n },\n },\n },\n ],\n }\n\n fields.push(customPresetsField)\n\n // Visual Effects — glassmorphism, shadows, border style\n fields.push({\n type: 'collapsible',\n label: {\n en: 'Visual Effects',\n cs: 'Vizuální efekty',\n },\n admin: {\n initCollapsed: true,\n className: 'tm-section-effects',\n description: {\n en: 'Configure UI effect style, shadow intensity and border appearance.',\n cs: 'Nastavte styl efektů UI, intenzitu stínů a vzhled okrajů.',\n },\n },\n fields: [\n {\n name: 'visualEffects',\n type: 'group',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'effectStyle',\n type: 'select',\n label: {\n en: 'Effect Style',\n cs: 'Styl efektů',\n },\n defaultValue: 'flat',\n options: [\n { label: { en: 'Flat', cs: 'Plochý' }, value: 'flat' },\n {\n label: { en: 'Elevated (Box shadows)', cs: 'Vyvýšený (stíny)' },\n value: 'elevated',\n },\n {\n label: {\n en: 'Glassmorphism (Frosted glass)',\n cs: 'Glassmorphism (mléčné sklo)',\n },\n value: 'glass',\n },\n {\n label: { en: 'Neumorphism (Soft UI)', cs: 'Neumorphism (měkké UI)' },\n value: 'neumorphic',\n },\n {\n label: { en: 'Claymorphism (Clay-like)', cs: 'Claymorphism (hlína)' },\n value: 'clay',\n },\n ],\n admin: {\n description: {\n en: 'Visual style applied to cards, panels and interactive elements.',\n cs: 'Vizuální styl karet, panelů a interaktivních prvků.',\n },\n width: '50%',\n },\n dbName: 'effect_style',\n },\n {\n name: 'shadowIntensity',\n type: 'select',\n label: {\n en: 'Shadow Intensity',\n cs: 'Intenzita stínů',\n },\n defaultValue: 'medium',\n options: [\n { label: { en: 'None', cs: 'Žádné' }, value: 'none' },\n { label: { en: 'Subtle', cs: 'Jemné' }, value: 'subtle' },\n { label: { en: 'Medium', cs: 'Střední' }, value: 'medium' },\n { label: { en: 'Strong', cs: 'Silné' }, value: 'strong' },\n { label: { en: 'Dramatic', cs: 'Dramatické' }, value: 'dramatic' },\n ],\n admin: {\n description: {\n en: 'Global shadow depth for elevated elements.',\n cs: 'Globální hloubka stínů pro vyvýšené prvky.',\n },\n width: '50%',\n },\n dbName: 'shadow_intensity',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'backdropBlur',\n type: 'select',\n label: {\n en: 'Backdrop Blur',\n cs: 'Rozmazání pozadí',\n },\n defaultValue: 'none',\n options: [\n { label: { en: 'None', cs: 'Žádné' }, value: 'none' },\n { label: { en: 'Slight (4px)', cs: 'Jemné (4px)' }, value: 'slight' },\n { label: { en: 'Medium (8px)', cs: 'Střední (8px)' }, value: 'medium' },\n { label: { en: 'Strong (16px)', cs: 'Silné (16px)' }, value: 'strong' },\n { label: { en: 'Heavy (24px)', cs: 'Intenzivní (24px)' }, value: 'heavy' },\n ],\n admin: {\n description: {\n en: 'Blur effect behind translucent elements (requires glass effect style).',\n cs: 'Rozmazání za průhledné prvky (vyžaduje styl skla).',\n },\n width: '50%',\n },\n dbName: 'backdrop_blur',\n },\n {\n name: 'borderStyle',\n type: 'select',\n label: {\n en: 'Border Style',\n cs: 'Styl okrajů',\n },\n defaultValue: 'solid',\n options: [\n { label: { en: 'None', cs: 'Žádné' }, value: 'none' },\n { label: { en: 'Solid', cs: 'Plné' }, value: 'solid' },\n { label: { en: 'Dashed', cs: 'Čárkované' }, value: 'dashed' },\n { label: { en: 'Dotted', cs: 'Tečkované' }, value: 'dotted' },\n { label: { en: 'Double', cs: 'Dvojité' }, value: 'double' },\n ],\n admin: {\n description: {\n en: 'Default border style for cards, inputs and dividers.',\n cs: 'Výchozí styl okrajů pro karty, vstupy a oddělovače.',\n },\n width: '50%',\n },\n dbName: 'border_style',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'borderWidth',\n type: 'select',\n label: {\n en: 'Border Width',\n cs: 'Tloušťka okraje',\n },\n defaultValue: '1px',\n options: [\n { label: '0px', value: '0px' },\n { label: '1px', value: '1px' },\n { label: '2px', value: '2px' },\n { label: '3px', value: '3px' },\n { label: '4px', value: '4px' },\n ],\n admin: { width: '50%' },\n dbName: 'border_width',\n },\n {\n name: 'glassOpacity',\n type: 'number',\n label: {\n en: 'Glass Opacity (%)',\n cs: 'Průhlednost skla (%)',\n },\n defaultValue: 60,\n min: 0,\n max: 100,\n admin: {\n description: {\n en: 'Card/panel opacity when using glass effect (0 = fully transparent, 100 = opaque).',\n cs: 'Průhlednost karet/panelů při skleněném efektu (0 = plně průhledné, 100 = neprůhledné).',\n },\n width: '50%',\n condition: (_, siblingData) => siblingData?.effectStyle === 'glass',\n },\n },\n ],\n },\n ],\n },\n ],\n })\n\n // Component Styles — buttons, cards, images, icons\n fields.push({\n type: 'collapsible',\n label: {\n en: 'Component Styles',\n cs: 'Styly komponent',\n },\n admin: {\n initCollapsed: true,\n className: 'tm-section-components',\n description: {\n en: 'Customize button variant, card style and navbar appearance.',\n cs: 'Přizpůsobte styl tlačítek, karet a navigační lišty.',\n },\n },\n fields: [\n {\n name: 'componentStyles',\n type: 'group',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'buttonVariant',\n type: 'select',\n label: {\n en: 'Primary Button Style',\n cs: 'Styl primárního tlačítka',\n },\n defaultValue: 'filled',\n options: [\n { label: { en: 'Filled (solid)', cs: 'Plné (solid)' }, value: 'filled' },\n { label: { en: 'Outlined', cs: 'Ohraničené' }, value: 'outlined' },\n { label: { en: 'Ghost (transparent)', cs: 'Průhledné' }, value: 'ghost' },\n { label: { en: 'Gradient', cs: 'Přechodové' }, value: 'gradient' },\n {\n label: { en: 'Pill (full rounded)', cs: 'Pill (plné zaoblení)' },\n value: 'pill',\n },\n {\n label: { en: 'Brutalist (thick border)', cs: 'Brutalistické (silný okraj)' },\n value: 'brutal',\n },\n ],\n admin: {\n description: {\n en: 'Default visual style of primary action buttons.',\n cs: 'Výchozí vizuální styl primárních tlačítek.',\n },\n width: '50%',\n },\n dbName: 'button_variant',\n },\n {\n name: 'buttonSize',\n type: 'select',\n label: {\n en: 'Button Size',\n cs: 'Velikost tlačítka',\n },\n defaultValue: 'medium',\n options: [\n { label: { en: 'Small', cs: 'Malé' }, value: 'small' },\n { label: { en: 'Medium', cs: 'Střední' }, value: 'medium' },\n { label: { en: 'Large', cs: 'Velké' }, value: 'large' },\n { label: { en: 'XL', cs: 'XL' }, value: 'xl' },\n ],\n admin: {\n description: {\n en: 'Default padding / font-size of buttons.',\n cs: 'Výchozí odsazení a velikost písma tlačítek.',\n },\n width: '50%',\n },\n dbName: 'button_size',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'cardStyle',\n type: 'select',\n label: {\n en: 'Card Style',\n cs: 'Styl karet',\n },\n defaultValue: 'elevated',\n options: [\n { label: { en: 'Elevated (shadow)', cs: 'Vyvýšené (stín)' }, value: 'elevated' },\n { label: { en: 'Flat (no shadow)', cs: 'Ploché (bez stínu)' }, value: 'flat' },\n { label: { en: 'Bordered', cs: 'S okrajem' }, value: 'bordered' },\n { label: { en: 'Glass', cs: 'Skleněné' }, value: 'glass' },\n { label: { en: 'Neumorphic', cs: 'Neumorfní' }, value: 'neumorphic' },\n {\n label: { en: 'Gradient border', cs: 'Přechodový okraj' },\n value: 'gradient-border',\n },\n ],\n admin: {\n description: {\n en: 'Default card/panel visual style across the website.',\n cs: 'Výchozí vizuální styl karet a panelů na webu.',\n },\n width: '50%',\n },\n dbName: 'card_style',\n },\n {\n name: 'cardHoverEffect',\n type: 'select',\n label: {\n en: 'Card Hover Effect',\n cs: 'Efekt při najetí na kartu',\n },\n defaultValue: 'lift',\n options: [\n { label: { en: 'None', cs: 'Žádný' }, value: 'none' },\n {\n label: { en: 'Lift (translate up)', cs: 'Zvednutí (posun nahoru)' },\n value: 'lift',\n },\n { label: { en: 'Scale up', cs: 'Zvětšení' }, value: 'scale' },\n { label: { en: 'Shadow grow', cs: 'Větší stín' }, value: 'shadow' },\n { label: { en: 'Border glow', cs: 'Zářící okraj' }, value: 'glow' },\n { label: { en: 'Tilt 3D', cs: '3D náklon' }, value: 'tilt' },\n ],\n admin: {\n width: '50%',\n },\n dbName: 'card_hover_effect',\n },\n ],\n },\n\n {\n type: 'row',\n fields: [\n {\n name: 'navbarStyle',\n type: 'select',\n label: {\n en: 'Navbar Style',\n cs: 'Styl navigace',\n },\n defaultValue: 'solid',\n options: [\n { label: { en: 'Solid', cs: 'Plná' }, value: 'solid' },\n {\n label: { en: 'Transparent (on hero)', cs: 'Průhledná (nad hero)' },\n value: 'transparent',\n },\n { label: { en: 'Blurred glass', cs: 'Rozmazané sklo' }, value: 'blur' },\n { label: { en: 'Floating', cs: 'Plovoucí' }, value: 'floating' },\n {\n label: {\n en: 'Minimal (bottom border only)',\n cs: 'Minimalistická (jen spodní okraj)',\n },\n value: 'minimal',\n },\n ],\n admin: {\n description: {\n en: 'Navigation bar visual style.',\n cs: 'Vizuální styl navigační lišty.',\n },\n width: '50%',\n },\n dbName: 'navbar_style',\n },\n {\n name: 'footerStyle',\n type: 'select',\n label: {\n en: 'Footer Style',\n cs: 'Styl patičky',\n },\n defaultValue: 'standard',\n options: [\n { label: { en: 'Standard', cs: 'Standardní' }, value: 'standard' },\n { label: { en: 'Minimal', cs: 'Minimalistická' }, value: 'minimal' },\n { label: { en: 'Dark', cs: 'Tmavá' }, value: 'dark' },\n {\n label: { en: 'Gradient top edge', cs: 'Gradient horní hrana' },\n value: 'gradient-top',\n },\n { label: { en: 'Full colour', cs: 'Plná barva' }, value: 'full-color' },\n ],\n admin: {\n description: {\n en: 'Footer visual style.',\n cs: 'Vizuální styl patičky.',\n },\n width: '50%',\n },\n dbName: 'footer_style',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'imageStyle',\n type: 'select',\n label: {\n en: 'Image Style',\n cs: 'Styl obrázků',\n },\n defaultValue: 'default',\n options: [\n { label: { en: 'Default', cs: 'Výchozí' }, value: 'default' },\n { label: { en: 'Rounded', cs: 'Zaoblené' }, value: 'rounded' },\n { label: { en: 'Circle', cs: 'Kruhové' }, value: 'circle' },\n { label: { en: 'Vignette', cs: 'Vinětace' }, value: 'vignette' },\n { label: { en: 'Grayscale', cs: 'Černobílé' }, value: 'grayscale' },\n { label: { en: 'Duotone', cs: 'Duotón' }, value: 'duotone' },\n { label: { en: 'Polaroid', cs: 'Polaroid' }, value: 'polaroid' },\n ],\n admin: {\n description: {\n en: 'Default treatment for content images (applied via [data-img] / .themed-image).',\n cs: 'Výchozí úprava obsahových obrázků (přes [data-img] / .themed-image).',\n },\n width: '50%',\n },\n dbName: 'image_style',\n },\n {\n name: 'linkStyle',\n type: 'select',\n label: {\n en: 'Link Style',\n cs: 'Styl odkazů',\n },\n defaultValue: 'underline-hover',\n options: [\n { label: { en: 'Always underlined', cs: 'Vždy podtržené' }, value: 'underline' },\n {\n label: { en: 'Underline on hover', cs: 'Podtržení při najetí' },\n value: 'underline-hover',\n },\n { label: { en: 'No underline', cs: 'Bez podtržení' }, value: 'none' },\n { label: { en: 'Highlight', cs: 'Zvýraznění' }, value: 'highlight' },\n {\n label: { en: 'Animated underline', cs: 'Animované podtržení' },\n value: 'animated',\n },\n ],\n admin: {\n description: {\n en: 'Default style for in-content links (applied via [data-link] / .themed-link).',\n cs: 'Výchozí styl odkazů v obsahu (přes [data-link] / .themed-link).',\n },\n width: '50%',\n },\n dbName: 'link_style',\n },\n ],\n },\n {\n type: 'row',\n fields: [\n {\n name: 'enableScrollReveal',\n type: 'checkbox',\n label: {\n en: 'Scroll reveal animations',\n cs: 'Animace při scrollování',\n },\n defaultValue: true,\n admin: {\n description: {\n en: 'Reveal elements as they enter the viewport.',\n cs: 'Odhalovat prvky při vstupu do viewportu.',\n },\n width: '50%',\n },\n },\n {\n name: 'enableHoverAnimations',\n type: 'checkbox',\n label: {\n en: 'Hover micro-animations',\n cs: 'Hover mikro-animace',\n },\n defaultValue: true,\n admin: {\n description: {\n en: 'Subtle motion on interactive elements when hovered.',\n cs: 'Jemný pohyb interaktivních prvků při najetí.',\n },\n width: '50%',\n },\n },\n ],\n },\n ],\n },\n ],\n })\n\n if (customThemeConfigurationFields?.length) {\n fields.push(...customThemeConfigurationFields)\n }\n\n if (customThemeConfigurationSections?.length) {\n customThemeConfigurationSections.forEach((section) => {\n fields.push({\n type: 'collapsible',\n label: section.label,\n admin: {\n initCollapsed: section.initCollapsed ?? true,\n description: section.description,\n },\n fields: section.fields,\n })\n })\n }\n\n // Advanced Settings (when using extended theme configuration)\n if (enableAdvancedFeatures) {\n const advancedFields: Field[] = [\n {\n name: 'animationLevel',\n type: 'select',\n label: {\n en: 'Animation Level',\n cs: 'Úroveň animací',\n },\n defaultValue: 'medium',\n options: [\n { label: { en: 'None', cs: 'Žádné' }, value: 'none' },\n { label: { en: 'Reduced', cs: 'Snížené' }, value: 'reduced' },\n { label: { en: 'Medium', cs: 'Střední' }, value: 'medium' },\n { label: { en: 'High', cs: 'Vysoké' }, value: 'high' },\n ],\n admin: {\n description: {\n en: 'Control website animations and transitions',\n cs: 'Kontrola animací a přechodů na webu',\n },\n width: '50%',\n },\n dbName: 'animation_level',\n },\n ]\n\n if (includeCustomCSS) {\n advancedFields.push({\n name: 'customCSS',\n type: 'code',\n label: {\n en: 'Custom CSS',\n cs: 'Vlastní CSS',\n },\n admin: {\n language: 'css',\n description: {\n en: 'Add custom CSS to override default styles',\n cs: 'Přidejte vlastní CSS pro přepsání výchozích stylů',\n },\n // placeholder:\n // ':root {\\n --primary: #your-color;\\n --border-radius: 8px;\\n --font-family: \"Your Font\";\\n}\\n\\n.custom-class {\\n /* Your custom styles */\\n}',\n // rows: 8,\n },\n })\n }\n\n fields.push({\n type: 'collapsible',\n label: {\n en: 'Advanced Settings',\n cs: 'Pokročilé nastavení',\n },\n admin: {\n initCollapsed: true,\n className: 'tm-section-advanced',\n },\n fields: advancedFields,\n })\n }\n\n // Return as tab configuration to be injected into tabs structure\n return {\n label: {\n en: 'Appearance Settings',\n cs: 'Nastavení vzhledu',\n },\n fields: [\n {\n name: 'themeConfiguration',\n type: 'group',\n admin: {\n className: 'tm-appearance',\n description: {\n en: 'Appearance and style of the whole website',\n cs: 'Vzhled a styl celého webu',\n },\n },\n fields,\n },\n ],\n }\n}\n"],"names":["BASE_FONT_SIZE_OPTIONS","BODY_FONT_OPTIONS","HEADING_FONT_OPTIONS","LINE_HEIGHT_OPTIONS","getTranslations","darkModeField","lightModeField","createThemeConfigurationField","options","themePresets","defaultTheme","includeColorModeToggle","includeCustomCSS","enableAdvancedFeatures","useThemePreviewField","customThemeConfigurationFields","customThemeConfigurationSections","fields","name","type","required","defaultValue","label","en","cs","validate","value","trim","length","req","i18n","language","ui","selectThemeError","admin","description","components","Field","custom","push","initCollapsed","className","width","dbName","placeholder","condition","_","siblingData","bodyFont","headingFont","map","option","customPresetsField","min","max","effectStyle","forEach","section","advancedFields"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FontPreview.d.ts","sourceRoot":"","sources":["../../../../src/globals/ThemeSettings/FontPicker/FontPreview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAA;AAIrE,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,MAAM,GACN,OAAO,GACP,OAAO,GACP,SAAS,GACT,MAAM,GACN,KAAK,GACL,MAAM,CAAA;AAEV,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAgPlD,CAAA"}
1
+ {"version":3,"file":"FontPreview.d.ts","sourceRoot":"","sources":["../../../../src/globals/ThemeSettings/FontPicker/FontPreview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAA;AAIrE,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,MAAM,GACN,OAAO,GACP,OAAO,GACP,SAAS,GACT,MAAM,GACN,KAAK,GACL,MAAM,CAAA;AAEV,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAoPlD,CAAA"}
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import React, { useEffect, useRef } from 'react';
4
+ import { useThemeLanguage } from '../../../hooks/useThemeTranslations.js';
4
5
  import { getTranslations } from '../../../translations.js';
5
- import { getAdminLanguage } from '../../../utils/getAdminLanguage.js';
6
6
  /**
7
7
  * FontPreview component with Shadow DOM isolation
8
8
  *
@@ -12,6 +12,7 @@ import { getAdminLanguage } from '../../../utils/getAdminLanguage.js';
12
12
  const shadowHostRef = useRef(null);
13
13
  const shadowRootRef = useRef(null);
14
14
  const fontLoadedRef = useRef(false);
15
+ const adminLang = useThemeLanguage();
15
16
  useEffect(()=>{
16
17
  if (!shadowHostRef.current) return;
17
18
  // Create Shadow DOM if not already created
@@ -56,7 +57,7 @@ import { getAdminLanguage } from '../../../utils/getAdminLanguage.js';
56
57
  padding: 0;
57
58
  `;
58
59
  let content;
59
- const t = getTranslations(getAdminLanguage());
60
+ const t = getTranslations(adminLang);
60
61
  switch(variant){
61
62
  case 'h1':
62
63
  content = document.createElement('h1');
@@ -218,11 +219,14 @@ import { getAdminLanguage } from '../../../utils/getAdminLanguage.js';
218
219
  font,
219
220
  variant,
220
221
  text,
221
- onLoad
222
+ onLoad,
223
+ adminLang
222
224
  ]);
223
- return /*#__PURE__*/ _jsx("div", {
225
+ // A span host keeps the preview valid inside interactive parents such as <button>.
226
+ return /*#__PURE__*/ _jsx("span", {
224
227
  ref: shadowHostRef,
225
228
  style: {
229
+ display: 'block',
226
230
  width: '100%',
227
231
  minHeight: '20px'
228
232
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/globals/ThemeSettings/FontPicker/FontPreview.tsx"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useRef } from 'react'\nimport type { GoogleFont } from '../../../app/api/google-fonts/route'\nimport { getTranslations } from '../../../translations.js'\nimport { getAdminLanguage } from '../../../utils/getAdminLanguage.js'\n\nexport type PreviewVariant =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'body'\n | 'small'\n | 'chars'\n | 'weights'\n | 'card'\n | 'row'\n | 'name'\n\nexport interface FontPreviewProps {\n font: GoogleFont\n variant: PreviewVariant\n text?: string\n onLoad?: () => void\n}\n\n/**\n * FontPreview component with Shadow DOM isolation\n *\n * This component renders font previews in an isolated Shadow DOM\n * to prevent Payload CMS admin styles from affecting the preview.\n */\nexport const FontPreview: React.FC<FontPreviewProps> = ({ font, variant, text, onLoad }) => {\n const shadowHostRef = useRef<HTMLDivElement>(null)\n const shadowRootRef = useRef<ShadowRoot | null>(null)\n const fontLoadedRef = useRef(false)\n\n useEffect(() => {\n if (!shadowHostRef.current) return\n\n // Create Shadow DOM if not already created\n if (!shadowRootRef.current) {\n shadowRootRef.current = shadowHostRef.current.attachShadow({ mode: 'open' })\n }\n\n const shadowRoot = shadowRootRef.current\n\n // Get font weights\n const weights = font.variants.filter((v) => !v.includes('italic')).join(';')\n const fontFamily = font.family\n\n // Load font CSS\n const loadFont = async () => {\n if (fontLoadedRef.current) return\n\n try {\n // Create font face CSS\n const fontUrl = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(\n fontFamily,\n )}:wght@${weights}&display=swap`\n\n // Check if font is already loaded\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = fontUrl\n\n // Wait for font to load\n link.onload = () => {\n fontLoadedRef.current = true\n onLoad?.()\n }\n\n // Add link to shadow root\n shadowRoot.appendChild(link)\n } catch (error) {\n console.error('Error loading font:', error)\n }\n }\n\n loadFont()\n\n // Render preview based on variant\n const renderPreview = () => {\n const container = document.createElement('div')\n container.style.cssText = `\n font-family: '${fontFamily}', sans-serif;\n color: inherit;\n margin: 0;\n padding: 0;\n `\n\n let content: HTMLElement\n const t = getTranslations(getAdminLanguage())\n\n switch (variant) {\n case 'h1':\n content = document.createElement('h1')\n content.style.cssText = `\n font-size: 48px;\n font-weight: 700;\n line-height: 1.2;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'h2':\n content = document.createElement('h2')\n content.style.cssText = `\n font-size: 36px;\n font-weight: 600;\n line-height: 1.3;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'h3':\n content = document.createElement('h3')\n content.style.cssText = `\n font-size: 24px;\n font-weight: 500;\n line-height: 1.4;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'body':\n content = document.createElement('p')\n content.style.cssText = `\n font-size: 16px;\n font-weight: 400;\n line-height: 1.6;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'small':\n content = document.createElement('p')\n content.style.cssText = `\n font-size: 14px;\n font-weight: 400;\n line-height: 1.5;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'chars':\n content = document.createElement('div')\n content.style.cssText = `\n font-size: 18px;\n font-weight: 400;\n line-height: 1.5;\n margin: 0;\n `\n content.textContent = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz 0123456789'\n break\n\n case 'weights':\n content = document.createElement('div')\n content.style.cssText = `margin: 0;`\n const availableWeights = font.variants\n .filter((v) => !v.includes('italic'))\n .map((v) => parseInt(v))\n .filter((w) => !isNaN(w))\n .sort((a, b) => a - b)\n\n availableWeights.forEach((weight) => {\n const line = document.createElement('div')\n line.style.cssText = `\n font-size: 16px;\n font-weight: ${weight};\n line-height: 1.8;\n margin: 4px 0;\n `\n line.textContent = `${weight} - ${t.ui.sampleSentence}`\n content.appendChild(line)\n })\n break\n\n case 'card':\n content = document.createElement('div')\n content.style.cssText = `\n padding: 16px;\n background: var(--theme-bg, #ffffff);\n border: 1px solid var(--theme-border, #e5e7eb);\n border-radius: 8px;\n margin: 0;\n `\n const title = document.createElement('h3')\n title.style.cssText = `\n font-size: 20px;\n font-weight: 600;\n margin: 0 0 8px 0;\n `\n title.textContent = font.family\n const description = document.createElement('p')\n description.style.cssText = `\n font-size: 14px;\n font-weight: 400;\n line-height: 1.5;\n margin: 0;\n color: var(--theme-text-secondary, #6b7280); // visual only (no text change)\n `\n description.textContent = text || t.ui.sampleSentence\n content.appendChild(title)\n content.appendChild(description)\n break\n\n case 'row':\n content = document.createElement('div')\n content.style.cssText = `\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n margin: 0;\n `\n const nameSpan = document.createElement('span')\n nameSpan.style.cssText = `\n font-size: 16px;\n font-weight: 500;\n min-width: 150px;\n `\n nameSpan.textContent = font.family\n const sampleSpan = document.createElement('span')\n sampleSpan.style.cssText = `\n font-size: 16px;\n font-weight: 400;\n flex: 1;\n opacity: 0.7;\n `\n sampleSpan.textContent = text || t.ui.sampleSentence\n content.appendChild(nameSpan)\n content.appendChild(sampleSpan)\n break\n\n case 'name':\n default:\n content = document.createElement('span')\n content.style.cssText = `\n font-size: 16px;\n font-weight: 500;\n margin: 0;\n `\n content.textContent = font.family\n break\n }\n\n container.appendChild(content)\n return container\n }\n\n // Clear previous content\n shadowRoot.innerHTML = ''\n\n // Render preview\n const preview = renderPreview()\n shadowRoot.appendChild(preview)\n\n // Cleanup\n return () => {\n if (shadowRoot) {\n shadowRoot.innerHTML = ''\n }\n }\n }, [font, variant, text, onLoad])\n\n return <div ref={shadowHostRef} style={{ width: '100%', minHeight: '20px' }} />\n}\n"],"names":["React","useEffect","useRef","getTranslations","getAdminLanguage","FontPreview","font","variant","text","onLoad","shadowHostRef","shadowRootRef","fontLoadedRef","current","attachShadow","mode","shadowRoot","weights","variants","filter","v","includes","join","fontFamily","family","loadFont","fontUrl","encodeURIComponent","link","document","createElement","rel","href","onload","appendChild","error","console","renderPreview","container","style","cssText","content","t","textContent","availableWeights","map","parseInt","w","isNaN","sort","a","b","forEach","weight","line","ui","sampleSentence","title","description","nameSpan","sampleSpan","innerHTML","preview","div","ref","width","minHeight"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/globals/ThemeSettings/FontPicker/FontPreview.tsx"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useRef } from 'react'\nimport type { GoogleFont } from '../../../app/api/google-fonts/route'\nimport { useThemeLanguage } from '../../../hooks/useThemeTranslations.js'\nimport { getTranslations } from '../../../translations.js'\n\nexport type PreviewVariant =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'body'\n | 'small'\n | 'chars'\n | 'weights'\n | 'card'\n | 'row'\n | 'name'\n\nexport interface FontPreviewProps {\n font: GoogleFont\n variant: PreviewVariant\n text?: string\n onLoad?: () => void\n}\n\n/**\n * FontPreview component with Shadow DOM isolation\n *\n * This component renders font previews in an isolated Shadow DOM\n * to prevent Payload CMS admin styles from affecting the preview.\n */\nexport const FontPreview: React.FC<FontPreviewProps> = ({ font, variant, text, onLoad }) => {\n const shadowHostRef = useRef<HTMLSpanElement>(null)\n const shadowRootRef = useRef<ShadowRoot | null>(null)\n const fontLoadedRef = useRef(false)\n const adminLang = useThemeLanguage()\n\n useEffect(() => {\n if (!shadowHostRef.current) return\n\n // Create Shadow DOM if not already created\n if (!shadowRootRef.current) {\n shadowRootRef.current = shadowHostRef.current.attachShadow({ mode: 'open' })\n }\n\n const shadowRoot = shadowRootRef.current\n\n // Get font weights\n const weights = font.variants.filter((v) => !v.includes('italic')).join(';')\n const fontFamily = font.family\n\n // Load font CSS\n const loadFont = async () => {\n if (fontLoadedRef.current) return\n\n try {\n // Create font face CSS\n const fontUrl = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(\n fontFamily,\n )}:wght@${weights}&display=swap`\n\n // Check if font is already loaded\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = fontUrl\n\n // Wait for font to load\n link.onload = () => {\n fontLoadedRef.current = true\n onLoad?.()\n }\n\n // Add link to shadow root\n shadowRoot.appendChild(link)\n } catch (error) {\n console.error('Error loading font:', error)\n }\n }\n\n loadFont()\n\n // Render preview based on variant\n const renderPreview = () => {\n const container = document.createElement('div')\n container.style.cssText = `\n font-family: '${fontFamily}', sans-serif;\n color: inherit;\n margin: 0;\n padding: 0;\n `\n\n let content: HTMLElement\n const t = getTranslations(adminLang)\n\n switch (variant) {\n case 'h1':\n content = document.createElement('h1')\n content.style.cssText = `\n font-size: 48px;\n font-weight: 700;\n line-height: 1.2;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'h2':\n content = document.createElement('h2')\n content.style.cssText = `\n font-size: 36px;\n font-weight: 600;\n line-height: 1.3;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'h3':\n content = document.createElement('h3')\n content.style.cssText = `\n font-size: 24px;\n font-weight: 500;\n line-height: 1.4;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'body':\n content = document.createElement('p')\n content.style.cssText = `\n font-size: 16px;\n font-weight: 400;\n line-height: 1.6;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'small':\n content = document.createElement('p')\n content.style.cssText = `\n font-size: 14px;\n font-weight: 400;\n line-height: 1.5;\n margin: 0;\n `\n content.textContent = text || font.family\n break\n\n case 'chars':\n content = document.createElement('div')\n content.style.cssText = `\n font-size: 18px;\n font-weight: 400;\n line-height: 1.5;\n margin: 0;\n `\n content.textContent = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz 0123456789'\n break\n\n case 'weights':\n content = document.createElement('div')\n content.style.cssText = `margin: 0;`\n const availableWeights = font.variants\n .filter((v) => !v.includes('italic'))\n .map((v) => parseInt(v))\n .filter((w) => !isNaN(w))\n .sort((a, b) => a - b)\n\n availableWeights.forEach((weight) => {\n const line = document.createElement('div')\n line.style.cssText = `\n font-size: 16px;\n font-weight: ${weight};\n line-height: 1.8;\n margin: 4px 0;\n `\n line.textContent = `${weight} - ${t.ui.sampleSentence}`\n content.appendChild(line)\n })\n break\n\n case 'card':\n content = document.createElement('div')\n content.style.cssText = `\n padding: 16px;\n background: var(--theme-bg, #ffffff);\n border: 1px solid var(--theme-border, #e5e7eb);\n border-radius: 8px;\n margin: 0;\n `\n const title = document.createElement('h3')\n title.style.cssText = `\n font-size: 20px;\n font-weight: 600;\n margin: 0 0 8px 0;\n `\n title.textContent = font.family\n const description = document.createElement('p')\n description.style.cssText = `\n font-size: 14px;\n font-weight: 400;\n line-height: 1.5;\n margin: 0;\n color: var(--theme-text-secondary, #6b7280); // visual only (no text change)\n `\n description.textContent = text || t.ui.sampleSentence\n content.appendChild(title)\n content.appendChild(description)\n break\n\n case 'row':\n content = document.createElement('div')\n content.style.cssText = `\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n margin: 0;\n `\n const nameSpan = document.createElement('span')\n nameSpan.style.cssText = `\n font-size: 16px;\n font-weight: 500;\n min-width: 150px;\n `\n nameSpan.textContent = font.family\n const sampleSpan = document.createElement('span')\n sampleSpan.style.cssText = `\n font-size: 16px;\n font-weight: 400;\n flex: 1;\n opacity: 0.7;\n `\n sampleSpan.textContent = text || t.ui.sampleSentence\n content.appendChild(nameSpan)\n content.appendChild(sampleSpan)\n break\n\n case 'name':\n default:\n content = document.createElement('span')\n content.style.cssText = `\n font-size: 16px;\n font-weight: 500;\n margin: 0;\n `\n content.textContent = font.family\n break\n }\n\n container.appendChild(content)\n return container\n }\n\n // Clear previous content\n shadowRoot.innerHTML = ''\n\n // Render preview\n const preview = renderPreview()\n shadowRoot.appendChild(preview)\n\n // Cleanup\n return () => {\n if (shadowRoot) {\n shadowRoot.innerHTML = ''\n }\n }\n }, [font, variant, text, onLoad, adminLang])\n\n // A span host keeps the preview valid inside interactive parents such as <button>.\n return (\n <span ref={shadowHostRef} style={{ display: 'block', width: '100%', minHeight: '20px' }} />\n )\n}\n"],"names":["React","useEffect","useRef","useThemeLanguage","getTranslations","FontPreview","font","variant","text","onLoad","shadowHostRef","shadowRootRef","fontLoadedRef","adminLang","current","attachShadow","mode","shadowRoot","weights","variants","filter","v","includes","join","fontFamily","family","loadFont","fontUrl","encodeURIComponent","link","document","createElement","rel","href","onload","appendChild","error","console","renderPreview","container","style","cssText","content","t","textContent","availableWeights","map","parseInt","w","isNaN","sort","a","b","forEach","weight","line","ui","sampleSentence","title","description","nameSpan","sampleSpan","innerHTML","preview","span","ref","display","width","minHeight"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/globals/ThemeSettings/FontPicker/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,KAAmD,MAAM,OAAO,CAAA;AAQvE,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAQlE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAanD,CAAA;AAED,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA2TlD,CAAA;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAC9B,eAAe,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/globals/ThemeSettings/FontPicker/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,KAAmD,MAAM,OAAO,CAAA;AASvE,OAAO,EAAiC,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAOhF,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAenD,CAAA;AAED,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAoWlD,CAAA;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAC9B,eAAe,eAAe,CAAA"}
@@ -1,13 +1,14 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useField } from '@payloadcms/ui';
4
+ import { Star } from 'lucide-react';
4
5
  import React, { useCallback, useEffect, useRef, useState } from 'react';
6
+ import { useThemeLanguage } from '../../../hooks/useThemeTranslations.js';
5
7
  import { FontPreview } from './FontPreview.js';
6
8
  import { PreviewContent } from './PreviewContent.js';
7
- import { getTranslations } from './translations.js';
9
+ import { getTranslations, translations } from './translations.js';
8
10
  // Import CSS for styling
9
11
  if (typeof window !== 'undefined') {
10
- // @ts-expect-error - Dynamic CSS import
11
12
  import('./styles.css').catch(()=>{});
12
13
  }
13
14
  /**
@@ -26,8 +27,9 @@ if (typeof window !== 'undefined') {
26
27
  const { value, setValue } = useField({
27
28
  path
28
29
  });
29
- const language = 'en' // Could be extracted from admin config
30
- ;
30
+ const adminLang = useThemeLanguage();
31
+ // FontPicker ships its own en/cs strings; fall back to English for any other locale.
32
+ const language = adminLang in translations ? adminLang : 'en';
31
33
  const handleChange = useCallback((fontFamily)=>{
32
34
  setValue(fontFamily);
33
35
  }, [
@@ -44,6 +46,7 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
44
46
  // State
45
47
  const [fonts, setFonts] = useState([]);
46
48
  const [loading, setLoading] = useState(false);
49
+ const [loadError, setLoadError] = useState(false);
47
50
  const [search, setSearch] = useState('');
48
51
  const [category, setCategory] = useState('all');
49
52
  const [subset, setSubset] = useState('all');
@@ -81,6 +84,7 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
81
84
  const fetchFonts = useCallback(async (reset = false)=>{
82
85
  if (loading) return;
83
86
  setLoading(true);
87
+ setLoadError(false);
84
88
  try {
85
89
  const currentOffset = reset ? 0 : offset;
86
90
  const params = new URLSearchParams({
@@ -91,6 +95,7 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
91
95
  offset: currentOffset.toString()
92
96
  });
93
97
  const response = await fetch(`/api/google-fonts?${params}`);
98
+ if (!response.ok) throw new Error(`Font request failed with ${response.status}`);
94
99
  const data = await response.json();
95
100
  if (reset) {
96
101
  setFonts(data.fonts);
@@ -105,6 +110,8 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
105
110
  setHasMore(currentOffset + data.fonts.length < data.total);
106
111
  } catch (error) {
107
112
  console.error('Error fetching fonts:', error);
113
+ setLoadError(true);
114
+ setHasMore(false);
108
115
  } finally{
109
116
  setLoading(false);
110
117
  }
@@ -220,12 +227,16 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
220
227
  children: [
221
228
  /*#__PURE__*/ _jsx("div", {
222
229
  className: "font-picker__preview-tabs",
230
+ role: "group",
231
+ "aria-label": t.previewModes,
223
232
  children: [
224
233
  'typography',
225
234
  'blog',
226
235
  'landing',
227
236
  'ui'
228
237
  ].map((tab)=>/*#__PURE__*/ _jsx("button", {
238
+ type: "button",
239
+ "aria-pressed": previewTab === tab,
229
240
  className: `font-picker__preview-tab ${previewTab === tab ? 'font-picker__preview-tab--active' : ''}`,
230
241
  onClick: ()=>setPreviewTab(tab),
231
242
  children: t.previewTabs[tab]
@@ -251,6 +262,7 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
251
262
  type: "text",
252
263
  className: "font-picker__search",
253
264
  placeholder: t.search,
265
+ "aria-label": t.search,
254
266
  value: search,
255
267
  onChange: (e)=>setSearch(e.target.value)
256
268
  }),
@@ -259,6 +271,7 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
259
271
  children: [
260
272
  /*#__PURE__*/ _jsxs("select", {
261
273
  className: "font-picker__select",
274
+ "aria-label": t.category,
262
275
  value: category,
263
276
  onChange: (e)=>setCategory(e.target.value),
264
277
  children: [
@@ -290,6 +303,7 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
290
303
  }),
291
304
  /*#__PURE__*/ _jsxs("select", {
292
305
  className: "font-picker__select",
306
+ "aria-label": t.subset,
293
307
  value: subset,
294
308
  onChange: (e)=>setSubset(e.target.value),
295
309
  children: [
@@ -347,8 +361,13 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
347
361
  }),
348
362
  /*#__PURE__*/ _jsxs("div", {
349
363
  className: "font-picker__view-toggle",
364
+ role: "group",
365
+ "aria-label": t.viewMode,
350
366
  children: [
351
367
  /*#__PURE__*/ _jsx("button", {
368
+ type: "button",
369
+ "aria-pressed": viewMode === 'row',
370
+ "aria-label": t.viewModes.row,
352
371
  className: `font-picker__view-button ${viewMode === 'row' ? 'font-picker__view-button--active' : ''}`,
353
372
  onClick: ()=>setViewMode('row'),
354
373
  title: t.viewModes.row,
@@ -357,6 +376,7 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
357
376
  height: "20",
358
377
  viewBox: "0 0 20 20",
359
378
  fill: "currentColor",
379
+ "aria-hidden": "true",
360
380
  children: [
361
381
  /*#__PURE__*/ _jsx("rect", {
362
382
  x: "2",
@@ -380,6 +400,9 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
380
400
  })
381
401
  }),
382
402
  /*#__PURE__*/ _jsx("button", {
403
+ type: "button",
404
+ "aria-pressed": viewMode === 'grid',
405
+ "aria-label": t.viewModes.grid,
383
406
  className: `font-picker__view-button ${viewMode === 'grid' ? 'font-picker__view-button--active' : ''}`,
384
407
  onClick: ()=>setViewMode('grid'),
385
408
  title: t.viewModes.grid,
@@ -388,6 +411,7 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
388
411
  height: "20",
389
412
  viewBox: "0 0 20 20",
390
413
  fill: "currentColor",
414
+ "aria-hidden": "true",
391
415
  children: [
392
416
  /*#__PURE__*/ _jsx("rect", {
393
417
  x: "2",
@@ -422,45 +446,76 @@ const FontPickerComponent = ({ value, onChange, language = 'en' })=>{
422
446
  }),
423
447
  /*#__PURE__*/ _jsxs("div", {
424
448
  className: `font-picker__list font-picker__list--${viewMode}`,
449
+ role: "list",
450
+ "aria-label": t.fontList,
451
+ "aria-busy": loading,
425
452
  children: [
426
- fonts.map((font)=>/*#__PURE__*/ _jsxs("div", {
427
- className: `font-picker__item ${selectedFont?.family === font.family ? 'font-picker__item--selected' : ''}`,
428
- onClick: ()=>handleFontSelect(font),
429
- onMouseEnter: ()=>handleFontHover(font),
453
+ fonts.map((font)=>{
454
+ const isSelected = selectedFont?.family === font.family;
455
+ const isFavorite = favorites.includes(font.family);
456
+ return /*#__PURE__*/ _jsxs("div", {
457
+ role: "listitem",
458
+ className: `font-picker__item ${isSelected ? 'font-picker__item--selected' : ''}`,
430
459
  children: [
431
- /*#__PURE__*/ _jsxs("div", {
432
- className: "font-picker__item-header",
460
+ /*#__PURE__*/ _jsxs("button", {
461
+ type: "button",
462
+ className: "font-picker__item-select",
463
+ "aria-pressed": isSelected,
464
+ onClick: ()=>handleFontSelect(font),
465
+ onMouseEnter: ()=>handleFontHover(font),
466
+ onFocus: ()=>handleFontHover(font),
433
467
  children: [
434
468
  /*#__PURE__*/ _jsx("span", {
435
469
  className: "font-picker__item-name",
436
470
  children: font.family
437
471
  }),
438
- /*#__PURE__*/ _jsx("button", {
439
- className: `font-picker__favorite ${favorites.includes(font.family) ? 'font-picker__favorite--active' : ''}`,
440
- onClick: (e)=>{
441
- e.stopPropagation();
442
- toggleFavorite(font.family);
443
- },
444
- title: favorites.includes(font.family) ? 'Remove from favorites' : 'Add to favorites',
445
- children: "★"
472
+ /*#__PURE__*/ _jsx("span", {
473
+ className: "font-picker__item-preview",
474
+ children: /*#__PURE__*/ _jsx(FontPreview, {
475
+ font: font,
476
+ variant: "row",
477
+ text: t.typography.body
478
+ })
446
479
  })
447
480
  ]
448
481
  }),
449
- /*#__PURE__*/ _jsx("div", {
450
- className: "font-picker__item-preview",
451
- children: /*#__PURE__*/ _jsx(FontPreview, {
452
- font: font,
453
- variant: "row",
454
- text: t.typography.body
482
+ /*#__PURE__*/ _jsx("button", {
483
+ type: "button",
484
+ className: `font-picker__favorite ${isFavorite ? 'font-picker__favorite--active' : ''}`,
485
+ "aria-pressed": isFavorite,
486
+ "aria-label": `${isFavorite ? t.removeFavorite : t.addFavorite}: ${font.family}`,
487
+ title: isFavorite ? t.removeFavorite : t.addFavorite,
488
+ onClick: ()=>toggleFavorite(font.family),
489
+ children: /*#__PURE__*/ _jsx(Star, {
490
+ size: 16,
491
+ "aria-hidden": "true",
492
+ fill: isFavorite ? 'currentColor' : 'none'
455
493
  })
456
494
  })
457
495
  ]
458
- }, font.family)),
496
+ }, font.family);
497
+ }),
459
498
  loading && /*#__PURE__*/ _jsx("div", {
460
499
  className: "font-picker__loading",
500
+ role: "status",
461
501
  children: t.loading
462
502
  }),
463
- !loading && fonts.length === 0 && /*#__PURE__*/ _jsx("div", {
503
+ !loading && loadError && /*#__PURE__*/ _jsxs("div", {
504
+ className: "font-picker__error",
505
+ role: "alert",
506
+ children: [
507
+ /*#__PURE__*/ _jsx("p", {
508
+ children: t.loadError
509
+ }),
510
+ /*#__PURE__*/ _jsx("button", {
511
+ type: "button",
512
+ className: "font-picker__retry",
513
+ onClick: ()=>fetchFonts(true),
514
+ children: t.retry
515
+ })
516
+ ]
517
+ }),
518
+ !loading && !loadError && fonts.length === 0 && /*#__PURE__*/ _jsx("div", {
464
519
  className: "font-picker__empty",
465
520
  children: t.noFonts
466
521
  }),