A list beside a panel: the shape of a detail or explorer artifact.
(props: { readonly next: () => number })
| 254 | |
| 255 | /** A list beside a panel: the shape of a detail or explorer artifact. */ |
| 256 | function SplitFigure(props: { readonly next: () => number }) { |
| 257 | const { next } = props; |
| 258 | const railWidth = 96; |
| 259 | const panelX = PAD + railWidth + 14; |
| 260 | const panelWidth = WIDTH - PAD - panelX; |
| 261 | const panelHeight = HEIGHT - PAD - BODY_TOP; |
| 262 | const points = Array.from({ length: 7 }, (_, index) => { |
| 263 | const x = panelX + 12 + (index * (panelWidth - 24)) / 6; |
| 264 | const y = BODY_TOP + panelHeight - 16 - between(next, 6, panelHeight - 40); |
| 265 | return `${x},${y}`; |
| 266 | }).join(" "); |
| 267 | |
| 268 | return ( |
| 269 | <> |
| 270 | {Array.from({ length: 4 }, (_, index) => ( |
| 271 | <Block |
| 272 | key={index} |
| 273 | x={PAD} |
| 274 | y={BODY_TOP + index * 22} |
| 275 | width={between(next, 52, railWidth)} |
| 276 | height={8} |
| 277 | className={index === 0 ? "fill-muted-foreground/35" : undefined} |
| 278 | /> |
| 279 | ))} |
| 280 | <rect |
| 281 | x={panelX} |
| 282 | y={BODY_TOP} |
| 283 | width={panelWidth} |
| 284 | height={panelHeight} |
| 285 | rx={4} |
| 286 | className="fill-transparent stroke-border" |
| 287 | strokeWidth={1} |
| 288 | /> |
| 289 | <polyline |
| 290 | points={points} |
| 291 | className="fill-none stroke-muted-foreground/50" |
| 292 | strokeWidth={1.5} |
| 293 | strokeLinejoin="round" |
| 294 | strokeLinecap="round" |
| 295 | /> |
| 296 | </> |
| 297 | ); |
| 298 | } |
| 299 | |
| 300 | const FIGURES = [BarsFigure, RowsFigure, TilesFigure, SplitFigure] as const; |
| 301 |