orvyn

package module
v0.0.0-...-9a879d8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2026 License: MIT Imports: 7 Imported by: 0

README

Orvyn - Complex TUI app development made simple

Orvyn is built on top of BubbleTea (https://github.com/charmbracelet/bubbletea), helping develop complex TUI applications. Depending on Lipgloss (https://github.com/charmbracelet/lipgloss) and Bubbles (https://github.com/charmbracelet/bubbles) too.

Orvyn purpose is to streamline the bubble tea development by allowing complex layout management and organizing the application with widgets. Creation of custom widgets and layouts is simple and ergonomic.

Orvyn comes with a powerful focus manager that helps bring to life your most complex TUI ideas. Packaged with a good amount of common widgets, ready to use and customizable to your will.

State of the project

The v1.0 is released and is in a stable state.

Want to know more about Orvyn

Try to catch me on stream : https://www.twitch.tv/halstendev

Documentation

Overview

Package orvyn is a layer on top of BubbleTea to help building complex tui applications.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ProcessExit determines if orvyn should manage the global exit keybind.
	ProcessExit bool

	// ExitKeybind to manage global exit
	ExitKeybind key.Binding

	// WindowSize hold the size of the Window.
	WindowSize Size
)
View Source
var VGap = NewSimpleRenderable("\n")

VGap is a SimpleRenderable representing a new line. Useful for layout building.

Functions

func CloseDialog

func CloseDialog() tea.Cmd

func DivideSizeFull

func DivideSizeFull(size int) (int, int)

DivideSizeFull is a helper function that allow to divide a size in 2. The first size returned will have the compensentation to avoid float result.

func GetKeyMsg

func GetKeyMsg(msg tea.Msg) (tea.KeyMsg, bool)

func GetTheme

func GetTheme() theme.Theme

func Init

func Init()

Init function is used to initialize orvyn and make it useable.

func OpenDialog

func OpenDialog(dialogID ScreenID, dialogScreen Screen, param any) tea.Cmd

func RegisterScreen

func RegisterScreen(id ScreenID, screen Screen)

RegisterScreen allows to register a Screen with the given ScreenID.

func Render

func Render() string

func SetPreviousScreen

func SetPreviousScreen(id ScreenID)

func SetTheme

func SetTheme(theme theme.Theme)

func SwitchScreen

func SwitchScreen(id ScreenID) tea.Cmd

SwitchScreen change the currently active screen and called OnExit and OnEnter.

func SwitchToPreviousScreen

func SwitchToPreviousScreen() tea.Cmd

func TickCmd

func TickCmd(seconds time.Duration, tag uint) tea.Cmd

TickCmd should be returned in update function to ensure the tick continues. Be sure to check and increment the tick tag when responding to the message.

func (s *Screen) Update(msg tea.Msg) tea.Cmd {
	switch msg := msg.(type) {
	case orvyn.TickMsg:
		if msg.Tag != s.tickTag {
			return nil
		}

		s.updateData()

		s.tickTag++
		return orvyn.TickCmd(tick, s.tickTag)
	}
}

func Update

func Update(msg tea.Msg) tea.Cmd

Types

type Activable

type Activable interface {
	// SetActive defines the active status of the Activable.
	SetActive(bool)

	// IsActive returns the active status of the Activable.
	IsActive() bool
}

Activable interface represents something that can be active or not.

type BaseActivable

type BaseActivable struct {
	// contains filtered or unexported fields
}

BaseActivable interface represents the basic implementation of an Activable. To avoid code repetition.

func NewBaseActivable

func NewBaseActivable() BaseActivable

NewBaseActivable creates a new BaseActivable.

func (*BaseActivable) IsActive

func (b *BaseActivable) IsActive() bool

func (*BaseActivable) SetActive

func (b *BaseActivable) SetActive(active bool)

type BaseFocusable

type BaseFocusable struct {
	// contains filtered or unexported fields
}

BaseFocusable can be integrated to a Widget to make it focusable.

func NewBaseFocusable

func NewBaseFocusable(widget Widget) BaseFocusable

func (*BaseFocusable) CanExitInputting

func (b *BaseFocusable) CanExitInputting() bool

func (*BaseFocusable) GetEnterInputKeybind

func (b *BaseFocusable) GetEnterInputKeybind() *key.Binding

func (*BaseFocusable) GetExitInputKeybind

func (b *BaseFocusable) GetExitInputKeybind() key.Binding

func (*BaseFocusable) GetFocusKeybind

func (b *BaseFocusable) GetFocusKeybind() *key.Binding

func (*BaseFocusable) IsFocused

func (b *BaseFocusable) IsFocused() bool

func (*BaseFocusable) IsInputting

func (b *BaseFocusable) IsInputting() bool

func (*BaseFocusable) OnBlur

func (b *BaseFocusable) OnBlur()

func (*BaseFocusable) OnEnterInput

func (b *BaseFocusable) OnEnterInput() tea.Cmd

func (*BaseFocusable) OnExitInput

func (b *BaseFocusable) OnExitInput() tea.Cmd

func (*BaseFocusable) OnFocus

func (b *BaseFocusable) OnFocus()

func (*BaseFocusable) SetBlurredStyle

func (b *BaseFocusable) SetBlurredStyle(style lipgloss.Style)

func (*BaseFocusable) SetFocusedStyle

func (b *BaseFocusable) SetFocusedStyle(style lipgloss.Style)

type BaseLayout

type BaseLayout struct {
	BaseRenderable
	// contains filtered or unexported fields
}

BaseLayout type is used to simplify the creation of custom layouts.

func NewBaseLayout

func NewBaseLayout(elements ...Renderable) BaseLayout

NewBaseLayout creates and returns a new BaseLayout.

func (*BaseLayout) GetElements

func (b *BaseLayout) GetElements() []Renderable

GetElements returns a slice of activated []Renderable.

func (*BaseLayout) SetActive

func (b *BaseLayout) SetActive(active bool)

SetActive change the active state of all elements of the layout and the layout itself.

type BaseRenderable

type BaseRenderable struct {
	BaseActivable
	// contains filtered or unexported fields
}

BaseRenderable is usefull to bring default implementation of the Renderable interface.

func NewBaseRenderable

func NewBaseRenderable() BaseRenderable

NewBaseRenderable creates and returns a new BaseRenderable.

func (*BaseRenderable) GetMinSize

func (b *BaseRenderable) GetMinSize() Size

func (*BaseRenderable) GetPreferredSize

func (b *BaseRenderable) GetPreferredSize() Size

func (*BaseRenderable) GetSize

func (b *BaseRenderable) GetSize() Size

func (*BaseRenderable) Resize

func (b *BaseRenderable) Resize(size Size)

func (*BaseRenderable) SetMinSize

func (b *BaseRenderable) SetMinSize(size Size)

func (*BaseRenderable) SetPreferredSize

func (b *BaseRenderable) SetPreferredSize(size Size)

type BaseWidget

type BaseWidget struct {
	BaseRenderable
	// contains filtered or unexported fields
}

BaseWidget helps building custom widgets.

func NewBaseWidget

func NewBaseWidget() BaseWidget

NewBaseWidget creates and returns a new BaseWidget.

func (*BaseWidget) GetContentSize

func (b *BaseWidget) GetContentSize() Size

func (*BaseWidget) GetStyle

func (b *BaseWidget) GetStyle() lipgloss.Style

func (*BaseWidget) Init

func (b *BaseWidget) Init() tea.Cmd

func (*BaseWidget) Resize

func (b *BaseWidget) Resize(size Size)

func (*BaseWidget) SetStyle

func (b *BaseWidget) SetStyle(style lipgloss.Style)

func (*BaseWidget) Update

func (b *BaseWidget) Update(msg tea.Msg) tea.Cmd

type DialogExitMsg

type DialogExitMsg struct {
	DialogID ScreenID
	Param    any
}

DialogExitMsg is the message sent when an Orvyn dialog is exited.

type FocusManager

type FocusManager struct {
	// NextFocusKeybind holds the key.Binding to loop through the Focusable Widgets.
	// Tab by default.
	NextFocusKeybind key.Binding

	// PreviousFocusKeybind holds the key.Binding to loop through the Focusable Widgets.
	// Shift+Tab by default.
	PreviousFocusKeybind key.Binding

	// ManageFocusNextPrevKeybind grants the focusManager to react to the NextFocusKeybind and PreviousFocusKeybind.
	// True by default.
	ManageFocusNextPrevKeybind bool
	// contains filtered or unexported fields
}

FocusManager can be instantiated when needed on a Screen to manage focus on multiple widgets. Manages focus and input mode of registred widgets.

func NewFocusManager

func NewFocusManager() *FocusManager

NewFocusManager creates and return a new *FocusManager.

func (*FocusManager) Add

func (f *FocusManager) Add(widget Focusable)

Add appends the given Focusable Widget to the manager. Order of append defines the focus order.

func (*FocusManager) BlurCurrent

func (f *FocusManager) BlurCurrent()

BlurCurrent simply blur the currently focused widget.

func (*FocusManager) ExitCurrentInput

func (f *FocusManager) ExitCurrentInput()

ExitCurrentInput simply exits the currently inputting widget.

func (*FocusManager) Focus

func (f *FocusManager) Focus(index int)

Focus set the focus on the Focusable Widget at the given index.

func (*FocusManager) FocusFirst

func (f *FocusManager) FocusFirst()

FocusFirst gives the focus to the first active widget.

func (*FocusManager) ForceInput

func (f *FocusManager) ForceInput(index int)

ForceInput forces the widget to enter input mode.

func (*FocusManager) Insert

func (f *FocusManager) Insert(index int, widget Focusable)

Insert adds a Focusable Widget at the given index. Change the focus order.

func (*FocusManager) IsInputting

func (f *FocusManager) IsInputting() bool

IsInputting returns true if a widget is in inputting mode.

func (*FocusManager) NextFocus

func (f *FocusManager) NextFocus()

NextFocus moves the focus to the next widget.

func (*FocusManager) PrevFocus

func (f *FocusManager) PrevFocus()

PrevFocus moves the focus to the previous widget.

func (*FocusManager) Remove

func (f *FocusManager) Remove(index int)

Remove the widget from the manager at the given index. Automatically focus the previous widget, if the given index is the currently focused widget.

func (*FocusManager) RemoveWidget

func (f *FocusManager) RemoveWidget(widget Focusable)

RemoveWidget removes the widget from the manager base on the given Focusable. Need to be a pointer for this function to work as expected.

func (*FocusManager) SetWidgets

func (f *FocusManager) SetWidgets(widgets []Focusable)

SetWidgets replaces the manager widget list with the one given. Given list order defines the focus order.

func (*FocusManager) TabIndex

func (f *FocusManager) TabIndex() int

TabIndex returns the current tab index of the manager.

func (*FocusManager) Update

func (f *FocusManager) Update(msg tea.Msg) tea.Cmd

Update needs to be called in the screen or widget update function.

func (s *Screen) Update(msg tea.Msg) tea.Cmd {
	switch msg := msg.(type) {
	case tea.KeyMsg:
		switch {
		case key.Matches(msg, keybind.Esc):
			return orvyn.SwitchToPreviousScreen()

		case key.Matches(msg, keybind.Enter):
			ok := s.submit()

			if ok {
				return orvyn.SwitchToPreviousScreen()
			}

			return nil
		}
	}

	cmd := s.focusManager.Update(msg)

	return cmd
}

func (*FocusManager) UpdateWidget

func (f *FocusManager) UpdateWidget(index int, widget Focusable)

Update allows to change the widget at the given index, whitout changing the focus order.

type Focusable

type Focusable interface {
	// Updatable to be able to update a focusable widget.
	Updatable

	// Activable to be able to activate or deactivate widget.
	Activable

	// OnFocus is called to make the widget react to the focus gain.
	OnFocus()

	// OnBlur is called to make the widget react to the loss of focus.
	OnBlur()

	// OnEnterInput is called when the widget enters the input mode.
	// Input mode means that all the tea.Msg will be managed by the widget.
	// Returns a tea.Cmd.
	OnEnterInput() tea.Cmd

	// OnExitInput is called when the widget exits the input mode.
	// Returns a tea.Cmd.
	OnExitInput() tea.Cmd

	// IsFocused return true if the widget is currently focused.
	// A widget can be focused without being in input mode.
	IsFocused() bool

	// IsInputting return true if the widget is in input mode.
	// Input mode means that all the tea.Msg will be managed by the widget.
	IsInputting() bool

	// GetFocusKeybind can return a *key.Binding if the widget should be
	// able to get directly focused with one key.
	GetFocusKeybind() *key.Binding

	// GetEnterInputKeybind can return a *key.Binding if the widget should be
	// able to enter the input mode.
	// Input mode means that all the tea.Msg will be managed by the widget.
	GetEnterInputKeybind() *key.Binding

	// GetExitInputKeybind returns by default "Esc". Can be overridden.
	GetExitInputKeybind() key.Binding

	// CanExitInputting returns true if the widget can exit his inputting state.
	CanExitInputting() bool

	// SetFocusedStyle allows to set the style when the widget is focused. By default theme.FocusedWidgetStyleID.
	SetFocusedStyle(lipgloss.Style)

	// SetBlurredStyle allows to set the style when the widget is blurred. By default theme.BlurredWidgetStyleID.
	SetBlurredStyle(lipgloss.Style)
	// contains filtered or unexported methods
}

Focusable interface represents the capacity to get and loose the focus.

type Layout

type Layout interface {
	// Renderable composing the Layout interface.
	Renderable

	// GetElements returns a slice of every active Renderable of the layout.
	GetElements() []Renderable
}

Layout interface based on Renderable interface.

type Renderable

type Renderable interface {
	// Activable compose the Renderable with the Activable interface
	Activable

	// Render is the way the renderable should be rendered.
	Render() string

	// Resize will be called when the renderable is resized by a layout.
	Resize(Size)

	// GetSize returns the current size of the Renderable.
	GetSize() Size

	// SetMinSize allows to set the minimal size of the Renderable.
	SetMinSize(Size)

	// GetMinSize returns the minimal size of the Renderable.
	GetMinSize() Size

	// SetPreferredSize allows to set the preferred size of the Renderable.
	SetPreferredSize(Size)

	// GetPreferredSize returns the preferred size of the Renderable.
	GetPreferredSize() Size
}

Renderable interface defines any orvyn element that can be rendered.

type Screen

type Screen interface {
	// OnEnter is called when the screen is entered. Can take as parameter a struct from the previous screen.
	OnEnter(any) tea.Cmd

	// OnExit is called when the screen is being exited. Can return a struct that will be passed to the next screen.
	OnExit() any

	// Updatable so the Screen can be updated.
	Updatable

	// Render returns the view string of the whole screen.
	Render() Layout
}

Screen interface defines behaviour of an Orvyn Screen.

func GetScreen

func GetScreen(id ScreenID) Screen

GetScreen returns the Screen for the given registered ScreenID.

type ScreenID

type ScreenID string

ScreenID type represents an ID for a screen.

func GetCurrentScreenID

func GetCurrentScreenID() ScreenID

GetCurrentScreenID returns the currently active ScreenID.

func GetPreviousScreen

func GetPreviousScreen() ScreenID

type SimpleRenderable

type SimpleRenderable struct {
	// BaseRenderable composing
	BaseRenderable

	// Style is the style that will be used to render the value of the SimpleRenderable.
	Style lipgloss.Style

	// SizeConstraint define if the style width and height should be taken into account when rendering the SimpleRenderable.
	SizeConstraint bool
	// contains filtered or unexported fields
}

SimpleRenderable represents a very basic and reusable renderable.

func NewSimpleRenderable

func NewSimpleRenderable(value string) *SimpleRenderable

NewSimpleRenderable creates a new SimpleRenderable and returns it.

func (*SimpleRenderable) GetMinSize

func (s *SimpleRenderable) GetMinSize() Size

func (*SimpleRenderable) GetPreferredSize

func (s *SimpleRenderable) GetPreferredSize() Size

func (*SimpleRenderable) Render

func (s *SimpleRenderable) Render() string

func (*SimpleRenderable) SetValue

func (s *SimpleRenderable) SetValue(value string)

SetValue changes the current value with the given one.

type Size

type Size struct {
	Width  int
	Height int
}

Size is a simple struct to represent a size.

func GetRenderSize

func GetRenderSize(style lipgloss.Style, value string) Size

GetRenderSize returns the Size of a value drawn with a given style.

func NewSize

func NewSize(width, height int) Size

NewSize returns a new Size.

type TickMsg

type TickMsg struct {
	Time time.Time
	Tag  uint
}

TickMsg simplify and assure the right tick msg management with a unique Tag.

type Updatable

type Updatable interface {
	Update(tea.Msg) tea.Cmd
}

Updatable interface gives ability to being updated.

type Widget

type Widget interface {
	// Init is called on the Widget when entering a Screen that contains it.
	Init() tea.Cmd

	// SetStyle allows to set the style of the base widget. By default theme.BlurredWidgetStyleID.
	SetStyle(lipgloss.Style)

	// GetStyle returns the widget style for custom rendering.
	GetStyle() lipgloss.Style

	// GetContentSize must be used when rendering the widget to get the real available size for the widgets content.
	// Borders of the style have been taken into account.
	GetContentSize() Size

	// Updatable so Widget can be updated.
	Updatable

	// Renderable so Widget can be rendered.
	Renderable
}

Widget interface defines behaviour of a widget.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL