@arcblock/terminal 3.1.17 → 3.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/styles.js CHANGED
@@ -1,134 +1,9 @@
1
1
  import e from "@emotion/styled";
2
- const t = e.div({
2
+ const r = e.div({
3
3
  // Base styles for .terminal-player
4
- display: "inline-block",
4
+ display: "block",
5
5
  position: "relative",
6
- fontSize: 0,
7
- // Terminal styles
8
- "& .terminal": { display: "inline-block" },
9
- "& .terminal .xterm .xterm-viewport": { overflowY: "hidden !important" },
10
- // Terminal frame
11
- "& .terminal-frame": { position: "relative" },
12
- // Reset styles for terminal divs
13
- "& .terminal div": {
14
- margin: 0,
15
- padding: 0,
16
- border: 0,
17
- outline: 0,
18
- fontWeight: "inherit",
19
- fontStyle: "inherit",
20
- fontSize: "100%",
21
- verticalAlign: "baseline"
22
- },
23
- // Window theme
24
- "&.terminal-window .terminal-frame": {
25
- borderRadius: 6,
26
- border: "1px solid #b3b3b3",
27
- boxShadow: "0px 0px 18px #b3b3b3",
28
- margin: 18,
29
- overflow: "hidden",
30
- "& .terminal-titlebar": {
31
- background: "#e8e8e8",
32
- borderBottom: "1px solid #b1aeb1",
33
- borderTop: "1px solid #f3f1f3",
34
- borderTopLeftRadius: 6,
35
- borderTopRightRadius: 6,
36
- color: "#3b4247",
37
- fontSize: 14,
38
- height: 22,
39
- lineHeight: "22px",
40
- position: "relative",
41
- textAlign: "center",
42
- width: "100%",
43
- "& .buttons": { left: 8, lineHeight: "0px", position: "absolute", top: 3.5 },
44
- "& .close-button": {
45
- background: "#ff5c5c",
46
- borderRadius: "50%",
47
- border: "1px solid #e33e41",
48
- display: "inline-block",
49
- height: 12,
50
- width: 12
51
- },
52
- "& .minimize-button": {
53
- background: "#ffbd4c",
54
- borderRadius: "50%",
55
- border: "1px solid #e09e3e",
56
- display: "inline-block",
57
- height: 12,
58
- marginLeft: 4,
59
- width: 12
60
- },
61
- "& .maximize-button": {
62
- background: "#00ca56",
63
- borderRadius: "50%",
64
- border: "1px solid #14ae46",
65
- display: "inline-block",
66
- height: 12,
67
- marginLeft: 4,
68
- width: 12
69
- }
70
- },
71
- "& .terminal-body": { backgroundColor: "#1d1d1d", padding: 10 }
72
- },
73
- // Floating theme
74
- "&.terminal-floating .terminal-frame": {
75
- backgroundColor: "#1d1d1d",
76
- borderRadius: 6,
77
- boxShadow: "0px 0px 18px #b3b3b3",
78
- margin: 18,
79
- overflow: "hidden",
80
- "& .terminal-titlebar": {
81
- color: "white",
82
- fontSize: 14,
83
- height: 34,
84
- lineHeight: "34px",
85
- position: "relative",
86
- textAlign: "center",
87
- width: "100%",
88
- "& .buttons": { left: 13, lineHeight: "0px", position: "absolute", top: 9 },
89
- "& .close-button": { background: "#ff5c5c", borderRadius: "50%", display: "inline-block", height: 15, width: 15 },
90
- "& .minimize-button": {
91
- background: "#ffbd4c",
92
- borderRadius: "50%",
93
- display: "inline-block",
94
- height: 15,
95
- lineHeight: "10px",
96
- marginLeft: 4,
97
- width: 15
98
- },
99
- "& .maximize-button": {
100
- background: "#00ca56",
101
- borderRadius: "50%",
102
- display: "inline-block",
103
- height: 15,
104
- lineHeight: "10px",
105
- marginLeft: 4,
106
- width: 15
107
- }
108
- },
109
- "& .terminal-body": { padding: 20 }
110
- },
111
- // Solid theme
112
- "&.terminal-solid .terminal-frame": {
113
- backgroundColor: "#1d1d1d",
114
- borderRadius: 6,
115
- boxShadow: "0px 0px 18px #b3b3b3",
116
- margin: 18,
117
- overflow: "hidden",
118
- "& .terminal-titlebar": {
119
- color: "white",
120
- fontSize: 14,
121
- position: "relative",
122
- textAlign: "center",
123
- width: "100%",
124
- "& .title": {
125
- margin: "15px 15px 15px",
126
- "&:empty": { display: "none" }
127
- },
128
- "& .buttons": { display: "none" }
129
- },
130
- "& .terminal-body": { padding: 20 }
131
- },
6
+ overflow: "hidden",
132
7
  // Player controls
133
8
  "& .controller": {
134
9
  background: "#45484d",
@@ -194,16 +69,21 @@ const t = e.div({
194
69
  "& .start svg": {
195
70
  cursor: "pointer",
196
71
  fill: "#eaeaea",
197
- height: 130,
72
+ width: 100,
73
+ height: 100,
198
74
  left: "50%",
199
75
  marginLeft: -65,
200
76
  marginTop: -65,
201
77
  position: "absolute",
202
78
  top: "50%",
203
- width: 130,
204
79
  zIndex: 20,
205
80
  filter: "drop-shadow(10px 10px 15px rgba(0, 0, 0, 0.4))",
206
- WebkitFilter: "drop-shadow(10px 10px 15px rgba(0, 0, 0, 0.4))"
81
+ WebkitFilter: "drop-shadow(10px 10px 15px rgba(0, 0, 0, 0.4))",
82
+ opacity: 0.6,
83
+ "&:hover": {
84
+ opacity: 0.8,
85
+ transition: "all 0.3s ease"
86
+ }
207
87
  },
208
88
  "&.small .start svg": { height: 60, marginLeft: -30, marginTop: -30, width: 60 },
209
89
  "&.framed .start svg": {
@@ -213,25 +93,31 @@ const t = e.div({
213
93
  OTransform: "translate(0px, 8px)",
214
94
  MsTransform: "translate(0px, 8px)"
215
95
  },
216
- "& .cover:hover + .start svg, & .start:hover svg": { fill: "white" },
217
96
  "&.started .cover, &.started .start": { display: "none" },
218
97
  "& .terminal-watermark": { zIndex: 99999 }
219
98
  }), o = e.div({
220
- // Xterm base styles
99
+ // Base xterm styles
221
100
  "& .xterm": {
222
- fontFeatureSettings: "'liga' 0",
101
+ cursor: "text",
223
102
  position: "relative",
224
103
  userSelect: "none",
225
- MsUserSelect: "none",
226
- WebkitUserSelect: "none",
227
- cursor: "text",
228
- "&.focus, &:focus": { outline: "none" },
229
- "&.enable-mouse-events": { cursor: "default" },
230
- "&.xterm-cursor-pointer": { cursor: "pointer" },
231
- "&.column-select.focus": { cursor: "crosshair" }
104
+ msUserSelect: "none",
105
+ webkitUserSelect: "none"
106
+ },
107
+ "& .xterm.focus, & .xterm:focus": {
108
+ outline: "none"
109
+ },
110
+ "& .xterm .xterm-helpers": {
111
+ position: "absolute",
112
+ top: 0,
113
+ // The z-index of the helpers must be higher than the canvases in order for IMEs to appear on top
114
+ zIndex: 5
232
115
  },
233
- "& .xterm .xterm-helpers": { position: "absolute", top: 0, zIndex: 5 },
234
116
  "& .xterm .xterm-helper-textarea": {
117
+ padding: 0,
118
+ border: 0,
119
+ margin: 0,
120
+ // Move textarea out of the screen to the far left, so that the cursor is not visible
235
121
  position: "absolute",
236
122
  opacity: 0,
237
123
  left: "-9999em",
@@ -239,34 +125,45 @@ const t = e.div({
239
125
  width: 0,
240
126
  height: 0,
241
127
  zIndex: -5,
128
+ // Prevent wrapping so the IME appears against the textarea at the correct position
242
129
  whiteSpace: "nowrap",
243
130
  overflow: "hidden",
244
131
  resize: "none"
245
132
  },
246
133
  "& .xterm .composition-view": {
134
+ // TODO: Composition position got messed up somewhere
247
135
  background: "#000",
248
- color: "#fff",
136
+ color: "#FFF",
249
137
  display: "none",
250
138
  position: "absolute",
251
139
  whiteSpace: "nowrap",
252
- zIndex: 1,
253
- "&.active": { display: "block" }
140
+ zIndex: 1
141
+ },
142
+ "& .xterm .composition-view.active": {
143
+ display: "block"
144
+ },
145
+ // '& .xterm .xterm-viewport': {
146
+ // // On OS X this is required in order for the scroll bar to appear fully opaque
147
+ // backgroundColor: 'transparent',
148
+ // overflowY: 'scroll',
149
+ // cursor: 'default',
150
+ // position: 'absolute',
151
+ // right: 0,
152
+ // left: 0,
153
+ // top: 0,
154
+ // bottom: 0,
155
+ // },
156
+ "& .xterm .xterm-screen": {
157
+ position: "relative"
254
158
  },
255
- "& .xterm .xterm-viewport": {
256
- backgroundColor: "#000",
257
- overflowY: "scroll",
258
- cursor: "default",
159
+ "& .xterm .xterm-screen canvas": {
259
160
  position: "absolute",
260
- right: 0,
261
161
  left: 0,
262
- top: 0,
263
- bottom: 0
162
+ top: 0
264
163
  },
265
- "& .xterm .xterm-screen": {
266
- position: "relative",
267
- "& canvas": { position: "absolute", left: 0, top: 0 }
164
+ "& .xterm .xterm-scroll-area": {
165
+ visibility: "hidden"
268
166
  },
269
- "& .xterm .xterm-scroll-area": { visibility: "hidden" },
270
167
  "& .xterm-char-measure-element": {
271
168
  display: "inline-block",
272
169
  visibility: "hidden",
@@ -275,20 +172,84 @@ const t = e.div({
275
172
  left: "-9999em",
276
173
  lineHeight: "normal"
277
174
  },
278
- "& .xterm .xterm-accessibility, & .xterm .xterm-message": {
175
+ "& .xterm.enable-mouse-events": {
176
+ // When mouse events are enabled (eg. tmux), revert to the standard pointer cursor
177
+ cursor: "default"
178
+ },
179
+ "& .xterm.xterm-cursor-pointer, & .xterm .xterm-cursor-pointer": {
180
+ cursor: "pointer"
181
+ },
182
+ "& .xterm.column-select.focus": {
183
+ // Column selection mode
184
+ cursor: "crosshair"
185
+ },
186
+ "& .xterm .xterm-accessibility:not(.debug), & .xterm .xterm-message": {
279
187
  position: "absolute",
280
188
  left: 0,
281
189
  top: 0,
282
190
  bottom: 0,
283
191
  right: 0,
284
192
  zIndex: 10,
193
+ color: "transparent",
194
+ pointerEvents: "none"
195
+ },
196
+ "& .xterm .xterm-accessibility-tree:not(.debug) *::selection": {
285
197
  color: "transparent"
286
198
  },
287
- "& .xterm .live-region": { position: "absolute", left: "-9999px", width: 1, height: 1, overflow: "hidden" },
288
- "& .xterm-dim": { opacity: 0.5 },
289
- "& .xterm-underline": { textDecoration: "underline" }
199
+ "& .xterm .xterm-accessibility-tree": {
200
+ userSelect: "text",
201
+ whiteSpace: "pre"
202
+ },
203
+ "& .xterm .live-region": {
204
+ position: "absolute",
205
+ left: "-9999px",
206
+ width: "1px",
207
+ height: "1px",
208
+ overflow: "hidden"
209
+ },
210
+ "& .xterm-dim": {
211
+ // Dim should not apply to background, so the opacity of the foreground color is applied
212
+ // explicitly in the generated class and reset to 1 here
213
+ opacity: "1 !important"
214
+ },
215
+ // Text decoration styles
216
+ "& .xterm-underline-1": { textDecoration: "underline" },
217
+ "& .xterm-underline-2": { textDecoration: "double underline" },
218
+ "& .xterm-underline-3": { textDecoration: "wavy underline" },
219
+ "& .xterm-underline-4": { textDecoration: "dotted underline" },
220
+ "& .xterm-underline-5": { textDecoration: "dashed underline" },
221
+ "& .xterm-overline": {
222
+ textDecoration: "overline"
223
+ },
224
+ "& .xterm-overline.xterm-underline-1": { textDecoration: "overline underline" },
225
+ "& .xterm-overline.xterm-underline-2": { textDecoration: "overline double underline" },
226
+ "& .xterm-overline.xterm-underline-3": { textDecoration: "overline wavy underline" },
227
+ "& .xterm-overline.xterm-underline-4": { textDecoration: "overline dotted underline" },
228
+ "& .xterm-overline.xterm-underline-5": { textDecoration: "overline dashed underline" },
229
+ "& .xterm-strikethrough": {
230
+ textDecoration: "line-through"
231
+ },
232
+ // Decoration styles
233
+ "& .xterm-screen .xterm-decoration-container .xterm-decoration": {
234
+ zIndex: 6,
235
+ position: "absolute"
236
+ },
237
+ "& .xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer": {
238
+ zIndex: 7
239
+ },
240
+ "& .xterm-decoration-overview-ruler": {
241
+ zIndex: 8,
242
+ position: "absolute",
243
+ top: 0,
244
+ right: 0,
245
+ pointerEvents: "none"
246
+ },
247
+ "& .xterm-decoration-top": {
248
+ zIndex: 2,
249
+ position: "relative"
250
+ }
290
251
  });
291
252
  export {
292
- t as PlayerRoot,
253
+ r as PlayerRoot,
293
254
  o as TerminalRoot
294
255
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/terminal",
3
- "version": "3.1.17",
3
+ "version": "3.1.18",
4
4
  "description": "A react wrapper for xterm allowing you to easily render a terminal in the browser",
5
5
  "keywords": [
6
6
  "react",
@@ -40,16 +40,16 @@
40
40
  "peerDependencies": {
41
41
  "react": "^19.0.0"
42
42
  },
43
- "gitHead": "5b5551ce69cf45e2bed8cc06fbb3592020b7618c",
43
+ "gitHead": "a145d1dd215444e7b65b8fa08cba2d8db513a94a",
44
44
  "dependencies": {
45
- "@arcblock/react-hooks": "3.1.17",
46
- "@arcblock/ux": "3.1.17",
45
+ "@arcblock/react-hooks": "3.1.18",
46
+ "@arcblock/ux": "3.1.18",
47
47
  "@emotion/react": "^11.14.0",
48
48
  "@emotion/styled": "^11.14.0",
49
+ "@xterm/addon-fit": "^0.10.0",
50
+ "@xterm/addon-web-links": "^0.11.0",
51
+ "@xterm/xterm": "^5.5.0",
49
52
  "ahooks": "^3.8.5",
50
- "lodash": "^4.17.21",
51
- "xterm": "4.19.0",
52
- "xterm-addon-fit": "^0.2.1",
53
- "xterm-addon-web-links": "^0.2.1"
53
+ "lodash": "^4.17.21"
54
54
  }
55
55
  }
package/src/Player.jsx CHANGED
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable react/no-unused-prop-types, no-console */
2
- import { useReducer, useState, useRef, useEffect, useCallback } from 'react';
2
+ import { useReducer, useRef, useEffect, useCallback } from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import { useSize } from 'ahooks';
5
4
  import isUndefined from 'lodash/isUndefined';
6
5
  import noop from 'lodash/noop';
7
6
 
@@ -19,7 +18,7 @@ import {
19
18
  defaultState,
20
19
  } from './util';
21
20
 
22
- export const PLAYER_FRAME_DELAY = 24;
21
+ export const PLAYER_FRAME_DELAY = 8;
23
22
 
24
23
  export default function Player({ ...rawProps }) {
25
24
  const props = Object.assign({}, rawProps);
@@ -49,13 +48,14 @@ export default function Player({ ...rawProps }) {
49
48
  cols: options.cols,
50
49
  rows: options.rows,
51
50
  cursorStyle: options.cursorStyle,
51
+ cursorBlink: options.cursorBlink ?? true,
52
52
  fontFamily: options.fontFamily,
53
53
  fontSize: options.fontSize,
54
54
  lineHeight: options.lineHeight,
55
55
  letterSpacing: options.letterSpacing,
56
56
  allowTransparency: true,
57
57
  scrollback: 0,
58
- theme: options.theme || {},
58
+ theme: options.enableTheme ? options.theme : {},
59
59
  };
60
60
 
61
61
  const stateReducer = (state, action) => {
@@ -85,39 +85,7 @@ export default function Player({ ...rawProps }) {
85
85
  const container = useRef(null);
86
86
  const animationRef = useRef(null);
87
87
  const startTimeRef = useRef(null);
88
- const [maxWidth, setMaxWidth] = useState(0);
89
- const size = useSize(document.body);
90
88
  const [state, dispatch] = useReducer(stateReducer, defaultState);
91
- const width = size?.width || 0;
92
-
93
- useEffect(() => {
94
- if (!terminal.current) {
95
- return;
96
- }
97
-
98
- try {
99
- const COLUMN_WIDTH = 972 / 121;
100
- const child = container.current.getBoundingClientRect();
101
- let containerWidth = child.x < 0 ? child.width + child.x : child.width;
102
- if (container.current.parentNode) {
103
- const parent = container.current.parentNode.getBoundingClientRect();
104
- if (child.width > parent.width) {
105
- containerWidth = parent.width;
106
- }
107
- }
108
-
109
- if (options.controls) {
110
- containerWidth -= 12;
111
- }
112
- const colContainer = Math.ceil(containerWidth / COLUMN_WIDTH);
113
- const cols = Math.min(Math.max(colContainer, 40), options.cols);
114
-
115
- terminal.current.resize(cols, options.rows);
116
- } catch (err) {
117
- // Do nothing
118
- }
119
- // eslint-disable-next-line react-hooks/exhaustive-deps
120
- }, [width, maxWidth]);
121
89
 
122
90
  // Render a frame with Promise-based approach
123
91
  const renderFrame = useCallback(
@@ -140,6 +108,21 @@ export default function Player({ ...rawProps }) {
140
108
  [frames, state.requireReset]
141
109
  );
142
110
 
111
+ // Render a frame synchronously for jump operations (no delay)
112
+ const renderFrameSync = useCallback(
113
+ (frameIndex) => {
114
+ const frame = frames[frameIndex];
115
+ if (frame && frame.content && terminal.current) {
116
+ if (state.requireReset) {
117
+ terminal.current.reset();
118
+ }
119
+ // Use synchronous write without callback for instant rendering
120
+ terminal.current.write(frame.content);
121
+ }
122
+ },
123
+ [frames, state.requireReset]
124
+ );
125
+
143
126
  // Emit a event
144
127
  const emitEvent = useCallback(
145
128
  (name) => {
@@ -151,21 +134,20 @@ export default function Player({ ...rawProps }) {
151
134
  );
152
135
 
153
136
  const doJump = useCallback(
154
- async (time) => {
137
+ (time) => {
155
138
  if (!terminal.current) return;
156
139
 
157
140
  terminal.current.reset();
158
141
  const toFrameIndex = findFrameAt(frames, time);
159
142
 
160
143
  if (toFrameIndex >= 0) {
161
- // Render all frames up to the target frame sequentially
144
+ // Render all frames up to the target frame synchronously for instant jump
162
145
  for (let i = 0; i <= toFrameIndex; i++) {
163
- // eslint-disable-next-line no-await-in-loop
164
- await renderFrame(i);
146
+ renderFrameSync(i);
165
147
  }
166
148
  }
167
149
  },
168
- [frames, renderFrame]
150
+ [frames, renderFrameSync]
169
151
  );
170
152
 
171
153
  const onJump = useCallback(
@@ -207,6 +189,9 @@ export default function Player({ ...rawProps }) {
207
189
 
208
190
  const onStart = useCallback(() => {
209
191
  if (state.isStarted === false) {
192
+ // 触发一下 resize,保证文字输出正常
193
+ terminal.current.resize();
194
+
210
195
  dispatch({ type: 'start' });
211
196
  if (terminal.current) {
212
197
  terminal.current.reset();
@@ -227,38 +212,15 @@ export default function Player({ ...rawProps }) {
227
212
  return false;
228
213
  }, [emitEvent]);
229
214
 
230
- const onPlay = useCallback(() => {
231
- if (state.currentFrame >= frames.length - 1) {
232
- // Reset to beginning if at the end
233
- dispatch({ type: 'reset', payload: { currentFrame: -1, currentTime: 0 } });
234
- if (terminal.current) {
235
- terminal.current.reset();
236
- }
237
- startTimeRef.current = null;
238
- // Start from beginning
239
- dispatch({ type: 'play', payload: { currentFrame: -1, currentTime: 0 } });
240
- } else {
241
- // Continue from current position
242
- startTimeRef.current = null; // Reset timing for accurate playback
243
- dispatch({ type: 'play' });
244
- }
245
-
246
- emitEvent('onPlay');
247
- return false;
248
- }, [state.currentFrame, frames.length, emitEvent]);
249
-
250
215
  // Render thumbnailTime
251
216
  useEffect(() => {
252
217
  if (!terminal.current) {
253
218
  return;
254
219
  }
255
- if (container.current) {
256
- try {
257
- setMaxWidth(container.current.getBoundingClientRect().width);
258
- } catch (e) {
259
- // Do nothing
260
- }
261
- }
220
+
221
+ // Focus terminal to ensure cursor is visible
222
+ terminal.current.focus();
223
+
262
224
  if (options.autoplay) {
263
225
  onStart();
264
226
  } else {
@@ -448,11 +410,6 @@ export default function Player({ ...rawProps }) {
448
410
  <span className="icon" />
449
411
  </div>
450
412
  )}
451
- {!state.isPlaying && state.isStarted && (
452
- <div className="play" onClick={onPlay} title="Play">
453
- <span className="icon" />
454
- </div>
455
- )}
456
413
  {!state.isPlaying && !state.isStarted && (
457
414
  <div className="play" onClick={onStart} title="Start">
458
415
  <span className="icon" />
package/src/Terminal.jsx CHANGED
@@ -2,9 +2,9 @@
2
2
  /* eslint-disable react/no-unused-class-component-methods */
3
3
  import React from 'react';
4
4
  import PropTypes from 'prop-types';
5
- import { Terminal as XTerm } from 'xterm';
6
- import { WebLinksAddon } from 'xterm-addon-web-links';
7
- import { FitAddon } from 'xterm-addon-fit';
5
+ import { Terminal as XTerm } from '@xterm/xterm';
6
+ import { WebLinksAddon } from '@xterm/addon-web-links';
7
+ import { FitAddon } from '@xterm/addon-fit';
8
8
  import debounce from 'lodash/debounce';
9
9
  import noop from 'lodash/noop';
10
10
  import { TerminalRoot } from './styles';
@@ -14,6 +14,8 @@ export default class Terminal extends React.Component {
14
14
 
15
15
  container = null;
16
16
 
17
+ shouldTriggerFitWhenWrite = false;
18
+
17
19
  componentDidMount() {
18
20
  const { value = '', options = {} } = this.props;
19
21
  this.fitAddon = new FitAddon();
@@ -31,15 +33,9 @@ export default class Terminal extends React.Component {
31
33
  this.xterm.write(value);
32
34
  }
33
35
 
34
- setTimeout(() => {
35
- if (this.xterm) {
36
- this.fitAddon.fit();
37
- }
38
- }, 0);
39
-
40
36
  this.debounceFit = debounce(() => {
41
37
  this.fitAddon.fit();
42
- }, 600);
38
+ }, 500);
43
39
 
44
40
  window.addEventListener('resize', this.debounceFit);
45
41
  }
@@ -75,6 +71,10 @@ export default class Terminal extends React.Component {
75
71
  write(data, cb) {
76
72
  if (this.xterm) {
77
73
  this.xterm.write(data, cb);
74
+ if (this.shouldTriggerFitWhenWrite) {
75
+ this.debounceFit();
76
+ this.shouldTriggerFitWhenWrite = false;
77
+ }
78
78
  }
79
79
  }
80
80
 
@@ -100,22 +100,29 @@ export default class Terminal extends React.Component {
100
100
  onRender(data);
101
101
  };
102
102
 
103
- resize(cols, rows) {
103
+ resize() {
104
104
  if (this.xterm) {
105
- this.xterm.resize(Math.round(cols), Math.round(rows));
105
+ const { cols, rows } = this.props.options;
106
+ this.shouldTriggerFitWhenWrite = true;
107
+ setTimeout(() => {
108
+ this.xterm.resize(Math.round(cols), Math.round(rows));
109
+ this.shouldTriggerFitWhenWrite = true;
110
+ }, 250);
106
111
  }
107
112
  }
108
113
 
109
114
  setOption(key, value) {
110
115
  if (this.xterm) {
111
- this.xterm.setOption(key, value);
116
+ // In xterm.js v5, use options object directly instead of setOption
117
+ this.xterm.options[key] = value;
112
118
  }
113
119
  }
114
120
 
115
121
  getOption(key) {
116
122
  if (this.xterm) {
117
- this.xterm.setOption(key);
123
+ return this.xterm.options[key];
118
124
  }
125
+ return undefined;
119
126
  }
120
127
 
121
128
  refresh() {