[GH-ISSUE #831] Setting a border on a Flex will hide the children. #605

Closed
opened 2026-03-04 01:06:24 +03:00 by kerem · 8 comments
Owner

Originally created by @tcurdt on GitHub (Mar 26, 2023).
Original GitHub issue: https://github.com/rivo/tview/issues/831

I am not sure what I am missing here - but as soon as I set a border the children disappear.

	layoutCol2 := tview.NewFlex().
		SetDirection(tview.FlexRow).
		AddItem(identification, 2, 0, false).
		AddItem(value, 1, 0, false).
		AddItem(details, 6, 0, false).
		AddItem(help, 1, 0, false).
		SetBorder(true)
Screenshot 2023-03-26 at 04 00 06

The same happens when setting a padding.

	layoutCol2 := tview.NewFlex().
		SetDirection(tview.FlexRow).
		AddItem(identification, 2, 0, false).
		AddItem(value, 1, 0, false).
		AddItem(details, 6, 0, false).
		AddItem(help, 1, 0, false).
		SetBorderPadding(1, 1, 1, 1)

Without it looks like this:

	layoutCol2 := tview.NewFlex().
		SetDirection(tview.FlexRow).
		AddItem(identification, 2, 0, false).
		AddItem(value, 1, 0, false).
		AddItem(details, 6, 0, false).
		AddItem(help, 1, 0, false)
Screenshot 2023-03-26 at 04 02 02
Originally created by @tcurdt on GitHub (Mar 26, 2023). Original GitHub issue: https://github.com/rivo/tview/issues/831 I am not sure what I am missing here - but as soon as I set a border the children disappear. ``` layoutCol2 := tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(identification, 2, 0, false). AddItem(value, 1, 0, false). AddItem(details, 6, 0, false). AddItem(help, 1, 0, false). SetBorder(true) ``` <img width="223" alt="Screenshot 2023-03-26 at 04 00 06" src="https://user-images.githubusercontent.com/13697/227751206-0233ed30-65b9-466b-8e37-1d984bdb110d.png"> The same happens when setting a padding. ``` layoutCol2 := tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(identification, 2, 0, false). AddItem(value, 1, 0, false). AddItem(details, 6, 0, false). AddItem(help, 1, 0, false). SetBorderPadding(1, 1, 1, 1) ``` Without it looks like this: ``` layoutCol2 := tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(identification, 2, 0, false). AddItem(value, 1, 0, false). AddItem(details, 6, 0, false). AddItem(help, 1, 0, false) ``` <img width="209" alt="Screenshot 2023-03-26 at 04 02 02" src="https://user-images.githubusercontent.com/13697/227751280-15d7aae3-252a-4ee4-ba47-3a813e8bbe8d.png">
kerem closed this issue 2026-03-04 01:06:24 +03:00
Author
Owner

@tcurdt commented on GitHub (Mar 26, 2023):

Interesting. This seems to be related to the builder pattern.
This works:

layoutCol2 := tview.NewFlex().
		SetDirection(tview.FlexRow).
		AddItem(identification, 2, 0, false).
		AddItem(value, 1, 0, false).
		AddItem(details, 6, 0, false).
		AddItem(help, 1, 0, false)

layoutCol2.SetBorder(true)
layoutCol2.SetBorderPadding(1, 1, 1, 1)
<!-- gh-comment-id:1483980466 --> @tcurdt commented on GitHub (Mar 26, 2023): Interesting. This seems to be related to the builder pattern. This works: ``` layoutCol2 := tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(identification, 2, 0, false). AddItem(value, 1, 0, false). AddItem(details, 6, 0, false). AddItem(help, 1, 0, false) layoutCol2.SetBorder(true) layoutCol2.SetBorderPadding(1, 1, 1, 1) ```
Author
Owner

@tcurdt commented on GitHub (Mar 26, 2023):

Unfortunately setting a padding reveals an area where I cannot set a background color.
Here the left and right padding is just white instead of black.

Screenshot 2023-03-26 at 18 19 30
<!-- gh-comment-id:1484148541 --> @tcurdt commented on GitHub (Mar 26, 2023): Unfortunately setting a padding reveals an area where I cannot set a background color. Here the left and right padding is just white instead of black. <img width="176" alt="Screenshot 2023-03-26 at 18 19 30" src="https://user-images.githubusercontent.com/13697/227789413-862eec2f-fc30-40a4-8eef-7e61cec8d1a5.png">
Author
Owner

@andreas-habel commented on GitHub (Apr 5, 2023):

I have the same issue here with a list:

package main

import (
	"github.com/rivo/tview"
)

func main() {
	app := tview.NewApplication()

	list := tview.NewList().
		AddItem("List item 1", "Some explanatory text", 'a', nil).
		AddItem("Quit", "Press to exit", 'q', func() {
			app.Stop()
		}).
		SetBorder(true)

	box := tview.NewFlex().
		AddItem(list, 0, 1, true)

	if err := app.SetRoot(box, true).Run(); err != nil {
		panic(err)
	}
}

image

//snip

	list := tview.NewList().
		AddItem("List item 1", "Some explanatory text", 'a', nil).
		AddItem("Quit", "Press to exit", 'q', func() {
			app.Stop()
		})

	list.SetBorder(true)

//snip

image

<!-- gh-comment-id:1497936800 --> @andreas-habel commented on GitHub (Apr 5, 2023): I have the same issue here with a list: ```golang package main import ( "github.com/rivo/tview" ) func main() { app := tview.NewApplication() list := tview.NewList(). AddItem("List item 1", "Some explanatory text", 'a', nil). AddItem("Quit", "Press to exit", 'q', func() { app.Stop() }). SetBorder(true) box := tview.NewFlex(). AddItem(list, 0, 1, true) if err := app.SetRoot(box, true).Run(); err != nil { panic(err) } } ``` ![image](https://user-images.githubusercontent.com/80671695/230171706-5d9330da-3c28-453a-ade8-11c5ed6ffc6b.png) ```golang //snip list := tview.NewList(). AddItem("List item 1", "Some explanatory text", 'a', nil). AddItem("Quit", "Press to exit", 'q', func() { app.Stop() }) list.SetBorder(true) //snip ``` ![image](https://user-images.githubusercontent.com/80671695/230171859-6898f2f2-d142-4965-87a8-860f83537dfb.png)
Author
Owner

@kiyutink commented on GitHub (Apr 5, 2023):

Hey folks, .SetBorder returns a *tview.Box for any primitive, because .Border is a method that comes from embedding a *Box into all the other primitives (see example for list).

What's happening is that by calling .Border at the end, the returned value captured in the variable is not a list, but a box. I imagine using this approach is the best bet here

With list that would mean instead of this:

list := tview.NewList().
  AddItem("List item 1", "Some explanatory text", 'a', nil).
  SetBorder(true)

Do this:

list := tview.NewList().
  AddItem("List item 1", "Some explanatory text", 'a', nil)
list.SetBorder(true)
<!-- gh-comment-id:1498242849 --> @kiyutink commented on GitHub (Apr 5, 2023): Hey folks, `.SetBorder` returns a `*tview.Box` for any primitive, because `.Border` is a method that comes from embedding a `*Box` into all the other primitives (see [example for list](https://github.com/rivo/tview/blob/master/list.go#L39)). What's happening is that by calling `.Border` at the end, the returned value captured in the variable is not a list, but a box. I imagine using [this approach](https://github.com/rivo/tview/issues/831#issuecomment-1483980466) is the best bet here With list that would mean instead of this: ```go list := tview.NewList(). AddItem("List item 1", "Some explanatory text", 'a', nil). SetBorder(true) ``` Do this: ```go list := tview.NewList(). AddItem("List item 1", "Some explanatory text", 'a', nil) list.SetBorder(true) ```
Author
Owner

@tcurdt commented on GitHub (Apr 5, 2023):

The work around is clear.
But I think the point is that the API suggest the use of a builder pattern - and that has issues.

<!-- gh-comment-id:1498248981 --> @tcurdt commented on GitHub (Apr 5, 2023): The work around is clear. But I think the point is that the API suggest the use of a builder pattern - and that has issues.
Author
Owner

@rivo commented on GitHub (Apr 6, 2023):

@tcurdt True. See also https://github.com/rivo/tview/issues/141#issuecomment-410437784 for some context.

<!-- gh-comment-id:1498600329 --> @rivo commented on GitHub (Apr 6, 2023): @tcurdt True. See also https://github.com/rivo/tview/issues/141#issuecomment-410437784 for some context.
Author
Owner

@rivo commented on GitHub (Apr 6, 2023):

The latest commit clarifies this in the package documentation. It should appear here once that page is updated. Unfortunately, there's no good way to implement this in Go without duplicating a lot of code.

<!-- gh-comment-id:1498616906 --> @rivo commented on GitHub (Apr 6, 2023): The latest commit clarifies this in the package documentation. It should appear [here](https://pkg.go.dev/github.com/rivo/tview#hdr-Type_Hierarchy) once that page is updated. Unfortunately, there's no good way to implement this in Go without duplicating a lot of code.
Author
Owner

@tcurdt commented on GitHub (Apr 6, 2023):

I might just drop using the builder all together.
Thanks for clarifying this in the docs.

For this https://github.com/rivo/tview/issues/831#issuecomment-1484148541 I should probably open another issue.

<!-- gh-comment-id:1498870330 --> @tcurdt commented on GitHub (Apr 6, 2023): I might just drop using the builder all together. Thanks for clarifying this in the docs. For this https://github.com/rivo/tview/issues/831#issuecomment-1484148541 I should probably open another issue.
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/tview#605
No description provided.