[GH-ISSUE #112] onMouseDown events do not fire when clicking a text node #795

Closed
opened 2026-03-14 08:35:51 +03:00 by kerem · 6 comments
Owner

Originally created by @remorses on GitHub (Aug 31, 2025).
Original GitHub issue: https://github.com/anomalyco/opentui/issues/112

Currently when you click a text node inside a box no onMouseDown events are fired.

Repro:

import { render } from '@opentui/react'
import { useState } from 'react'

function BugRepro() {
    const [outerClicks, setOuterClicks] = useState(0)
    const [innerClicks, setInnerClicks] = useState(0)
    const [textClicks, setTextClicks] = useState(0)

    return (
        <box flexDirection="column" gap={1}>
            <box
                onMouseDown={() => {
                    setOuterClicks(prev => prev + 1)
                    console.log('Outer box clicked')
                }}
                border={true}
                padding={2}
            >
                <box
                    onMouseDown={() => {
                        setInnerClicks(prev => prev + 1)
                        console.log('Inner box clicked')
                    }}
                    border={true}
                    padding={1}
                >
                    <text onMouseDown={() => {
                        setTextClicks(prev => prev + 1)
                        console.log('Text clicked')
                    }}>
                        Click me
                    </text>
                </box>
            </box>

            <text>Outer box clicks: {outerClicks}</text>
            <text>Inner box clicks: {innerClicks}</text>
            <text>Text clicks: {textClicks}</text>
        </box>
    )
}

render(<BugRepro />)


Originally created by @remorses on GitHub (Aug 31, 2025). Original GitHub issue: https://github.com/anomalyco/opentui/issues/112 Currently when you click a text node inside a box no `onMouseDown` events are fired. Repro: ```tsx import { render } from '@opentui/react' import { useState } from 'react' function BugRepro() { const [outerClicks, setOuterClicks] = useState(0) const [innerClicks, setInnerClicks] = useState(0) const [textClicks, setTextClicks] = useState(0) return ( <box flexDirection="column" gap={1}> <box onMouseDown={() => { setOuterClicks(prev => prev + 1) console.log('Outer box clicked') }} border={true} padding={2} > <box onMouseDown={() => { setInnerClicks(prev => prev + 1) console.log('Inner box clicked') }} border={true} padding={1} > <text onMouseDown={() => { setTextClicks(prev => prev + 1) console.log('Text clicked') }}> Click me </text> </box> </box> <text>Outer box clicks: {outerClicks}</text> <text>Inner box clicks: {innerClicks}</text> <text>Text clicks: {textClicks}</text> </box> ) } render(<BugRepro />) ```
kerem 2026-03-14 08:35:51 +03:00
  • closed this issue
  • added the
    core
    bug
    labels
Author
Owner

@msmps commented on GitHub (Aug 31, 2025):

ahh! i think this is a problem irrespective of where the node is placed in the tree! i think this is due to a conflict with the select logic here @kommander

you should be able to work around this at the moment @remorses by setting selectable to false on the text node

<!-- gh-comment-id:3240299338 --> @msmps commented on GitHub (Aug 31, 2025): ahh! i think this is a problem irrespective of where the node is placed in the tree! i think this is due to a conflict with the select logic [here](https://github.com/sst/opentui/blob/8241e6d99f68b74f38686c36ffb809c67563461a/packages/core/src/renderer.ts#L665-L674) @kommander you should be able to work around this at the moment @remorses by setting `selectable` to false on the text node
Author
Owner

@kommander commented on GitHub (Aug 31, 2025):

Correct. When a node is selectable it currently swallows the mouse button event.

<!-- gh-comment-id:3240301579 --> @kommander commented on GitHub (Aug 31, 2025): Correct. When a node is selectable it currently swallows the mouse button event.
Author
Owner

@remorses commented on GitHub (Aug 31, 2025):

I guess the best way to solve this would be to add an onClick event that fires on mouse over and only if the user did not drag the cursor more than n characters, like in the browser

<!-- gh-comment-id:3240345046 --> @remorses commented on GitHub (Aug 31, 2025): I guess the best way to solve this would be to add an onClick event that fires on mouse over and only if the user did not drag the cursor more than n characters, like in the browser
Author
Owner

@kommander commented on GitHub (Aug 31, 2025):

You mean on mouse up and only fire if not dragging? I think that could be solved then by starting text selection on drag, not on down, maybe.

Need to get that handler test covered.

<!-- gh-comment-id:3240354824 --> @kommander commented on GitHub (Aug 31, 2025): You mean on mouse up and only fire if not dragging? I think that could be solved then by starting text selection on drag, not on down, maybe. Need to get that handler test covered.
Author
Owner

@remorses commented on GitHub (Aug 31, 2025):

Yes that's also a good idea

I know John Carmack is very opinionated about this and would prefer that option much better 😆

https://x.com/ID_AA_Carmack/status/1787850053912064005

<!-- gh-comment-id:3240362939 --> @remorses commented on GitHub (Aug 31, 2025): Yes that's also a good idea I know John Carmack is very opinionated about this and would prefer that option much better 😆 https://x.com/ID_AA_Carmack/status/1787850053912064005
Author
Owner

@kommander commented on GitHub (Sep 2, 2025):

For me this works #123, allowing both behaviours and selection is still instant on the cell where selection actually starts. And it's less complex.

<!-- gh-comment-id:3245022021 --> @kommander commented on GitHub (Sep 2, 2025): For me this works #123, allowing both behaviours and selection is still instant on the cell where selection actually starts. And it's less complex.
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#795
No description provided.