drago-ex / component
Collection of Bootstrap components and widgets for Nette Framework.
Requires
- php: >=8.3 <9
- latte/latte: ^3.1
- nette/application: ^3.2
Requires (Dev)
- nette/tester: ^2.5
- phpstan/phpstan-nette: ^2.0
- tracy/tracy: ^2.10
Suggests
- drago-ex/translator: Configures Latte translation support for bundled templates using translation macros.
Provides
None
Conflicts
None
Replaces
None
README
Bootstrap components such as modal, offcanvas, dropdown, and tabs.
Requirements
- PHP >= 8.3, < 9
- Nette Framework
- Composer
- Bootstrap
- Naja
- Node.js
Installation
composer require drago-ex/component
Project files
File copying is handled automatically by drago-ex/project-tools,
which must be installed in your project. Without it, copy the files manually according to the copy section
in this package's composer.json. To skip this package, set "skip": true under
extra.drago-tools.packages.<package-name> in your root composer.json.
Modal and offcanvas
In the Control component, use the Drago\Component\Component trait.
Passing variables to the template:
$template->offcanvasId = $this->getUniqueIdComponent(self::Offcanvas); $template->modalId = $this->getUniqueIdComponent(self::Modal);
You can then implement the Drago\Component\ModalHandle and Drago\Component\OffcanvasHandle interfaces.
The optional argument of modalComponent() and offCanvasComponent() is the name of a snippet to redraw;
here it is the modal and offcanvas snippets from the templates below:
#[Requires(ajax: true)] public function handleOpenModal(): void { $this->modalComponent('modal'); } #[Requires(ajax: true)] public function handleOpenOffcanvas(): void { $this->offCanvasComponent('offcanvas'); }
Attributes on interface methods are not inherited, so repeat #[Requires(ajax: true)] in your implementation.
You can also write your own signal handler and redraw the related snippets manually.
#[Requires(ajax: true)] public function handleOpenModalWindow(): void { $this->modalComponent(); $this->redrawControl('...'); }
Use the component templates in Latte. If you need to redraw multiple blocks, add additional snippets inside the embedded template.
The offcanvas is 61rem wide; pass size to change it, e.g. size: '100vw' for the whole screen.
<a n:href="openOffcanvas!" class="ajax" data-naja-history="off">Open Offcanvas</a> {embed 'path/to/@offcanvas.latte', offcanvasId: $offcanvasId} {block title}Title{/block} {block body} {snippet offcanvas} ... {/snippet} {/block} {/embed} <a n:href="openModal!" class="ajax" data-naja-history="off">Open Modal</a> {embed 'path/to/@modal.latte', modalId: $modalId} {block title}Title{/block} {block body} {snippet modal} ... {/snippet} {/block} {block footer} {import 'path/to/@dismiss-button.latte'} {include buttonDismiss, type: 'modal'} {/block} {/embed}
JavaScript setup
Since the package is installed via Composer, add the following to your package.json to make the drago-component alias available in your bundler:
{
"type": "module",
"dependencies": {
"drago-component": "file:vendor/drago-ex/component"
}
}
Then run npm install.
import { BootstrapComponents } from 'drago-component'; naja.registerExtension(new BootstrapComponents());
Dropdown widget
The dropdown widget is a small Latte wrapper for Bootstrap dropdown menus. It is useful for compact navigation actions, language switchers, user menus, or theme controls.
Register the dropdown helper in your frontend entry point:
import { BootstrapDropdowns } from 'drago-component'; naja.registerExtension(new BootstrapDropdowns());
Use the widget in Latte:
{embed 'path/to/@dropdown.latte', name: 'Menu', icon: 'fa-solid fa-bars', menu: 'end'} {block menu} {include item, name: 'Homepage', link: ':Front:Home:'} {include item, name: 'Administration', link: 'Admin:'} {include divider} {include item, name: 'Sign out', link: 'Sign:out'} {/block} {/embed}
Available parameters:
name: dropdown toggle label (required, translated).icon: optional Font Awesome icon class.menu: optional Bootstrap menu alignment suffix, for exampleend,lg-start, orlg-end.
The menu value is appended to the Bootstrap dropdown-menu-* class, so menu: 'end' renders
dropdown-menu-end and menu: 'lg-start' renders dropdown-menu-lg-start.
The widget keeps dropdown behavior on Bootstrap.
For custom colors, prefer Bootstrap utilities and variables on your own layout instead of overriding the dropdown widget.
The widget provides helper blocks:
item: renders a translated dropdown link.divider: renders a dropdown divider.
Tabs widget
The tabs widget renders Bootstrap tabs from a small configuration array and keeps the content blocks in the same template. Bootstrap tab JavaScript must be available in the project.
{embed 'path/to/@tabs.latte', tabs: [ [ id: 'profile', label: 'Profile information', heading: 'Profile information', description: 'Update the name and email address used for your account.', block: 'profileInfo', ], [ id: 'password', label: 'Change password', heading: 'Change password', description: 'Use a strong password to keep your account secure.', block: 'changePassword', ], ], active: 'profile', class: 'card', headerClass: 'px-3 pt-3', contentClass: 'p-4' } {block profileInfo} {control profile} {/block} {block changePassword} {control password} {/block} {/embed}
Each tab item supports:
id: unique tab identifier.label: translated tab label.block: block name rendered as tab content.class: optional class for the tab pane.heading: optional translated heading above the tab content.description: optional translated description below the heading.headingClass: optional heading class.descriptionClass: optional description class.
Widget parameters:
tabs: list of tab definitions.active: active tab id; when omitted, the first tab is active.class: optional wrapper class.headerClass: optional class for the tabs header.contentClass: optional class for the tab content wrapper.