diff --git a/Alert.php b/Alert.php
index e5755c1..18f3960 100644
--- a/Alert.php
+++ b/Alert.php
@@ -135,9 +135,7 @@ class Alert extends Widget
*/
protected function initOptions()
{
- Html::addCssClass($this->options, 'alert');
- Html::addCssClass($this->options, 'fade');
- Html::addCssClass($this->options, 'in');
+ Html::addCssClass($this->options, ['alert', 'fade', 'in']);
if ($this->closeButton !== false) {
$this->closeButton = array_merge([
diff --git a/Button.php b/Button.php
index eedcc46..985279a 100644
--- a/Button.php
+++ b/Button.php
@@ -46,7 +46,7 @@ class Button extends Widget
{
parent::init();
$this->clientOptions = false;
- Html::addCssClass($this->options, 'btn');
+ Html::addCssClass($this->options, ['widget' => 'btn']);
}
/**
diff --git a/ButtonDropdown.php b/ButtonDropdown.php
index 0d10b6f..1a379d7 100644
--- a/ButtonDropdown.php
+++ b/ButtonDropdown.php
@@ -75,7 +75,7 @@ class ButtonDropdown extends Widget
public function run()
{
// @todo use [[options]] instead of [[containerOptions]] and introduce [[buttonOptions]] before 2.1 release
- Html::addCssClass($this->containerOptions, 'btn-group');
+ Html::addCssClass($this->containerOptions, ['widget' => 'btn-group']);
$options = $this->containerOptions;
$tag = ArrayHelper::remove($options, 'tag', 'div');
@@ -94,7 +94,7 @@ class ButtonDropdown extends Widget
*/
protected function renderButton()
{
- Html::addCssClass($this->options, 'btn');
+ Html::addCssClass($this->options, ['widget' => 'btn']);
$label = $this->label;
if ($this->encodeLabel) {
$label = Html::encode($label);
@@ -102,7 +102,7 @@ class ButtonDropdown extends Widget
if ($this->split) {
$options = $this->options;
$this->options['data-toggle'] = 'dropdown';
- Html::addCssClass($this->options, 'dropdown-toggle');
+ Html::addCssClass($this->options, ['toggle' => 'dropdown-toggle']);
unset($this->options['id']);
$splitButton = Button::widget([
'label' => '',
@@ -116,7 +116,7 @@ class ButtonDropdown extends Widget
if (!isset($options['href'])) {
$options['href'] = '#';
}
- Html::addCssClass($options, 'dropdown-toggle');
+ Html::addCssClass($options, ['toggle' => 'dropdown-toggle']);
$options['data-toggle'] = 'dropdown';
$splitButton = '';
}
diff --git a/ButtonGroup.php b/ButtonGroup.php
index 4bf47ef..a0c3ec2 100644
--- a/ButtonGroup.php
+++ b/ButtonGroup.php
@@ -65,7 +65,7 @@ class ButtonGroup extends Widget
public function init()
{
parent::init();
- Html::addCssClass($this->options, 'btn-group');
+ Html::addCssClass($this->options, ['widget' => 'btn-group']);
}
/**
diff --git a/Carousel.php b/Carousel.php
index f212619..d932a66 100644
--- a/Carousel.php
+++ b/Carousel.php
@@ -72,7 +72,7 @@ class Carousel extends Widget
public function init()
{
parent::init();
- Html::addCssClass($this->options, 'carousel');
+ Html::addCssClass($this->options, ['widget' => 'carousel']);
}
/**
@@ -149,7 +149,7 @@ class Carousel extends Widget
throw new InvalidConfigException('The "content" option is required.');
}
- Html::addCssClass($options, 'item');
+ Html::addCssClass($options, ['widget' => 'item']);
if ($index === 0) {
Html::addCssClass($options, 'active');
}
diff --git a/Collapse.php b/Collapse.php
index 0b33cd5..b2de61f 100644
--- a/Collapse.php
+++ b/Collapse.php
@@ -78,7 +78,7 @@ class Collapse extends Widget
public function init()
{
parent::init();
- Html::addCssClass($this->options, 'panel-group');
+ Html::addCssClass($this->options, ['widget' => 'panel-group']);
}
/**
@@ -109,7 +109,7 @@ class Collapse extends Widget
}
$header = $item['label'];
$options = ArrayHelper::getValue($item, 'options', []);
- Html::addCssClass($options, 'panel panel-default');
+ Html::addCssClass($options, ['panel' => 'panel', 'widget' => 'panel-default']);
$items[] = Html::tag('div', $this->renderItem($header, $item, ++$index), $options);
}
@@ -130,7 +130,7 @@ class Collapse extends Widget
$id = $this->options['id'] . '-collapse' . $index;
$options = ArrayHelper::getValue($item, 'contentOptions', []);
$options['id'] = $id;
- Html::addCssClass($options, 'panel-collapse collapse');
+ Html::addCssClass($options, ['widget' => 'panel-collapse', 'collapse' => 'collapse']);
$encodeLabel = isset($item['encode']) ? $item['encode'] : $this->encodeLabels;
if ($encodeLabel) {
diff --git a/Dropdown.php b/Dropdown.php
index 1c28f01..b68ac11 100644
--- a/Dropdown.php
+++ b/Dropdown.php
@@ -77,7 +77,7 @@ class Dropdown extends Widget
unset($this->submenuOptions['id']);
}
parent::init();
- Html::addCssClass($this->options, 'dropdown-menu');
+ Html::addCssClass($this->options, ['widget' => 'dropdown-menu']);
}
/**
@@ -120,7 +120,7 @@ class Dropdown extends Widget
if (empty($item['items'])) {
if ($url === null) {
$content = $label;
- Html::addCssClass($itemOptions, 'dropdown-header');
+ Html::addCssClass($itemOptions, ['widget' => 'dropdown-header']);
} else {
$content = Html::a($label, $url, $linkOptions);
}
@@ -131,7 +131,7 @@ class Dropdown extends Widget
}
$content = Html::a($label, $url === null ? '#' : $url, $linkOptions)
. $this->renderItems($item['items'], $submenuOptions);
- Html::addCssClass($itemOptions, 'dropdown-submenu');
+ Html::addCssClass($itemOptions, ['widget' => 'dropdown-submenu']);
}
$lines[] = Html::tag('li', $content, $itemOptions);
diff --git a/Modal.php b/Modal.php
index c138f30..6555135 100644
--- a/Modal.php
+++ b/Modal.php
@@ -136,7 +136,7 @@ class Modal extends Widget
$this->header = $button . "\n" . $this->header;
}
if ($this->header !== null) {
- Html::addCssClass($this->headerOptions, 'modal-header');
+ Html::addCssClass($this->headerOptions, ['widget' => 'modal-header']);
return Html::tag('div', "\n" . $this->header . "\n", $this->headerOptions);
} else {
return null;
@@ -168,7 +168,7 @@ class Modal extends Widget
protected function renderFooter()
{
if ($this->footer !== null) {
- Html::addCssClass($this->footerOptions, 'modal-footer');
+ Html::addCssClass($this->footerOptions, ['widget' => 'modal-footer']);
return Html::tag('div', "\n" . $this->footer . "\n", $this->footerOptions);
} else {
return null;
@@ -224,7 +224,7 @@ class Modal extends Widget
'role' => 'dialog',
'tabindex' => -1,
], $this->options);
- Html::addCssClass($this->options, 'modal');
+ Html::addCssClass($this->options, ['widget' => 'modal']);
if ($this->clientOptions !== false) {
$this->clientOptions = array_merge(['show' => false], $this->clientOptions);
diff --git a/Nav.php b/Nav.php
index 5be7994..d59e9b0 100644
--- a/Nav.php
+++ b/Nav.php
@@ -121,7 +121,7 @@ class Nav extends Widget
if ($this->dropDownCaret === null) {
$this->dropDownCaret = Html::tag('b', '', ['class' => 'caret']);
}
- Html::addCssClass($this->options, 'nav');
+ Html::addCssClass($this->options, ['widget' => 'nav']);
}
/**
@@ -178,8 +178,8 @@ class Nav extends Widget
if ($items !== null) {
$linkOptions['data-toggle'] = 'dropdown';
- Html::addCssClass($options, 'dropdown');
- Html::addCssClass($linkOptions, 'dropdown-toggle');
+ Html::addCssClass($options, ['widget' => 'dropdown']);
+ Html::addCssClass($linkOptions, ['widget' => 'dropdown-toggle']);
if ($this->dropDownCaret !== '') {
$label .= ' ' . $this->dropDownCaret;
}
diff --git a/NavBar.php b/NavBar.php
index aa6db21..f67f32b 100644
--- a/NavBar.php
+++ b/NavBar.php
@@ -93,11 +93,11 @@ class NavBar extends Widget
{
parent::init();
$this->clientOptions = false;
- Html::addCssClass($this->options, 'navbar');
- if ($this->options['class'] === 'navbar') {
- Html::addCssClass($this->options, 'navbar-default');
+ if (empty($this->options['class'])) {
+ Html::addCssClass($this->options, ['navbar', 'navbar-default']);
+ } else {
+ Html::addCssClass($this->options, ['widget' => 'navbar']);
}
- Html::addCssClass($this->brandOptions, 'navbar-brand');
if (empty($this->options['role'])) {
$this->options['role'] = 'navigation';
}
@@ -116,12 +116,11 @@ class NavBar extends Widget
}
echo $this->renderToggleButton();
if ($this->brandLabel !== false) {
- Html::addCssClass($this->brandOptions, 'navbar-brand');
+ Html::addCssClass($this->brandOptions, ['widget' => 'navbar-brand']);
echo Html::a($this->brandLabel, $this->brandUrl === false ? Yii::$app->homeUrl : $this->brandUrl, $this->brandOptions);
}
echo Html::endTag('div');
- Html::addCssClass($this->containerOptions, 'collapse');
- Html::addCssClass($this->containerOptions, 'navbar-collapse');
+ Html::addCssClass($this->containerOptions, ['collapse' => 'collapse', 'widget' => 'navbar-collapse']);
$options = $this->containerOptions;
$tag = ArrayHelper::remove($options, 'tag', 'div');
echo Html::beginTag($tag, $options);
diff --git a/Progress.php b/Progress.php
index d80bd6b..14c7122 100644
--- a/Progress.php
+++ b/Progress.php
@@ -96,7 +96,7 @@ class Progress extends Widget
public function init()
{
parent::init();
- Html::addCssClass($this->options, 'progress');
+ Html::addCssClass($this->options, ['widget' => 'progress']);
}
/**
@@ -152,7 +152,7 @@ class Progress extends Widget
'style' => "width:{$percent}%",
];
$options = array_merge($defaultOptions, $options);
- Html::addCssClass($options, 'progress-bar');
+ Html::addCssClass($options, ['widget' => 'progress-bar']);
$out = Html::beginTag('div', $options);
$out .= $label;
diff --git a/Tabs.php b/Tabs.php
index ff5293a..f60724f 100644
--- a/Tabs.php
+++ b/Tabs.php
@@ -122,7 +122,7 @@ class Tabs extends Widget
public function init()
{
parent::init();
- Html::addCssClass($this->options, 'nav ' . $this->navType);
+ Html::addCssClass($this->options, ['widget' => 'nav', $this->navType]);
}
/**
@@ -162,13 +162,13 @@ class Tabs extends Widget
if (isset($item['items'])) {
$label .= ' ';
- Html::addCssClass($headerOptions, 'dropdown');
+ Html::addCssClass($headerOptions, ['widget' => 'dropdown']);
if ($this->renderDropdown($n, $item['items'], $panes)) {
Html::addCssClass($headerOptions, 'active');
}
- Html::addCssClass($linkOptions, 'dropdown-toggle');
+ Html::addCssClass($linkOptions, ['widget' => 'dropdown-toggle']);
$linkOptions['data-toggle'] = 'dropdown';
$header = Html::a($label, "#", $linkOptions) . "\n"
. Dropdown::widget(['items' => $item['items'], 'clientOptions' => false, 'view' => $this->getView()]);
@@ -176,7 +176,7 @@ class Tabs extends Widget
$options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', []));
$options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-tab' . $n);
- Html::addCssClass($options, 'tab-pane');
+ Html::addCssClass($options, ['widget' => 'tab-pane']);
if (ArrayHelper::remove($item, 'active')) {
Html::addCssClass($options, 'active');
Html::addCssClass($headerOptions, 'active');
@@ -241,7 +241,7 @@ class Tabs extends Widget
$content = ArrayHelper::remove($item, 'content');
$options = ArrayHelper::remove($item, 'contentOptions', []);
- Html::addCssClass($options, 'tab-pane');
+ Html::addCssClass($options, ['widget' => 'tab-pane']);
if (ArrayHelper::remove($item, 'active')) {
Html::addCssClass($options, 'active');
Html::addCssClass($item['options'], 'active');
diff --git a/docs/guide/usage-widgets.md b/docs/guide/usage-widgets.md
index 004a949..6b63e72 100644
--- a/docs/guide/usage-widgets.md
+++ b/docs/guide/usage-widgets.md
@@ -17,3 +17,40 @@ framework features. All widgets belong to `\yii\bootstrap` namespace:
- [[yii\bootstrap\NavBar|NavBar]]
- [[yii\bootstrap\Progress|Progress]]
- [[yii\bootstrap\Tabs|Tabs]]
+
+
+## Customize widget CSS classes
+
+Widgets allow quick composition of the HTML for particular Bootstrap components, which requires usage of the
+Bootstrap CSS classes. Those classes are added automatically by the widgets. However usually widget provides
+fields or properties, which allow customization of the CSS styles for particular HTML tags.
+
+For example: you may use [[yii\bootstrap\Button::options]] to customize appearance of the rendered button.
+Class 'btn' will be added automatically, so you don't need to worry about it. All you need is specify particular
+button class:
+
+```php
+echo Button::widget([
+ 'label' => 'Action',
+ 'options' => ['class' => 'btn-primary'], // produces class "btn btn-primary"
+]);
+```
+
+However, sometimes you may need to replace standard class, added by the widget, with alternative one.
+For example: widget [[yii\bootstrap\ButtonGroup]] uses 'btn-group' class for the container div, but you may
+need to use 'btn-group-vertical', which allows vertical-style layout for the buttons. Using plain 'class' option
+simply adds 'btn-group-vertical' to 'btn-group', which produces incorrect result.
+In order to actually replace class added by widget, you need to specify 'class' option as array, containing
+needed class name under the 'widget' key:
+
+```php
+echo ButtonGroup::widget([
+ 'options' => [
+ 'class' => ['widget' => 'btn-group-vertical'] // replace 'btn-group' with 'btn-group-vertical'
+ ],
+ 'buttons' => [
+ ['label' => 'A'],
+ ['label' => 'B'],
+ ]
+]);
+```