Skip to content

Commit

Permalink
feat: Pass the children attribute as-is to the react component
Browse files Browse the repository at this point in the history
Related to #43
  • Loading branch information
bfanger committed Oct 31, 2024
1 parent b78918f commit 717975d
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 32 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"type": "git",
"url": "https://github.com/bfanger/svelte-preprocess-react.git"
},
"version": "2.0.1",
"version": "2.0.2",
"license": "MIT",
"type": "module",
"scripts": {
Expand Down
74 changes: 43 additions & 31 deletions src/lib/preprocessReact.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,37 +253,49 @@ function replaceReactTags(node, content, filename, components = {}) {
}
}
});
if (node.children && node.children.length > 0) {
const isTextContent =
node.children.filter(
(/** @type {any} */ child) =>
["Text", "MustacheTag"].includes(child.type) === false,
).length === 0;
/** @type {string[]} */
const escaped = [];
if (isTextContent) {
// Convert text & expressions into a children prop.
escaped.push('"');
node.children.forEach((/** @type {any} */ child) => {
if (child.type === "Text") {
escaped.push(
child.data.replace(/"/g, `{'"'}`).replace(/\n/g, `{'\\n'}`),
);
} else if (child.type === "MustacheTag") {
const expression = content.original.slice(child.start, child.end);
escaped.push(expression);
} else {
throw new Error(`Unexpected node type:${child.type}`);
}
});
escaped.push('"');
// slot was converted to children prop
content.appendRight(
node.children[0].start - 1,
` react$children=${escaped.join("")} /`,
);
content.remove(node.children[0].start, node.end);
return components;
if (node.children) {
if (node.children.length === 0) {
const childrenProp =
Array.isArray(node.attributes) &&
node.attributes.find(
(/** @type {any} */ attr) => attr.name === "children",
);
if (childrenProp) {
// If children are passed as attribute, pass the value as-is to the react component.
content.appendLeft(childrenProp.start, "react$"); // renames "children" to "react$children"
}
} else {
const isTextContent =
node.children.filter(
(/** @type {any} */ child) =>
["Text", "MustacheTag"].includes(child.type) === false,
).length === 0;
/** @type {string[]} */
const escaped = [];
if (isTextContent) {
// Convert text & expressions into a children prop.
escaped.push('"');
node.children.forEach((/** @type {any} */ child) => {
if (child.type === "Text") {
escaped.push(
child.data.replace(/"/g, `{'"'}`).replace(/\n/g, `{'\\n'}`),
);
} else if (child.type === "MustacheTag") {
const expression = content.original.slice(child.start, child.end);
escaped.push(expression);
} else {
throw new Error(`Unexpected node type:${child.type}`);
}
});
escaped.push('"');
// slot was converted to children prop
content.appendRight(
node.children[0].start - 1,
` react$children=${escaped.join("")} /`,
);
content.remove(node.children[0].start, node.end);
return components;
}
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/routes/render-prop/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { createElement } from "react";
import Search from "./Search";
let query = $state("123");
const react = sveltify({ Search });
</script>

<input type="search" bind:value={query} />

<react.Search
{query}
children={(results) =>
results.map((result, i) => createElement("div", { key: i }, result))}
/>
12 changes: 12 additions & 0 deletions src/routes/render-prop/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
type Props = {
query: string;
children: (results: string[]) => React.ReactNode;
};
export default function Search({ query, children }: Props) {
// The number of results is determined by the length of the query string.
const results: string[] = new Array(query.length)
.fill(null)
.map((_, i) => `result ${i + 1} with ${query}`);

return children(results);
}

0 comments on commit 717975d

Please sign in to comment.