From ccf3fcf4af41758dcfead69da6a16359e6a7ef08 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 2 Mar 2026 16:54:23 +0000 Subject: [PATCH] Add API to replace Login component renderer --- .../element-web-module-api.api.md | 26 +++++- .../src/api/custom-components.ts | 83 ++++++++++++++++++- 2 files changed, 107 insertions(+), 2 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 86cce8dfec..43a36a6ca2 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 @@ -7,6 +7,7 @@ import { ComponentType } from 'react'; 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'; @@ -109,10 +110,29 @@ export interface ConfigApi { // @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 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; @@ -171,6 +191,11 @@ export interface DirectoryCustomisations { requireCanonicalAliasAccessToPublish?(): boolean; } +// @alpha +export type ExtendablePropsRenderFunction =

( +props: P, +originalComponent: (props: P) => JSX.Element) => JSX.Element; + // @alpha export interface ExtrasApi { getVisibleRoomBySpaceKey(spaceKey: string, cb: () => string[]): void; @@ -476,4 +501,3 @@ export interface WidgetVariablesCustomisations { // (No @packageDocumentation comment for this package) ``` - diff --git a/packages/element-web-module-api/src/api/custom-components.ts b/packages/element-web-module-api/src/api/custom-components.ts index faba9c02cb..0265c9c63d 100644 --- a/packages/element-web-module-api/src/api/custom-components.ts +++ b/packages/element-web-module-api/src/api/custom-components.ts @@ -5,8 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ -import type { JSX } from "react"; +import type { JSX, ReactNode } from "react"; import type { MatrixEvent } from "../models/event"; +import type { AccountAuthInfo } from "./auth.ts"; /** * Properties for all message components. @@ -91,6 +92,71 @@ export type CustomRoomPreviewBarRenderFunction = ( originalComponent: (props: CustomRoomPreviewBarComponentProps) => JSX.Element, ) => JSX.Element; +/** + * Authentication server config object. + * @alpha Subject to change. + */ +export interface CustomLoginComponentPropsServerConfig { + /** + * The URL of the homeserver's client-server API + */ + hsUrl: string; + /** + * The name of the homeserver to present to the user + */ + hsName: string; +} + +/** + * Properties for login component. + * @alpha Subject to change. + */ +export type CustomLoginComponentProps = { + /** + * The details of the currently chosen Matrix homeserver + */ + serverConfig: CustomLoginComponentPropsServerConfig; + /** + * The URL fragment to send the user to after authentication is complete + */ + fragmentAfterLogin?: string; + /** + * Additional components to render as children + */ + children?: ReactNode; + /** + * Function to complete login + * @param data - the data to authenticate the user with + */ + onLoggedIn(data: AccountAuthInfo): void; + /** + * Function to change the selected server + * @param config - new server configuration details + */ + onServerConfigChange(config: CustomLoginComponentPropsServerConfig): void; +}; + +/** + * Function used to render a component with a superset of the known props. + * @alpha Unlikely to change + */ +export type ExtendablePropsRenderFunction =

( + /** + * Properties for the component to be rendered. + */ + props: P, + /** + * Render function for the original component. + */ + originalComponent: (props: P) => JSX.Element, +) => JSX.Element; + +/** + * Function used to render a login component. + * @alpha Unlikely to change + */ +export type CustomLoginRenderFunction = ExtendablePropsRenderFunction; + /** * API for inserting custom components into Element. * @alpha Subject to change. @@ -143,4 +209,19 @@ export interface CustomComponentsApi { * ``` */ registerRoomPreviewBar(renderer: CustomRoomPreviewBarRenderFunction): void; + + /** + * Register a renderer for the login component. + * + * The render function should return a rendered component. + * + * @param renderer - The render function for the login component. + * @example + * ``` + * customComponents.registerLoginComponent((props, OriginalComponent) => { + * return ; + * }); + * ``` + */ + registerLoginComponent(renderer: CustomLoginRenderFunction): void; }