Skip to content

Commit 6c4a0ac

Browse files
committed
style: Improve visualization of packet layer headers
1 parent cc1be2b commit 6c4a0ac

File tree

1 file changed

+40
-28
lines changed

1 file changed

+40
-28
lines changed

src/components/EncapsulatedPacket.tsx

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function EncapsulatedPacket(props: Props) {
3232
{ x: fromClient ? CLIENT_X : SERVER_X, y: START_Y + STEP_Y }, // Transport
3333
{ x: fromClient ? CLIENT_X : SERVER_X, y: START_Y + STEP_Y * 2 }, // Internet
3434
{ x: fromClient ? CLIENT_X : SERVER_X, y: START_Y + STEP_Y * 3 }, // Network Interface
35-
{ x: TRANSMISSION_X, y: START_Y + STEP_Y * 4 }, // Transmission
35+
{ x: TRANSMISSION_X, y: START_Y + STEP_Y * 3 }, // Transmission
3636
{ x: fromClient ? SERVER_X : CLIENT_X, y: START_Y + STEP_Y * 3 }, // Network Interface (receiver)
3737
{ x: fromClient ? SERVER_X : CLIENT_X, y: START_Y + STEP_Y * 2 }, // Internet (receiver)
3838
{ x: fromClient ? SERVER_X : CLIENT_X, y: START_Y + STEP_Y * 1 }, // Transport (receiver)
@@ -43,6 +43,10 @@ function EncapsulatedPacket(props: Props) {
4343
}, [props.stage, props.packet.from])
4444

4545
const Icon = props.packet.type.icon
46+
const isClientToServer = props.packet.from === 'client'
47+
const isOnSenderSide = props.stage < 4
48+
const alignRight = isClientToServer ? isOnSenderSide : !isOnSenderSide
49+
const isOnTransmission = props.stage === 4
4650

4751
return (
4852
<div
@@ -54,40 +58,48 @@ function EncapsulatedPacket(props: Props) {
5458
zIndex: 50,
5559
}}
5660
>
57-
{/* Base packet (envelope) */}
5861
<div className="relative">
59-
{/* Data payload (envelope) */}
60-
<div className="w-16 h-12 mt-2 bg-white border-2 border-black rounded flex items-center justify-center">
61-
<Icon className="w-8 h-8 text-black" />
62+
<div className="w-16 h-12 mt-2 bg-white border-2 border-black rounded flex items-start justify-center">
63+
<Icon className="mt-0.5 w-6 h-6 text-black" />
6264
</div>
6365

64-
{/* Layer headers (colored borders) */}
65-
{visibleHeaders.map((layerIndex) => (
66-
<div
67-
key={`header-${layerIndex}`}
68-
className="absolute inset-0 border-4 rounded"
69-
style={{
70-
borderColor: TCP_IP_LAYERS[layerIndex].color,
71-
transform: `scale(${1 + (visibleHeaders.length - visibleHeaders.indexOf(layerIndex)) * 0.15})`,
72-
zIndex: -layerIndex,
73-
}}
74-
>
75-
{/* Header label */}
76-
<div
77-
className="absolute -top-5 left-1/2 transform -translate-x-1/2 text-[8px] font-bold px-1 rounded"
78-
style={{
79-
backgroundColor: TCP_IP_LAYERS[layerIndex].color,
80-
color: 'white',
81-
}}
82-
>
83-
{TCP_IP_LAYERS[layerIndex].header}
66+
{visibleHeaders.map((layerIndex, i) => {
67+
const layer = TCP_IP_LAYERS[layerIndex]
68+
69+
const verticalSpacing = 20
70+
const verticalOffset = i * verticalSpacing
71+
72+
return (
73+
<div key={`header-${layerIndex}`}>
74+
<div
75+
className="absolute inset-0 border-4 rounded"
76+
style={{
77+
borderColor: layer.color,
78+
transform: `scale(${1 + (visibleHeaders.length - i) * 0.12})`,
79+
zIndex: -layerIndex,
80+
}}
81+
/>
82+
{!isOnTransmission && (
83+
<div
84+
className="absolute text-[8px] font-bold px-1 py-0.5 rounded whitespace-nowrap text-white text-center min-w-18"
85+
style={{
86+
top: `${verticalOffset}px`,
87+
left: alignRight ? '100%' : 'auto',
88+
right: alignRight ? 'auto' : '100%',
89+
transform: `translateX(${alignRight ? '16px' : '-16px'})`,
90+
backgroundColor: layer.color,
91+
}}
92+
>
93+
{layer.header}
94+
</div>
95+
)}
8496
</div>
85-
</div>
86-
))}
97+
)
98+
})}
8799

88100
{/* Packet type label */}
89101
<div
90-
className="absolute -bottom-6 left-1/2 transform -translate-x-1/2 whitespace-nowrap text-sm font-bold text-center px-1 rounded"
102+
className="absolute bottom-1 left-1/2 transform -translate-x-1/2 whitespace-nowrap text-[10px] font-bold text-center px-1 rounded"
91103
style={{ backgroundColor: props.packet.type.color, color: 'white' }}
92104
>
93105
{props.packet.type.name}

0 commit comments

Comments
 (0)