A lightweight and framework-independent library for template string interpolation similar to JSX elements.
pnpm add string-format-jsx
Use with any framework
import { formatElements } from 'string-format-jsx';
formatElements('Hello, <a>@u3u</a>', {
createElement: (type, props, children) => yourFramework.createElement(type, props, children),
});
Use the entrance of React.createElement
by default
Tip
The formatElements
is only used for replacing JSX elements and does not include string interpolation functionality. You can use it together with the built-in interpolation
function or any other interpolation library.
import { formatElements } from 'string-format-jsx/react';
const result = formatElements('Hello, <a>@u3u</a>', {
components: {
a: (children) => <Link>{children}</Link>,
},
});
Use interpolation
and formatElements
together.
import { Trans } from 'string-format-jsx/trans';
const result = (
<Trans
components={{
a: (children, key) => {
return (
<a
className="text-primary-500 hover:text-primary-400 transition"
key={key}
onClick={() => {
console.log(children);
}}
>
{children}
</a>
);
},
b: (children, key) => {
return (
<b className="font-medium" key={key}>
{children}
</b>
);
},
}}
text={dedent`
Hello, <a>The number is <b>{count}</b></a>
<br />
The number is <b>{count}</b>.
`}
values={{
count: 10,
}}
/>
);
Built-in support for simple string templates interpolation, you can use any other string interpolation library.
import { interpolation } from 'string-format-jsx';
const result = interpolation('Hello, {name} ({count})', {
values: {
count: 0,
name: 'u3u',
},
});
import { formatElements, interpolation } from 'string-format-jsx';
export const Trans = {
functional: true,
name: 'Trans',
props: {
tag: { default: 'span', type: [String, Object, Function] },
text: String,
values: Object,
},
render: (h, { data, props, scopedSlots: slots }) => {
const { tag, text, values } = props;
return h(
tag,
data,
formatElements(interpolation(text, { values }), {
components: slots,
createElement: h,
}),
);
},
};
const vnode = (
<Trans
scopedSlots={{
a: (children) => {
return (
<a
class="cursor-pointer text-primary hover:text-primary-400"
onClick={() => {
console.log(children);
}}
>
{children}
</a>
);
},
b: (children) => <b class="font-medium">{children}</b>,
}}
text={dedent`
Hello, <a>The number is <b>{count}</b></a>
<br />
The number is <b>{count}</b>.
`}
values={{ count: 10 }}
/>
);
Core extracted from next-translate.