Skip to content

About

UI Awesome HTML Core Component for PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

UI Awesome

Html Core Component


PHPUnit Mutation Testing PHPStan Security

Composable, immutable PHP primitives for building UI components: alerts, breadcrumbs, dropdowns, navbars, toggles, and menu items.
Accessible by default, fluent API, framework-friendly data hooks, and rendering powered by html-core.

Features

Feature Overview

Installation

composer require ui-awesome/html-core-component:^0.4

Quick start

This package ships both abstract base classes (for subclassing) and ready-to-use concrete classes (Alert, Breadcrumb, Dropdown, NavBar, Toggle, Item, Menu). The concrete classes can be used directly via ::tag() without any subclassing.

The exposed abstractions are:

  • BaseAlert / Alert dismissible alerts with prefix/suffix containers and an optional toggle.
  • BaseBreadcrumb / Breadcrumb accessible breadcrumb navigation with active-path detection.
  • BaseDropdown / Dropdown dropdown menus with toggles, dividers, and active-link wiring.
  • BaseNavBar / NavBar navigation bars with brand, menu, and collapsible toggle.
  • BaseToggle / Toggle button or link toggles with full data-attribute coverage (Bootstrap, Flowbite, Tailwind UI).

Custom breadcrumb

use UIAwesome\Html\Core\Component\Base\BaseBreadcrumb;
use UIAwesome\Html\Core\Component\Item;

final class Breadcrumb extends BaseBreadcrumb {}

echo Breadcrumb::tag()
    ->items(
        Item::tag()->label('Home')->link('/'),
        Item::tag()->label('Library')->link('/library'),
        Item::tag()->label('Data')->active(true),
    )
    ->currentPath('/library')
    ->render();

Custom dropdown

use UIAwesome\Html\Core\Component\Base\BaseDropdown;
use UIAwesome\Html\Core\Component\Item;

final class Dropdown extends BaseDropdown {}

echo Dropdown::tag()
    ->items(
        Item::tag()->label('Profile')->link('/profile'),
        Item::tag()->label('Settings')->link('/settings'),
        Item::tag()->divider(),
        Item::tag()->label('Sign out')->link('/logout'),
    )
    ->render();

Custom navbar with toggle

This example renders markup only. Connect the button to a menu target and provide the required client-side behavior.

use UIAwesome\Html\Core\Component\Base\{BaseNavBar, BaseToggle};
use UIAwesome\Html\Core\Component\{Item, Menu};

final class NavBar extends BaseNavBar {}
final class Toggle extends BaseToggle {}

echo NavBar::tag()
    ->brandText('My App')
    ->brandLink('/')
    ->brandToggle(Toggle::tag()->content('Menu'))
    ->menu(
        Menu::tag()->items(
            Item::tag()->label('Home')->link('/'),
            Item::tag()->label('About')->link('/about'),
        ),
    )
    ->render();

Nested defaults and toggle labels

NavBar::menuDefaultDefinitions() configures the menu passed to menu(), and Menu::dropdownDefaultDefinitions() configures each nested dropdown, so a theme can supply a shared dropdown toggle and list classes.

A value the child sets itself wins over the default. A dropdown keeps its own toggle, toggleLabel, linkTag, listItemTag, linkActiveClass, linkDisabledClass, and linkAriaCurrent. A menu keeps the same link and list-item values plus its own listDropdownItemClass and dropdownDefaultDefinitions, which then replace the navbar definitions as a whole. The hasOwn*() methods, such as hasOwnToggle() and hasOwnLinkTag(), report these choices; the remaining defaults still apply.

toggleLabel() replaces only the content of the toggle that applies, whether the default or the dropdown's own, and keeps its markup, classes, toggleContent() decoration, and icons. A non-empty label requires a BaseToggle; rendering throws InvalidArgumentException when the toggle is raw markup or missing.

use UIAwesome\Html\Core\Component\{Dropdown, Item, Menu, NavBar, Toggle};

echo NavBar::tag()
    ->menuDefaultDefinitions(
        [
            'dropdownDefaultDefinitions' => [
                [
                    'listClass' => 'dropdown-menu',
                    'toggle' => Toggle::tag()->class('dropdown-toggle')->content('Menu'),
                ],
            ],
        ],
    )
    ->menu(
        Menu::tag()->items(
            Dropdown::tag()
                ->id('account')
                ->items(Item::tag()->label('Profile')->link('/profile'))
                ->toggleLabel('Account'),
            Dropdown::tag()
                ->id('help')
                ->items(Item::tag()->label('Docs')->link('/docs'))
                ->toggle(Toggle::tag()->class('help-toggle')->content('Help')),
        ),
    )
    ->render();

The first dropdown relabels the default toggle; the second keeps its own toggle and still receives the list class:

Menu with wrapped labels

Each item label can be wrapped in its own element (for styling or truncation) via labelTag/labelClass. Without labelTag, the label renders as plain text.

use UIAwesome\Html\Core\Component\{Item, Menu};
use UIAwesome\Html\Interop\Inline;

echo Menu::tag()
    ->type('nav')
    ->linkClass('nav-link')
    ->linkActiveClass('is-active')
    ->items(
        Item::tag()
            ->label('Request')
            ->link('/request')
            ->active()
            ->labelTag(Inline::SPAN)
            ->labelClass('nav-link-label'),
        Item::tag()
            ->label('Logs')
            ->link('/logs')
            ->labelTag(Inline::SPAN)
            ->labelClass('nav-link-label'),
    )
    ->render();

Application-scoped styling

Framework styling is supplied by a ThemeInterface implementation resolved through Config and applied with BaseTag::config(). The theme reads the ComponentContext to pick the recipe, so variants (danger, info, warning, ...) travel with the context instead of being hard-coded on the component.

use UIAwesome\Html\Core\Component\Alert;
use UIAwesome\Html\Core\Config\{Call, ComponentContext, Config, Cookbook, Recipe};
use UIAwesome\Html\Core\Theme\ThemeInterface;

final class AppTheme implements ThemeInterface
{
    public function getName(): string
    {
        return 'app';
    }

    public function getRecipes(ComponentContext $context): iterable
    {
        if ($context->component !== 'alert' || $context->variant === null) {
            return;
        }

        yield new Recipe(
            'app.alert',
            new Cookbook(new Call('class', "alert alert-{$context->variant}")),
        );
    }
}

$config = new Config(new AppTheme());

echo Alert::tag()
    ->config($config, new ComponentContext('alert', variant: 'danger'))
    ->content('Watch out!')
    ->render();

config() applies recipes immediately. Call it before fluent setters that must remain local overrides.

For per-instance defaults that do not belong to a theme, pass them to the factory:

use UIAwesome\Html\Core\Component\Alert;

echo Alert::tag(['class' => 'alert alert-danger'])->content('Watch out!')->render();

Component context names

The component names, structural variants, and states this package defines are string-backed enums under UIAwesome\Html\Core\Component\Values, so callers and themes reference a symbol that static analysis can check instead of repeating string literals.

Enum Cases
ComponentName ALERT, BREADCRUMB, DROPDOWN, ITEM, MENU, NAVBAR, TOGGLE
ToggleVariant MENU (menu), MENU_DROPDOWN (menu-dropdown), SELECTOR_THEME (selector-theme)
NavBarVariant ALIGN_RIGHT (align-right)
DropdownVariant LANGUAGE (language)
ComponentState DISMISSIBLE (dismissible)

Pass the backing value to ComponentContext, and compare against it in a theme:

use UIAwesome\Html\Core\Component\Toggle;
use UIAwesome\Html\Core\Component\Values\{ComponentName, ToggleVariant};
use UIAwesome\Html\Core\Config\ComponentContext;

echo Toggle::tag()
    ->config($config, new ComponentContext(ComponentName::TOGGLE->value, variant: ToggleVariant::MENU->value))
    ->content('Menu')
    ->render();

// Inside ThemeInterface::getRecipes()
if ($context->component === ComponentName::TOGGLE->value && $context->variant === ToggleVariant::MENU->value) {
    // ...
}

Passing the enum cases directly to ComponentContext requires an ui-awesome/html-core version whose ComponentContext accepts BackedEnum values. Alert color variants (danger, success, ...), sizes, and schemes remain plain strings defined by each theme.

Note

The Bootstrap5 and Flowbite cookbooks were removed in 0.3.0. Flowbite is discontinued, and the Bootstrap 5 presets are being republished as standalone theme packages. See the Upgrade Guide for the migration.

Documentation

For detailed testing, migration, and quality workflows.

Package information

PHP Latest Stable Version Total Downloads

Project status

Codecov PHPStan Level Max Quality StyleCI

Our social networks

Follow on X

License

License

About

UI Awesome HTML Core Component for PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

Generated from yii-tools/template