From cdb683f4d8cd807bb2cfbcf5d71317a1728702a7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 5 Aug 2025 10:44:29 +0200 Subject: [PATCH] docs/adrs: adr 15 for loader structure Signed-off-by: Patrik Oldsberg --- .../adr015-jsx-loader-structure.md | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 docs/architecture-decisions/adr015-jsx-loader-structure.md diff --git a/docs/architecture-decisions/adr015-jsx-loader-structure.md b/docs/architecture-decisions/adr015-jsx-loader-structure.md new file mode 100644 index 0000000000..0a9a5e6c55 --- /dev/null +++ b/docs/architecture-decisions/adr015-jsx-loader-structure.md @@ -0,0 +1,69 @@ +--- +id: adrs-adr015 +title: 'ADR015: Types and naming for element and component options' +description: Architecture Decision Record (ADR) for the proper types and naming for element and component options +--- + +## Context + +Until now there hasn't been a clear standard for how to define options that are intended to provide JSX elements or components. This led to a mix of different patterns in public APIs, which this ADR aims to standardize. + +## Decision + +We will use one of the following option property names and types when defining options that are intended to provide JSX elements or components: + +### Simple element + +This option is used when a simple synchronous JSX element is provided. It must only be used in areas where lazy-loading is not needed. + +```tsx +{ + element: JSX.Element; +} +``` + +### Simple component + +This option is used when a simple synchronous component is provided. It must only be used in areas where lazy-loading is not needed. + +```tsx +{ + component: (props: { ... }) => JSX.Element | null +} +``` + +### Async element loader + +This option is used when a simple asynchronous JSX element is provided. It is the preferred option when only producing a single instance and there is no need to pass properties to the component. This format simplifies the creation of closures for passing additional properties in the loader implementation. + +```tsx +{ + loader: () => Promise; +} +``` + +### Async component loader + +This option is used when a simple asynchronous component is provided. It is the preferred option when properties need to be passed to the component or multiple instance are needed, and lazy-loading is required. + +```tsx +{ + loader: () => Promise<(props: { ... }) => JSX.Element | null> +} +``` + +### Any component loader + +This option is used in the same cases as the async component loader, but when the option of synchronous loading is also needed. The structure of always having the outer loader function, even in the synchronous case, makes it possible to determine the type of the loader at runtime. + +```tsx +{ + loader: (() => props => JSX.Element | null) | (() => Promise JSX.Element | null>) +} +``` + +## Consequences + +We will update all APIs for the new frontend system in the `@backstage/frontend-*` packages. + +We will not update any of the existing APIs for the old frontend system in the `@backstage/core-*` packages.