Skip to content

Commit 6cfcbb3

Browse files
phegmanpeterhegmanjacobmllr95
authored
feat(b-dropdown): add toggle-attrs prop (closes #3694) (#6339)
* feat(b-dropdown): add `toggle-attrs` prop Add `toggle-attrs` prop to allow adding HTML attributes to the dropdown toggle * Update dropdown.js * Update dropdown.spec.js Co-authored-by: peterhegman <phegman@gitlab.com> Co-authored-by: Jacob Müller <jacob.mueller.elz@gmail.com>
1 parent 2a449ab commit 6cfcbb3

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

src/components/dropdown/dropdown.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { NAME_DROPDOWN } from '../../constants/components'
33
import {
44
PROP_TYPE_ARRAY_OBJECT_STRING,
55
PROP_TYPE_BOOLEAN,
6+
PROP_TYPE_OBJECT,
67
PROP_TYPE_OBJECT_STRING,
78
PROP_TYPE_STRING
89
} from '../../constants/props'
@@ -40,6 +41,7 @@ export const props = makePropsConfigurable(
4041
splitTo: makeProp(PROP_TYPE_OBJECT_STRING),
4142
splitVariant: makeProp(PROP_TYPE_STRING),
4243
text: makeProp(PROP_TYPE_STRING),
44+
toggleAttrs: makeProp(PROP_TYPE_OBJECT, {}),
4345
toggleClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
4446
toggleTag: makeProp(PROP_TYPE_STRING, 'button'),
4547
// TODO: This really should be `toggleLabel`
@@ -145,6 +147,9 @@ export const BDropdown = /*#__PURE__*/ Vue.extend({
145147
staticClass: 'dropdown-toggle',
146148
class: this.toggleClasses,
147149
attrs: {
150+
// Merge in user supplied attributes
151+
...this.toggleAttrs,
152+
// Must have attributes
148153
id: this.safeId('_BV_toggle_'),
149154
'aria-haspopup': 'true',
150155
'aria-expanded': toString(visible)

src/components/dropdown/dropdown.spec.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,9 @@ describe('dropdown', () => {
300300
block: true
301301
}
302302
})
303+
303304
expect(wrapper.classes()).not.toContain('btn-group')
305+
304306
wrapper.destroy()
305307
})
306308

@@ -312,8 +314,10 @@ describe('dropdown', () => {
312314
split: true
313315
}
314316
})
317+
315318
expect(wrapper.classes()).toContain('btn-group')
316319
expect(wrapper.classes()).toContain('d-flex')
320+
317321
wrapper.destroy()
318322
})
319323

@@ -324,7 +328,9 @@ describe('dropdown', () => {
324328
noCaret: true
325329
}
326330
})
331+
327332
expect(wrapper.find('.dropdown-toggle').classes()).toContain('dropdown-toggle-no-caret')
333+
328334
wrapper.destroy()
329335
})
330336

@@ -336,7 +342,9 @@ describe('dropdown', () => {
336342
split: true
337343
}
338344
})
345+
339346
expect(wrapper.find('.dropdown-toggle').classes()).not.toContain('dropdown-toggle-no-caret')
347+
340348
wrapper.destroy()
341349
})
342350

@@ -347,7 +355,22 @@ describe('dropdown', () => {
347355
toggleTag: 'div'
348356
}
349357
})
358+
350359
expect(wrapper.find('.dropdown-toggle').element.tagName).toBe('DIV')
360+
361+
wrapper.destroy()
362+
})
363+
364+
it('should have attributes on toggle when "toggle-attrs" prop is set', async () => {
365+
const wrapper = mount(BDropdown, {
366+
attachTo: createContainer(),
367+
propsData: {
368+
toggleAttrs: { 'data-foo-bar': 'foo-bar' }
369+
}
370+
})
371+
372+
expect(wrapper.find('.dropdown-toggle').attributes('data-foo-bar')).toBe('foo-bar')
373+
351374
wrapper.destroy()
352375
})
353376

@@ -358,17 +381,21 @@ describe('dropdown', () => {
358381
dropup: true
359382
}
360383
})
384+
361385
expect(wrapper.classes()).toContain('dropdown')
362386
expect(wrapper.classes()).toContain('dropup')
363387
expect(wrapper.classes()).not.toContain('show')
364388
expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show')
389+
365390
wrapper.vm.show()
366391
await waitNT(wrapper.vm)
367392
await waitRAF()
393+
368394
expect(wrapper.classes()).toContain('dropdown')
369395
expect(wrapper.classes()).toContain('dropup')
370396
expect(wrapper.classes()).toContain('show')
371397
expect(wrapper.find('.dropdown-menu').classes()).toContain('show')
398+
372399
wrapper.destroy()
373400
})
374401

@@ -379,17 +406,21 @@ describe('dropdown', () => {
379406
dropright: true
380407
}
381408
})
409+
382410
expect(wrapper.classes()).toContain('dropdown')
383411
expect(wrapper.classes()).toContain('dropright')
384412
expect(wrapper.classes()).not.toContain('show')
385413
expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show')
414+
386415
wrapper.vm.show()
387416
await waitNT(wrapper.vm)
388417
await waitRAF()
418+
389419
expect(wrapper.classes()).toContain('dropdown')
390420
expect(wrapper.classes()).toContain('dropright')
391421
expect(wrapper.classes()).toContain('show')
392422
expect(wrapper.find('.dropdown-menu').classes()).toContain('show')
423+
393424
wrapper.destroy()
394425
})
395426

@@ -400,17 +431,21 @@ describe('dropdown', () => {
400431
dropleft: true
401432
}
402433
})
434+
403435
expect(wrapper.classes()).toContain('dropdown')
404436
expect(wrapper.classes()).toContain('dropleft')
405437
expect(wrapper.classes()).not.toContain('show')
406438
expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show')
439+
407440
wrapper.vm.show()
408441
await waitNT(wrapper.vm)
409442
await waitRAF()
443+
410444
expect(wrapper.classes()).toContain('dropdown')
411445
expect(wrapper.classes()).toContain('dropleft')
412446
expect(wrapper.classes()).toContain('show')
413447
expect(wrapper.find('.dropdown-menu').classes()).toContain('show')
448+
414449
wrapper.destroy()
415450
})
416451

@@ -423,10 +458,12 @@ describe('dropdown', () => {
423458
split: true
424459
}
425460
})
461+
426462
const $buttons = wrapper.findAll('button')
427463
const $split = $buttons.at(0)
428-
429464
expect($split.classes()).toContain(splitClass)
465+
466+
wrapper.destroy()
430467
})
431468

432469
it('menu should have class dropdown-menu-right when prop right set', async () => {
@@ -436,17 +473,21 @@ describe('dropdown', () => {
436473
right: true
437474
}
438475
})
476+
439477
expect(wrapper.classes()).toContain('dropdown')
440478
expect(wrapper.classes()).not.toContain('show')
441479
expect(wrapper.find('.dropdown-menu').classes()).toContain('dropdown-menu-right')
442480
expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show')
481+
443482
wrapper.vm.show()
444483
await waitNT(wrapper.vm)
445484
await waitRAF()
485+
446486
expect(wrapper.classes()).toContain('dropdown')
447487
expect(wrapper.classes()).toContain('show')
448488
expect(wrapper.find('.dropdown-menu').classes()).toContain('dropdown-menu-right')
449489
expect(wrapper.find('.dropdown-menu').classes()).toContain('show')
490+
450491
wrapper.destroy()
451492
})
452493

src/components/dropdown/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@
9898
"prop": "text",
9999
"description": "Text to place in the toggle button, or in the split button is split mode"
100100
},
101+
{
102+
"prop": "toggleAttrs",
103+
"version": "2.22.0",
104+
"description": "Additional attributes to apply to the toggle button"
105+
},
101106
{
102107
"prop": "toggleClass",
103108
"description": "CSS class (or classes) to add to the toggle button"

0 commit comments

Comments
 (0)