Skip to content

Instantly share code, notes, and snippets.

@xplato
Created February 2, 2023 05:24
Show Gist options
  • Save xplato/6cf765614f71656166ee3d8436604fce to your computer and use it in GitHub Desktop.
Save xplato/6cf765614f71656166ee3d8436604fce to your computer and use it in GitHub Desktop.
import React, {
Children,
cloneElement,
HTMLAttributes,
isValidElement,
} from "react"
interface Schema {
[key: string]:
| HTMLAttributes<any>
| ((
child: React.ReactElement,
index: number
) => React.ReactElement | HTMLAttributes<any>)
}
export const remapChildren = (
children: React.ReactNode,
schema: Schema
): React.ReactNode => {
return Children.map(children, (child, index) => {
if (!isValidElement(child)) {
return child
}
if (child.props.children) {
child = cloneElement(child, {
// @ts-ignore
children: remapChildren(child.props.children, schema),
})
}
for (const [key, value] of Object.entries(schema)) {
if (
typeof child !== "string" &&
typeof child !== "number" &&
typeof child.type !== "string"
) {
if (child.type.name === key) {
if (typeof value === "function") {
const result = value(child, index)
if (React.isValidElement(result)) {
return result
} else {
return cloneElement(child, result as HTMLAttributes<any>)
}
} else {
return cloneElement(child, value)
}
}
}
}
return child
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment