From 2cd86f7c3d0b3c0ade2c9a3918ef8d8d385e1d39 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 24 Sep 2025 10:58:41 +0100 Subject: [PATCH] Add some experimental module interfaces ...with somewhat placeholder names as they're the best I can think of right now: * 'Extras': To add new bits of UI to places (specifically the space panel) * 'Builtins': For modules to render components that are part of Element Web * 'Navigation': For modules to add paths to the URL router --- .../src/api/builtins.ts | 19 +++++++++++++++++++ .../element-web-module-api/src/api/extras.ts | 18 ++++++++++++++++++ .../element-web-module-api/src/api/index.ts | 6 ++++++ .../src/api/navigation.ts | 6 ++++++ packages/element-web-module-api/src/index.ts | 2 ++ 5 files changed, 51 insertions(+) create mode 100644 packages/element-web-module-api/src/api/builtins.ts create mode 100644 packages/element-web-module-api/src/api/extras.ts diff --git a/packages/element-web-module-api/src/api/builtins.ts b/packages/element-web-module-api/src/api/builtins.ts new file mode 100644 index 0000000000..31280366e0 --- /dev/null +++ b/packages/element-web-module-api/src/api/builtins.ts @@ -0,0 +1,19 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +export interface RoomViewProps { + roomId?: string; +} + +/** + * Exposes components that are part of Element Web to allow modules to render them + * as part of their custom components (because they can't import the components from + * Element Web since it would cause a dependency cycle) + */ +export interface BuiltinsApi { + getRoomViewComponent(): React.ComponentType; +} diff --git a/packages/element-web-module-api/src/api/extras.ts b/packages/element-web-module-api/src/api/extras.ts new file mode 100644 index 0000000000..c4ad313b5f --- /dev/null +++ b/packages/element-web-module-api/src/api/extras.ts @@ -0,0 +1,18 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import { JSX } from "react"; + +interface SpacePanelItemProps { + isPanelCollapsed: boolean; +} + +export type SpacePanelItemRenderFunction = (props: SpacePanelItemProps) => JSX.Element; + +export interface ExtrasApi { + addSpacePanelItem(renderer: SpacePanelItemRenderFunction): void; +} diff --git a/packages/element-web-module-api/src/api/index.ts b/packages/element-web-module-api/src/api/index.ts index 8a59260773..9ad4fc614f 100644 --- a/packages/element-web-module-api/src/api/index.ts +++ b/packages/element-web-module-api/src/api/index.ts @@ -15,6 +15,8 @@ import { NavigationApi } from "./navigation.ts"; import { DialogApiExtension } from "./dialog.ts"; import { AccountAuthApiExtension } from "./auth.ts"; import { ProfileApiExtension } from "./profile.ts"; +import { ExtrasApi } from "./extras.ts"; +import { BuiltinsApi } from "./builtins.ts"; /** * Module interface for modules to implement. @@ -103,12 +105,16 @@ export interface Api */ readonly customComponents: CustomComponentsApi; + readonly builtins: BuiltinsApi; + /** * API to navigate the application. * @public */ readonly navigation: NavigationApi; + readonly extras: ExtrasApi; + /** * Create a ReactDOM root for rendering React components. * Exposed to allow modules to avoid needing to bundle their own ReactDOM. diff --git a/packages/element-web-module-api/src/api/navigation.ts b/packages/element-web-module-api/src/api/navigation.ts index a3b073274c..063b683445 100644 --- a/packages/element-web-module-api/src/api/navigation.ts +++ b/packages/element-web-module-api/src/api/navigation.ts @@ -5,6 +5,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ +import { JSX } from "react"; + +export type LocationRenderFunction = () => JSX.Element; + /** * API methods to navigate the application. * @public @@ -16,4 +20,6 @@ export interface NavigationApi { * @param join - If true, the user will be made to attempt to join the room/space if they are not already a member. */ toMatrixToLink(link: string, join?: boolean): Promise; + + registerLocationRenderer(path: string, renderer: LocationRenderFunction): void; } diff --git a/packages/element-web-module-api/src/index.ts b/packages/element-web-module-api/src/index.ts index 196db8d9fc..e89adc482d 100644 --- a/packages/element-web-module-api/src/index.ts +++ b/packages/element-web-module-api/src/index.ts @@ -11,10 +11,12 @@ export type { Config, ConfigApi } from "./api/config"; export type { I18nApi, Variables, Translations } from "./api/i18n"; export type * from "./models/event"; export type * from "./api/custom-components"; +export type * from "./api/extras"; export type * from "./api/legacy-modules"; export type * from "./api/legacy-customisations"; export type * from "./api/auth"; export type * from "./api/dialog"; export type * from "./api/profile"; export type * from "./api/navigation"; +export type * from "./api/builtins"; export * from "./api/watchable";