11import { type ITerminalAddon , type ITerminalInitOnlyOptions , type ITerminalOptions , Terminal } from '@xterm/xterm'
22import '@xterm/xterm/css/xterm.css'
3- import { type ComponentPropsWithoutRef , useEffect , useRef , useState } from 'react'
3+ import { useEffect , useRef , useState , type ComponentPropsWithoutRef } from 'react'
44
55export interface UseXTermProps {
66 addons ?: ITerminalAddon [ ]
@@ -22,48 +22,42 @@ export interface UseXTermProps {
2222
2323export function useXTerm ( { options, addons, listeners } : UseXTermProps = { } ) {
2424 const terminalRef = useRef < HTMLDivElement > ( null )
25+ const listenersRef = useRef < UseXTermProps [ 'listeners' ] > ( listeners )
2526 const [ terminalInstance , setTerminalInstance ] = useState < Terminal | null > ( null )
2627
28+ // Keep the latest version of listeners without retriggering the effect
29+ useEffect ( ( ) => {
30+ listenersRef . current = listeners
31+ } , [ listeners ] )
32+
2733 useEffect ( ( ) => {
2834 const instance = new Terminal ( {
2935 fontFamily : 'operator mono,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace' ,
3036 fontSize : 14 ,
31- theme : {
32- background : '#101420' ,
33- } ,
37+ theme : { background : '#101420' } ,
3438 cursorStyle : 'underline' ,
3539 cursorBlink : false ,
3640 ...options ,
3741 } )
3842
39- // Load addons if the prop exists
40- if ( addons ) {
41- addons . forEach ( ( addon ) => {
42- instance . loadAddon ( addon )
43- } )
44- }
45-
46- // Listeners
47- if ( listeners ) {
48- if ( listeners . onBinary ) instance . onBinary ( listeners . onBinary )
49- if ( listeners . onCursorMove ) instance . onCursorMove ( listeners . onCursorMove )
50- if ( listeners . onLineFeed ) instance . onLineFeed ( listeners . onLineFeed )
51- if ( listeners . onScroll ) instance . onScroll ( listeners . onScroll )
52- if ( listeners . onSelectionChange ) instance . onSelectionChange ( listeners . onSelectionChange )
53- if ( listeners . onRender ) instance . onRender ( listeners . onRender )
54- if ( listeners . onResize ) instance . onResize ( listeners . onResize )
55- if ( listeners . onTitleChange ) instance . onTitleChange ( listeners . onTitleChange )
56- if ( listeners . onKey ) instance . onKey ( listeners . onKey )
57- if ( listeners . onData ) instance . onData ( listeners . onData )
43+ // Load optional addons
44+ addons ?. forEach ( ( addon ) => instance . loadAddon ( addon ) )
5845
59- // Add Custom Key Event Handler
60- if ( listeners . customKeyEventHandler ) {
61- instance . attachCustomKeyEventHandler ( listeners . customKeyEventHandler )
62- }
63- }
46+ // Register event listeners from the ref
47+ const l = listenersRef . current
48+ l ?. onBinary && instance . onBinary ( l . onBinary )
49+ l ?. onCursorMove && instance . onCursorMove ( l . onCursorMove )
50+ l ?. onLineFeed && instance . onLineFeed ( l . onLineFeed )
51+ l ?. onScroll && instance . onScroll ( l . onScroll )
52+ l ?. onSelectionChange && instance . onSelectionChange ( l . onSelectionChange )
53+ l ?. onRender && instance . onRender ( l . onRender )
54+ l ?. onResize && instance . onResize ( l . onResize )
55+ l ?. onTitleChange && instance . onTitleChange ( l . onTitleChange )
56+ l ?. onKey && instance . onKey ( l . onKey )
57+ l ?. onData && instance . onData ( l . onData )
58+ l ?. customKeyEventHandler && instance . attachCustomKeyEventHandler ( l . customKeyEventHandler )
6459
6560 if ( terminalRef . current ) {
66- // Mount terminal
6761 instance . open ( terminalRef . current )
6862 instance . focus ( )
6963 }
@@ -74,23 +68,7 @@ export function useXTerm({ options, addons, listeners }: UseXTermProps = {}) {
7468 instance . dispose ( )
7569 setTerminalInstance ( null )
7670 }
77- } , [
78- terminalRef ,
79- options ,
80- addons ,
81- listeners ,
82- listeners ?. onBinary ,
83- listeners ?. onCursorMove ,
84- listeners ?. onData ,
85- listeners ?. onKey ,
86- listeners ?. onLineFeed ,
87- listeners ?. onScroll ,
88- listeners ?. onSelectionChange ,
89- listeners ?. onRender ,
90- listeners ?. onResize ,
91- listeners ?. onTitleChange ,
92- listeners ?. customKeyEventHandler ,
93- ] )
71+ } , [ options , addons ] )
9472
9573 return {
9674 ref : terminalRef ,
0 commit comments