Installation
composer require cisse/ui-bundle symfonycasts/tailwind-bundle gehrisandro/tailwind-merge-php
Add to config/bundles.php:
Cisse\Bundle\UiBundle\UiBundleBundle::class => ['all' => true],
Configure Tailwind
Update assets/app.css:
@import "tailwindcss";
@source "../../vendor/cisse/ui-bundle"; /* Critical */
@tailwind base;
@tailwind components;
@tailwind utilities;
First Component Usage In a Twig template:
{{ ui_button('Click Me', { type: 'primary' }) }}
Verify the bundle is registered by checking the generated HTML output.
{{ ui_form({
action: path('submit'),
method: 'POST',
fields: [
ui_input('username', { label: 'Username', required: true }),
ui_select('role', { label: 'Role', options: ['admin', 'user'] }),
ui_button('Submit', { type: 'submit' })
]
}) }}
Twig Component Usage
ui_button, ui_card, ui_modal
{{ ui_button('Action', { icon: 'edit', variant: 'outline' }) }}
{{ ui_modal('Confirm', {
content: ui_card('Are you sure?', { class: 'p-4' })
}) }}
Dynamic Data Binding Use Twig variables for dynamic content:
{% for item in items %}
{{ ui_table_row(item, {
cells: [
ui_table_cell(item.name),
ui_table_cell(item.price, { class: 'font-bold' })
]
}) }}
{% endfor %}
Configuration via PHP Pass complex configurations from controllers:
return $this->render('template.html.twig', [
'formConfig' => [
'fields' => [
['type' => 'input', 'name' => 'email', 'label' => 'Email'],
['type' => 'checkbox', 'name' => 'subscribe', 'label' => 'Subscribe']
]
]
]);
Reusable Component Blocks Create partials for complex UI sections:
{# _partials/user_card.html.twig #}
{{ ui_card(user, {
header: ui_card_header(user.name, { avatar: user.avatar }),
body: ui_card_body(user.bio)
}) }}
@source directive in your CSS:
@source "../../vendor/cisse/ui-bundle" {
@apply 'bg-custom-blue' => 'bg-blue-600';
}
tailwind.config.js):
module.exports = {
darkMode: 'class',
// ...
}
Toggle classes in Twig:
<div class="{{ ui_dark_mode_toggle() }}">
{{ ui_button('Toggle Dark Mode', { class: 'dark:bg-gray-800' }) }}
</div>
Missing @source Directive
@source "../../vendor/cisse/ui-bundle" is included before @tailwind directives in your CSS.Class Merging Conflicts
gehrisandro/tailwind-merge-php for intelligent merging. Configure in config/packages/tailwind.yaml:
merge_php: true
Component Not Found Errors
Unknown "ui_button" function or similar.config/bundles.php and Twig is auto-reloaded (php bin/console cache:clear).Dark Mode Not Working
dark:...) are ignored.darkMode: 'class' is set in tailwind.config.js and the dark class is toggled on the <html> or <body> tag.npm run dev or npm run build to ensure Tailwind is processing the @source directive.ui_validate function to check component configurations:
{{ dump(ui_validate(ui_button('Test', { invalid: 'option' }))) }}
Custom Components Extend the bundle by creating new Twig functions in a custom bundle:
// src/Twig/Extension/CustomUiExtension.php
public function getFunctions()
{
return [
new \Twig\TwigFunction('ui_custom_component', [$this, 'renderCustomComponent']),
];
}
Override Default Styles
Use Tailwind’s @layer directive to override component styles:
@layer components {
.ui-button {
@apply bg-red-500 hover:bg-red-700;
}
}
Add New Component Types
Contribute new components by extending the bundle’s Component classes (located in src/Component/). Example:
// src/Component/CustomComponent.php
class CustomComponent extends AbstractComponent
{
public function render(): string
{
return $this->renderHtml('custom_component.html.twig', [
'data' => $this->data,
]);
}
}
tailwind.config.js):
module.exports = {
purge: [
'./templates/**/*.html.twig',
'./assets/**/*.js',
],
}
How can I help you explore Laravel packages today?