NAME

Clay::UI::Box - styled container widget role for Clay::UI

SYNOPSIS

use v5.22;
use Object::Pad;
use Clay::XS qw(sizing_fixed sizing_grow padding_all CLAY_TOP_TO_BOTTOM);
use Clay::UI;
use Clay::UI::Box;
use Clay::UI::Text;

class My::Box   :strict(params) :does(Clay::UI::Box) {}
class My::Label :strict(params) :does(Clay::UI::Text) {}

my $sidebar = My::Box->new(
	id               => 'sidebar',
	layout           => {
		sizing           => { width => sizing_fixed(200), height => sizing_grow() },
		padding          => padding_all(8),
		child_gap        => 4,
		layout_direction => CLAY_TOP_TO_BOTTOM,
	},
	background_color => [40, 50, 60, 255],
	corner_radius    => 6,
	border_color     => [80, 80, 80, 255],
	border_width     => 1,
);
$sidebar->add_child(map { My::Label->new(text => $_) } qw(Home Search Settings));

my $ui = Clay::UI->new(width => 800, height => 600, root => $sidebar);
my $commands = $ui->render;

$sidebar->background_color([60, 70, 80, 255]);    # shown from the next render on

DESCRIPTION

Clay::UI::Box is the general-purpose container widget: an element that holds any children and has every layout and style attribute - sizing, padding and child placement, background colour, border, corner radius and floating. Most widget classes start from it.

Like every widget in Clay::UI it is a role, so that you can combine it with other roles in a class of your own. Compose it in a class (as My::Box above) to get a widget you can construct; add interaction roles such as Clay::UI::Role::Interaction::Pressable to make the box react to the pointer.

All attributes are constructor parameters and read/write accessors, so a box's layout and style can change at any time; the change shows at the next render. Values are checked when they are set (at construction or by the accessor) and a bad value dies there, naming the attribute. The box keeps its own copy of every value and every read returns a new copy, so changing a hash or array after passing it in, or one an accessor returned, does not change the box. Every write bumps the revision (Clay::UI::Revision); reads never do.

Declare consumer classes :strict(params), so that a misspelled constructor parameter dies instead of being ignored:

class My::Box :strict(params) :does(Clay::UI::Box) {}

AT A GLANCE

Everything a Box has, with the role that documents it.

Constructor parameters and attributes

id

Element id, set at construction only (read-only reader).

layout

Sizing, padding, child gap, child alignment, layout direction, line gap and line sizing.

background_color

Fill colour.

border_color

Border colour.

border_width

Border widths: one number or per side.

corner_radius

Corner radius: one number or per corner.

floating

Take the box out of the layout and attach it to another element.

width_group

Share the width with other elements of the same group.

height_group

Share the height with other elements of the same group.

Children

add_child

Append children.

remove_child

Remove the given children.

remove_child_with_id

Remove children by id.

remove_children_with

Remove children matching a test.

clear_children

Remove all children.

children

The children, as a new arrayref.

get_children_with

The children matching a test.

has_child

Whether a widget is a child.

add_internal_children, remove_internal_children, internal_children, layout_children

Helpers a widget class lays out next to its user's children.

descendants

Every widget below this one, in layout pre-order.

Tree

parent

The widget this one is attached to.

root

The topmost widget above this one.

ui

The Clay::UI this widget is part of.

contains

Whether a widget is this one or below it.

tree_changed

The hook a subclass overrides to react when the widget joins or leaves a tree.

Events

on

Register a listener for an event name.

handlers_for

The listeners registered for an event name.

fire_event

Fire an event at this box; it bubbles up through the parents.

Declaration and extension

to_config

The declaration (the hash of settings Clay receives for the element).

resolve_id

The id the layout pass uses for the box.

mark_changed

Bump the revision from a setter of your own.

contribute_layout, contribute_background, contribute_border, contribute_corner_radius, contribute_floating, contribute_sizing_group

The methods that add each part to the declaration; see "EXTENDING THE DECLARATION" in Clay::UI::Role::Core::Element.

COMPOSED ROLES

Clay::UI::Box composes:

A Box does not scroll. For a styled scroll container, compose Clay::UI::Role::Layout::HasScroll in the same class (it then needs an id):

class My::ScrollBox :strict(params)
	:does(Clay::UI::Box)
	:does(Clay::UI::Role::Layout::HasScroll) {}

A Box does not react to the pointer by itself: add Clay::UI::Role::Interaction::Hoverable, Clay::UI::Role::Interaction::Pressable or Clay::UI::Role::Interaction::Focusable.

SEE ALSO

Clay::UI, Clay::UI::Text, Clay::UI::Grid, Clay::Manual, Clay::Cookbook, Clay::XS::Structs.