Packages

Native desktop GUI framework for Gleam, powered by Iced

Current section

Files

Jump to
plushie_gleam src plushie widget stack.gleam
Raw

src/plushie/widget/stack.gleam

//// Stack container widget builder.
import gleam/dict
import gleam/list
import gleam/option.{type Option, None}
import plushie/node.{type Node, Node}
import plushie/prop/a11y.{type A11y}
import plushie/prop/length.{type Length}
import plushie/widget/build
pub opaque type Stack {
Stack(
id: String,
children: List(Node),
width: Option(Length),
height: Option(Length),
clip: Option(Bool),
a11y: Option(A11y),
)
}
/// Create a new stack builder.
pub fn new(id: String) -> Stack {
Stack(id:, children: [], width: None, height: None, clip: None, a11y: None)
}
/// Set the width.
pub fn width(s: Stack, w: Length) -> Stack {
Stack(..s, width: option.Some(w))
}
/// Set the height.
pub fn height(s: Stack, h: Length) -> Stack {
Stack(..s, height: option.Some(h))
}
/// Set whether overflowing content is clipped.
pub fn clip(s: Stack, c: Bool) -> Stack {
Stack(..s, clip: option.Some(c))
}
/// Add a child node.
pub fn push(s: Stack, child: Node) -> Stack {
Stack(..s, children: list.append(s.children, [child]))
}
/// Add multiple child nodes.
pub fn extend(s: Stack, children: List(Node)) -> Stack {
Stack(..s, children: list.append(s.children, children))
}
/// Set accessibility properties for this widget.
pub fn a11y(s: Stack, a: A11y) -> Stack {
Stack(..s, a11y: option.Some(a))
}
/// Option type for stack properties.
pub type Opt {
Width(Length)
Height(Length)
Clip(Bool)
A11y(A11y)
}
/// Apply a list of options to a stack builder.
pub fn with_opts(s: Stack, opts: List(Opt)) -> Stack {
list.fold(opts, s, fn(st, opt) {
case opt {
Width(w) -> width(st, w)
Height(h) -> height(st, h)
Clip(v) -> clip(st, v)
A11y(a) -> a11y(st, a)
}
})
}
/// Build the stack into a renderable Node.
pub fn build(s: Stack) -> Node {
let props =
dict.new()
|> build.put_optional("width", s.width, length.to_prop_value)
|> build.put_optional("height", s.height, length.to_prop_value)
|> build.put_optional_bool("clip", s.clip)
|> build.put_optional("a11y", s.a11y, a11y.to_prop_value)
Node(id: s.id, kind: "stack", props:, children: s.children, meta: dict.new())
}