From b02934f7b574a73ec8184b00d184ef8be7758ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Mon, 11 May 2020 09:03:21 +0200 Subject: [PATCH 01/18] fix(b-nav-item-dropdown): let `` handle `href` default --- src/components/nav/nav-item-dropdown.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/components/nav/nav-item-dropdown.js b/src/components/nav/nav-item-dropdown.js index 85cfc190890..55d5c06a244 100644 --- a/src/components/nav/nav-item-dropdown.js +++ b/src/components/nav/nav-item-dropdown.js @@ -1,19 +1,19 @@ import Vue from '../../utils/vue' -import { props as BDropdownProps } from '../dropdown/dropdown' -import idMixin from '../../mixins/id' -import dropdownMixin from '../../mixins/dropdown' -import normalizeSlotMixin from '../../mixins/normalize-slot' import pluckProps from '../../utils/pluck-props' import { htmlOrText } from '../../utils/html' +import dropdownMixin from '../../mixins/dropdown' +import idMixin from '../../mixins/id' +import normalizeSlotMixin from '../../mixins/normalize-slot' +import { props as BDropdownProps } from '../dropdown/dropdown' import { BLink } from '../link/link' -// -- Constants -- - +// --- Props --- export const props = pluckProps( ['text', 'html', 'menuClass', 'toggleClass', 'noCaret', 'role', 'lazy'], BDropdownProps ) +// --- Main component --- // @vue/component export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ name: 'BNavItemDropdown', @@ -41,16 +41,13 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ } }, render(h) { - const button = h( + const $button = h( BLink, { ref: 'toggle', staticClass: 'nav-link dropdown-toggle', class: this.toggleClasses, - props: { - href: '#', - disabled: this.disabled - }, + props: { disabled: this.disabled }, attrs: { id: this.safeId('_BV_button_'), 'aria-haspopup': 'true', @@ -68,7 +65,8 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ h('span', { domProps: htmlOrText(this.html, this.text) }) ] ) - const menu = h( + + const $menu = h( 'ul', { staticClass: 'dropdown-menu', @@ -84,6 +82,7 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ }, !this.lazy || this.visible ? this.normalizeSlot('default', { hide: this.hide }) : [h()] ) + return h( 'li', { @@ -91,7 +90,7 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ class: this.dropdownClasses, attrs: { id: this.safeId() } }, - [button, menu] + [$button, $menu] ) } }) From 389b300114b2cb2ec44f1f58448e7423ce1d2636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Mon, 11 May 2020 22:55:51 +0200 Subject: [PATCH 02/18] Update nav-item-dropdown.js --- src/components/nav/nav-item-dropdown.js | 40 ++++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/components/nav/nav-item-dropdown.js b/src/components/nav/nav-item-dropdown.js index 55d5c06a244..f9315abdc85 100644 --- a/src/components/nav/nav-item-dropdown.js +++ b/src/components/nav/nav-item-dropdown.js @@ -5,13 +5,16 @@ import dropdownMixin from '../../mixins/dropdown' import idMixin from '../../mixins/id' import normalizeSlotMixin from '../../mixins/normalize-slot' import { props as BDropdownProps } from '../dropdown/dropdown' -import { BLink } from '../link/link' +import { BLink, props as BLinkProps } from '../link/link' // --- Props --- -export const props = pluckProps( - ['text', 'html', 'menuClass', 'toggleClass', 'noCaret', 'role', 'lazy'], - BDropdownProps -) +export const props = { + ...pluckProps( + ['text', 'html', 'menuClass', 'toggleClass', 'noCaret', 'role', 'lazy'], + BDropdownProps + ), + ...pluckProps(['href'], BLinkProps) +} // --- Main component --- // @vue/component @@ -20,6 +23,9 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ mixins: [idMixin, dropdownMixin, normalizeSlotMixin], props, computed: { + buttonId() { + return this.safeId('_BV_button_') + }, isNav() { // Signal to dropdown mixin that we are in a navbar return true @@ -41,23 +47,29 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ } }, render(h) { + const { buttonId, visible } = this + const $button = h( BLink, { - ref: 'toggle', staticClass: 'nav-link dropdown-toggle', class: this.toggleClasses, - props: { disabled: this.disabled }, + props: { + href: this.href || `#${buttonId}`, + disabled: this.disabled + }, attrs: { - id: this.safeId('_BV_button_'), + id: buttonId, + role: 'button', 'aria-haspopup': 'true', - 'aria-expanded': this.visible ? 'true' : 'false' + 'aria-expanded': visible ? 'true' : 'false' }, on: { mousedown: this.onMousedown, click: this.toggle, keydown: this.toggle // Handle ENTER, SPACE and DOWN - } + }, + ref: 'toggle' }, [ this.$slots['button-content'] || @@ -71,16 +83,16 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ { staticClass: 'dropdown-menu', class: this.menuClasses, - ref: 'menu', attrs: { tabindex: '-1', - 'aria-labelledby': this.safeId('_BV_button_') + 'aria-labelledby': buttonId }, on: { keydown: this.onKeydown // Handle UP, DOWN and ESC - } + }, + ref: 'menu' }, - !this.lazy || this.visible ? this.normalizeSlot('default', { hide: this.hide }) : [h()] + !this.lazy || visible ? this.normalizeSlot('default', { hide: this.hide }) : [h()] ) return h( From e918f3d2f4a2a6e0cc74231797c50966bcf4c876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Mon, 11 May 2020 22:55:56 +0200 Subject: [PATCH 03/18] Update nav-item-dropdown.spec.js --- src/components/nav/nav-item-dropdown.spec.js | 94 +++++++++++++++++--- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/src/components/nav/nav-item-dropdown.spec.js b/src/components/nav/nav-item-dropdown.spec.js index 2ed200bc36f..f01e8ebadc0 100644 --- a/src/components/nav/nav-item-dropdown.spec.js +++ b/src/components/nav/nav-item-dropdown.spec.js @@ -1,21 +1,39 @@ import { mount } from '@vue/test-utils' +import { waitNT } from '../../../tests/utils' import { BNavItemDropdown } from './nav-item-dropdown' describe('nav-item-dropdown', () => { - it('should have custom toggle class in nav-item-dropdown', async () => { + it('has expected default structure', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { - text: 'toggle', - toggleClass: 'nav-link-custom' + text: 'toggle' } }) + expect(wrapper.vm).toBeDefined() - expect(wrapper.findAll('.dropdown-toggle').length).toBe(1) - const $toggle = wrapper.find('.dropdown-toggle') + await waitNT(wrapper.vm) - expect($toggle.classes()).toContain('nav-link') + expect(wrapper.element.tagName).toBe('LI') + expect(wrapper.element.hasAttribute('id')).toBe(true) + expect(wrapper.classes()).toContain('nav-item') + expect(wrapper.classes()).toContain('b-nav-dropdown') + expect(wrapper.classes()).toContain('dropdown') + + const $toggle = wrapper.find('.dropdown-toggle') + expect($toggle.element.tagName).toBe('A') + expect($toggle.element.hasAttribute('id')).toBe(true) + expect($toggle.attributes('role')).toEqual('button') + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($toggle.attributes('href')).toEqual(`#${$toggle.attributes('id')}`) expect($toggle.classes()).toContain('dropdown-toggle') - expect($toggle.classes()).toContain('nav-link-custom') + expect($toggle.classes()).toContain('nav-link') + + const $menu = wrapper.find('.dropdown-menu') + expect($menu.element.tagName).toBe('UL') + expect($menu.attributes('tabindex')).toEqual('-1') + expect($menu.attributes('aria-labelledby')).toEqual($toggle.attributes('id')) + expect($menu.classes()).toContain('dropdown-menu') wrapper.destroy() }) @@ -26,13 +44,35 @@ describe('nav-item-dropdown', () => { text: 'toggle' } }) - expect(wrapper.vm).toBeDefined() + expect(wrapper.vm).toBeDefined() expect(wrapper.vm.isNav).toBe(true) wrapper.destroy() }) + it('should have custom toggle class in nav-item-dropdown', async () => { + const wrapper = mount(BNavItemDropdown, { + propsData: { + text: 'toggle', + toggleClass: 'nav-link-custom' + } + }) + + expect(wrapper.vm).toBeDefined() + + await waitNT(wrapper.vm) + + const $toggle = wrapper.find('.dropdown-toggle') + expect($toggle.element.tagName).toBe('A') + expect($toggle.attributes('href')).toEqual(`#${$toggle.attributes('id')}`) + expect($toggle.classes()).toContain('nav-link') + expect($toggle.classes()).toContain('dropdown-toggle') + expect($toggle.classes()).toContain('nav-link-custom') + + wrapper.destroy() + }) + it('should be disabled when disabled prop set', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { @@ -40,17 +80,47 @@ describe('nav-item-dropdown', () => { disabled: true } }) + expect(wrapper.vm).toBeDefined() - expect(wrapper.findAll('.dropdown-toggle').length).toBe(1) + + await waitNT(wrapper.vm) + const $toggle = wrapper.find('.dropdown-toggle') expect($toggle.element.tagName).toBe('A') - - expect($toggle.attributes('aria-disabled')).toBeDefined() - expect($toggle.attributes('href')).toEqual('#') + expect($toggle.attributes('role')).toEqual('button') + expect($toggle.attributes('href')).toEqual(`#${$toggle.attributes('id')}`) + expect($toggle.classes()).toContain('nav-link') + expect($toggle.classes()).toContain('dropdown-toggle') expect($toggle.classes()).toContain('disabled') + expect($toggle.attributes('aria-disabled')).toBeDefined() + + wrapper.destroy() + }) + + it('should prevent click when custom href is set', async () => { + const wrapper = mount(BNavItemDropdown, { + propsData: { + text: 'toggle', + href: '/foobar' + } + }) + + expect(wrapper.vm).toBeDefined() + + await waitNT(wrapper.vm) + + const $toggle = wrapper.find('.dropdown-toggle') + expect($toggle.element.tagName).toBe('A') + expect($toggle.attributes('href')).toEqual('/foobar') expect($toggle.classes()).toContain('nav-link') expect($toggle.classes()).toContain('dropdown-toggle') + await $toggle.trigger('click') + expect(wrapper.emitted('toggle')).toBeDefined() + expect(wrapper.emitted('toggle').length).toBe(1) + expect(wrapper.emitted('toggle')[0]).toBeDefined() + expect(wrapper.emitted('toggle')[0][0].defaultPrevented).toBe(true) + wrapper.destroy() }) }) From b6cbbb894777df9c5bcb3ac3011f6fcb5f22b78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Mon, 11 May 2020 23:05:05 +0200 Subject: [PATCH 04/18] Update nav-item-dropdown.js --- src/components/nav/nav-item-dropdown.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/nav/nav-item-dropdown.js b/src/components/nav/nav-item-dropdown.js index f9315abdc85..391609b42dc 100644 --- a/src/components/nav/nav-item-dropdown.js +++ b/src/components/nav/nav-item-dropdown.js @@ -23,8 +23,8 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ mixins: [idMixin, dropdownMixin, normalizeSlotMixin], props, computed: { - buttonId() { - return this.safeId('_BV_button_') + toggleId() { + return this.safeId('_BV_toggle_') }, isNav() { // Signal to dropdown mixin that we are in a navbar @@ -47,19 +47,19 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ } }, render(h) { - const { buttonId, visible } = this + const { toggleId, visible } = this - const $button = h( + const $toggle = h( BLink, { staticClass: 'nav-link dropdown-toggle', class: this.toggleClasses, props: { - href: this.href || `#${buttonId}`, + href: this.href || `#${toggleId}`, disabled: this.disabled }, attrs: { - id: buttonId, + id: toggleId, role: 'button', 'aria-haspopup': 'true', 'aria-expanded': visible ? 'true' : 'false' @@ -85,7 +85,7 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ class: this.menuClasses, attrs: { tabindex: '-1', - 'aria-labelledby': buttonId + 'aria-labelledby': toggleId }, on: { keydown: this.onKeydown // Handle UP, DOWN and ESC @@ -102,7 +102,7 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ class: this.dropdownClasses, attrs: { id: this.safeId() } }, - [$button, $menu] + [$toggle, $menu] ) } }) From a0226614a57a454bc8953b44c7823b8d877b1ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Mon, 11 May 2020 23:11:09 +0200 Subject: [PATCH 05/18] Update nav-item-dropdown.js --- src/components/nav/nav-item-dropdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/nav/nav-item-dropdown.js b/src/components/nav/nav-item-dropdown.js index 391609b42dc..c7fc10d18c8 100644 --- a/src/components/nav/nav-item-dropdown.js +++ b/src/components/nav/nav-item-dropdown.js @@ -55,7 +55,7 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ staticClass: 'nav-link dropdown-toggle', class: this.toggleClasses, props: { - href: this.href || `#${toggleId}`, + href: this.href || `#${toggleId || ''}`, disabled: this.disabled }, attrs: { From a0f016c81da5b6c5ea5282d0d14d31be4ed358c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Tue, 12 May 2020 00:00:11 +0200 Subject: [PATCH 06/18] Update id.js --- src/mixins/id.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/mixins/id.js b/src/mixins/id.js index 51572258488..44d8abd5d5e 100644 --- a/src/mixins/id.js +++ b/src/mixins/id.js @@ -1,8 +1,6 @@ -/* - * SSR Safe Client Side ID attribute generation - * id's can only be generated client side, after mount. - * this._uid is not synched between server and client. - */ +// SSR safe client-side ID attribute generation +// ID's can only be generated client-side, after mount +// `this._uid` is not synched between server and client // @vue/component export default { @@ -19,13 +17,13 @@ export default { }, computed: { safeId() { - // Computed property that returns a dynamic function for creating the ID. - // Reacts to changes in both .id and .localId_ And regens a new function + // Computed property that returns a dynamic function for creating the ID + // Reacts to changes in both `.id` and `.localId_` and regenerates a new function const id = this.id || this.localId_ // We return a function that accepts an optional suffix string - // So this computed prop looks and works like a method!!! - // But benefits from Vue's Computed prop caching + // So this computed prop looks and works like a method + // but benefits from Vue's computed prop caching const fn = suffix => { if (!id) { return null @@ -37,10 +35,10 @@ export default { } }, mounted() { - // mounted only occurs client side + // `mounted()` only occurs client-side this.$nextTick(() => { - // Update dom with auto ID after dom loaded to prevent - // SSR hydration errors. + // Update DOM with auto-generated ID after mount + // to prevent SSR hydration errors this.localId_ = `__BVID__${this._uid}` }) } From f78433472fa3a7f0a412aa43edfcd3e51576b83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Tue, 12 May 2020 00:10:53 +0200 Subject: [PATCH 07/18] Update nav-item-dropdown.js --- src/components/nav/nav-item-dropdown.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/components/nav/nav-item-dropdown.js b/src/components/nav/nav-item-dropdown.js index c7fc10d18c8..a5f11eeb1b7 100644 --- a/src/components/nav/nav-item-dropdown.js +++ b/src/components/nav/nav-item-dropdown.js @@ -5,16 +5,13 @@ import dropdownMixin from '../../mixins/dropdown' import idMixin from '../../mixins/id' import normalizeSlotMixin from '../../mixins/normalize-slot' import { props as BDropdownProps } from '../dropdown/dropdown' -import { BLink, props as BLinkProps } from '../link/link' +import { BLink } from '../link/link' // --- Props --- -export const props = { - ...pluckProps( - ['text', 'html', 'menuClass', 'toggleClass', 'noCaret', 'role', 'lazy'], - BDropdownProps - ), - ...pluckProps(['href'], BLinkProps) -} +export const props = pluckProps( + ['text', 'html', 'menuClass', 'toggleClass', 'noCaret', 'role', 'lazy'], + BDropdownProps +) // --- Main component --- // @vue/component @@ -55,7 +52,7 @@ export const BNavItemDropdown = /*#__PURE__*/ Vue.extend({ staticClass: 'nav-link dropdown-toggle', class: this.toggleClasses, props: { - href: this.href || `#${toggleId || ''}`, + href: `#${this.id || ''}`, disabled: this.disabled }, attrs: { From 0d2b64619bad327d4c6381ebfd9a8d657c2c1176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Tue, 12 May 2020 00:10:57 +0200 Subject: [PATCH 08/18] Update nav-item-dropdown.spec.js --- src/components/nav/nav-item-dropdown.spec.js | 56 ++++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/components/nav/nav-item-dropdown.spec.js b/src/components/nav/nav-item-dropdown.spec.js index f01e8ebadc0..24b1d18e649 100644 --- a/src/components/nav/nav-item-dropdown.spec.js +++ b/src/components/nav/nav-item-dropdown.spec.js @@ -1,5 +1,5 @@ import { mount } from '@vue/test-utils' -import { waitNT } from '../../../tests/utils' +import { waitNT, waitRAF } from '../../../tests/utils' import { BNavItemDropdown } from './nav-item-dropdown' describe('nav-item-dropdown', () => { @@ -25,7 +25,7 @@ describe('nav-item-dropdown', () => { expect($toggle.attributes('role')).toEqual('button') expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toEqual('false') - expect($toggle.attributes('href')).toEqual(`#${$toggle.attributes('id')}`) + expect($toggle.attributes('href')).toEqual('#') expect($toggle.classes()).toContain('dropdown-toggle') expect($toggle.classes()).toContain('nav-link') @@ -38,7 +38,7 @@ describe('nav-item-dropdown', () => { wrapper.destroy() }) - it('should flag that we are in a nav', async () => { + it('should have a flag that we are in a nav', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { text: 'toggle' @@ -51,7 +51,7 @@ describe('nav-item-dropdown', () => { wrapper.destroy() }) - it('should have custom toggle class in nav-item-dropdown', async () => { + it('should have custom toggle class when "toggle-class" prop set', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { text: 'toggle', @@ -60,20 +60,15 @@ describe('nav-item-dropdown', () => { }) expect(wrapper.vm).toBeDefined() - await waitNT(wrapper.vm) const $toggle = wrapper.find('.dropdown-toggle') - expect($toggle.element.tagName).toBe('A') - expect($toggle.attributes('href')).toEqual(`#${$toggle.attributes('id')}`) - expect($toggle.classes()).toContain('nav-link') - expect($toggle.classes()).toContain('dropdown-toggle') expect($toggle.classes()).toContain('nav-link-custom') wrapper.destroy() }) - it('should be disabled when disabled prop set', async () => { + it('should be disabled when "disabled" prop set', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { text: 'toggle', @@ -82,38 +77,53 @@ describe('nav-item-dropdown', () => { }) expect(wrapper.vm).toBeDefined() - await waitNT(wrapper.vm) const $toggle = wrapper.find('.dropdown-toggle') - expect($toggle.element.tagName).toBe('A') - expect($toggle.attributes('role')).toEqual('button') - expect($toggle.attributes('href')).toEqual(`#${$toggle.attributes('id')}`) - expect($toggle.classes()).toContain('nav-link') - expect($toggle.classes()).toContain('dropdown-toggle') expect($toggle.classes()).toContain('disabled') expect($toggle.attributes('aria-disabled')).toBeDefined() wrapper.destroy() }) - it('should prevent click when custom href is set', async () => { + it('should open/close on toggle click', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { - text: 'toggle', - href: '/foobar' + text: 'toggle' } }) expect(wrapper.vm).toBeDefined() + await waitNT(wrapper.vm) + + const $toggle = wrapper.find('.dropdown-toggle') + expect(wrapper.vm.visible).toBe(false) + expect($toggle.attributes('aria-expanded')).toEqual('false') + + await $toggle.trigger('click') + await waitRAF() + expect(wrapper.vm.visible).toBe(true) + expect($toggle.attributes('aria-expanded')).toEqual('true') + await $toggle.trigger('click') + await waitRAF() + expect(wrapper.vm.visible).toBe(false) + expect($toggle.attributes('aria-expanded')).toEqual('false') + + wrapper.destroy() + }) + + it('should prevent toggle click', async () => { + const wrapper = mount(BNavItemDropdown, { + propsData: { + text: 'toggle' + } + }) + + expect(wrapper.vm).toBeDefined() await waitNT(wrapper.vm) const $toggle = wrapper.find('.dropdown-toggle') - expect($toggle.element.tagName).toBe('A') - expect($toggle.attributes('href')).toEqual('/foobar') - expect($toggle.classes()).toContain('nav-link') - expect($toggle.classes()).toContain('dropdown-toggle') await $toggle.trigger('click') expect(wrapper.emitted('toggle')).toBeDefined() From 8c2a68b5cc2c1eb1b2c3e88a524e782c8a18b13b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Tue, 12 May 2020 00:20:13 +0200 Subject: [PATCH 09/18] Update nav-item-dropdown.spec.js --- src/components/nav/nav-item-dropdown.spec.js | 32 ++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/components/nav/nav-item-dropdown.spec.js b/src/components/nav/nav-item-dropdown.spec.js index 24b1d18e649..cbcf59535b9 100644 --- a/src/components/nav/nav-item-dropdown.spec.js +++ b/src/components/nav/nav-item-dropdown.spec.js @@ -4,11 +4,7 @@ import { BNavItemDropdown } from './nav-item-dropdown' describe('nav-item-dropdown', () => { it('has expected default structure', async () => { - const wrapper = mount(BNavItemDropdown, { - propsData: { - text: 'toggle' - } - }) + const wrapper = mount(BNavItemDropdown) expect(wrapper.vm).toBeDefined() await waitNT(wrapper.vm) @@ -39,11 +35,7 @@ describe('nav-item-dropdown', () => { }) it('should have a flag that we are in a nav', async () => { - const wrapper = mount(BNavItemDropdown, { - propsData: { - text: 'toggle' - } - }) + const wrapper = mount(BNavItemDropdown) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.isNav).toBe(true) @@ -54,7 +46,6 @@ describe('nav-item-dropdown', () => { it('should have custom toggle class when "toggle-class" prop set', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { - text: 'toggle', toggleClass: 'nav-link-custom' } }) @@ -71,7 +62,6 @@ describe('nav-item-dropdown', () => { it('should be disabled when "disabled" prop set', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { - text: 'toggle', disabled: true } }) @@ -86,6 +76,24 @@ describe('nav-item-dropdown', () => { wrapper.destroy() }) + it('should have href with ID when "id" prop set', async () => { + const wrapper = mount(BNavItemDropdown, { + propsData: { + id: 'foo' + } + }) + + expect(wrapper.vm).toBeDefined() + await waitNT(wrapper.vm) + + expect(wrapper.element.hasAttribute('id')).toBe(true) + + const $toggle = wrapper.find('.dropdown-toggle') + expect($toggle.attributes('href')).toEqual(`#${wrapper.attributes('id')}`) + + wrapper.destroy() + }) + it('should open/close on toggle click', async () => { const wrapper = mount(BNavItemDropdown, { propsData: { From 5c878197e59c470318295fd0445b3be00ada7d00 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 11 May 2020 19:30:00 -0300 Subject: [PATCH 10/18] Update README.md --- src/components/nav/README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/nav/README.md b/src/components/nav/README.md index 379dcc6deb2..16bee6178aa 100644 --- a/src/components/nav/README.md +++ b/src/components/nav/README.md @@ -190,12 +190,13 @@ Use `` to place dropdown items within your nav. Sometimes you want to add your own class names to the generated dropdown toggle button, that by default have the classes `nav-link` and `dropdown-toggle`. Use the `toggle-class` prop to add them -(like above) which will produce something like: +(like above) which will render HTML similar to: ```html