Skip to content
Permalink
Browse files

feat(b-dropdown): add `block` support to toggle button (closes #4266) (

…#4269)

* feat(b-dropdown): add `block` support to toggle button

* Update README.md

* Update dropdown.spec.js

* Update README.md
  • Loading branch information
jackmu95 committed Oct 17, 2019
1 parent 55787dd commit 30029e3b01d16178cc1c43b0294ffa4ed4966574
@@ -308,6 +308,58 @@ split button its own variant via the `split-variant` prop.
<!-- b-dropdown-split-variant.vue -->
```

### Block level dropdowns

By default dropdowns act like buttons and are displayed inline. To create block level dropdowns
(that span to the full width of a parent) set the `block` prop. Both, regular and split button
dropdowns are supported.

```html
<div>
<b-dropdown text="Block Level Dropdown" block variant="primary" class="m-2">
<b-dropdown-item href="#">Action</b-dropdown-item>
<b-dropdown-item href="#">Another action</b-dropdown-item>
<b-dropdown-item href="#">Something else here</b-dropdown-item>
</b-dropdown>

<b-dropdown
text="Block Level Split Dropdown"
block
split
split-variant="outline-primary"
variant="primary"
class="m-2"
>
<b-dropdown-item href="#">Action</b-dropdown-item>
<b-dropdown-item href="#">Another action</b-dropdown-item>
<b-dropdown-item href="#">Something else here...</b-dropdown-item>
</b-dropdown>
</div>

<!-- b-dropdown-block.vue -->
```

If you want the dropdown menu to span to the full width of the parent container too, add the `w-100`
utility class to the `menu-class` prop.

```html
<div>
<b-dropdown
text="Block Level Dropdown Menu"
block
variant="primary"
class="m-2"
menu-class="w-100"
>
<b-dropdown-item href="#">Action</b-dropdown-item>
<b-dropdown-item href="#">Another action</b-dropdown-item>
<b-dropdown-item href="#">Something else here</b-dropdown-item>
</b-dropdown>
</div>

<!-- b-dropdown-block-menu.vue -->
```

### Dropdown sub-component color variants

Many of the supported dropdown [sub-components](#dropdown-supported-sub-components) provide a
@@ -24,6 +24,10 @@ export const props = {
type: String,
default: () => getComponentConfig(NAME, 'variant')
},
block: {
type: Boolean,
default: false
},
menuClass: {
type: [String, Array],
default: null
@@ -84,9 +88,16 @@ export const BDropdown = /*#__PURE__*/ Vue.extend({
this.directionClass,
{
show: this.visible,
// Position `static` is needed to allow menu to "breakout" of the scrollParent boundaries
// when boundary is anything other than `scrollParent`
// See https://github.com/twbs/bootstrap/issues/24251#issuecomment-341413786
// The 'btn-group' class is required in `split` mode for button alignment
// It needs also to be applied when `block` is disabled to allow multiple
// dropdowns to be aligned one line
'btn-group': this.split || !this.block,
// When `block` is enabled and we are in `split` mode the 'd-flex' class
// needs to be applied to allow the buttons to stretch to full width
'd-flex': this.block && this.split,
// Position `static` is needed to allow menu to "breakout" of the `scrollParent`
// boundaries when boundary is anything other than `scrollParent`
// See: https://github.com/twbs/bootstrap/issues/24251#issuecomment-341413786
'position-static': this.boundary !== 'scrollParent' || !this.boundary
}
]
@@ -115,9 +126,10 @@ export const BDropdown = /*#__PURE__*/ Vue.extend({
const buttonContent = this.normalizeSlot('button-content') || this.html || stripTags(this.text)
if (this.split) {
const btnProps = {
disabled: this.disabled,
variant: this.splitVariant || this.variant,
size: this.size
size: this.size,
block: this.block,
disabled: this.disabled
}
// We add these as needed due to router-link issues with defined property with undefined/null values
if (this.splitTo) {
@@ -149,10 +161,11 @@ export const BDropdown = /*#__PURE__*/ Vue.extend({
staticClass: 'dropdown-toggle',
class: this.toggleClasses,
props: {
tag: this.toggleTag,
variant: this.variant,
size: this.size,
disabled: this.disabled,
tag: this.toggleTag
block: this.block && !this.split,
disabled: this.disabled
},
attrs: {
id: this.safeId('_BV_toggle_'),
@@ -186,7 +199,7 @@ export const BDropdown = /*#__PURE__*/ Vue.extend({
return h(
'div',
{
staticClass: 'dropdown btn-group b-dropdown',
staticClass: 'dropdown b-dropdown',
class: this.dropdownClasses,
attrs: { id: this.safeId() }
},
@@ -247,6 +247,30 @@ describe('dropdown', () => {
wrapper.destroy()
})

it('should not have "btn-group" class when block is true', async () => {
const wrapper = mount(BDropdown, {
attachToDocument: true,
propsData: {
block: true
}
})
expect(wrapper.classes()).not.toContain('btn-group')
wrapper.destroy()
})

it('should have "btn-group" and "d-flex" classes when block and split are true', async () => {
const wrapper = mount(BDropdown, {
attachToDocument: true,
propsData: {
block: true,
split: true
}
})
expect(wrapper.classes()).toContain('btn-group')
expect(wrapper.classes()).toContain('d-flex')
wrapper.destroy()
})

it('should have "dropdown-toggle-no-caret" class when no-caret is true', async () => {
const wrapper = mount(BDropdown, {
attachToDocument: true,
@@ -67,6 +67,10 @@
"prop": "toggleClass",
"description": "CSS class (or classes) to add to the toggle button"
},
{
"prop": "block",
"description": "Renders a 100% width toggle button (expands to the width of it's parent container)"
},
{
"prop": "noCaret",
"description": "Hide the caret indicator on the toggle button"

0 comments on commit 30029e3

Please sign in to comment.
You can’t perform that action at this time.