From 06d6c0ef1efb0cb4a3a9b21ae873b2abaf4ab73d Mon Sep 17 00:00:00 2001 From: SnapOtter Date: Tue, 5 May 2026 23:09:10 +0800 Subject: [PATCH] feat: add transparency-fixer settings component --- .../tools/transparency-fixer-settings.tsx | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 apps/web/src/components/tools/transparency-fixer-settings.tsx diff --git a/apps/web/src/components/tools/transparency-fixer-settings.tsx b/apps/web/src/components/tools/transparency-fixer-settings.tsx new file mode 100644 index 00000000..ed1119e6 --- /dev/null +++ b/apps/web/src/components/tools/transparency-fixer-settings.tsx @@ -0,0 +1,140 @@ +import { ChevronDown, ChevronRight } from "lucide-react"; +import { useEffect, useRef, useState } from "react"; +import { ProgressCard } from "@/components/common/progress-card"; +import { useToolProcessor } from "@/hooks/use-tool-processor"; +import { useFileStore } from "@/stores/file-store"; + +type OutputFormat = "png" | "webp"; + +// ── Shared controls (used by both standalone page and pipeline steps) ── + +export interface TransparencyFixerControlsProps { + settings: Record; + onChange: (settings: Record) => void; +} + +export function TransparencyFixerControls({ + settings: _settings, + onChange, +}: TransparencyFixerControlsProps) { + const [defringe, setDefringe] = useState(30); + const [outputFormat, setOutputFormat] = useState("png"); + const [advancedOpen, setAdvancedOpen] = useState(false); + + const onChangeRef = useRef(onChange); + useEffect(() => { + onChangeRef.current = onChange; + }); + + // Sync settings on every control change + useEffect(() => { + onChangeRef.current({ defringe, outputFormat }); + }, [defringe, outputFormat]); + + return ( +
+

+ Upload a PNG with a fake transparent background and we'll fix it in one click. +

+ + {/* Advanced toggle */} + + + {advancedOpen && ( +
+ {/* Defringe slider */} +
+
+ Defringe + + {defringe} + +
+ setDefringe(Number(e.target.value))} + className="w-full mt-0.5" + /> +
+ + {/* Output Format dropdown */} +
+

+ Output Format +

+ +
+
+ )} +
+ ); +} + +// ── Standalone tool page wrapper ── + +export function TransparencyFixerSettings() { + const { files } = useFileStore(); + const { processFiles, processAllFiles, processing, error, progress } = + useToolProcessor("transparency-fixer"); + const [settings, setSettings] = useState>({}); + + const handleProcess = () => { + if (files.length > 1) { + processAllFiles(files, settings); + } else { + processFiles(files, settings); + } + }; + + const hasFile = files.length > 0; + const hasMultiple = files.length > 1; + + return ( +
+ + + {/* Error */} + {error &&

{error}

} + + {/* Process button / progress */} + {processing ? ( + + ) : ( + + )} +
+ ); +}