lipgloss icon indicating copy to clipboard operation
lipgloss copied to clipboard

feat: Add border text functions for top and bottom borders.

Open pachecot opened this issue 1 year ago β€’ 6 comments

This allows to set titles and status information in the borders.

This solves the issue where I keep trying to add some status information to the bottom of a border. I either need to take it apart and rebuild it with the additional information or create my own bottom border. This also allows setting some title information, which is nice too.

this still need some error checking if someone returns longer strings.

type BorderFunc func(width int, middle string) string

func (s Style) BorderTopFunc(p Position, bf BorderFunc) Style 
func (s Style) BorderBottomFunc(p Position, bf BorderFunc) Style 

Example..

    NewStyle().
        Width(10).
        Border(NormalBorder()).
        BorderTopFunc(Left, func(width int, middle string) string {
            return "TITLE" 
        })
β”ŒTITLE─────┐
β”‚          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

will allow to set functions for each corner

β”ŒA───B───C┐
β”‚         β”‚
β””D───E───Fβ”˜

pachecot avatar Oct 03 '24 00:10 pachecot

made some changes to names and api so will accept strings and func() string.

here is sample..

	m := struct {
		index  int
		count  int
		status string
	}{
		index:  5,
		count:  10,
		status: ":)",
	}

	reverseStyle := lipgloss.NewStyle().Reverse(true)

	t := lipgloss.NewStyle().
		Width(40).
		Height(10).
		Border(lipgloss.NormalBorder()).
		BorderDecoration(lipgloss.NewBorderDecoration(
			lipgloss.Top,
			lipgloss.Center,
			reverseStyle.Padding(0, 1).Render("BIG TITLE"),
		)).
		BorderDecoration(lipgloss.NewBorderDecoration(
			lipgloss.Bottom,
			lipgloss.Right,
			func(width int, middle string) string {
				return reverseStyle.Render(fmt.Sprintf("[%d/%d]", m.index+1, m.count)) + middle
			},
		)).
		BorderDecoration(lipgloss.NewBorderDecoration(
			lipgloss.Bottom,
			lipgloss.Left,
			reverseStyle.Padding(0, 1).SetString(fmt.Sprintf("Status: %s", m.status)).String,
		))

	fmt.Println(t)

image

pachecot avatar Oct 05 '24 23:10 pachecot

Very nice! We had originally resigned to not including this sort of functionality, but your implementation looks really good. A couple open questions:

  • What should happen when a label is wider than the width of the box? Truncate? Expand the box?
  • What should happen when two labels collide? For example, when we have long left and right labels.

Can you also fix the issues pointed out with the linter?

meowgorithm avatar Oct 07 '24 16:10 meowgorithm

thanks,

I will address the issues in the linter. It looks like a bug.

It is intended to limit to the length of the box truncating the texts. Currently, it is first come first served, Left -> Center -> Right. so it is unfair and some may not even be included. I would like to change it to a more fair truncating, where they all get some of the space.

Currently they could collide. that will need to be addressed.

pachecot avatar Oct 07 '24 21:10 pachecot

Made some changes to equalize the sizes some and provide space between the labels. Currently does not add ellipsis, may want to add them.

t := style: NewStyle().
    Width(16).
    Border(NormalBorder()).
    BorderDecoration(NewBorderDecoration(Top, Left, "LeftLeftLeftLeft")).
    BorderDecoration(NewBorderDecoration(Top, Center, "CenterCenterCenter")).
    BorderDecoration(NewBorderDecoration(Top, Right, "RightRightRightRight"))
β”ŒLeftL─Cent─Right┐
β”‚                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

pachecot avatar Oct 07 '24 23:10 pachecot

I figured out how to include side borders also, so made some additional updates.

The support for style for the side borders are limited. I am not sure if there are existing functions that could support this better.

image

pachecot avatar Oct 11 '24 13:10 pachecot

This would be really helpful. Is there any intention to merge this?

matthjes avatar Nov 23 '25 14:11 matthjes