Components

Reusable templates with named slots and props.

Top section

Body section

Bottom section

Only default content

Hello, Props!

This is the card body.

PHP
<?php $Layout = fragment([ el('header', [bg-info-subtle mt-3], [ slot('header') ]), el('main', [bg-info-subtle], [ slot() ]), el('footer', [bg-info-subtle mb-3], [ slot('footer') ]), ]); // Optional: a template that also reads a prop, e.g. title $CardTpl = fragment([ el('div', [ cls('card') ], [ el('h2', [], [ text(prop('title')) ]), // reads ctx.props.title at runtime slot(), // default body ]), ]); // Use the component with NAMED slots (including 'default') $NamedSlotsInstance = component($Layout, [], [ 'header' => [ el('p', [cls('p-3 m-0')], [ text(val('Top')) ]) ], 'default' => [ el('p', [cls('p-3 m-0')], [ text(val('Body')) ]) ], 'footer' => [ el('p', [cls('p-3 m-0')], [ text(val('Bottom')) ]) ], ]); // Use the component with ONLY DEFAULT slot (unnamed children form) // This becomes slots: { "default": [...] } in the IR. $DefaultOnlyInstance = component($Layout, [], [ el('p', [], [ text(val('Only default content')) ]) ]); // A component that passes PROPS and default slot content $CardInstance = component($CardTpl, /* props */ [ 'title' => val('Hello, Props!'), ], [ el('p', [], [ text(val('This is the card body.')) ]), ]); // Compose a page IR that uses the three component instances $app = fragment([ el('div', [ cls('container') ], [ $NamedSlotsInstance, $DefaultOnlyInstance, $CardInstance, ]), ]);