Description
The screen() helper accepts fullscreen: true to wrap the rendered component in <FullScreen>, but there's no way to pass props (like hideCursor) through to the underlying <FullScreen> component.
This forces consumers into one of two bad patterns:
-
Double wrapping — Set fullscreen: true AND render <FullScreen hideCursor> internally. This writes \x1B[?1049h (enter alt screen buffer) twice, causing terminal-dependent rendering bugs (blank screen on some terminals, content only visible in scrollback after quit).
-
Manual management — Set fullscreen: false and handle <FullScreen> internally, bypassing the framework's cleanup logic in the finally block.
Proposed API
fullscreen should accept boolean | FullScreenProps with discriminated typing:
// Simple toggle (current behavior)
screen({ fullscreen: true })
screen({ fullscreen: false })
// Object form — enables fullscreen with props forwarded to <FullScreen>
screen({ fullscreen: { hideCursor: true } })
The type should be a clean discriminated union:
type ScreenFullscreen = boolean | FullScreenProps
interface FullScreenProps {
readonly hideCursor?: boolean
// future props go here
}
When fullscreen is an object (truthy), it's treated as enabled and the object is spread as props onto <FullScreen>. When false, disabled. When true, enabled with defaults (current behavior, no breaking change).
Additionally, hideCursor should also be available as a root-level option on screen() as a convenience shorthand — both forms should work:
// Root-level shorthand
screen({ fullscreen: true, hideCursor: true })
// Object form (takes precedence if both specified)
screen({ fullscreen: { hideCursor: true } })
Current behavior
In render-BsTEEL-N.js, screen() wraps with a bare <FullScreen>:
jsx(FullScreen, { children: jsx(ScreenComponent, { ...ctx.args }) })
No props are forwarded.
Additional Context
Discovered while debugging a jog init blank screen issue in @joggr/cli — the init command had fullscreen: true in its screen config AND <FullScreen hideCursor> in the component, causing double alt-screen-buffer entry. Fix was to remove the internal <FullScreen> and accept losing hideCursor.
Description
The
screen()helper acceptsfullscreen: trueto wrap the rendered component in<FullScreen>, but there's no way to pass props (likehideCursor) through to the underlying<FullScreen>component.This forces consumers into one of two bad patterns:
Double wrapping — Set
fullscreen: trueAND render<FullScreen hideCursor>internally. This writes\x1B[?1049h(enter alt screen buffer) twice, causing terminal-dependent rendering bugs (blank screen on some terminals, content only visible in scrollback after quit).Manual management — Set
fullscreen: falseand handle<FullScreen>internally, bypassing the framework's cleanup logic in thefinallyblock.Proposed API
fullscreenshould acceptboolean | FullScreenPropswith discriminated typing:The type should be a clean discriminated union:
When
fullscreenis an object (truthy), it's treated as enabled and the object is spread as props onto<FullScreen>. Whenfalse, disabled. Whentrue, enabled with defaults (current behavior, no breaking change).Additionally,
hideCursorshould also be available as a root-level option onscreen()as a convenience shorthand — both forms should work:Current behavior
In
render-BsTEEL-N.js,screen()wraps with a bare<FullScreen>:No props are forwarded.
Additional Context
Discovered while debugging a
jog initblank screen issue in@joggr/cli— the init command hadfullscreen: truein its screen config AND<FullScreen hideCursor>in the component, causing double alt-screen-buffer entry. Fix was to remove the internal<FullScreen>and accept losinghideCursor.