mirror of
https://github.com/Maks1mS/bubbles.git
synced 2025-10-18 16:38:56 +03:00
Compare commits
1 Commits
stable-v0.
...
list-lint-
Author | SHA1 | Date | |
---|---|---|---|
|
2e55803b28 |
@@ -66,7 +66,7 @@ Supports "dot-style" pagination (similar to what you might see on iOS) and
|
|||||||
numeric page numbering, but you could also just use this component for the
|
numeric page numbering, but you could also just use this component for the
|
||||||
logic and visualize pagination however you like.
|
logic and visualize pagination however you like.
|
||||||
|
|
||||||
* [Example code](https://github.com/charmbracelet/bubbletea/blob/master/examples/paginator/main.go)
|
* [Example code](https://github.com/charmbracelet/bubbletea/blob/master/examples/pager/main.go)
|
||||||
|
|
||||||
|
|
||||||
## Viewport
|
## Viewport
|
||||||
|
@@ -8,8 +8,8 @@ import (
|
|||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Internal ID management. Used during animating to ensure that frame messages
|
// Internal ID management for text inputs. Necessary for blink integrity when
|
||||||
// are received only by spinner components that sent them.
|
// multiple text inputs are involved.
|
||||||
var (
|
var (
|
||||||
lastID int
|
lastID int
|
||||||
idMtx sync.Mutex
|
idMtx sync.Mutex
|
||||||
@@ -67,22 +67,6 @@ var (
|
|||||||
Frames: []string{"🙈", "🙉", "🙊"},
|
Frames: []string{"🙈", "🙉", "🙊"},
|
||||||
FPS: time.Second / 3, //nolint:gomnd
|
FPS: time.Second / 3, //nolint:gomnd
|
||||||
}
|
}
|
||||||
Meter = Spinner{
|
|
||||||
Frames: []string{
|
|
||||||
"▱▱▱",
|
|
||||||
"▰▱▱",
|
|
||||||
"▰▰▱",
|
|
||||||
"▰▰▰",
|
|
||||||
"▰▰▱",
|
|
||||||
"▰▱▱",
|
|
||||||
"▱▱▱",
|
|
||||||
},
|
|
||||||
FPS: time.Second / 7, //nolint:gomnd
|
|
||||||
}
|
|
||||||
Hamburger = Spinner{
|
|
||||||
Frames: []string{"☱", "☲", "☴", "☲"},
|
|
||||||
FPS: time.Second / 3, //nolint:gomnd
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Model contains the state for the spinner. Use NewModel to create new models
|
// Model contains the state for the spinner. Use NewModel to create new models
|
||||||
@@ -109,17 +93,11 @@ func (m Model) ID() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a model with default values.
|
// New returns a model with default values.
|
||||||
func New(opts ...Option) Model {
|
func New() Model {
|
||||||
m := Model{
|
return Model{
|
||||||
Spinner: Line,
|
Spinner: Line,
|
||||||
id: nextID(),
|
id: nextID(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt(&m)
|
|
||||||
}
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewModel returns a model with default values.
|
// NewModel returns a model with default values.
|
||||||
@@ -205,23 +183,3 @@ func (m Model) tick(id, tag int) tea.Cmd {
|
|||||||
func Tick() tea.Msg {
|
func Tick() tea.Msg {
|
||||||
return TickMsg{Time: time.Now()}
|
return TickMsg{Time: time.Now()}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option is used to set options in New. For example:
|
|
||||||
//
|
|
||||||
// spinner := New(WithSpinner(Dot))
|
|
||||||
//
|
|
||||||
type Option func(*Model)
|
|
||||||
|
|
||||||
// WithSpinner is an option to set the spinner.
|
|
||||||
func WithSpinner(spinner Spinner) Option {
|
|
||||||
return func(m *Model) {
|
|
||||||
m.Spinner = spinner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithStyle is an option to set the spinner style.
|
|
||||||
func WithStyle(style lipgloss.Style) Option {
|
|
||||||
return func(m *Model) {
|
|
||||||
m.Style = style
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -1,61 +0,0 @@
|
|||||||
package spinner_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/spinner"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSpinnerNew(t *testing.T) {
|
|
||||||
assertEqualSpinner := func(t *testing.T, exp, got spinner.Spinner) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
if exp.FPS != got.FPS {
|
|
||||||
t.Errorf("expecting %d FPS, got %d", exp.FPS, got.FPS)
|
|
||||||
}
|
|
||||||
|
|
||||||
if e, g := len(exp.Frames), len(got.Frames); e != g {
|
|
||||||
t.Fatalf("expecting %d frames, got %d", e, g)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, e := range exp.Frames {
|
|
||||||
if g := got.Frames[i]; e != g {
|
|
||||||
t.Errorf("expecting frame index %d with value %q, got %q", i, e, g)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.Run("default", func(t *testing.T) {
|
|
||||||
s := spinner.New()
|
|
||||||
|
|
||||||
assertEqualSpinner(t, spinner.Line, s.Spinner)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("WithSpinner", func(t *testing.T) {
|
|
||||||
customSpinner := spinner.Spinner{
|
|
||||||
Frames: []string{"a", "b", "c", "d"},
|
|
||||||
FPS: 16,
|
|
||||||
}
|
|
||||||
|
|
||||||
s := spinner.New(spinner.WithSpinner(customSpinner))
|
|
||||||
|
|
||||||
assertEqualSpinner(t, customSpinner, s.Spinner)
|
|
||||||
})
|
|
||||||
|
|
||||||
tests := map[string]spinner.Spinner{
|
|
||||||
"Line": spinner.Line,
|
|
||||||
"Dot": spinner.Dot,
|
|
||||||
"MiniDot": spinner.MiniDot,
|
|
||||||
"Jump": spinner.Jump,
|
|
||||||
"Pulse": spinner.Pulse,
|
|
||||||
"Points": spinner.Points,
|
|
||||||
"Globe": spinner.Globe,
|
|
||||||
"Moon": spinner.Moon,
|
|
||||||
"Monkey": spinner.Monkey,
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, s := range tests {
|
|
||||||
t.Run(name, func(t *testing.T) {
|
|
||||||
assertEqualSpinner(t, spinner.New(spinner.WithSpinner(s)).Spinner, s)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@@ -205,7 +205,7 @@ func (m *Model) SetValue(s string) {
|
|||||||
} else {
|
} else {
|
||||||
m.value = runes
|
m.value = runes
|
||||||
}
|
}
|
||||||
if m.pos == 0 || m.pos > len(m.value) {
|
if (m.pos == 0 && len(m.value) == 0) || m.pos > len(m.value) {
|
||||||
m.setCursor(len(m.value))
|
m.setCursor(len(m.value))
|
||||||
}
|
}
|
||||||
m.handleOverflow()
|
m.handleOverflow()
|
||||||
|
@@ -162,7 +162,9 @@ func (m *Model) Start() tea.Cmd {
|
|||||||
|
|
||||||
// Stop pauses the timer. Has no effect if the timer has timed out.
|
// Stop pauses the timer. Has no effect if the timer has timed out.
|
||||||
func (m *Model) Stop() tea.Cmd {
|
func (m *Model) Stop() tea.Cmd {
|
||||||
return m.startStop(false)
|
return func() tea.Msg {
|
||||||
|
return m.startStop(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle stops the timer if it's running and starts it if it's stopped.
|
// Toggle stops the timer if it's running and starts it if it's stopped.
|
||||||
|
Reference in New Issue
Block a user