| 1 | import { lazy, Suspense, type ComponentProps, type KeyboardEvent, type PointerEvent } from "react"; |
| 2 | import { StatusBar } from "../components/StatusBar"; |
| 3 | import type { Translator } from "../lib/i18n"; |
| 4 | |
| 5 | const TerminalPanel = lazy(() => import("../components/TerminalPanel").then((module) => ({ default: module.TerminalPanel }))); |
| 6 | |
| 7 | export type AppBottomRegionsProps = { |
| 8 | terminal: { |
| 9 | surfaceVisible?: boolean; |
| 10 | open: boolean; |
| 11 | contentVisible: boolean; |
| 12 | remoteSurface: boolean; |
| 13 | t: Translator; |
| 14 | panel: ComponentProps<typeof TerminalPanel>; |
| 15 | resizer: { |
| 16 | min: number; |
| 17 | max: number; |
| 18 | value: number; |
| 19 | onPointerDown: (event: PointerEvent<HTMLButtonElement>) => void; |
| 20 | onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void; |
| 21 | onReset: () => void; |
| 22 | }; |
| 23 | }; |
| 24 | status?: ComponentProps<typeof StatusBar>; |
| 25 | }; |
| 26 | |
| 27 | /** Bottom shell surfaces remain mounted according to their original lifecycle. */ |
| 28 | export function AppBottomRegions({ terminal, status }: AppBottomRegionsProps) { |
| 29 | return ( |
| 30 | <> |
| 31 | <aside className="terminal-drawer" aria-label={terminal.t("terminal.title")} aria-hidden={!terminal.open} inert={!terminal.open ? true : undefined}> |
| 32 | {!terminal.remoteSurface && terminal.contentVisible && ( |
| 33 | <Suspense fallback={<div className="terminal-empty"><span className="terminal-empty__spinner" />{terminal.t("terminal.loading")}</div>}> |
| 34 | <TerminalPanel {...terminal.panel} /> |
| 35 | </Suspense> |
| 36 | )} |
| 37 | </aside> |
| 38 | {terminal.surfaceVisible !== false && <button |
| 39 | className="terminal-drawer-resizer" type="button" role="separator" aria-orientation="horizontal" |
| 40 | aria-label={terminal.t("terminal.resize")} aria-valuemin={terminal.resizer.min} |
| 41 | aria-valuemax={terminal.resizer.max} aria-valuenow={terminal.resizer.value} |
| 42 | aria-hidden={!terminal.open} tabIndex={terminal.open ? 0 : -1} |
| 43 | onPointerDown={terminal.resizer.onPointerDown} onKeyDown={terminal.resizer.onKeyDown} |
| 44 | onDoubleClick={terminal.resizer.onReset} |
| 45 | />} |
| 46 | {status && <StatusBar {...status} />} |
| 47 | </> |
| 48 | ); |
| 49 | } |
| 50 |