Skip to content

Commit ae9b4c4

Browse files
committed
feat: check box
1 parent 852f643 commit ae9b4c4

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

utils/checkbox.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package utils
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
tea "github.com/charmbracelet/bubbletea"
8+
)
9+
10+
type CheckBox[T any] struct {
11+
Options []T
12+
Cursor int
13+
Selected map[int]bool // Tracks selected indices
14+
}
15+
16+
func NewCheckBox[T any](options []T) *CheckBox[T] {
17+
selected := make(map[int]bool)
18+
for idx := 0; idx < len(options); idx++ {
19+
selected[idx] = false
20+
}
21+
return &CheckBox[T]{
22+
Options: options,
23+
Selected: selected,
24+
Cursor: 0,
25+
}
26+
}
27+
28+
func (s *CheckBox[T]) Select(msg tea.Msg) (*CheckBox[T], tea.Cmd, bool) {
29+
switch msg := msg.(type) {
30+
case tea.KeyMsg:
31+
switch msg.String() {
32+
case "down", "j":
33+
s.Cursor = (s.Cursor + 1) % len(s.Options)
34+
return s, nil, false
35+
case "up", "k":
36+
s.Cursor = (s.Cursor - 1 + len(s.Options)) % len(s.Options)
37+
return s, nil, false
38+
case " ":
39+
s.Selected[s.Cursor] = !s.Selected[s.Cursor]
40+
return s, nil, false
41+
case "q", "ctrl+c":
42+
return s, tea.Quit, false
43+
case "enter":
44+
// If you still need to do something specific when Enter is pressed,
45+
// you can handle it here, or remove this case if it's not needed
46+
return s, nil, true
47+
}
48+
}
49+
return s, nil, false // Default to returning the current state with no command
50+
}
51+
52+
func (s *CheckBox[T]) View() string {
53+
var b strings.Builder
54+
for i, option := range s.Options {
55+
// Mark selected items and the current cursor
56+
cursor := " "
57+
if i == s.Cursor {
58+
cursor = ">"
59+
}
60+
selectedMark := " "
61+
if s.Selected[i] {
62+
selectedMark = "x"
63+
}
64+
b.WriteString(fmt.Sprintf("%s [%s] %v\n", cursor, selectedMark, option))
65+
}
66+
return b.String()
67+
}

0 commit comments

Comments
 (0)