ui

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 17, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Default = Theme{
	Online:  lipgloss.Color("#04B575"),
	Idle:    lipgloss.Color("#FFBF00"),
	Offline: lipgloss.Color("#FF5F87"),
	Unknown: lipgloss.AdaptiveColor{Light: "#9A9A9A", Dark: "#6C6C6C"},

	Accent:        lipgloss.Color("#FF5F87"),
	AccentSubtle:  lipgloss.AdaptiveColor{Light: "#5B41DF", Dark: "#7B61FF"},
	Selected:      lipgloss.AdaptiveColor{Light: "#DDD9FF", Dark: "#2D2B55"},
	Border:        lipgloss.AdaptiveColor{Light: "#CCCCCC", Dark: "#3D3D3D"},
	TextPrimary:   lipgloss.AdaptiveColor{Light: "#1A1A1A", Dark: "#FFFDF5"},
	TextSecondary: lipgloss.AdaptiveColor{Light: "#6C6A62", Dark: "#B4B2A9"},
	ModalDimColor: lipgloss.AdaptiveColor{Light: "#e4e4ee", Dark: "#17171f"},
}

Default is the Charm Native theme.

View Source
var Presets = map[string]Theme{
	"default": Default,
	"catppuccin": {
		Online:        lipgloss.Color("#a6e3a1"),
		Idle:          lipgloss.Color("#f9e2af"),
		Offline:       lipgloss.Color("#f38ba8"),
		Unknown:       lipgloss.AdaptiveColor{Light: "#7c7f93", Dark: "#6c7086"},
		Accent:        lipgloss.Color("#cba6f7"),
		AccentSubtle:  lipgloss.AdaptiveColor{Light: "#1e66f5", Dark: "#89b4fa"},
		Selected:      lipgloss.AdaptiveColor{Light: "#dce0e8", Dark: "#313244"},
		Border:        lipgloss.AdaptiveColor{Light: "#bcc0cc", Dark: "#45475a"},
		TextPrimary:   lipgloss.AdaptiveColor{Light: "#4c4f69", Dark: "#cdd6f4"},
		TextSecondary: lipgloss.AdaptiveColor{Light: "#6c6f85", Dark: "#9399b2"},
		ModalDimColor: lipgloss.AdaptiveColor{Light: "#e0e4ec", Dark: "#14141e"},
	},
	"dracula": {
		Online:        lipgloss.Color("#50fa7b"),
		Idle:          lipgloss.Color("#f1fa8c"),
		Offline:       lipgloss.Color("#ff5555"),
		Unknown:       lipgloss.AdaptiveColor{Light: "#6272a4", Dark: "#6272a4"},
		Accent:        lipgloss.Color("#bd93f9"),
		AccentSubtle:  lipgloss.AdaptiveColor{Light: "#6272a4", Dark: "#8be9fd"},
		Selected:      lipgloss.AdaptiveColor{Light: "#f8f8f2", Dark: "#44475a"},
		Border:        lipgloss.AdaptiveColor{Light: "#6272a4", Dark: "#6272a4"},
		TextPrimary:   lipgloss.AdaptiveColor{Light: "#282a36", Dark: "#f8f8f2"},
		TextSecondary: lipgloss.AdaptiveColor{Light: "#6272a4", Dark: "#6272a4"},
		ModalDimColor: lipgloss.AdaptiveColor{Light: "#e8e8f0", Dark: "#161620"},
	},
	"nord": {
		Online:        lipgloss.Color("#a3be8c"),
		Idle:          lipgloss.Color("#ebcb8b"),
		Offline:       lipgloss.Color("#bf616a"),
		Unknown:       lipgloss.AdaptiveColor{Light: "#7b88a1", Dark: "#4c566a"},
		Accent:        lipgloss.Color("#88c0d0"),
		AccentSubtle:  lipgloss.AdaptiveColor{Light: "#5e81ac", Dark: "#81a1c1"},
		Selected:      lipgloss.AdaptiveColor{Light: "#e5e9f0", Dark: "#3b4252"},
		Border:        lipgloss.AdaptiveColor{Light: "#d8dee9", Dark: "#4c566a"},
		TextPrimary:   lipgloss.AdaptiveColor{Light: "#2e3440", Dark: "#eceff4"},
		TextSecondary: lipgloss.AdaptiveColor{Light: "#4c566a", Dark: "#7b88a1"},
		ModalDimColor: lipgloss.AdaptiveColor{Light: "#e8ecf0", Dark: "#181c22"},
	},
}

Presets is the map of named built-in themes selectable via --theme.

View Source
var S = initStyles()

S is the active styles singleton. Omarchy theme is used when detected, falling back to the built-in Default.

Functions

func CreatureLines

func CreatureLines(frame int, state MascotState) [3]string

CreatureLines returns the 3 lines of the small inline creature. Visible width: 4 chars ("╭─╮ " / "│◉│~" / "╰─╯ ").

func NewPeerList

func NewPeerList(peers []tailscale.Peer, height int) list.Model

NewPeerList returns a configured bubbles list.Model for the peer pane.

func PeersToItems

func PeersToItems(peers []tailscale.Peer, flashPeers map[string]bool) []list.Item

PeersToItems converts a peer slice to list items. flashPeers is an optional set of hostnames that should briefly flash their row.

func RenderDetail

func RenderDetail(peer tailscale.Peer, info tailscale.NetworkInfo, showRoutes bool, width int, mascotFrame int, mascotState MascotState, pingFlash bool) string

RenderDetail returns the full content string for the detail viewport.

func RenderHelpBar

func RenderHelpBar(width int, showFull bool) string

RenderHelpBar renders the bottom help bar.

func RenderModalDismissHint added in v1.1.0

func RenderModalDismissHint(width int) string

RenderModalDismissHint renders the help bar for panels that dismiss on any key.

func RenderModalPickHint added in v1.1.0

func RenderModalPickHint(width int, peerHostname, peerOS string) string

RenderModalPickHint renders the help bar while the connection type modal is open.

func RenderModalSSHHint added in v1.1.0

func RenderModalSSHHint(width int) string

RenderModalSSHHint renders the help bar while the SSH credentials form is active.

func RenderNoTailscale

func RenderNoTailscale(errMsg string, width int) string

RenderNoTailscale renders a friendly error panel for when tailscaled isn't reachable.

func RenderStatusBar

func RenderStatusBar(info tailscale.NetworkInfo, errMsg, returnMsg string, width int, frame int, state MascotState, exitFlash, refreshFlash bool) string

RenderStatusBar renders the top status bar.

func SetTheme added in v1.1.0

func SetTheme(name string)

SetTheme applies a named preset theme, overriding Omarchy detection. Call this before model.New() so all rendered styles use the new theme. Unknown names are silently ignored.

func StatusLogoTail

func StatusLogoTail(frame int, state MascotState) string

StatusLogoTail returns the animated tail for use in the status bar logo. Reacts to mascot state: active when pinging, still when offline.

Types

type MascotState added in v1.1.0

type MascotState int

MascotState controls which animation set the creature uses.

const (
	MascotNormal    MascotState = iota // gentle blink, tail wags
	MascotPinging                      // eye flickers ◉/◌ (scanning), tail spins
	MascotOffline                      // sad eye, no tail movement
	MascotReturning                    // excited — rapid eye + tail, mint border
)

type PeerDelegate

type PeerDelegate struct{}

PeerDelegate renders each peer row.

func (PeerDelegate) Height

func (d PeerDelegate) Height() int

func (PeerDelegate) Render

func (d PeerDelegate) Render(w io.Writer, m list.Model, index int, item list.Item)

func (PeerDelegate) Spacing

func (d PeerDelegate) Spacing() int

func (PeerDelegate) Update

func (d PeerDelegate) Update(_ tea.Msg, _ *list.Model) tea.Cmd

type PeerItem

type PeerItem struct {
	Peer     tailscale.Peer
	Flashing bool // briefly true when the peer's online state just changed
}

PeerItem wraps a tailscale.Peer so it implements list.Item.

func (PeerItem) Description

func (p PeerItem) Description() string

func (PeerItem) FilterValue

func (p PeerItem) FilterValue() string

func (PeerItem) Title

func (p PeerItem) Title() string

type Styles

type Styles struct {
	T Theme

	// Status bar
	StatusBar     lipgloss.Style
	StatusOnline  lipgloss.Style
	StatusOffline lipgloss.Style
	StatusMeta    lipgloss.Style

	// Peer list
	ListItem         lipgloss.Style
	ListItemSelected lipgloss.Style
	ListDotOnline    lipgloss.Style
	ListDotIdle      lipgloss.Style
	ListDotOffline   lipgloss.Style
	ListDotUnknown   lipgloss.Style
	ListTag          lipgloss.Style
	ListStatusBar    lipgloss.Style

	// Detail panel
	DetailBorder  lipgloss.Style
	DetailHeader  lipgloss.Style
	DetailSection lipgloss.Style
	DetailLabel   lipgloss.Style
	DetailValue   lipgloss.Style

	// Ping sparkline
	SparkGood lipgloss.Style
	SparkMid  lipgloss.Style
	SparkBad  lipgloss.Style

	// Help bar
	HelpKey  lipgloss.Style
	HelpDesc lipgloss.Style
	HelpSep  lipgloss.Style

	// Panel chrome
	PanelBorder lipgloss.Style

	// Connect popup
	PopupSelected lipgloss.Style
	PopupDim      lipgloss.Style
}

Styles holds all pre-built lipgloss styles derived from the active theme.

func New

func New(t Theme) Styles

New builds a Styles from the given Theme.

type Theme

type Theme struct {
	Online  lipgloss.Color
	Idle    lipgloss.Color
	Offline lipgloss.Color
	Unknown lipgloss.AdaptiveColor

	Accent        lipgloss.Color         // logo, section headers
	AccentSubtle  lipgloss.AdaptiveColor // keys in helpbar, tags
	Selected      lipgloss.AdaptiveColor // selected row bg
	Border        lipgloss.AdaptiveColor // panel dividers
	TextPrimary   lipgloss.AdaptiveColor
	TextSecondary lipgloss.AdaptiveColor
	ModalDimColor lipgloss.AdaptiveColor // background behind centered modal panels
}

Theme holds all color values for a visual theme. A --theme flag can swap this struct out without touching rendering logic.

func LoadOmarchyTheme

func LoadOmarchyTheme() (Theme, bool)

LoadOmarchyTheme attempts to read the active Omarchy theme from ~/.config/omarchy/themes/current/colors.toml and maps it to a Theme. Returns (theme, true) on success, (zero, false) if Omarchy isn't present.

Jump to

Keyboard shortcuts

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