feat: drag-to-resize device nodes + BrickWallFire for firewall

- NodeResizer on DeviceNode (same pattern as group nodes); icon scales
  proportionally with node width, clamped 16–60px
- Removes S/M/L static picker — resize is now direct manipulation
- firewall: ShieldAlert → BrickWallFire

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-04-13 04:07:52 +00:00
parent 31324aa154
commit 47353a68cd
3 changed files with 54 additions and 71 deletions

View File

@@ -3,7 +3,7 @@ import { Trash2, Minus, Spline, GitBranch, BringToFront, SendToBack } from 'luci
import { cn } from '@/lib/utils'
import type { DeviceProperties, DiagramEdge } from '@/types'
import type { Node, Edge } from '@xyflow/react'
import type { DeviceNodeData, IconSize } from '../nodes/DeviceNode'
import type { DeviceNodeData } from '../nodes/DeviceNode'
interface PropertiesPanelProps {
selectedNode: Node | null
@@ -272,30 +272,6 @@ export function PropertiesPanel({
<FieldInput value={nodeData.label} onChange={handleLabelChange} placeholder="Device name" />
</div>
{/* Icon size */}
<div className="flex flex-col gap-1">
<FieldLabel>Icon Size</FieldLabel>
<div className="flex gap-1">
{(['sm', 'md', 'lg'] as IconSize[]).map(size => {
const active = (nodeData.iconSize ?? 'md') === size
return (
<button
key={size}
onClick={() => onNodeUpdate(selectedNode!.id, { iconSize: size } as Partial<DeviceNodeData>)}
className={cn(
'flex flex-1 items-center justify-center rounded border py-1.5 text-[10px] font-medium uppercase transition-colors',
active
? 'border-accent bg-accent/10 text-accent'
: 'border-default text-muted-foreground hover:border-hover hover:text-primary',
)}
>
{size}
</button>
)
})}
</div>
</div>
{/* Layering */}
<div className="flex flex-col gap-1">
<FieldLabel>Layer</FieldLabel>