Skip to content

Commit 065e7a9

Browse files
Sudhir Mitharwalgregberge
authored andcommitted
fix(titleProp): handle the existing title case by using element instead of value (children) (#315)
Instead of return the children of title from conditional expression, we can return the title element itself e.g. If title is undefined then return the existing title else return: `<title>{title}</title>`
1 parent afe008d commit 065e7a9

3 files changed

Lines changed: 60 additions & 26 deletions

File tree

packages/babel-plugin-svg-dynamic-title/src/index.js

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,36 @@ const plugin = ({ types: t }) => ({
1111
return
1212
}
1313

14-
function getTitleElement(existingTitleChildren = []) {
15-
// create the expression for the title rendering
16-
let expression = t.identifier('title')
17-
// get the existing title string value
18-
const existingTitle = (existingTitleChildren || [])
19-
.map(c => c.value)
20-
.join()
21-
if (existingTitle) {
22-
// if title exists
23-
// render as follows
24-
// {title === undefined ? existingTitle : title}
25-
expression = t.conditionalExpression(
26-
t.binaryExpression('===', expression, t.identifier('undefined')),
27-
t.stringLiteral(existingTitle),
28-
expression,
29-
)
30-
}
31-
32-
// create a title element with the given expression
14+
function createTitle(children = []) {
3315
return t.jsxElement(
3416
t.jsxOpeningElement(t.jsxIdentifier('title'), []),
3517
t.jsxClosingElement(t.jsxIdentifier('title')),
36-
[t.jsxExpressionContainer(expression)],
18+
children,
3719
)
3820
}
21+
function getTitleElement(existingTitleChildren = []) {
22+
const titleExpression = t.identifier('title')
23+
let titleElement = createTitle([
24+
t.jsxExpressionContainer(titleExpression),
25+
])
26+
if (existingTitleChildren && existingTitleChildren.length) {
27+
// if title already exists
28+
// render as follows
29+
const fallbackTitleElement = createTitle(existingTitleChildren)
30+
// {title === undefined ? fallbackTitleElement : titleElement}
31+
const conditionalExpressionForTitle = t.conditionalExpression(
32+
t.binaryExpression(
33+
'===',
34+
titleExpression,
35+
t.identifier('undefined'),
36+
),
37+
fallbackTitleElement,
38+
titleElement,
39+
)
40+
titleElement = t.jsxExpressionContainer(conditionalExpressionForTitle)
41+
}
42+
return titleElement
43+
}
3944

4045
// store the title element
4146
let titleElement

packages/babel-plugin-svg-dynamic-title/src/index.test.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,23 @@ describe('plugin', () => {
1717
)
1818
})
1919

20-
it('should add title attribute and fallback to existing title', () => {
21-
expect(testPlugin('<svg><title>Hello</title></svg>')).toMatchInlineSnapshot(
22-
`"<svg><title>{title === undefined ? \\"Hello\\" : title}</title></svg>;"`,
20+
it('should add title element and fallback to existing title', () => {
21+
// testing when the existing title contains a simple string
22+
expect(testPlugin(`<svg><title>Hello</title></svg>`)).toMatchInlineSnapshot(
23+
`"<svg>{title === undefined ? <title>Hello</title> : <title>{title}</title>}</svg>;"`,
24+
)
25+
// testing when the existing title contains an JSXExpression
26+
expect(
27+
testPlugin(`<svg><title>{"Hello"}</title></svg>`),
28+
).toMatchInlineSnapshot(
29+
`"<svg>{title === undefined ? <title>{\\"Hello\\"}</title> : <title>{title}</title>}</svg>;"`,
30+
)
31+
})
32+
it('should support empty title', () => {
33+
expect(testPlugin('<svg><title></title></svg>')).toMatchInlineSnapshot(
34+
`"<svg><title>{title}</title></svg>;"`,
2335
)
2436
})
25-
2637
it('should support self closing title', () => {
2738
expect(testPlugin('<svg><title /></svg>')).toMatchInlineSnapshot(
2839
`"<svg><title>{title}</title></svg>;"`,

packages/babel-preset/src/index.test.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ describe('preset', () => {
6969
`)
7070
})
7171
it('should handle titleProp and fallback on existing title', () => {
72+
// testing when existing title has string as chilren
7273
expect(
73-
testPreset('<svg><title>Old</title></svg>', {
74+
testPreset(`<svg><title>Hello</title></svg>`, {
7475
titleProp: true,
7576
state: {
7677
componentName: 'SvgComponent',
@@ -81,7 +82,24 @@ describe('preset', () => {
8182
8283
const SvgComponent = ({
8384
title
84-
}) => <svg><title>{title === undefined ? \\"Old\\" : title}</title></svg>;
85+
}) => <svg>{title === undefined ? <title>Hello</title> : <title>{title}</title>}</svg>;
86+
87+
export default SvgComponent;"
88+
`)
89+
// testing when existing title has JSXExpression as children
90+
expect(
91+
testPreset(`<svg><title>{"Hello"}</title></svg>`, {
92+
titleProp: true,
93+
state: {
94+
componentName: 'SvgComponent',
95+
},
96+
}),
97+
).toMatchInlineSnapshot(`
98+
"import React from \\"react\\";
99+
100+
const SvgComponent = ({
101+
title
102+
}) => <svg>{title === undefined ? <title>{\\"Hello\\"}</title> : <title>{title}</title>}</svg>;
85103
86104
export default SvgComponent;"
87105
`)

0 commit comments

Comments
 (0)