@@ -14,6 +14,7 @@ import {
1414} from "@/features/channels/ui/markdownDocFocus" ;
1515import { useEscapeKey } from "@/shared/hooks/useEscapeKey" ;
1616import { useIsThreadPanelOverlay } from "@/shared/hooks/use-mobile" ;
17+ import { cn } from "@/shared/lib/cn" ;
1718import {
1819 AuxiliaryPanel ,
1920 AuxiliaryPanelBody ,
@@ -37,6 +38,8 @@ type MarkdownDocPanelProps = {
3738 url : string ;
3839 /** Human-readable filename from the imeta `filename` field. */
3940 filename : string ;
41+ /** Fill a parent focus drawer and center the document reading column. */
42+ isFocusMode ?: boolean ;
4043 isSinglePanelView ?: boolean ;
4144 layout ?: "standalone" | "split" ;
4245 onClose : ( ) => void ;
@@ -68,6 +71,7 @@ function decodeErrorMessage(kind: "too-large" | "binary"): string {
6871export function MarkdownDocPanel ( {
6972 url,
7073 filename,
74+ isFocusMode = false ,
7175 isSinglePanelView = false ,
7276 layout = "standalone" ,
7377 onClose,
@@ -125,7 +129,8 @@ export function MarkdownDocPanel({
125129
126130 return (
127131 < AuxiliaryPanel
128- isSinglePanelView = { isSinglePanelView }
132+ className = { isFocusMode ? "w-full" : undefined }
133+ isSinglePanelView = { isFocusMode || isSinglePanelView }
129134 layout = { layout }
130135 onClose = { onClose }
131136 testId = "markdown-doc-panel"
@@ -155,13 +160,21 @@ export function MarkdownDocPanel({
155160 </ AuxiliaryPanelHeader >
156161 }
157162 >
158- < AuxiliaryPanelBody className = "flex min-h-0 flex-col" panelPadding >
163+ < AuxiliaryPanelBody
164+ className = "flex min-h-0 flex-col"
165+ panelPadding = { ! isFocusMode }
166+ >
159167 { /* The view picker gets its own pinned row below the title: sharing
160168 the title row squeezed the filename out, and the header chrome
161169 band overlays anything placed directly after it in the header
162170 slot — so the row lives inside the chrome-padded body instead. */ }
163171 { decoded ?. kind === "ok" ? (
164- < div className = "flex shrink-0 items-center px-4 pb-2" >
172+ < div
173+ className = { cn (
174+ "flex w-full shrink-0 items-center px-4 pb-2" ,
175+ isFocusMode && "mx-auto max-w-[55rem]" ,
176+ ) }
177+ >
165178 < SegmentedControl
166179 legend = "Document view"
167180 onValueChange = { setView }
@@ -174,43 +187,45 @@ export function MarkdownDocPanel({
174187 </ div >
175188 ) : null }
176189 < div className = "min-h-0 flex-1 overflow-y-auto px-4 pb-6" >
177- { docQuery . isPending ? (
178- < div
179- className = "flex items-center justify-center py-12"
180- data-testid = "markdown-doc-loading"
181- >
182- < Loader2 className = "h-5 w-5 animate-spin text-muted-foreground/70" />
183- </ div >
184- ) : errorMessage !== null ? (
185- < div className = "flex flex-col items-center gap-3 py-12 text-center" >
186- < p className = "text-sm text-muted-foreground" > { errorMessage } </ p >
187- < Button onClick = { handleDownload } size = "sm" variant = "secondary" >
188- < Download className = "mr-1.5 h-4 w-4" />
189- Download file
190- </ Button >
191- </ div >
192- ) : decoded ?. kind === "ok" ? (
193- view === "preview" ? (
194- < Markdown
195- blockCode
196- className = "pt-3 text-sm"
197- content = { decoded . text }
198- hardLineBreaks = { false }
199- />
200- ) : (
201- < pre
202- className = "overflow-x-auto pt-3 text-xs leading-relaxed"
203- data-testid = "markdown-doc-code"
190+ < div className = { cn ( "w-full" , isFocusMode && "mx-auto max-w-[55rem]" ) } >
191+ { docQuery . isPending ? (
192+ < div
193+ className = "flex items-center justify-center py-12"
194+ data-testid = "markdown-doc-loading"
204195 >
205- { /* Shiki's synchronous-tokenization guard caps highlighting at
206- 150 lines; longer documents render as plain text here. */ }
207- < SyntaxHighlightedCode
208- code = { decoded . text }
209- language = "markdown"
196+ < Loader2 className = "h-5 w-5 animate-spin text-muted-foreground/70" />
197+ </ div >
198+ ) : errorMessage !== null ? (
199+ < div className = "flex flex-col items-center gap-3 py-12 text-center" >
200+ < p className = "text-sm text-muted-foreground" > { errorMessage } </ p >
201+ < Button onClick = { handleDownload } size = "sm" variant = "secondary" >
202+ < Download className = "mr-1.5 h-4 w-4" />
203+ Download file
204+ </ Button >
205+ </ div >
206+ ) : decoded ?. kind === "ok" ? (
207+ view === "preview" ? (
208+ < Markdown
209+ blockCode
210+ className = "pt-3 text-sm"
211+ content = { decoded . text }
212+ hardLineBreaks = { false }
210213 />
211- </ pre >
212- )
213- ) : null }
214+ ) : (
215+ < pre
216+ className = "overflow-x-auto pt-3 text-xs leading-relaxed"
217+ data-testid = "markdown-doc-code"
218+ >
219+ { /* Shiki's synchronous-tokenization guard caps highlighting at
220+ 150 lines; longer documents render as plain text here. */ }
221+ < SyntaxHighlightedCode
222+ code = { decoded . text }
223+ language = "markdown"
224+ />
225+ </ pre >
226+ )
227+ ) : null }
228+ </ div >
214229 </ div >
215230 </ AuxiliaryPanelBody >
216231 </ AuxiliaryPanel >
0 commit comments