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

Add BlockBorder, OuterHalfBlockBorder, and InnerHalfBlockBorder border styles #120

Merged
merged 2 commits into from Oct 27, 2022

Conversation

AlyxPractice
Copy link
Contributor

By having the same color for the border and the background of the element, it gives some cool results:
image

For context, in a game where you can buy upgrades, you can show the user the ones that have been already bought, the ones they can buy, and the ones still locked:

image

I think it could be a useful addition, for example when you want to highlight something as if it was a button.


Quick testing:

package main

import (
	"fmt"

	"github.com/charmbracelet/lipgloss"
)

var (
	innerBorder = lipgloss.Border{
		Top:         "▄",
		Bottom:      "▀",
		Left:        "▐",
		Right:       "▌",
		TopLeft:     "▗",
		TopRight:    "▖",
		BottomLeft:  "▝",
		BottomRight: "▘",
	}
)

func main() {
	fmt.Println()
	color := lipgloss.Color("#00f5d4)")
	testBorders := lipgloss.NewStyle().Foreground(lipgloss.Color("#333")).Background(color).BorderForeground(color)
	fmt.Println(testBorders.Copy().Border(lipgloss.NormalBorder()).Render("NormalBorder"))
	fmt.Println(testBorders.Copy().Border(lipgloss.RoundedBorder()).Render("RoundedBorder"))
	fmt.Println(testBorders.Copy().Border(innerBorder).Render("InnerBorder"))
	fmt.Println(testBorders.Copy().Border(lipgloss.ThickBorder()).Render("ThickBorder"))
	fmt.Println(testBorders.Copy().Border(lipgloss.DoubleBorder()).Render("DoubleBorder"))
	fmt.Println(testBorders.Copy().Border(lipgloss.HiddenBorder()).Render("HiddenBorder"))
}

@meowgorithm meowgorithm added the enhancement New feature or request label Sep 5, 2022
@meowgorithm
Copy link
Member

This is great; thanks for the PR. My only thought here is the name, since the effect you're going for in your example could also be done with inner padding. I wonder if there's anything else that's perhaps more clear. Maybe BlockBorder?

@AlyxPractice
Copy link
Contributor Author

since the effect you're going for in your example could also be done with inner padding

If I'm not mistaken, inner padding + background would create a larger border effect (notice the size of the top/bottom border):
image

Maybe BlockBorder?

My reasoning behind the name was that by organizing the characters differently and changing corners blocks, you would get some kind of outer border, and by using a full-width block character, you would get another effect too (fullBorder), same as for Padding(1) with a width difference, as the border would be added to Width() where Padding() is part of the Width set (IIRC):
image

I'm of course all open to renaming it to something else, but at least you have more context now 😊
Maybe something like HalfBlockBorder? InnerHalfBlockBorder?

The characters come from here, if needed: https://en.wikipedia.org/wiki/Box-drawing_character#Block_Elements
And the Unicode standard for these characters, with their names in it: http://www.unicode.org/charts/PDF/U2580.pdf

Here's a new version of the demo, with a standardized width to easily compare them together:

image

package main

import (
	"fmt"

	"github.com/charmbracelet/lipgloss"
)

var (
	fullBorder = lipgloss.Border{
		Top:         "█",
		Bottom:      "█",
		Left:        "█",
		Right:       "█",
		TopLeft:     "█",
		TopRight:    "█",
		BottomLeft:  "█",
		BottomRight: "█",
	}
	outerBorder = lipgloss.Border{
		Top:         "▀",
		Bottom:      "▄",
		Left:        "▌",
		Right:       "▐",
		TopLeft:     "▛",
		TopRight:    "▜",
		BottomLeft:  "▙",
		BottomRight: "▟",
	}
	innerBorder = lipgloss.Border{
		Top:         "▄",
		Bottom:      "▀",
		Left:        "▐",
		Right:       "▌",
		TopLeft:     "▗",
		TopRight:    "▖",
		BottomLeft:  "▝",
		BottomRight: "▘",
	}
)

func main() {
	fmt.Println()
	color := lipgloss.Color("#00f5d4)")
	testBorders := lipgloss.NewStyle().Foreground(lipgloss.Color("#333")).Background(color).BorderForeground(color).Width(15)
	fmt.Println(testBorders.Copy().Border(lipgloss.NormalBorder()).Render("NormalBorder"))
	fmt.Println(testBorders.Copy().Border(lipgloss.RoundedBorder()).Render("RoundedBorder"))
	fmt.Println(testBorders.Copy().Border(fullBorder).Render("FullBorder"))
	fmt.Println(testBorders.Copy().Border(innerBorder).Render("InnerBorder"))
	fmt.Println(testBorders.Copy().Border(outerBorder).Render("OuterBorder"))
	fmt.Println(testBorders.Copy().Border(lipgloss.ThickBorder()).Render("ThickBorder"))
	fmt.Println(testBorders.Copy().Border(lipgloss.DoubleBorder()).Render("DoubleBorder"))
	fmt.Println(testBorders.Copy().Border(lipgloss.HiddenBorder()).Render("HiddenBorder"))
	fmt.Println(testBorders.Copy().Padding(1).Render("WithPadding1"))
}

@maaslalani
Copy link
Member

maaslalani commented Sep 20, 2022

Not 100% sure on this but maybe this could be called OutlineBorder? Since it acts as an outline. If the full outline border is also introduced it could be OutlineBorder and ThickOutlineBorder? Or, perhaps InnerOutlineBorder / OuterOutlineBorder / FullOutlineBorder.

Thinking about this a bit more, I think BlockBorder and InnerHalfBlockBorder and OuterHalfBlockBorder also make a lot of sense.

@AlyxPractice
Copy link
Contributor Author

Love the names! I will edit my PR and add the new ones too.

@AlyxPractice AlyxPractice changed the title Add innerBorder style Add BlockBorder, OuterHalfBlockBorder, and InnerHalfBlockBorder border styles Oct 27, 2022
@AlyxPractice
Copy link
Contributor Author

AlyxPractice commented Oct 27, 2022

Hey, I took a while to get back on it, thanks for your patience 🙇

Here are the results with the new names and variations:
image

What do you think? Anything else I can do? 😊

@maaslalani
Copy link
Member

Thanks so much @VictorBersy, this looks great!

@maaslalani maaslalani merged commit 9ee8b6e into charmbracelet:master Oct 27, 2022
renovate bot added a commit to sheldonhull/az-pr that referenced this pull request Apr 3, 2023
…s to v0.7.1 (#7)

[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[github.com/charmbracelet/lipgloss](https://togithub.com/charmbracelet/lipgloss)
| require | minor | `v0.6.0` -> `v0.7.1` |

---

### Release Notes

<details>
<summary>charmbracelet/lipgloss</summary>

###
[`v0.7.1`](https://togithub.com/charmbracelet/lipgloss/releases/tag/v0.7.1)

[Compare
Source](https://togithub.com/charmbracelet/lipgloss/compare/v0.7.0...v0.7.1)

This bugfix release fixes a problem introduced in v0.7.0 where
applications could freeze or hang on start-up.

#### What's Changed

- fix(renderer): use termenv default renderer by
[@&#8203;aymanbagabas](https://togithub.com/aymanbagabas) in
[charmbracelet/lipgloss#179
- chore: bump termenv to v0.15.1 by
[@&#8203;muesli](https://togithub.com/muesli) in
[charmbracelet/lipgloss#180

**Full Changelog**:
charmbracelet/lipgloss@v0.7.0...v0.7.1

###
[`v0.7.0`](https://togithub.com/charmbracelet/lipgloss/releases/tag/v0.7.0)

[Compare
Source](https://togithub.com/charmbracelet/lipgloss/compare/v0.6.0...v0.7.0)

### Custom Renderers

We're pleased to introduce custom renders for Lip Gloss! Custom
renderers allow you to render to a specific outputs, which is
particularly important when you want to detect the color profile and
dark background status for multiple different outputs at runtime, such
as in a server-client situation.

Here's what it looks like:

```go
func myLittleHandler(sess ssh.Session) {
    // Create a renderer for the client.
    renderer := lipgloss.NewRenderer(sess)

    // Create a new style on the renderer.
    style := renderer.NewStyle().Background(lipgloss.AdaptiveColor{Light: "63", Dark: "228"})

    // Render. The color profile and dark background state will be correctly detected.
    io.WriteString(sess, style.Render("Heyyyyyyy"))
}
```

For a full example on using a custom renderer over SSH with
[Wish](https://togithub.com/charmbracelet/wish) see the [SSH
example](https://togithub.com/charmbracelet/lipgloss/blob/master/examples/ssh).

#### New API Stuff

-   `type Renderer struct`
-   `NewRenderer(io.Writer)`
-   `DefaultRenderer()`
-   `SetDefaultRenderer(*lipgloss.Renderer)`
-   `style.Renderer(*lipgloss.Renderer) Style`

#### What's Changed

##### New

- lipgloss renderer by
[@&#8203;aymanbagabas](https://togithub.com/aymanbagabas) in
[charmbracelet/lipgloss#140
and
[charmbracelet/lipgloss#174
- add BlockBorder, OuterHalfBlockBorder, and InnerHalfBlockBorder border
styles by [@&#8203;VictorBersy](https://togithub.com/VictorBersy) in
[charmbracelet/lipgloss#120

##### Fixed

- RGBA implementations for non-hex color values by
[@&#8203;muesli](https://togithub.com/muesli) in
[charmbracelet/lipgloss#126
- unify get border size function names by
[@&#8203;nerg4l](https://togithub.com/nerg4l) in
[charmbracelet/lipgloss#148
- reduce dependencies by
[@&#8203;caarlos0](https://togithub.com/caarlos0) in
[charmbracelet/lipgloss#146
- don't concurrently change output profiles by
[@&#8203;muesli](https://togithub.com/muesli) in
[charmbracelet/lipgloss#172

#### New Contributors

- [@&#8203;dependabot](https://togithub.com/dependabot) made their first
contribution in
[charmbracelet/lipgloss#133
- [@&#8203;winder](https://togithub.com/winder) made their first
contribution in
[charmbracelet/lipgloss#147
- [@&#8203;VictorBersy](https://togithub.com/VictorBersy) made their
first contribution in
[charmbracelet/lipgloss#120
- [@&#8203;nervo](https://togithub.com/nervo) made their first
contribution in
[charmbracelet/lipgloss#156
- [@&#8203;caarlos0](https://togithub.com/caarlos0) made their first
contribution in
[charmbracelet/lipgloss#146
- [@&#8203;Isti115](https://togithub.com/Isti115) made their first
contribution in
[charmbracelet/lipgloss#170
- [@&#8203;nerg4l](https://togithub.com/nerg4l) made their first
contribution in
[charmbracelet/lipgloss#148

**Full Changelog**:
charmbracelet/lipgloss@v0.6.0...v0.7.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 3am on Monday" (UTC),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/sheldonhull/az-pr).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4yMi4xIiwidXBkYXRlZEluVmVyIjoiMzUuMjIuMSJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants