import type { CSSProperties } from "react"; /** * Shared dual-color swatch styling. * * This module lives OUTSIDE src/frontend/extension/ so it can be imported by the * free frontend bundle (src/frontend/main.tsx -> components/SwatchGroup.tsx) * without importing extension-only code. The gradient logic here is kept local * to preserve base/extension bundle separation. */ export type DualColorCut = "vertical" | "horizontal" | "diagonal" | "diagonal_reverse"; export type DualColorGradient = "none" | "gentle" | "aggressive"; export interface DualColorSettings { dualColorEnabled: boolean; dualColorCut: DualColorCut; dualColorGradient: DualColorGradient; } export const DEFAULT_DUAL_COLOR_SETTINGS: DualColorSettings = { dualColorEnabled: false, dualColorCut: "diagonal", dualColorGradient: "none", }; /** * Build the background style for a color/dual-color swatch. * * Mirrors the extension dual-color behaviour for the live frontend. Returns * null when no primary color is present. */ export const buildDualColorStyle = ( primary: string | undefined, secondary: string | undefined, settings: DualColorSettings | null | undefined, ): CSSProperties | null => { const p = String(primary || "").trim(); const s = String(secondary || "").trim(); const effective = { ...DEFAULT_DUAL_COLOR_SETTINGS, ...(settings || {}), }; if (!p) return null; if (!effective.dualColorEnabled || !s) { return { backgroundColor: p }; } const angle = (() => { if (effective.dualColorCut === "vertical") return 90; if (effective.dualColorCut === "horizontal") return 180; if (effective.dualColorCut === "diagonal_reverse") return 45; return 135; })(); const stops = (() => { if (effective.dualColorGradient === "gentle") return { pEnd: 25, sStart: 75 }; if (effective.dualColorGradient === "aggressive") return { pEnd: 45, sStart: 55 }; return { pEnd: 50, sStart: 50 }; })(); return { backgroundImage: `linear-gradient(${angle}deg, ${p} 0%, ${p} ${stops.pEnd}%, ${s} ${stops.sStart}%, ${s} 100%)`, backgroundColor: p, }; };