Skip to content

Commit 3756b2c

Browse files
Hiwsjacobmllr95
andauthored
feat(b-icon): add proper title support (closes #5711) (#5724)
* update icon-base.js * update package.json * Add tests * Improved default title handling * Update icon-base.js Co-authored-by: Jacob Müller <jacob.mueller.elz@gmail.com>
1 parent 6a892f0 commit 3756b2c

File tree

8 files changed

+5722
-9
lines changed

8 files changed

+5722
-9
lines changed

src/icons/helpers/icon-base.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import { toFloat } from '../../utils/number'
77

88
// Common icon props (should be cloned/spread before using)
99
export const commonIconProps = {
10+
title: {
11+
type: String
12+
// default: null
13+
},
1014
variant: {
1115
type: String,
1216
default: null
@@ -132,6 +136,8 @@ export const BVIconBase = /*#__PURE__*/ Vue.extend({
132136
$inner = h('g', {}, [$inner])
133137
}
134138

139+
const $title = props.title ? h('title', props.title) : null
140+
135141
return h(
136142
'svg',
137143
mergeData(
@@ -156,7 +162,7 @@ export const BVIconBase = /*#__PURE__*/ Vue.extend({
156162
}
157163
}
158164
),
159-
[$inner]
165+
[$title, $inner]
160166
)
161167
}
162168
})

src/icons/helpers/make-icon.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const makeIcon = (name, content) => {
1616
const kebabName = kebabCase(name)
1717
const iconName = `BIcon${pascalCase(name)}`
1818
const iconNameClass = `bi-${kebabName}`
19+
const iconTitle = kebabName.replace(/-/g, ' ')
1920
const svgContent = trim(content || '')
2021
// Return the icon component definition
2122
return /*#__PURE__*/ Vue.extend({
@@ -31,11 +32,20 @@ export const makeIcon = (name, content) => {
3132
render(h, { data, props }) {
3233
return h(
3334
BVIconBase,
34-
mergeData(data, {
35-
staticClass: iconNameClass,
36-
props: { ...props, content: svgContent },
37-
attrs: { 'aria-label': kebabName.replace(/-/g, ' ') }
38-
})
35+
mergeData(
36+
// Defaults
37+
{
38+
props: { title: iconTitle },
39+
attrs: { 'aria-label': iconTitle }
40+
},
41+
// User data
42+
data,
43+
// Required data
44+
{
45+
staticClass: iconNameClass,
46+
props: { ...props, content: svgContent }
47+
}
48+
)
3949
)
4050
}
4151
})

src/icons/icons.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// --- BEGIN AUTO-GENERATED FILE ---
22
//
33
// @IconsVersion: 1.0.0
4-
// @Generated: 2020-09-01T12:06:08.751Z
4+
// @Generated: 2020-09-03T14:07:12.302Z
55
//
66
// This file is generated on each build. Do not edit this file!
77

src/icons/icons.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// --- BEGIN AUTO-GENERATED FILE ---
22
//
33
// @IconsVersion: 1.0.0
4-
// @Generated: 2020-09-01T12:06:08.751Z
4+
// @Generated: 2020-09-03T14:07:12.302Z
55
//
66
// This file is generated on each build. Do not edit this file!
77

src/icons/icons.spec.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,4 +502,46 @@ describe('icons', () => {
502502

503503
wrapper.destroy()
504504
})
505+
506+
it('b-icon title prop works', async () => {
507+
const wrapper = mount(BIcon, {
508+
localVue,
509+
propsData: {
510+
icon: 'circle-fill',
511+
title: 'Circle'
512+
}
513+
})
514+
515+
expect(wrapper.exists()).toBe(true)
516+
expect(wrapper.element.tagName).toBe('svg')
517+
expect(wrapper.classes()).toContain('b-icon')
518+
expect(wrapper.classes()).toContain('bi')
519+
expect(wrapper.classes()).toContain('bi-circle-fill')
520+
521+
const $title = wrapper.find('title')
522+
expect($title.exists()).toBe(true)
523+
expect($title.text()).toBe('Circle')
524+
525+
wrapper.destroy()
526+
})
527+
528+
it('b-icon <title> should not render when title is undefined', async () => {
529+
const wrapper = mount(BIcon, {
530+
localVue,
531+
propsData: {
532+
icon: 'circle-fill'
533+
}
534+
})
535+
536+
expect(wrapper.exists()).toBe(true)
537+
expect(wrapper.element.tagName).toBe('svg')
538+
expect(wrapper.classes()).toContain('b-icon')
539+
expect(wrapper.classes()).toContain('bi')
540+
expect(wrapper.classes()).toContain('bi-circle-fill')
541+
542+
const $title = wrapper.find('title')
543+
expect($title.exists()).toBe(false)
544+
545+
wrapper.destroy()
546+
})
505547
})

src/icons/iconstack.spec.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,44 @@ describe('icons > b-iconstack', () => {
118118

119119
wrapper.destroy()
120120
})
121+
122+
it('b-iconstack title prop works', async () => {
123+
const wrapper = mount(BIconstack, {
124+
propsData: {
125+
icon: 'circle-fill',
126+
title: 'Circle'
127+
}
128+
})
129+
130+
expect(wrapper.exists()).toBe(true)
131+
expect(wrapper.element.tagName).toBe('svg')
132+
expect(wrapper.classes()).toContain('b-icon')
133+
expect(wrapper.classes()).toContain('b-iconstack')
134+
expect(wrapper.classes()).toContain('bi')
135+
136+
const $title = wrapper.find('title')
137+
expect($title.exists()).toBe(true)
138+
expect($title.text()).toBe('Circle')
139+
140+
wrapper.destroy()
141+
})
142+
143+
it('b-iconstack <title> should not render when title is undefined', async () => {
144+
const wrapper = mount(BIconstack, {
145+
propsData: {
146+
icon: 'circle-fill'
147+
}
148+
})
149+
150+
expect(wrapper.exists()).toBe(true)
151+
expect(wrapper.element.tagName).toBe('svg')
152+
expect(wrapper.classes()).toContain('b-icon')
153+
expect(wrapper.classes()).toContain('b-iconstack')
154+
expect(wrapper.classes()).toContain('bi')
155+
156+
const $title = wrapper.find('title')
157+
expect($title.exists()).toBe(false)
158+
159+
wrapper.destroy()
160+
})
121161
})

0 commit comments

Comments
 (0)