import type { Fabric, SewOrderKey, StagedDocument, SvgPlanMode, ThreadProfileMode, } from '@/lib/engine'; import { FABRIC_MODES, PLAN_MODES, THREAD_PROFILE_MODES } from '@/lib/engine'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Input } from '@/components/ui/input'; import { Slider } from '@/components/ui/slider'; import { Switch } from '@/components/ui/switch'; import { Label } from '@/components/ui/label'; import { Button } from '@/components/ui/button'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { setGlobal, autoOrder, remapSourceColor, setGeometryTolerance, setScale, } from './staging-actions'; interface Props { doc: StagedDocument; mode: 'replace' | 'append'; update: (fn: (doc: StagedDocument) => StagedDocument) => void; } export default function GlobalToolbar({ doc, mode, update }: Props) { const sources = Object.keys(doc.threadMap); return (
{/* fabric */} {/* order by */} {/* logical geometry detail */} }> detail {doc.geometryToleranceMM.toFixed(2)} mm { const raw = Array.isArray(vals) ? vals[0] : (vals as number); update((d) => setGeometryTolerance(d, raw)); }} />

Boundary detail only; stitch spacing stays recipe-specific.

{/* scale */} }> scale {doc.scaleFactor.toFixed(2)}× { const raw = Array.isArray(vals) ? vals[0] : (vals as number); update((d) => setScale(d, raw)); }} />

1× = fitted size · adjust if SVG dimensions are wrong

{/* seed */} {/* thread mapping */} }> Threads source thread {sources.map((src) => ( {src}
{doc.palette.map((hex, i) => (
))}
); }