Files
Compass/web/components/og/utils.tsx
2025-08-27 21:30:05 +02:00

58 lines
1.6 KiB
TypeScript

import { createElement, ReactElement, ReactNode } from 'react'
// new function for type reasons
export function classToTw(element: ReactElement) {
return replaceTw(element) as ReactElement
}
/** Traverse react element's tree, replacing className prop with tw for satori engine */
function replaceTw(element: ReactNode): ReactNode {
// base case
if (!element || typeof element !== 'object') {
if (typeof element === 'string') return element
return element
}
// fragment
if (!('type' in element)) {
// Convert to array safely
const children = Array.isArray(element) ? element : [element]
return <>{children.map(replaceTw)}</>
}
// component
if (typeof element.type === 'function') {
if (element.type.prototype?.isReactComponent) {
throw Error(
'React class component not supported in classname to tw middleware because Sinclair is lazy.'
)
}
// functional component
const component = element.type as (props: any) => ReactElement
const newType = (props: any) => replaceTw(component(props)) as ReactElement
return createElement(newType, element.props)
}
// pure element
// Replace `className` with `tw` for this element
const { props } = element
const newProps = { ...props }
if (props.className) {
newProps.tw = props.className
delete newProps.className
}
// Recursively replace children, whether we have many, one, or no children
const { children } = props
const newChildren = children
? Array.isArray(children)
? children.map(replaceTw)
: [replaceTw(children)]
: []
return createElement(element.type, newProps, newChildren)
}