Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

pachecot
Copy link

@pachecot pachecot commented Oct 3, 2024

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┘

this adds callback functions to set text in borders when they are generated.
…r text

changed internals to use interface{} so will work with string or String().

border length was not being checked before, now it is limited to the width of the border.
@pachecot pachecot marked this pull request as draft October 5, 2024 19:55
@pachecot
Copy link
Author

pachecot commented Oct 5, 2024

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

@meowgorithm
Copy link
Member

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?

@pachecot
Copy link
Author

pachecot commented Oct 7, 2024

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
Copy link
Author

pachecot commented Oct 7, 2024

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┐
│                │
└────────────────┘

Position was not specific enough, could not distinguish between Top and Left, so could not use for side borders. BorderSide currently enum, could possibly be a flag.
@pachecot
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants