Skip to content

Commit

Permalink
feat: add transform option
Browse files Browse the repository at this point in the history
  • Loading branch information
hansottowirtz committed Jul 20, 2023
1 parent 3c9c777 commit 33d0f9b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
6 changes: 6 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ export interface HTMLReactParserOptions {
domNode: DOMNode
) => JSX.Element | object | void | undefined | null | false;

transform?: (
reactNode: JSX.Element | string,
domNode: DOMNode,
index: number
) => JSX.Element | string | null;

trim?: boolean;
}

Expand Down
12 changes: 9 additions & 3 deletions lib/dom-to-react.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var canTextBeChildOfNode = utilities.canTextBeChildOfNode;
* @param {DomElement[]} nodes - DOM nodes.
* @param {object} [options={}] - Options.
* @param {Function} [options.replace] - Replacer.
* @param {Function} [options.transform] - Transform.
* @param {object} [options.library] - Library (React, Preact, etc.).
* @returns - String or JSX element(s).
*/
Expand All @@ -26,6 +27,11 @@ function domToReact(nodes, options) {
var node;
var isWhitespace;
var hasReplace = typeof options.replace === 'function';
var transform =
options.transform ||
function (reactNode) {
return reactNode;
};
var replaceElement;
var props;
var children;
Expand All @@ -46,7 +52,7 @@ function domToReact(nodes, options) {
key: replaceElement.key || i
});
}
result.push(replaceElement);
result.push(transform(replaceElement, node, i));
continue;
}
}
Expand All @@ -68,7 +74,7 @@ function domToReact(nodes, options) {

// We have a text node that's not whitespace and it can be nested
// in its parent so add it to the results
result.push(node.data);
result.push(transform(node.data, node, i));
continue;
}

Expand Down Expand Up @@ -115,7 +121,7 @@ function domToReact(nodes, options) {
props.key = i;
}

result.push(createElement(node.name, props, children));
result.push(transform(createElement(node.name, props, children), node, i));
}

return result.length === 1 ? result[0] : result;
Expand Down
37 changes: 37 additions & 0 deletions test/dom-to-react.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,43 @@ describe('domToReact replace option', () => {
});
});

describe('domToReact transform option', () => {
it('can wrap all elements', () => {
const options = {
transform: (reactNode, node, i) => {
return React.createElement('div', { key: i }, reactNode);
}
};

const reactElement = domToReact(htmlToDOM(html.list), options);
expect(reactElement.key).toBe('0');
expect(reactElement.props.children.props.children[0].key).toBe('0');
expect(reactElement.props.children.props.children[1].key).toBe('1');
expect(reactElement).toMatchInlineSnapshot(`
<div>
<ol>
<div>
<li>
<div>
One
</div>
</li>
</div>
<div>
<li
value="2"
>
<div>
Two
</div>
</li>
</div>
</ol>
</div>
`);
});
});

describe('domToReact', () => {
describe('when React >=16', () => {
it('preserves unknown attributes', () => {
Expand Down

0 comments on commit 33d0f9b

Please sign in to comment.