diff --git a/packages/app-experiments/src/Experiment1.tsx b/packages/app-experiments/src/Experiment1.tsx index 4508d097a3..c5a4bc660b 100644 --- a/packages/app-experiments/src/Experiment1.tsx +++ b/packages/app-experiments/src/Experiment1.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { ComponentType, createContext, useMemo } from 'react'; +import React, { ComponentType, createContext } from 'react'; /* @@ -29,34 +29,83 @@ App structure: // import { redExtensionPointRef } from 'wherever'; -type Extension = { - factory(instanceOptions: { config: TInstanceConfig }): ComponentType; +type Extension = { + factory(instanceOptions: { id: string; config: TInstanceConfig }): TOutput; }; -type ExtensionInstance = { +type ExtensionInstanceConfig = { id: string; config: TInstanceConfig; + // what should point be for root + point?: string; extension: Extension; }; +type ExtensionInstance = { + id: string; + // what should point be for root + point?: string; + output: ComponentType; +}; + const BackstageAppContext = createContext<{ - extensionInstances: ExtensionInstance[]; + extensionInstances: ExtensionInstance[]; }>({ extensionInstances: [] }); const container = { createExtension(extensionOptions: { - render: (config: TInstanceConfig) => JSX.Element; + render: (options: { id: string; config: TInstanceConfig }) => JSX.Element; }): Extension { return { - factory(instanceOptions: { config: TInstanceConfig }) { - return () => extensionOptions.render(instanceOptions.config); + factory(instanceOptions) { + return () => + extensionOptions.render({ + id: instanceOptions.id, + config: instanceOptions.config, + }); }, }; }, }; +const ExtensionInstanceDerp = (props: { id: string }) => { + const { id } = props; + const { extensionInstances } = React.useContext(BackstageAppContext); + + const value = extensionInstances.find(i => i.id === id); + + if (!value) { + throw new Error(`No extension instance found with id ${id}`); + } + + const { output: ComponentInstance } = value; + + return ; +}; + +const ExtensionPointInstance = (props: { id: string }) => { + const { extensionInstances } = React.useContext(BackstageAppContext); + + return ( + <> + {extensionInstances + .filter(i => i.point === props.id) + .map(extensionInstance => ( + + ))} + + ); +}; + +const Container = container.createExtension({ + render: ({ id }) => , +}); + const Box = container.createExtension({ - render: (config: { color: string }) => { + render: ({ config }: { config: { color: string } }) => { return (
{config.color} @@ -65,44 +114,55 @@ const Box = container.createExtension({ }, }); -const ExtensionInstanceDerp = (props: { id: string }) => { - const { id } = props; - const { extensionInstances } = React.useContext(BackstageAppContext); - - const instance = extensionInstances.find(i => i.id === id); - - if (!instance) { - throw new Error(`No extension instance found with id ${id}`); - } - - const Component = useMemo( - () => instance.extension.factory({ config: instance.config }), - [instance], - ); - return ; -}; +function createExtensionInstances( + instanceConfigs: ExtensionInstanceConfig[], +): ExtensionInstance[] { + return instanceConfigs.map(instanceConfig => ({ + id: instanceConfig.id, + point: instanceConfig.point, + output: instanceConfig.extension.factory({ + id: instanceConfig.id, + config: instanceConfig.config, + }), + })); +} export function Experiment1() { // const element = useExtension("red"); + const extensionInstances = createExtensionInstances([ + { id: 'root', config: {}, extension: Container }, + { id: 'nestedRoot', point: 'root', config: {}, extension: Container }, + { + id: 'red', + point: 'nestedRoot', + config: { color: 'red' }, + extension: Box, + }, + { + id: 'green', + point: 'nestedRoot', + config: { color: 'green' }, + extension: Box, + }, + { + id: 'blue', + point: 'nestedRoot', + config: { color: 'blue' }, + extension: Box, + }, + ]); + return (

Experiment 1

This is an experiment to see how the app-experiments package works.

- {/* extension point */} - - - +
); }