UNPKG

@backstage/plugin-techdocs-react

Version:

Shared frontend utilities for TechDocs and Addons

290 lines (282 loc) • 9.94 kB
import * as react from 'react'; import { ComponentType, PropsWithChildren, Dispatch, SetStateAction, ReactNode } from 'react'; import * as _backstage_core_plugin_api from '@backstage/core-plugin-api'; import { Extension, RouteFunc } from '@backstage/core-plugin-api'; import { T as TechDocsAddonOptions, a as TechDocsAddonLocations, b as TechDocsMetadata, c as TechDocsEntityMetadata } from './types/types.d-BooYUMWM.js'; import { CompoundEntityRef, Entity } from '@backstage/catalog-model'; import * as react_jsx_runtime from 'react/jsx-runtime'; import { AsyncState } from 'react-use/esm/useAsync'; import { Config } from '@backstage/config'; /** * Key for each addon. * @public */ declare const TECHDOCS_ADDONS_KEY = "techdocs.addons.addon.v1"; /** * Marks the `<TechDocsAddons>` registry component. * @public */ declare const TECHDOCS_ADDONS_WRAPPER_KEY = "techdocs.addons.wrapper.v1"; /** * TechDocs Addon registry. * @public */ declare const TechDocsAddons: ComponentType<PropsWithChildren<{}>>; /** * Create a TechDocs addon overload signature without props. * @public */ declare function createTechDocsAddonExtension(options: TechDocsAddonOptions): Extension<() => JSX.Element | null>; /** * Create a TechDocs addon overload signature with props. * @public */ declare function createTechDocsAddonExtension<TComponentProps>(options: TechDocsAddonOptions<TComponentProps>): Extension<(props: TComponentProps) => JSX.Element | null>; /** * hook to use addons in components * @public */ declare const useTechDocsAddons: () => { renderComponentByName: (name: string) => JSX.Element | null; renderComponentsByLocation: (location: keyof typeof TechDocsAddonLocations) => (JSX.Element | null)[] | null; }; /** * API to talk to techdocs-backend. * * @public */ interface TechDocsApi { getCookie(): Promise<{ expiresAt: string; }>; getApiOrigin(): Promise<string>; getTechDocsMetadata(entityId: CompoundEntityRef): Promise<TechDocsMetadata>; getEntityMetadata(entityId: CompoundEntityRef): Promise<TechDocsEntityMetadata>; } /** * Utility API reference for the {@link TechDocsApi}. * * @public */ declare const techdocsApiRef: _backstage_core_plugin_api.ApiRef<TechDocsApi>; /** * The outcome of a docs sync operation. * * @public */ type SyncResult = 'cached' | 'updated'; /** * API which talks to TechDocs storage to fetch files to render. * * @public */ interface TechDocsStorageApi { getApiOrigin(): Promise<string>; getStorageUrl(): Promise<string>; getBuilder(): Promise<string>; getEntityDocs(entityId: CompoundEntityRef, path: string): Promise<string>; syncEntityDocs(entityId: CompoundEntityRef, logHandler?: (line: string) => void): Promise<SyncResult>; getBaseUrl(oldBaseUrl: string, entityId: CompoundEntityRef, path: string): Promise<string>; } /** * Utility API reference for the {@link TechDocsStorageApi}. * * @public */ declare const techdocsStorageApiRef: _backstage_core_plugin_api.ApiRef<TechDocsStorageApi>; /** * @public type for the value of the TechDocsReaderPageContext */ type TechDocsReaderPageValue = { metadata: AsyncState<TechDocsMetadata>; entityRef: CompoundEntityRef; entityMetadata: AsyncState<TechDocsEntityMetadata>; shadowRoot?: ShadowRoot; setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>; title: string; setTitle: Dispatch<SetStateAction<string>>; subtitle: string; setSubtitle: Dispatch<SetStateAction<string>>; /** * @deprecated property can be passed down directly to the `TechDocsReaderPageContent` instead. */ onReady?: () => void; }; /** * render function for {@link TechDocsReaderPageProvider} * * @public */ type TechDocsReaderPageProviderRenderFunction = (value: TechDocsReaderPageValue) => JSX.Element; /** * Props for {@link TechDocsReaderPageProvider} * * @public */ type TechDocsReaderPageProviderProps = { entityRef: CompoundEntityRef; children: TechDocsReaderPageProviderRenderFunction | ReactNode; }; /** * A context to store the reader page state * @public */ declare const TechDocsReaderPageProvider: react.MemoExoticComponent<(props: TechDocsReaderPageProviderProps) => react_jsx_runtime.JSX.Element>; /** * Hook used to get access to shared state between reader page components. * @public */ declare const useTechDocsReaderPage: () => TechDocsReaderPageValue; /** * Name for the event dispatched when ShadowRoot styles are loaded. * @public */ declare const SHADOW_DOM_STYLE_LOAD_EVENT = "TECH_DOCS_SHADOW_DOM_STYLE_LOAD"; /** * Returns the style's loading state. * * @example * Here's an example that updates the sidebar position only after styles are calculated: * ```jsx * import { * TechDocsShadowDom, * useShadowDomStylesLoading, * } from '@backstage/plugin-techdocs-react'; * * export const TechDocsReaderPageContent = () => { * // ... * const dom = useTechDocsReaderDom(entity); * const isStyleLoading = useShadowDomStylesLoading(dom); * * const updateSidebarPosition = useCallback(() => { * //... * }, [dom]); * * useEffect(() => { * if (!isStyleLoading) { * updateSidebarPosition(); * } * }, [isStyleLoading, updateSidebarPosition]); * * const handleDomAppend = useCallback( * (newShadowRoot: ShadowRoot) => { * setShadowRoot(newShadowRoot); * }, * [setShadowRoot], * ); * * return <TechDocsShadowDom element={dom} onAppend={handleDomAppend} />; * }; * ``` * * @param element - which is the ShadowRoot tree. * @returns a boolean value, true if styles are being loaded. * @public */ declare const useShadowDomStylesLoading: (element: Element | null) => boolean; /** * Props for {@link TechDocsShadowDom}. * * @remarks * If you want to use portals to render Material UI components in the Shadow DOM, * you must render these portals as children because this component wraps its children in a Material UI StylesProvider * to ensure that Material UI styles are applied. * * @public */ type TechDocsShadowDomProps = PropsWithChildren<{ /** * Element tree that is appended to ShadowRoot. */ element: Element; /** * Callback called when the element tree is appended in ShadowRoot. */ onAppend?: (shadowRoot: ShadowRoot) => void; }>; /** * Renders a tree of elements in a Shadow DOM. * * @remarks * Centers the styles loaded event to avoid having multiple locations setting the opacity style in Shadow DOM causing the screen to flash multiple times, * so if you want to know when Shadow DOM styles are computed, you can listen for the "TECH_DOCS_SHADOW_DOM_STYLE_LOAD" event dispatched by the element tree. * * @example * Here is an example using this component and also listening for styles loaded event: *```jsx * import { * TechDocsShadowDom, * SHADOW_DOM_STYLE_LOAD_EVENT, * } from '@backstage/plugin-techdocs-react'; * * export const TechDocsReaderPageContent = ({ entity }: TechDocsReaderPageContentProps) => { * // ... * const dom = useTechDocsReaderDom(entity); * * useEffect(() => { * const updateSidebarPosition = () => { * // ... * }; * dom?.addEventListener(SHADOW_DOM_STYLE_LOAD_EVENT, updateSidebarPosition); * return () => { * dom?.removeEventListener(SHADOW_DOM_STYLE_LOAD_EVENT, updateSidebarPosition); * }; * }, [dom]); * * const handleDomAppend = useCallback( * (newShadowRoot: ShadowRoot) => { * setShadowRoot(newShadowRoot); * }, * [setShadowRoot], * ); * * return <TechDocsShadowDom element={dom} onAppend={handleDomAppend} />; * }; * ``` * * @param props - see {@link TechDocsShadowDomProps}. * @public */ declare const TechDocsShadowDom: (props: TechDocsShadowDomProps) => react_jsx_runtime.JSX.Element; /** * Hook for use within TechDocs addons that provides access to the underlying * shadow root of the current page, allowing the DOM within to be mutated. * @public */ declare const useShadowRoot: () => ShadowRoot | undefined; /** * Convenience hook for use within TechDocs addons that provides access to * elements that match a given selector within the shadow root. * * @public */ declare const useShadowRootElements: <TReturnedElement extends HTMLElement = HTMLElement>(selectors: string[]) => TReturnedElement[]; /** * Hook for retrieving a selection within the ShadowRoot. * @public */ declare const useShadowRootSelection: (waitMillis?: number) => Selection | null; /** * Lower-case entity triplets by default, but allow override. * * @public */ declare function toLowercaseEntityRefMaybe(entityRef: CompoundEntityRef, config: Config): CompoundEntityRef; /** * Get the entity path annotation from the given entity and ensure it starts with a slash. * * @public */ declare function getEntityRootTechDocsPath(entity: Entity): string; /** * Build the TechDocs URL for the given entity. This helper should be used anywhere there * is a link to an entities TechDocs. * * @public */ declare const buildTechDocsURL: (entity: Entity, routeFunc: RouteFunc<{ namespace: string; kind: string; name: string; }> | undefined) => string | undefined; export { SHADOW_DOM_STYLE_LOAD_EVENT, type SyncResult, TECHDOCS_ADDONS_KEY, TECHDOCS_ADDONS_WRAPPER_KEY, TechDocsAddonLocations, TechDocsAddonOptions, TechDocsAddons, type TechDocsApi, TechDocsEntityMetadata, TechDocsMetadata, TechDocsReaderPageProvider, type TechDocsReaderPageProviderProps, type TechDocsReaderPageProviderRenderFunction, type TechDocsReaderPageValue, TechDocsShadowDom, type TechDocsShadowDomProps, type TechDocsStorageApi, buildTechDocsURL, createTechDocsAddonExtension, getEntityRootTechDocsPath, techdocsApiRef, techdocsStorageApiRef, toLowercaseEntityRefMaybe, useShadowDomStylesLoading, useShadowRoot, useShadowRootElements, useShadowRootSelection, useTechDocsAddons, useTechDocsReaderPage };