Skip to content

Commit 567cdbb

Browse files
committed
Upgrade to react 19
1 parent 6990d67 commit 567cdbb

File tree

15 files changed

+91
-79
lines changed

15 files changed

+91
-79
lines changed

bun.lock

Lines changed: 14 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"zustand": "^5.0.8"
5555
},
5656
"devDependencies": {
57-
"@types/react": "^18.3.12",
57+
"@types/react": "19.2.14",
5858
"@types/react-reconciler": "^0.32.0",
5959
"react-dom": "^19.0.0",
6060
"strip-ansi": "^7.1.2"

cli/src/components/blocks/agent-branch-item.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ export const AgentBranchItem = memo((props: AgentBranchItemProps) => {
8080
}
8181

8282
if (React.isValidElement(value)) {
83+
const elProps = value.props as Record<string, unknown>
8384
if (value.type === React.Fragment) {
84-
return isTextRenderable(value.props.children)
85+
return isTextRenderable(elProps.children as ReactNode)
8586
}
8687

8788
if (typeof value.type === 'string') {
@@ -90,7 +91,7 @@ export const AgentBranchItem = memo((props: AgentBranchItemProps) => {
9091
value.type === 'strong' ||
9192
value.type === 'em'
9293
) {
93-
return isTextRenderable(value.props.children)
94+
return isTextRenderable(elProps.children as ReactNode)
9495
}
9596

9697
return false

cli/src/components/clickable.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ export function makeTextUnselectable(node: ReactNode): ReactNode {
2828

2929
if (!isValidElement(node)) return node
3030

31-
const el = node as ReactElement
31+
const el = node as ReactElement<{ children?: ReactNode; [key: string]: unknown }>
3232
const type = el.type
3333

3434
// Ensure text and span nodes are not selectable
3535
if (typeof type === 'string' && (type === 'text' || type === 'span')) {
3636
const nextProps = { ...el.props, selectable: false }
37-
const nextChildren = el.props?.children ? makeTextUnselectable(el.props.children) : el.props?.children
37+
const nextChildren = el.props.children ? makeTextUnselectable(el.props.children) : el.props.children
3838
return cloneElement(el, nextProps, nextChildren)
3939
}
4040

4141
// Recurse into other host elements and components' children
42-
const nextChildren = el.props?.children ? makeTextUnselectable(el.props.children) : el.props?.children
42+
const nextChildren = el.props.children ? makeTextUnselectable(el.props.children) : el.props.children
4343
return cloneElement(el, el.props, nextChildren)
4444
}
4545

cli/src/components/tools/tool-call-item.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ const isTextRenderable = (value: ReactNode): boolean => {
3333
}
3434

3535
if (React.isValidElement(value)) {
36+
const elProps = value.props as Record<string, unknown>
3637
if (value.type === React.Fragment) {
37-
return isTextRenderable(value.props.children)
38+
return isTextRenderable(elProps.children as ReactNode)
3839
}
3940

4041
if (typeof value.type === 'string') {
@@ -43,7 +44,7 @@ const isTextRenderable = (value: ReactNode): boolean => {
4344
value.type === 'strong' ||
4445
value.type === 'em'
4546
) {
46-
return isTextRenderable(value.props.children)
47+
return isTextRenderable(elProps.children as ReactNode)
4748
}
4849

4950
return false

cli/src/types/react19-compat.d.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* React 19 compatibility shim for OpenTUI JSX types.
3+
*
4+
* OpenTUI's JSX namespace defines `type Element = React.ReactNode`.
5+
* In React 19, `FunctionComponent` returns `ReactNode | Promise<ReactNode>`,
6+
* but `Promise<ReactNode>` is not assignable to `ReactNode`.
7+
*
8+
* This augmentation adds a narrower call signature to `FunctionComponent`
9+
* that returns just `ReactNode`. Due to TypeScript's interface merging rules,
10+
* the later declaration's overloads have higher precedence, so the narrower
11+
* signature is resolved first — fixing all `React.FC` JSX compatibility errors.
12+
*/
13+
import 'react'
14+
15+
declare module 'react' {
16+
interface FunctionComponent<P = {}> {
17+
(props: P): ReactNode
18+
}
19+
}

0 commit comments

Comments
 (0)