Skip to content

Commit

Permalink
feat: move tree to root (#342)
Browse files Browse the repository at this point in the history
* feat: support any type for list Root func

Signed-off-by: Carlos Alexandro Becker <[email protected]>

* feat: move tree to root

Signed-off-by: Carlos Alexandro Becker <[email protected]>

* feat: more cleanup

Signed-off-by: Carlos Alexandro Becker <[email protected]>

* docs(examples): bring back tree examples

* docs(examples): add tree toggle example

* docs(examples): fix toggle tree hierarchy; as bashbunni metadata

* fix(tree): stylize whitespace when vertically joining tree elements

* docs: get started with trees

* feat: add RootStyle with example

* test: add test for RootStyle func

* docs(godoc): replace list mentions in tree package

* refactor(examples): use Root shorthand instead of tree.New where applicable

---------

Signed-off-by: Carlos Alexandro Becker <[email protected]>
Co-authored-by: bashbunni <[email protected]>
Co-authored-by: Christian Rocha <[email protected]>
  • Loading branch information
3 people authored Aug 19, 2024
1 parent 0618c73 commit feb42a9
Show file tree
Hide file tree
Showing 21 changed files with 438 additions and 59 deletions.
94 changes: 94 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,100 @@ for i := 0; i < repeat; i++ {
}
```

## Rendering Trees

Lip Gloss ships with a tree rendering sub-package.

```go
import "github.com/charmbracelet/lipgloss/tree"
```

Define a new tree.

```go
t := tree.Root(".").
Child("A", "B", "C")
```

Print the tree.

```go
fmt.Println(t)

// .
// ├── A
// ├── B
// └── C
```

Trees have the ability to nest.

```go
t := tree.Root(".").
Child("Item 1").
Child(
tree.Root("Item 2").
Child("Item 2.1").
Child("Item 2.2").
Child("Item 2.3"),
).
Child(
tree.Root("Item 3").
Child("Item 3.1").
Child("Item 3.2"),
)
```

Print the tree.

```go
fmt.Println(t)
```

<p align="center">
<img width="400" alt="Tree Example (simple)" src="https://stuff.charm.sh/lipgloss/tree-simple.png">
</p>

Trees can be customized via their enumeration function as well as using
`lipgloss.Style`s.

```go
enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRight(1)
itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1)

t := tree.
Root("Makeup").
Child(
"Glossier",
"Claire’s Boutique",
"Nyx",
"Mac",
"Milk",
).
Enumerator(tree.RoundedEnumerator).
EnumeratorStyle(enumeratorStyle).
ItemStyle(itemStyle)

```

Print the tree.

<p align="center">
<img width="600" alt="Tree Example (makeup)" src="https://stuff.charm.sh/lipgloss/tree/tree-makeup.png">
</p>

The predefined enumerators for trees are `DefaultEnumerator` and `RoundedEnumerator`.

If you need, you can also build trees incrementally:

```go
t := tree.New()

for i := 0; i < repeat; i++ {
t.Child("Lip Gloss")
}
```

---

## FAQ
Expand Down
2 changes: 1 addition & 1 deletion examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/charmbracelet/bubbletea v0.25.0 // indirect
github.com/charmbracelet/keygen v0.5.0 // indirect
github.com/charmbracelet/log v0.4.0 // indirect
github.com/charmbracelet/x/ansi v0.1.3 // indirect
github.com/charmbracelet/x/ansi v0.1.4 // indirect
github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651 // indirect
github.com/charmbracelet/x/exp/term v0.0.0-20240328150354-ab9afc214dfd // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
Expand Down
4 changes: 2 additions & 2 deletions examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ github.com/charmbracelet/ssh v0.0.0-20240401141849-854cddfa2917 h1:NZKjJ7d/pzk/A
github.com/charmbracelet/ssh v0.0.0-20240401141849-854cddfa2917/go.mod h1:8/Ve8iGRRIGFM1kepYfRF2pEOF5Y3TEZYoJaA54228U=
github.com/charmbracelet/wish v1.4.0 h1:pL1uVP/YuYgJheHEj98teZ/n6pMYnmlZq/fcHvomrfc=
github.com/charmbracelet/wish v1.4.0/go.mod h1:ew4/MjJVfW/akEO9KmrQHQv1F7bQRGscRMrA+KtovTk=
github.com/charmbracelet/x/ansi v0.1.3 h1:RBh/eleNWML5R524mjUF0yVRePTwqN9tPtV+DPgO5Lw=
github.com/charmbracelet/x/ansi v0.1.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM=
github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651 h1:3RXpZWGWTOeVXCTv0Dnzxdv/MhNUkBfEcbaTY0zrTQI=
github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
github.com/charmbracelet/x/exp/term v0.0.0-20240328150354-ab9afc214dfd h1:HqBjkSFXXfW4IgX3TMKipWoPEN08T3Pi4SA/3DLss/U=
Expand Down
39 changes: 39 additions & 0 deletions examples/tree/background/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"fmt"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/tree"
)

func main() {
enumeratorStyle := lipgloss.NewStyle().
Background(lipgloss.Color("0")).
Padding(0, 1)

headerItemStyle := lipgloss.NewStyle().
Background(lipgloss.Color("#ee6ff8")).
Foreground(lipgloss.Color("#ecfe65")).
Bold(true).
Padding(0, 1)

itemStyle := headerItemStyle.Background(lipgloss.Color("0"))

t := tree.Root("# Table of Contents").
RootStyle(itemStyle).
ItemStyle(itemStyle).
EnumeratorStyle(enumeratorStyle).
Child(
tree.Root("## Chapter 1").
Child("Chapter 1.1").
Child("Chapter 1.2"),
).
Child(
tree.Root("## Chapter 2").
Child("Chapter 2.1").
Child("Chapter 2.2"),
)

fmt.Println(t)
}
28 changes: 28 additions & 0 deletions examples/tree/files/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"fmt"
"os"
"path/filepath"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/tree"
)

func main() {
enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("240")).PaddingRight(1)
itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).Bold(true).PaddingRight(1)

t := tree.Root(".").EnumeratorStyle(enumeratorStyle).ItemStyle(itemStyle)
_ = filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
t.Child(tree.Root(path))
}
return nil
})

fmt.Println(t)
}
29 changes: 29 additions & 0 deletions examples/tree/makeup/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"fmt"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/tree"
)

func main() {
enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRight(1)
itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1)

t := tree.
Root("Makeup").
Child(
"Glossier",
"Claire’s Boutique",
"Nyx",
"Mac",
"Milk",
).
Enumerator(tree.RoundedEnumerator).
EnumeratorStyle(enumeratorStyle).
ItemStyle(itemStyle).
RootStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575")))

fmt.Println(t)
}
37 changes: 37 additions & 0 deletions examples/tree/rounded/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package main

import (
"fmt"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/tree"
)

func main() {
itemStyle := lipgloss.NewStyle().MarginRight(1)
enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("8")).MarginRight(1)

t := tree.Root("Groceries").
Child(
tree.Root("Fruits").
Child(
"Blood Orange",
"Papaya",
"Dragonfruit",
"Yuzu",
),
tree.Root("Items").
Child(
"Cat Food",
"Nutella",
"Powdered Sugar",
),
tree.Root("Veggies").
Child(
"Leek",
"Artichoke",
),
).ItemStyle(itemStyle).EnumeratorStyle(enumeratorStyle).Enumerator(tree.RoundedEnumerator)

fmt.Println(t)
}
27 changes: 27 additions & 0 deletions examples/tree/simple/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"fmt"

"github.com/charmbracelet/lipgloss/tree"
)

func main() {
t := tree.Root(".").
Child("Item 1").
Child(
tree.New().
Root("Item 2").
Child("Item 2.1").
Child("Item 2.2").
Child("Item 2.3"),
).
Child(
tree.New().
Root("Item 3").
Child("Item 3.1").
Child("Item 3.2"),
)

fmt.Println(t)
}
26 changes: 26 additions & 0 deletions examples/tree/styles/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"fmt"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/tree"
)

func main() {
purple := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRight(1)
pink := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1)

t := tree.New().
Child(
"Glossier",
"Claire’s Boutique",
tree.Root("Nyx").
Child("Lip Gloss", "Foundation").
EnumeratorStyle(pink),
"Mac",
"Milk",
).
EnumeratorStyle(purple)
fmt.Println(t)
}
Loading

0 comments on commit feb42a9

Please sign in to comment.