Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/components/dropdown/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 21 additions & 8 deletions src/components/dropdown/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export const props = {
type: String,
default: () => getComponentConfig(NAME, 'variant')
},
block: {
type: Boolean,
default: false
},
menuClass: {
type: [String, Array],
default: null
Expand Down Expand Up @@ -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
}
]
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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_'),
Expand Down Expand Up @@ -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() }
},
Expand Down
24 changes: 24 additions & 0 deletions src/components/dropdown/dropdown.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions src/components/dropdown/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down