Documentation
¶
Overview ¶
Package components holds the leaf render widgets of the TUI app shell: the status bar and the tab bar. They are pure value types — given a width they return a styled string — so they are trivially unit-testable and hold no Bubble Tea state of their own.
Index ¶
- func MaskValue(raw string) string
- func Pane(st styles.Styles, title, body string, width, height int) string
- func PaneContentLeft() int
- func PaneContentTop() int
- func PaneFocused(st styles.Styles, title, body string, width, height int) string
- func PaneInner(width, height int) (int, int)
- type AWSIdentity
- type EntryList
- func (l *EntryList) Len() int
- func (l *EntryList) Move(delta int) bool
- func (l *EntryList) RowAtLine(line int) (int, bool)
- func (l *EntryList) Scroll(delta int) bool
- func (l *EntryList) SelectIndex(i int) bool
- func (l *EntryList) Selected() int
- func (l *EntryList) SelectedRow() (ListRow, bool)
- func (l *EntryList) SetFocused(focused bool)
- func (l *EntryList) SetRows(rows []ListRow, hasMore bool)
- func (l *EntryList) SetSize(width, height int)
- func (l *EntryList) View() string
- type HistoryEntry
- type HistoryTable
- func (t *HistoryTable) Compare() bool
- func (t *HistoryTable) Len() int
- func (t *HistoryTable) Move(delta int) bool
- func (t *HistoryTable) PickedVersions() (int, int, bool)
- func (t *HistoryTable) RowAtLine(line int) (int, bool)
- func (t *HistoryTable) Scroll(delta int) bool
- func (t *HistoryTable) SelectIndex(i int) bool
- func (t *HistoryTable) Selected() int
- func (t *HistoryTable) SetCompare(on bool)
- func (t *HistoryTable) SetFocused(focused bool)
- func (t *HistoryTable) SetReveal(revealed bool)
- func (t *HistoryTable) SetRows(rows []HistoryEntry)
- func (t *HistoryTable) SetSize(width, height int)
- func (t *HistoryTable) TogglePick()
- func (t *HistoryTable) View() string
- type ListRow
- type StatusBar
- type Tab
- type TabBar
- type ValuePane
- func (p *ValuePane) ContentHeight() int
- func (p *ValuePane) HintSuffix() string
- func (p *ValuePane) Masked() bool
- func (p *ValuePane) RawValue() string
- func (p *ValuePane) SetSize(width, height int)
- func (p *ValuePane) SetValue(raw string, secret bool)
- func (p *ValuePane) ToggleMask()
- func (p *ValuePane) Update(msg tea.Msg) (tea.Cmd, bool)
- func (p *ValuePane) View() string
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func MaskValue ¶
MaskValue masks a (possibly multi-line) value: each line becomes a run of bullets capped at maxMaskWidth, so neither the content nor (beyond the cap) the length reaches the screen. Shared by the value pane and the diff page so a secret diff is masked identically on both sides.
func Pane ¶
Pane frames a titled body inside a rounded border sized to width×height (the OUTER size). The title occupies the first inner line; the body fills the rest. Every content line is normalized to exactly the inner width (truncated or padded) so the border stays rectangular and no line ever re-wraps — the bug that split a right-aligned badge onto its own row. Centralizing the framing keeps every pane identical, which also keeps goldens stable.
func PaneContentLeft ¶
func PaneContentLeft() int
PaneContentLeft is the column a pane's content starts on, measured from the pane's left edge: the left border plus the left interior padding. See PaneContentTop for why hit-testing pages derive origins from these helpers.
func PaneContentTop ¶
func PaneContentTop() int
PaneContentTop is the row a pane's first content line (its title) sits on, measured from the pane's top edge: the top border plus the top interior padding, then the title row for the body beneath it. Pages that hit-test pane content derive their region origins from this (and PaneContentLeft) so the mouse map can never drift from renderPane's actual geometry (#661/#663/#698).
func PaneFocused ¶
PaneFocused frames a pane exactly like Pane but with the focused border, so the pane that currently holds keyboard focus is visually distinct from the idle one.
Types ¶
type AWSIdentity ¶
AWSIdentity carries the async-resolved AWS caller identity shown in the status bar. It is a plain data struct (no SDK types) so the status bar never depends on the AWS provider package; the launch layer fills it via an injected fetcher.
type EntryList ¶
type EntryList struct {
// contains filtered or unexported fields
}
EntryList is a scrollable, single-select list of entry rows. It renders its own selection cursor and hit-tests row clicks against the same layout it draws (so a click reduces to the same selection a key move produces). It holds no Bubble Tea machinery: the page drives it with explicit Move/Select calls.
func NewEntryList ¶
NewEntryList builds an empty list with the given styles.
func (*EntryList) Move ¶
Move changes the selection by delta, clamping at the ends, and keeps the selection visible. It reports whether the viewport actually scrolled (the offset changed), so callers can force a full repaint only when a scroll-region optimization would otherwise fire (see internal/tui/termquirk).
func (*EntryList) RowAtLine ¶
RowAtLine maps a 0-based content line (relative to the list body, i.e. below its title/border) to a row index, or (0, false) when the line is the footer or past the last visible row. A row's name line and its value line both map back to that row, so a click anywhere in a row selects it. Clicks derive their target through this, never a hard-coded coordinate.
func (*EntryList) Scroll ¶
Scroll moves the viewport by delta rows without moving the selection (wheel scrolling), clamped so it never scrolls past the ends. It reports whether the offset actually changed (false when already clamped at an end), so callers can force a full repaint only on a real scroll (see internal/tui/termquirk).
func (*EntryList) SelectIndex ¶
SelectIndex selects a specific index (clamped) and keeps it visible. It reports whether the offset changed (a click on a partially-visible row scrolls it fully into view), so callers can force a full repaint only then (see termquirk).
func (*EntryList) SelectedRow ¶
SelectedRow returns the selected row and true, or a zero row and false when the list is empty.
func (*EntryList) SetFocused ¶
SetFocused sets whether the list pane holds keyboard focus, which selects the active vs dimmed selection style the next View draws with.
func (*EntryList) SetRows ¶
SetRows replaces the rows, clamping the selection into range. hasMore appends the load-more footer; pass true only when the source reports a real next page.
type HistoryEntry ¶
type HistoryEntry struct {
// Label is the version label ("#14" or a shortened id).
Label string
// Date is the pre-formatted date, empty when unknown.
Date string
// Current marks the current version.
Current bool
// Badges are trailing chips (state or staging labels).
Badges []string
// Value is this version's raw value, shown on an indented line beneath the
// version header (masked by default when Secret is set). Empty when there is no
// value to show, in which case no value line is drawn.
Value string
// Secret reports whether Value is secret material, so it is masked with bullets
// unless the table is revealed.
Secret bool
// TagsLine is an indented per-version tag line (Azure Key Vault), empty when
// the provider keeps tags at the resource level.
TagsLine string
}
HistoryEntry is one presentation-ready version row. Badges (state or staging labels) and the per-version tag line are precomputed by the page so the widget never interprets provider metadata.
type HistoryTable ¶
type HistoryTable struct {
// contains filtered or unexported fields
}
HistoryTable is a scrollable, single-select version table with an optional compare mode in which up to two rows are marked for a diff. It renders its own cursor and compare markers and hit-tests row clicks against the same layout it draws.
func NewHistoryTable ¶
func NewHistoryTable(st styles.Styles) HistoryTable
NewHistoryTable builds an empty history table.
func (*HistoryTable) Compare ¶
func (t *HistoryTable) Compare() bool
Compare reports whether compare mode is on.
func (*HistoryTable) Move ¶
func (t *HistoryTable) Move(delta int) bool
Move changes the selection by delta, clamped, keeping it visible. It reports whether the viewport actually scrolled (the offset changed), so callers can force a full repaint only when a scroll-region optimization would otherwise fire (see internal/tui/termquirk).
func (*HistoryTable) PickedVersions ¶
func (t *HistoryTable) PickedVersions() (int, int, bool)
PickedVersions returns the two picked row indices in selection order and true when exactly two rows are marked (ready to diff).
func (*HistoryTable) RowAtLine ¶
func (t *HistoryTable) RowAtLine(line int) (int, bool)
RowAtLine maps a 0-based content line to a row index, or (0, false) when the line is past the last visible row. A row's header, value, and tag lines all map back to that row, so a click anywhere in a row selects it.
func (*HistoryTable) Scroll ¶
func (t *HistoryTable) Scroll(delta int) bool
Scroll wheel-scrolls without moving the selection. It reports whether the offset actually changed (false when already clamped at an end), so callers can force a full repaint only on a real scroll (see internal/tui/termquirk).
func (*HistoryTable) SelectIndex ¶
func (t *HistoryTable) SelectIndex(i int) bool
SelectIndex selects a specific row index (clamped). It reports whether the offset changed (a click on a partially-visible row scrolls it fully into view), so callers can force a full repaint only then (see termquirk).
func (*HistoryTable) Selected ¶
func (t *HistoryTable) Selected() int
Selected returns the selected index, or -1 when empty.
func (*HistoryTable) SetCompare ¶
func (t *HistoryTable) SetCompare(on bool)
SetCompare toggles compare mode; leaving it clears the picks.
func (*HistoryTable) SetFocused ¶
func (t *HistoryTable) SetFocused(focused bool)
SetFocused sets whether the history pane holds keyboard focus, which selects the active vs dimmed selection style the next View draws with.
func (*HistoryTable) SetReveal ¶
func (t *HistoryTable) SetReveal(revealed bool)
SetReveal unmasks (or re-masks) the per-version value lines. The owning page drives it from the detail value pane's mask state, so the shared `x` toggle reveals the current value and the history values together (GUI parity).
func (*HistoryTable) SetRows ¶
func (t *HistoryTable) SetRows(rows []HistoryEntry)
SetRows replaces the rows and resets scrolling/compare picks. Reveal resets to masked so a previous entry's reveal never carries forward onto a new one (mirrors the value pane resetting its mask on SetValue).
func (*HistoryTable) SetSize ¶
func (t *HistoryTable) SetSize(width, height int)
SetSize sets the table's inner content size.
func (*HistoryTable) TogglePick ¶
func (t *HistoryTable) TogglePick()
TogglePick marks/unmarks the selected row for comparison. A third pick evicts the oldest so at most two rows are ever selected.
func (*HistoryTable) View ¶
func (t *HistoryTable) View() string
View renders the table body into width×height.
type ListRow ¶
type ListRow struct {
// Name is the entry name (the primary column).
Name string
// Preview is an optional value preview rendered on an indented SECOND line
// beneath the name (values-mode); empty draws no value line, so the row is a
// single line. The caller flattens/truncates it — an explicit values:on is a
// reveal, so a secret value is shown, mirroring the GUI (#734).
Preview string
// Badges are trailing chips (e.g. "staged", "(NULL)") shown right of the row.
Badges []string
}
ListRow is one presentation-ready entry row. The owning page precomputes the value preview and badges, so the list widget stays dumb.
type StatusBar ¶
type StatusBar struct {
Scope provider.Scope
Styles styles.Styles
// Identity is the resolved AWS caller identity (AWS scope only); nil until
// the async STS lookup returns.
Identity *AWSIdentity
// Loading is true while the AWS identity lookup is in flight, so the bar can
// show a placeholder instead of an empty account.
Loading bool
}
StatusBar renders the fixed top line: the provider and its scope. Provider and scope never change for the process lifetime (they are fixed at launch), so the only mutable input is the AWS identity, which loads asynchronously.
type Tab ¶
Tab is one entry in the tab bar. Service is the internal key the app uses to pick the page for the tab ("param", "secret", or "staging"); Title is the display label (e.g. "Key Vault").
type TabBar ¶
TabBar renders the row of tab labels and hit-tests mouse clicks against them.
type ValuePane ¶
type ValuePane struct {
// contains filtered or unexported fields
}
ValuePane renders an entry value in a scrollable viewport, masked by default. Reveal is per-pane and never persisted by the pane itself; the owning page decides when to reset it (e.g. on selecting another entry). The raw value is held privately and only rendered when revealed, so a masked pane never emits the real value. A revealed value that parses as JSON is ALWAYS pretty-printed (parity with the GUI, which formats every JSON value rather than offering a manual toggle; #732) — formatting is gated behind reveal so a masked secret is never normalized.
func (*ValuePane) ContentHeight ¶
ContentHeight returns the display-line count of the current (masked-or- revealed, formatted) content, so the owning page can size the value pane to its content instead of a fixed height (adaptive value height, #783). It counts the same string display() feeds the viewport, so it tracks the mask/reveal and JSON-formatting state exactly.
func (*ValuePane) HintSuffix ¶
HintSuffix is the "(x to reveal)" hint shown next to the Value label for a masked secret; empty when there is nothing to reveal.
func (*ValuePane) RawValue ¶
RawValue returns the raw value regardless of masking, for the clipboard copy. The copy never changes the mask state, so a masked secret stays masked on screen even after it is copied (#689).
func (*ValuePane) SetValue ¶
SetValue loads a value and whether it is secret (and thus masked by default). A non-secret value is shown formatted-if-JSON; masking is reset to the secret default, so switching entries never carries a previous reveal forward.
func (*ValuePane) ToggleMask ¶
func (p *ValuePane) ToggleMask()
ToggleMask flips masking for a secret value; a non-secret value is never masked, so the toggle is a no-op there.