feat: migrate TUI layer from React to SolidJS#53
Merged
platypusrex merged 3 commits intomainfrom Feb 16, 2026
Merged
Conversation
Migrate all TUI components, hooks, and infrastructure from @opentui/react to @opentui/solid. This is a complete rewrite of the rendering layer while preserving all existing functionality. Build infrastructure: - Swap deps: solid-js, @opentui/solid replacing react, @opentui/react - tsconfig: jsx preserve, jsxImportSource @opentui/solid - New build.ts using @opentui/solid/bun-plugin - Delete react-compiler.preload.ts Foundation: - ThemeProvider: store-based context for reactive theme switching - All hooks converted from useState/useEffect/useRef to createSignal/createEffect - Signal accessors replace ref-mirror pattern throughout Components (16 files): - All components rewritten for Solid's run-once component model - <For>/<Index>/<Show>/<Switch> replace conditional rendering - createMemo for derived values (filteredCommands, fuzzy results) - <Index> for lists where selection index reactivity matters Bug fixes found during migration: - Command menu/file picker: use createMemo for filtered lists - Theme picker: <Index> + store-based ThemeProvider for live preview - Tool expand/collapse: extract ExpandableTool with <Show> for reactivity - Ctrl+E: works during thinking, not just idle - Confirmation 'y' leak: defer confirmingToolId clear via queueMicrotask - Scroll follow: use ScrollBoxRenderable.scrollTo(idx) - extractContext: track multi-line oldString end line for correct diffs
🦋 Changeset detectedLatest commit: 4bbf529 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Values computed in Solid component bodies run once and become stale. Wrap derived data in createMemo so they recompute when dependencies change. - SessionPicker: projectSessions, groups, flatSessions, sessionIndexMap, scrollHeight - ThemeProvider: isDark now reactive via createMemo - Modal: leftOffset, topOffset, modalWidth recompute on terminal resize - DiffView: diffString, filetype, diffStyle - AssistantMessage: markdownStyle - StatusBar: modeColors - ContextStatsModal: statusColor, statusText, progressColor, ProgressBar bars - SidePanel: ContextBar filled/empty, ContextSection statusColor, TodoSection completed/total/activeTodos/statusColors - ConfirmingView: deduplicate p().type === 'command' condition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@opentui/reactto@opentui/solidChanges
Build infrastructure:
solid-js,@opentui/solidreplacingreact,@opentui/reacttsconfig.json:jsx: "preserve",jsxImportSource: "@opentui/solid"build.tsusing@opentui/solid/bun-pluginreact-compiler.preload.tsFoundation:
ThemeProvider: store-based context (createStore+reconcile) for reactive theme switching through destructuredtokensuseState/useEffect/useReftocreateSignal/createEffectComponents (16 files):
<For>/<Index>/<Show>/<Switch>replace conditional renderingcreateMemofor derived values (filtered commands, fuzzy search results)<Index>for lists where selection index reactivity matters (theme picker, command menu, file picker)Bug fixes found during migration:
createMemofor filtered lists (component bodies run once)<Index>+ store-basedThemeProviderfor live previewExpandableToolsub-component with<Show>for reactivityconfirmingToolIdclear viaqueueMicrotaskScrollBoxRenderable.scrollTo(idx)(not non-existentscrollToIndex)extractContext: track multi-lineoldStringend line for correct diff previewsTracking
Closes #52
Testing
bun check:typespasses cleanbun lint— 3 warnings (idiomatic Solidref={var!}), 8 infos (pre-existing)