'use client'; import { cn } from '@/lib/utils'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/shared/ui/popover'; import { useThemeSwitch } from '@/components/shared/useThemeSwitch'; import { useEffect, useMemo, useState } from 'react'; import chroma from 'chroma-js'; import { Button } from '@/components/shared/ui/button'; import { ColorThemeObject, complementaryColorThemes, } from '@/components/bricks/theme/color-themes'; import { CheckIcon, ChevronsUpDownIcon, CopyIcon, Loader2 } from 'lucide-react'; import { Separator } from '@/components/shared/ui/separator'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DialogClose, } from '@/components/shared/ui/dialog'; import { CodeEditor } from '@/components/shared/CodeEditor'; import { CopyButton } from '@/components/shared/ui/copy-button'; import { getShipixenThemeJs } from '@/components/bricks/theme/code-stringifiers/get-theme-js-file'; import { useThemeStore } from '@/components/bricks/state/theme-state'; import { getStyleString } from '@/components/bricks/theme/code-stringifiers/get-style-string'; export const ThemeSelector = ({ className, onThemeChanged, showCopyCodeButton = true, // Show copy code button & overlay showChangeThemeLabel = true, // Show input label }: { className?: string; onThemeChanged?: (theme: ColorThemeObject) => void; showCopyCodeButton?: boolean; showChangeThemeLabel?: boolean; }) => { const stateThemeObject = useThemeStore((state) => state.themeObject); const stateSetThemeObject = useThemeStore((state) => state.setThemeObject); const stateFonts = useThemeStore((state) => state.fonts); const stateSetFonts = useThemeStore((state) => state.setFonts); const { default: fontFamilyDefault, display: fontFamilyDisplay } = stateFonts; const { currentTheme } = useThemeSwitch(); const isDarkMode = currentTheme === 'dark'; const [themeSelectorOpen, setThemeSelectorOpen] = useState(false); const [isClient, setIsClient] = useState(false); const theme = { primary: { lighter: stateThemeObject.colors.primary[3], light: stateThemeObject.colors.primary[4], main: stateThemeObject.colors.primary[5], dark: stateThemeObject.colors.primary[6], darker: stateThemeObject.colors.primary[7], }, secondary: { lighter: stateThemeObject.colors.secondary[3], light: stateThemeObject.colors.secondary[4], main: stateThemeObject.colors.secondary[5], dark: stateThemeObject.colors.secondary[6], darker: stateThemeObject.colors.secondary[7], }, primaryTailwindName: stateThemeObject.tailwindNames.primary, secondaryTailwindName: stateThemeObject.tailwindNames.secondary, }; const themeStyleString = getStyleString({ primary: theme.primary, secondary: theme.secondary, }); const pickColorTheme = ( theme: (typeof complementaryColorThemes)[0], index: number, ) => { stateSetThemeObject(theme); if (onThemeChanged) { onThemeChanged(theme); } }; const mapColor = (color: string, index: number) => (
); const mapColors = ( theme: (typeof complementaryColorThemes)[0], index?: number, selected?: boolean, ) => { const relevantPrimaryColors = [ theme.colors.primary[3], theme.colors.primary[4], theme.colors.primary[5], theme.colors.primary[6], theme.colors.primary[7], ]; const relevantSecondaryColors = [ theme.colors.secondary[3], theme.colors.secondary[4], theme.colors.secondary[5], theme.colors.secondary[6], theme.colors.secondary[7], ]; return (
{isClient ? ( <> {selected && (
)} {relevantPrimaryColors.map(mapColor)} {relevantSecondaryColors.map(mapColor)} ) : (
)}
); }; const formattedCodeString = getShipixenThemeJs(theme); // Create font URL for Google Fonts const fonts = useMemo(() => { // replace space with '+' const headingFont = fontFamilyDefault.name.replace(/ /g, '+'); const displayFont = fontFamilyDisplay.name.replace(/ /g, '+'); const headingFontWeights = fontFamilyDefault.variableFont ? `:wght@400..600` : `:wght@${(fontFamilyDefault.weights || [400, 600]).join(';')}`; const displayFontWeights = fontFamilyDisplay.variableFont || !fontFamilyDisplay.weights ? `:wght@400..600` : `:wght@${(fontFamilyDisplay.weights || [400, 600]).join(';')}`; return { fontUrl: `https://fonts.googleapis.com/css2?family=${headingFont}${headingFontWeights}&family=${displayFont}${displayFontWeights}&display=swap`, bodyFont: fontFamilyDefault, displayFont: fontFamilyDisplay, }; }, [fontFamilyDefault, fontFamilyDisplay]); useEffect(() => { setIsClient(true); }, []); return ( <> {isClient ? ( <> ) : null}
{showChangeThemeLabel ? (

Change theme

) : null}
{complementaryColorThemes.map((theme, index) => (
))}
{showCopyCodeButton ? ( <> Copy code Paste the code below in your Shipixen app under:{' '} data/config/colors.js.
See{' '} the docs {' '} for more info.
) : null}
); };