A fluent, immutable PHP library for rendering form fields bound to a form model.
Labels, hints, errors, and controls composed through application-scoped configuration.
composer require ui-awesome/html-field:^0.1The field resolves the id, name, and label from the form model and renders a text input by default.
use App\Model\BasicForm;
use UIAwesome\Html\Field\Field;
echo Field::tag()
->formModel(new BasicForm())
->property('username')
->render();
// <div>
// <label for="basicform-username">Username</label>
// <input id="basicform-username" name="BasicForm[username]" type="text">
// </div>Hints link to the input through aria-describedby; property errors render after the control.
use App\Model\BasicForm;
use UIAwesome\Html\Field\Field;
$form = new BasicForm();
$form->addError('username', 'Username is required.');
echo Field::tag()
->formModel($form)
->property('username')
->hintContent('Choose a unique username.')
->render();
// <div>
// <label for="basicform-username">Username</label>
// <input id="basicform-username" name="BasicForm[username]" type="text" aria-describedby="basicform-username-help">
// <div id="basicform-username-help">
// Choose a unique username.
// </div>
// <div>
// Username is required.
// </div>
// </div>Any form control can replace the default input; the form model field config is applied to the replacement.
use App\Model\BasicForm;
use UIAwesome\Html\Field\Field;
use UIAwesome\Html\Form\InputEmail;
echo Field::tag()
->formModel(new BasicForm())
->property('username')
->input(InputEmail::tag())
->containerClass('form-group')
->render();
// <div class="form-group">
// <label for="basicform-username">Username</label>
// <input id="basicform-username" name="BasicForm[username]" type="email">
// </div>Field selects controls through ControlFactory and applies application-scoped recipes to the field, container,
label, control, hint, error, prefix, and suffix contexts. The package does not select a theme: replace $theme with
any ThemeInterface implementation, such as a Flowbite or DaisyUI theme.
use UIAwesome\Html\Core\Config\Config;
use UIAwesome\Html\Field\Factory\ControlFactory;
use UIAwesome\Html\Field\Field;
$config = new Config(theme: $theme, factory: new ControlFactory());
echo Field::tag()
->config($config)
->control('email')
->formModel($form)
->property('email')
->render();The default registry supports checkbox, checkbox-list, email, password, radio, radio-list, select,
text, and textarea. Registrations are immutable — derive a factory with with() to replace or extend them.
Select and its typed Option objects come from ui-awesome/html: compose the control there and the field passes
the resolved model value to Select::value().
CheckboxList, RadioList, and ChoiceItem also come from ui-awesome/html; Field supplies their checked values,
name, validation state, label, hint, and errors. See the usage guide for examples, slot contexts, and recipe methods.
Form model field configurations are applied through the core config applier in strict mode, once per render, against
the control the field finally resolves — so the fluent call order never changes the outcome. An entry naming a method
the resolved control does not expose throws ConfigException instead of being skipped, so typos such as maxlenght
fail at render time. The model binding runs first and the config last, so entries such as value, id, name,
checked, and placeholder act as explicit per-property overrides rather than being silently overwritten. See the
upgrade guide for the precedence table and the supported entry shapes.
For detailed usage, testing, and quality workflows.