feat: enhance styling and layout of workflow components for improved usability

This commit is contained in:
mlogclub
2026-06-28 22:40:07 +08:00
parent 15be17e0df
commit e7e0bbf170
4 changed files with 22 additions and 17 deletions
@@ -24,7 +24,7 @@ export function WorkflowCanvasControls({
autoLayoutDisabled?: boolean autoLayoutDisabled?: boolean
}) { }) {
return ( return (
<div className="inline-flex h-9 items-center gap-1 rounded-md bg-background/95 p-1 shadow-sm backdrop-blur"> <div className="inline-flex h-9 items-center gap-0.5 rounded-md border border-slate-200/80 bg-white/95 p-1 shadow-sm backdrop-blur">
<CanvasControlButton label="缩小" onClick={onZoomOut}> <CanvasControlButton label="缩小" onClick={onZoomOut}>
<MinusIcon className="size-3.5" /> <MinusIcon className="size-3.5" />
</CanvasControlButton> </CanvasControlButton>
@@ -35,7 +35,7 @@ export function WorkflowCanvasControls({
type="button" type="button"
variant="ghost" variant="ghost"
size="sm" size="sm"
className="h-7 w-12 px-1 text-xs tabular-nums" className="h-7 w-12 px-1 text-xs tabular-nums text-slate-700 hover:bg-slate-100 hover:text-slate-950"
aria-label="重置为 100%" aria-label="重置为 100%"
disabled={!onResetZoom} disabled={!onResetZoom}
onClick={onResetZoom} onClick={onResetZoom}
@@ -49,6 +49,7 @@ export function WorkflowCanvasControls({
<CanvasControlButton label="放大" onClick={onZoomIn}> <CanvasControlButton label="放大" onClick={onZoomIn}>
<PlusIcon className="size-3.5" /> <PlusIcon className="size-3.5" />
</CanvasControlButton> </CanvasControlButton>
<span className="mx-1 h-4 w-px shrink-0 bg-slate-200" />
<CanvasControlButton label="适配画布" onClick={onFitView}> <CanvasControlButton label="适配画布" onClick={onFitView}>
<Maximize2Icon className="size-3.5" /> <Maximize2Icon className="size-3.5" />
</CanvasControlButton> </CanvasControlButton>
@@ -78,7 +79,7 @@ function CanvasControlButton({
type="button" type="button"
variant="ghost" variant="ghost"
size="icon-xs" size="icon-xs"
className="size-7" className="size-7 text-slate-700 hover:bg-slate-100 hover:text-slate-950"
aria-label={label} aria-label={label}
disabled={disabled || !onClick} disabled={disabled || !onClick}
onClick={onClick} onClick={onClick}
@@ -16,7 +16,7 @@ export function WorkflowEditorStatus({
edgeCount: number edgeCount: number
}) { }) {
return ( return (
<div className="pointer-events-none inline-flex min-h-8 w-fit max-w-full items-center gap-2 rounded-md border border-slate-200/80 bg-white/90 px-2.5 py-1 text-xs text-slate-500 shadow-sm backdrop-blur"> <div className="pointer-events-none inline-flex w-fit max-w-full items-center gap-2 px-1 text-xs text-slate-500">
<span <span
className={cn( className={cn(
"inline-flex shrink-0 items-center gap-1", "inline-flex shrink-0 items-center gap-1",
@@ -24,14 +24,15 @@ export function WorkflowEditorStatus({
)} )}
> >
{validation.valid ? ( {validation.valid ? (
<CheckCircle2Icon className="size-3.5" /> <CheckCircle2Icon className="size-3" />
) : ( ) : (
<AlertTriangleIcon className="size-3.5" /> <AlertTriangleIcon className="size-3" />
)} )}
{validation.valid ? "检查通过" : `${validation.errors.length} 个问题`} {validation.valid ? "检查通过" : `${validation.errors.length} 个问题`}
</span> </span>
<span className="h-3 w-px shrink-0 bg-slate-200" /> <span className="shrink-0 text-slate-300">/</span>
<span className="shrink-0">{nodeCount} </span> <span className="shrink-0">{nodeCount} </span>
<span className="shrink-0 text-slate-300">·</span>
<span className="shrink-0">{edgeCount} 线</span> <span className="shrink-0">{edgeCount} 线</span>
</div> </div>
) )
@@ -2,6 +2,7 @@
import type { ReactNode } from "react" import type { ReactNode } from "react"
import { import {
CheckIcon,
Redo2Icon, Redo2Icon,
RotateCcwIcon, RotateCcwIcon,
SaveIcon, SaveIcon,
@@ -41,29 +42,31 @@ export function WorkflowEditorToolbar({
publishDisabled?: boolean publishDisabled?: boolean
}) { }) {
return ( return (
<div className="inline-flex min-h-10 w-fit max-w-full items-center rounded-md bg-background/95 px-2 py-1 shadow-sm backdrop-blur"> <div className="inline-flex min-h-9 w-fit max-w-full items-center rounded-md bg-white/95 px-1.5 py-1 shadow-sm backdrop-blur">
<div className="flex min-w-0 items-center gap-1 overflow-x-auto"> <div className="flex min-w-0 items-center gap-0.5 overflow-x-auto">
{toolbarExtra} {toolbarExtra}
<Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs" disabled={undoDisabled} onClick={onUndo}> <Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs text-slate-700 hover:bg-slate-100 hover:text-slate-950" disabled={undoDisabled} onClick={onUndo}>
<Undo2Icon className="size-3.5" /> <Undo2Icon className="size-3.5" />
</Button> </Button>
<Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs" disabled={redoDisabled} onClick={onRedo}> <Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs text-slate-700 hover:bg-slate-100 hover:text-slate-950" disabled={redoDisabled} onClick={onRedo}>
<Redo2Icon className="size-3.5" /> <Redo2Icon className="size-3.5" />
</Button> </Button>
<Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs" disabled={restoreDefaultDisabled} onClick={onRestoreDefault}> <Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs text-slate-700 hover:bg-slate-100 hover:text-slate-950" disabled={restoreDefaultDisabled} onClick={onRestoreDefault}>
<RotateCcwIcon className="size-3.5" /> <RotateCcwIcon className="size-3.5" />
</Button> </Button>
<Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs" disabled={validateDisabled} onClick={onValidate}> <span className="mx-1 h-4 w-px shrink-0 bg-slate-200" />
<Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs text-slate-700 hover:bg-slate-100 hover:text-slate-950" disabled={validateDisabled} onClick={onValidate}>
<CheckIcon className="size-3.5" />
</Button> </Button>
<Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs" disabled={saveDraftDisabled} onClick={onSaveDraft}> <Button type="button" variant="ghost" size="sm" className="h-7 shrink-0 px-2 text-xs text-slate-700 hover:bg-slate-100 hover:text-slate-950" disabled={saveDraftDisabled} onClick={onSaveDraft}>
<SaveIcon className="size-3.5" /> <SaveIcon className="size-3.5" />
</Button> </Button>
<Button type="button" size="sm" className="h-7 shrink-0 px-2 text-xs" disabled={publishDisabled} onClick={onPublish}> <Button type="button" size="sm" className="h-7 shrink-0 bg-[#2575FC] px-2 text-xs hover:bg-[#1b63d8]" disabled={publishDisabled} onClick={onPublish}>
<SendIcon className="size-3.5" /> <SendIcon className="size-3.5" />
</Button> </Button>
@@ -330,7 +330,7 @@ function WorkflowEditorInner({
> >
<div <div
className={cn( className={cn(
"absolute left-3 top-3 z-50 flex max-w-[calc(100%-1.5rem)] flex-col items-start gap-2", "absolute left-3 top-3 z-50 flex max-w-[calc(100%-1.5rem)] flex-col items-start gap-1.5",
selectedNodeId && "max-w-[calc(100%-25rem)]" selectedNodeId && "max-w-[calc(100%-25rem)]"
)} )}
> >
@@ -356,7 +356,7 @@ function WorkflowEditorInner({
/> />
</div> </div>
<div className="absolute bottom-3 left-3 z-50"> <div className="absolute bottom-4 left-4 z-50">
<WorkflowCanvasControls <WorkflowCanvasControls
zoomPercent={zoomPercent} zoomPercent={zoomPercent}
onZoomIn={() => playgroundTools.zoomin(true)} onZoomIn={() => playgroundTools.zoomin(true)}