Skip to content

Commit

Permalink
feat: grid layout
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdottv committed May 8, 2024
1 parent 95c02c6 commit 5bbb20a
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
30 changes: 30 additions & 0 deletions examples/layout/grid/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import "github.com/charmbracelet/huh"

func main() {
form := huh.NewForm(
huh.NewGroup(
huh.NewInput().Title("First"),
huh.NewInput().Title("Second"),
huh.NewInput().Title("Third"),
),
huh.NewGroup(
huh.NewInput().Title("Fourth"),
huh.NewInput().Title("Fifth"),
huh.NewInput().Title("Sixth"),
),
huh.NewGroup(
huh.NewInput().Title("Seventh"),
huh.NewInput().Title("Eigth"),
huh.NewInput().Title("Nineth"),
huh.NewInput().Title("Tenth"),
),
huh.NewGroup(
huh.NewInput().Title("Eleventh"),
huh.NewInput().Title("Twelveth"),
huh.NewInput().Title("Thirteenth"),
),
).WithLayout(huh.LayoutGrid(2, 2))
form.Run()
}
58 changes: 58 additions & 0 deletions layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ func LayoutColumns(columns int) Layout {
return &layoutColumns{columns: columns}
}

// Grid layout distributes groups in a grid.
func LayoutGrid(rows int, columns int) Layout {
return &layoutGrid{rows: rows, columns: columns}
}

type layoutDefault struct{}

func (l *layoutDefault) View(f *Form) string {
Expand Down Expand Up @@ -89,3 +94,56 @@ func (l *layoutStack) View(f *Form) string {
func (l *layoutStack) GroupWidth(_ *Form, _ *Group, w int) int {
return w
}

type layoutGrid struct {
rows, columns int
}

func (l *layoutGrid) visibleGroups(f *Form) [][]*Group {
total := l.rows * l.columns
segmentIndex := f.paginator.Page / total
start := segmentIndex * total
end := start + total

if end > len(f.groups) {
end = len(f.groups)
}

visible := f.groups[start:end]
grid := make([][]*Group, l.rows)
for i := 0; i < l.rows; i++ {
startRow := i * l.columns
endRow := startRow + l.columns
if startRow >= len(visible) {
break
}
if endRow > len(visible) {
endRow = len(visible)
}
grid[i] = visible[startRow:endRow]
}
return grid
}

func (l *layoutGrid) View(f *Form) string {
grid := l.visibleGroups(f)
if len(grid) == 0 {
return ""
}

var rows []string
for _, row := range grid {
var columns []string
for _, group := range row {
columns = append(columns, group.Content())
}
rows = append(rows, lipgloss.JoinHorizontal(lipgloss.Top, columns...))
}
footer := f.groups[f.paginator.Page].Footer()

return lipgloss.JoinVertical(lipgloss.Left, strings.Join(rows, "\n"), footer)
}

func (l *layoutGrid) GroupWidth(_ *Form, _ *Group, w int) int {
return w / l.columns
}

0 comments on commit 5bbb20a

Please sign in to comment.