Skip to content

Commit 4322ccb

Browse files
authored
fix(list-group-item): set button type to 'button' when button in mode or tag=button (Fixes #2192) (#2194)
* fix(list-group-item): set button type to 'button' when button in mode or tag=button (Fixes #2192) * Create list-group-item.spec.js
1 parent e167688 commit 4322ccb

File tree

2 files changed

+235
-7
lines changed

2 files changed

+235
-7
lines changed

src/components/list-group/list-group-item.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,35 @@ export default {
4040
: !props.href && !props.to ? props.tag : Link
4141
const isAction = Boolean(
4242
props.href ||
43-
props.to ||
44-
props.action ||
45-
props.button ||
46-
arrayIncludes(actionTags, props.tag)
43+
props.to ||
44+
props.action ||
45+
props.button ||
46+
arrayIncludes(actionTags, props.tag)
4747
)
48+
const attrs = {}
49+
let itemProps = {}
50+
if (tag === 'button') {
51+
if (!data.attrs || !data.attrs.type) {
52+
// Add a type for button is one not provided in passed attributes
53+
attrs.type = 'button'
54+
}
55+
if (props.disabled) {
56+
// Set disabled attribute if button and disabled
57+
attrs.disabled = true
58+
}
59+
} else {
60+
itemProps = pluckProps(linkProps, props)
61+
}
4862
const componentData = {
63+
attrs,
64+
props: itemProps,
4965
staticClass: 'list-group-item',
5066
class: {
5167
[`list-group-item-${props.variant}`]: Boolean(props.variant),
5268
'list-group-item-action': isAction,
5369
active: props.active,
5470
disabled: props.disabled
55-
},
56-
attrs: tag === 'button' && props.disabled ? { disabled: true } : {},
57-
props: props.button ? {} : pluckProps(linkProps, props)
71+
}
5872
}
5973

6074
return h(tag, mergeData(data, componentData), children)
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
import ListGroupItem from './list-group-item'
2+
import { mount } from '@vue/test-utils'
3+
4+
describe('list-group-item', async () => {
5+
it('default should have tag div', async () => {
6+
const wrapper = mount(ListGroupItem)
7+
expect(wrapper.is('div')).toBe(true)
8+
})
9+
10+
it('default should contain only single class of list-group-item', async () => {
11+
const wrapper = mount(ListGroupItem)
12+
expect(wrapper.classes().length).toBe(1)
13+
expect(wrapper.classes()).toContain('list-group-item')
14+
})
15+
16+
it('default should not have class list-group-item-action', async () => {
17+
const wrapper = mount(ListGroupItem)
18+
expect(wrapper.classes()).not.toContain('list-group-item-action')
19+
})
20+
21+
it('default should not have class active', async () => {
22+
const wrapper = mount(ListGroupItem)
23+
expect(wrapper.classes()).not.toContain('active')
24+
})
25+
26+
it('default should not have class disabled', async () => {
27+
const wrapper = mount(ListGroupItem)
28+
expect(wrapper.classes()).not.toContain('disabled')
29+
})
30+
31+
it('default should not have type attribute', async () => {
32+
const wrapper = mount(ListGroupItem)
33+
expect(wrapper.attributes('type')).not.toBeDefined()
34+
})
35+
36+
it('default should not have disabled attribute', async () => {
37+
const wrapper = mount(ListGroupItem)
38+
expect(wrapper.attributes('disabled')).not.toBeDefined()
39+
})
40+
41+
it('should have disabled class when disabled=true', async () => {
42+
const wrapper = mount(ListGroupItem, {
43+
context: {
44+
props: { disabled: true }
45+
}
46+
})
47+
expect(wrapper.classes()).toContain('disabled')
48+
})
49+
50+
it('should have active class when active=true', async () => {
51+
const wrapper = mount(ListGroupItem, {
52+
context: {
53+
props: { active: true }
54+
}
55+
})
56+
expect(wrapper.classes()).toContain('active')
57+
})
58+
59+
it('should have variant class and base class when variant set', async () => {
60+
const wrapper = mount(ListGroupItem, {
61+
context: {
62+
props: { variant: 'danger' }
63+
}
64+
})
65+
expect(wrapper.classes()).toContain('list-group-item')
66+
expect(wrapper.classes()).toContain('list-group-item-danger')
67+
})
68+
69+
it('should have tag a when href is set', async () => {
70+
const wrapper = mount(ListGroupItem, {
71+
context: {
72+
props: { href: '/foobar' }
73+
}
74+
})
75+
expect(wrapper.is('a')).toBe(true)
76+
})
77+
78+
it('should have class list-group-item-action when href is set', async () => {
79+
const wrapper = mount(ListGroupItem, {
80+
context: {
81+
props: { href: '/foobar' }
82+
}
83+
})
84+
expect(wrapper.classes()).toContain('list-group-item-action')
85+
})
86+
87+
it('should have class list-group-item-action when action=true', async () => {
88+
const wrapper = mount(ListGroupItem, {
89+
context: {
90+
props: { action: true }
91+
}
92+
})
93+
expect(wrapper.classes()).toContain('list-group-item-action')
94+
})
95+
96+
it('should have class list-group-item-action when tag=a', async () => {
97+
const wrapper = mount(ListGroupItem, {
98+
context: {
99+
props: { tag: 'a' }
100+
}
101+
})
102+
expect(wrapper.classes()).toContain('list-group-item-action')
103+
})
104+
105+
it('should have href attribute when href is set', async () => {
106+
const wrapper = mount(ListGroupItem, {
107+
context: {
108+
props: { href: '/foobar' }
109+
}
110+
})
111+
expect(wrapper.attributes('href')).toBe('/foobar')
112+
})
113+
114+
it('should have tag button when tag=button', async () => {
115+
const wrapper = mount(ListGroupItem, {
116+
context: {
117+
props: { tag: 'button' }
118+
}
119+
})
120+
expect(wrapper.is('button')).toBe(true)
121+
})
122+
123+
it('should have tag a when tag=a', async () => {
124+
const wrapper = mount(ListGroupItem, {
125+
context: {
126+
props: { tag: 'a' }
127+
}
128+
})
129+
expect(wrapper.is('a')).toBe(true)
130+
})
131+
132+
it('should have tag button when button=true', async () => {
133+
const wrapper = mount(ListGroupItem, {
134+
context: {
135+
props: { button: true }
136+
}
137+
})
138+
expect(wrapper.is('button')).toBe(true)
139+
})
140+
141+
it('should have tag button when button=true and tag=foo', async () => {
142+
const wrapper = mount(ListGroupItem, {
143+
context: {
144+
props: {
145+
button: true,
146+
tag: 'foo'
147+
}
148+
}
149+
})
150+
expect(wrapper.is('button')).toBe(true)
151+
})
152+
153+
it('should not have href when button=true and href set', async () => {
154+
const wrapper = mount(ListGroupItem, {
155+
context: {
156+
props: {
157+
button: true,
158+
href: '/foobar'
159+
}
160+
}
161+
})
162+
expect(wrapper.is('button')).toBe(true)
163+
expect(wrapper.attributes('href')).not.toBeDefined()
164+
})
165+
166+
it('should have class list-group-item-action when button=true', async () => {
167+
const wrapper = mount(ListGroupItem, {
168+
context: {
169+
props: { button: true }
170+
}
171+
})
172+
expect(wrapper.classes()).toContain('list-group-item-action')
173+
})
174+
175+
it('should have type=button when button=true', async () => {
176+
const wrapper = mount(ListGroupItem, {
177+
context: {
178+
props: { button: true }
179+
}
180+
})
181+
expect(wrapper.attributes('type')).toEqual('button')
182+
})
183+
184+
it('should have type=submit when button=true and attr type=submit', async () => {
185+
const wrapper = mount(ListGroupItem, {
186+
context: {
187+
props: { button: true },
188+
attrs: { type: 'submit' }
189+
}
190+
})
191+
expect(wrapper.attributes('type')).toEqual('submit')
192+
})
193+
194+
it('should not have attribute disabled when button=true and disabled not set', async () => {
195+
const wrapper = mount(ListGroupItem, {
196+
context: {
197+
props: { button: true }
198+
}
199+
})
200+
expect(wrapper.attributes('disabled')).not.toBeDefined()
201+
})
202+
203+
it('should have attribute disabled when button=true and disabled=true', async () => {
204+
const wrapper = mount(ListGroupItem, {
205+
context: {
206+
props: {
207+
button: true,
208+
disabled: true
209+
}
210+
}
211+
})
212+
expect(wrapper.attributes('disabled')).toBeDefined()
213+
})
214+
})

0 commit comments

Comments
 (0)