CLI Layout Engine
A proof of concept for integrating a CSS-based layout engine with terminal UIs in Go. This project demonstrates how to build beautifully laid out terminal interfaces using CSS Grid, Flexbox, and the box model.
Features
- CSS-based Layouts: Full support for Flexbox and Grid layouts in the terminal
- Advanced Color Support: OKLCH color gradients and wide-gamut color spaces via the
color library
- Unicode Text Support: Proper handling of emoji sequences, CJK characters, and grapheme clusters via the
text library
- Responsive Design: Automatically relayouts on terminal resize
- Component System: Reusable UI components (collapsible sections, loading indicators, progress bars)
- Smart Rendering: Efficient screen buffer with ANSI escape code optimization
- Animation Support: 30fps animation timeline for loading indicators and transitions
Architecture
Core Components
-
renderer/: Core rendering system
style.go - Visual styling (colors, borders, text attributes)
ansi.go - ANSI escape code generation
screen.go - Screen buffer and rendering logic
-
components/: Reusable UI components
message.go - Styled message blocks
loading.go - Loading indicators, spinners, progress bars
collapsible.go - Expandable/collapsible sections
-
examples/: Demo applications
demo.go - Codex CLI-like UI demonstration
Design Principles
-
Separation of Concerns
- Layout engine handles sizing, positioning, and spacing
- Style system handles colors, borders, and visual effects
- No property duplication between systems
-
Professional Color Handling
- Perceptually uniform color operations using OKLCH
- Support for CSS color parsing
- Wide-gamut color space support
-
Responsive by Default
- Layouts automatically adapt to terminal size
- Bubbletea integration for resize events
Dependencies
- layout - CSS Grid/Flexbox layout engine
- color - Professional color manipulation
- text - Unicode-aware text measurement and rendering
- bubbletea - Terminal UI framework
Running the Demo
cd examples
go build -o demo ./cmd/demo
./demo
Demo Controls
- '1' - Toggle first collapsible section
- '2' - Toggle second collapsible section
- Space - Toggle all sections
- 'q' or ESC or Ctrl+C - Quit
Example Usage
Creating a Simple Layout
package main
import (
"github.com/SCKelemen/cli/renderer"
"github.com/SCKelemen/cli/components"
"github.com/SCKelemen/layout"
"github.com/SCKelemen/color"
)
func main() {
// Create a message block
msg := components.NewMessageBlock("Hello, World!")
// Create layout tree
root := &layout.Node{
Style: layout.Style{
Display: layout.DisplayFlex,
FlexDirection: layout.FlexDirectionColumn,
Width: 80,
Height: 24,
Padding: layout.Uniform(2),
},
}
rootStyled := renderer.NewStyledNode(root, nil)
rootStyled.AddChild(msg.ToStyledNode())
// Compute layout
layout.Layout(root, layout.Tight(80, 24))
// Render to screen
screen := renderer.NewScreen(80, 24)
screen.Render(rootStyled)
print(screen.String())
}
Creating Custom Components
type CustomComponent struct {
Title string
Color *color.Color
}
func (c *CustomComponent) ToStyledNode() *renderer.StyledNode {
node := &layout.Node{
Style: layout.Style{
Display: layout.DisplayBlock,
Width: 40,
Height: 3,
},
}
style := &renderer.Style{
Foreground: c.Color,
Bold: true,
}
style.WithBorder(renderer.RoundedBorder)
styledNode := renderer.NewStyledNode(node, style)
styledNode.Content = c.Title
return styledNode
}
Current Features in Layout Engine
The layout engine (github.com/SCKelemen/layout) includes:
- ✅ Text-based units:
em, rem, ch for font-relative sizing
- ✅ Viewport units:
vh, vw, vmin, vmax for responsive layouts
- ✅ Absolute units:
px, pt, pc, in, cm, mm, Q
- ✅ Writing modes:
horizontal-tb, vertical-lr for international text
- ✅ CSS Grid: Full grid layout with template areas, auto-placement, spanning
- ✅ Flexbox: Complete flexbox implementation with all alignment options
- ✅ Box model: Margin, padding, border with proper box-sizing support
- ✅ Intrinsic sizing:
min-content, max-content, fit-content sizing
Future Enhancements
- Line-based CLI mode (print-only, non-redrawable content)
- Multiline, multicursor text editor component
- More advanced animation easing functions
- Bottom-up content flow and reflow
- More component types (tables, lists, menus)
- Additional writing modes (
vertical-rl, sideways-lr, sideways-rl)
Contributing
This is a proof of concept project. Feel free to experiment and extend it for your own use cases.