Skip to content

fix(web): qualify JSX.Element for React 19 in the design-system types (HT-97) - #111

Merged
zaridan merged 1 commit into
mainfrom
feat/ht-97-jsx-namespace
Jul 20, 2026
Merged

fix(web): qualify JSX.Element for React 19 in the design-system types (HT-97)#111
zaridan merged 1 commit into
mainfrom
feat/ht-97-jsx-namespace

Conversation

@zaridan

@zaridan zaridan commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Closes HT-97. Found by CodeRabbit on #105.

The bug

Every .d.ts under web/src/components/ds/ declared its return type as the global JSX.Element. React 19 removed that namespace, and this repo runs react / @types/react ^19.2.4 — so all 34 declarations resolved to nothing.

tsc --noEmit --types react  (ds/**/*.d.ts, WITHOUT --skipLibCheck)
  before → exit 2, 29 × error TS2503: Cannot find namespace 'JSX'
  after  → exit 0, 0 errors

Why CI never caught it: web/tsconfig.json sets skipLibCheck: true, which skips declaration-file checking altogether. Build and typecheck were green over broken types the entire time. Nothing was breaking at runtime — the cost was that every consumer and editor got no usable return type from the design system's API contract.

Fixed upstream first

Per the bidirectional policy in CLAUDE.md: these files are byte-verbatim copies of the Claude Design project, so editing them here would have broken the verbatim invariant on 21 files. All 26 upstream .d.ts were fixed — including the five components/app/ screens that exist only in the design project — and the 21 that mirror into ds/ were re-pulled.

React.JSX.Element, not an added import

These files already use React.ReactNode and React.CSSProperties off the UMD global without importing React, and those resolve fine — only the bare JSX namespace didn't. Qualifying it keeps the house style untouched and adds no imports.

Verification

Check Result
tsc over ds/**/*.d.ts without --skipLibCheck exit 0, 0 errors (was 29)
Diff contains any non-JSX.Element line none
21 files byte-identical to the design project after re-pull 21/21
Upload read back and compared before re-pulling 26/26 stuck
./node_modules/.bin/biome check . 0
npm run typecheck (web) 0
npm run build (web) 0

The read-back step is deliberate: in HT-94 a write_files returned success and silently did not apply, which only surfaced later during a byte-comparison. Success from that call is not proof it landed.

Not in this PR

skipLibCheck: true is what hid this. Turning it off may surface unrelated third-party noise, so it's a separate judgement call rather than a drive-by change here.

⚠️ Reviewer note: npx biome in this repo resolves to an unrelated stub package at 0.3.3 and exits 0 having processed zero files. The real binary is ./node_modules/.bin/biome at the repo root, which is what produced the result above.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • TypeScript Improvements
    • Updated component type declarations to use React’s namespaced JSX element type.
    • Improved compatibility with modern React and TypeScript configurations without changing component behavior, props, or user-facing functionality.

… (HT-97)

Every .d.ts under web/src/components/ds/ declared its return type as the
GLOBAL `JSX.Element`. React 19 removed that namespace, and this repo runs
react / @types/react ^19.2.4, so those 34 declarations resolved to nothing.

CI never caught it because web/tsconfig.json sets skipLibCheck: true, which
skips declaration-file checking entirely — the build and typecheck were
green over broken types the whole time. Found by CodeRabbit on PR #105.

Fixed UPSTREAM FIRST in the Claude Design project, then re-pulled verbatim,
per the bidirectional policy in CLAUDE.md — editing these copies directly
would have broken the verbatim invariant on 21 files. All 26 upstream .d.ts
were fixed (including the five components/app/ screens that live only in the
design project); the 21 that mirror into ds/ came back down here.

`React.JSX.Element` rather than an added import: these files already use
`React.ReactNode` and `React.CSSProperties` off the UMD global without
importing React, and those resolve fine — only the bare `JSX` namespace did
not. This keeps the house style unchanged.

Verified:
- tsc --noEmit --types react over ds/**/*.d.ts WITHOUT --skipLibCheck:
  exit 0, 0 errors (was exit 2, 29 x TS2503 "Cannot find namespace 'JSX'")
- the diff contains no line that isn't a JSX.Element qualification
- all 21 files byte-identical to the design project after the re-pull
- upload read back and compared before re-pulling, since a write_files
  reporting success is not proof it applied (learned the hard way in HT-94)

Gates (each on its own exit code): biome check . = 0, npm run typecheck = 0,
npm run build = 0.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ec4dc37d-2bad-4379-978b-eb847bab2550

📥 Commits

Reviewing files that changed from the base of the PR and between d53f482 and ca37759.

📒 Files selected for processing (21)
  • web/src/components/ds/core/Avatar.d.ts
  • web/src/components/ds/core/Button.d.ts
  • web/src/components/ds/core/CommandMenu.d.ts
  • web/src/components/ds/core/CredentialRow.d.ts
  • web/src/components/ds/core/DropdownMenu.d.ts
  • web/src/components/ds/core/EmptyState.d.ts
  • web/src/components/ds/core/IconButton.d.ts
  • web/src/components/ds/core/Kbd.d.ts
  • web/src/components/ds/core/MenuItem.d.ts
  • web/src/components/ds/core/Skeleton.d.ts
  • web/src/components/ds/core/SnoozePicker.d.ts
  • web/src/components/ds/core/SplitButton.d.ts
  • web/src/components/ds/core/StatusPill.d.ts
  • web/src/components/ds/core/TagChip.d.ts
  • web/src/components/ds/core/TextInput.d.ts
  • web/src/components/ds/core/Toast.d.ts
  • web/src/components/ds/core/primitives-support.d.ts
  • web/src/components/ds/inbox/ConversationRow.d.ts
  • web/src/components/ds/inbox/FolderItem.d.ts
  • web/src/components/ds/inbox/MessageBand.d.ts
  • web/src/components/ds/inbox/ToolbarBand.d.ts

📝 Walkthrough

Walkthrough

All listed design-system .d.ts declarations now return React.JSX.Element instead of JSX.Element. Props, parameters, component behavior, and helper signatures remain unchanged.

Changes

React JSX declaration alignment

Layer / File(s) Summary
Core component declarations
web/src/components/ds/core/*.d.ts
Core components and primitive helpers now declare React.JSX.Element return types while preserving existing props and parameters.
Inbox component declarations
web/src/components/ds/inbox/*.d.ts
Inbox components now declare React.JSX.Element return types without changing their props.-->

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the React 19 JSX.Element typing update across design-system declaration files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ht-97-jsx-namespace

Comment @coderabbitai help to get the list of available commands.

@zaridan
zaridan merged commit 382dd14 into main Jul 20, 2026
5 checks passed
@zaridan
zaridan deleted the feat/ht-97-jsx-namespace branch July 20, 2026 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant