Documentation
¶
Overview ¶
Package tuiml provides a declarative, type-safe markup language for building terminal user interfaces using Ultraviolet as the rendering engine.
⚠️ EXPERIMENTAL: This is an experimental project, primarily AI-generated as an exploration of declarative TUI frameworks. Use at your own risk.
TUIML allows you to define TUI layouts using familiar XML-like markup syntax combined with Go templates for dynamic content. It integrates seamlessly with Bubble Tea for application lifecycle management while leveraging Ultraviolet's efficient cell-based rendering.
Basic Example ¶
type ViewData struct {
Title string
Content string
}
const tmpl = `
<vstack gap="1">
<box border="rounded">
<text style="bold; fg:cyan">{{ .Title }}</text>
</box>
<text>{{ .Content }}</text>
</vstack>
`
t := tuiml.MustParse[ViewData](tmpl)
data := ViewData{
Title: "Hello World",
Content: "Welcome to TUIML!",
}
output := t.Render(data, 80, 24)
Elements ¶
- vstack: Vertical stack container with gap and alignment
- hstack: Horizontal stack container with gap and alignment
- text: Text content with styling and alignment
- box: Container with borders and padding
- scrollview: Scrollable viewport with scrollbars
- divider: Horizontal or vertical separator line
- spacer: Flexible or fixed empty space
- slot: Placeholder for dynamic content
Styling ¶
Elements support CSS-like inline styling:
<text style="fg:cyan; bg:#1a1b26; bold; italic">Styled text</text>
For programmatic styling, use the StyleBuilder:
style := tuiml.NewStyle().
Fg(tuiml.Hex("#FF5555")).
Bold().
Build()
Custom Components ¶
Register custom components with the component registry:
tuiml.Register("card", func(props Props, children []Element) Element {
return tuiml.NewBox(
tuiml.NewVStack(children...),
).WithBorder("rounded").WithPadding(1)
})
Use in markup:
<card><text>Content</text></card>
Stateful Components ¶
Use slots for stateful components that manage their own state:
type Input struct {
value string
}
func (i *Input) Update(msg tea.Msg) { /* handle events */ }
func (i *Input) Render() tuiml.Element {
return tuiml.NewBox(tuiml.NewText(i.value)).WithBorder("rounded")
}
Template with slot:
<vstack> <text>Enter name:</text> <slot name="input" /> </vstack>
Render with slots:
slots := map[string]tuiml.Element{
"input": m.inputComp.Render(),
}
output := tmpl.RenderWithSlots(data, slots, width, height)
Bubble Tea Integration ¶
type model struct {
template *tuiml.Template[ViewData]
width int
height int
}
func (m model) Init() tea.Cmd {
return tea.RequestWindowSize
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.width = msg.Width
m.height = msg.Height
}
return m, nil
}
func (m model) View() tea.View {
data := ViewData{...}
output := m.template.Render(data, m.width, m.height)
return tea.NewView(output)
}
Package tuiml provides examples and patterns for building interactive TUI components.
Building Interactive Components ¶
When creating custom components that render other elements, you must pass through your component's ID to the root element you return. This ensures that mouse clicks anywhere in your component return your component's ID, not child element IDs.
## Pattern: Pass Through Component ID
type MyComponent struct {
tuiml.BaseElement // Provides ID() and SetID()
// ... your fields
}
func (c *MyComponent) Render() tuiml.Element {
// Build your UI
root := tuiml.NewVStack(
tuiml.NewText(c.label),
tuiml.NewBox(tuiml.NewText(c.value)),
)
// CRITICAL: Set your component's ID on the root element
root.SetID(c.ID())
return root
}
## Why This Matters
HitTest() prefers elements with explicit IDs over auto-generated ones. When multiple elements overlap at a click point:
- Without SetID: Returns child element with auto-generated ID like "elem_0x123..."
- With SetID: Returns your component with meaningful ID like "name-input"
This allows you to handle clicks on the component as a whole, not individual children.
## Example Usage
input := NewInput("Name:")
input.SetID("name-input")
// In template
slots := map[string]tuiml.Element{
"input": input.Render(), // VStack with ID "name-input"
}
// In callback
view.Callback = func(msg tea.Msg) tea.Cmd {
if click, ok := msg.(tea.MouseClickMsg); ok {
elem := boundsMap.HitTest(click.X, click.Y)
// elem.ID() returns "name-input" - exactly what you want!
}
}
See examples/interactive-form for a complete working example.
Index ¶
- Constants
- func ClearRegistry()
- func GetFlexBasis(elem Element) int
- func GetFlexGrow(elem Element) int
- func GetFlexShrink(elem Element) int
- func Hex(s string) color.Color
- func HexSafe(s string) (color.Color, error)
- func IsFlexible(elem Element) bool
- func ParseStyle(s string) (uv.Style, error)
- func RGB(r, g, b uint8) color.Color
- func Register(name string, factory ComponentFactory)
- func RegisteredComponents() []string
- func Unregister(name string)
- type AutoConstraint
- type Badge
- type BaseElement
- type BoundsMap
- func (bm *BoundsMap) AllElements() []ElementWithBounds
- func (bm *BoundsMap) GetBounds(id string) (uv.Rectangle, bool)
- func (bm *BoundsMap) GetByID(id string) (Element, bool)
- func (bm *BoundsMap) HitTest(x, y int) Element
- func (bm *BoundsMap) HitTestAll(x, y int) []Element
- func (bm *BoundsMap) HitTestWithContainer(x, y int) (top Element, container Element)
- func (bm *BoundsMap) Register(elem Element, bounds uv.Rectangle)
- type Box
- func (b *Box) Children() []Element
- func (b *Box) Draw(scr uv.Screen, area uv.Rectangle)
- func (b *Box) Layout(constraints Constraints) Size
- func (b *Box) WithBorder(border string) *Box
- func (b *Box) WithBorderStyle(style uv.Style) *Box
- func (b *Box) WithHeight(height SizeConstraint) *Box
- func (b *Box) WithMargin(margin int) *Box
- func (b *Box) WithMarginBottom(margin int) *Box
- func (b *Box) WithMarginLeft(margin int) *Box
- func (b *Box) WithMarginRight(margin int) *Box
- func (b *Box) WithMarginTop(margin int) *Box
- func (b *Box) WithPadding(padding int) *Box
- func (b *Box) WithWidth(width SizeConstraint) *Box
- type Button
- func (b *Button) Children() []Element
- func (b *Button) Draw(scr uv.Screen, area uv.Rectangle)
- func (b *Button) Layout(constraints Constraints) Size
- func (b *Button) WithActiveStyle(style uv.Style) *Button
- func (b *Button) WithBorder(border string) *Button
- func (b *Button) WithHeight(height SizeConstraint) *Button
- func (b *Button) WithHoverStyle(style uv.Style) *Button
- func (b *Button) WithPadding(padding int) *Button
- func (b *Button) WithStyle(style uv.Style) *Button
- func (b *Button) WithWidth(width SizeConstraint) *Button
- type ComponentFactory
- type Constraint
- type Constraints
- type Divider
- type Element
- func Card(title string, titleStyle, borderStyle uv.Style, children ...Element) Element
- func NewBadge(props Props, children []Element) Element
- func NewButtonFromProps(props Props, children []Element) Element
- func NewHeader(props Props, children []Element) Element
- func NewProgress(props Props, _ []Element) Element
- func Overlay(children ...Element) Element
- func Section(header string, headerStyle uv.Style, children ...Element) Element
- func Separated(children ...Element) Element
- type ElementWithBounds
- type FixedConstraint
- type Flex
- type HStack
- func (h *HStack) Children() []Element
- func (h *HStack) Draw(scr uv.Screen, area uv.Rectangle)
- func (h *HStack) Layout(constraints Constraints) Size
- func (h *HStack) WithGap(gap int) *HStack
- func (h *HStack) WithHeight(height SizeConstraint) *HStack
- func (h *HStack) WithValign(valign string) *HStack
- func (h *HStack) WithWidth(width SizeConstraint) *HStack
- type Header
- type PercentConstraint
- type Positioned
- func (p *Positioned) Children() []Element
- func (p *Positioned) Draw(scr uv.Screen, area uv.Rectangle)
- func (p *Positioned) Layout(_ Constraints) Size
- func (p *Positioned) WithBottom(bottom int) *Positioned
- func (p *Positioned) WithHeight(height SizeConstraint) *Positioned
- func (p *Positioned) WithRight(right int) *Positioned
- func (p *Positioned) WithWidth(width SizeConstraint) *Positioned
- type Progress
- type Props
- type ScrollView
- func (s *ScrollView) Children() []Element
- func (s *ScrollView) ContentSize() Size
- func (s *ScrollView) Draw(scr uv.Screen, area uv.Rectangle)
- func (s *ScrollView) Layout(constraints Constraints) Size
- func (s *ScrollView) ScrollDown(amount int, contentHeight, viewportHeight int)
- func (s *ScrollView) ScrollLeft(amount int)
- func (s *ScrollView) ScrollRight(amount int, contentWidth, viewportWidth int)
- func (s *ScrollView) ScrollUp(amount int)
- func (s *ScrollView) WithHeight(height SizeConstraint) *ScrollView
- func (s *ScrollView) WithHorizontal(enabled bool) *ScrollView
- func (s *ScrollView) WithOffset(x, y int) *ScrollView
- func (s *ScrollView) WithScrollbar(show bool) *ScrollView
- func (s *ScrollView) WithVertical(enabled bool) *ScrollView
- func (s *ScrollView) WithWidth(width SizeConstraint) *ScrollView
- type Size
- type SizeConstraint
- type Slot
- type Spacer
- type StyleBuilder
- func (sb *StyleBuilder) Bg(c color.Color) *StyleBuilder
- func (sb *StyleBuilder) Blink() *StyleBuilder
- func (sb *StyleBuilder) Bold() *StyleBuilder
- func (sb *StyleBuilder) Build() uv.Style
- func (sb *StyleBuilder) Faint() *StyleBuilder
- func (sb *StyleBuilder) Fg(c color.Color) *StyleBuilder
- func (sb *StyleBuilder) Italic() *StyleBuilder
- func (sb *StyleBuilder) Reverse() *StyleBuilder
- func (sb *StyleBuilder) Strikethrough() *StyleBuilder
- func (sb *StyleBuilder) Underline() *StyleBuilder
- func (sb *StyleBuilder) UnderlineColor(c color.Color) *StyleBuilder
- func (sb *StyleBuilder) UnderlineStyle(style uv.Underline) *StyleBuilder
- type Template
- type Text
- type VStack
- func (v *VStack) Children() []Element
- func (v *VStack) Draw(scr uv.Screen, area uv.Rectangle)
- func (v *VStack) Layout(constraints Constraints) Size
- func (v *VStack) WithAlign(align string) *VStack
- func (v *VStack) WithGap(gap int) *VStack
- func (v *VStack) WithHeight(height SizeConstraint) *VStack
- func (v *VStack) WithWidth(width SizeConstraint) *VStack
- type ZStack
- func (z *ZStack) Children() []Element
- func (z *ZStack) Draw(scr uv.Screen, area uv.Rectangle)
- func (z *ZStack) Layout(constraints Constraints) Size
- func (z *ZStack) WithAlign(align string) *ZStack
- func (z *ZStack) WithHeight(height SizeConstraint) *ZStack
- func (z *ZStack) WithValign(valign string) *ZStack
- func (z *ZStack) WithWidth(width SizeConstraint) *ZStack
Constants ¶
const ( BorderNone = "none" BorderNormal = "normal" BorderRounded = "rounded" BorderThick = "thick" BorderDouble = "double" BorderHidden = "hidden" )
Border styles.
const ( AlignLeft = "left" AlignCenter = "center" AlignRight = "right" AlignTop = "top" AlignMiddle = "middle" AlignBottom = "bottom" )
Alignment constants.
const ( UnitAuto = "auto" UnitMin = "min" UnitMax = "max" UnitPercent = "%" )
Size constraint units.
const ( UnderlineNone = "none" UnderlineSingle = "single" UnderlineDouble = "double" UnderlineCurly = "curly" UnderlineDotted = "dotted" UnderlineDashed = "dashed" UnderlineSolid = "solid" )
Underline styles (matching UV).
Variables ¶
This section is empty.
Functions ¶
func ClearRegistry ¶
func ClearRegistry()
ClearRegistry removes all registered components. Useful for testing.
func GetFlexBasis ¶
GetFlexBasis returns the flex-basis value for an element. Returns 0 (auto) if the element is not a Flex wrapper.
func GetFlexGrow ¶
GetFlexGrow returns the flex-grow value for an element. Returns 0 if the element is not a Flex wrapper.
func GetFlexShrink ¶
GetFlexShrink returns the flex-shrink value for an element. Returns 1 if the element is not a Flex wrapper.
func Hex ¶
Hex creates a color from a hex string. Panics if invalid - use HexSafe for error handling.
func IsFlexible ¶
IsFlexible returns true if the element can grow.
func ParseStyle ¶
ParseStyle parses a style string into a UV Style. Format: "fg:red; bg:#1a1b26; bold; italic".
func Register ¶
func Register(name string, factory ComponentFactory)
Register registers a custom component with the given name. The factory function will be called to create instances of the component.
Example:
tuiml.Register("badge", func(props Props, children []Element) Element {
return &Badge{
text: props.Get("text"),
color: props.Get("color"),
}
})
func RegisteredComponents ¶
func RegisteredComponents() []string
RegisteredComponents returns a list of all registered component names.
Types ¶
type AutoConstraint ¶
type AutoConstraint struct{}
AutoConstraint represents content-based sizing.
func (AutoConstraint) Apply ¶
func (a AutoConstraint) Apply(available int) int
Apply returns the available size (will be calculated based on content).
type Badge ¶
type Badge struct {
BaseElement
Text string
Style uv.Style
}
Badge represents a badge element (like "NEW", "BETA", status indicators).
func (*Badge) Layout ¶
func (b *Badge) Layout(constraints Constraints) Size
Layout calculates badge size.
type BaseElement ¶
type BaseElement struct {
// contains filtered or unexported fields
}
BaseElement provides common functionality for all elements. Elements should embed this to get ID and bounds tracking.
func (*BaseElement) Bounds ¶
func (b *BaseElement) Bounds() uv.Rectangle
Bounds returns the element's last rendered bounds.
func (*BaseElement) ID ¶
func (b *BaseElement) ID() string
ID returns the element's identifier. If no ID was explicitly set, returns a pointer-based ID.
func (*BaseElement) SetBounds ¶
func (b *BaseElement) SetBounds(bounds uv.Rectangle)
SetBounds records the element's rendered bounds. This should be called at the start of Draw().
func (*BaseElement) SetID ¶
func (b *BaseElement) SetID(id string)
SetID sets the element's identifier.
type BoundsMap ¶
type BoundsMap struct {
// contains filtered or unexported fields
}
BoundsMap tracks all rendered elements and their positions for hit testing. It is immutable after creation and safe for concurrent reads.
func (*BoundsMap) AllElements ¶
func (bm *BoundsMap) AllElements() []ElementWithBounds
AllElements returns all registered elements with their bounds.
func (*BoundsMap) HitTest ¶
HitTest returns the top-most element at the given screen coordinates. When multiple elements overlap at a point, it prefers elements with explicitly set IDs over auto-generated IDs (elem_*).
This behavior is crucial for interactive components: when you click inside a component's rendered area, you want the component's ID, not its children's. For example, clicking anywhere in an Input component should return the Input's ID, not the Text or Box child inside it.
To achieve this, set your component's ID on the root element it returns:
func (i *Input) Render() tuiml.Element {
vstack := tuiml.NewVStack(...)
vstack.SetID(i.ID()) // Pass through component ID
return vstack
}
Returns nil if no element is found at that position.
func (*BoundsMap) HitTestAll ¶
HitTestAll returns all elements at the given screen coordinates, ordered from top to bottom (first element is visually on top).
This is useful for nested interactive components like scroll views with clickable children, where you need to know both the child that was clicked and the parent containers.
Example usage:
hits := boundsMap.HitTestAll(x, y)
for _, elem := range hits {
switch elem.ID() {
case "list-item-5":
// Handle item click
case "main-scroll-view":
// Also track that we're in the scroll view
}
}
Returns empty slice if no elements are found at that position.
func (*BoundsMap) HitTestWithContainer ¶
HitTestWithContainer returns the top element and the first parent container with an explicit ID. This is useful for scroll views with clickable items where you want to know both what was clicked and which container it's in.
The "top" element is the visually topmost element at the coordinates. The "container" is the first element in the hit stack (after top) that has an explicit ID (not auto-generated with "elem_" prefix).
Example usage:
top, container := boundsMap.HitTestWithContainer(x, y)
if top != nil {
handleClick(top.ID())
}
if container != nil && container.ID() == "scroll-view" {
// We know we clicked inside a scroll view
}
Returns (nil, nil) if no element is found at that position.
type Box ¶
type Box struct {
BaseElement
Child Element
Border string // normal, rounded, thick, double, hidden, none
BorderStyle uv.Style
Width SizeConstraint
Height SizeConstraint
Padding int
Margin int // margin on all sides
MarginTop int
MarginRight int
MarginBottom int
MarginLeft int
}
Box represents a container with an optional border.
func PanelWithMargin ¶
PanelWithMargin creates a box with border, padding, and margin.
func (*Box) Layout ¶
func (b *Box) Layout(constraints Constraints) Size
Layout calculates the box size.
func (*Box) WithBorder ¶
WithBorder sets the border style and returns the box for chaining.
func (*Box) WithBorderStyle ¶
WithBorderStyle sets the border style and returns the box for chaining.
func (*Box) WithHeight ¶
func (b *Box) WithHeight(height SizeConstraint) *Box
WithHeight sets the height constraint and returns the box for chaining.
func (*Box) WithMargin ¶
WithMargin sets the margin on all sides and returns the box for chaining.
func (*Box) WithMarginBottom ¶
WithMarginBottom sets the bottom margin and returns the box for chaining.
func (*Box) WithMarginLeft ¶
WithMarginLeft sets the left margin and returns the box for chaining.
func (*Box) WithMarginRight ¶
WithMarginRight sets the right margin and returns the box for chaining.
func (*Box) WithMarginTop ¶
WithMarginTop sets the top margin and returns the box for chaining.
func (*Box) WithPadding ¶
WithPadding sets the padding and returns the box for chaining.
func (*Box) WithWidth ¶
func (b *Box) WithWidth(width SizeConstraint) *Box
WithWidth sets the width constraint and returns the box for chaining.
type Button ¶
type Button struct {
BaseElement
Text string
Style uv.Style
HoverStyle uv.Style
ActiveStyle uv.Style
Border string
Padding int
Width SizeConstraint
Height SizeConstraint
}
Button represents a clickable button element.
func (*Button) Layout ¶
func (b *Button) Layout(constraints Constraints) Size
Layout calculates button size.
func (*Button) WithActiveStyle ¶
WithActiveStyle sets the active (pressed) style and returns the button for chaining.
func (*Button) WithBorder ¶
WithBorder sets the border type and returns the button for chaining.
func (*Button) WithHeight ¶
func (b *Button) WithHeight(height SizeConstraint) *Button
WithHeight sets the height constraint and returns the button for chaining.
func (*Button) WithHoverStyle ¶
WithHoverStyle sets the hover style and returns the button for chaining.
func (*Button) WithPadding ¶
WithPadding sets the padding and returns the button for chaining.
func (*Button) WithWidth ¶
func (b *Button) WithWidth(width SizeConstraint) *Button
WithWidth sets the width constraint and returns the button for chaining.
type ComponentFactory ¶
ComponentFactory is a function that creates an Element from props and children. Custom components should implement this signature.
func GetComponent ¶
func GetComponent(name string) (ComponentFactory, bool)
GetComponent retrieves a component factory by name. Returns nil if the component is not registered.
type Constraint ¶
type Constraint interface {
// Apply applies the constraint to the given available size.
Apply(available int) int
}
Constraint represents a size constraint that can be applied.
type Constraints ¶
Constraints define the size constraints for layout calculations.
func (Constraints) Constrain ¶
func (c Constraints) Constrain(size Size) Size
Constrain returns a size that satisfies the constraints.
type Divider ¶
type Divider struct {
BaseElement
Vertical bool
Char string
Style uv.Style
}
Divider represents a horizontal or vertical line.
func NewVerticalDivider ¶
func NewVerticalDivider() *Divider
NewVerticalDivider creates a new vertical divider.
func (*Divider) Layout ¶
func (d *Divider) Layout(constraints Constraints) Size
Layout calculates the divider size.
type Element ¶
type Element interface {
uv.Drawable
// Layout calculates the element's desired size within the given constraints.
// It returns the actual size the element will occupy.
Layout(constraints Constraints) Size
// Children returns the child elements for container types.
// Returns nil for leaf elements.
Children() []Element
// ID returns a unique identifier for this element.
// Used for hit testing and event handling.
ID() string
// SetID sets the element's identifier.
SetID(id string)
// Bounds returns the element's last rendered screen coordinates.
// Updated during Draw() and used for mouse hit testing.
Bounds() uv.Rectangle
// SetBounds records the element's rendered bounds.
// This should be called at the start of Draw().
SetBounds(bounds uv.Rectangle)
}
Element represents a renderable component in the TUI. Elements implement the UV Drawable interface and can be composed into trees.
func NewButtonFromProps ¶
NewButtonFromProps creates a button from props (for parser).
func NewProgress ¶
NewProgress creates a progress bar component.
type ElementWithBounds ¶
ElementWithBounds pairs an element with its rendered bounds.
type FixedConstraint ¶
type FixedConstraint int
FixedConstraint represents a fixed size in cells.
func (FixedConstraint) Apply ¶
func (f FixedConstraint) Apply(available int) int
Apply returns the fixed size, clamped to available space.
type Flex ¶
type Flex struct {
BaseElement
Child Element
Grow int // flex-grow: how much to grow relative to siblings (default 0 = no grow)
Shrink int // flex-shrink: how much to shrink relative to siblings (default 1)
Basis int // flex-basis: initial size before flex calculation (default 0 = auto)
}
Flex represents an element wrapper that supports flex-grow and flex-shrink. Use this to make elements flexible within VStack or HStack.
func (*Flex) Layout ¶
func (f *Flex) Layout(constraints Constraints) Size
Layout calculates the flex child size.
func (*Flex) WithShrink ¶
WithShrink sets the flex-shrink and returns the flex for chaining.
type HStack ¶
type HStack struct {
BaseElement
Items []Element
Gap int
Width SizeConstraint
Height SizeConstraint
Valign string // top, middle, bottom (vertical alignment of children)
}
HStack represents a horizontal stack container.
func (*HStack) Layout ¶
func (h *HStack) Layout(constraints Constraints) Size
Layout calculates the total size of the horizontal stack.
func (*HStack) WithHeight ¶
func (h *HStack) WithHeight(height SizeConstraint) *HStack
WithHeight sets the height constraint and returns the hstack for chaining.
func (*HStack) WithValign ¶
WithValign sets the vertical alignment and returns the hstack for chaining.
func (*HStack) WithWidth ¶
func (h *HStack) WithWidth(width SizeConstraint) *HStack
WithWidth sets the width constraint and returns the hstack for chaining.
type Header ¶
type Header struct {
BaseElement
Text string
Level int // 1-6, like HTML
Style uv.Style
Border bool
}
Header is a styled header component.
func (*Header) Layout ¶
func (h *Header) Layout(constraints Constraints) Size
Layout calculates header size.
type PercentConstraint ¶
type PercentConstraint int
PercentConstraint represents a percentage of available space (0-100).
func (PercentConstraint) Apply ¶
func (p PercentConstraint) Apply(available int) int
Apply returns the percentage of available space.
type Positioned ¶
type Positioned struct {
BaseElement
Child Element
X int // X position (cells from left)
Y int // Y position (cells from top)
Right int // Distance from right edge (if >= 0, overrides X)
Bottom int // Distance from bottom edge (if >= 0, overrides Y)
Width SizeConstraint
Height SizeConstraint
}
Positioned represents an absolutely positioned element. The element is positioned at specific coordinates relative to its parent.
func NewPositioned ¶
func NewPositioned(child Element, x, y int) *Positioned
NewPositioned creates a new absolutely positioned element.
func Position ¶
func Position(child Element, x, y int) *Positioned
Position creates an absolutely positioned element.
func PositionBottom ¶
func PositionBottom(child Element, x, bottom int) *Positioned
PositionBottom creates an element positioned relative to the bottom edge.
func PositionCorner ¶
func PositionCorner(child Element, right, bottom int) *Positioned
PositionCorner creates an element positioned at a corner.
func PositionRight ¶
func PositionRight(child Element, right, y int) *Positioned
PositionRight creates an element positioned relative to the right edge.
func (*Positioned) Children ¶
func (p *Positioned) Children() []Element
Children returns the child element.
func (*Positioned) Draw ¶
func (p *Positioned) Draw(scr uv.Screen, area uv.Rectangle)
Draw renders the positioned element.
func (*Positioned) Layout ¶
func (p *Positioned) Layout(_ Constraints) Size
Layout calculates the positioned element size. Positioned elements don't affect parent layout - they return 0 size.
func (*Positioned) WithBottom ¶
func (p *Positioned) WithBottom(bottom int) *Positioned
WithBottom sets the bottom edge distance and returns the positioned element for chaining. When set (>= 0), this overrides the Y position.
func (*Positioned) WithHeight ¶
func (p *Positioned) WithHeight(height SizeConstraint) *Positioned
WithHeight sets the height constraint and returns the positioned element for chaining.
func (*Positioned) WithRight ¶
func (p *Positioned) WithRight(right int) *Positioned
WithRight sets the right edge distance and returns the positioned element for chaining. When set (>= 0), this overrides the X position.
func (*Positioned) WithWidth ¶
func (p *Positioned) WithWidth(width SizeConstraint) *Positioned
WithWidth sets the width constraint and returns the positioned element for chaining.
type Progress ¶
type Progress struct {
BaseElement
Value int
Max int
Width SizeConstraint
Style uv.Style
Char string
}
Progress represents a progress bar element.
func (*Progress) Layout ¶
func (p *Progress) Layout(constraints Constraints) Size
Layout calculates progress bar size.
type Props ¶
Props is a map of properties passed to elements.
type ScrollView ¶
type ScrollView struct {
BaseElement
Child Element
// Scroll position
OffsetX int
OffsetY int
// Viewport size constraints
Width SizeConstraint
Height SizeConstraint
// Scrollbar options
ShowScrollbar bool
ScrollbarStyle uv.Style
// Scroll direction
Horizontal bool // If true, scrolls horizontally
Vertical bool // If true, scrolls vertically (default)
}
ScrollView represents a scrollable container. Content can be larger than the viewport and will be clipped.
func NewScrollView ¶
func NewScrollView(child Element) *ScrollView
NewScrollView creates a new scrollable view.
func (*ScrollView) Children ¶
func (s *ScrollView) Children() []Element
Children returns the child element.
func (*ScrollView) ContentSize ¶
func (s *ScrollView) ContentSize() Size
ContentSize returns the full size of the content.
func (*ScrollView) Draw ¶
func (s *ScrollView) Draw(scr uv.Screen, area uv.Rectangle)
Draw renders the scrollable view.
func (*ScrollView) Layout ¶
func (s *ScrollView) Layout(constraints Constraints) Size
Layout calculates the scroll view size.
func (*ScrollView) ScrollDown ¶
func (s *ScrollView) ScrollDown(amount int, contentHeight, viewportHeight int)
ScrollDown scrolls down by the given amount.
func (*ScrollView) ScrollLeft ¶
func (s *ScrollView) ScrollLeft(amount int)
ScrollLeft scrolls left by the given amount.
func (*ScrollView) ScrollRight ¶
func (s *ScrollView) ScrollRight(amount int, contentWidth, viewportWidth int)
ScrollRight scrolls right by the given amount.
func (*ScrollView) ScrollUp ¶
func (s *ScrollView) ScrollUp(amount int)
ScrollUp scrolls up by the given amount.
func (*ScrollView) WithHeight ¶
func (s *ScrollView) WithHeight(height SizeConstraint) *ScrollView
WithHeight sets the height constraint.
func (*ScrollView) WithHorizontal ¶
func (s *ScrollView) WithHorizontal(enabled bool) *ScrollView
WithHorizontal enables/disables horizontal scrolling.
func (*ScrollView) WithOffset ¶
func (s *ScrollView) WithOffset(x, y int) *ScrollView
WithOffset sets the scroll offset and returns the scroll view for chaining.
func (*ScrollView) WithScrollbar ¶
func (s *ScrollView) WithScrollbar(show bool) *ScrollView
WithScrollbar enables/disables scrollbar.
func (*ScrollView) WithVertical ¶
func (s *ScrollView) WithVertical(enabled bool) *ScrollView
WithVertical enables/disables vertical scrolling.
func (*ScrollView) WithWidth ¶
func (s *ScrollView) WithWidth(width SizeConstraint) *ScrollView
WithWidth sets the width constraint.
type SizeConstraint ¶
type SizeConstraint struct {
// contains filtered or unexported fields
}
SizeConstraint represents a size constraint with units.
func NewFixedConstraint ¶
func NewFixedConstraint(size int) SizeConstraint
NewFixedConstraint creates a fixed size constraint.
func NewPercentConstraint ¶
func NewPercentConstraint(percent int) SizeConstraint
NewPercentConstraint creates a percentage constraint.
func (SizeConstraint) Apply ¶
func (sc SizeConstraint) Apply(available, content int) int
Apply applies the size constraint to get an actual size.
func (SizeConstraint) IsAuto ¶
func (sc SizeConstraint) IsAuto() bool
IsAuto returns true if this is an auto constraint.
func (SizeConstraint) IsFixed ¶
func (sc SizeConstraint) IsFixed() bool
IsFixed returns true if this is a fixed size constraint.
func (SizeConstraint) IsPercent ¶
func (sc SizeConstraint) IsPercent() bool
IsPercent returns true if this is a percentage constraint.
func (SizeConstraint) String ¶
func (sc SizeConstraint) String() string
String returns a string representation.
type Slot ¶
type Slot struct {
BaseElement
Name string
// contains filtered or unexported fields
}
Slot represents a placeholder for dynamic content. Slots are filled with Elements passed via RenderWithSlots.
func (*Slot) Layout ¶
func (s *Slot) Layout(constraints Constraints) Size
Layout calculates the slot's element size if it exists.
type Spacer ¶
type Spacer struct {
BaseElement
Size int // fixed size, 0 means flexible
}
Spacer represents empty space that can grow to fill available space.
func NewFixedSpacer ¶
NewFixedSpacer creates a new spacer with fixed size.
func (*Spacer) Layout ¶
func (s *Spacer) Layout(constraints Constraints) Size
Layout calculates the spacer size.
type StyleBuilder ¶
type StyleBuilder struct {
// contains filtered or unexported fields
}
StyleBuilder provides a fluent API for building styles.
func (*StyleBuilder) Bg ¶
func (sb *StyleBuilder) Bg(c color.Color) *StyleBuilder
Bg sets the background color.
func (*StyleBuilder) Blink ¶
func (sb *StyleBuilder) Blink() *StyleBuilder
Blink makes the text blink.
func (*StyleBuilder) Build ¶
func (sb *StyleBuilder) Build() uv.Style
Build returns the built style.
func (*StyleBuilder) Faint ¶
func (sb *StyleBuilder) Faint() *StyleBuilder
Faint makes the text faint/dim.
func (*StyleBuilder) Fg ¶
func (sb *StyleBuilder) Fg(c color.Color) *StyleBuilder
Fg sets the foreground color.
func (*StyleBuilder) Italic ¶
func (sb *StyleBuilder) Italic() *StyleBuilder
Italic makes the text italic.
func (*StyleBuilder) Reverse ¶
func (sb *StyleBuilder) Reverse() *StyleBuilder
Reverse reverses foreground and background.
func (*StyleBuilder) Strikethrough ¶
func (sb *StyleBuilder) Strikethrough() *StyleBuilder
Strikethrough adds strikethrough.
func (*StyleBuilder) Underline ¶
func (sb *StyleBuilder) Underline() *StyleBuilder
Underline sets single underline.
func (*StyleBuilder) UnderlineColor ¶
func (sb *StyleBuilder) UnderlineColor(c color.Color) *StyleBuilder
UnderlineColor sets the underline color.
func (*StyleBuilder) UnderlineStyle ¶
func (sb *StyleBuilder) UnderlineStyle(style uv.Underline) *StyleBuilder
UnderlineStyle sets the underline style.
type Template ¶
type Template[T any] struct { // contains filtered or unexported fields }
Template is a type-safe TUIML template that can be rendered with data of type T.
func MustParseWithFuncs ¶
MustParseWithFuncs parses TUIML markup with custom functions and panics on error.
func Parse ¶
Parse parses TUIML markup into a type-safe template. The markup can contain Go template syntax like {{ .Variable }}.
func ParseWithFuncs ¶
ParseWithFuncs parses TUIML markup with custom template functions.
func (*Template[T]) Render ¶
Render renders the template with the given data to the specified viewport size.
func (*Template[T]) RenderWithBounds ¶
func (t *Template[T]) RenderWithBounds(data T, slots map[string]Element, width, height int) (uv.ScreenBuffer, *BoundsMap)
RenderWithBounds renders the template and returns both the screen buffer and bounds map. The bounds map can be used for mouse hit testing in event handlers.
type Text ¶
type Text struct {
BaseElement
Content string
Style uv.Style
Wrap bool
Align string // left, center, right
}
Text represents a text element.
func (*Text) Layout ¶
func (t *Text) Layout(constraints Constraints) Size
Layout calculates the text size.
type VStack ¶
type VStack struct {
BaseElement
Items []Element
Gap int
Width SizeConstraint
Height SizeConstraint
Align string // left, center, right (horizontal alignment of children)
}
VStack represents a vertical stack container.
func (*VStack) Layout ¶
func (v *VStack) Layout(constraints Constraints) Size
Layout calculates the total size of the vertical stack.
func (*VStack) WithHeight ¶
func (v *VStack) WithHeight(height SizeConstraint) *VStack
WithHeight sets the height constraint and returns the vstack for chaining.
func (*VStack) WithWidth ¶
func (v *VStack) WithWidth(width SizeConstraint) *VStack
WithWidth sets the width constraint and returns the vstack for chaining.
type ZStack ¶
type ZStack struct {
BaseElement
Items []Element
Width SizeConstraint
Height SizeConstraint
Align string // Horizontal alignment: left, center, right
Valign string // Vertical alignment: top, middle, bottom
}
ZStack represents a layered stack container where children are drawn on top of each other. Later children in the stack are drawn on top of earlier children.
func (*ZStack) Layout ¶
func (z *ZStack) Layout(constraints Constraints) Size
Layout calculates the total size of the layered stack. ZStack takes the maximum width and height of all children.
func (*ZStack) WithAlign ¶
WithAlign sets the horizontal alignment and returns the zstack for chaining.
func (*ZStack) WithHeight ¶
func (z *ZStack) WithHeight(height SizeConstraint) *ZStack
WithHeight sets the height constraint and returns the zstack for chaining.
func (*ZStack) WithValign ¶
WithValign sets the vertical alignment and returns the zstack for chaining.
func (*ZStack) WithWidth ¶
func (z *ZStack) WithWidth(width SizeConstraint) *ZStack
WithWidth sets the width constraint and returns the zstack for chaining.