github vadimdemedes/ink v8.0.0

3 hours ago

Breaking

  • Require React 19.3+ 7829102
  • minWidth and maxWidth on <Box> now only accept numbers (#1029) 7cd7fd9
    • Percentage strings were never documented as supported, and Yoga resolved them against the wrong ancestor
  • stdin, stdout, and stderr are now typed as generic Node.js streams (#981) eb82d8f
    • This applies to the render() options and to useStdin(), useStdout(), and useStderr(). TTY-only properties like stdout.columns are no longer part of the types
  • useInput no longer receives unrecognized terminal control sequences (#1014) c76893e
    • Mouse reports, focus in/out events, cursor position reports, and other terminal replies used to arrive in input with the ESC stripped, as if typed. They are now dropped

New

  • Add contentOffsetX and contentOffsetY props to <Box> for building scrollable views (#765) 3ba5828
  • Add clientWidth and clientHeight to useBoxMetrics() and measureElement() (#988) 3ba5828
    • The element size excluding borders, which is the space its content can occupy
  • Accept any Node.js stream for the stdin, stdout, and stderr options of render() (#981) eb82d8f
    • For example, PassThrough or other Readable/Writable streams. Raw mode is used only when stdin is a TTY with setRawMode()
  • Skip unchanged line prefixes in incrementalRendering mode (#1036) 91eb50a
    • Only the changed part of a line is written, which reduces output and flicker
  • Drop the ws dependency in favor of the native WebSocket for React DevTools (#976) 33567ed
  • Recognize application keypad Enter as key.return b73ebf4

Fixes

Rendering

  • Preserve scrollback when clearing the viewport (#994) fe1d123
  • Preserve terminal history after clear() 494ebeb
  • Restore the unchanged frame when rerendering after clear() fc358c2
  • Redraw the frame when the terminal loses rows (#1025) f603aeb
  • Keep content above the frame when rows shrink while the cursor is shown (#1031) c800284
  • Keep the cursor on the last line when output has no trailing newline (#982) cdc18fa
  • Restore the terminal cursor below the frame on exit 06385e9
  • Preserve the cursor position when its component skips rendering 013feb2
  • Fix incremental rendering of single-line updates, new blank rows, and changed rows (#1039) 9a501e4 507c0c9 509ea75
  • Fix overflow clipping when both the shorthand and an explicit axis are set, and preserve <Transform> line indices when clipping 4f3c7aa
  • Fix background color inheritance for <Static> and nested <Text> 753a5f8
  • Fix fractional percentages being truncated in layout sizes, and restore layout defaults when style props are undefined 274b15a
  • Preserve visibility across Suspense transitions fc685bc
  • Call onRender after the frame is written 83d7de5

<Static>

  • Stop replaying <Static> output on full-clear frames (#1005) d661543
  • Replay <Static> output when resuming re-enters the alternate screen (#1012) 9235028
  • Fix repeated padding, ignored margins, and output inside hidden ancestors 793fe59
  • Keep <Static> output after abandoned concurrent renders 8678b76
  • Reset captured <Static> output when its identity changes cfdd9e6
  • Preserve blank <Static> rows f6b2620 c0fa4ef 5911f44
  • Fix dangling staticNode reference on indirect subtree removal (#979) 5448e6b

Text

  • Truncate each line of multi-line text separately (#1006) 4b44934
  • Keep text at its natural width when there is no room to wrap (#1022) 36f5624
  • Fix multi-line <Text> vanishing when it starts above the top of the output (#1001) 77aba4a
  • Strip control characters (except tab and newline) from text content (#1020) 405f751 2fbc26a
  • Expand tabs, and fix CRLF text overwriting box borders and zero-width spaces overwriting surrounding output 32dc266
  • Preserve ANSI styles across explicit newlines b419e5c
  • Preserve combining marks across nested text styles 80b1c9c
  • Normalize colon and C1 SGR sequences before layout (#1019) b0dfd61 9dfe137 7fe1577
  • Preserve styles and columns on clipped or overwritten wide characters f7e57a5 064df65
  • Remeasure text when its wrapping mode or <Transform> wrap points change fc685bc 9c323f6
  • Preserve the available width when measuring truncated text 1e57b23
  • Fix crashes from invalid color names, and whitespace handling in RGB colors 3be9ed7

Input

  • Fix legacy keyboard modifiers, modified SS3 keys, and Kitty keyboard parsing and detection 2ee828c
    • reportAssociatedText now enables reportAllKeysAsEscapeCodes automatically
  • Handle Ctrl+C that arrives together with ordinary input 13707d2
  • Do not mutate the caller's buffer when parsing Meta keys 36d7739
  • Keep onKittyQueryResponse stable across rerender() calls (#1007) 70beca5
  • Defer input hook side effects while the terminal is suspended (#1016) 61004d7
  • Make suspendTerminal() handles idempotent, and do not restore input modes that were released or belong to an unmounted app a7297c4 b35e89a c613707
  • Preserve output during non-interactive terminal suspension a6789fb

Focus

  • Treat components that share a focus ID as one Tab stop (#1026) 02ae1e5
  • Make disableFocus() blur the focused component as documented, and respect it when new components auto-focus d130588
  • Prevent collisions in automatically generated focus IDs d130588
  • Treat an empty string as a valid focus ID f6f7dc7

Other

  • Fix screen-reader output: semantic text and labels, empty <Transform> labels, rewrapping when the terminal widens, and restoring output after console writes (#1028) f480301 bebfe2d
  • Fix error source excerpts for file URLs and multiline messages, and treat non-Error throws as rendering failures 81e2451
  • Fix renderToString() swallowing thrown undefined, and run effect cleanup when output rendering fails 9f7c1d0
  • Fix useWindowSize() missing resizes before it subscribes fab670b
  • Track box metrics when a child attaches the ref after mount 53244dc
  • Reset useAnimation() values while paused f25d312
  • Use defaults for render() options that are undefined 659249d
  • Fix unbounded text caches (#986) ad9e3ea
  • Fix wrapText cache returning results for the wrong text or width (#998) 3809acc
  • Free the root Yoga node on unmount (#999) 064b4f6
  • Avoid retaining an exit listener when calling waitUntilExit() after unmount 1fcd380

Migration guide

React 19.3

Upgrade react (and @types/react) to 19.3 or later.

minWidth and maxWidth

Use a number. If you need a relative minimum or maximum width, compute it from useWindowSize() or useBoxMetrics() of the parent.

-<Box minWidth="50%">
+<Box minWidth={Math.floor(columns / 2)}>

Stream types

useStdout().stdout is now typed as NodeJS.WritableStream, so TTY properties like columns and rows are no longer available in the types. Use useWindowSize() instead, which also re-renders on resize.

-const {stdout} = useStdout();
-const width = stdout.columns;
+const {columns: width} = useWindowSize();

Control sequences in useInput

If your useInput handler parsed mouse reports, focus events, or other terminal replies from input, it will no longer receive them. Keys that Ink recognizes, including Kitty keyboard protocol events, are not affected.


v7.1.1...v8.0.0

Don't miss a new ink release

NewReleases is sending notifications on new releases.