83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
|
|
import { LocalizedText } from "@workspace/i18n"
|
||
|
|
import { Badge } from "@workspace/ui/components/badge"
|
||
|
|
import { MoonIcon, SunIcon } from "@workspace/ui/components/icon"
|
||
|
|
import { cn } from "@workspace/ui/lib/utils"
|
||
|
|
|
||
|
|
import { appearanceMessages } from "../messages"
|
||
|
|
import type { ThemeColorConfig, ThemeScheme } from "../theme"
|
||
|
|
import {
|
||
|
|
accentColorSwatches,
|
||
|
|
baseColorSwatches,
|
||
|
|
ThemeColorPicker,
|
||
|
|
} from "./theme-color-picker"
|
||
|
|
import { ThemePreview } from "./theme-preview"
|
||
|
|
|
||
|
|
export interface ThemeConfigCardProps {
|
||
|
|
active?: boolean
|
||
|
|
className?: string
|
||
|
|
compacted?: boolean
|
||
|
|
config: ThemeColorConfig
|
||
|
|
onConfigChange: (config: ThemeColorConfig) => void
|
||
|
|
scheme: ThemeScheme
|
||
|
|
}
|
||
|
|
|
||
|
|
export function ThemeConfigCard({
|
||
|
|
active = false,
|
||
|
|
className,
|
||
|
|
compacted = false,
|
||
|
|
config,
|
||
|
|
onConfigChange,
|
||
|
|
scheme,
|
||
|
|
}: ThemeConfigCardProps) {
|
||
|
|
const titleMessage =
|
||
|
|
scheme === "light"
|
||
|
|
? appearanceMessages.lightTheme
|
||
|
|
: appearanceMessages.darkTheme
|
||
|
|
const descriptionMessage =
|
||
|
|
scheme === "light"
|
||
|
|
? appearanceMessages.lightThemeDescription
|
||
|
|
: appearanceMessages.darkThemeDescription
|
||
|
|
|
||
|
|
return (
|
||
|
|
<section className={cn("w-md rounded-xl border", className)}>
|
||
|
|
<header className="flex gap-4 border-b p-3">
|
||
|
|
{scheme === "light" ? (
|
||
|
|
<SunIcon className="size-5" />
|
||
|
|
) : (
|
||
|
|
<MoonIcon className="size-5" />
|
||
|
|
)}
|
||
|
|
<h2>
|
||
|
|
<LocalizedText message={titleMessage} />
|
||
|
|
</h2>
|
||
|
|
{active && (
|
||
|
|
<Badge className="ml-auto">
|
||
|
|
<LocalizedText message={appearanceMessages.active} />
|
||
|
|
</Badge>
|
||
|
|
)}
|
||
|
|
</header>
|
||
|
|
<div className="space-y-4 p-4">
|
||
|
|
<p>
|
||
|
|
<LocalizedText message={descriptionMessage} />
|
||
|
|
</p>
|
||
|
|
<ThemePreview compacted={compacted} config={config} scheme={scheme} />
|
||
|
|
<ThemeColorPicker
|
||
|
|
swatches={baseColorSwatches}
|
||
|
|
title={<LocalizedText message={appearanceMessages.baseColor} />}
|
||
|
|
value={config.baseColor}
|
||
|
|
onValueChange={(baseColor) =>
|
||
|
|
onConfigChange({ ...config, baseColor })
|
||
|
|
}
|
||
|
|
/>
|
||
|
|
<ThemeColorPicker
|
||
|
|
swatches={accentColorSwatches}
|
||
|
|
title={<LocalizedText message={appearanceMessages.primaryColor} />}
|
||
|
|
value={config.accentColor}
|
||
|
|
onValueChange={(accentColor) =>
|
||
|
|
onConfigChange({ ...config, accentColor })
|
||
|
|
}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
)
|
||
|
|
}
|