Files
iris/ui/layout.go
Hugo Nijhuis 00d98879d3
Some checks failed
CI / build (push) Failing after 36s
Initial iris repository structure
WASM reactive UI framework for Go:
- reactive/ - Signal[T], Effect, Runtime
- ui/ - Button, Text, Input, View, Canvas, SVG components
- navigation/ - Router, guards, history management
- auth/ - OIDC client for WASM applications
- host/ - Static file server

Extracted from arcadia as open-source component.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-08 19:23:49 +01:00

91 lines
2.7 KiB
Go

package ui
import "strings"
// VerticalGroup is a view that arranges its children vertically
// It uses CSS Grid with a single column
func VerticalGroup(children ...View) View {
v := NewView()
v.e.Grid()
v.e.GridTemplateColumns("1fr") // Force single column
v.e.GridAutoFlow("row")
v.e.Width("100%")
for _, child := range children {
v.Child(child)
}
return v
}
// HorizontalGroup is a view that arranges its children horizontally
// It uses flexbox to do so
func HorizontalGroup(children ...View) View {
v := NewView()
v.e.Grid()
v.e.GridTemplateColumns("repeat(auto-fit, minmax(250px, 1fr))")
v.e.Width("100%")
for _, child := range children {
v.Child(child)
}
return v
}
// Spacer is a view that takes up all available space
// It uses flexbox to do so
func Spacer() View {
v := NewView()
v.e.Get("style").Call("setProperty", "flex", "1")
return v
}
// OverlayGroup creates a container where children are stacked on top of each other
func OverlayGroup(children ...View) View {
v := NewView()
v.e.Get("style").Call("setProperty", "position", "relative")
v.e.Get("style").Call("setProperty", "display", "block")
// Add children with absolute positioning (except first one)
for i, child := range children {
if i == 0 {
// First child acts as the base layer
v.Child(child)
} else {
// Subsequent children are absolutely positioned as overlays
// They need pointer-events: none so clicks pass through to layers below
child.e.Get("style").Call("setProperty", "position", "absolute")
child.e.Get("style").Call("setProperty", "top", "0")
child.e.Get("style").Call("setProperty", "left", "0")
child.e.Get("style").Call("setProperty", "width", "100%")
child.e.Get("style").Call("setProperty", "height", "100%")
child.e.Get("style").Call("setProperty", "pointer-events", "none")
v.Child(child)
}
}
return v
}
// Divider creates a visual separator line
func Divider() View {
v := NewView()
v.e.Get("style").Call("setProperty", "border-top", "1px solid #ccc")
v.e.Get("style").Call("setProperty", "margin", "8px 0")
v.e.Get("style").Call("setProperty", "width", "100%")
v.e.Get("style").Call("setProperty", "height", "1px")
return v
}
// FlexLayout creates a horizontal layout with explicit column sizing
// Example: FlexLayout([]string{"48px", "1fr", "240px"}, left, center, right)
// Supports fixed widths (e.g., "48px"), flexible ("1fr"), and auto-sized ("auto")
func FlexLayout(columns []string, children ...View) View {
v := NewView()
v.e.Grid()
v.e.Get("style").Call("setProperty", "grid-template-columns", strings.Join(columns, " "))
v.e.Width("100%")
v.e.Height("100%")
for _, child := range children {
v.Child(child)
}
return v
}