v2.10.2 705579a

table.go RawHistoryFolder

1package components
2
3import (
4	"github.com/bnema/gordon/internal/adapters/in/cli/ui/styles"
5
6	"github.com/charmbracelet/lipgloss"
7	"github.com/charmbracelet/lipgloss/table"
8)
9
10// TableColumn defines a table column.
11type TableColumn struct {
12	Title string
13	Width int
14}
15
16// TableModel is a styled table component.
17type TableModel struct {
18	columns     []TableColumn
19	rows        [][]string
20	border      lipgloss.Border
21	borderStyle lipgloss.Style
22	headerStyle lipgloss.Style
23	cellStyle   lipgloss.Style
24	oddStyle    lipgloss.Style
25	evenStyle   lipgloss.Style
26	width       int
27}
28
29// TableOption configures a TableModel.
30type TableOption func(*TableModel)
31
32// NewTable creates a new styled table.
33func NewTable(opts ...TableOption) *TableModel {
34	t := &TableModel{
35		border:      lipgloss.RoundedBorder(),
36		borderStyle: lipgloss.NewStyle().Foreground(styles.ColorBorder),
37		headerStyle: lipgloss.NewStyle().
38			Bold(true).
39			Foreground(styles.ColorPrimary).
40			Padding(0, 1),
41		cellStyle: lipgloss.NewStyle().
42			Foreground(styles.ColorText).
43			Padding(0, 1),
44		oddStyle: lipgloss.NewStyle().
45			Foreground(styles.ColorText).
46			Padding(0, 1),
47		evenStyle: lipgloss.NewStyle().
48			Foreground(styles.ColorText).
49			Padding(0, 1),
50	}
51
52	for _, opt := range opts {
53		opt(t)
54	}
55
56	return t
57}
58
59// WithColumns sets the table columns.
60func WithColumns(cols []TableColumn) TableOption {
61	return func(t *TableModel) {
62		t.columns = cols
63	}
64}
65
66// WithRows sets the table rows.
67func WithRows(rows [][]string) TableOption {
68	return func(t *TableModel) {
69		t.rows = rows
70	}
71}
72
73// WithBorder sets the table border style.
74func WithBorder(b lipgloss.Border) TableOption {
75	return func(t *TableModel) {
76		t.border = b
77	}
78}
79
80// WithTableWidth sets the table width.
81func WithTableWidth(w int) TableOption {
82	return func(t *TableModel) {
83		t.width = w
84	}
85}
86
87// WithHeaderStyle sets the header style.
88func WithHeaderStyle(s lipgloss.Style) TableOption {
89	return func(t *TableModel) {
90		t.headerStyle = s
91	}
92}
93
94// WithCellStyle sets the cell style.
95func WithCellStyle(s lipgloss.Style) TableOption {
96	return func(t *TableModel) {
97		t.cellStyle = s
98		t.oddStyle = s
99		t.evenStyle = s
100	}
101}
102
103// WithAlternateRows enables alternating row colors.
104func WithAlternateRows(odd, even lipgloss.Style) TableOption {
105	return func(t *TableModel) {
106		t.oddStyle = odd
107		t.evenStyle = even
108	}
109}
110
111// SetColumns sets the table columns.
112func (t *TableModel) SetColumns(cols []TableColumn) {
113	t.columns = cols
114}
115
116// SetRows sets the table rows.
117func (t *TableModel) SetRows(rows [][]string) {
118	t.rows = rows
119}
120
121// AddRow adds a row to the table.
122func (t *TableModel) AddRow(row []string) {
123	t.rows = append(t.rows, row)
124}
125
126// ClearRows removes all rows from the table.
127func (t *TableModel) ClearRows() {
128	t.rows = nil
129}
130
131// Render renders the table as a string.
132func (t *TableModel) Render() string {
133	if len(t.columns) == 0 {
134		return ""
135	}
136
137	// Extract headers
138	headers := make([]string, len(t.columns))
139	for i, col := range t.columns {
140		headers[i] = col.Title
141	}
142
143	// Create table
144	tbl := table.New().
145		Border(t.border).
146		BorderStyle(t.borderStyle).
147		Headers(headers...).
148		Rows(t.rows...).
149		StyleFunc(func(row, col int) lipgloss.Style {
150			if row == table.HeaderRow {
151				return t.headerStyle
152			}
153			if row%2 == 0 {
154				return t.evenStyle
155			}
156			return t.oddStyle
157		})
158
159	// Apply width if set
160	if t.width > 0 {
161		tbl = tbl.Width(t.width)
162	}
163
164	return tbl.String()
165}
166
167// View returns the table view (alias for Render).
168func (t *TableModel) View() string {
169	return t.Render()
170}
171
172// SimpleTable creates a simple table with headers and rows.
173// This is a convenience function for quick table rendering.
174func SimpleTable(headers []string, rows [][]string) string {
175	cols := make([]TableColumn, len(headers))
176	for i, h := range headers {
177		cols[i] = TableColumn{Title: h}
178	}
179
180	t := NewTable(
181		WithColumns(cols),
182		WithRows(rows),
183	)
184
185	return t.Render()
186}
187
188// RouteTable creates a table specifically for displaying routes.
189func RouteTable(routes [][]string) string {
190	return SimpleTable(
191		[]string{"Domain", "Image", "Status"},
192		routes,
193	)
194}
195
196// TokenTable creates a table specifically for displaying tokens.
197func TokenTable(tokens [][]string) string {
198	return SimpleTable(
199		[]string{"ID", "Subject", "Scopes", "Expires", "Revoked"},
200		tokens,
201	)
202}
203
204// SecretTable creates a table specifically for displaying secrets.
205func SecretTable(secrets [][]string) string {
206	return SimpleTable(
207		[]string{"Key", "Value"},
208		secrets,
209	)
210}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close