Skip to content

Commit

Permalink
Merge pull request #1260 from remarkablemark/feat/replace
Browse files Browse the repository at this point in the history
feat(dom-to-react): pass index as 2nd argument to `replace` option
  • Loading branch information
remarkablemark authored Jan 10, 2024
2 parents b56255e + b27d30c commit a706ced
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,19 @@ parse('<p id="replace">text</p>', {
});
```

The second argument is the index:

```ts
parse('<br>', {
replace(domNode, index) {
console.assert(typeof index === 'number');
},
});
```

> [!NOTE]
> The index will restart at 0 when traversing the node's children so don't rely on index being a unique key.
#### replace with TypeScript

For TypeScript, you'll need to check that `domNode` is an instance of domhandler's `Element`:
Expand Down
13 changes: 11 additions & 2 deletions __tests__/dom-to-react.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,14 @@ describe('replace option', () => {
},
);

it("does not set key if there's a single node", () => {
it('does not set key for a single node', () => {
const reactElement = domToReact(htmlToDOM(html.single), {
replace: () => <div />,
}) as JSX.Element;
expect(reactElement.key).toBe(null);
});

it("does not modify keys if they're already set", () => {
it('does not modify keys if they are already set', () => {
const reactElements = domToReact(
htmlToDOM(html.single + html.customElement),
{
Expand Down Expand Up @@ -230,6 +230,15 @@ describe('replace option', () => {
const reactElement = domToReact(htmlToDOM('<div>test</div>'), options);
expect(reactElement).toEqual(<div>test</div>);
});

it('passes index as the 2nd argument', () => {
const reactElement = domToReact(htmlToDOM('<li>one</li><li>two</li>'), {
replace(domNode, index) {
expect(typeof index).toBe('number');
},
});
expect(reactElement).toHaveLength(2);
});
});

describe('transform option', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/dom-to-react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default function domToReact(

// replace with custom React element (if present)
if (hasReplace) {
let replaceElement = options.replace!(node) as JSX.Element;
let replaceElement = options.replace!(node, index) as JSX.Element;

if (isValidElement(replaceElement)) {
// set "key" prop for sibling elements
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface HTMLReactParserOptions {

replace?: (
domNode: DOMNode,
index: number,
) => JSX.Element | string | null | boolean | object | void;

transform?: (
Expand Down

0 comments on commit a706ced

Please sign in to comment.