mirror of
https://github.com/zoriya/bubbles.git
synced 2026-08-16 01:43:21 +00:00
wip: filepicker, help, list, table, textarea, textinput, viewport
This commit is contained in:
@@ -29,7 +29,7 @@ func nextID() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new filepicker model with default styling and key bindings.
|
// New returns a new filepicker model with default styling and key bindings.
|
||||||
func New() Model {
|
func New(ctx *tea.Context) Model {
|
||||||
return Model{
|
return Model{
|
||||||
id: nextID(),
|
id: nextID(),
|
||||||
CurrentDirectory: ".",
|
CurrentDirectory: ".",
|
||||||
@@ -49,7 +49,7 @@ func New() Model {
|
|||||||
minStack: newStack(),
|
minStack: newStack(),
|
||||||
maxStack: newStack(),
|
maxStack: newStack(),
|
||||||
KeyMap: DefaultKeyMap(),
|
KeyMap: DefaultKeyMap(),
|
||||||
Styles: DefaultStyles(),
|
Styles: DefaultStyles(ctx.Renderer),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,13 +112,7 @@ type Styles struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DefaultStyles defines the default styling for the file picker.
|
// DefaultStyles defines the default styling for the file picker.
|
||||||
func DefaultStyles() Styles {
|
func DefaultStyles(r *lipgloss.Renderer) Styles {
|
||||||
return DefaultStylesWithRenderer(lipgloss.DefaultRenderer())
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultStylesWithRenderer defines the default styling for the file picker,
|
|
||||||
// with a given Lip Gloss renderer.
|
|
||||||
func DefaultStylesWithRenderer(r *lipgloss.Renderer) Styles {
|
|
||||||
return Styles{
|
return Styles{
|
||||||
DisabledCursor: r.NewStyle().Foreground(lipgloss.Color("247")),
|
DisabledCursor: r.NewStyle().Foreground(lipgloss.Color("247")),
|
||||||
Cursor: r.NewStyle().Foreground(lipgloss.Color("212")),
|
Cursor: r.NewStyle().Foreground(lipgloss.Color("212")),
|
||||||
|
|||||||
+6
-6
@@ -15,7 +15,6 @@ import (
|
|||||||
// Note that if a key is disabled (via key.Binding.SetEnabled) it will not be
|
// Note that if a key is disabled (via key.Binding.SetEnabled) it will not be
|
||||||
// rendered in the help view, so in theory generated help should self-manage.
|
// rendered in the help view, so in theory generated help should self-manage.
|
||||||
type KeyMap interface {
|
type KeyMap interface {
|
||||||
|
|
||||||
// ShortHelp returns a slice of bindings to be displayed in the short
|
// ShortHelp returns a slice of bindings to be displayed in the short
|
||||||
// version of the help. The help bubble will render help in the order in
|
// version of the help. The help bubble will render help in the order in
|
||||||
// which the help items are returned here.
|
// which the help items are returned here.
|
||||||
@@ -58,18 +57,19 @@ type Model struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new help view with some useful defaults.
|
// New creates a new help view with some useful defaults.
|
||||||
func New() Model {
|
func New(ctx *tea.Context) Model {
|
||||||
keyStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{
|
r := ctx.Renderer
|
||||||
|
keyStyle := r.NewStyle().Foreground(lipgloss.AdaptiveColor{
|
||||||
Light: "#909090",
|
Light: "#909090",
|
||||||
Dark: "#626262",
|
Dark: "#626262",
|
||||||
})
|
})
|
||||||
|
|
||||||
descStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{
|
descStyle := r.NewStyle().Foreground(lipgloss.AdaptiveColor{
|
||||||
Light: "#B2B2B2",
|
Light: "#B2B2B2",
|
||||||
Dark: "#4A4A4A",
|
Dark: "#4A4A4A",
|
||||||
})
|
})
|
||||||
|
|
||||||
sepStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{
|
sepStyle := r.NewStyle().Foreground(lipgloss.AdaptiveColor{
|
||||||
Light: "#DDDADA",
|
Light: "#DDDADA",
|
||||||
Dark: "#3C3C3C",
|
Dark: "#3C3C3C",
|
||||||
})
|
})
|
||||||
@@ -118,7 +118,7 @@ func (m Model) ShortHelpView(bindings []key.Binding) string {
|
|||||||
|
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
var totalWidth int
|
var totalWidth int
|
||||||
var separator = m.Styles.ShortSeparator.Inline(true).Render(m.ShortSeparator)
|
separator := m.Styles.ShortSeparator.Inline(true).Render(m.ShortSeparator)
|
||||||
|
|
||||||
for i, kb := range bindings {
|
for i, kb := range bindings {
|
||||||
if !kb.Enabled() {
|
if !kb.Enabled() {
|
||||||
|
|||||||
+4
-4
@@ -195,14 +195,14 @@ type Model struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new model with sensible defaults.
|
// New returns a new model with sensible defaults.
|
||||||
func New(items []Item, delegate ItemDelegate, width, height int) Model {
|
func New(ctx *tea.Context, items []Item, delegate ItemDelegate, width, height int) Model {
|
||||||
styles := DefaultStyles()
|
styles := DefaultStyles(ctx.Renderer)
|
||||||
|
|
||||||
sp := spinner.New()
|
sp := spinner.New()
|
||||||
sp.Spinner = spinner.Line
|
sp.Spinner = spinner.Line
|
||||||
sp.Style = styles.Spinner
|
sp.Style = styles.Spinner
|
||||||
|
|
||||||
filterInput := textinput.New()
|
filterInput := textinput.New(ctx)
|
||||||
filterInput.Prompt = "Filter: "
|
filterInput.Prompt = "Filter: "
|
||||||
filterInput.PromptStyle = styles.FilterPrompt
|
filterInput.PromptStyle = styles.FilterPrompt
|
||||||
filterInput.Cursor.Style = styles.FilterCursor
|
filterInput.Cursor.Style = styles.FilterCursor
|
||||||
@@ -236,7 +236,7 @@ func New(items []Item, delegate ItemDelegate, width, height int) Model {
|
|||||||
items: items,
|
items: items,
|
||||||
Paginator: p,
|
Paginator: p,
|
||||||
spinner: sp,
|
spinner: sp,
|
||||||
Help: help.New(),
|
Help: help.New(ctx),
|
||||||
}
|
}
|
||||||
|
|
||||||
m.updatePagination()
|
m.updatePagination()
|
||||||
|
|||||||
+7
-3
@@ -7,6 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
)
|
)
|
||||||
|
|
||||||
type item string
|
type item string
|
||||||
@@ -29,7 +30,8 @@ func (d itemDelegate) Render(w io.Writer, m Model, index int, listItem Item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStatusBarItemName(t *testing.T) {
|
func TestStatusBarItemName(t *testing.T) {
|
||||||
list := New([]Item{item("foo"), item("bar")}, itemDelegate{}, 10, 10)
|
ctx := &tea.Context{Renderer: lipgloss.DefaultRenderer()}
|
||||||
|
list := New(ctx, []Item{item("foo"), item("bar")}, itemDelegate{}, 10, 10)
|
||||||
expected := "2 items"
|
expected := "2 items"
|
||||||
if !strings.Contains(list.statusView(), expected) {
|
if !strings.Contains(list.statusView(), expected) {
|
||||||
t.Fatalf("Error: expected view to contain %s", expected)
|
t.Fatalf("Error: expected view to contain %s", expected)
|
||||||
@@ -43,7 +45,8 @@ func TestStatusBarItemName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStatusBarWithoutItems(t *testing.T) {
|
func TestStatusBarWithoutItems(t *testing.T) {
|
||||||
list := New([]Item{}, itemDelegate{}, 10, 10)
|
ctx := &tea.Context{Renderer: lipgloss.DefaultRenderer()}
|
||||||
|
list := New(ctx, []Item{}, itemDelegate{}, 10, 10)
|
||||||
|
|
||||||
expected := "No items"
|
expected := "No items"
|
||||||
if !strings.Contains(list.statusView(), expected) {
|
if !strings.Contains(list.statusView(), expected) {
|
||||||
@@ -52,7 +55,8 @@ func TestStatusBarWithoutItems(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCustomStatusBarItemName(t *testing.T) {
|
func TestCustomStatusBarItemName(t *testing.T) {
|
||||||
list := New([]Item{item("foo"), item("bar")}, itemDelegate{}, 10, 10)
|
ctx := &tea.Context{Renderer: lipgloss.DefaultRenderer()}
|
||||||
|
list := New(ctx, []Item{item("foo"), item("bar")}, itemDelegate{}, 10, 10)
|
||||||
list.SetStatusBarItemName("connection", "connections")
|
list.SetStatusBarItemName("connection", "connections")
|
||||||
|
|
||||||
expected := "2 connections"
|
expected := "2 connections"
|
||||||
|
|||||||
+18
-18
@@ -41,57 +41,57 @@ type Styles struct {
|
|||||||
|
|
||||||
// DefaultStyles returns a set of default style definitions for this list
|
// DefaultStyles returns a set of default style definitions for this list
|
||||||
// component.
|
// component.
|
||||||
func DefaultStyles() (s Styles) {
|
func DefaultStyles(r *lipgloss.Renderer) (s Styles) {
|
||||||
verySubduedColor := lipgloss.AdaptiveColor{Light: "#DDDADA", Dark: "#3C3C3C"}
|
verySubduedColor := lipgloss.AdaptiveColor{Light: "#DDDADA", Dark: "#3C3C3C"}
|
||||||
subduedColor := lipgloss.AdaptiveColor{Light: "#9B9B9B", Dark: "#5C5C5C"}
|
subduedColor := lipgloss.AdaptiveColor{Light: "#9B9B9B", Dark: "#5C5C5C"}
|
||||||
|
|
||||||
s.TitleBar = lipgloss.NewStyle().Padding(0, 0, 1, 2)
|
s.TitleBar = r.NewStyle().Padding(0, 0, 1, 2)
|
||||||
|
|
||||||
s.Title = lipgloss.NewStyle().
|
s.Title = r.NewStyle().
|
||||||
Background(lipgloss.Color("62")).
|
Background(lipgloss.Color("62")).
|
||||||
Foreground(lipgloss.Color("230")).
|
Foreground(lipgloss.Color("230")).
|
||||||
Padding(0, 1)
|
Padding(0, 1)
|
||||||
|
|
||||||
s.Spinner = lipgloss.NewStyle().
|
s.Spinner = r.NewStyle().
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#8E8E8E", Dark: "#747373"})
|
Foreground(lipgloss.AdaptiveColor{Light: "#8E8E8E", Dark: "#747373"})
|
||||||
|
|
||||||
s.FilterPrompt = lipgloss.NewStyle().
|
s.FilterPrompt = r.NewStyle().
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#ECFD65"})
|
Foreground(lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#ECFD65"})
|
||||||
|
|
||||||
s.FilterCursor = lipgloss.NewStyle().
|
s.FilterCursor = r.NewStyle().
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#EE6FF8", Dark: "#EE6FF8"})
|
Foreground(lipgloss.AdaptiveColor{Light: "#EE6FF8", Dark: "#EE6FF8"})
|
||||||
|
|
||||||
s.DefaultFilterCharacterMatch = lipgloss.NewStyle().Underline(true)
|
s.DefaultFilterCharacterMatch = r.NewStyle().Underline(true)
|
||||||
|
|
||||||
s.StatusBar = lipgloss.NewStyle().
|
s.StatusBar = r.NewStyle().
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#A49FA5", Dark: "#777777"}).
|
Foreground(lipgloss.AdaptiveColor{Light: "#A49FA5", Dark: "#777777"}).
|
||||||
Padding(0, 0, 1, 2)
|
Padding(0, 0, 1, 2)
|
||||||
|
|
||||||
s.StatusEmpty = lipgloss.NewStyle().Foreground(subduedColor)
|
s.StatusEmpty = r.NewStyle().Foreground(subduedColor)
|
||||||
|
|
||||||
s.StatusBarActiveFilter = lipgloss.NewStyle().
|
s.StatusBarActiveFilter = r.NewStyle().
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#1a1a1a", Dark: "#dddddd"})
|
Foreground(lipgloss.AdaptiveColor{Light: "#1a1a1a", Dark: "#dddddd"})
|
||||||
|
|
||||||
s.StatusBarFilterCount = lipgloss.NewStyle().Foreground(verySubduedColor)
|
s.StatusBarFilterCount = r.NewStyle().Foreground(verySubduedColor)
|
||||||
|
|
||||||
s.NoItems = lipgloss.NewStyle().
|
s.NoItems = r.NewStyle().
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#909090", Dark: "#626262"})
|
Foreground(lipgloss.AdaptiveColor{Light: "#909090", Dark: "#626262"})
|
||||||
|
|
||||||
s.ArabicPagination = lipgloss.NewStyle().Foreground(subduedColor)
|
s.ArabicPagination = r.NewStyle().Foreground(subduedColor)
|
||||||
|
|
||||||
s.PaginationStyle = lipgloss.NewStyle().PaddingLeft(2) //nolint:gomnd
|
s.PaginationStyle = r.NewStyle().PaddingLeft(2) //nolint:gomnd
|
||||||
|
|
||||||
s.HelpStyle = lipgloss.NewStyle().Padding(1, 0, 0, 2)
|
s.HelpStyle = r.NewStyle().Padding(1, 0, 0, 2)
|
||||||
|
|
||||||
s.ActivePaginationDot = lipgloss.NewStyle().
|
s.ActivePaginationDot = r.NewStyle().
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#847A85", Dark: "#979797"}).
|
Foreground(lipgloss.AdaptiveColor{Light: "#847A85", Dark: "#979797"}).
|
||||||
SetString(bullet)
|
SetString(bullet)
|
||||||
|
|
||||||
s.InactivePaginationDot = lipgloss.NewStyle().
|
s.InactivePaginationDot = r.NewStyle().
|
||||||
Foreground(verySubduedColor).
|
Foreground(verySubduedColor).
|
||||||
SetString(bullet)
|
SetString(bullet)
|
||||||
|
|
||||||
s.DividerDot = lipgloss.NewStyle().
|
s.DividerDot = r.NewStyle().
|
||||||
Foreground(verySubduedColor).
|
Foreground(verySubduedColor).
|
||||||
SetString(" " + bullet + " ")
|
SetString(" " + bullet + " ")
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -115,10 +115,10 @@ func (m *Model) SetStyles(s Styles) {
|
|||||||
type Option func(*Model)
|
type Option func(*Model)
|
||||||
|
|
||||||
// New creates a new model for the table widget.
|
// New creates a new model for the table widget.
|
||||||
func New(opts ...Option) Model {
|
func New(ctx *tea.Context, opts ...Option) Model {
|
||||||
m := Model{
|
m := Model{
|
||||||
cursor: 0,
|
cursor: 0,
|
||||||
viewport: viewport.New(0, 20),
|
viewport: viewport.New(ctx, 0, 20),
|
||||||
|
|
||||||
KeyMap: DefaultKeyMap(),
|
KeyMap: DefaultKeyMap(),
|
||||||
styles: DefaultStyles(),
|
styles: DefaultStyles(),
|
||||||
@@ -380,7 +380,7 @@ func (m *Model) FromValues(value, separator string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m Model) headersView() string {
|
func (m Model) headersView() string {
|
||||||
var s = make([]string, 0, len(m.cols))
|
s := make([]string, 0, len(m.cols))
|
||||||
for _, col := range m.cols {
|
for _, col := range m.cols {
|
||||||
style := lipgloss.NewStyle().Width(col.Width).MaxWidth(col.Width).Inline(true)
|
style := lipgloss.NewStyle().Width(col.Width).MaxWidth(col.Width).Inline(true)
|
||||||
renderedCell := style.Render(runewidth.Truncate(col.Title, col.Width, "…"))
|
renderedCell := style.Render(runewidth.Truncate(col.Title, col.Width, "…"))
|
||||||
@@ -390,7 +390,7 @@ func (m Model) headersView() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) renderRow(rowID int) string {
|
func (m *Model) renderRow(rowID int) string {
|
||||||
var s = make([]string, 0, len(m.cols))
|
s := make([]string, 0, len(m.cols))
|
||||||
for i, value := range m.rows[rowID] {
|
for i, value := range m.rows[rowID] {
|
||||||
style := lipgloss.NewStyle().Width(m.cols[i].Width).MaxWidth(m.cols[i].Width).Inline(true)
|
style := lipgloss.NewStyle().Width(m.cols[i].Width).MaxWidth(m.cols[i].Width).Inline(true)
|
||||||
renderedCell := m.styles.Cell.Render(style.Render(runewidth.Truncate(value, m.cols[i].Width, "…")))
|
renderedCell := m.styles.Cell.Render(style.Render(runewidth.Truncate(value, m.cols[i].Width, "…")))
|
||||||
|
|||||||
+10
-3
@@ -1,10 +1,16 @@
|
|||||||
package table
|
package table
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
)
|
||||||
|
|
||||||
func TestFromValues(t *testing.T) {
|
func TestFromValues(t *testing.T) {
|
||||||
input := "foo1,bar1\nfoo2,bar2\nfoo3,bar3"
|
input := "foo1,bar1\nfoo2,bar2\nfoo3,bar3"
|
||||||
table := New(WithColumns([]Column{{Title: "Foo"}, {Title: "Bar"}}))
|
ctx := &tea.Context{Renderer: lipgloss.DefaultRenderer()}
|
||||||
|
table := New(ctx, WithColumns([]Column{{Title: "Foo"}, {Title: "Bar"}}))
|
||||||
table.FromValues(input, ",")
|
table.FromValues(input, ",")
|
||||||
|
|
||||||
if len(table.rows) != 3 {
|
if len(table.rows) != 3 {
|
||||||
@@ -22,8 +28,9 @@ func TestFromValues(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFromValuesWithTabSeparator(t *testing.T) {
|
func TestFromValuesWithTabSeparator(t *testing.T) {
|
||||||
|
ctx := &tea.Context{Renderer: lipgloss.DefaultRenderer()}
|
||||||
input := "foo1.\tbar1\nfoo,bar,baz\tbar,2"
|
input := "foo1.\tbar1\nfoo,bar,baz\tbar,2"
|
||||||
table := New(WithColumns([]Column{{Title: "Foo"}, {Title: "Bar"}}))
|
table := New(ctx, WithColumns([]Column{{Title: "Foo"}, {Title: "Bar"}}))
|
||||||
table.FromValues(input, "\t")
|
table.FromValues(input, "\t")
|
||||||
|
|
||||||
if len(table.rows) != 2 {
|
if len(table.rows) != 2 {
|
||||||
|
|||||||
@@ -29,8 +29,10 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Internal messages for clipboard operations.
|
// Internal messages for clipboard operations.
|
||||||
type pasteMsg string
|
type (
|
||||||
type pasteErrMsg struct{ error }
|
pasteMsg string
|
||||||
|
pasteErrMsg struct{ error }
|
||||||
|
)
|
||||||
|
|
||||||
// KeyMap is the key bindings for different actions within the textarea.
|
// KeyMap is the key bindings for different actions within the textarea.
|
||||||
type KeyMap struct {
|
type KeyMap struct {
|
||||||
@@ -244,12 +246,12 @@ type Model struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new model with default settings.
|
// New creates a new model with default settings.
|
||||||
func New(r *tea.Context) Model {
|
func New(ctx *tea.Context) Model {
|
||||||
vp := viewport.New(0, 0)
|
vp := viewport.New(ctx, 0, 0)
|
||||||
vp.KeyMap = viewport.KeyMap{}
|
vp.KeyMap = viewport.KeyMap{}
|
||||||
cur := cursor.New()
|
cur := cursor.New()
|
||||||
|
|
||||||
focusedStyle, blurredStyle := DefaultStyles(r.Renderer)
|
focusedStyle, blurredStyle := DefaultStyles(ctx.Renderer)
|
||||||
|
|
||||||
m := Model{
|
m := Model{
|
||||||
CharLimit: defaultCharLimit,
|
CharLimit: defaultCharLimit,
|
||||||
@@ -605,8 +607,7 @@ func (m *Model) transposeLeft() {
|
|||||||
if m.col >= len(m.value[m.row]) {
|
if m.col >= len(m.value[m.row]) {
|
||||||
m.SetCursor(m.col - 1)
|
m.SetCursor(m.col - 1)
|
||||||
}
|
}
|
||||||
m.value[m.row][m.col-1], m.value[m.row][m.col] =
|
m.value[m.row][m.col-1], m.value[m.row][m.col] = m.value[m.row][m.col], m.value[m.row][m.col-1]
|
||||||
m.value[m.row][m.col], m.value[m.row][m.col-1]
|
|
||||||
if m.col < len(m.value[m.row]) {
|
if m.col < len(m.value[m.row]) {
|
||||||
m.SetCursor(m.col + 1)
|
m.SetCursor(m.col + 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNew(t *testing.T) {
|
func TestNew(t *testing.T) {
|
||||||
@@ -429,7 +430,9 @@ func TestRendersEndOfLineBuffer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newTextArea() Model {
|
func newTextArea() Model {
|
||||||
textarea := New()
|
textarea := New(&tea.Context{
|
||||||
|
Renderer: lipgloss.DefaultRenderer(),
|
||||||
|
})
|
||||||
|
|
||||||
textarea.Prompt = "> "
|
textarea.Prompt = "> "
|
||||||
textarea.Placeholder = "Hello, World!"
|
textarea.Placeholder = "Hello, World!"
|
||||||
|
|||||||
@@ -17,8 +17,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Internal messages for clipboard operations.
|
// Internal messages for clipboard operations.
|
||||||
type pasteMsg string
|
type (
|
||||||
type pasteErrMsg struct{ error }
|
pasteMsg string
|
||||||
|
pasteErrMsg struct{ error }
|
||||||
|
)
|
||||||
|
|
||||||
// EchoMode sets the input behavior of the text input field.
|
// EchoMode sets the input behavior of the text input field.
|
||||||
type EchoMode int
|
type EchoMode int
|
||||||
@@ -153,14 +155,15 @@ type Model struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new model with default settings.
|
// New creates a new model with default settings.
|
||||||
func New() Model {
|
func New(ctx *tea.Context) Model {
|
||||||
|
r := ctx.Renderer
|
||||||
return Model{
|
return Model{
|
||||||
Prompt: "> ",
|
Prompt: "> ",
|
||||||
EchoCharacter: '*',
|
EchoCharacter: '*',
|
||||||
CharLimit: 0,
|
CharLimit: 0,
|
||||||
PlaceholderStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("240")),
|
PlaceholderStyle: r.NewStyle().Foreground(lipgloss.Color("240")),
|
||||||
ShowSuggestions: false,
|
ShowSuggestions: false,
|
||||||
CompletionStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("240")),
|
CompletionStyle: r.NewStyle().Foreground(lipgloss.Color("240")),
|
||||||
Cursor: cursor.New(),
|
Cursor: cursor.New(),
|
||||||
KeyMap: DefaultKeyMap,
|
KeyMap: DefaultKeyMap,
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ import (
|
|||||||
|
|
||||||
// New returns a new model with the given width and height as well as default
|
// New returns a new model with the given width and height as well as default
|
||||||
// key mappings.
|
// key mappings.
|
||||||
func New(width, height int) (m Model) {
|
func New(ctx *tea.Context, width, height int) (m Model) {
|
||||||
m.Width = width
|
m.Width = width
|
||||||
m.Height = height
|
m.Height = height
|
||||||
|
m.renderer = ctx.Renderer
|
||||||
m.setInitialValues()
|
m.setInitialValues()
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
@@ -54,6 +55,7 @@ type Model struct {
|
|||||||
|
|
||||||
initialized bool
|
initialized bool
|
||||||
lines []string
|
lines []string
|
||||||
|
renderer *lipgloss.Renderer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) setInitialValues() {
|
func (m *Model) setInitialValues() {
|
||||||
@@ -372,7 +374,7 @@ func (m Model) View() string {
|
|||||||
}
|
}
|
||||||
contentWidth := w - m.Style.GetHorizontalFrameSize()
|
contentWidth := w - m.Style.GetHorizontalFrameSize()
|
||||||
contentHeight := h - m.Style.GetVerticalFrameSize()
|
contentHeight := h - m.Style.GetVerticalFrameSize()
|
||||||
contents := lipgloss.NewStyle().
|
contents := m.renderer.NewStyle().
|
||||||
Width(contentWidth). // pad to width.
|
Width(contentWidth). // pad to width.
|
||||||
Height(contentHeight). // pad to height.
|
Height(contentHeight). // pad to height.
|
||||||
MaxHeight(contentHeight). // truncate height if taller.
|
MaxHeight(contentHeight). // truncate height if taller.
|
||||||
|
|||||||
Reference in New Issue
Block a user