Documentation
¶
Overview ¶
Package appshell composes a common interactive-CLI-tool layout — a header, a full-width input, a scrollable content area, and an optional key-hints footer — out of existing widgets, without introducing any new rendering primitive of its own.
Stability: experimental. Its API may change in any minor release.
Example ¶
An appshell frames content with a title, a scrolling area and an input line.
package main
import (
"fmt"
"strings"
"github.com/ows4444/tui/ansi"
"github.com/ows4444/tui/appshell"
)
func main() {
m := appshell.New("my app", 40, 5)
fmt.Println(strings.Contains(ansi.StripANSI(m.View()), "my app"))
}
Output: true
Index ¶
- type Child
- type Model
- type Router
- func (r Router) Add(id string, c Child) Router
- func (r Router) Bindings() []keymap.Binding
- func (r Router) Focus(id string) Router
- func (r Router) FocusNext() Router
- func (r Router) FocusPrev() Router
- func (r Router) Focused() string
- func (r Router) SetBounds(id string, rect layout.Rect) Router
- func (r Router) SetLayout(root layout.Node, size layout.Size) Router
- func (r Router) SetTheme(t theme.Theme) Router
- func (r Router) Update(msg tui.Msg) (Router, tui.Cmd)
- func (r Router) View(id string) string
- func (r Router) WithTabCycle(on bool) Router
- type SubmitMsg
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Child ¶
Child is what a Router holds: anything that can take a message and render. Build one from a widget with Wrap. A Child that also has SetTheme(theme.Theme) Child receives the Router's theme, and one with Bindings() []keymap.Binding lends its bindings to the Router's own.
func Wrap ¶
Wrap adapts a widget type T (any value with Update(tui.Msg) (T, tui.Cmd) and View() string) to a Child. If T has SetTheme(theme.Theme) T (see tui.ThemeSetter) or is a tui.Themeable whose SetTheme returns a T, the Router's theme reaches it; if T has Bindings() []keymap.Binding the Router reports them while the child is focused.
type Model ¶
type Model struct {
Title string
Input textinput.Model
Content viewport.Model
Hints []widgets.Hint
Theme theme.Theme
// contains filtered or unexported fields
}
Model is a composed application shell: a title rendered via widgets.Header, a single-line Input, a scrollable Content viewport, and an optional row of Hints rendered via widgets.KeyHints.
v1 scope: AppShell composes exactly one input field, and that field is always treated as focused — Update always forwards keys to Input (after handling Enter itself), so there's no separate focus-tracking state.
func New ¶
New returns a Model with an Input and a Content viewport sized to width (content height contentHeight), and the Input focused and ready to type into.
func (Model) LayoutNode ¶
LayoutNode adapts the shell to a layout.Node: the title, the input (which scrolls to fit) and the key hints keep their natural height, and the content fills the space between them. The Model is not changed.
func (Model) Linearize ¶
Linearize renders the shell as plain text for accessible output (see tui.Linearizer): the title, the input's line, the content's lines, and each key hint as "Key: <key>, <action>".
func (Model) SetTheme ¶
SetTheme returns m with t applied to the shell and forwarded to its children: the header reads m.Theme, and the Input's text and placeholder styles are rebuilt from t's Text and Muted roles. The Content viewport renders the caller's own text and has no theme of its own. It makes Model a tui.ThemeSetter, so tui.WithTheme reaches the shell without app code forwarding the theme.
func (Model) Tokens ¶
Tokens returns the colour tokens the widget renders with: its theme's roles, overridden by any theme.WithTokens(theme.ComponentAppShell, ...) and then by WithTokens.
func (Model) Update ¶
Update handles a message. On Enter it emits a SubmitMsg carrying the Input's current value via a Cmd and clears the Input; any other key is forwarded to Input.Update.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router is an opt-in composition router for a screen of several children registered by id. It is a value: every method returns the next Router.
Routing rules, see Update: keys go to the focused child only; mouse events go to the child under the pointer (see SetBounds, SetLayout); every other message, ResizeMsg included, is broadcast to all children. The theme is delivered with SetTheme, to each themeable child once.
func NewRouter ¶
func NewRouter() Router
NewRouter returns an empty Router. The first child added has focus.
func (Router) Add ¶
Add registers c under id, after the children already added. A repeated id replaces that child in place. If SetTheme was called before, c receives the theme now.
func (Router) Bindings ¶
Bindings returns the focused child's bindings when it has them, so a help screen follows focus. It makes Router a tui.BindingsProvider.
func (Router) Focus ¶
Focus gives focus to the child registered as id. An unknown id changes nothing.
func (Router) SetBounds ¶
SetBounds records the rectangle child id occupies, in the same coordinates as the mouse events the Router receives. Unknown ids are recorded too and take effect once a child with that id is added.
func (Router) SetLayout ¶
SetLayout takes every child's rectangle from root laid out at size: the node named with the child's id (layout.Named) gives its rectangle. Children with no such node lose their bounds. The rectangles are relative to root's top-left, so the mouse coordinates must be too.
func (Router) SetTheme ¶
SetTheme delivers t to every child that takes a theme, once each, and to children added later when they are added. Other children are untouched. It makes Router a tui.ThemeSetter[Router].
func (Router) Update ¶
Update routes msg. A Tab or Shift+Tab moves focus when WithTabCycle is on. Any other tui.Key goes to the focused child only. A tui.MouseEvent is routed by position (see SetBounds). Everything else, ResizeMsg and ticks included, is broadcast to every child in order; the Cmds are batched.
func (Router) View ¶
View returns the View of the child registered as id, or "" if unknown. The Router does not lay children out itself; compose the views with package layout.
func (Router) WithTabCycle ¶
WithTabCycle opts in to Tab and Shift+Tab moving focus to the next and previous child (wrapping). Off by default, when Tab goes to the focused child like any other key.