spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / mods / diff / hooks / views / current-pane / message-pane-of / message-pane-of.tsx
89 lines · 2.8 KBRaw
1/* @jsxRuntime classic */
2/* @jsx h */
3/* @jsxFrag Fragment */
4import type { RenderElement } from 'claude-code'
5
6import type { Kit } from '../../kit'
7import Layout from '../../layout'
8
9/**
10 * The pane while a message stands in for the list (ReplDiffSidebar's
11 * centered body: the first fetch, the empty state, the too-many and
12 * only-hidden states): the header block, the built-in's blank row under it,
13 * the message with the pickers under it, the pre-session line.
14 *
15 * With nothing listed below and the rows to hold it, the message's lines
16 * sit where the built-in centers them (half the spare rows above, rounded
17 * down; each wrapped line centered on its own), the pickers right under
18 * them and the pre-session line at the foot; otherwise it all stacks from
19 * the top, the pickers on the blank row the built-in leaves above the
20 * pre-session line (that blank row itself when there are none).
21 *
22 * @param kit the elements, the width, the body's rows
23 * @param pane the header block, the message's lines, the pickers, the
24 * pre-session line, and what is listed under it
25 * @returns the pane's tree
26 */
27export function messagePaneOf(
28 kit: Kit,
29 pane: {
30 top: readonly RenderElement[]
31 message: readonly string[]
32 controls: RenderElement | null
33 earlier: RenderElement | null
34 rest: readonly RenderElement[]
35 },
36): RenderElement {
37 const { Box, Text } = kit.ui
38 const { top, controls, earlier, rest } = pane
39 const lines = pane.message.flatMap(text =>
40 Layout.wrappedLines(Layout.sanitizeName(text), kit.columns),
41 )
42 const drawn = lines.map(line => <Text dimColor>{line}</Text>)
43 const controlRows = controls === null ? [] : [controls]
44 const earlierRows = earlier === null ? [] : [earlier]
45 const aboveEarlier =
46 controlRows.length > 0 || earlierRows.length === 0
47 ? controlRows
48 : [<Box height={1} />]
49 const middleRows = kit.rows - top.length - 1 - (earlier === null ? 0 : 3)
50 const above = Math.floor((middleRows - lines.length) / 2)
51 const isCentered =
52 rest.length === 0 &&
53 middleRows - above - lines.length >= controlRows.length
54
55 if (!isCentered) {
56 return (
57 <Box flexDirection="column">
58 {[
59 ...top,
60 <Box height={1} />,
61 ...drawn,
62 ...aboveEarlier,
63 ...earlierRows,
64 ...rest,
65 ]}
66 </Box>
67 )
68 }
69
70 const spacer = above > 0 ? [<Box height={above} />] : []
71 const foot = earlierRows.map(row => (
72 <Box flexDirection="column" marginTop={1} paddingBottom={1}>
73 {row}
74 </Box>
75 ))
76
77 return (
78 <Box flexDirection="column" height={kit.rows}>
79 {[
80 ...top,
81 <Box height={1} />,
82 <Box flexDirection="column" height={middleRows} alignItems="center">
83 {[...spacer, ...drawn, ...controlRows]}
84 </Box>,
85 ...foot,
86 ]}
87 </Box>
88 )
89}