Skip to content

Commit 4d975b0

Browse files
authored
Merge pull request #2998 from mjmlio/bugfix/MJML-43-mj-accordion_font-family_padding-x
fix(mjml-accordion): font-family / padding-x #2997
2 parents 4d41b9d + de41570 commit 4d975b0

File tree

8 files changed

+183
-8
lines changed

8 files changed

+183
-8
lines changed

packages/mjml-accordion/src/Accordion.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ export default class MjAccordion extends BodyComponent {
7070
}
7171
}
7272

73+
getChildContext() {
74+
return {
75+
...this.context,
76+
accordionFontFamily: this.getAttribute('font-family'),
77+
}
78+
}
79+
7380
render() {
7481
const childrenAttr = [
7582
'border',

packages/mjml-accordion/src/AccordionElement.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ export default class MjAccordionElement extends BodyComponent {
9191
return result.join('\n')
9292
}
9393

94+
getChildContext() {
95+
return {
96+
...this.context,
97+
elementFontFamily: this.getAttribute('font-family'),
98+
}
99+
}
100+
94101
render() {
95102
return `
96103
<tr

packages/mjml-accordion/src/AccordionText.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ export default class MjAccordionText extends BodyComponent {
3131
td: {
3232
background: this.getAttribute('background-color'),
3333
'font-size': this.getAttribute('font-size'),
34-
'font-family': this.getAttribute('font-family'),
34+
'font-family': this.resolveFontFamily(),
3535
'font-weight': this.getAttribute('font-weight'),
3636
'letter-spacing': this.getAttribute('letter-spacing'),
3737
'line-height': this.getAttribute('line-height'),
3838
color: this.getAttribute('color'),
39+
padding: this.getAttribute('padding'),
3940
'padding-bottom': this.getAttribute('padding-bottom'),
4041
'padding-left': this.getAttribute('padding-left'),
4142
'padding-right': this.getAttribute('padding-right'),
4243
'padding-top': this.getAttribute('padding-top'),
43-
padding: this.getAttribute('padding'),
4444
},
4545
table: {
4646
width: '100%',
@@ -62,6 +62,23 @@ export default class MjAccordionText extends BodyComponent {
6262
`
6363
}
6464

65+
resolveFontFamily() {
66+
if (
67+
this.props &&
68+
this.props.rawAttrs &&
69+
Object.prototype.hasOwnProperty.call(this.props.rawAttrs, 'font-family')
70+
) {
71+
return this.getAttribute('font-family')
72+
}
73+
if (this.context && this.context.elementFontFamily) {
74+
return this.context.elementFontFamily
75+
}
76+
if (this.context && this.context.accordionFontFamily) {
77+
return this.context.accordionFontFamily
78+
}
79+
return MjAccordionText.defaultAttributes.fontFamily
80+
}
81+
6582
render() {
6683
return `
6784
<div

packages/mjml-accordion/src/AccordionTitle.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ export default class MjAccordionTitle extends BodyComponent {
3131
'background-color': this.getAttribute('background-color'),
3232
color: this.getAttribute('color'),
3333
'font-size': this.getAttribute('font-size'),
34-
'font-family': this.getAttribute('font-family'),
34+
'font-family': this.resolveFontFamily(),
3535
'font-weight': this.getAttribute('font-weight'),
36+
padding: this.getAttribute('padding'),
3637
'padding-bottom': this.getAttribute('padding-bottom'),
3738
'padding-left': this.getAttribute('padding-left'),
3839
'padding-right': this.getAttribute('padding-right'),
3940
'padding-top': this.getAttribute('padding-top'),
40-
padding: this.getAttribute('padding'),
4141
},
4242
table: {
4343
width: '100%',
@@ -56,6 +56,23 @@ export default class MjAccordionTitle extends BodyComponent {
5656
}
5757
}
5858

59+
resolveFontFamily() {
60+
if (
61+
this.props &&
62+
this.props.rawAttrs &&
63+
Object.prototype.hasOwnProperty.call(this.props.rawAttrs, 'font-family')
64+
) {
65+
return this.getAttribute('font-family')
66+
}
67+
if (this.context && this.context.elementFontFamily) {
68+
return this.context.elementFontFamily
69+
}
70+
if (this.context && this.context.accordionFontFamily) {
71+
return this.context.accordionFontFamily
72+
}
73+
return MjAccordionTitle.defaultAttributes.fontFamily
74+
}
75+
5976
renderTitle() {
6077
return `
6178
<td

packages/mjml-core/src/createComponent.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,15 @@ class Component {
5656
props = {},
5757
globalAttributes = {},
5858
absoluteFilePath = null,
59+
rawAttrs = {},
5960
} = initialDatas
6061

6162
this.props = {
6263
absoluteFilePath,
6364
...props,
6465
children,
6566
content,
67+
rawAttrs,
6668
}
6769

6870
this.attributes = formatAttributes(
@@ -207,10 +209,12 @@ export class BodyComponent extends Component {
207209
children = children || this.props.children
208210

209211
if (rawXML) {
210-
return children.map((child) => {
211-
child.attributes = {...attributes, ...child.attributes}
212-
return jsonToXML(child)
213-
}).join('\n')
212+
return children
213+
.map((child) => {
214+
child.attributes = { ...attributes, ...child.attributes }
215+
return jsonToXML(child)
216+
})
217+
.join('\n')
214218
}
215219

216220
const sibling = children.length

packages/mjml-core/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ export default function mjml2html(mjml, options = {}) {
271271
...defaultAttributesForClasses,
272272
...omit(attributes, ['mj-class']),
273273
},
274+
rawAttrs: { ...omit(attributes, ['mj-class']) },
274275
globalAttributes: {
275276
...globalData.defaultAttributes['mj-all'],
276277
},
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const chai = require('chai')
2+
const { load } = require('cheerio')
3+
const mjml = require('../lib')
4+
5+
describe('mj-accordion font-family inheritance', function () {
6+
it('should render correct font-family in CSS style values on accordion-title and accordion-text', function () {
7+
const input = `
8+
<mjml>
9+
<mj-body>
10+
<mj-section>
11+
<mj-column>
12+
<mj-accordion css-class="my-accordion-1" font-family="serif">
13+
<mj-accordion-element>
14+
<mj-accordion-title>Why use an accordion?</mj-accordion-title>
15+
<mj-accordion-text>
16+
Because emails with a lot of content are most of the time a very bad experience on mobile, mj-accordion comes handy when you want to deliver a lot of information in a concise way.
17+
</mj-accordion-text>
18+
</mj-accordion-element>
19+
</mj-accordion>
20+
</mj-column>
21+
</mj-section>
22+
<mj-section>
23+
<mj-column>
24+
<mj-accordion css-class="my-accordion-2" font-family="serif">
25+
<mj-accordion-element font-family="sans-serif">
26+
<mj-accordion-title font-family="monospace">Why use an accordion?</mj-accordion-title>
27+
<mj-accordion-text font-family="monospace">
28+
Because emails with a lot of content are most of the time a very bad experience on mobile, mj-accordion comes handy when you want to deliver a lot of information in a concise way.
29+
</mj-accordion-text>
30+
</mj-accordion-element>
31+
</mj-accordion>
32+
</mj-column>
33+
</mj-section>
34+
</mj-body>
35+
</mjml>
36+
`
37+
38+
const { html } = mjml(input)
39+
40+
const $ = load(html)
41+
42+
// style values should be correct
43+
chai
44+
.expect(
45+
$(
46+
'.my-accordion-1 .mj-accordion-title td:first-child, .my-accordion-1 .mj-accordion-content td:first-child',
47+
'.my-accordion-2 .mj-accordion-title td:first-child, .my-accordion-2 .mj-accordion-content td:first-child, ',
48+
)
49+
.map(function getAttr() {
50+
const start = $(this).attr('style').indexOf('font-family:') + 12
51+
const end = $(this).attr('style').indexOf(';', start)
52+
const result = $(this).attr('style').substring(start, end)
53+
return result
54+
})
55+
.get(),
56+
'Font-family in CSS style values on accordion-title',
57+
)
58+
.to.eql(['serif', 'serif', 'monospace', 'monospace'])
59+
})
60+
})
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const chai = require('chai')
2+
const { load } = require('cheerio')
3+
const mjml = require('../lib')
4+
5+
describe('mj-accordion padding-X', function () {
6+
it('should render correct padding in CSS style values on accordion-title and accordion-text', function () {
7+
const input = `
8+
<mjml>
9+
<mj-body>
10+
<mj-section>
11+
<mj-column>
12+
<mj-accordion>
13+
<mj-accordion-element>
14+
<mj-accordion-title padding="20px" padding-bottom="40px" padding-left="40px" padding-right="40px" padding-top="40px">Why use an accordion?</mj-accordion-title>
15+
<mj-accordion-text padding="20px" padding-bottom="40px" padding-left="40px" padding-right="40px" padding-top="40px">
16+
Because emails with a lot of content are most of the time a very bad experience on mobile, mj-accordion comes handy when you want to deliver a lot of information in a concise way.
17+
</mj-accordion-text>
18+
</mj-accordion-element>
19+
</mj-accordion>
20+
</mj-column>
21+
</mj-section>
22+
</mj-body>
23+
</mjml>
24+
`
25+
26+
const { html } = mjml(input)
27+
const $ = load(html)
28+
29+
function extractPadding(style, prop) {
30+
const start = style.indexOf(`${prop}:`) + prop.length + 1
31+
const end = style.indexOf(';', start)
32+
return style.substring(start, end).trim()
33+
}
34+
35+
const paddings = [
36+
'padding-left',
37+
'padding-right',
38+
'padding-top',
39+
'padding-bottom',
40+
]
41+
const results = paddings.map((padding) =>
42+
$(
43+
'.mj-accordion-title td:first-child, .mj-accordion-content td:first-child',
44+
)
45+
.map(function () {
46+
const style = $(this).attr('style')
47+
return extractPadding(style, padding)
48+
})
49+
.get(),
50+
)
51+
52+
// Each padding should be ['40px', '40px']
53+
paddings.forEach((padding, idx) => {
54+
chai
55+
.expect(
56+
results[idx],
57+
`${padding} in CSS style values on accordion-title and accordion-text`,
58+
)
59+
.to.eql(['40px', '40px'])
60+
})
61+
})
62+
})

0 commit comments

Comments
 (0)