refactor: Update bottom controls for improved styling and functionality

- Adjusted button styles across various components for consistency and better UX.
- Enhanced layout of action controls to utilize whitespace more effectively.
- Updated slider styles for a more modern appearance and improved usability.
- Refined input fields and labels for better accessibility and readability.
- Introduced new app surface styles for a cohesive design across the application.
- Added tests for canvas cursor behavior to ensure correct cursor display during operations.
This commit is contained in:
syntaxbullet
2026-07-11 14:55:32 +02:00
parent 37aa719047
commit 5915c62a9a
31 changed files with 345 additions and 287 deletions

View File

@@ -19,16 +19,19 @@ export function MagicWandControls({ settings, dispatch }: { settings: MagicWandS
<BottomControlDivider />
<Slider label="Clean" value={settings.despeckle} min={0} max={20} onChange={(despeckle) => dispatch(commandIds.toolSetMagicWandSettings, { despeckle })} />
<BottomControlDivider />
<button type="button" className={`rounded-full px-4 py-2 text-base font-medium transition ${settings.contiguous ? "bg-white text-black" : "bg-white/10 text-white"}`} aria-label="Contiguous selection" aria-pressed={settings.contiguous} title="Select only connected pixels" onClick={() => dispatch(commandIds.toolSetMagicWandSettings, { contiguous: !settings.contiguous })}>Contiguous</button>
<button type="button" className={`rounded-md px-3 py-1.5 text-xs font-medium transition ${settings.contiguous ? "bg-sky-300 text-slate-950" : "bg-white/[0.06] text-white/70"}`} aria-label="Contiguous selection" aria-pressed={settings.contiguous} title="Select only connected pixels" onClick={() => dispatch(commandIds.toolSetMagicWandSettings, { contiguous: !settings.contiguous })}>Contiguous</button>
<BottomControlDivider />
{(["replace", "add", "subtract"] as const).map((mode) => (
<button key={mode} type="button" className={`rounded-full px-4 py-2 text-base font-medium capitalize transition ${settings.mode === mode ? "bg-white text-black" : "bg-white/10 text-white"}`} aria-pressed={settings.mode === mode} onClick={() => dispatch(commandIds.toolSetMagicWandSettings, { mode })}>{mode}</button>
<button key={mode} type="button" className={`rounded-md px-3 py-1.5 text-xs font-medium capitalize transition ${settings.mode === mode ? "bg-sky-300 text-slate-950" : "bg-white/[0.06] text-white/70"}`} aria-pressed={settings.mode === mode} onClick={() => dispatch(commandIds.toolSetMagicWandSettings, { mode })}>{mode}</button>
))}
<span className="px-2 text-sm text-white/60">Shift-click adds, Alt-click subtracts</span>
<span className="flex items-center gap-1 px-1 text-[0.65rem] text-white/45" aria-label="Shift click adds; Alt click subtracts" title="Shift-click adds · Alt-click subtracts">
<kbd className="rounded border border-white/10 px-1 py-0.5 font-sans text-white/65">⇧ +</kbd>
<kbd className="rounded border border-white/10 px-1 py-0.5 font-sans text-white/65">⌥ −</kbd>
</span>
</div>
);
}
function Slider({ label, value, min, max, onChange }: { label: string; value: number; min: number; max: number; onChange: (value: number) => void }) {
return <label className={bottomControlFieldClass()}><span className={bottomControlLabelClass()}>{label}</span><BottomControlSlider min={min} max={max} value={value} className="w-32" aria-label={`Magic wand ${label}`} onValueChange={onChange} /><span className="w-8 text-right text-base text-white">{Math.round(value)}</span></label>;
return <label className={`${bottomControlFieldClass()} min-w-0`}><span className={bottomControlLabelClass()}>{label}</span><BottomControlSlider min={min} max={max} value={value} className="min-w-8 w-[clamp(2rem,7vw,5rem)] shrink" aria-label={`Magic wand ${label}`} onValueChange={onChange} /><span className="w-7 shrink-0 text-right text-xs font-medium text-white/85">{Math.round(value)}</span></label>;
}