import React , { Suspense } from 'react' ; import ReactDOM from 'react-dom' ; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ; import { faSpinner } from '@fortawesome/free-solid-svg-icons' ; /**
 * A factory function returning a Promise of React default-exported Component Class Module.
 */ type ReactAsyncComponentClassFactory = ( ) => Promise < { default : React . ComponentClass < any > | React . FunctionComponent < any > ; } > ; /**
 * Convert a hyphenated string to camelCase.
 */ function hyphenToCamelCase ( name ) { return name . replace ( /-(.)/g , ( _match , char ) => { return char . toUpperCase ( ) ; } ) ; } param el returns function convertElementAttributesToPropsMap ( el ) { if ( el . hasAttributes ( ) === false ) { return { } ; } const result = { } ; for ( const attribute of el . attributes ) { let name = attribute . name ; if ( name === 'for' ) { name = 'htmlFor' ; } if ( name === 'class' ) { name = 'className' ; } name = hyphenToCamelCase ( name ) ; result [ name ] = attribute . value ; } return result ; } param selector param lazyComponent export function renderAsyncComponent ( selector , lazyComponent ) { for ( const el of document . querySelectorAll ( selector ) ) { const LazyComponent = React . lazy ( lazyComponent ) ; const fallback = < FontAwesomeIcon icon = { faSpinner } pulse > < /FontAwesomeIcon>; const props = convertElementAttributesToPropsMap ( el ) ; const render = ( < Suspense fallback = { fallback } > < LazyComponent { ... props } > < /LazyComponent> < /Suspense>); ReactDOM . render ( render , el ) ; } }