Skip to content

Commit afcadd9

Browse files
jacobmllr95mosinve
authored andcommitted
feat(button): Make button tag configurable (bootstrap-vue#1929)
* feat(button): Make button tag configurable
1 parent 8a2ca5e commit afcadd9

File tree

6 files changed

+57
-4
lines changed

6 files changed

+57
-4
lines changed

src/components/button/button.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ const btnProps = {
2626
type: String,
2727
default: 'button'
2828
},
29+
tag: {
30+
type: String,
31+
default: 'button'
32+
},
2933
pressed: {
3034
// tri-state prop: true, false or null
3135
// => on, off, not a toggle
@@ -55,6 +59,7 @@ export default {
5559
render (h, { props, data, listeners, children }) {
5660
const isLink = Boolean(props.href || props.to)
5761
const isToggle = typeof props.pressed === 'boolean'
62+
const isButtonTag = props.tag === 'button'
5863
const on = {
5964
click (e) {
6065
if (props.disabled && e instanceof Event) {
@@ -90,8 +95,8 @@ export default {
9095
],
9196
props: isLink ? pluckProps(linkPropKeys, props) : null,
9297
attrs: {
93-
type: isLink ? null : props.type,
94-
disabled: isLink ? null : props.disabled,
98+
type: isButtonTag && !isLink ? props.type : null,
99+
disabled: isButtonTag && !isLink ? props.disabled : null,
95100
// Data attribute not used for js logic,
96101
// but only for BS4 style selectors.
97102
'data-toggle': isToggle ? 'button' : null,
@@ -107,6 +112,6 @@ export default {
107112
on
108113
}
109114

110-
return h(isLink ? Link : 'button', mergeData(data, componentData), children)
115+
return h(isLink ? Link : props.tag, mergeData(data, componentData), children)
111116
}
112117
}

src/components/button/button.spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,20 @@ describe('button', async () => {
5555
expect(btnRootNode.href).toBe('https://github.com/bootstrap-vue/bootstrap-vue')
5656
})
5757

58+
it('should use the given tag', async () => {
59+
const { app: { $refs } } = window
60+
const btnRootNode = $refs.btn_div
61+
62+
expect(btnRootNode).toBeElement('div')
63+
})
64+
65+
it('should use button when no tag is given', async () => {
66+
const { app: { $refs } } = window
67+
const btnRootNode = $refs.btn_no_tag
68+
69+
expect(btnRootNode).toBeElement('button')
70+
})
71+
5872
it('should emit "click" event when clicked', async () => {
5973
const { app: { $refs } } = window
6074
const btn = $refs.btn_click

src/components/button/fixtures/button.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@
2424
alt="github">
2525
</b-btn>
2626
</div>
27+
<div class="col-md-4 pb-2">
28+
<b-btn variant="secondary"
29+
tag="div"
30+
ref="btn_div">
31+
I am a div
32+
</b-btn>
33+
</div>
34+
<div class="col-md-4 pb-2">
35+
<b-btn variant="secondary"
36+
ref="btn_no_tag">
37+
I am a button
38+
</b-btn>
39+
</div>
2740
<div class="col-md-4 pb-2">
2841
<b-btn variant="success"
2942
ref="btn_click"

src/components/dropdown/dropdown.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export default {
3737
props: {
3838
variant: this.variant,
3939
size: this.size,
40-
disabled: this.disabled
40+
disabled: this.disabled,
41+
tag: this.toggleTag
4142
},
4243
attrs: {
4344
id: this.safeId('_BV_toggle_'),
@@ -98,6 +99,10 @@ export default {
9899
type: [String, Array],
99100
default: null
100101
},
102+
toggleTag: {
103+
type: String,
104+
default: 'button'
105+
},
101106
toggleClass: {
102107
type: [String, Array],
103108
default: null

src/components/dropdown/dropdown.spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ describe('dropdown', async () => {
7373
expect(dd_1).not.toHaveClass('position-static')
7474
})
7575
*/
76+
77+
it('should have a toggle with the given toggle tag', async () => {
78+
const { app: { $refs } } = window
79+
const { dd_10 } = $refs // eslint-disable-line camelcase
80+
81+
const toggle = dd_10.$el.querySelector('.dropdown-toggle')
82+
expect(toggle).toBeElement('div')
83+
})
84+
7685
it('dd-item should render as link by default', async () => {
7786
const {app: {$refs}} = window
7887
const {dd_6} = $refs // eslint-disable-line camelcase

src/components/dropdown/fixtures/dropdown.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,11 @@
9090
<b-dropdown-item href="#">Action</b-dropdown-item>
9191
<b-dropdown-item href="#">Another action</b-dropdown-item>
9292
</b-dropdown>
93+
94+
<br><br>
95+
96+
<b-dropdown ref="dd_10" text="Dropdown" toggle-tag="div">
97+
<b-dropdown-item href="#">Action</b-dropdown-item>
98+
<b-dropdown-item href="#">Another action</b-dropdown-item>
99+
</b-dropdown>
93100
</div>

0 commit comments

Comments
 (0)