From 76f25aa2dfb3157bdbe694298c47fb181d9375fa Mon Sep 17 00:00:00 2001 From: peterhegman Date: Wed, 20 Jan 2021 15:31:55 -0800 Subject: [PATCH 1/3] feat(b-dropdown): add `toggle-attrs` prop Add `toggle-attrs` prop to allow adding HTML attributes to the dropdown toggle --- src/components/dropdown/dropdown.js | 5 +++++ src/components/dropdown/dropdown.spec.js | 11 +++++++++++ src/components/dropdown/package.json | 5 +++++ 3 files changed, 21 insertions(+) diff --git a/src/components/dropdown/dropdown.js b/src/components/dropdown/dropdown.js index cf48422ba43..9f3cbf2eb8b 100644 --- a/src/components/dropdown/dropdown.js +++ b/src/components/dropdown/dropdown.js @@ -3,6 +3,7 @@ import { NAME_DROPDOWN } from '../../constants/components' import { PROP_TYPE_ARRAY_OBJECT_STRING, PROP_TYPE_BOOLEAN, + PROP_TYPE_OBJECT, PROP_TYPE_OBJECT_STRING, PROP_TYPE_STRING } from '../../constants/props' @@ -42,6 +43,7 @@ export const props = makePropsConfigurable( text: makeProp(PROP_TYPE_STRING), toggleClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), toggleTag: makeProp(PROP_TYPE_STRING, 'button'), + toggleAttrs: makeProp(PROP_TYPE_OBJECT, {}), // TODO: This really should be `toggleLabel` toggleText: makeProp(PROP_TYPE_STRING, 'Toggle dropdown'), variant: makeProp(PROP_TYPE_STRING, 'secondary') @@ -145,6 +147,9 @@ export const BDropdown = /*#__PURE__*/ Vue.extend({ staticClass: 'dropdown-toggle', class: this.toggleClasses, attrs: { + // Merge in user supplied attributes + ...this.toggleAttrs, + // Must have attributes id: this.safeId('_BV_toggle_'), 'aria-haspopup': 'true', 'aria-expanded': toString(visible) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 01e2d383ec9..1e2c36afb8e 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -351,6 +351,17 @@ describe('dropdown', () => { wrapper.destroy() }) + it('should have attrs on toggle when toggle-attrs is set', async () => { + const wrapper = mount(BDropdown, { + attachTo: createContainer(), + propsData: { + toggleAttrs: { 'data-foo-bar': 'foo-bar' } + } + }) + expect(wrapper.find('.dropdown-toggle').attributes('data-foo-bar')).toBe('foo-bar') + wrapper.destroy() + }) + it('should have class dropup when prop dropup set', async () => { const wrapper = mount(BDropdown, { attachTo: createContainer(), diff --git a/src/components/dropdown/package.json b/src/components/dropdown/package.json index c056212f4d0..1abcf2e5f0a 100644 --- a/src/components/dropdown/package.json +++ b/src/components/dropdown/package.json @@ -98,6 +98,11 @@ "prop": "text", "description": "Text to place in the toggle button, or in the split button is split mode" }, + { + "prop": "toggleAttrs", + "version": "2.22.0", + "description": "Additional attributes to apply to the toggle button" + }, { "prop": "toggleClass", "description": "CSS class (or classes) to add to the toggle button" From 362b65a911c39bbda006507282587130d16267a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Thu, 21 Jan 2021 11:40:58 +0100 Subject: [PATCH 2/3] Update dropdown.js --- src/components/dropdown/dropdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.js b/src/components/dropdown/dropdown.js index 9f3cbf2eb8b..c7f72b7ed42 100644 --- a/src/components/dropdown/dropdown.js +++ b/src/components/dropdown/dropdown.js @@ -41,9 +41,9 @@ export const props = makePropsConfigurable( splitTo: makeProp(PROP_TYPE_OBJECT_STRING), splitVariant: makeProp(PROP_TYPE_STRING), text: makeProp(PROP_TYPE_STRING), + toggleAttrs: makeProp(PROP_TYPE_OBJECT, {}), toggleClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), toggleTag: makeProp(PROP_TYPE_STRING, 'button'), - toggleAttrs: makeProp(PROP_TYPE_OBJECT, {}), // TODO: This really should be `toggleLabel` toggleText: makeProp(PROP_TYPE_STRING, 'Toggle dropdown'), variant: makeProp(PROP_TYPE_STRING, 'secondary') From a31f67f9e7d88e05384624c58afb1530874bfe9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Thu, 21 Jan 2021 11:41:06 +0100 Subject: [PATCH 3/3] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 34 ++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 1e2c36afb8e..e916e170f13 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -300,7 +300,9 @@ describe('dropdown', () => { block: true } }) + expect(wrapper.classes()).not.toContain('btn-group') + wrapper.destroy() }) @@ -312,8 +314,10 @@ describe('dropdown', () => { split: true } }) + expect(wrapper.classes()).toContain('btn-group') expect(wrapper.classes()).toContain('d-flex') + wrapper.destroy() }) @@ -324,7 +328,9 @@ describe('dropdown', () => { noCaret: true } }) + expect(wrapper.find('.dropdown-toggle').classes()).toContain('dropdown-toggle-no-caret') + wrapper.destroy() }) @@ -336,7 +342,9 @@ describe('dropdown', () => { split: true } }) + expect(wrapper.find('.dropdown-toggle').classes()).not.toContain('dropdown-toggle-no-caret') + wrapper.destroy() }) @@ -347,18 +355,22 @@ describe('dropdown', () => { toggleTag: 'div' } }) + expect(wrapper.find('.dropdown-toggle').element.tagName).toBe('DIV') + wrapper.destroy() }) - it('should have attrs on toggle when toggle-attrs is set', async () => { + it('should have attributes on toggle when "toggle-attrs" prop is set', async () => { const wrapper = mount(BDropdown, { attachTo: createContainer(), propsData: { toggleAttrs: { 'data-foo-bar': 'foo-bar' } } }) + expect(wrapper.find('.dropdown-toggle').attributes('data-foo-bar')).toBe('foo-bar') + wrapper.destroy() }) @@ -369,17 +381,21 @@ describe('dropdown', () => { dropup: true } }) + expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).toContain('dropup') expect(wrapper.classes()).not.toContain('show') expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show') + wrapper.vm.show() await waitNT(wrapper.vm) await waitRAF() + expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).toContain('dropup') expect(wrapper.classes()).toContain('show') expect(wrapper.find('.dropdown-menu').classes()).toContain('show') + wrapper.destroy() }) @@ -390,17 +406,21 @@ describe('dropdown', () => { dropright: true } }) + expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).toContain('dropright') expect(wrapper.classes()).not.toContain('show') expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show') + wrapper.vm.show() await waitNT(wrapper.vm) await waitRAF() + expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).toContain('dropright') expect(wrapper.classes()).toContain('show') expect(wrapper.find('.dropdown-menu').classes()).toContain('show') + wrapper.destroy() }) @@ -411,17 +431,21 @@ describe('dropdown', () => { dropleft: true } }) + expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).toContain('dropleft') expect(wrapper.classes()).not.toContain('show') expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show') + wrapper.vm.show() await waitNT(wrapper.vm) await waitRAF() + expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).toContain('dropleft') expect(wrapper.classes()).toContain('show') expect(wrapper.find('.dropdown-menu').classes()).toContain('show') + wrapper.destroy() }) @@ -434,10 +458,12 @@ describe('dropdown', () => { split: true } }) + const $buttons = wrapper.findAll('button') const $split = $buttons.at(0) - expect($split.classes()).toContain(splitClass) + + wrapper.destroy() }) it('menu should have class dropdown-menu-right when prop right set', async () => { @@ -447,17 +473,21 @@ describe('dropdown', () => { right: true } }) + expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).not.toContain('show') expect(wrapper.find('.dropdown-menu').classes()).toContain('dropdown-menu-right') expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show') + wrapper.vm.show() await waitNT(wrapper.vm) await waitRAF() + expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).toContain('show') expect(wrapper.find('.dropdown-menu').classes()).toContain('dropdown-menu-right') expect(wrapper.find('.dropdown-menu').classes()).toContain('show') + wrapper.destroy() })