lipgloss/list/list.go
Carlos Alexandro Becker d21c576fdf
feat: trees and lists (#264)
* feat: implement list renderer

* feat: data model for list

* feat: add Offset, Height, Indent

* feat: tree renderer

* fix: list example

* test: last tree node is a subtree

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: tree

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: lint

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* docs: example

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* test: inc cov

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: multiline items

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* feat: one approach to sublists

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: tree improvements

* wip

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* wip

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* wip

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* wip

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: prevent having to pass renderer to all trees

* test: force linux line endings

* fix: windows

* fix: lint issues

* fix: ignore lint issue failing forever

* fix: renames

* fix: renderer

* ci: fix coveralls hopefully

* wip

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: style

* docs: update

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: renderer

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* test: cover with tests

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* feat: more list enumerators

* fix: drop renderer api

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* feat: improve api

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: prealloc

* fix: clean up

* fix: list setup

* fix: improve sublist tests

* fix: improve sublists

* refactor: simplify

* docs: more examples, readme updates

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* docs: readme

* fix: set item style

* fix(tree): do not use golden files

* test: do not use golden files

* refactor: remove unused code

* feat: hide nodes

* feat: filter

* fix: allow fmt.Stringer

* test: table within a tree

* docs: update

* fix: rename atter to data

* test: test public api only

* docs: sublist with table example

* docs: update example

* fix: lint issues

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* docs: update examples

* docs: update

* feat: offset

* feat: offsetstart && offsetend

* fix: remove last from enumerator

* refactor: make tree more explicit

* `New()` now take no args
* added a new `Root(string)` method
* added a new `Items(...any)` method

* refactor: improve list

* docs: fix examples

* test: ensure embed lists in trees

* docs: sublist example with list as tree node

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* refactor: first pass at examples cleanup

* refactor: first pass at examples cleanup

* fix: support multi-line prefixes

* test: more glow-style lists within trees

* docs: simplify examples

* fix: improve handling of different types

* chore: go mod tidy

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* fix: code review suggestions

Co-authored-by: Ayman Bagabas <ayman.bagabas@gmail.com>
Co-authored-by: bashbunni <15822994+bashbunni@users.noreply.github.com>

* fix: apply code review suggestion

* feat(tree): rounded enumerator (#280)

* chore(examples): go mod tidy

* feat(tree): add rounded corner enumerator

* test: rounded enumerator test

* docs: readme updates

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* docs: readme updates

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* chore: fmt

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* docs: godoc

* docs: godoc

* fix: bash's issue

* fix: bad example

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

* docs: improve godoc for trees and lists (#296)

* docs(godoc): add overview

* docs(godoc): include examples in godoc

* docs(godoc): fix roman numerals example

* docs(godoc): fix tree examples

* docs(godoc): attempt to fix list Enumerator examples

* docs: added some examples to godoc

* fix(list): New(items...) with sublist

* docs: update examples

* chore(tree): improve var names in rounded example

* fix: use padding instead of margin to better styles

* fix: lint

---------

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Co-authored-by: Maas Lalani <maas@lalani.dev>
Co-authored-by: Ayman Bagabas <ayman.bagabas@gmail.com>
Co-authored-by: bashbunni <15822994+bashbunni@users.noreply.github.com>
Co-authored-by: Christian Rocha <christian@rocha.is>
2024-05-24 12:02:18 -03:00

167 lines
4.1 KiB
Go

// Package list provides an API to create printable list structures that can be
// included in any command line application. This package includes full support
// for nested lists. Here's how you do it:
//
// l := list.New(
// "A",
// "B",
// "C",
// list.New(
// "D",
// "E",
// "F",
// ).Enumerator(list.Roman),
// )
// fmt.Println(l)
//
// The list package provides built-in enumerator styles to help glamourize your
// lists. This package wraps the tree package with list-specific styling. Lists
// are fully customizable, so let your creativity flow.
package list
import (
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/tree"
)
type (
// Enumerator is the type of enumeration to use for the list styling.
// It is the prefix for the list.
Enumerator func(data Data, i int) string
// List is a list of items.
List struct {
inner *tree.Tree
}
// Data is the interface that wraps the basic methods of a list model.
Data tree.Data
// StyleFunc allows the list to be styled per item.
StyleFunc tree.StyleFunc
)
// Returns true if this node is hidden.
func (n *List) Hidden() bool {
return n.inner.Hidden()
}
// Hide sets whether or not to hide the tree.
// This is useful for collapsing or hiding sub-lists.
func (n *List) Hide(hide bool) *List {
n.inner.Hide(hide)
return n
}
// Offset sets the tree children offsets.
func (n *List) OffsetStart(offset int) *List {
n.inner.OffsetStart(offset)
return n
}
// Offset sets the tree children offsets.
func (n *List) OffsetEnd(offset int) *List {
n.inner.OffsetEnd(offset)
return n
}
// Name returns the root name of this node.
func (n *List) Name() string { return n.inner.Name() }
func (n *List) String() string {
return n.inner.String()
}
// EnumeratorStyle sets the enumeration style.
// Margins and paddings should usually be set only in ItemStyle or ItemStyleFunc.
func (n *List) EnumeratorStyle(style lipgloss.Style) *List {
n.inner.EnumeratorStyle(style)
return n
}
// EnumeratorStyleFunc sets the enumeration style function. Use this function
// for conditional styling.
//
// Margins and paddings should usually be set only in ItemStyle/ItemStyleFunc.
//
// l := list.New().
// EnumeratorStyleFunc(func(_ tree.Data, i int) lipgloss.Style {
// if i == 1 {
// return lipgloss.NewStyle().Foreground(hightlightColor)
// }
// return lipgloss.NewStyle().Foreground(dimColor)
// })
func (n *List) EnumeratorStyleFunc(fn StyleFunc) *List {
n.inner.EnumeratorStyleFunc(tree.StyleFunc(fn))
return n
}
// ItemStyle sets the item style.
//
// l := tree.New("Duck", "Duck", "Duck", "Goose", "Duck").
// ItemStyle(lipgloss.NewStyle().Foreground(lipgloss.Color(255)))
func (n *List) ItemStyle(style lipgloss.Style) *List {
n.inner.ItemStyle(style)
return n
}
// ItemStyleFunc sets the item style function. Use this for conditional styling.
// For example:
//
// l := list.New().
// ItemStyleFunc(func(_ tree.Data, i int) lipgloss.Style {
// st := baseStyle.Copy()
// if selectedIndex == i {
// return st.Foreground(hightlightColor)
// }
// return st.Foreground(dimColor)
// })
func (n *List) ItemStyleFunc(fn StyleFunc) *List {
n.inner.ItemStyleFunc(tree.StyleFunc(fn))
return n
}
// Item appends an item to a list. Lists support nesting.
//
// l := list.New().
// Item("Item 1").
// Item(list.New("Item 1.1", "Item 1.2"))
func (n *List) Item(item any) *List {
switch item := item.(type) {
case *List:
n.inner.Item(item.inner)
default:
n.inner.Item(item)
}
return n
}
// Items add multiple items to the tree.
func (n *List) Items(items ...any) *List {
for _, item := range items {
n.Item(item)
}
return n
}
// Enumerator sets the enumerator implementation. Lipgloss includes
// predefined enumerators including bullets, roman numerals, and more. For
// example, you can have a numbered list:
//
// list.New().
// Enumerator(Arabic)
func (n *List) Enumerator(enum Enumerator) *List {
n.inner.Enumerator(func(data tree.Data, i int) (string, string) {
return " ", enum(data, i)
})
return n
}
// New returns a new list with a bullet enumerator.
func New(items ...any) *List {
l := &List{
inner: tree.New(),
}
return l.Items(items...).Enumerator(Bullet)
}