From b27d30c5699f6de68ef05c8134589cd6a58d1a5f Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 10 Jan 2024 15:48:17 -0500 Subject: [PATCH] feat(dom-to-react): pass index as 2nd argument to `replace` option Closes #1240 --- README.md | 13 +++++++++++++ __tests__/dom-to-react.test.tsx | 13 +++++++++++-- src/dom-to-react.ts | 2 +- src/types.ts | 1 + 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d5a115f2..e3f39788 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,19 @@ parse('

text

', { }); ``` +The second argument is the index: + +```ts +parse('
', { + 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`: diff --git a/__tests__/dom-to-react.test.tsx b/__tests__/dom-to-react.test.tsx index 92cafb54..8ec21bec 100644 --- a/__tests__/dom-to-react.test.tsx +++ b/__tests__/dom-to-react.test.tsx @@ -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: () =>
, }) 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), { @@ -230,6 +230,15 @@ describe('replace option', () => { const reactElement = domToReact(htmlToDOM('
test
'), options); expect(reactElement).toEqual(
test
); }); + + it('passes index as the 2nd argument', () => { + const reactElement = domToReact(htmlToDOM('
  • one
  • two
  • '), { + replace(domNode, index) { + expect(typeof index).toBe('number'); + }, + }); + expect(reactElement).toHaveLength(2); + }); }); describe('transform option', () => { diff --git a/src/dom-to-react.ts b/src/dom-to-react.ts index 47804e54..3af21d33 100644 --- a/src/dom-to-react.ts +++ b/src/dom-to-react.ts @@ -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 diff --git a/src/types.ts b/src/types.ts index d032410f..1503ed3f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -19,6 +19,7 @@ export interface HTMLReactParserOptions { replace?: ( domNode: DOMNode, + index: number, ) => JSX.Element | string | null | boolean | object | void; transform?: (