@kilivi/payloadcms-theme-management 2.0.0 → 2.2.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.
- package/README.md +346 -845
- package/dist/components/AppearanceSessionControls.d.ts +15 -0
- package/dist/components/AppearanceSessionControls.d.ts.map +1 -0
- package/dist/components/AppearanceSessionControls.js +152 -0
- package/dist/components/AppearanceSessionControls.js.map +1 -0
- package/dist/components/ColorModeToggle.css +42 -0
- package/dist/components/ColorModeToggle.d.ts +40 -0
- package/dist/components/ColorModeToggle.d.ts.map +1 -0
- package/dist/components/ColorModeToggle.js +111 -0
- package/dist/components/ColorModeToggle.js.map +1 -0
- package/dist/components/ServerThemeInjector.d.ts +13 -1
- package/dist/components/ServerThemeInjector.d.ts.map +1 -1
- package/dist/components/ServerThemeInjector.js +65 -15
- package/dist/components/ServerThemeInjector.js.map +1 -1
- package/dist/components/ThemeLivePreviewSync.d.ts +4 -0
- package/dist/components/ThemeLivePreviewSync.d.ts.map +1 -1
- package/dist/components/ThemeLivePreviewSync.js +28 -4
- package/dist/components/ThemeLivePreviewSync.js.map +1 -1
- package/dist/components/ThemeSwitcher.d.ts +36 -0
- package/dist/components/ThemeSwitcher.d.ts.map +1 -0
- package/dist/components/ThemeSwitcher.js +89 -0
- package/dist/components/ThemeSwitcher.js.map +1 -0
- package/dist/components/typographyPreviewUtils.d.ts +5 -0
- package/dist/components/typographyPreviewUtils.d.ts.map +1 -1
- package/dist/components/typographyPreviewUtils.js +24 -11
- package/dist/components/typographyPreviewUtils.js.map +1 -1
- package/dist/constants/devicePreviews.d.ts +35 -0
- package/dist/constants/devicePreviews.d.ts.map +1 -0
- package/dist/constants/devicePreviews.js +43 -0
- package/dist/constants/devicePreviews.js.map +1 -0
- package/dist/constants/themeFonts.d.ts +94 -168
- package/dist/constants/themeFonts.d.ts.map +1 -1
- package/dist/constants/themeFonts.js +260 -140
- package/dist/constants/themeFonts.js.map +1 -1
- package/dist/endpoints/themeFonts.d.ts +5 -0
- package/dist/endpoints/themeFonts.d.ts.map +1 -0
- package/dist/endpoints/themeFonts.js +138 -0
- package/dist/endpoints/themeFonts.js.map +1 -0
- package/dist/extended-presets.d.ts +0 -4
- package/dist/extended-presets.d.ts.map +1 -1
- package/dist/extended-presets.js +1 -18
- package/dist/extended-presets.js.map +1 -1
- package/dist/extended-themes.d.ts.map +1 -1
- package/dist/extended-themes.js +428 -0
- package/dist/extended-themes.js.map +1 -1
- package/dist/fields/AccessibilityAuditField.d.ts +2 -0
- package/dist/fields/AccessibilityAuditField.d.ts.map +1 -0
- package/dist/fields/AccessibilityAuditField.js +303 -0
- package/dist/fields/AccessibilityAuditField.js.map +1 -0
- package/dist/fields/AppearancePreviewField.d.ts +2 -0
- package/dist/fields/AppearancePreviewField.d.ts.map +1 -0
- package/dist/fields/AppearancePreviewField.js +826 -0
- package/dist/fields/AppearancePreviewField.js.map +1 -0
- package/dist/fields/ColorPickerField.d.ts.map +1 -1
- package/dist/fields/ColorPickerField.js +89 -85
- package/dist/fields/ColorPickerField.js.map +1 -1
- package/dist/fields/FontSelectField.css +155 -0
- package/dist/fields/FontSelectField.d.ts +8 -0
- package/dist/fields/FontSelectField.d.ts.map +1 -1
- package/dist/fields/FontSelectField.js +223 -188
- package/dist/fields/FontSelectField.js.map +1 -1
- package/dist/fields/PaletteGeneratorField.d.ts +7 -0
- package/dist/fields/PaletteGeneratorField.d.ts.map +1 -0
- package/dist/fields/PaletteGeneratorField.js +327 -0
- package/dist/fields/PaletteGeneratorField.js.map +1 -0
- package/dist/fields/StylePresetField.d.ts +3 -0
- package/dist/fields/StylePresetField.d.ts.map +1 -0
- package/dist/fields/StylePresetField.js +463 -0
- package/dist/fields/StylePresetField.js.map +1 -0
- package/dist/fields/ThemeColorPickerField.css +115 -35
- package/dist/fields/ThemeColorPickerField.d.ts.map +1 -1
- package/dist/fields/ThemeColorPickerField.js +204 -70
- package/dist/fields/ThemeColorPickerField.js.map +1 -1
- package/dist/fields/ThemeExportField.d.ts +6 -0
- package/dist/fields/ThemeExportField.d.ts.map +1 -0
- package/dist/fields/ThemeExportField.js +202 -0
- package/dist/fields/ThemeExportField.js.map +1 -0
- package/dist/fields/ThemePresetImportField.d.ts.map +1 -1
- package/dist/fields/ThemePresetImportField.js +56 -25
- package/dist/fields/ThemePresetImportField.js.map +1 -1
- package/dist/fields/ThemePreviewField.css +444 -5
- package/dist/fields/ThemePreviewField.d.ts.map +1 -1
- package/dist/fields/ThemePreviewField.js +265 -170
- package/dist/fields/ThemePreviewField.js.map +1 -1
- package/dist/fields/ThemeTokenSelectField.d.ts.map +1 -1
- package/dist/fields/ThemeTokenSelectField.js +278 -80
- package/dist/fields/ThemeTokenSelectField.js.map +1 -1
- package/dist/fields/colorFieldHelpers.d.ts +90 -0
- package/dist/fields/colorFieldHelpers.d.ts.map +1 -0
- package/dist/fields/colorFieldHelpers.js +133 -0
- package/dist/fields/colorFieldHelpers.js.map +1 -0
- package/dist/fields/colorModeFields.d.ts +1 -1
- package/dist/fields/colorModeFields.d.ts.map +1 -1
- package/dist/fields/colorModeFields.js +49 -7
- package/dist/fields/colorModeFields.js.map +1 -1
- package/dist/fields/themeConfigurationField.d.ts +8 -1
- package/dist/fields/themeConfigurationField.d.ts.map +1 -1
- package/dist/fields/themeConfigurationField.js +1209 -228
- package/dist/fields/themeConfigurationField.js.map +1 -1
- package/dist/globals/ThemeSettings/FontPicker/FontPreview.d.ts.map +1 -1
- package/dist/globals/ThemeSettings/FontPicker/FontPreview.js +8 -4
- package/dist/globals/ThemeSettings/FontPicker/FontPreview.js.map +1 -1
- package/dist/globals/ThemeSettings/FontPicker/index.d.ts.map +1 -1
- package/dist/globals/ThemeSettings/FontPicker/index.js +81 -26
- package/dist/globals/ThemeSettings/FontPicker/index.js.map +1 -1
- package/dist/globals/ThemeSettings/FontPicker/styles.css +98 -41
- package/dist/globals/ThemeSettings/FontPicker/translations.d.ts +6 -0
- package/dist/globals/ThemeSettings/FontPicker/translations.d.ts.map +1 -1
- package/dist/globals/ThemeSettings/FontPicker/translations.js +14 -2
- package/dist/globals/ThemeSettings/FontPicker/translations.js.map +1 -1
- package/dist/globals/ThemeSettings/config.d.ts.map +1 -1
- package/dist/globals/ThemeSettings/config.js +76 -79
- package/dist/globals/ThemeSettings/config.js.map +1 -1
- package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.d.ts.map +1 -1
- package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.js +63 -62
- package/dist/globals/ThemeSettings/fields/FontLoadingGuideField.js.map +1 -1
- package/dist/globals/ThemeSettings/fields/TypographyInfoField.d.ts.map +1 -1
- package/dist/globals/ThemeSettings/fields/TypographyInfoField.js +22 -25
- package/dist/globals/ThemeSettings/fields/TypographyInfoField.js.map +1 -1
- package/dist/hooks/useAppearanceSession.d.ts +50 -0
- package/dist/hooks/useAppearanceSession.d.ts.map +1 -0
- package/dist/hooks/useAppearanceSession.js +91 -0
- package/dist/hooks/useAppearanceSession.js.map +1 -0
- package/dist/hooks/useNativeLivePreview.d.ts +15 -0
- package/dist/hooks/useNativeLivePreview.d.ts.map +1 -0
- package/dist/hooks/useNativeLivePreview.js +18 -0
- package/dist/hooks/useNativeLivePreview.js.map +1 -0
- package/dist/hooks/useThemeFonts.d.ts +10 -0
- package/dist/hooks/useThemeFonts.d.ts.map +1 -0
- package/dist/hooks/useThemeFonts.js +36 -0
- package/dist/hooks/useThemeFonts.js.map +1 -0
- package/dist/hooks/useThemeTranslations.d.ts +13 -0
- package/dist/hooks/useThemeTranslations.d.ts.map +1 -0
- package/dist/hooks/useThemeTranslations.js +22 -0
- package/dist/hooks/useThemeTranslations.js.map +1 -0
- package/dist/i18n.d.ts +53 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +53 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +13 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -29
- package/dist/index.js.map +1 -1
- package/dist/next-fonts.d.ts +3 -0
- package/dist/next-fonts.d.ts.map +1 -0
- package/dist/next-fonts.js +360 -0
- package/dist/next-fonts.js.map +1 -0
- package/dist/payload-types.d.ts +34 -6
- package/dist/payload-types.d.ts.map +1 -1
- package/dist/payload-types.js.map +1 -1
- package/dist/presets.d.ts +14 -0
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js.map +1 -1
- package/dist/providers/Theme/index.d.ts.map +1 -1
- package/dist/providers/Theme/index.js +75 -11
- package/dist/providers/Theme/index.js.map +1 -1
- package/dist/providers/Theme/themeConfig.d.ts.map +1 -1
- package/dist/providers/Theme/themeConfig.js +104 -0
- package/dist/providers/Theme/themeConfig.js.map +1 -1
- package/dist/providers/Theme/types.d.ts +1 -1
- package/dist/providers/Theme/types.d.ts.map +1 -1
- package/dist/providers/Theme/types.js +10 -1
- package/dist/providers/Theme/types.js.map +1 -1
- package/dist/style-presets.d.ts +75 -0
- package/dist/style-presets.d.ts.map +1 -0
- package/dist/style-presets.js +738 -0
- package/dist/style-presets.js.map +1 -0
- package/dist/translations.d.ts +164 -1
- package/dist/translations.d.ts.map +1 -1
- package/dist/translations.js +320 -9
- package/dist/translations.js.map +1 -1
- package/dist/tweakcn-special-themes.d.ts.map +1 -1
- package/dist/tweakcn-special-themes.js +585 -9
- package/dist/tweakcn-special-themes.js.map +1 -1
- package/dist/types/css.d.js +3 -0
- package/dist/types/css.d.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/getThemeSettings.d.ts.map +1 -1
- package/dist/utilities/getThemeSettings.js +2 -14
- package/dist/utilities/getThemeSettings.js.map +1 -1
- package/dist/utils/contrast.d.ts +63 -0
- package/dist/utils/contrast.d.ts.map +1 -0
- package/dist/utils/contrast.js +158 -0
- package/dist/utils/contrast.js.map +1 -0
- package/dist/utils/exportTokens.d.ts +30 -0
- package/dist/utils/exportTokens.d.ts.map +1 -0
- package/dist/utils/exportTokens.js +183 -0
- package/dist/utils/exportTokens.js.map +1 -0
- package/dist/utils/generatePalette.d.ts +46 -0
- package/dist/utils/generatePalette.d.ts.map +1 -0
- package/dist/utils/generatePalette.js +127 -0
- package/dist/utils/generatePalette.js.map +1 -0
- package/dist/utils/generateThemeCSS.d.ts.map +1 -1
- package/dist/utils/generateThemeCSS.js +2 -40
- package/dist/utils/generateThemeCSS.js.map +1 -1
- package/dist/utils/livePreviewThemeRuntime.d.ts +22 -3
- package/dist/utils/livePreviewThemeRuntime.d.ts.map +1 -1
- package/dist/utils/livePreviewThemeRuntime.js +48 -15
- package/dist/utils/livePreviewThemeRuntime.js.map +1 -1
- package/dist/utils/localizedText.d.ts +8 -0
- package/dist/utils/localizedText.d.ts.map +1 -0
- package/dist/utils/localizedText.js +21 -0
- package/dist/utils/localizedText.js.map +1 -0
- package/dist/utils/resolveThemeConfiguration.d.ts +60 -1
- package/dist/utils/resolveThemeConfiguration.d.ts.map +1 -1
- package/dist/utils/resolveThemeConfiguration.js +53 -13
- package/dist/utils/resolveThemeConfiguration.js.map +1 -1
- package/dist/utils/themeColors.d.ts +3 -0
- package/dist/utils/themeColors.d.ts.map +1 -1
- package/dist/utils/themeColors.js +30 -1
- package/dist/utils/themeColors.js.map +1 -1
- package/dist/utils/themeHtmlAttributes.d.ts +32 -12
- package/dist/utils/themeHtmlAttributes.d.ts.map +1 -1
- package/dist/utils/themeHtmlAttributes.js +38 -5
- package/dist/utils/themeHtmlAttributes.js.map +1 -1
- package/dist/utils/themeUtils.d.ts +3 -5
- package/dist/utils/themeUtils.d.ts.map +1 -1
- package/dist/utils/themeUtils.js +474 -6
- package/dist/utils/themeUtils.js.map +1 -1
- package/dist/utils/tweakcnConverter.d.ts +1 -3
- package/dist/utils/tweakcnConverter.d.ts.map +1 -1
- package/dist/utils/tweakcnConverter.js +1 -3
- package/dist/utils/tweakcnConverter.js.map +1 -1
- package/package.json +15 -5
- package/dist/components/ThemePreview.d.ts +0 -3
- package/dist/components/ThemePreview.d.ts.map +0 -1
- package/dist/components/ThemePreview.js +0 -321
- package/dist/components/ThemePreview.js.map +0 -1
- package/dist/plugin.d.ts +0 -2
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -3
- package/dist/plugin.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/fields/AppearancePreviewField.tsx"],"sourcesContent":["'use client'\n\nimport { useFormFields } from '@payloadcms/ui'\nimport {\n ExternalLink,\n Monitor,\n Moon,\n Smartphone,\n Sparkles,\n Sun,\n Tablet,\n type LucideIcon,\n} from 'lucide-react'\nimport { useId, useMemo, useState } from 'react'\nimport {\n DEFAULT_DEVICE_PREVIEW_ID,\n DEVICE_PREVIEWS,\n getDevicePreview,\n type DevicePreviewId,\n} from '../constants/devicePreviews.js'\nimport { useThemeLanguage, useThemeTranslations } from '../hooks/useThemeTranslations.js'\nimport { resolveTypographyPreview } from '../components/typographyPreviewUtils.js'\nimport { useNativeLivePreview } from '../hooks/useNativeLivePreview.js'\nimport { useThemeFonts } from '../hooks/useThemeFonts.js'\nimport { borderRadiusPresets } from '../providers/Theme/themeConfig.js'\n\nconst DEVICE_ICONS: Record<DevicePreviewId, LucideIcon> = {\n mobile: Smartphone,\n tablet: Tablet,\n desktop: Monitor,\n}\n\n/**\n * Live, reactive preview of the Visual Effects + Component Styles + colour\n * choices. Mounted as a `ui` field inside the Appearance Settings tab so editors\n * see the combined result of every control update instantly — mirroring the CSS\n * that `generateThemeCSS` produces on the front-end.\n */\n\ntype Mode = 'light' | 'dark'\n\nconst SHADOW_MAP: Record<string, string> = {\n none: 'none',\n subtle: '0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04)',\n medium: '0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)',\n strong: '0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)',\n dramatic: '0 25px 50px -12px rgba(0,0,0,0.25)',\n}\n\nconst BLUR_PX_MAP: Record<string, string> = {\n none: '0px',\n slight: '4px',\n medium: '8px',\n strong: '16px',\n heavy: '24px',\n}\n\nconst BUTTON_SIZE_MAP: Record<string, { padding: string; fontSize: string }> = {\n small: { padding: '6px 12px', fontSize: '12px' },\n medium: { padding: '8px 16px', fontSize: '13px' },\n large: { padding: '10px 24px', fontSize: '15px' },\n xl: { padding: '14px 32px', fontSize: '17px' },\n}\n\nfunction radiusToPx(token: string | undefined): string {\n const preset = borderRadiusPresets[(token ?? 'medium') as keyof typeof borderRadiusPresets]\n const css = preset?.css as Record<string, string> | undefined\n return css?.['--radius-large'] ?? css?.['--radius-default'] ?? '0.75rem'\n}\n\ninterface Palette {\n background: string\n foreground: string\n card: string\n cardForeground: string\n primary: string\n primaryForeground: string\n secondary: string\n secondaryForeground: string\n muted: string\n mutedForeground: string\n accent: string\n accentForeground: string\n border: string\n gradientFrom: string\n gradientVia: string\n gradientTo: string\n}\n\ninterface Choices {\n effectStyle: string\n shadowIntensity: string\n backdropBlur: string\n borderStyle: string\n borderWidth: string\n glassOpacity: number\n buttonVariant: string\n buttonSize: string\n cardStyle: string\n cardHoverEffect: string\n imageStyle: string\n navbarStyle: string\n footerStyle: string\n linkStyle: string\n borderRadius: string\n /** Padding / gap multiplier from the spacing scale. */\n space: number\n}\n\nconst SPACING_SCALE: Record<string, number> = { compact: 0.75, medium: 1, comfortable: 1.5, spacious: 1.5 }\nconst px = (value: number, c: Choices) => `${Math.round(value * c.space)}px`\n\nfunction cardSurface(c: Choices, p: Palette, radius: string): React.CSSProperties {\n const base: React.CSSProperties = {\n background: p.card,\n color: p.cardForeground,\n borderRadius: radius,\n border:\n c.borderStyle === 'none' || c.borderWidth === '0px'\n ? 'none'\n : `${c.borderWidth} ${c.borderStyle} ${p.border}`,\n padding: px(16, c),\n transition: 'transform 200ms ease, box-shadow 200ms ease',\n }\n\n // Card style takes precedence for the structural look, effect style for depth.\n if (c.cardStyle === 'bordered') {\n return {\n ...base,\n border: `2px solid ${p.foreground}`,\n borderRadius: 0,\n boxShadow: `4px 4px 0 ${p.foreground}`,\n }\n }\n if (c.cardStyle === 'gradient-border') {\n return {\n ...base,\n border: '2px solid transparent',\n borderImage: `linear-gradient(135deg, ${p.gradientFrom}, ${p.gradientVia}, ${p.gradientTo}) 1`,\n boxShadow: SHADOW_MAP[c.shadowIntensity] ?? SHADOW_MAP.medium,\n }\n }\n\n switch (c.effectStyle) {\n case 'glass':\n return {\n ...base,\n background: `color-mix(in srgb, ${p.card} ${c.glassOpacity}%, transparent)`,\n backdropFilter: `blur(${BLUR_PX_MAP[c.backdropBlur] ?? '8px'}) saturate(150%)`,\n border: `1px solid color-mix(in srgb, ${p.border} 50%, transparent)`,\n boxShadow: '0 4px 24px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.15)',\n }\n case 'neumorphic':\n return {\n ...base,\n background: p.background,\n border: 'none',\n boxShadow: '6px 6px 12px rgba(0,0,0,0.12), -6px -6px 12px rgba(255,255,255,0.7)',\n }\n case 'clay':\n return {\n ...base,\n border: 'none',\n boxShadow: '4px 4px 0 rgba(0,0,0,0.22), 0 8px 20px rgba(0,0,0,0.08)',\n }\n case 'elevated':\n return { ...base, border: 'none', boxShadow: SHADOW_MAP[c.shadowIntensity] ?? SHADOW_MAP.medium }\n case 'flat':\n default:\n return { ...base, boxShadow: 'none' }\n }\n}\n\nfunction buttonStyle(c: Choices, p: Palette, radius: string): React.CSSProperties {\n const size = BUTTON_SIZE_MAP[c.buttonSize] ?? BUTTON_SIZE_MAP.medium!\n const base: React.CSSProperties = {\n ...size,\n fontWeight: 600,\n cursor: 'pointer',\n borderRadius: radius,\n border: 'none',\n transition: 'transform 120ms ease, box-shadow 120ms ease',\n whiteSpace: 'nowrap',\n }\n switch (c.buttonVariant) {\n case 'outlined':\n return { ...base, background: 'transparent', color: p.primary, border: `1.5px solid ${p.primary}` }\n case 'ghost':\n return { ...base, background: 'transparent', color: p.primary }\n case 'gradient':\n return {\n ...base,\n backgroundImage: `linear-gradient(135deg, ${p.gradientFrom}, ${p.gradientVia}, ${p.gradientTo})`,\n color: p.primaryForeground,\n }\n case 'pill':\n return { ...base, background: p.primary, color: p.primaryForeground, borderRadius: '9999px' }\n case 'brutal':\n return {\n ...base,\n background: p.card,\n color: p.foreground,\n border: `2px solid ${p.foreground}`,\n borderRadius: 0,\n boxShadow: `3px 3px 0 ${p.foreground}`,\n }\n case 'filled':\n default:\n return { ...base, background: p.primary, color: p.primaryForeground }\n }\n}\n\nfunction navbarStyle(c: Choices, p: Palette): React.CSSProperties {\n const base: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: `${px(10, c)} ${px(14, c)}`,\n background: p.background,\n color: p.foreground,\n borderBottom: `1px solid ${p.border}`,\n }\n switch (c.navbarStyle) {\n case 'transparent':\n return { ...base, background: 'transparent', borderBottom: '1px solid transparent' }\n case 'blur':\n return {\n ...base,\n background: `color-mix(in srgb, ${p.background} 70%, transparent)`,\n backdropFilter: 'blur(12px)',\n }\n case 'floating':\n return {\n ...base,\n margin: '8px',\n borderRadius: radiusToPx(c.borderRadius),\n border: `1px solid ${p.border}`,\n boxShadow: '0 4px 24px rgba(0,0,0,0.10)',\n }\n case 'minimal':\n return { ...base, borderBottom: `1px solid ${p.border}`, boxShadow: 'none' }\n case 'solid':\n default:\n return base\n }\n}\n\nfunction linkStyle(c: Choices, p: Palette): React.CSSProperties {\n switch (c.linkStyle) {\n case 'underline':\n return { color: p.primary, textDecoration: 'underline', textUnderlineOffset: '0.15em' }\n case 'none':\n return { color: p.primary, textDecoration: 'none' }\n case 'highlight':\n return {\n color: p.foreground,\n textDecoration: 'none',\n backgroundImage: `linear-gradient(transparent 60%, color-mix(in srgb, ${p.primary} 28%, transparent) 0)`,\n }\n case 'animated':\n return {\n color: p.primary,\n textDecoration: 'none',\n borderBottom: `2px solid ${p.primary}`,\n paddingBottom: '1px',\n }\n case 'underline-hover':\n default:\n return { color: p.primary, textDecoration: 'none' }\n }\n}\n\nexport default function AppearancePreviewField() {\n const formFields = useFormFields(([state]) => state) as Record<\n string,\n { value?: unknown } | undefined\n >\n const lang = useThemeLanguage() as 'en' | 'cs'\n const translations = useThemeTranslations()\n const t = translations.appearancePreview\n const site = translations.preview\n const [mode, setMode] = useState<Mode>('light')\n const [device, setDevice] = useState<DevicePreviewId>(DEFAULT_DEVICE_PREVIEW_ID)\n const uid = useId().replace(/[:]/g, '')\n const nativePreview = useNativeLivePreview()\n\n const activeDevice = getDevicePreview(device)\n\n // Fonts follow the Typography section (or the theme preset when set to \"Use theme preset\"),\n // so this single preview shows colours, type and component styles together.\n const typographyValue = (key: string) =>\n formFields?.[`themeConfiguration.typography.${key}`]?.value as string | undefined\n const typography = resolveTypographyPreview(\n {\n bodyFont: typographyValue('bodyFont'),\n headingFont: typographyValue('headingFont'),\n bodyFontCustom: typographyValue('bodyFontCustom'),\n headingFontCustom: typographyValue('headingFontCustom'),\n baseFontSize: typographyValue('baseFontSize'),\n lineHeight: typographyValue('lineHeight'),\n headingWeight: typographyValue('headingWeight'),\n letterSpacing: typographyValue('letterSpacing'),\n },\n formFields?.['themeConfiguration.theme']?.value as string | undefined,\n )\n useThemeFonts([typographyValue('bodyFont'), typographyValue('headingFont')])\n\n const str = (key: string, fallback: string): string => {\n const v = formFields?.[`themeConfiguration.${key}`]?.value\n return typeof v === 'string' && v.trim().length > 0 ? v : fallback\n }\n const num = (key: string, fallback: number): number => {\n const v = formFields?.[`themeConfiguration.${key}`]?.value\n return typeof v === 'number' ? v : fallback\n }\n\n const choices: Choices = {\n effectStyle: str('visualEffects.effectStyle', 'flat'),\n shadowIntensity: str('visualEffects.shadowIntensity', 'medium'),\n backdropBlur: str('visualEffects.backdropBlur', 'none'),\n borderStyle: str('visualEffects.borderStyle', 'solid'),\n borderWidth: str('visualEffects.borderWidth', '1px'),\n glassOpacity: num('visualEffects.glassOpacity', 60),\n buttonVariant: str('componentStyles.buttonVariant', 'filled'),\n buttonSize: str('componentStyles.buttonSize', 'medium'),\n cardStyle: str('componentStyles.cardStyle', 'elevated'),\n cardHoverEffect: str('componentStyles.cardHoverEffect', 'lift'),\n imageStyle: str('componentStyles.imageStyle', 'default'),\n navbarStyle: str('componentStyles.navbarStyle', 'solid'),\n footerStyle: str('componentStyles.footerStyle', 'standard'),\n linkStyle: str('componentStyles.linkStyle', 'underline-hover'),\n borderRadius: str('borderRadius', 'medium'),\n space: SPACING_SCALE[str('spacing', 'medium')] ?? 1,\n }\n\n const modeKey = mode === 'light' ? 'lightMode' : 'darkMode'\n const fallback: Palette =\n mode === 'light'\n ? {\n background: '#ffffff',\n foreground: '#0a0a0a',\n card: '#ffffff',\n cardForeground: '#0a0a0a',\n primary: '#9372f7',\n primaryForeground: '#fafafa',\n secondary: '#f4f4f5',\n secondaryForeground: '#18181b',\n muted: '#f4f4f5',\n mutedForeground: '#71717a',\n accent: '#f4f4f5',\n accentForeground: '#18181b',\n border: '#e4e4e7',\n gradientFrom: '#9372f7',\n gradientVia: '#7c6ff0',\n gradientTo: '#22d3ee',\n }\n : {\n background: '#0a0a0a',\n foreground: '#fafafa',\n card: '#09090b',\n cardForeground: '#fafafa',\n primary: '#9372f7',\n primaryForeground: '#09090b',\n secondary: '#27272a',\n secondaryForeground: '#fafafa',\n muted: '#27272a',\n mutedForeground: '#a1a1aa',\n accent: '#27272a',\n accentForeground: '#fafafa',\n border: '#27272a',\n gradientFrom: '#9372f7',\n gradientVia: '#7c6ff0',\n gradientTo: '#22d3ee',\n }\n\n const palette: Palette = useMemo(() => {\n const p = { ...fallback }\n ;(Object.keys(fallback) as (keyof Palette)[]).forEach((key) => {\n p[key] = str(`${modeKey}.${key}`, fallback[key])\n })\n // Same fallback as the site's --gradient-brand: primary → accent when no stops are set.\n p.gradientFrom = str(`${modeKey}.gradientFrom`, p.primary)\n p.gradientTo = str(`${modeKey}.gradientTo`, p.accent)\n p.gradientVia = str(`${modeKey}.gradientVia`, p.gradientFrom)\n return p\n }, [formFields, mode])\n\n const radius = radiusToPx(choices.borderRadius)\n const card = cardSurface(choices, palette, radius)\n const btn = buttonStyle(choices, palette, radius)\n const nav = navbarStyle(choices, palette)\n\n // Hover effects can't be expressed inline, so emit a scoped style block.\n const hoverCSS = (() => {\n const sel = `.${uid} .tm-prev-card`\n switch (choices.cardHoverEffect) {\n case 'lift':\n return `${sel}:hover{transform:translateY(-6px);box-shadow:0 20px 40px rgba(0,0,0,0.14)}`\n case 'scale':\n return `${sel}:hover{transform:scale(1.02)}`\n case 'glow':\n return `${sel}:hover{box-shadow:0 0 0 3px color-mix(in srgb, ${palette.primary} 25%, transparent),0 8px 32px rgba(0,0,0,0.12)}`\n case 'shadow':\n return `${sel}:hover{box-shadow:0 24px 50px -12px rgba(0,0,0,0.35)}`\n case 'tilt':\n return `${sel}:hover{transform:perspective(800px) rotateX(3deg) rotateY(-3deg)}`\n default:\n return ''\n }\n })()\n const btnHoverCSS = `.${uid} .tm-prev-btn:hover{filter:brightness(1.05)}${\n choices.buttonVariant === 'brutal'\n ? `.${uid} .tm-prev-btn:hover{transform:translate(-2px,-2px);box-shadow:5px 5px 0 ${palette.foreground}}`\n : ''\n }`\n // Movement-based hover effects only run for users who haven't asked for reduced motion.\n const previewCSS = `@media (prefers-reduced-motion: no-preference){${hoverCSS}${btnHoverCSS}}`\n\n // Content image treatment, mirroring the site's [data-img] rules.\n const imageCss: React.CSSProperties = (() => {\n const base: React.CSSProperties = {\n aspectRatio: '4 / 3',\n borderRadius: 0,\n backgroundImage: `radial-gradient(circle at 70% 30%, ${palette.accent} 0 18%, transparent 19%), linear-gradient(160deg, ${palette.gradientFrom}, ${palette.gradientTo})`,\n }\n switch (choices.imageStyle) {\n case 'rounded':\n return { ...base, borderRadius: radius }\n case 'circle':\n return { ...base, aspectRatio: '1 / 1', borderRadius: '9999px' }\n case 'grayscale':\n return { ...base, filter: 'grayscale(1)' }\n case 'duotone':\n return { ...base, filter: 'grayscale(1) contrast(1.05)', mixBlendMode: 'luminosity' }\n case 'vignette':\n return { ...base, boxShadow: 'inset 0 0 40px rgba(0,0,0,0.45)' }\n case 'polaroid':\n return {\n ...base,\n border: '8px solid #fff',\n borderBottomWidth: '24px',\n boxShadow: '0 6px 16px rgba(0,0,0,0.18)',\n borderRadius: '2px',\n }\n default:\n return base\n }\n })()\n\n const headingStyle: React.CSSProperties = {\n fontFamily: typography.headingFont,\n fontWeight: Number(typography.headingWeight) || 700,\n letterSpacing: typography.headingLetterSpacing,\n textTransform: typography.headingTransform,\n lineHeight: 1.15,\n margin: 0,\n }\n\n const footerStyleCss: React.CSSProperties =\n choices.footerStyle === 'dark'\n ? { background: palette.foreground, color: palette.background }\n : choices.footerStyle === 'full-color'\n ? { background: palette.primary, color: palette.primaryForeground }\n : choices.footerStyle === 'gradient-top'\n ? {\n background: palette.background,\n color: palette.mutedForeground,\n borderTop: '3px solid transparent',\n borderImage: `linear-gradient(135deg, ${palette.gradientFrom}, ${palette.gradientVia}, ${palette.gradientTo}) 1`,\n }\n : choices.footerStyle === 'minimal'\n ? { background: 'transparent', color: palette.mutedForeground, borderTop: `1px solid ${palette.border}` }\n : { background: palette.muted, color: palette.mutedForeground, borderTop: `1px solid ${palette.border}` }\n\n // With Payload's native Live Preview the real site is the preview: no mock.\n if (nativePreview.isEnabled) {\n if (nativePreview.isOpen) return null\n return (\n <div className=\"tm-native-preview-hint\">\n <div className=\"tm-native-preview-hint__text\">\n <span className=\"tm-native-preview-hint__title\">\n <Sparkles size={14} aria-hidden />\n {t.nativeTitle}\n </span>\n <span className=\"tm-native-preview-hint__body\">{t.nativeBody}</span>\n </div>\n <button type=\"button\" className=\"tm-native-preview-hint__action\" onClick={nativePreview.open}>\n <ExternalLink size={14} aria-hidden />\n {t.nativeOpen}\n </button>\n </div>\n )\n }\n\n return (\n // The slot spans the whole right column of the Appearance tab on wide admins;\n // its inner panel is sticky so the preview stays in view while editing.\n <div className={`tm-live-preview-slot ${uid}`}>\n <div className=\"tm-live-preview\">\n <style dangerouslySetInnerHTML={{ __html: previewCSS }} />\n\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '8px',\n gap: '8px',\n flexWrap: 'wrap',\n }}\n >\n <div>\n <div\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '6px',\n fontSize: '13px',\n fontWeight: 600,\n color: 'var(--theme-elevation-800)',\n }}\n >\n <Sparkles size={14} aria-hidden />\n {t.title}\n </div>\n <div style={{ fontSize: '12px', color: 'var(--theme-elevation-600)' }}>{t.subtitle}</div>\n </div>\n <div style={{ display: 'inline-flex', gap: '8px', flexWrap: 'wrap' }}>\n {/* Device / viewport switcher */}\n <div\n role=\"group\"\n aria-label={t.viewport}\n style={{ display: 'inline-flex', borderRadius: '8px', overflow: 'hidden', border: '1px solid var(--theme-elevation-200)' }}\n >\n {DEVICE_PREVIEWS.map((d) => {\n const Icon = DEVICE_ICONS[d.id]\n return (\n <button\n key={d.id}\n type=\"button\"\n aria-pressed={device === d.id}\n onClick={() => setDevice(d.id)}\n title={`${lang === 'cs' ? d.labelCs : d.label} — ${d.width}×${d.height}`}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '5px',\n minHeight: '28px',\n padding: '5px 10px',\n fontSize: '12px',\n fontWeight: 600,\n cursor: 'pointer',\n border: 'none',\n background: device === d.id ? 'var(--theme-elevation-800)' : 'transparent',\n color: device === d.id ? 'var(--theme-elevation-0)' : 'var(--theme-elevation-600)',\n }}\n >\n <Icon size={13} aria-hidden />\n {lang === 'cs' ? d.labelCs : d.label}\n </button>\n )\n })}\n </div>\n {/* Light / dark switcher */}\n <div\n role=\"group\"\n aria-label={`${t.light} / ${t.dark}`}\n style={{ display: 'inline-flex', borderRadius: '8px', overflow: 'hidden', border: '1px solid var(--theme-elevation-200)' }}\n >\n {(['light', 'dark'] as Mode[]).map((m) => {\n const Icon = m === 'light' ? Sun : Moon\n return (\n <button\n key={m}\n type=\"button\"\n aria-pressed={mode === m}\n onClick={() => setMode(m)}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '5px',\n minHeight: '28px',\n padding: '5px 12px',\n fontSize: '12px',\n fontWeight: 600,\n cursor: 'pointer',\n border: 'none',\n background: mode === m ? 'var(--theme-elevation-800)' : 'transparent',\n color: mode === m ? 'var(--theme-elevation-0)' : 'var(--theme-elevation-600)',\n }}\n >\n <Icon size={13} aria-hidden />\n {m === 'light' ? t.light : t.dark}\n </button>\n )\n })}\n </div>\n </div>\n </div>\n\n {/* Viewport wrapper — constrains the frame to the active device width */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n background: 'var(--theme-elevation-50)',\n borderRadius: '14px',\n padding: device === 'desktop' ? '0' : '16px',\n }}\n >\n {/* Browser-like frame. It is a picture of the site, so it is inert: its\n sample buttons and links must not become dead tab stops. */}\n <div\n ref={(el) => el?.setAttribute('inert', '')}\n style={{\n width: '100%',\n maxWidth: device === 'desktop' ? '100%' : `${activeDevice.width}px`,\n borderRadius: '14px',\n overflow: 'hidden',\n border: '1px solid var(--theme-elevation-200)',\n boxShadow: '0 8px 24px rgba(0,0,0,0.10)',\n background: palette.background,\n color: palette.foreground,\n fontFamily: typography.bodyFont,\n lineHeight: typography.lineHeight,\n }}\n >\n <nav style={nav}>\n <span style={{ fontWeight: 700, fontSize: '13px' }}>{site.siteTitle}</span>\n <span style={{ display: 'flex', gap: '14px', fontSize: '12px', opacity: 0.85 }}>\n <span>{site.nav.home}</span>\n <span>{site.nav.about}</span>\n <span style={{ ...linkStyle(choices, palette) }}>{site.nav.services}</span>\n </span>\n </nav>\n\n <div style={{ padding: px(20, choices), display: 'grid', gap: px(14, choices) }}>\n <div>\n <div style={{ ...headingStyle, fontSize: '24px' }}>{t.heading}</div>\n <p\n style={{\n margin: `${px(6, choices)} 0 0`,\n fontSize: `calc(${typography.baseFontSize} * 0.8125)`,\n lineHeight: typography.lineHeight,\n color: palette.mutedForeground,\n maxWidth: '60ch',\n }}\n >\n {t.body}\n <a style={linkStyle(choices, palette)}>{t.link}</a>.\n </p>\n </div>\n\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: device === 'mobile' ? '1fr' : 'minmax(0, 3fr) minmax(0, 2fr)',\n gap: px(12, choices),\n alignItems: 'start',\n }}\n >\n <div className=\"tm-prev-card\" style={card}>\n <div style={{ ...headingStyle, fontSize: '15px', marginBottom: px(6, choices) }}>\n {t.cardTitle}\n </div>\n <p\n style={{\n margin: `0 0 ${px(12, choices)}`,\n fontSize: `calc(${typography.baseFontSize} * 0.75)`,\n lineHeight: typography.lineHeight,\n color: palette.cardForeground,\n opacity: 0.8,\n }}\n >\n {t.cardBody}\n </p>\n <div style={{ display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap' }}>\n <button type=\"button\" className=\"tm-prev-btn\" style={btn}>\n {t.primary}\n </button>\n <button\n type=\"button\"\n style={{\n ...(BUTTON_SIZE_MAP[choices.buttonSize] ?? BUTTON_SIZE_MAP.medium),\n fontWeight: 600,\n cursor: 'pointer',\n borderRadius: choices.buttonVariant === 'pill' ? '9999px' : radius,\n background: palette.secondary,\n color: palette.secondaryForeground,\n border: 'none',\n }}\n >\n {t.secondary}\n </button>\n </div>\n </div>\n <div aria-hidden style={imageCss} />\n </div>\n </div>\n\n <div style={{ padding: `${px(12, choices)} ${px(16, choices)}`, fontSize: '11px', ...footerStyleCss }}>\n © {new Date().getFullYear()} {site.siteTitle} — {t.footer}\n </div>\n </div>\n </div>\n\n </div>\n </div>\n )\n}\n"],"names":["useFormFields","ExternalLink","Monitor","Moon","Smartphone","Sparkles","Sun","Tablet","useId","useMemo","useState","DEFAULT_DEVICE_PREVIEW_ID","DEVICE_PREVIEWS","getDevicePreview","useThemeLanguage","useThemeTranslations","resolveTypographyPreview","useNativeLivePreview","useThemeFonts","borderRadiusPresets","DEVICE_ICONS","mobile","tablet","desktop","SHADOW_MAP","none","subtle","medium","strong","dramatic","BLUR_PX_MAP","slight","heavy","BUTTON_SIZE_MAP","small","padding","fontSize","large","xl","radiusToPx","token","preset","css","SPACING_SCALE","compact","comfortable","spacious","px","value","c","Math","round","space","cardSurface","p","radius","base","background","card","color","cardForeground","borderRadius","border","borderStyle","borderWidth","transition","cardStyle","foreground","boxShadow","borderImage","gradientFrom","gradientVia","gradientTo","shadowIntensity","effectStyle","glassOpacity","backdropFilter","backdropBlur","buttonStyle","size","buttonSize","fontWeight","cursor","whiteSpace","buttonVariant","primary","backgroundImage","primaryForeground","navbarStyle","display","alignItems","justifyContent","borderBottom","margin","linkStyle","textDecoration","textUnderlineOffset","paddingBottom","AppearancePreviewField","formFields","state","lang","translations","t","appearancePreview","site","preview","mode","setMode","device","setDevice","uid","replace","nativePreview","activeDevice","typographyValue","key","typography","bodyFont","headingFont","bodyFontCustom","headingFontCustom","baseFontSize","lineHeight","headingWeight","letterSpacing","str","fallback","v","trim","length","num","choices","cardHoverEffect","imageStyle","footerStyle","modeKey","secondary","secondaryForeground","muted","mutedForeground","accent","accentForeground","palette","Object","keys","forEach","btn","nav","hoverCSS","sel","btnHoverCSS","previewCSS","imageCss","aspectRatio","filter","mixBlendMode","borderBottomWidth","headingStyle","fontFamily","Number","headingLetterSpacing","textTransform","headingTransform","footerStyleCss","borderTop","isEnabled","isOpen","div","className","span","aria-hidden","nativeTitle","nativeBody","button","type","onClick","open","nativeOpen","style","dangerouslySetInnerHTML","__html","marginBottom","gap","flexWrap","title","subtitle","role","aria-label","viewport","overflow","map","d","Icon","id","aria-pressed","labelCs","label","width","height","minHeight","light","dark","m","ref","el","setAttribute","maxWidth","siteTitle","opacity","home","about","services","heading","body","a","link","gridTemplateColumns","cardTitle","cardBody","Date","getFullYear","footer"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPickerField.d.ts","sourceRoot":"","sources":["../../src/fields/ColorPickerField.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ColorPickerField.d.ts","sourceRoot":"","sources":["../../src/fields/ColorPickerField.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAanD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,+BA8RnE"}
|
|
@@ -1,9 +1,12 @@
|
|
|
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 {
|
|
4
|
+
import { Palette } from 'lucide-react';
|
|
5
|
+
import { useCallback, useEffect, useId, useRef, useState } from 'react';
|
|
6
|
+
import { useThemeLanguage, useThemeTranslations } from '../hooks/useThemeTranslations.js';
|
|
7
|
+
import { resolveLocalizedText } from '../utils/localizedText.js';
|
|
5
8
|
const colorPresets = {
|
|
6
|
-
|
|
9
|
+
themeColors: [
|
|
7
10
|
'#3b82f6',
|
|
8
11
|
'#1e40af',
|
|
9
12
|
'#b45309',
|
|
@@ -11,7 +14,7 @@ const colorPresets = {
|
|
|
11
14
|
'#8b5cf6',
|
|
12
15
|
'#f97316'
|
|
13
16
|
],
|
|
14
|
-
|
|
17
|
+
commonColors: [
|
|
15
18
|
'#ef4444',
|
|
16
19
|
'#10b981',
|
|
17
20
|
'#f59e0b',
|
|
@@ -19,7 +22,7 @@ const colorPresets = {
|
|
|
19
22
|
'#ec4899',
|
|
20
23
|
'#6b7280'
|
|
21
24
|
],
|
|
22
|
-
|
|
25
|
+
neutralTones: [
|
|
23
26
|
'#000000',
|
|
24
27
|
'#1f2937',
|
|
25
28
|
'#6b7280',
|
|
@@ -28,17 +31,6 @@ const colorPresets = {
|
|
|
28
31
|
'#ffffff'
|
|
29
32
|
]
|
|
30
33
|
};
|
|
31
|
-
function resolveLocalizedValue(value) {
|
|
32
|
-
if (typeof value === 'string') {
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
if (typeof value === 'object' && value !== null) {
|
|
36
|
-
const localized = value;
|
|
37
|
-
const fallback = localized.en ?? localized.cs ?? localized[''];
|
|
38
|
-
return typeof fallback === 'string' ? fallback : '';
|
|
39
|
-
}
|
|
40
|
-
return '';
|
|
41
|
-
}
|
|
42
34
|
export default function ColorPickerField(props) {
|
|
43
35
|
const { field, path } = props;
|
|
44
36
|
const { value = '#000000', setValue } = useField({
|
|
@@ -46,9 +38,15 @@ export default function ColorPickerField(props) {
|
|
|
46
38
|
});
|
|
47
39
|
const [isPickerOpen, setIsPickerOpen] = useState(false);
|
|
48
40
|
const pickerRef = useRef(null);
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
41
|
+
const toggleRef = useRef(null);
|
|
42
|
+
const t = useThemeTranslations().colorPicker;
|
|
43
|
+
const language = useThemeLanguage();
|
|
44
|
+
const inputId = useId();
|
|
45
|
+
const descriptionId = useId();
|
|
46
|
+
const popoverId = useId();
|
|
47
|
+
const fieldLabel = resolveLocalizedText(field.label, language);
|
|
48
|
+
const fieldDescription = resolveLocalizedText(field.admin?.description, language);
|
|
49
|
+
const placeholder = resolveLocalizedText(field.admin?.placeholder, language) || t.placeholder;
|
|
52
50
|
const handleColorChange = useCallback((color)=>{
|
|
53
51
|
setValue(color);
|
|
54
52
|
}, [
|
|
@@ -66,17 +64,24 @@ export default function ColorPickerField(props) {
|
|
|
66
64
|
if (!isPickerOpen) {
|
|
67
65
|
return;
|
|
68
66
|
}
|
|
69
|
-
function
|
|
70
|
-
|
|
67
|
+
function handlePointerOutside(event) {
|
|
68
|
+
const target = event.target;
|
|
69
|
+
if (pickerRef.current?.contains(target) || toggleRef.current?.contains(target)) {
|
|
71
70
|
return;
|
|
72
71
|
}
|
|
73
|
-
|
|
72
|
+
setIsPickerOpen(false);
|
|
73
|
+
}
|
|
74
|
+
function handleKeyDown(event) {
|
|
75
|
+
if (event.key === 'Escape') {
|
|
74
76
|
setIsPickerOpen(false);
|
|
77
|
+
toggleRef.current?.focus();
|
|
75
78
|
}
|
|
76
79
|
}
|
|
77
|
-
document.addEventListener('
|
|
80
|
+
document.addEventListener('pointerdown', handlePointerOutside);
|
|
81
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
78
82
|
return ()=>{
|
|
79
|
-
document.removeEventListener('
|
|
83
|
+
document.removeEventListener('pointerdown', handlePointerOutside);
|
|
84
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
80
85
|
};
|
|
81
86
|
}, [
|
|
82
87
|
isPickerOpen
|
|
@@ -88,7 +93,7 @@ export default function ColorPickerField(props) {
|
|
|
88
93
|
},
|
|
89
94
|
children: [
|
|
90
95
|
fieldLabel && /*#__PURE__*/ _jsxs("label", {
|
|
91
|
-
htmlFor:
|
|
96
|
+
htmlFor: inputId,
|
|
92
97
|
className: "field-label",
|
|
93
98
|
style: {
|
|
94
99
|
display: 'block',
|
|
@@ -109,11 +114,12 @@ export default function ColorPickerField(props) {
|
|
|
109
114
|
]
|
|
110
115
|
}),
|
|
111
116
|
fieldDescription && /*#__PURE__*/ _jsx("div", {
|
|
117
|
+
id: descriptionId,
|
|
112
118
|
className: "field-description",
|
|
113
119
|
style: {
|
|
114
120
|
marginBottom: '8px',
|
|
115
121
|
fontSize: '13px',
|
|
116
|
-
color: 'var(--theme-elevation-
|
|
122
|
+
color: 'var(--theme-elevation-600)',
|
|
117
123
|
lineHeight: 1.5
|
|
118
124
|
},
|
|
119
125
|
children: fieldDescription
|
|
@@ -127,44 +133,49 @@ export default function ColorPickerField(props) {
|
|
|
127
133
|
},
|
|
128
134
|
children: [
|
|
129
135
|
/*#__PURE__*/ _jsx("button", {
|
|
136
|
+
ref: toggleRef,
|
|
130
137
|
type: "button",
|
|
131
138
|
onClick: togglePicker,
|
|
132
139
|
className: "color-preview-button",
|
|
140
|
+
"aria-expanded": isPickerOpen,
|
|
141
|
+
"aria-controls": isPickerOpen ? popoverId : undefined,
|
|
142
|
+
"aria-label": `${t.presetsTitle}${fieldLabel ? `: ${fieldLabel}` : ''}`,
|
|
133
143
|
style: {
|
|
134
144
|
width: '40px',
|
|
135
145
|
height: '40px',
|
|
136
146
|
borderRadius: '6px',
|
|
137
|
-
border: '2px solid
|
|
138
|
-
backgroundColor: value || '
|
|
147
|
+
border: '2px solid var(--theme-elevation-200)',
|
|
148
|
+
backgroundColor: value || 'var(--theme-elevation-0)',
|
|
139
149
|
cursor: 'pointer',
|
|
140
150
|
position: 'relative',
|
|
141
151
|
display: 'flex',
|
|
142
152
|
alignItems: 'center',
|
|
143
153
|
justifyContent: 'center'
|
|
144
154
|
},
|
|
145
|
-
title: value ?
|
|
146
|
-
children: !value && /*#__PURE__*/ _jsx(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
},
|
|
151
|
-
children: "?"
|
|
155
|
+
title: value ? `${t.currentColor}: ${value}` : t.presetsTitle,
|
|
156
|
+
children: !value && /*#__PURE__*/ _jsx(Palette, {
|
|
157
|
+
size: 18,
|
|
158
|
+
color: "var(--theme-elevation-500)",
|
|
159
|
+
"aria-hidden": true
|
|
152
160
|
})
|
|
153
161
|
}),
|
|
154
162
|
/*#__PURE__*/ _jsx("input", {
|
|
155
|
-
id:
|
|
163
|
+
id: inputId,
|
|
156
164
|
type: "text",
|
|
157
165
|
value: value || '',
|
|
158
166
|
onChange: handleInputChange,
|
|
159
167
|
placeholder: placeholder,
|
|
168
|
+
"aria-describedby": fieldDescription ? descriptionId : undefined,
|
|
169
|
+
spellCheck: false,
|
|
160
170
|
style: {
|
|
161
171
|
flex: 1,
|
|
172
|
+
minWidth: 0,
|
|
162
173
|
padding: '8px 12px',
|
|
163
174
|
border: '1px solid var(--theme-elevation-150)',
|
|
164
175
|
borderRadius: '6px',
|
|
165
176
|
fontSize: '14px',
|
|
166
177
|
fontFamily: 'monospace',
|
|
167
|
-
backgroundColor: 'var(--theme-elevation-0)',
|
|
178
|
+
backgroundColor: 'var(--theme-input-bg, var(--theme-elevation-0))',
|
|
168
179
|
color: 'var(--theme-elevation-1000)'
|
|
169
180
|
}
|
|
170
181
|
}),
|
|
@@ -172,7 +183,8 @@ export default function ColorPickerField(props) {
|
|
|
172
183
|
type: "color",
|
|
173
184
|
value: value?.startsWith('#') ? value : '#3b82f6',
|
|
174
185
|
onChange: handleInputChange,
|
|
175
|
-
title:
|
|
186
|
+
title: t.customColor,
|
|
187
|
+
"aria-label": t.customColor,
|
|
176
188
|
style: {
|
|
177
189
|
width: '40px',
|
|
178
190
|
height: '40px',
|
|
@@ -185,6 +197,9 @@ export default function ColorPickerField(props) {
|
|
|
185
197
|
}),
|
|
186
198
|
isPickerOpen && /*#__PURE__*/ _jsxs("div", {
|
|
187
199
|
ref: pickerRef,
|
|
200
|
+
id: popoverId,
|
|
201
|
+
role: "dialog",
|
|
202
|
+
"aria-label": t.presetsTitle,
|
|
188
203
|
className: "color-presets",
|
|
189
204
|
style: {
|
|
190
205
|
position: 'absolute',
|
|
@@ -202,16 +217,27 @@ export default function ColorPickerField(props) {
|
|
|
202
217
|
overflowY: 'auto'
|
|
203
218
|
},
|
|
204
219
|
children: [
|
|
205
|
-
/*#__PURE__*/
|
|
220
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
206
221
|
style: {
|
|
222
|
+
display: 'flex',
|
|
223
|
+
alignItems: 'center',
|
|
224
|
+
gap: '6px',
|
|
207
225
|
marginBottom: '16px',
|
|
208
226
|
fontSize: '14px',
|
|
209
227
|
fontWeight: 600,
|
|
210
228
|
color: 'var(--theme-elevation-800)'
|
|
211
229
|
},
|
|
212
|
-
children:
|
|
230
|
+
children: [
|
|
231
|
+
/*#__PURE__*/ _jsx(Palette, {
|
|
232
|
+
size: 14,
|
|
233
|
+
"aria-hidden": true
|
|
234
|
+
}),
|
|
235
|
+
t.presetsTitle
|
|
236
|
+
]
|
|
213
237
|
}),
|
|
214
|
-
Object.
|
|
238
|
+
Object.keys(colorPresets).map((group)=>/*#__PURE__*/ _jsxs("div", {
|
|
239
|
+
role: "group",
|
|
240
|
+
"aria-label": t[group],
|
|
215
241
|
style: {
|
|
216
242
|
marginBottom: '16px'
|
|
217
243
|
},
|
|
@@ -220,12 +246,10 @@ export default function ColorPickerField(props) {
|
|
|
220
246
|
style: {
|
|
221
247
|
marginBottom: '8px',
|
|
222
248
|
fontSize: '12px',
|
|
223
|
-
fontWeight:
|
|
224
|
-
color: 'var(--theme-elevation-600)'
|
|
225
|
-
textTransform: 'uppercase',
|
|
226
|
-
letterSpacing: '0.05em'
|
|
249
|
+
fontWeight: 600,
|
|
250
|
+
color: 'var(--theme-elevation-600)'
|
|
227
251
|
},
|
|
228
|
-
children:
|
|
252
|
+
children: t[group]
|
|
229
253
|
}),
|
|
230
254
|
/*#__PURE__*/ _jsx("div", {
|
|
231
255
|
style: {
|
|
@@ -233,40 +257,28 @@ export default function ColorPickerField(props) {
|
|
|
233
257
|
gridTemplateColumns: 'repeat(6, 1fr)',
|
|
234
258
|
gap: '6px'
|
|
235
259
|
},
|
|
236
|
-
children:
|
|
260
|
+
children: colorPresets[group].map((color)=>{
|
|
261
|
+
const selected = value === color;
|
|
262
|
+
return /*#__PURE__*/ _jsx("button", {
|
|
237
263
|
type: "button",
|
|
238
264
|
onClick: ()=>handleColorChange(color),
|
|
265
|
+
"aria-pressed": selected,
|
|
266
|
+
"aria-label": `${t.selectColor} ${color}`,
|
|
267
|
+
title: color,
|
|
239
268
|
style: {
|
|
240
269
|
width: '36px',
|
|
241
270
|
height: '36px',
|
|
242
271
|
borderRadius: '6px',
|
|
243
|
-
border:
|
|
272
|
+
border: selected ? '3px solid var(--theme-elevation-900)' : '1px solid var(--theme-elevation-200)',
|
|
244
273
|
backgroundColor: color,
|
|
245
274
|
cursor: 'pointer',
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
},
|
|
251
|
-
title: `${color} - Click to select`,
|
|
252
|
-
onMouseEnter: (event)=>{
|
|
253
|
-
event.currentTarget.style.transform = 'scale(1.1)';
|
|
254
|
-
},
|
|
255
|
-
onMouseLeave: (event)=>{
|
|
256
|
-
event.currentTarget.style.transform = 'scale(1)';
|
|
257
|
-
},
|
|
258
|
-
children: color === '#ffffff' && /*#__PURE__*/ _jsx("div", {
|
|
259
|
-
style: {
|
|
260
|
-
position: 'absolute',
|
|
261
|
-
inset: 0,
|
|
262
|
-
border: '1px solid var(--theme-elevation-150)',
|
|
263
|
-
borderRadius: 'inherit'
|
|
264
|
-
}
|
|
265
|
-
})
|
|
266
|
-
}, color))
|
|
275
|
+
boxShadow: selected ? '0 0 0 2px var(--theme-elevation-0)' : '0 1px 3px rgba(0, 0, 0, 0.1)'
|
|
276
|
+
}
|
|
277
|
+
}, color);
|
|
278
|
+
})
|
|
267
279
|
})
|
|
268
280
|
]
|
|
269
|
-
},
|
|
281
|
+
}, group)),
|
|
270
282
|
/*#__PURE__*/ _jsxs("div", {
|
|
271
283
|
style: {
|
|
272
284
|
marginTop: '16px',
|
|
@@ -278,10 +290,10 @@ export default function ColorPickerField(props) {
|
|
|
278
290
|
style: {
|
|
279
291
|
marginBottom: '8px',
|
|
280
292
|
fontSize: '12px',
|
|
281
|
-
fontWeight:
|
|
293
|
+
fontWeight: 600,
|
|
282
294
|
color: 'var(--theme-elevation-600)'
|
|
283
295
|
},
|
|
284
|
-
children:
|
|
296
|
+
children: t.customColor
|
|
285
297
|
}),
|
|
286
298
|
/*#__PURE__*/ _jsxs("div", {
|
|
287
299
|
style: {
|
|
@@ -294,6 +306,7 @@ export default function ColorPickerField(props) {
|
|
|
294
306
|
type: "color",
|
|
295
307
|
value: value?.startsWith('#') ? value : '#3b82f6',
|
|
296
308
|
onChange: handleInputChange,
|
|
309
|
+
"aria-label": t.customColor,
|
|
297
310
|
style: {
|
|
298
311
|
width: '36px',
|
|
299
312
|
height: '36px',
|
|
@@ -302,22 +315,13 @@ export default function ColorPickerField(props) {
|
|
|
302
315
|
cursor: 'pointer'
|
|
303
316
|
}
|
|
304
317
|
}),
|
|
305
|
-
/*#__PURE__*/
|
|
318
|
+
/*#__PURE__*/ _jsx("div", {
|
|
306
319
|
style: {
|
|
307
|
-
fontSize: '
|
|
308
|
-
color: '
|
|
309
|
-
lineHeight: 1.
|
|
320
|
+
fontSize: '12px',
|
|
321
|
+
color: 'var(--theme-elevation-600)',
|
|
322
|
+
lineHeight: 1.4
|
|
310
323
|
},
|
|
311
|
-
children:
|
|
312
|
-
/*#__PURE__*/ _jsx("div", {
|
|
313
|
-
children: /*#__PURE__*/ _jsx("strong", {
|
|
314
|
-
children: "Formats:"
|
|
315
|
-
})
|
|
316
|
-
}),
|
|
317
|
-
/*#__PURE__*/ _jsx("div", {
|
|
318
|
-
children: "Hex, RGB, HSL, CSS vars"
|
|
319
|
-
})
|
|
320
|
-
]
|
|
324
|
+
children: t.formats
|
|
321
325
|
})
|
|
322
326
|
]
|
|
323
327
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/ColorPickerField.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport type { TextFieldClientProps } from 'payload'\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nconst colorPresets: Record<string, string[]> = {\n 'Theme Colors': ['#3b82f6', '#1e40af', '#b45309', '#78716c', '#8b5cf6', '#f97316'],\n 'Common Colors': ['#ef4444', '#10b981', '#f59e0b', '#06b6d4', '#ec4899', '#6b7280'],\n 'Neutral Tones': ['#000000', '#1f2937', '#6b7280', '#d1d5db', '#f3f4f6', '#ffffff'],\n}\n\nfunction resolveLocalizedValue(value: unknown): string {\n if (typeof value === 'string') {\n return value\n }\n\n if (typeof value === 'object' && value !== null) {\n const localized = value as Record<string, unknown>\n const fallback = localized.en ?? localized.cs ?? localized['']\n return typeof fallback === 'string' ? fallback : ''\n }\n\n return ''\n}\n\nexport default function ColorPickerField(props: TextFieldClientProps) {\n const { field, path } = props\n const { value = '#000000', setValue } = useField<string>({ path })\n const [isPickerOpen, setIsPickerOpen] = useState(false)\n const pickerRef = useRef<HTMLDivElement>(null)\n\n const fieldLabel = resolveLocalizedValue(field.label)\n const fieldDescription = resolveLocalizedValue(field.admin?.description)\n const placeholder = resolveLocalizedValue(field.admin?.placeholder) || 'e.g., #3b82f6, hsl(...)'\n\n const handleColorChange = useCallback(\n (color: string) => {\n setValue(color)\n },\n [setValue],\n )\n\n const handleInputChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n handleColorChange(event.target.value)\n },\n [handleColorChange],\n )\n\n const togglePicker = useCallback(() => {\n setIsPickerOpen((previous) => !previous)\n }, [])\n\n useEffect(() => {\n if (!isPickerOpen) {\n return\n }\n\n function handleClickOutside(event: MouseEvent) {\n if (!pickerRef.current) {\n return\n }\n\n if (!pickerRef.current.contains(event.target as Node)) {\n setIsPickerOpen(false)\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside)\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isPickerOpen])\n\n return (\n <div className=\"field-type color-picker-field\" style={{ position: 'relative' }}>\n {fieldLabel && (\n <label\n htmlFor={path}\n className=\"field-label\"\n style={{ display: 'block', marginBottom: '8px', fontSize: '13px', fontWeight: 600 }}\n >\n {fieldLabel}\n {field.required && (\n <span\n className=\"required\"\n style={{ color: 'var(--theme-error-500)', marginLeft: '4px' }}\n >\n *\n </span>\n )}\n </label>\n )}\n\n {fieldDescription && (\n <div\n className=\"field-description\"\n style={{\n marginBottom: '8px',\n fontSize: '13px',\n color: 'var(--theme-elevation-500)',\n lineHeight: 1.5,\n }}\n >\n {fieldDescription}\n </div>\n )}\n\n <div\n className=\"color-picker-input-group\"\n style={{ display: 'flex', alignItems: 'center', gap: '8px' }}\n >\n <button\n type=\"button\"\n onClick={togglePicker}\n className=\"color-preview-button\"\n style={{\n width: '40px',\n height: '40px',\n borderRadius: '6px',\n border: '2px solid #e5e7eb',\n backgroundColor: value || '#ffffff',\n cursor: 'pointer',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n title={value ? `Current color: ${value}` : 'Select a color'}\n >\n {!value && <span style={{ fontSize: '20px', color: '#9ca3af' }}>?</span>}\n </button>\n\n <input\n id={path}\n type=\"text\"\n value={value || ''}\n onChange={handleInputChange}\n placeholder={placeholder}\n style={{\n flex: 1,\n padding: '8px 12px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '6px',\n fontSize: '14px',\n fontFamily: 'monospace',\n backgroundColor: 'var(--theme-elevation-0)',\n color: 'var(--theme-elevation-1000)',\n }}\n />\n\n <input\n type=\"color\"\n value={value?.startsWith('#') ? value : '#3b82f6'}\n onChange={handleInputChange}\n title=\"Pick a color\"\n style={{\n width: '40px',\n height: '40px',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n }}\n />\n </div>\n\n {isPickerOpen && (\n <div\n ref={pickerRef}\n className=\"color-presets\"\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n right: 0,\n zIndex: 1000,\n marginTop: '4px',\n padding: '16px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '8px',\n backgroundColor: 'var(--theme-elevation-0)',\n boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n maxHeight: '300px',\n overflowY: 'auto',\n }}\n >\n <div\n style={{\n marginBottom: '16px',\n fontSize: '14px',\n fontWeight: 600,\n color: 'var(--theme-elevation-800)',\n }}\n >\n 🎨 Professional Color Picker\n </div>\n\n {Object.entries(colorPresets).map(([groupName, colors]) => (\n <div key={groupName} style={{ marginBottom: '16px' }}>\n <div\n style={{\n marginBottom: '8px',\n fontSize: '12px',\n fontWeight: 500,\n color: 'var(--theme-elevation-600)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n {groupName}\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: '6px' }}>\n {colors.map((color) => (\n <button\n key={color}\n type=\"button\"\n onClick={() => handleColorChange(color)}\n style={{\n width: '36px',\n height: '36px',\n borderRadius: '6px',\n border:\n value === color\n ? '3px solid var(--theme-success-500)'\n : '1px solid var(--theme-elevation-150)',\n backgroundColor: color,\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n position: 'relative',\n overflow: 'hidden',\n boxShadow:\n value === color\n ? '0 0 0 2px var(--theme-primary-200)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)',\n }}\n title={`${color} - Click to select`}\n onMouseEnter={(event) => {\n event.currentTarget.style.transform = 'scale(1.1)'\n }}\n onMouseLeave={(event) => {\n event.currentTarget.style.transform = 'scale(1)'\n }}\n >\n {color === '#ffffff' && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'inherit',\n }}\n />\n )}\n </button>\n ))}\n </div>\n </div>\n ))}\n\n <div\n style={{\n marginTop: '16px',\n paddingTop: '16px',\n borderTop: '1px solid var(--theme-elevation-100)',\n }}\n >\n <div\n style={{\n marginBottom: '8px',\n fontSize: '12px',\n fontWeight: 500,\n color: 'var(--theme-elevation-600)',\n }}\n >\n CUSTOM COLOR\n </div>\n <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <input\n type=\"color\"\n value={value?.startsWith('#') ? value : '#3b82f6'}\n onChange={handleInputChange}\n style={{\n width: '36px',\n height: '36px',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n }}\n />\n <div style={{ fontSize: '11px', color: '#9ca3af', lineHeight: 1.3 }}>\n <div>\n <strong>Formats:</strong>\n </div>\n <div>Hex, RGB, HSL, CSS vars</div>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n"],"names":["useField","useCallback","useEffect","useRef","useState","colorPresets","resolveLocalizedValue","value","localized","fallback","en","cs","ColorPickerField","props","field","path","setValue","isPickerOpen","setIsPickerOpen","pickerRef","fieldLabel","label","fieldDescription","admin","description","placeholder","handleColorChange","color","handleInputChange","event","target","togglePicker","previous","handleClickOutside","current","contains","document","addEventListener","removeEventListener","div","className","style","position","htmlFor","display","marginBottom","fontSize","fontWeight","required","span","marginLeft","lineHeight","alignItems","gap","button","type","onClick","width","height","borderRadius","border","backgroundColor","cursor","justifyContent","title","input","id","onChange","flex","padding","fontFamily","startsWith","ref","top","left","right","zIndex","marginTop","boxShadow","maxHeight","overflowY","Object","entries","map","groupName","colors","textTransform","letterSpacing","gridTemplateColumns","transition","overflow","onMouseEnter","currentTarget","transform","onMouseLeave","inset","paddingTop","borderTop","strong"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/fields/ColorPickerField.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport { Palette } from 'lucide-react'\nimport type { TextFieldClientProps } from 'payload'\nimport { useCallback, useEffect, useId, useRef, useState } from 'react'\nimport { useThemeLanguage, useThemeTranslations } from '../hooks/useThemeTranslations.js'\nimport { resolveLocalizedText } from '../utils/localizedText.js'\n\ntype PresetGroup = 'themeColors' | 'commonColors' | 'neutralTones'\n\nconst colorPresets: Record<PresetGroup, string[]> = {\n themeColors: ['#3b82f6', '#1e40af', '#b45309', '#78716c', '#8b5cf6', '#f97316'],\n commonColors: ['#ef4444', '#10b981', '#f59e0b', '#06b6d4', '#ec4899', '#6b7280'],\n neutralTones: ['#000000', '#1f2937', '#6b7280', '#d1d5db', '#f3f4f6', '#ffffff'],\n}\n\nexport default function ColorPickerField(props: TextFieldClientProps) {\n const { field, path } = props\n const { value = '#000000', setValue } = useField<string>({ path })\n const [isPickerOpen, setIsPickerOpen] = useState(false)\n const pickerRef = useRef<HTMLDivElement>(null)\n const toggleRef = useRef<HTMLButtonElement>(null)\n const t = useThemeTranslations().colorPicker\n const language = useThemeLanguage()\n const inputId = useId()\n const descriptionId = useId()\n const popoverId = useId()\n\n const fieldLabel = resolveLocalizedText(field.label, language)\n const fieldDescription = resolveLocalizedText(field.admin?.description, language)\n const placeholder =\n resolveLocalizedText(field.admin?.placeholder, language) || t.placeholder\n\n const handleColorChange = useCallback(\n (color: string) => {\n setValue(color)\n },\n [setValue],\n )\n\n const handleInputChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n handleColorChange(event.target.value)\n },\n [handleColorChange],\n )\n\n const togglePicker = useCallback(() => {\n setIsPickerOpen((previous) => !previous)\n }, [])\n\n useEffect(() => {\n if (!isPickerOpen) {\n return\n }\n\n function handlePointerOutside(event: PointerEvent) {\n const target = event.target as Node\n if (pickerRef.current?.contains(target) || toggleRef.current?.contains(target)) {\n return\n }\n setIsPickerOpen(false)\n }\n\n function handleKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n setIsPickerOpen(false)\n toggleRef.current?.focus()\n }\n }\n\n document.addEventListener('pointerdown', handlePointerOutside)\n document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n document.removeEventListener('pointerdown', handlePointerOutside)\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [isPickerOpen])\n\n return (\n <div className=\"field-type color-picker-field\" style={{ position: 'relative' }}>\n {fieldLabel && (\n <label\n htmlFor={inputId}\n className=\"field-label\"\n style={{ display: 'block', marginBottom: '8px', fontSize: '13px', fontWeight: 600 }}\n >\n {fieldLabel}\n {field.required && (\n <span\n className=\"required\"\n style={{ color: 'var(--theme-error-500)', marginLeft: '4px' }}\n >\n *\n </span>\n )}\n </label>\n )}\n\n {fieldDescription && (\n <div\n id={descriptionId}\n className=\"field-description\"\n style={{\n marginBottom: '8px',\n fontSize: '13px',\n color: 'var(--theme-elevation-600)',\n lineHeight: 1.5,\n }}\n >\n {fieldDescription}\n </div>\n )}\n\n <div\n className=\"color-picker-input-group\"\n style={{ display: 'flex', alignItems: 'center', gap: '8px' }}\n >\n <button\n ref={toggleRef}\n type=\"button\"\n onClick={togglePicker}\n className=\"color-preview-button\"\n aria-expanded={isPickerOpen}\n aria-controls={isPickerOpen ? popoverId : undefined}\n aria-label={`${t.presetsTitle}${fieldLabel ? `: ${fieldLabel}` : ''}`}\n style={{\n width: '40px',\n height: '40px',\n borderRadius: '6px',\n border: '2px solid var(--theme-elevation-200)',\n backgroundColor: value || 'var(--theme-elevation-0)',\n cursor: 'pointer',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n title={value ? `${t.currentColor}: ${value}` : t.presetsTitle}\n >\n {!value && <Palette size={18} color=\"var(--theme-elevation-500)\" aria-hidden />}\n </button>\n\n <input\n id={inputId}\n type=\"text\"\n value={value || ''}\n onChange={handleInputChange}\n placeholder={placeholder}\n aria-describedby={fieldDescription ? descriptionId : undefined}\n spellCheck={false}\n style={{\n flex: 1,\n minWidth: 0,\n padding: '8px 12px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '6px',\n fontSize: '14px',\n fontFamily: 'monospace',\n backgroundColor: 'var(--theme-input-bg, var(--theme-elevation-0))',\n color: 'var(--theme-elevation-1000)',\n }}\n />\n\n <input\n type=\"color\"\n value={value?.startsWith('#') ? value : '#3b82f6'}\n onChange={handleInputChange}\n title={t.customColor}\n aria-label={t.customColor}\n style={{\n width: '40px',\n height: '40px',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n }}\n />\n </div>\n\n {isPickerOpen && (\n <div\n ref={pickerRef}\n id={popoverId}\n role=\"dialog\"\n aria-label={t.presetsTitle}\n className=\"color-presets\"\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n right: 0,\n zIndex: 1000,\n marginTop: '4px',\n padding: '16px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '8px',\n backgroundColor: 'var(--theme-elevation-0)',\n boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n maxHeight: '300px',\n overflowY: 'auto',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n marginBottom: '16px',\n fontSize: '14px',\n fontWeight: 600,\n color: 'var(--theme-elevation-800)',\n }}\n >\n <Palette size={14} aria-hidden />\n {t.presetsTitle}\n </div>\n\n {(Object.keys(colorPresets) as PresetGroup[]).map((group) => (\n <div key={group} role=\"group\" aria-label={t[group]} style={{ marginBottom: '16px' }}>\n <div\n style={{\n marginBottom: '8px',\n fontSize: '12px',\n fontWeight: 600,\n color: 'var(--theme-elevation-600)',\n }}\n >\n {t[group]}\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: '6px' }}>\n {colorPresets[group].map((color) => {\n const selected = value === color\n return (\n <button\n key={color}\n type=\"button\"\n onClick={() => handleColorChange(color)}\n aria-pressed={selected}\n aria-label={`${t.selectColor} ${color}`}\n title={color}\n style={{\n width: '36px',\n height: '36px',\n borderRadius: '6px',\n border: selected\n ? '3px solid var(--theme-elevation-900)'\n : '1px solid var(--theme-elevation-200)',\n backgroundColor: color,\n cursor: 'pointer',\n boxShadow: selected\n ? '0 0 0 2px var(--theme-elevation-0)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)',\n }}\n />\n )\n })}\n </div>\n </div>\n ))}\n\n <div\n style={{\n marginTop: '16px',\n paddingTop: '16px',\n borderTop: '1px solid var(--theme-elevation-100)',\n }}\n >\n <div\n style={{\n marginBottom: '8px',\n fontSize: '12px',\n fontWeight: 600,\n color: 'var(--theme-elevation-600)',\n }}\n >\n {t.customColor}\n </div>\n <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <input\n type=\"color\"\n value={value?.startsWith('#') ? value : '#3b82f6'}\n onChange={handleInputChange}\n aria-label={t.customColor}\n style={{\n width: '36px',\n height: '36px',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n }}\n />\n <div style={{ fontSize: '12px', color: 'var(--theme-elevation-600)', lineHeight: 1.4 }}>\n {t.formats}\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n"],"names":["useField","Palette","useCallback","useEffect","useId","useRef","useState","useThemeLanguage","useThemeTranslations","resolveLocalizedText","colorPresets","themeColors","commonColors","neutralTones","ColorPickerField","props","field","path","value","setValue","isPickerOpen","setIsPickerOpen","pickerRef","toggleRef","t","colorPicker","language","inputId","descriptionId","popoverId","fieldLabel","label","fieldDescription","admin","description","placeholder","handleColorChange","color","handleInputChange","event","target","togglePicker","previous","handlePointerOutside","current","contains","handleKeyDown","key","focus","document","addEventListener","removeEventListener","div","className","style","position","htmlFor","display","marginBottom","fontSize","fontWeight","required","span","marginLeft","id","lineHeight","alignItems","gap","button","ref","type","onClick","aria-expanded","aria-controls","undefined","aria-label","presetsTitle","width","height","borderRadius","border","backgroundColor","cursor","justifyContent","title","currentColor","size","aria-hidden","input","onChange","aria-describedby","spellCheck","flex","minWidth","padding","fontFamily","startsWith","customColor","role","top","left","right","zIndex","marginTop","boxShadow","maxHeight","overflowY","Object","keys","map","group","gridTemplateColumns","selected","aria-pressed","selectColor","paddingTop","borderTop","formats"],"mappings":"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"}
|