Skip to content

Commit

Permalink
refactor!: unified createElement signature
Browse files Browse the repository at this point in the history
  • Loading branch information
u3u committed Dec 13, 2023
1 parent 42e05f2 commit aa646bb
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 12 deletions.
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Use with any framework
import { formatElements } from 'string-format-jsx';

formatElements('Hello, <a>@u3u</a>', {
createElement: (type, children, key) => yourFramework.createElement(type, { key }, children),
createElement: (type, props, children) => yourFramework.createElement(type, props, children),
});
```

Expand Down Expand Up @@ -97,6 +97,39 @@ const result = interpolation('Hello, {name} ({count})', {
});
```

## Examples

### Vue2

```js
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,
}),
);
},
};
```

## Thanks

Core extracted from [next-translate](https://github.com/aralroca/next-translate).
Expand Down
16 changes: 11 additions & 5 deletions src/core.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
export interface FormatElementsOptions<T> {
components?: Record<string, (children: T | string, key: number) => T>;
createElement?(type: string, children: T | string, key: number): T;
components?: Record<string, (children: (T | string)[] | string, key: number) => T>;
createElement?(
type: string,
props: {
key: number;
},
children: (T | string)[] | string,
): T;
}

export const formatElements = <T>(text: string, options: FormatElementsOptions<T> = {}) => {
Expand All @@ -20,15 +26,15 @@ export const formatElements = <T>(text: string, options: FormatElementsOptions<T

for (const [key, [type, children, after]] of elements.entries()) {
const render = components?.[type];
const child = children && (formatElements<T>(children, options) as T | string);
const child = children && formatElements<T>(children, options);

tree.push(
render
? render?.(child, key)
: //
createElement
? createElement?.(type, child, key)
: child,
? createElement?.(type, { key }, child)
: (child as string),
);

if (after) tree.push(after);
Expand Down
2 changes: 1 addition & 1 deletion src/react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface FormatElementsOptions extends Options<ReactNode> {}
*/
export const formatElements = (text: string, options: FormatElementsOptions = {}) => {
return format<ReactNode>(text, {
createElement: (type, children, key) => createElement(type, { key }, children),
createElement,
...options,
});
};
16 changes: 12 additions & 4 deletions test/__snapshots__/core.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,30 @@ exports[`should match snapshots 1`] = `
"The number is ",
{
"children": "{count}",
"key": 0,
"props": {
"key": 0,
},
"type": "b",
},
],
"key": 0,
"props": {
"key": 0,
},
"type": "component",
},
{
"children": undefined,
"key": 1,
"props": {
"key": 1,
},
"type": "br",
},
"The number is ",
{
"children": "{count}",
"key": 2,
"props": {
"key": 2,
},
"type": "b",
},
".",
Expand Down
2 changes: 1 addition & 1 deletion test/core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ it('should match snapshots', () => {
The number is <b>{count}</b>.
`,
{
createElement: (type, children, key) => ({ children, key, type }),
createElement: (type, props, children) => ({ children, props, type }),
},
),

Expand Down

0 comments on commit aa646bb

Please sign in to comment.