toast

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2026 License: MIT Imports: 5 Imported by: 0

README

toast

toast
Latest Release Build Status MIT License

Toast-style alert overlays for BubbleTea v2 TUI applications.

Alerts appear at a configurable corner of your terminal UI, animate with a color fade, and disappear automatically after a set duration — with no host-side timer management required.

toast demo

Install

go get github.com/ceffo/toast

Requires Go 1.26+ and charm.land/bubbletea/v2.

Quick start

package main

import (
    "time"

    tea "charm.land/bubbletea/v2"
    "github.com/ceffo/toast"
)

type model struct {
    toast  toast.Model
    width  int
    height int
}

func initialModel() model {
    t := toast.New(60, toast.FontUnicode, 3*time.Second).
        WithPosition(toast.TopRight).
        WithQueueDepth(5).
        WithMinWidth(20).
        WithAllowEscToClose()

    return model{toast: t, width: 80, height: 24}
}

func (m model) Init() tea.Cmd {
    return m.toast.Init()
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    var cmds []tea.Cmd

    switch msg := msg.(type) {
    case tea.KeyPressMsg:
        switch msg.String() {
        case "i":
            cmds = append(cmds, m.toast.NewAlertCmd(toast.InfoAlertUnicode, "everything is fine"))
        case "w":
            cmds = append(cmds, m.toast.NewAlertCmd(toast.WarnAlertUnicode, "disk usage above 80%"))
        case "e":
            cmds = append(cmds, m.toast.NewAlertCmd(toast.ErrorAlertUnicode, "connection refused"))
        case "esc":
            // ESC guard: only quit when no alert is active.
            if !m.toast.HasActiveAlert() {
                return m, tea.Quit
            }
        }
    }

    var toastCmd tea.Cmd
    m.toast, toastCmd = m.toast.Update(msg)
    cmds = append(cmds, toastCmd)

    return m, tea.Batch(cmds...)
}

func (m model) View() tea.View {
    content := "Hello, world!"
    return tea.View{Content: m.toast.Render(content), AltScreen: true}
}

A fully working example is in example/main.go.

API reference

Creating a model
t := toast.New(width int, font toast.FontStyle, duration time.Duration)
Builder Description
.WithPosition(pos) Where alerts appear (default: zero value = TopLeft)
.WithQueueDepth(n) Max queued alerts; oldest is dropped when full (default: 5)
.WithMinWidth(n) Minimum alert box width in columns
.WithAllowEscToClose() Let users dismiss the current alert with Esc
Positions

TopLeft · TopCenter · TopRight · BottomLeft · BottomCenter · BottomRight

Font styles
Constant Glyphs
toast.FontASCII (i) (!) [!!] (?)
toast.FontUnicode ?
toast.FontNerdFont Nerd Font icons
Built-in alert definitions

Each level ships in three font variants: InfoAlertASCII, InfoAlertUnicode, InfoAlertNerdFont, and likewise for Warn, Error, and Debug.

Custom alerts
var SuccessAlert = toast.AlertDefinition{
    Prefix:    "✓",
    ForeColor: "#00FF88",       // hex color string
    Position:  toast.TopCenter, // omit to use the model's default position
}

cmds = append(cmds, m.toast.NewAlertCmd(SuccessAlert, "deployment done"))
Wiring into your model
// 1. Forward Init
func (m model) Init() tea.Cmd { return m.toast.Init() }

// 2. Forward Update (must reassign m.toast)
m.toast, toastCmd = m.toast.Update(msg)

// 3. Render — pass your fully-rendered content string, get the composited result back
return tea.View{Content: m.toast.Render(content), AltScreen: true}

// 4. Fire an alert from any Update branch
cmds = append(cmds, m.toast.NewAlertCmd(toast.WarnAlertUnicode, "something happened"))
ESC guard

When WithAllowEscToClose() is set, pressing Esc dismisses the current alert instead of propagating the key to your app. Use HasActiveAlert() to guard your own Esc handler:

case "esc":
    if !m.toast.HasActiveAlert() {
        return m, tea.Quit // safe to quit — no alert is stealing Esc
    }

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	InfoAlert = AlertLevel{
				// contains filtered or unexported fields
	}

	WarnAlert = AlertLevel{
				// contains filtered or unexported fields
	}

	ErrorAlert = AlertLevel{
				// contains filtered or unexported fields
	}

	DebugAlert = AlertLevel{
				// contains filtered or unexported fields
	}
)

Built-in alert levels — one per severity. Pass to NewAlertCmd; the model resolves the correct variant based on the FontStyle given to New().

Functions

This section is empty.

Types

type AlertDefinition

type AlertDefinition struct {
	Prefix    string
	ForeColor string
	Position  Position // zero value means use the model default
}

AlertDefinition holds the visual configuration for one alert level.

func (AlertDefinition) Resolve added in v0.2.0

Resolve implements AlertSpec. AlertDefinition is already fully specified, so it returns itself regardless of font style.

type AlertLevel added in v0.2.0

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

AlertLevel is a font-style-indexed bundle of three AlertDefinitions — one for ASCII, Unicode, and NerdFont. The model's stored FontStyle determines which variant is used at alert time.

func (AlertLevel) Resolve added in v0.2.0

func (l AlertLevel) Resolve(f FontStyle) AlertDefinition

Resolve implements AlertSpec, picking the variant that matches f.

type AlertSpec added in v0.2.0

type AlertSpec interface {
	Resolve(FontStyle) AlertDefinition
}

AlertSpec is the common interface for anything that can be passed to NewAlertCmd. AlertDefinition satisfies it by returning itself; AlertLevel satisfies it by resolving to the right variant for the model's FontStyle.

type FontStyle

type FontStyle string

FontStyle selects the glyph set used for alert prefixes.

const (
	FontASCII    FontStyle = "ascii"
	FontUnicode  FontStyle = "unicode"
	FontNerdFont FontStyle = "nerdfont"
)

type Model

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

Model holds the toast overlay state.

func New

func New(width int, font FontStyle, duration time.Duration) Model

New creates a Model. font is stored and used by NewAlertCmd to resolve the correct AlertDefinition variant when an AlertLevel is passed.

func (Model) HasActiveAlert

func (m Model) HasActiveAlert() bool

HasActiveAlert reports whether there are any queued alerts.

func (Model) Init

func (m Model) Init() tea.Cmd

Init returns nil — no startup command needed.

func (Model) NewAlertCmd

func (m Model) NewAlertCmd(spec AlertSpec, msg string) tea.Cmd

NewAlertCmd returns a tea.Cmd that enqueues an alert. spec may be an AlertLevel (resolved using the model's FontStyle) or a fully specified AlertDefinition. Uses def.Position if valid, otherwise falls back to the model's position.

func (Model) Render

func (m Model) Render(content string) string

Render overlays the head alert on content and returns the composited string. Returns content unchanged if no alerts are queued.

func (Model) Update

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)

Update handles alertMsg, tickMsg, and esc key.

func (Model) WithAllowEscToClose

func (m Model) WithAllowEscToClose() Model

func (Model) WithMinWidth

func (m Model) WithMinWidth(min int) Model

func (Model) WithPosition

func (m Model) WithPosition(pos Position) Model

func (Model) WithQueueDepth

func (m Model) WithQueueDepth(depth int) Model

type Position

type Position string

Position specifies where on screen an Alert overlay appears.

const (
	// UnspecifiedPosition is the zero value; callers must set a real position.
	UnspecifiedPosition Position = ""

	TopLeft      Position = "top-left"
	TopCenter    Position = "top-center"
	TopRight     Position = "top-right"
	BottomLeft   Position = "bottom-left"
	BottomCenter Position = "bottom-center"
	BottomRight  Position = "bottom-right"
)

func (Position) IsValid

func (p Position) IsValid() bool

IsValid reports whether p is one of the six defined positions.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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