UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

82 lines (68 loc) 2.06 kB
import { cloneElement, isValidElement } from 'react' type Props = Record<string, any> export type FoundRootHTML = { children: React.ReactElement htmlProps?: Props bodyProps?: Props head?: React.ReactElement } /** * To enable custom <html> and other html-like stuff in the root _layout * we are doing some fancy stuff, namely, just capturing the root layout return * value and deep-mapping over it. * * On server, we filter it out and hoist it to the parent root html in createApp * * On client, we just filter it out completely as in One we don't hydrate html */ export function filterRootHTML(el: React.ReactNode): FoundRootHTML { let htmlProps: Props | undefined let bodyProps: React.ReactElement | undefined let head: React.ReactElement | undefined function traverse(element: React.ReactNode) { if (!element || typeof element !== 'object') { return element } if (Array.isArray(element)) { return element.map(traverse) } const reactElement = element as React.ReactElement const { type, props } = reactElement if (type === 'html') { const { children, ...restProps } = reactElement.props htmlProps = restProps return traverse(children) } if (type === 'head') { head = reactElement return null } if (type === 'body') { const { children, ...restProps } = reactElement.props bodyProps = restProps return children } if (process.env.TAMAGUI_TARGET === 'native') { if ( isValidElement(element) && typeof element.type === 'string' && element.type.toLowerCase() === element.type ) { // filter out things like <meta /> etc on native // because it could just be thown in <html> or a fragment to be hoisted on web return null } } return element } const children = traverse(el) || // if none found, we assume they aren't returning any html so just pass it on el return { children, htmlProps, bodyProps, head, } }