Skip to content

Commit 8ce8d3f

Browse files
committed
SVG to JSX fixes
1 parent 1083572 commit 8ce8d3f

File tree

6 files changed

+48
-21
lines changed

6 files changed

+48
-21
lines changed

crates/core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ bitflags = { version = "2.7.0", features = ["serde"] }
99
browserslist-rs = "0.18.1"
1010
json-sourcemap = "0.2.0"
1111
node-semver = "2.2.0"
12-
serde = { version = "1.0.123", features = ["derive"] }
12+
serde = { version = "1.0.123", features = ["derive", "rc"] }
1313
serde_bytes = "0.11.5"
1414
serde-value = "0.7.0"

crates/html/src/jsx.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ fn to_jsx<'arena>(dom: &'arena Node<'arena>) -> JSXElementChild {
2323
attrs: attrs
2424
.borrow()
2525
.iter()
26-
.filter(|attr| matches!(attr.name.ns, ns!()))
2726
.map(|attr| {
2827
JSXAttrOrSpread::JSXAttr(JSXAttr {
2928
name: JSXAttrName::Ident(IdentName::new(
@@ -470,18 +469,18 @@ fn jsx_attr_name<'a>(name: &'a ExpandedName) -> &'a str {
470469
expanded_name!("", "x") => "x",
471470
expanded_name!("", "xchannelselector") => "xChannelSelector",
472471
expanded_name!("", "x-height") => "xHeight",
473-
expanded_name!("", "xlink:actuate") => "xlinkActuate",
474-
expanded_name!("", "xlink:arcrole") => "xlinkArcrole",
475-
expanded_name!("", "xlink:href") => "xlinkHref",
476-
expanded_name!("", "xlink:role") => "xlinkRole",
477-
expanded_name!("", "xlink:show") => "xlinkShow",
478-
expanded_name!("", "xlink:title") => "xlinkTitle",
479-
expanded_name!("", "xlink:type") => "xlinkType",
480-
expanded_name!("", "xml:base") => "xmlBase",
481-
expanded_name!("", "xml:lang") => "xmlLang",
482-
expanded_name!("", "xmlns") => "xmlns",
483-
expanded_name!("", "xml:space") => "xmlSpace",
484-
expanded_name!("", "xmlns:xlink") => "xmlnsXlink",
472+
expanded_name!(xlink "actuate") => "xlinkActuate",
473+
expanded_name!(xlink "arcrole") => "xlinkArcrole",
474+
expanded_name!(xlink "href") => "xlinkHref",
475+
expanded_name!(xlink "role") => "xlinkRole",
476+
expanded_name!(xlink "show") => "xlinkShow",
477+
expanded_name!(xlink "title") => "xlinkTitle",
478+
expanded_name!(xlink "type") => "xlinkType",
479+
expanded_name!(xml "base") => "xmlBase",
480+
expanded_name!(xml "lang") => "xmlLang",
481+
expanded_name!(xmlns "xmlns") => "xmlns",
482+
expanded_name!(xml "space") => "xmlSpace",
483+
expanded_name!(xmlns "xlink") => "xmlnsXlink",
485484
expanded_name!("", "y1") => "y1",
486485
expanded_name!("", "y2") => "y2",
487486
expanded_name!("", "y") => "y",
@@ -708,6 +707,10 @@ impl<'de> Deserialize<'de> for ExpandProps {
708707
}
709708

710709
pub fn to_component<'arena>(dom: &'arena Node<'arena>, options: JsxOptions) -> Program {
710+
if let Some(svg) = dom.find(expanded_name!(svg "svg")) {
711+
svg.remove_attribute(expanded_name!(xmlns "xmlns"));
712+
}
713+
711714
if options.dimensions {
712715
match &options.icon {
713716
Icon::None => {}
@@ -1200,6 +1203,25 @@ mod tests {
12001203
..Default::default()
12011204
},
12021205
);
1206+
1207+
test(
1208+
r#"
1209+
<?xml version="1.0" encoding="UTF-8"?>
1210+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
1211+
<text xml:space="preserve"> foo </text>
1212+
</svg>
1213+
"#,
1214+
indoc! {r#"
1215+
export default function SvgComponent(props) {
1216+
return <svg viewBox="0 0 100 100" {...props}>
1217+
<text xmlSpace="preserve"> foo </text>
1218+
</svg>;
1219+
}
1220+
"#},
1221+
JsxOptions {
1222+
..Default::default()
1223+
},
1224+
);
12031225
}
12041226

12051227
#[test]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"dependencies": {
33
"preact": "*"
4+
},
5+
"alias": {
6+
"preact/jsx-dev-runtime": "preact/jsx-runtime"
47
}
58
}

packages/core/integration-tests/test/svg-react.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe('svg-react', function () {
1919
let file = await outputFS.readFile(b.getBundles()[0].filePath, 'utf-8');
2020
assert(!file.includes('inkscape'));
2121
assert(file.includes('function SvgComponent'));
22-
assert(file.includes('createElement("svg"'));
22+
assert(file.includes('jsxDEV)("svg"'));
2323
assert(file.includes('id: "fbacef__circle"'));
2424
});
2525

@@ -37,7 +37,7 @@ describe('svg-react', function () {
3737
let types = await outputFS.readFile(b.getBundles()[1].filePath, 'utf-8');
3838

3939
assert(!file.includes('inkscape'));
40-
assert(file.includes('createElement("svg"'));
40+
assert(file.includes('jsxDEV)("svg"'));
4141
assert(types.includes('const Icon: SVGRComponent'));
4242
});
4343

@@ -57,7 +57,8 @@ describe('svg-react', function () {
5757
assert(file.includes('function SvgComponent'));
5858
assert(file.includes('_react.forwardRef'));
5959
assert(file.includes('_react.memo'));
60-
assert(file.includes('h("svg"'));
60+
assert(file.includes('preact/jsx-dev-runtime'));
61+
assert(file.includes('jsxDEV)("svg"'));
6162
assert(file.includes('width: "1em"'));
6263
assert(file.includes('role: "img"'));
6364
assert(file.includes('fill: props.fill'));

packages/transformers/js/src/JSTransformer.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,7 @@ export default (new Transformer({
258258
});
259259
}
260260

261-
if (automaticJSXRuntime) {
262-
jsxImportSource = reactLib;
263-
}
261+
jsxImportSource = reactLib;
264262
}
265263

266264
isJSX = Boolean(compilerOptions?.jsx || pragma);
@@ -450,7 +448,9 @@ export default (new Transformer({
450448
type,
451449
jsx_pragma: config?.pragma,
452450
jsx_pragma_frag: config?.pragmaFrag,
453-
automatic_jsx_runtime: Boolean(config?.automaticJSXRuntime),
451+
automatic_jsx_runtime: Boolean(
452+
config?.automaticJSXRuntime || asset.meta.jsxRuntime === 'automatic',
453+
),
454454
jsx_import_source: config?.jsxImportSource,
455455
is_development: options.mode === 'development',
456456
react_refresh: Boolean(config?.reactRefresh),

packages/transformers/svg-jsx/src/SvgJsxTransformer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ Unsupported SVGR option "template".
9595

9696
asset.type = 'jsx';
9797
asset.bundleBehavior = null;
98+
asset.meta.jsxRuntime = 'automatic';
9899
asset.setBuffer(jsx);
99100

100101
return [asset];

0 commit comments

Comments
 (0)