You have entered the following information:
Build clear interfaces with Yii2 and Bootstrap 6.
'; Dialog::end(); ``` Widgets load their CSS and JavaScript on demand. The JavaScript bundle uses `type="module"` and exposes no `window.bootstrap` by default; use the registered bundle’s `importJs()` helper for custom plugin code. Titles and labels are encoded by default, while body and footer content require encoding when they contain user data. ## Documentation Practical guides and complete examples, with API details generated from PHPDoc. * 📚 [Installation Guide](/docs/extensions/bootstrap6/installation/): packages, aliases, assets, and CDN delivery. * ⚙️ [Configuration Guide](/docs/extensions/bootstrap6/configuration/): practical choices for plugins, items, forms, and icons. * 💡 [Usage Examples](/docs/extensions/bootstrap6/examples/): widget gallery and complete view recipes. * 🔄 [Migration from Bootstrap 5](/docs/extensions/bootstrap6/migration/) * 🧪 [Testing Guide](/docs/extensions/bootstrap6/testing/) * 📖 [Generated API Reference](https://yii2-framework.github.io/docs/extensions/bootstrap6/reference/) ## AI assistance AI agents: readReview your changes before continuing.
'; Dialog::end(); ``` `ButtonMenu` uses `options` for its trigger: use the ordinary attribute methods there. Input widgets’ `attribute` property still identifies the model field; their `attribute()` method sets an HTML attribute. ### Plugin initialization Widgets emit `data-bs-*` attributes, and a non-empty `clientOptions` array requests explicit initialization through the ES module. `Chips`, `Combobox`, `NavOverflow`, `OtpInput`, `Range`, `Strength`, and inline or preselected `Datepicker` widgets also initialize with empty options so they work in fragments inserted after page load. `Carousel` and `Toast` initialize with empty options too; `Button` initializes when `clientOptions` is an array. Set `clientOptions` to `false` to skip explicit initialization; rendered data attributes can still activate the Bootstrap data API. `clientEvents` handlers use `addEventListener` independently of `clientOptions`. Menu options and events belong on `ButtonMenu` or the trigger carrying `data-bs-toggle="menu"`, not on a standalone menu panel. Menu and tab events bubble, allowing `Nav` and `Tabs` to listen on their lists. `NavBar` uses the drawer data API and ignores these plugin properties; CSS-only widgets ignore them too. See [JavaScript recipes](/docs/extensions/bootstrap6/examples/#javascript) for handlers and custom plugin access. ### Begin and end widgets Call matching `begin()` and `end()` as statements in a view or layout: both return widget instances, and `end()` renders and echoes the captured HTML. `Alert`, `Collapse`, `Dialog`, `Drawer`, `NavBar`, `Toast`, `Popover`, and `Tooltip` support this pattern. For `Popover` and `Tooltip`, the captured content is the **trigger**, not the popup body. Keep rendering inside a view’s output buffer, including under worker runtimes. ## Icons Use the DI container to replace the icons of `Accordion` and `Combobox` throughout the application: ```php use UIAwesome\Html\Svg\Svg; use yii2\extensions\bootstrap6\IconSet; return [ 'container' => [ 'definitions' => [ IconSet::class => ['accordionChevron' => Svg::icon('Flowbite:chevron-down')], ], ], ]; ``` Widget-level `icon`, `caretIcon`, or `checkIcon` options override the shared icon. `Svg` instances receive structural classes from the widgets; plain markup must supply `accordion-icon`, `combobox-caret`, or `menu-item-check` itself so Bootstrap can size, rotate, and hide it. Optional font icons need `BootstrapIconAsset`. ## Enumerations Prefer enum cases to strings when configuring themes, sizes, placement, and navigation style. Enum-typed properties also accept a valid case value; unknown strings raise `InvalidConfigException`. The [enum reference](https://yii2-framework.github.io/docs/extensions/bootstrap6/reference/) lists the available cases. Use `Breakpoint::prefix()` for responsive classes rather than Bootstrap 5 suffixes such as `col-md-6`. ## Widgets Choose a widget from the [gallery](/docs/extensions/bootstrap6/examples/#widgets), then consult its generated API only for the options needed. For lists, prefer the immutable item objects, while retaining arrays where they are convenient. Each `with*()` on an item returns a copy: assign or chain its result. This differs from the mutable widget attribute methods. ```php use yii2\extensions\bootstrap6\Nav; use yii2\extensions\bootstrap6\enum\NavStyle; use yii2\extensions\bootstrap6\item\NavItem; echo Nav::widget([ 'style' => NavStyle::PILLS, 'items' => [ NavItem::to('Home', ['/site/index']), NavItem::to('Coming soon')->withDisabled(true), ], ]); ``` Keep an item’s `encode` unset to inherit the widget’s label policy, and its `active` unset when the widget should choose the active state. Objects and array configurations can be mixed, including nested menus. ### Accordion Use it for expandable content without JavaScript: it renders native `Read the terms before continuing.
'; Dialog::end(); ``` `backdrop: false` hides the backdrop; it does not mean “keep open on click”. Escape still closes the dialog unless `keyboard` is disabled. Supply a title or an accessible label, and encode user data echoed into the body or footer. [More examples](/docs/extensions/bootstrap6/examples/#dialog). ### Drawer Choose placement through `DrawerPlacement`. A responsive drawer becomes inline content above the selected breakpoint; page scrolling and fullscreen display are separate choices. [Example](/docs/extensions/bootstrap6/examples/#drawer). ### LinkPager For consistent pagination in every grid and list, define the package `LinkPager` as the DI replacement for `yii\widgets\LinkPager`. Custom page labels contain HTML, so encode user text. [Example](/docs/extensions/bootstrap6/examples/#linkpager). ### Menu Use `ButtonMenu` or `Nav` for a complete trigger/panel pair. Standalone `Menu` renders only the panel and must follow its trigger; configure plugin options on that trigger. [Example](/docs/extensions/bootstrap6/examples/#menu). ### Nav Use route arrays and leave `active` unset to let the widget detect the current route. Explicit active state is useful when the navigation does not follow the current controller route. [Example](/docs/extensions/bootstrap6/examples/#nav). ### NavBar Navigation collapses into a drawer. Set `drawerOptions` to `false` for content that should always render inline; configure drawer behavior there rather than through the navbar’s `clientOptions`. [Example](/docs/extensions/bootstrap6/examples/#navbar). ### NavOverflow Use it when a navigation row should move excess links into a “More” menu instead of wrapping. [Example](/docs/extensions/bootstrap6/examples/#navoverflow). ### OtpInput Use the model/name binding for the submitted code and `groups` for presentation. `options` targets the input, while `containerOptions` targets its visual slots. [Example](/docs/extensions/bootstrap6/examples/#otpinput). ### Placeholder Use skeletons while content loads. `pulse` and `glow` animations require a container; `wave` can apply directly. [Example](/docs/extensions/bootstrap6/examples/#placeholder). ### Popover and Tooltip Capture the trigger between `begin()` and `end()`. Set a popover’s `content` separately; keep `html` disabled for plain text. [Popover example](/docs/extensions/bootstrap6/examples/#popover), [tooltip example](/docs/extensions/bootstrap6/examples/#tooltip). ### Progress Use a descriptive accessible label, and keep values inside the configured bounds. Use `ProgressBar` items for stacked segments. [Example](/docs/extensions/bootstrap6/examples/#progress). ### Range `options` targets the input, while `containerOptions` targets the plugin wrapper. Supply meaningful tick labels when the scale needs explanation. [Example](/docs/extensions/bootstrap6/examples/#range). ### Spinner Keep a descriptive status label for assistive technology, especially when nearby text does not explain the pending operation. [Example](/docs/extensions/bootstrap6/examples/#spinner). ### Stepper Provide at least one step. Mark the current step explicitly and add URLs when users may revisit earlier steps. [Example](/docs/extensions/bootstrap6/examples/#stepper). ### Strength Render it beside the password input, or set `input` to a selector. Its client-side feedback does not replace server-side password validation. [Example](/docs/extensions/bootstrap6/examples/#strength). ### Tabs When no item is active, the first visible, enabled pane is activated. Keep label and content encoding separate; content is HTML. [Example](/docs/extensions/bootstrap6/examples/#tabs). ### Toast A toast initializes its plugin but stays hidden until `show()` is called. This view shows a dismissible notification using the same ES module URL as the registered bundle: ```php use yii2\extensions\bootstrap6\Toast; use yii2\extensions\bootstrap6\asset\BootstrapPluginAsset; echo Toast::widget([ 'options' => ['id' => 'notice'], 'title' => 'Saved', 'body' => 'Your changes have been saved.', ]); $bundle = BootstrapPluginAsset::register($this); $this->registerJs($bundle->importJs( $this, 'bootstrap.Toast.getOrCreateInstance(document.getElementById("notice")).show();', )); ``` For a user-supplied body, pass `Html::encode($text)`. Use `dateTime: null` to omit the time; the v5 `false` value is not accepted. [More examples](/docs/extensions/bootstrap6/examples/#toast). ### ToggleButtonGroup Choose checkbox or radio behavior to match the model attribute. With a model, the hidden input submits an empty value when nothing is selected; `options['unselect']` changes that value. [Example](/docs/extensions/bootstrap6/examples/#togglebuttongroup). ### Toggler Use it to toggle a class or attribute on target elements. It is independent of the model `attribute` concept used by input widgets. [Example](/docs/extensions/bootstrap6/examples/#toggler). ## Forms ### ActiveForm Use this package’s `ActiveForm` so its fields render Bootstrap 6 markup. Given a model with `email` and `notify` attributes, this view uses a floating email field and a switch: ```php use yii2\extensions\bootstrap6\ActiveForm; $form = ActiveForm::begin(['layout' => ActiveForm::LAYOUT_FLOATING, 'nativeValidation' => true]); echo $form->field($model, 'email')->textInput(['type' => 'email']); echo $form->field($model, 'notify')->checkbox(['switch' => true]); ActiveForm::end(); ``` `nativeValidation` opts into Bootstrap’s `:user-invalid` styling; `'valid'` also styles valid controls. Server-side validation still uses `is-invalid`, and remains necessary regardless of the browser styling. ### Layouts Choose stacked fields for general forms, horizontal fields for aligned labels, inline fields for short toolbars, and floating fields for controls suited to floating labels. Use the package `LAYOUT_*` constants and customize individual fields through `fieldConfig`. Floating checkbox/radio lists fall back to stacked markup; inline fields omit the individual error elements. See the [form recipes](/docs/extensions/bootstrap6/examples/#forms) before choosing that tradeoff. ### ActiveField Use `checkbox(['switch' => true])` for a switch. Set `inputTemplate` for an input group, and override the horizontal label/wrapper grid through `horizontalCssClasses`. List values replace the corresponding default classes. A caller-supplied class on a select retains `form-control`; select controls do not inherit an input placeholder. [Field recipes](/docs/extensions/bootstrap6/examples/#select-range-static-control-and-input-group). ## HTML helpers Use `yii2\extensions\bootstrap6\Html` when helper output must match Bootstrap 6 controls, badges, validation feedback, or theme classes. It extends Yii’s HTML helper, including `encode()`. Its generated API documents signatures; [helper recipes](/docs/extensions/bootstrap6/examples/#html-helpers) show combinations. ## Next steps * [Installation](/docs/extensions/bootstrap6/installation/). * [Usage examples](/docs/extensions/bootstrap6/examples/). * [Migration from Bootstrap 5](/docs/extensions/bootstrap6/migration/). * [Agent skill](/docs/extensions/bootstrap6/agents/). * [Testing](/docs/extensions/bootstrap6/testing/). # Usage examples > Each snippet renders in a fresh view, so widget id values start at w0. Each snippet renders in a fresh view, so widget `id` values start at `w0`. Long inline SVG icons are shortened to ``, and asset URLs are shown as `/assets/
',
['content' => '
'],
],
],
);
```
```html
```
The plugin is always created:
```js
import("/assets/
'),
CarouselItem::to('
'),
],
],
);
```
### Chips
```php
use yii2\extensions\bootstrap6\Chips;
echo Chips::widget(['name' => 'tags', 'value' => ['php', 'yii'], 'placeholder' => 'Add a tag']);
```
```html
This action cannot be undone.
'; Dialog::end(); ``` ```html ``` The same dialog configured with the fluent methods, which chain on the value returned by `begin()`; the `dialog` class is still added while rendering: ```php Dialog::begin(['title' => 'Delete post', 'toggleButton' => ['label' => 'Delete']]) ->addClass('shadow-lg') ->addTogglerClass('btn-outline', 'theme-danger') ->addTogglerAttribute('aria-haspopup', 'dialog'); echo 'This action cannot be undone.
'; Dialog::end(); ``` ```html ``` Sizes, responsive fullscreen, and backdrop behavior: ```php use yii2\extensions\bootstrap6\enum\{Breakpoint, DialogSize}; Dialog::begin( [ 'title' => 'Terms of service', 'toggleButton' => ['label' => 'Read the terms'], 'size' => DialogSize::LG, 'fullscreenBelow' => Breakpoint::MD, 'backdrop' => 'static', 'scrollable' => true, ], ); echo 'A static backdrop keeps the dialog open on outside clicks; close it with the button.
'; echo 'The body scrolls inside the dialog when the content is taller than the viewport.
'; Dialog::end(); ``` ```html ``` ### Drawer ```php use yii2\extensions\bootstrap6\Drawer; use yii2\extensions\bootstrap6\enum\DrawerPlacement; Drawer::begin( ['title' => 'Filters', 'placement' => DrawerPlacement::END, 'toggleButton' => ['label' => 'Show filters']], ); echo 'Filter form'; Drawer::end(); ``` ```html ``` `'responsive' => Breakpoint::LG` renders `class="lg:drawer drawer-start"`: the content is a drawer below `lg` and inline from `lg` up. ### LinkPager ```php use yii\data\Pagination; use yii2\extensions\bootstrap6\LinkPager; use yii2\extensions\bootstrap6\enum\{Size, Theme}; echo LinkPager::widget( [ 'pagination' => new Pagination(['totalCount' => 30, 'pageSize' => 10, 'page' => 1, 'route' => 'post/index']), 'size' => Size::SM, 'theme' => Theme::PRIMARY, ], ); ``` ```html ``` Use it in every grid and list view through the DI container: add the definition to `container.definitions` in `config/web.php`, or set it at runtime: ```php use yii\data\ArrayDataProvider; use yii\widgets\ListView; // config/web.php: 'container' => ['definitions' => [\yii\widgets\LinkPager::class => LinkPager::class]] Yii::$container->set(\yii\widgets\LinkPager::class, LinkPager::class); echo ListView::widget( [ 'dataProvider' => new ArrayDataProvider( ['allModels' => range(1, 30), 'pagination' => ['pageSize' => 10, 'route' => 'post/index']], ), 'itemView' => static fn(int $number): string => "Post $number", 'layout' => '{pager}', ], ); ``` ### Menu `Menu` renders only the panel; place it after your own toggle: ```php use yii2\extensions\bootstrap6\{Html, Menu}; echo Html::button('Options', ['class' => 'btn-solid', 'data-bs-toggle' => 'menu', 'aria-expanded' => 'false']); echo Menu::widget( [ 'items' => [ ['header' => 'Account'], ['label' => 'Profile', 'url' => ['/user/profile'], 'active' => true], ['label' => 'More', 'items' => [['label' => 'Settings', 'url' => '#']]], '-', ['text' => 'Signed in as admin'], ], ], ); ``` ```html ``` The same panel built with value objects renders the same markup: ```php use yii2\extensions\bootstrap6\item\MenuItem; use yii2\extensions\bootstrap6\Menu; echo Menu::widget( [ 'items' => [ MenuItem::header('Account'), MenuItem::link('Profile', ['/user/profile'])->withActive(true), MenuItem::submenu('More', [MenuItem::link('Settings', '#')]), MenuItem::divider(), MenuItem::text('Signed in as admin'), ], ], ); ``` The Menu plugin binds to the toggle, so `clientOptions` and `clientEvents` set on a standalone `Menu` target the panel and have no effect on the toggle. Put the options on the toggle as `data-bs-*` attributes, or use `ButtonMenu`. ### Nav ```php use yii2\extensions\bootstrap6\Nav; use yii2\extensions\bootstrap6\enum\NavStyle; echo Nav::widget( [ 'style' => NavStyle::PILLS, 'items' => [ ['label' => 'Home', 'url' => ['/site/index'], 'active' => true], ['label' => 'Docs', 'items' => [['label' => 'Guide', 'url' => '#'], ['label' => 'API', 'url' => '#']]], ['label' => 'Disabled', 'disabled' => true], ], ], ); ``` ```html ``` The same nav built with value objects renders the same markup; leave `active` as `null` to detect it from the route: ```php use yii2\extensions\bootstrap6\enum\NavStyle; use yii2\extensions\bootstrap6\item\{MenuItem, NavItem}; use yii2\extensions\bootstrap6\Nav; echo Nav::widget( [ 'style' => NavStyle::PILLS, 'items' => [ NavItem::to('Home', ['/site/index'])->withActive(true), NavItem::menu('Docs', [MenuItem::link('Guide', '#'), MenuItem::link('API', '#')]), NavItem::to('Disabled')->withDisabled(true), ], ], ); ``` ### NavBar ```php use yii2\extensions\bootstrap6\{Nav, NavBar}; NavBar::begin(['brandLabel' => 'My App', 'brandUrl' => '/', 'options' => ['class' => 'bg-1']]); echo Nav::widget( [ 'options' => ['class' => 'navbar-nav'], 'items' => [['label' => 'Home', 'url' => '/', 'active' => true], ['label' => 'About', 'url' => '/about']], ], ); NavBar::end(); ``` ```html ``` `'drawerOptions' => false` renders the content inline without toggler and drawer, and `'expand' => null` renders `navbar-expand` for every width. ### NavOverflow ```php use yii2\extensions\bootstrap6\NavOverflow; use yii2\extensions\bootstrap6\enum\NavStyle; echo NavOverflow::widget( [ 'moreText' => 'More', 'nav' => [ 'style' => NavStyle::UNDERLINE, 'items' => [['label' => 'Overview', 'url' => '#', 'active' => true], ['label' => 'Reports', 'url' => '#']], ], ], ); ``` ```html ``` ### OtpInput ```php use yii2\extensions\bootstrap6\OtpInput; echo OtpInput::widget(['name' => 'code', 'length' => 6, 'groups' => [3, 3]]); ``` ```html``` ### Popover ```php use yii2\extensions\bootstrap6\Popover; use yii2\extensions\bootstrap6\enum\Placement; Popover::begin(['title' => 'Popover title', 'content' => 'And here is some content.', 'placement' => Placement::RIGHT]); echo ''; Popover::end(); ``` ```html ``` ### Progress ```php use yii2\extensions\bootstrap6\Progress; use yii2\extensions\bootstrap6\enum\Theme; echo Progress::widget( ['percent' => 60, 'label' => '60%', 'theme' => Theme::SUCCESS, 'striped' => true, 'ariaLabel' => 'Upload'], ); ``` ```html