import { ImageryProvider } from "cesium"; import { forwardRef, HTMLAttributes, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, ForwardRefRenderFunction, PropsWithChildren, } from "react"; import { CesiumContext } from "./context"; import { useCesiumComponent, Options } from "./hooks"; import { pick } from "./util"; export type CesiumComponentOptions< Element, Props extends RootComponentInternalProps, State = any, > = Options & { renderContainer?: boolean; noChildren?: boolean; containerProps?: (keyof Props)[] | ((props: Props) => HTMLAttributes); defaultProps?: Partial; }; export type CesiumComponentRef = { cesiumElement?: Element; }; export type CesiumComponentType = ForwardRefExoticComponent< PropsWithoutRef & RefAttributes> >; export type RootComponentInternalProps = { onUpdate?: () => void; }; export type RootComponentInternalValues = { imageryLayerWaitingList?: (Promise | ImageryProvider)[]; }; export const createCesiumComponent = ({ renderContainer, noChildren, containerProps, defaultProps, ...options }: CesiumComponentOptions): CesiumComponentType => { const component: ForwardRefRenderFunction, Props> = (props, ref) => { const mergedProps = { ...defaultProps, ...props, }; // eslint-disable-next-line react-hooks/rules-of-hooks const [provided, mounted, wrapperRef] = useCesiumComponent( options, mergedProps, ref, ); if (noChildren) return null; const children = mounted ? "children" in mergedProps ? (mergedProps as PropsWithChildren).children : null : null; const wrappedChildren = renderContainer ? (
{children}
) : children ? ( <>{children} ) : null; if (provided) { return {wrappedChildren}; } return wrappedChildren; }; component.displayName = options.name; return forwardRef(component); };