From bf69ddf2b457c04c438da80658ad2ffbd9606179 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 6 Mar 2026 10:58:00 +0000 Subject: [PATCH 1/4] Add module APIs to enable widget toggle buttons --- .../element-web-module-api.api.md | 19 +++++- packages/element-web-module-api/package.json | 3 + .../element-web-module-api/src/api/extras.ts | 16 +++++ .../element-web-module-api/src/api/index.ts | 9 +++ .../element-web-module-api/src/api/widget.ts | 68 +++++++++++++++++++ packages/element-web-module-api/src/index.ts | 1 + 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 packages/element-web-module-api/src/api/widget.ts diff --git a/packages/element-web-module-api/element-web-module-api.api.md b/packages/element-web-module-api/element-web-module-api.api.md index 86cce8dfec..aff9156165 100644 --- a/packages/element-web-module-api/element-web-module-api.api.md +++ b/packages/element-web-module-api/element-web-module-api.api.md @@ -5,6 +5,7 @@ ```ts import { ComponentType } from 'react'; +import { IWidget } from 'matrix-widget-api'; import { JSX } from 'react'; import { ModuleApi } from '@matrix-org/react-sdk-module-api'; import { Root } from 'react-dom/client'; @@ -56,6 +57,8 @@ export interface Api extends LegacyModuleApiExtension, LegacyCustomisationsApiEx readonly rootNode: HTMLElement; readonly stores: StoresApi; // @alpha + readonly widget: WidgetApi; + // @alpha readonly widgetLifecycle: WidgetLifecycleApi; } @@ -107,6 +110,9 @@ export interface ConfigApi { get(key?: K): Config | Config[K]; } +// @alpha +export type Container = "top" | "right" | "center"; + // @alpha export interface CustomComponentsApi { registerMessageRenderer(eventTypeOrFilter: string | ((mxEvent: MatrixEvent) => boolean), renderer: CustomMessageRenderFunction, hints?: CustomMessageRenderHints): void; @@ -174,6 +180,7 @@ export interface DirectoryCustomisations { // @alpha export interface ExtrasApi { getVisibleRoomBySpaceKey(spaceKey: string, cb: () => string[]): void; + setRoomHeaderButtonCallback(cb: RoomHeaderButtonsCallback): void; setSpacePanelItem(spaceKey: string, props: SpacePanelItemProps): void; } @@ -358,6 +365,9 @@ export interface Room { name: Watchable; } +// @alpha +export type RoomHeaderButtonsCallback = (roomId: string) => JSX.Element | undefined; + // @alpha @deprecated (undocumented) export interface RoomListCustomisations { isRoomVisible?(room: Room): boolean; @@ -436,6 +446,14 @@ export class Watchable { watch(listener: (value: T) => void): void; } +// @alpha +export interface WidgetApi { + getAppAvatarUrl(app: IWidget, width?: number, height?: number, resizeMethod?: string): string | null; + getWidgetsInRoom(roomId: string): IWidget[]; + isAppInContainer(app: IWidget, container: Container, roomId: string): boolean; + moveAppToContainer(app: IWidget, container: Container, roomId: string): void; +} + // @alpha export type WidgetDescriptor = { id: string; @@ -476,4 +494,3 @@ export interface WidgetVariablesCustomisations { // (No @packageDocumentation comment for this package) ``` - diff --git a/packages/element-web-module-api/package.json b/packages/element-web-module-api/package.json index 6950765e7b..63a87ad3b2 100644 --- a/packages/element-web-module-api/package.json +++ b/packages/element-web-module-api/package.json @@ -61,5 +61,8 @@ "matrix-web-i18n": { "optional": true } + }, + "dependencies": { + "matrix-widget-api": "^1.17.0" } } diff --git a/packages/element-web-module-api/src/api/extras.ts b/packages/element-web-module-api/src/api/extras.ts index 5ffc9c4f16..1f6f9818c6 100644 --- a/packages/element-web-module-api/src/api/extras.ts +++ b/packages/element-web-module-api/src/api/extras.ts @@ -43,6 +43,15 @@ export interface SpacePanelItemProps { onSelected: () => void; } +/** + * A callback that returns a JSX element representing the buttons. + * + * @alpha + * @param roomId - The ID of the room for which the header is being rendered. + * @returns A JSX element representing the buttons to be rendered in the room header, or undefined if no buttons should be rendered. + */ +export type RoomHeaderButtonsCallback = (roomId: string) => JSX.Element | undefined; + /** * API for inserting extra UI into Element Web. * @alpha Subject to change. @@ -67,4 +76,11 @@ export interface ExtrasApi { * @param cb - A callback that returns the list of visible room IDs. */ getVisibleRoomBySpaceKey(spaceKey: string, cb: () => string[]): void; + + /** + * Sets the callback to get extra buttons in the room header (which can vary depending on the room being displayed). + * + * @param cb - A callback that returns a JSX element representing the buttons (see {@link RoomHeaderButtonsCallback}). + */ + setRoomHeaderButtonCallback(cb: RoomHeaderButtonsCallback): void; } diff --git a/packages/element-web-module-api/src/api/index.ts b/packages/element-web-module-api/src/api/index.ts index 9c5e59ed57..840eea6eb2 100644 --- a/packages/element-web-module-api/src/api/index.ts +++ b/packages/element-web-module-api/src/api/index.ts @@ -1,5 +1,6 @@ /* Copyright 2025 New Vector Ltd. +Copyright 2026 Element Creations Ltd. SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. @@ -20,6 +21,7 @@ import { type BuiltinsApi } from "./builtins.ts"; import { type StoresApi } from "./stores.ts"; import { type ClientApi } from "./client.ts"; import { type WidgetLifecycleApi } from "./widget-lifecycle.ts"; +import { type WidgetApi } from "./widget.ts"; /** * Module interface for modules to implement. @@ -143,6 +145,13 @@ export interface Api */ readonly widgetLifecycle: WidgetLifecycleApi; + /** + * API for modules to interact with widgets in Element Web, including getting what widgets + * are active in a given room. + * @alpha Subject to change. + */ + readonly widget: WidgetApi; + /** * 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/widget.ts b/packages/element-web-module-api/src/api/widget.ts new file mode 100644 index 0000000000..66c8b31e73 --- /dev/null +++ b/packages/element-web-module-api/src/api/widget.ts @@ -0,0 +1,68 @@ +/* +Copyright 2026 Element Creations Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import { type IWidget } from "matrix-widget-api"; + +/** + * Containers that control where a widget is displayed on the screen. + * + * "top" is the app drawer, and currently the only sensible value. + * + * "right" is the right panel, and the default for widgets. Setting + * this as a container on a widget is essentially like saying "no + * changes needed", though this may change in the future. + * + * "center" was uncodumented at time of porting this from an enum. + * Possibly when a widget replaces the main chat view like element call. + * + * @alpha Subject to change. + */ +export type Container = "top" | "right" | "center"; + +/** + * An API for interfacing with widgets in Element Web, including getting what widgets + * are active in a given room. + * @alpha Subject to change. + */ +export interface WidgetApi { + /** + * Gets the widgets active in a given room. + * + * @param roomId - The room to get the widgets for. + */ + getWidgetsInRoom(roomId: string): IWidget[]; + + /** + * Gets the URL of a widget's avatar, if it has one. + * + * @param app - The widget to get the avatar URL for. + * @param width - Optional width to resize the avatar to. + * @param height - Optional height to resize the avatar to. + * @param resizeMethod - Optional method to use when resizing the avatar. + * @returns The URL of the widget's avatar, or null if it doesn't have one. + */ + getAppAvatarUrl(app: IWidget, width?: number, height?: number, resizeMethod?: string): string | null; + + /** + * Checks if a widget is in a specific container in a given room. + * + * @param app - The widget to check. + * @param container - The container to check. + * @param roomId - The room to check in. + * @returns True if the widget is in the specified container, false otherwise. + */ + isAppInContainer(app: IWidget, container: Container, roomId: string): boolean; + + /** + * Moves a widget to a specific container in a given room. + * + * @param app - The widget to move. + * @param container - The container to move the widget to. + * @param roomId - The room to move the widget in. + */ + moveAppToContainer(app: IWidget, container: Container, roomId: string): void; +} diff --git a/packages/element-web-module-api/src/index.ts b/packages/element-web-module-api/src/index.ts index 89c8b24dbd..33b8b92c58 100644 --- a/packages/element-web-module-api/src/index.ts +++ b/packages/element-web-module-api/src/index.ts @@ -23,5 +23,6 @@ export type * from "./api/builtins"; export type * from "./api/stores"; export type * from "./api/client"; export type * from "./api/widget-lifecycle"; +export type * from "./api/widget"; export * from "./api/watchable"; export type * from "./utils"; From a96327b691ff3bcecac2a0710e51f99909ffb184 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 9 Mar 2026 15:48:14 +0000 Subject: [PATCH 2/4] Make matrix-widget-api a devDependency as it's only for the type --- packages/element-web-module-api/package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/element-web-module-api/package.json b/packages/element-web-module-api/package.json index 63a87ad3b2..c00b38855e 100644 --- a/packages/element-web-module-api/package.json +++ b/packages/element-web-module-api/package.json @@ -39,6 +39,7 @@ "@types/semver": "^7.5.8", "@vitest/coverage-v8": "^4.0.0", "matrix-web-i18n": "^3.3.0", + "matrix-widget-api": "^1.17.0", "rollup-plugin-external-globals": "^0.13.0", "semver": "^7.6.3", "typescript": "^5.7.3", @@ -62,7 +63,5 @@ "optional": true } }, - "dependencies": { - "matrix-widget-api": "^1.17.0" - } + "dependencies": {} } From 4591a72d3ac1530f38b67ff84a3488a01131d35e Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 9 Mar 2026 15:51:42 +0000 Subject: [PATCH 3/4] Change to add callback --- packages/element-web-module-api/src/api/extras.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/element-web-module-api/src/api/extras.ts b/packages/element-web-module-api/src/api/extras.ts index 1f6f9818c6..ad437c4986 100644 --- a/packages/element-web-module-api/src/api/extras.ts +++ b/packages/element-web-module-api/src/api/extras.ts @@ -78,9 +78,9 @@ export interface ExtrasApi { getVisibleRoomBySpaceKey(spaceKey: string, cb: () => string[]): void; /** - * Sets the callback to get extra buttons in the room header (which can vary depending on the room being displayed). + * Adds a callback to get extra buttons in the room header (which can vary depending on the room being displayed). * * @param cb - A callback that returns a JSX element representing the buttons (see {@link RoomHeaderButtonsCallback}). */ - setRoomHeaderButtonCallback(cb: RoomHeaderButtonsCallback): void; + addRoomHeaderButtonCallback(cb: RoomHeaderButtonsCallback): void; } From 90ab1534c93102847e78cbc74a952e8da07be4b7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 9 Mar 2026 18:19:05 +0000 Subject: [PATCH 4/4] change back to unix line endings --- .../element-web-module-api.api.md | 1078 ++++++++--------- 1 file changed, 539 insertions(+), 539 deletions(-) diff --git a/packages/element-web-module-api/element-web-module-api.api.md b/packages/element-web-module-api/element-web-module-api.api.md index d64e8bffda..5e32792e81 100644 --- a/packages/element-web-module-api/element-web-module-api.api.md +++ b/packages/element-web-module-api/element-web-module-api.api.md @@ -1,539 +1,539 @@ -## API Report File for "@element-hq/element-web-module-api" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -import { ComponentType } from 'react'; -import { IWidget } from 'matrix-widget-api'; -import { JSX } from 'react'; -import { ModuleApi } from '@matrix-org/react-sdk-module-api'; -import { ReactNode } from 'react'; -import { Root } from 'react-dom/client'; -import { RuntimeModule } from '@matrix-org/react-sdk-module-api'; - -// @public -export interface AccountAuthApiExtension { - overwriteAccountAuth(accountInfo: AccountAuthInfo): Promise; -} - -// @public -export interface AccountAuthInfo { - accessToken: string; - deviceId: string; - homeserverUrl: string; - refreshToken?: string; - userId: string; -} - -// @public -export interface AccountDataApi { - delete(eventType: string): Promise; - get(eventType: string): Watchable; - set(eventType: string, content: unknown): Promise; -} - -// @alpha @deprecated (undocumented) -export interface AliasCustomisations { - // (undocumented) - getDisplayAliasForAliasSet?(canonicalAlias: string | null, altAliases: string[]): string | null; -} - -// Warning: (ae-incompatible-release-tags) The symbol "Api" is marked as @public, but its signature references "LegacyModuleApiExtension" which is marked as @alpha -// Warning: (ae-incompatible-release-tags) The symbol "Api" is marked as @public, but its signature references "LegacyCustomisationsApiExtension" which is marked as @alpha -// -// @public -export interface Api extends LegacyModuleApiExtension, LegacyCustomisationsApiExtension, DialogApiExtension, AccountAuthApiExtension, ProfileApiExtension { - // @alpha - readonly builtins: BuiltinsApi; - readonly client: ClientApi; - readonly config: ConfigApi; - createRoot(element: Element): Root; - // @alpha - readonly customComponents: CustomComponentsApi; - // @alpha - readonly customisations: CustomisationsApi; - // @alpha - readonly extras: ExtrasApi; - readonly i18n: I18nApi; - readonly navigation: NavigationApi; - readonly rootNode: HTMLElement; - readonly stores: StoresApi; - // @alpha - readonly widget: WidgetApi; - // @alpha - readonly widgetLifecycle: WidgetLifecycleApi; -} - -// @alpha -export interface BuiltinsApi { - renderNotificationDecoration(roomId: string): React.ReactNode; - renderRoomAvatar(roomId: string, size?: string): React.ReactNode; - renderRoomView(roomId: string, props?: RoomViewProps): React.ReactNode; -} - -// @alpha -export type CapabilitiesApprover = (widget: WidgetDescriptor, requestedCapabilities: Set) => MaybePromise | undefined>; - -// @alpha @deprecated (undocumented) -export interface ChatExportCustomisations { - getForceChatExportParameters(): { - format?: ExportFormat; - range?: ExportType; - numberOfMessages?: number; - includeAttachments?: boolean; - sizeMb?: number; - }; -} - -// @public -export interface ClientApi { - accountData: AccountDataApi; - getRoom: (id: string) => Room | null; -} - -// @alpha @deprecated (undocumented) -export interface ComponentVisibilityCustomisations { - shouldShowComponent?(component: "UIComponent.sendInvites" | "UIComponent.roomCreation" | "UIComponent.spaceCreation" | "UIComponent.exploreRooms" | "UIComponent.addIntegrations" | "UIComponent.filterContainer" | "UIComponent.roomOptionsMenu"): boolean; -} - -// @public -export interface Config { - // (undocumented) - brand: string; -} - -// @public -export interface ConfigApi { - // (undocumented) - get(): Config; - // (undocumented) - get(key: K): Config[K]; - // (undocumented) - get(key?: K): Config | Config[K]; -} - -// @alpha -export type Container = "top" | "right" | "center"; - -// @alpha -export interface CustomComponentsApi { - registerLoginComponent(renderer: CustomLoginRenderFunction): void; - registerMessageRenderer(eventTypeOrFilter: string | ((mxEvent: MatrixEvent) => boolean), renderer: CustomMessageRenderFunction, hints?: CustomMessageRenderHints): void; - registerRoomPreviewBar(renderer: CustomRoomPreviewBarRenderFunction): void; -} - -// @alpha -export interface CustomisationsApi { - registerShouldShowComponent(fn: (this: void, component: UIComponent) => boolean | void): void; -} - -// @alpha -export type CustomLoginComponentProps = { - serverConfig: CustomLoginComponentPropsServerConfig; - fragmentAfterLogin?: string; - children?: ReactNode; - onLoggedIn(data: AccountAuthInfo): void; - onServerConfigChange(config: CustomLoginComponentPropsServerConfig): void; -}; - -// @alpha -export interface CustomLoginComponentPropsServerConfig { - hsName: string; - hsUrl: string; -} - -// @alpha -export type CustomLoginRenderFunction = ExtendablePropsRenderFunction; - -// @alpha -export type CustomMessageComponentProps = { - mxEvent: MatrixEvent; -}; - -// @alpha -export type CustomMessageRenderFunction = ( -props: CustomMessageComponentProps, -originalComponent?: (props?: OriginalMessageComponentProps) => React.JSX.Element) => JSX.Element; - -// @alpha -export type CustomMessageRenderHints = { - allowEditingEvent?: boolean; - allowDownloadingMedia?: (mxEvent: MatrixEvent) => Promise; -}; - -// @alpha -export type CustomRoomPreviewBarComponentProps = { - roomId?: string; - roomAlias?: string; -}; - -// @alpha -export type CustomRoomPreviewBarRenderFunction = ( -props: CustomRoomPreviewBarComponentProps, -originalComponent: (props: CustomRoomPreviewBarComponentProps) => JSX.Element) => JSX.Element; - -// @public -export interface DialogApiExtension { - openDialog(initialOptions: DialogOptions, dialog: ComponentType

>, props: P): DialogHandle; -} - -// @public -export type DialogHandle = { - finished: Promise<{ - ok: boolean; - model: M | null; - }>; - close(): void; -}; - -// @public -export interface DialogOptions { - title: string; -} - -// @public -export type DialogProps = { - onSubmit(model: M): void; - onCancel(): void; -}; - -// @alpha @deprecated (undocumented) -export interface DirectoryCustomisations { - // (undocumented) - requireCanonicalAliasAccessToPublish?(): boolean; -} - -// @alpha -export type ExtendablePropsRenderFunction =

( -props: P, -originalComponent: (props: P) => JSX.Element) => JSX.Element; - -// @alpha -export interface ExtrasApi { - addRoomHeaderButtonCallback(cb: RoomHeaderButtonsCallback): void; - getVisibleRoomBySpaceKey(spaceKey: string, cb: () => string[]): void; - setSpacePanelItem(spaceKey: string, props: SpacePanelItemProps): void; -} - -// @public -export interface I18nApi { - humanizeTime(this: void, timeMillis: number): string; - get language(): string; - register(this: void, translations: Partial): void; - translate(this: void, key: keyof Translations, variables?: Variables): string; -} - -// @alpha -export type IdentityApprover = (widget: WidgetDescriptor) => MaybePromise; - -// @alpha @deprecated (undocumented) -export type LegacyCustomisations = (customisations: T) => void; - -// @alpha @deprecated (undocumented) -export interface LegacyCustomisationsApiExtension { - // @deprecated (undocumented) - readonly _registerLegacyAliasCustomisations: LegacyCustomisations; - // @deprecated (undocumented) - readonly _registerLegacyChatExportCustomisations: LegacyCustomisations>; - // @deprecated (undocumented) - readonly _registerLegacyComponentVisibilityCustomisations: LegacyCustomisations; - // @deprecated (undocumented) - readonly _registerLegacyDirectoryCustomisations: LegacyCustomisations; - // @deprecated (undocumented) - readonly _registerLegacyLifecycleCustomisations: LegacyCustomisations; - // @deprecated (undocumented) - readonly _registerLegacyMediaCustomisations: LegacyCustomisations>; - // @deprecated (undocumented) - readonly _registerLegacyRoomListCustomisations: LegacyCustomisations>; - // @deprecated (undocumented) - readonly _registerLegacyUserIdentifierCustomisations: LegacyCustomisations; - // @deprecated (undocumented) - readonly _registerLegacyWidgetPermissionsCustomisations: LegacyCustomisations>; - // @deprecated (undocumented) - readonly _registerLegacyWidgetVariablesCustomisations: LegacyCustomisations; -} - -// @alpha @deprecated (undocumented) -export interface LegacyModuleApiExtension { - // @deprecated - _registerLegacyModule(LegacyModule: RuntimeModuleConstructor): Promise; -} - -// @alpha @deprecated (undocumented) -export interface LifecycleCustomisations { - // (undocumented) - onLoggedOutAndStorageCleared?(): void; -} - -// @alpha -export type LocationRenderFunction = () => JSX.Element; - -// @alpha -export interface MatrixEvent { - content: Record; - eventId: string; - originServerTs: number; - roomId: string; - sender: string; - stateKey?: string; - type: string; - unsigned: Record; -} - -// @public -export type MaybePromise = T | PromiseLike; - -// @alpha @deprecated (undocumented) -export interface Media { - // (undocumented) - downloadSource(): Promise; - // (undocumented) - getSquareThumbnailHttp(dim: number): string | null; - // (undocumented) - getThumbnailHttp(width: number, height: number, mode?: "scale" | "crop"): string | null; - // (undocumented) - getThumbnailOfSourceHttp(width: number, height: number, mode?: "scale" | "crop"): string | null; - // (undocumented) - readonly hasThumbnail: boolean; - // (undocumented) - readonly isEncrypted: boolean; - // (undocumented) - readonly srcHttp: string | null; - // (undocumented) - readonly srcMxc: string; - // (undocumented) - readonly thumbnailHttp: string | null; - // (undocumented) - readonly thumbnailMxc: string | null | undefined; -} - -// @alpha @deprecated (undocumented) -export interface MediaContructable { - // (undocumented) - new (prepared: PreparedMedia): Media; -} - -// @alpha @deprecated (undocumented) -export interface MediaCustomisations { - // (undocumented) - readonly Media: MediaContructable; - // (undocumented) - mediaFromContent(content: Content, client?: Client): Media; - // (undocumented) - mediaFromMxc(mxc?: string, client?: Client): Media; -} - -// @public -export interface Module { - // (undocumented) - load(): Promise; -} - -// @public -export interface ModuleFactory { - // (undocumented) - new (api: Api): Module; - // (undocumented) - readonly moduleApiVersion: string; - // (undocumented) - readonly prototype: Module; -} - -// @public -export class ModuleIncompatibleError extends Error { - constructor(pluginVersion: string); -} - -// @public -export class ModuleLoader { - constructor(api: Api); - // Warning: (ae-forgotten-export) The symbol "ModuleExport" needs to be exported by the entry point index.d.ts - // - // (undocumented) - load(moduleExport: ModuleExport): Promise; - // (undocumented) - start(): Promise; -} - -// @public -export interface NavigationApi { - openRoom(roomIdOrAlias: string, opts?: OpenRoomOptions): void; - // @alpha - registerLocationRenderer(path: string, renderer: LocationRenderFunction): void; - toMatrixToLink(link: string, join?: boolean): Promise; -} - -// @public -export interface OpenRoomOptions { - autoJoin?: boolean; - viaServers?: string[]; -} - -// @alpha -export type OriginalMessageComponentProps = { - showUrlPreview?: boolean; -}; - -// @alpha -export type PreloadApprover = (widget: WidgetDescriptor) => MaybePromise; - -// @public -export interface Profile { - displayName?: string; - isGuest?: boolean; - userId?: string; -} - -// @public -export interface ProfileApiExtension { - readonly profile: Watchable; -} - -// @public -export interface Room { - getLastActiveTimestamp: () => number; - id: string; - name: Watchable; -} - -// @alpha -export type RoomHeaderButtonsCallback = (roomId: string) => JSX.Element | undefined; - -// @alpha @deprecated (undocumented) -export interface RoomListCustomisations { - isRoomVisible?(room: Room): boolean; -} - -// @public -export interface RoomListStoreApi { - getRooms(): Watchable; - waitForReady(): Promise; -} - -// @alpha -export interface RoomViewProps { - enableReadReceiptsAndMarkersOnActivity?: boolean; - hideComposer?: boolean; - hideHeader?: boolean; - hidePinnedMessageBanner?: boolean; - hideRightPanel?: boolean; - hideWidgets?: boolean; -} - -// @alpha @deprecated (undocumented) -export type RuntimeModuleConstructor = new (api: ModuleApi) => RuntimeModule; - -// @alpha -export interface SpacePanelItemProps { - className?: string; - icon?: JSX.Element; - label: string; - onSelected: () => void; - style?: React.CSSProperties; - tooltip?: string; -} - -// @public -export interface StoresApi { - roomListStore: RoomListStoreApi; -} - -// @public -export type Translations = Record; - -// @alpha -export const enum UIComponent { - AddIntegrations = "UIComponent.addIntegrations", - CreateRooms = "UIComponent.roomCreation", - CreateSpaces = "UIComponent.spaceCreation", - ExploreRooms = "UIComponent.exploreRooms", - FilterContainer = "UIComponent.filterContainer", - InviteUsers = "UIComponent.sendInvites", - RoomOptionsMenu = "UIComponent.roomOptionsMenu" -} - -// @alpha @deprecated (undocumented) -export interface UserIdentifierCustomisations { - getDisplayUserIdentifier(userId: string, opts: { - roomId?: string; - withDisplayName?: boolean; - }): string | null; -} - -// @public -export function useWatchable(watchable: Watchable): T; - -// @public -export type Variables = { - count?: number; - [key: string]: number | string | undefined; -}; - -// @public -export class Watchable { - constructor(currentValue: T); - // Warning: (ae-forgotten-export) The symbol "WatchFn" needs to be exported by the entry point index.d.ts - // - // (undocumented) - protected readonly listeners: Set>; - protected onFirstWatch(): void; - protected onLastWatch(): void; - // (undocumented) - unwatch(listener: (value: T) => void): void; - get value(): T; - set value(value: T); - // (undocumented) - watch(listener: (value: T) => void): void; -} - -// @alpha -export interface WidgetApi { - getAppAvatarUrl(app: IWidget, width?: number, height?: number, resizeMethod?: string): string | null; - getWidgetsInRoom(roomId: string): IWidget[]; - isAppInContainer(app: IWidget, container: Container, roomId: string): boolean; - moveAppToContainer(app: IWidget, container: Container, roomId: string): void; -} - -// @alpha -export type WidgetDescriptor = { - id: string; - templateUrl: string; - creatorUserId: string; - type: string; - origin: string; - roomId?: string; -}; - -// @alpha -export interface WidgetLifecycleApi { - registerCapabilitiesApprover(approver: CapabilitiesApprover): void; - registerIdentityApprover(approver: IdentityApprover): void; - registerPreloadApprover(approver: PreloadApprover): void; -} - -// @alpha @deprecated (undocumented) -export interface WidgetPermissionsCustomisations { - preapproveCapabilities?(widget: Widget, requestedCapabilities: Set): Promise>; -} - -// @alpha @deprecated (undocumented) -export interface WidgetVariablesCustomisations { - isReady?(): Promise; - provideVariables?(): { - currentUserId: string; - userDisplayName?: string; - userHttpAvatarUrl?: string; - clientId?: string; - clientTheme?: string; - clientLanguage?: string; - deviceId?: string; - baseUrl?: string; - }; -} - -// (No @packageDocumentation comment for this package) - -``` +## API Report File for "@element-hq/element-web-module-api" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ComponentType } from 'react'; +import { IWidget } from 'matrix-widget-api'; +import { JSX } from 'react'; +import { ModuleApi } from '@matrix-org/react-sdk-module-api'; +import { ReactNode } from 'react'; +import { Root } from 'react-dom/client'; +import { RuntimeModule } from '@matrix-org/react-sdk-module-api'; + +// @public +export interface AccountAuthApiExtension { + overwriteAccountAuth(accountInfo: AccountAuthInfo): Promise; +} + +// @public +export interface AccountAuthInfo { + accessToken: string; + deviceId: string; + homeserverUrl: string; + refreshToken?: string; + userId: string; +} + +// @public +export interface AccountDataApi { + delete(eventType: string): Promise; + get(eventType: string): Watchable; + set(eventType: string, content: unknown): Promise; +} + +// @alpha @deprecated (undocumented) +export interface AliasCustomisations { + // (undocumented) + getDisplayAliasForAliasSet?(canonicalAlias: string | null, altAliases: string[]): string | null; +} + +// Warning: (ae-incompatible-release-tags) The symbol "Api" is marked as @public, but its signature references "LegacyModuleApiExtension" which is marked as @alpha +// Warning: (ae-incompatible-release-tags) The symbol "Api" is marked as @public, but its signature references "LegacyCustomisationsApiExtension" which is marked as @alpha +// +// @public +export interface Api extends LegacyModuleApiExtension, LegacyCustomisationsApiExtension, DialogApiExtension, AccountAuthApiExtension, ProfileApiExtension { + // @alpha + readonly builtins: BuiltinsApi; + readonly client: ClientApi; + readonly config: ConfigApi; + createRoot(element: Element): Root; + // @alpha + readonly customComponents: CustomComponentsApi; + // @alpha + readonly customisations: CustomisationsApi; + // @alpha + readonly extras: ExtrasApi; + readonly i18n: I18nApi; + readonly navigation: NavigationApi; + readonly rootNode: HTMLElement; + readonly stores: StoresApi; + // @alpha + readonly widget: WidgetApi; + // @alpha + readonly widgetLifecycle: WidgetLifecycleApi; +} + +// @alpha +export interface BuiltinsApi { + renderNotificationDecoration(roomId: string): React.ReactNode; + renderRoomAvatar(roomId: string, size?: string): React.ReactNode; + renderRoomView(roomId: string, props?: RoomViewProps): React.ReactNode; +} + +// @alpha +export type CapabilitiesApprover = (widget: WidgetDescriptor, requestedCapabilities: Set) => MaybePromise | undefined>; + +// @alpha @deprecated (undocumented) +export interface ChatExportCustomisations { + getForceChatExportParameters(): { + format?: ExportFormat; + range?: ExportType; + numberOfMessages?: number; + includeAttachments?: boolean; + sizeMb?: number; + }; +} + +// @public +export interface ClientApi { + accountData: AccountDataApi; + getRoom: (id: string) => Room | null; +} + +// @alpha @deprecated (undocumented) +export interface ComponentVisibilityCustomisations { + shouldShowComponent?(component: "UIComponent.sendInvites" | "UIComponent.roomCreation" | "UIComponent.spaceCreation" | "UIComponent.exploreRooms" | "UIComponent.addIntegrations" | "UIComponent.filterContainer" | "UIComponent.roomOptionsMenu"): boolean; +} + +// @public +export interface Config { + // (undocumented) + brand: string; +} + +// @public +export interface ConfigApi { + // (undocumented) + get(): Config; + // (undocumented) + get(key: K): Config[K]; + // (undocumented) + get(key?: K): Config | Config[K]; +} + +// @alpha +export type Container = "top" | "right" | "center"; + +// @alpha +export interface CustomComponentsApi { + registerLoginComponent(renderer: CustomLoginRenderFunction): void; + registerMessageRenderer(eventTypeOrFilter: string | ((mxEvent: MatrixEvent) => boolean), renderer: CustomMessageRenderFunction, hints?: CustomMessageRenderHints): void; + registerRoomPreviewBar(renderer: CustomRoomPreviewBarRenderFunction): void; +} + +// @alpha +export interface CustomisationsApi { + registerShouldShowComponent(fn: (this: void, component: UIComponent) => boolean | void): void; +} + +// @alpha +export type CustomLoginComponentProps = { + serverConfig: CustomLoginComponentPropsServerConfig; + fragmentAfterLogin?: string; + children?: ReactNode; + onLoggedIn(data: AccountAuthInfo): void; + onServerConfigChange(config: CustomLoginComponentPropsServerConfig): void; +}; + +// @alpha +export interface CustomLoginComponentPropsServerConfig { + hsName: string; + hsUrl: string; +} + +// @alpha +export type CustomLoginRenderFunction = ExtendablePropsRenderFunction; + +// @alpha +export type CustomMessageComponentProps = { + mxEvent: MatrixEvent; +}; + +// @alpha +export type CustomMessageRenderFunction = ( +props: CustomMessageComponentProps, +originalComponent?: (props?: OriginalMessageComponentProps) => React.JSX.Element) => JSX.Element; + +// @alpha +export type CustomMessageRenderHints = { + allowEditingEvent?: boolean; + allowDownloadingMedia?: (mxEvent: MatrixEvent) => Promise; +}; + +// @alpha +export type CustomRoomPreviewBarComponentProps = { + roomId?: string; + roomAlias?: string; +}; + +// @alpha +export type CustomRoomPreviewBarRenderFunction = ( +props: CustomRoomPreviewBarComponentProps, +originalComponent: (props: CustomRoomPreviewBarComponentProps) => JSX.Element) => JSX.Element; + +// @public +export interface DialogApiExtension { + openDialog(initialOptions: DialogOptions, dialog: ComponentType

>, props: P): DialogHandle; +} + +// @public +export type DialogHandle = { + finished: Promise<{ + ok: boolean; + model: M | null; + }>; + close(): void; +}; + +// @public +export interface DialogOptions { + title: string; +} + +// @public +export type DialogProps = { + onSubmit(model: M): void; + onCancel(): void; +}; + +// @alpha @deprecated (undocumented) +export interface DirectoryCustomisations { + // (undocumented) + requireCanonicalAliasAccessToPublish?(): boolean; +} + +// @alpha +export type ExtendablePropsRenderFunction =

( +props: P, +originalComponent: (props: P) => JSX.Element) => JSX.Element; + +// @alpha +export interface ExtrasApi { + addRoomHeaderButtonCallback(cb: RoomHeaderButtonsCallback): void; + getVisibleRoomBySpaceKey(spaceKey: string, cb: () => string[]): void; + setSpacePanelItem(spaceKey: string, props: SpacePanelItemProps): void; +} + +// @public +export interface I18nApi { + humanizeTime(this: void, timeMillis: number): string; + get language(): string; + register(this: void, translations: Partial): void; + translate(this: void, key: keyof Translations, variables?: Variables): string; +} + +// @alpha +export type IdentityApprover = (widget: WidgetDescriptor) => MaybePromise; + +// @alpha @deprecated (undocumented) +export type LegacyCustomisations = (customisations: T) => void; + +// @alpha @deprecated (undocumented) +export interface LegacyCustomisationsApiExtension { + // @deprecated (undocumented) + readonly _registerLegacyAliasCustomisations: LegacyCustomisations; + // @deprecated (undocumented) + readonly _registerLegacyChatExportCustomisations: LegacyCustomisations>; + // @deprecated (undocumented) + readonly _registerLegacyComponentVisibilityCustomisations: LegacyCustomisations; + // @deprecated (undocumented) + readonly _registerLegacyDirectoryCustomisations: LegacyCustomisations; + // @deprecated (undocumented) + readonly _registerLegacyLifecycleCustomisations: LegacyCustomisations; + // @deprecated (undocumented) + readonly _registerLegacyMediaCustomisations: LegacyCustomisations>; + // @deprecated (undocumented) + readonly _registerLegacyRoomListCustomisations: LegacyCustomisations>; + // @deprecated (undocumented) + readonly _registerLegacyUserIdentifierCustomisations: LegacyCustomisations; + // @deprecated (undocumented) + readonly _registerLegacyWidgetPermissionsCustomisations: LegacyCustomisations>; + // @deprecated (undocumented) + readonly _registerLegacyWidgetVariablesCustomisations: LegacyCustomisations; +} + +// @alpha @deprecated (undocumented) +export interface LegacyModuleApiExtension { + // @deprecated + _registerLegacyModule(LegacyModule: RuntimeModuleConstructor): Promise; +} + +// @alpha @deprecated (undocumented) +export interface LifecycleCustomisations { + // (undocumented) + onLoggedOutAndStorageCleared?(): void; +} + +// @alpha +export type LocationRenderFunction = () => JSX.Element; + +// @alpha +export interface MatrixEvent { + content: Record; + eventId: string; + originServerTs: number; + roomId: string; + sender: string; + stateKey?: string; + type: string; + unsigned: Record; +} + +// @public +export type MaybePromise = T | PromiseLike; + +// @alpha @deprecated (undocumented) +export interface Media { + // (undocumented) + downloadSource(): Promise; + // (undocumented) + getSquareThumbnailHttp(dim: number): string | null; + // (undocumented) + getThumbnailHttp(width: number, height: number, mode?: "scale" | "crop"): string | null; + // (undocumented) + getThumbnailOfSourceHttp(width: number, height: number, mode?: "scale" | "crop"): string | null; + // (undocumented) + readonly hasThumbnail: boolean; + // (undocumented) + readonly isEncrypted: boolean; + // (undocumented) + readonly srcHttp: string | null; + // (undocumented) + readonly srcMxc: string; + // (undocumented) + readonly thumbnailHttp: string | null; + // (undocumented) + readonly thumbnailMxc: string | null | undefined; +} + +// @alpha @deprecated (undocumented) +export interface MediaContructable { + // (undocumented) + new (prepared: PreparedMedia): Media; +} + +// @alpha @deprecated (undocumented) +export interface MediaCustomisations { + // (undocumented) + readonly Media: MediaContructable; + // (undocumented) + mediaFromContent(content: Content, client?: Client): Media; + // (undocumented) + mediaFromMxc(mxc?: string, client?: Client): Media; +} + +// @public +export interface Module { + // (undocumented) + load(): Promise; +} + +// @public +export interface ModuleFactory { + // (undocumented) + new (api: Api): Module; + // (undocumented) + readonly moduleApiVersion: string; + // (undocumented) + readonly prototype: Module; +} + +// @public +export class ModuleIncompatibleError extends Error { + constructor(pluginVersion: string); +} + +// @public +export class ModuleLoader { + constructor(api: Api); + // Warning: (ae-forgotten-export) The symbol "ModuleExport" needs to be exported by the entry point index.d.ts + // + // (undocumented) + load(moduleExport: ModuleExport): Promise; + // (undocumented) + start(): Promise; +} + +// @public +export interface NavigationApi { + openRoom(roomIdOrAlias: string, opts?: OpenRoomOptions): void; + // @alpha + registerLocationRenderer(path: string, renderer: LocationRenderFunction): void; + toMatrixToLink(link: string, join?: boolean): Promise; +} + +// @public +export interface OpenRoomOptions { + autoJoin?: boolean; + viaServers?: string[]; +} + +// @alpha +export type OriginalMessageComponentProps = { + showUrlPreview?: boolean; +}; + +// @alpha +export type PreloadApprover = (widget: WidgetDescriptor) => MaybePromise; + +// @public +export interface Profile { + displayName?: string; + isGuest?: boolean; + userId?: string; +} + +// @public +export interface ProfileApiExtension { + readonly profile: Watchable; +} + +// @public +export interface Room { + getLastActiveTimestamp: () => number; + id: string; + name: Watchable; +} + +// @alpha +export type RoomHeaderButtonsCallback = (roomId: string) => JSX.Element | undefined; + +// @alpha @deprecated (undocumented) +export interface RoomListCustomisations { + isRoomVisible?(room: Room): boolean; +} + +// @public +export interface RoomListStoreApi { + getRooms(): Watchable; + waitForReady(): Promise; +} + +// @alpha +export interface RoomViewProps { + enableReadReceiptsAndMarkersOnActivity?: boolean; + hideComposer?: boolean; + hideHeader?: boolean; + hidePinnedMessageBanner?: boolean; + hideRightPanel?: boolean; + hideWidgets?: boolean; +} + +// @alpha @deprecated (undocumented) +export type RuntimeModuleConstructor = new (api: ModuleApi) => RuntimeModule; + +// @alpha +export interface SpacePanelItemProps { + className?: string; + icon?: JSX.Element; + label: string; + onSelected: () => void; + style?: React.CSSProperties; + tooltip?: string; +} + +// @public +export interface StoresApi { + roomListStore: RoomListStoreApi; +} + +// @public +export type Translations = Record; + +// @alpha +export const enum UIComponent { + AddIntegrations = "UIComponent.addIntegrations", + CreateRooms = "UIComponent.roomCreation", + CreateSpaces = "UIComponent.spaceCreation", + ExploreRooms = "UIComponent.exploreRooms", + FilterContainer = "UIComponent.filterContainer", + InviteUsers = "UIComponent.sendInvites", + RoomOptionsMenu = "UIComponent.roomOptionsMenu" +} + +// @alpha @deprecated (undocumented) +export interface UserIdentifierCustomisations { + getDisplayUserIdentifier(userId: string, opts: { + roomId?: string; + withDisplayName?: boolean; + }): string | null; +} + +// @public +export function useWatchable(watchable: Watchable): T; + +// @public +export type Variables = { + count?: number; + [key: string]: number | string | undefined; +}; + +// @public +export class Watchable { + constructor(currentValue: T); + // Warning: (ae-forgotten-export) The symbol "WatchFn" needs to be exported by the entry point index.d.ts + // + // (undocumented) + protected readonly listeners: Set>; + protected onFirstWatch(): void; + protected onLastWatch(): void; + // (undocumented) + unwatch(listener: (value: T) => void): void; + get value(): T; + set value(value: T); + // (undocumented) + watch(listener: (value: T) => void): void; +} + +// @alpha +export interface WidgetApi { + getAppAvatarUrl(app: IWidget, width?: number, height?: number, resizeMethod?: string): string | null; + getWidgetsInRoom(roomId: string): IWidget[]; + isAppInContainer(app: IWidget, container: Container, roomId: string): boolean; + moveAppToContainer(app: IWidget, container: Container, roomId: string): void; +} + +// @alpha +export type WidgetDescriptor = { + id: string; + templateUrl: string; + creatorUserId: string; + type: string; + origin: string; + roomId?: string; +}; + +// @alpha +export interface WidgetLifecycleApi { + registerCapabilitiesApprover(approver: CapabilitiesApprover): void; + registerIdentityApprover(approver: IdentityApprover): void; + registerPreloadApprover(approver: PreloadApprover): void; +} + +// @alpha @deprecated (undocumented) +export interface WidgetPermissionsCustomisations { + preapproveCapabilities?(widget: Widget, requestedCapabilities: Set): Promise>; +} + +// @alpha @deprecated (undocumented) +export interface WidgetVariablesCustomisations { + isReady?(): Promise; + provideVariables?(): { + currentUserId: string; + userDisplayName?: string; + userHttpAvatarUrl?: string; + clientId?: string; + clientTheme?: string; + clientLanguage?: string; + deviceId?: string; + baseUrl?: string; + }; +} + +// (No @packageDocumentation comment for this package) + +```