Search by

drago-ex / component

accgit

Collection of Bootstrap components and widgets for Nette Framework.

Package info

github.com/drago-ex/component

pkg:composer/drago-ex/component

Statistics

Installs: 699

Dependents: 3

Suggesters: 0

Stars: 0

Open Issues: 0

v2.3.0 2026-10-17 13:16 UTC

README

Bootstrap components such as modal, offcanvas, dropdown, and tabs.

License: MIT PHP version Tests Coding Style

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 example end, lg-start, or lg-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.