diff --git a/src/__helpers__/burger.tsx b/src/__helpers__/burger.tsx index a086046..7c4f5e3 100644 --- a/src/__helpers__/burger.tsx +++ b/src/__helpers__/burger.tsx @@ -1,19 +1,31 @@ import * as React from "react"; -export const Bun = ({ variant }: { variant: string }) => ( -
{`${variant} bun`}
+export const Bun = ({ + variant, + propIndex +}: { + variant: string; + propIndex?: number; +}) => ( +
+
{propIndex && `Order: ${propIndex}`}
+ {`${variant} bun`} +
); export const Patty = ({ id, size, - ingredient + ingredient, + propIndex }: { id: number; size: string; ingredient: React.ReactNode; + propIndex?: number; }) => (
+
{propIndex && `Order: ${propIndex}`}
{`${size} patty`} {ingredient}
@@ -26,14 +38,17 @@ export const PattyIngredient = ({ variant }: { variant: string }) => ( export const Burger = ({ bun, cheese, - children + children, + propIndex }: { bun: React.ReactNode; chain: string; cheese: boolean; children: React.ReactNode; + propIndex?: number; }) => (
+
{propIndex && `Order: ${propIndex}`}
{bun}
{cheese && "cheese"}
{children}
diff --git a/src/__tests__/__snapshots__/index.tsx.snap b/src/__tests__/__snapshots__/index.tsx.snap index 10d643d..7f989f4 100644 --- a/src/__tests__/__snapshots__/index.tsx.snap +++ b/src/__tests__/__snapshots__/index.tsx.snap @@ -2,8 +2,10 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] = `
+
+
sesame bun
@@ -14,6 +16,9 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] =
+
+ 0 +
large patty
impossible @@ -22,6 +27,9 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] =
+
+ Order: 1 +
large patty
beef @@ -30,6 +38,7 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] =
+
sesame bun
@@ -38,8 +47,10 @@ exports[`ReactFromJSON to render a flat entry with a components attribute 1`] = exports[`ReactFromJSON to render a recursive entry 1`] = `
+
+
sesame bun
@@ -50,6 +61,9 @@ exports[`ReactFromJSON to render a recursive entry 1`] = `
+
+ 0 +
large patty
impossible @@ -58,6 +72,9 @@ exports[`ReactFromJSON to render a recursive entry 1`] = `
+
+ Order: 1 +
large patty
beef @@ -66,6 +83,7 @@ exports[`ReactFromJSON to render a recursive entry 1`] = `
+
sesame bun
diff --git a/src/index.tsx b/src/index.tsx index ee52ec8..7e490ac 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -8,6 +8,7 @@ export interface Component { interface ComponentLookupProps { componentType: string; componentIndex: number; + propIndex?: number; } export interface ComponentLookup { @@ -44,7 +45,8 @@ class ReactFromJSON< ComponentLookup = ({ componentIndex, - componentType + componentType, + propIndex }: ComponentLookupProps) => { const { components } = this.props; @@ -58,12 +60,13 @@ class ReactFromJSON< ...component, props: { id: component.id || componentIndex, // Map id to component props if specified on root. Otherwise, use index. + propIndex: propIndex, ...component.props } }); }; - resolveProp = (prop: any): any => { + resolveProp = (prop: any, index?: number): any => { if (prop === null) { return prop; } else if (Array.isArray(prop)) { @@ -76,23 +79,25 @@ class ReactFromJSON< ) { const component: Component = prop; - return this.renderComponent(component); + return this.renderComponent(component, index); } } return prop; }; - getNextKey(type: string) { + getNextKey(type: string, propIndex?: number) { this.counter[type] = this.counter[type] || 0; - return `${type}_${this.counter[type]++}`; + const propIndexKey = + typeof propIndex !== "undefined" ? `_${propIndex}` : ""; + return `${type}_${this.counter[type]++}${propIndexKey}`; } - renderComponent(component: Component) { + renderComponent(component: Component, propIndex?: number) { const { mapping } = this.props; const { type, props } = component; const resolvedProps = {}; - const key = this.getNextKey(type); + const key = this.getNextKey(type, propIndex); const propKeys = Object.keys(props); @@ -109,7 +114,9 @@ class ReactFromJSON< throw `Tried to render the "${type}" component, but it's not specified in your mapping.`; } - return ; + return ( + + ); } render() {