import React , { ReactNode , FunctionComponentElement } from "react" ; import warning from "warning" ; import { plugins } from "@webiny/plugins" ; import { Plugin } from "@webiny/plugins/types" ; import imagePlugin from "./image" ; export { imagePlugin } ; type RenderPluginOptions < T > = { wrapper ? : boolean ; fn ? : string ; filter ? : ( value : T , index : number , array : T [ ] ) => boolean ; reverse ? : boolean ; } ; interface RenderPlugin { < T extends Plugin = Plugin > ( name , params ? , options ? ) : ReactNode | ReactNode [ ] ; } interface RenderPlugins { < T extends Plugin = Plugin > ( type , params ? , options ? ) : ReactNode | ReactNode [ ] ; } const PluginComponent = ( props ) : FunctionComponentElement < { } > => props . children ; const PluginsComponent = ( props ) : FunctionComponentElement < { } > => props . children ; export const renderPlugin = ( name , params = { } , options = { } ) => { const { wrapper = true , fn = "render" } = options ; const plugin = plugins . byName ( name ) ; warning ( plugin , `No such plugin "${ name }"` ) ; if ( ! plugin ) { return null ; } const content = plugin [ fn ] ( params ) ; if ( content ) { return wrapper ? ( < PluginComponent key = { plugin . name } name = { name } params = { params } fn = { fn } > { content } < /PluginComponent>) : (React.cloneElement(content, { key: plugin.name })); } return null ; } ; export const renderPlugins = ( type , params = { } , options = { } ) => { const { wrapper = true , fn = "render" , filter = v => v , reverse } = options ; const content = plugins . byType ( type ) . filter ( filter ) . map ( plugin => renderPlugin ( plugin . name , params , { wrapper , fn } ) ) . filter ( Boolean ) ; if ( reverse ) { content . reverse ( ) ; } return wrapper ? ( < PluginsComponent type = { type } params = { params } fn = { fn } > { content } < /PluginsComponent>) : (content); } ; export default [ imagePlugin ] ;