Skip to content

Commit 6646c27

Browse files
authored
feat: Support text-decoration-style: double (#685)
Seems easy to support.
1 parent 82de867 commit 6646c27

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ Satori uses the same Flexbox [layout engine](https://yogalayout.com) as React Na
194194
<tr><td><code>textAlign</code></td><td><code>start</code>, <code>end</code>, <code>left</code>, <code>right</code>, <code>center</code>, <code>justify</code>, default to <code>start</code></td><td></td></tr>
195195
<tr><td><code>textTransform</code></td><td><code>none</code>, <code>lowercase</code>, <code>uppercase</code>, <code>capitalize</code>, defaults to <code>none</code></td><td></td></tr>
196196
<tr><td><code>textOverflow</code></td><td><code>clip</code>, <code>ellipsis</code>, defaults to <code>clip</code></td><td></td></tr>
197-
<tr><td><code>textDecoration</code></td><td>Support line types <code>underline</code> and <code>line-through</code>, and styles <code>dotted</code>, <code>dashed</code>, <code>solid</code></td><td><a href="https://og-playground.vercel.app/?share=nVLLTsMwEPwVaxHqJYgUOCCr9EL5Ajj24mQ3icH1Ro5DW6L8O3ZeQpwKJ-_M7ox25O0gZySQsEH9ubdCNP5s6KnrYi1ERbqsvBSrdZper5KRPGr01S8OdVMbdQ5sYeg0s7HeaUe512xDL2fTHuzcrRWitqUU63RiMpV_lI5bi89s2AXFVVEUixtb_6q_SIr7u4kqVR3lEfT93m5jEZMsMYSnk99Rzk5NO1i2tArT21hsbsPwJaqwEjmjJ-mCLtbH4RtfhWxlNVj8JP6-hUD2nlA4wsFthP_aRqBqqmCVmXYMN-LZa34hAa6jvAHZwXACIB_TNIHxRkA-RICUtSXIQpmGEqADv-u3cx0PzB8HFHziP74cMkKQ3rXUJ-BVFiYqMoaP7AxC_w0">Example</a></td></tr>
197+
<tr><td><code>textDecoration</code></td><td>Support line types <code>underline</code> and <code>line-through</code>, and styles <code>dotted</code>, <code>dashed</code>, <code>double</code>, <code>solid</code></td><td><a href="https://og-playground.vercel.app/?share=pVPLTsMwEPwVaytUkAKkPCRklV4oXwDHXhx7YxtcO3Ic2hLl37GTtEKIQynywTvjndGstG6BO4FAYS70x8oSUoedwce2TTUhCrVUgZLpLM_PptlAbrQI6gcndF0ZtotsaXC7Z1O91B550M7GN-5Ms7b714oJoa2kZJaPTMH4u_SuseLJGeejYlKW5cHN2fCiP5GS25uRkqxK8gS6bmUXqUiTHMYgAbdhidx5NmawzuI0di9SMb-OzceoYiT0Ro_SAzpan5ovg4qzSdVbfCf-noIIFwIK4lH0bgM8KQ0RrFbRqjDNMNyAT8rUFAbJhHP-_1CDl5cFO8-z_lzdX_ySb39DBq5KTjXQFvoVBfqQ5xkMOwz0LgGBRSOBlszUmAGu3Zt-3VXpA4RNj6JP2rPndYECaPANdhkEVsQOhca4jfNGQPcF">Example</a></td></tr>
198198
<tr><td><code>textShadow</code></td><td>Supported</td><td></td></tr>
199199
<tr><td><code>lineHeight</code></td><td>Supported</td><td></td></tr>
200200
<tr><td><code>letterSpacing</code></td><td>Supported</td><td></td></tr>

src/builder/text-decoration.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,23 @@ export default function buildDecoration(
4545
? `0 ${height * 2}`
4646
: undefined
4747

48+
// https://www.w3.org/TR/css-backgrounds-3/#valdef-line-style-double
49+
const extraLine =
50+
textDecorationStyle === 'double'
51+
? buildXMLString('line', {
52+
x1: left,
53+
y1: y + height + 1,
54+
x2: left + width,
55+
y2: y + height + 1,
56+
stroke: textDecorationColor || color,
57+
'stroke-width': height,
58+
'stroke-dasharray': dasharray,
59+
'stroke-linecap':
60+
textDecorationStyle === 'dotted' ? 'round' : 'square',
61+
transform: matrix,
62+
})
63+
: ''
64+
4865
return (
4966
(clipPathId ? `<g clip-path="url(#${clipPathId})">` : '') +
5067
buildXMLString('line', {
@@ -58,6 +75,7 @@ export default function buildDecoration(
5875
'stroke-linecap': textDecorationStyle === 'dotted' ? 'round' : 'square',
5976
transform: matrix,
6077
}) +
78+
extraLine +
6179
(clipPathId ? '</g>' : '')
6280
)
6381
}
Loading

test/text-decoration.test.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,45 @@ describe('Text Decoration', () => {
187187
)
188188
expect(toImage(svg, 100)).toMatchImageSnapshot()
189189
})
190+
191+
it('Should work correctly when `text-decoration-style: double`', async () => {
192+
const svg = await satori(
193+
<div
194+
style={{
195+
height: '100%',
196+
width: '100%',
197+
display: 'flex',
198+
flexDirection: 'column',
199+
alignItems: 'center',
200+
justifyContent: 'center',
201+
backgroundColor: '#fff',
202+
fontSize: 20,
203+
fontWeight: 600,
204+
}}
205+
>
206+
<div
207+
style={{
208+
backgroundColor: '#91a8d0',
209+
textDecoration: 'underline double',
210+
color: 'white',
211+
}}
212+
>
213+
It doesn’t exist, it never has. I’m nostalgic for a place that never
214+
existed.
215+
</div>
216+
<div
217+
style={{
218+
backgroundColor: '#000',
219+
textDecoration: 'line-through double',
220+
color: 'white',
221+
}}
222+
>
223+
It doesn’t exist, it never has. I’m nostalgic for a place that never
224+
existed.
225+
</div>
226+
</div>,
227+
{ width: 200, height: 200, fonts }
228+
)
229+
expect(toImage(svg, 200)).toMatchImageSnapshot()
230+
})
190231
})

0 commit comments

Comments
 (0)