[GH-ISSUE #260] scrollbox with For inside doesn't properly render content #67

Closed
opened 2026-03-02 23:44:19 +03:00 by kerem · 2 comments
Owner

Originally created by @istarkov on GitHub (Nov 3, 2025).
Original GitHub issue: https://github.com/anomalyco/opentui/issues/260

Reproduction of the issue in the opencode repo. (Will not show messages after 3s)

ref https://github.com/sst/opencode/issues/3819 (+ few others)
ref https://github.com/sst/opencode/pull/3834

the fast fix is same as there, wrapping <For with <box><For...</box>

// packages/solid/tmp.tsx
import { SyntaxStyle } from "../core/src/syntax-style"
import { render } from "./index"
import { createEffect, createMemo, createSignal, For } from "solid-js"
import type { ScrollBoxRenderable } from "../core/src/renderables"

const syntaxStyle = SyntaxStyle.fromTheme([])

const code = `

# HELLO

world

## HELLO World

\`\`\`html
<div
  class="min-h-screen bg-gradient-to-br from-amber-50 via-orange-50 to-rose-50 relative overflow-hidden"
>
  <!-- Sakura Petals Background Animation -->
  <div class="absolute inset-0 pointer-events-none">
    <div class="sakura-petal absolute top-10 left-20 animate-pulse opacity-60">
      🌸
    </div>
    <div
      class="sakura-petal absolute top-1/2 right-20 animate-pulse opacity-45"
      style="animation-delay: 1.5s"
    >
      🌸
    </div>
    <div
      class="sakura-petal absolute bottom-40 right-1/3 animate-pulse opacity-55"
      style="animation-delay: 0.5s"
    >
      🌸
    </div>
  </div>
/div>
\`\`\`


`

function ScrollFail() {
  const [count, setCount] = createSignal(0)
  const messages = createMemo(() => Array.from({ length: count() }, (_, i) => code))

  let scroll: ScrollBoxRenderable

  createEffect(() => {
    setTimeout(() => {
      setCount(100)
      setTimeout(() => {
        scroll?.scrollTo(scroll.scrollHeight)
      }, 10)
    }, 3000)
  })

  return (
    <scrollbox ref={(r) => (scroll = r)} focused stickyScroll={true} stickyStart="bottom" flexGrow={1}>
      <For each={messages()}>
        {(code) => (
          <box marginTop={2} marginBottom={2}>
            <code drawUnstyledText={false} syntaxStyle={syntaxStyle} content={code} filetype="markdown" />
          </box>
        )}
      </For>
    </scrollbox>
  )
}

render(() => (
  <box flexDirection="column" gap={1}>
    <box flexShrink={0}>
      <text>Some visual content</text>
    </box>
    <ScrollFail />
    <box flexShrink={0}>
      <text>Some visual content</text>
    </box>
  </box>
))
Originally created by @istarkov on GitHub (Nov 3, 2025). Original GitHub issue: https://github.com/anomalyco/opentui/issues/260 Reproduction of the issue in the opencode repo. (Will not show messages after 3s) ref https://github.com/sst/opencode/issues/3819 (+ few others) ref https://github.com/sst/opencode/pull/3834 _the fast fix is same as there, wrapping `<For` with `<box><For...</box>`_ ```typescript // packages/solid/tmp.tsx import { SyntaxStyle } from "../core/src/syntax-style" import { render } from "./index" import { createEffect, createMemo, createSignal, For } from "solid-js" import type { ScrollBoxRenderable } from "../core/src/renderables" const syntaxStyle = SyntaxStyle.fromTheme([]) const code = ` # HELLO world ## HELLO World \`\`\`html <div class="min-h-screen bg-gradient-to-br from-amber-50 via-orange-50 to-rose-50 relative overflow-hidden" > <!-- Sakura Petals Background Animation --> <div class="absolute inset-0 pointer-events-none"> <div class="sakura-petal absolute top-10 left-20 animate-pulse opacity-60"> 🌸 </div> <div class="sakura-petal absolute top-1/2 right-20 animate-pulse opacity-45" style="animation-delay: 1.5s" > 🌸 </div> <div class="sakura-petal absolute bottom-40 right-1/3 animate-pulse opacity-55" style="animation-delay: 0.5s" > 🌸 </div> </div> /div> \`\`\` ` function ScrollFail() { const [count, setCount] = createSignal(0) const messages = createMemo(() => Array.from({ length: count() }, (_, i) => code)) let scroll: ScrollBoxRenderable createEffect(() => { setTimeout(() => { setCount(100) setTimeout(() => { scroll?.scrollTo(scroll.scrollHeight) }, 10) }, 3000) }) return ( <scrollbox ref={(r) => (scroll = r)} focused stickyScroll={true} stickyStart="bottom" flexGrow={1}> <For each={messages()}> {(code) => ( <box marginTop={2} marginBottom={2}> <code drawUnstyledText={false} syntaxStyle={syntaxStyle} content={code} filetype="markdown" /> </box> )} </For> </scrollbox> ) } render(() => ( <box flexDirection="column" gap={1}> <box flexShrink={0}> <text>Some visual content</text> </box> <ScrollFail /> <box flexShrink={0}> <text>Some visual content</text> </box> </box> )) ```
kerem closed this issue 2026-03-02 23:44:19 +03:00
Author
Owner

@kommander commented on GitHub (Nov 3, 2025):

@Adictya @fezproof could you help out here?

<!-- gh-comment-id:3483005595 --> @kommander commented on GitHub (Nov 3, 2025): @Adictya @fezproof could you help out here?
Author
Owner

@istarkov commented on GitHub (Nov 4, 2025):

Fixed

<!-- gh-comment-id:3486234931 --> @istarkov commented on GitHub (Nov 4, 2025): Fixed
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#67
No description provided.