mirror of
https://github.com/zoriya/bubbles.git
synced 2026-08-16 01:43:21 +00:00
chore(textarea): improve cursor styling API
This commit is contained in:
+27
-34
@@ -154,9 +154,9 @@ type CursorStyle struct {
|
|||||||
// CursorBlink determines whether or not the cursor should blink.
|
// CursorBlink determines whether or not the cursor should blink.
|
||||||
Blink bool
|
Blink bool
|
||||||
|
|
||||||
// BlinkSpeed is the speed at which the virtualcursor blinks. This has no
|
// BlinkSpeed is the speed at which the virtual cursor blinks. This has no
|
||||||
// effect on real cursors as well as no effect if the cursor is set not
|
// effect on real cursors as well as no effect if the cursor is set not to
|
||||||
// to [CursorBlink].
|
// [CursorBlink].
|
||||||
//
|
//
|
||||||
// By default, the blink speed is set to about 500ms.
|
// By default, the blink speed is set to about 500ms.
|
||||||
BlinkSpeed time.Duration
|
BlinkSpeed time.Duration
|
||||||
@@ -168,6 +168,7 @@ type CursorStyle struct {
|
|||||||
type Styles struct {
|
type Styles struct {
|
||||||
Focused StyleState
|
Focused StyleState
|
||||||
Blurred StyleState
|
Blurred StyleState
|
||||||
|
Cursor CursorStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
// StyleState that will be applied to the text area.
|
// StyleState that will be applied to the text area.
|
||||||
@@ -186,7 +187,6 @@ type StyleState struct {
|
|||||||
Placeholder lipgloss.Style
|
Placeholder lipgloss.Style
|
||||||
Prompt lipgloss.Style
|
Prompt lipgloss.Style
|
||||||
Text lipgloss.Style
|
Text lipgloss.Style
|
||||||
Cursor CursorStyle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StyleState) computedCursorLine() lipgloss.Style {
|
func (s StyleState) computedCursorLine() lipgloss.Style {
|
||||||
@@ -264,7 +264,7 @@ type Model struct {
|
|||||||
|
|
||||||
// Styling. FocusedStyle and BlurredStyle are used to style the textarea in
|
// Styling. FocusedStyle and BlurredStyle are used to style the textarea in
|
||||||
// focused and blurred states.
|
// focused and blurred states.
|
||||||
styles Styles
|
Styles Styles
|
||||||
|
|
||||||
// activeStyle is the current styling to use.
|
// activeStyle is the current styling to use.
|
||||||
// It is used to abstract the differences in focus state when styling the
|
// It is used to abstract the differences in focus state when styling the
|
||||||
@@ -345,7 +345,7 @@ func New() Model {
|
|||||||
MaxHeight: defaultMaxHeight,
|
MaxHeight: defaultMaxHeight,
|
||||||
MaxWidth: defaultMaxWidth,
|
MaxWidth: defaultMaxWidth,
|
||||||
Prompt: lipgloss.ThickBorder().Left + " ",
|
Prompt: lipgloss.ThickBorder().Left + " ",
|
||||||
styles: styles,
|
Styles: styles,
|
||||||
activeStyle: &styles.Blurred,
|
activeStyle: &styles.Blurred,
|
||||||
cache: memoization.NewMemoCache[line, [][]rune](maxLines),
|
cache: memoization.NewMemoCache[line, [][]rune](maxLines),
|
||||||
EndOfBufferCharacter: ' ',
|
EndOfBufferCharacter: ' ',
|
||||||
@@ -383,9 +383,6 @@ func DefaultStyles(isDark bool) Styles {
|
|||||||
Placeholder: lipgloss.NewStyle().Foreground(lipgloss.Color("240")),
|
Placeholder: lipgloss.NewStyle().Foreground(lipgloss.Color("240")),
|
||||||
Prompt: lipgloss.NewStyle().Foreground(lipgloss.Color("7")),
|
Prompt: lipgloss.NewStyle().Foreground(lipgloss.Color("7")),
|
||||||
Text: lipgloss.NewStyle(),
|
Text: lipgloss.NewStyle(),
|
||||||
Cursor: CursorStyle{
|
|
||||||
Style: lipgloss.NewStyle().Foreground(lipgloss.Color("7")),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
s.Blurred = StyleState{
|
s.Blurred = StyleState{
|
||||||
Base: lipgloss.NewStyle(),
|
Base: lipgloss.NewStyle(),
|
||||||
@@ -397,6 +394,10 @@ func DefaultStyles(isDark bool) Styles {
|
|||||||
Prompt: lipgloss.NewStyle().Foreground(lipgloss.Color("7")),
|
Prompt: lipgloss.NewStyle().Foreground(lipgloss.Color("7")),
|
||||||
Text: lipgloss.NewStyle().Foreground(lightDark(lipgloss.Color("245"), lipgloss.Color("7"))),
|
Text: lipgloss.NewStyle().Foreground(lightDark(lipgloss.Color("245"), lipgloss.Color("7"))),
|
||||||
}
|
}
|
||||||
|
s.Cursor = CursorStyle{
|
||||||
|
Style: lipgloss.NewStyle().Foreground(lipgloss.Color("7")),
|
||||||
|
Blink: true,
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,40 +411,34 @@ func DefaultDarkStyles() Styles {
|
|||||||
return DefaultStyles(true)
|
return DefaultStyles(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStyles sets the styles for the textarea.
|
// updateVirtualCursorStyle sets styling on the virtual cursor based on the
|
||||||
func (m *Model) SetStyles(s Styles) {
|
// textarea's style settings.
|
||||||
m.styles = s
|
func (m *Model) updateVirtualCursorStyle() {
|
||||||
if m.focus {
|
if !m.VirtualCursor {
|
||||||
m.activeStyle = &m.styles.Focused
|
m.virtualCursor.SetMode(cursor.CursorHide)
|
||||||
} else {
|
return
|
||||||
m.activeStyle = &m.styles.Blurred
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m.virtualCursor.Style = s.Focused.Cursor.Style
|
m.virtualCursor.Style = m.Styles.Cursor.Style
|
||||||
m.virtualCursor.BlinkedStyle = s.Focused.Cursor.BlinkedStyle
|
m.virtualCursor.BlinkedStyle = m.Styles.Cursor.BlinkedStyle
|
||||||
|
|
||||||
// By default, the blink speed of the cursor is set to a default
|
// By default, the blink speed of the cursor is set to a default
|
||||||
// internally.
|
// internally.
|
||||||
if s.Focused.Cursor.BlinkSpeed > 0 {
|
if m.Styles.Cursor.BlinkSpeed > 0 {
|
||||||
m.virtualCursor.BlinkSpeed = m.activeStyle.Cursor.BlinkSpeed
|
m.virtualCursor.BlinkSpeed = m.Styles.Cursor.BlinkSpeed
|
||||||
}
|
}
|
||||||
|
|
||||||
if !m.VirtualCursor {
|
if !m.VirtualCursor {
|
||||||
m.virtualCursor.SetMode(cursor.CursorHide)
|
m.virtualCursor.SetMode(cursor.CursorHide)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.Focused.Cursor.Blink {
|
if m.Styles.Cursor.Blink {
|
||||||
m.virtualCursor.SetMode(cursor.CursorBlink)
|
m.virtualCursor.SetMode(cursor.CursorBlink)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m.virtualCursor.SetMode(cursor.CursorStatic)
|
m.virtualCursor.SetMode(cursor.CursorStatic)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Styles returns the styles for the textarea.
|
|
||||||
func (m Model) Styles() Styles {
|
|
||||||
return m.styles
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValue sets the value of the text input.
|
// SetValue sets the value of the text input.
|
||||||
func (m *Model) SetValue(s string) {
|
func (m *Model) SetValue(s string) {
|
||||||
m.Reset()
|
m.Reset()
|
||||||
@@ -682,7 +677,7 @@ func (m Model) Focused() bool {
|
|||||||
// receive keyboard input and the cursor will be hidden.
|
// receive keyboard input and the cursor will be hidden.
|
||||||
func (m *Model) Focus() tea.Cmd {
|
func (m *Model) Focus() tea.Cmd {
|
||||||
m.focus = true
|
m.focus = true
|
||||||
m.activeStyle = &m.styles.Focused
|
m.activeStyle = &m.Styles.Focused
|
||||||
return m.virtualCursor.Focus()
|
return m.virtualCursor.Focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -690,7 +685,7 @@ func (m *Model) Focus() tea.Cmd {
|
|||||||
// not receive keyboard input and the cursor will be hidden.
|
// not receive keyboard input and the cursor will be hidden.
|
||||||
func (m *Model) Blur() {
|
func (m *Model) Blur() {
|
||||||
m.focus = false
|
m.focus = false
|
||||||
m.activeStyle = &m.styles.Blurred
|
m.activeStyle = &m.Styles.Blurred
|
||||||
m.virtualCursor.Blur()
|
m.virtualCursor.Blur()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1195,6 +1190,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
|
|||||||
|
|
||||||
// View renders the text area in its current state.
|
// View renders the text area in its current state.
|
||||||
func (m Model) View() string {
|
func (m Model) View() string {
|
||||||
|
m.updateVirtualCursorStyle()
|
||||||
if m.Value() == "" && m.row == 0 && m.col == 0 && m.Placeholder != "" {
|
if m.Value() == "" && m.row == 0 && m.col == 0 && m.Placeholder != "" {
|
||||||
return m.placeholderView()
|
return m.placeholderView()
|
||||||
}
|
}
|
||||||
@@ -1422,16 +1418,13 @@ func Blink() tea.Msg {
|
|||||||
// If you're using a real cursor, you should also set [Model.VirtualCursor] to
|
// If you're using a real cursor, you should also set [Model.VirtualCursor] to
|
||||||
// false.
|
// false.
|
||||||
func (m Model) Cursor() *tea.Cursor {
|
func (m Model) Cursor() *tea.Cursor {
|
||||||
if m.VirtualCursor || !m.Focused() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
lineInfo := m.LineInfo()
|
lineInfo := m.LineInfo()
|
||||||
x, y := lineInfo.CharOffset, m.cursorLineNumber()-m.viewport.YOffset
|
x, y := lineInfo.CharOffset, m.cursorLineNumber()-m.viewport.YOffset
|
||||||
|
|
||||||
c := tea.NewCursor(x, y)
|
c := tea.NewCursor(x, y)
|
||||||
c.Blink = m.styles.Focused.Cursor.Blink
|
c.Blink = m.Styles.Cursor.Blink
|
||||||
c.Color = m.styles.Focused.Cursor.Style.GetForeground()
|
c.Color = m.Styles.Cursor.Style.GetForeground()
|
||||||
|
c.Shape = m.Styles.Cursor.Shape
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user