Compare commits

...
Sign in to create a new pull request.

5 commits

Author SHA1 Message Date
Michael Telatynski
4f14d3f5ae
Stash
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-06 11:41:40 +00:00
Michael Telatynski
62c765bfd3
Fix React class constructor signature to not pass context
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-06 11:41:32 +00:00
Michael Telatynski
983db465c3
Fix react function refs returning things
This is incompatible with React 19

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-06 11:37:57 +00:00
Michael Telatynski
c299d2a0d1
Codemod
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-06 00:15:08 +00:00
Michael Telatynski
a9a3751f3e
Upgrade to React 19
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-06 00:01:50 +00:00
313 changed files with 750 additions and 663 deletions

View file

@ -71,9 +71,13 @@
"update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js" "update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js"
}, },
"resolutions": { "resolutions": {
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"oidc-client-ts": "3.1.0", "oidc-client-ts": "3.1.0",
"jwt-decode": "4.0.0", "jwt-decode": "4.0.0",
"caniuse-lite": "1.0.30001684", "caniuse-lite": "1.0.30001684",
"react": "19.0.0",
"react-dom": "19.0.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0",
"wrap-ansi": "npm:wrap-ansi@^7.0.0" "wrap-ansi": "npm:wrap-ansi@^7.0.0"
}, },
@ -135,10 +139,10 @@
"posthog-js": "1.157.2", "posthog-js": "1.157.2",
"qrcode": "1.5.4", "qrcode": "1.5.4",
"re-resizable": "6.10.1", "re-resizable": "6.10.1",
"react": "^18.3.1", "react": "^19",
"react-beautiful-dnd": "^13.1.0", "react-beautiful-dnd": "^13.1.0",
"react-blurhash": "^0.3.0", "react-blurhash": "^0.3.0",
"react-dom": "^18.3.1", "react-dom": "^19",
"react-focus-lock": "^2.5.1", "react-focus-lock": "^2.5.1",
"react-transition-group": "^4.4.1", "react-transition-group": "^4.4.1",
"rfc4648": "^1.4.0", "rfc4648": "^1.4.0",
@ -179,7 +183,7 @@
"@svgr/webpack": "^8.0.0", "@svgr/webpack": "^8.0.0",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.4.8", "@testing-library/jest-dom": "^6.4.8",
"@testing-library/react": "^16.0.0", "@testing-library/react": "^16.1.0",
"@testing-library/user-event": "^14.5.2", "@testing-library/user-event": "^14.5.2",
"@types/commonmark": "^0.27.4", "@types/commonmark": "^0.27.4",
"@types/counterpart": "^0.18.1", "@types/counterpart": "^0.18.1",
@ -201,9 +205,9 @@
"@types/node-fetch": "^2.6.2", "@types/node-fetch": "^2.6.2",
"@types/pako": "^2.0.0", "@types/pako": "^2.0.0",
"@types/qrcode": "^1.3.5", "@types/qrcode": "^1.3.5",
"@types/react": "18.3.3", "@types/react": "^19",
"@types/react-beautiful-dnd": "^13.0.0", "@types/react-beautiful-dnd": "^13.0.0",
"@types/react-dom": "18.3.1", "@types/react-dom": "^19",
"@types/react-transition-group": "^4.4.0", "@types/react-transition-group": "^4.4.0",
"@types/sanitize-html": "2.13.0", "@types/sanitize-html": "2.13.0",
"@types/semver": "^7.5.8", "@types/semver": "^7.5.8",

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import { JSXElementConstructor } from "react"; import { JSXElementConstructor, type JSX } from "react";
export type { NonEmptyArray, XOR, Writeable } from "matrix-js-sdk/src/matrix"; export type { NonEmptyArray, XOR, Writeable } from "matrix-js-sdk/src/matrix";

11
src/@types/react.d.ts vendored
View file

@ -11,9 +11,14 @@ import React, { PropsWithChildren } from "react";
declare module "react" { declare module "react" {
// Fix forwardRef types for Generic components - https://stackoverflow.com/a/58473012 // Fix forwardRef types for Generic components - https://stackoverflow.com/a/58473012
function forwardRef<T, P = {}>( function forwardRef<T, P = {}>(
render: (props: PropsWithChildren<P>, ref: React.ForwardedRef<T>) => React.ReactElement | null, render: (props: PropsWithChildren<P>, ref: React.ForwardedRef<T>) => React.ReactElement<any> | null,
): (props: P & React.RefAttributes<T>) => React.ReactElement | null; ): (props: P & React.RefAttributes<T>) => React.ReactElement<any> | null;
// Fix lazy types - https://stackoverflow.com/a/71017028 // Fix lazy types - https://stackoverflow.com/a/71017028
function lazy<T extends ComponentType<any>>(factory: () => Promise<{ default: T }>): T; // function lazy<T extends ComponentType<any>>(factory: () => Promise<{ default: T }>): T;
// Workaround for generics in React 19
interface FunctionComponent {
defaultProps?: {};
}
} }

View file

@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { LegacyRef, ReactNode } from "react"; import React, { Ref, ReactNode, type JSX } from "react";
import sanitizeHtml from "sanitize-html"; import sanitizeHtml from "sanitize-html";
import classNames from "classnames"; import classNames from "classnames";
import katex from "katex"; import katex from "katex";
@ -503,7 +503,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
export function topicToHtml( export function topicToHtml(
topic?: string, topic?: string,
htmlTopic?: string, htmlTopic?: string,
ref?: LegacyRef<HTMLSpanElement>, ref?: Ref<HTMLSpanElement>,
allowExtendedHtml = false, allowExtendedHtml = false,
): ReactNode { ): ReactNode {
if (!SettingsStore.getValue("feature_html_topic")) { if (!SettingsStore.getValue("feature_html_topic")) {

View file

@ -205,7 +205,7 @@ export const sanitizeHtmlParams: IExtendedSanitizeOptions = {
}; };
/* Wrapper around linkify-react merging in our default linkify options */ /* Wrapper around linkify-react merging in our default linkify options */
export function Linkify({ as, options, children }: React.ComponentProps<typeof _Linkify>): ReactElement { export function Linkify({ as, options, children }: React.ComponentProps<typeof _Linkify>): ReactElement<any> {
return ( return (
<_Linkify as={as} options={merge({}, linkifyMatrixOptions, options)}> <_Linkify as={as} options={merge({}, linkifyMatrixOptions, options)}>
{children} {children}

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { Key, MutableRefObject, ReactElement, RefCallback } from "react"; import React, { HTMLAttributes, Key, MutableRefObject, ReactElement, RefCallback } from "react";
interface IChildProps { interface IChildProps {
style: React.CSSProperties; style: React.CSSProperties;
@ -23,7 +23,7 @@ interface IProps {
innerRef?: MutableRefObject<any>; innerRef?: MutableRefObject<any>;
} }
function isReactElement(c: ReturnType<(typeof React.Children)["toArray"]>[number]): c is ReactElement { function isReactElement(c: ReturnType<(typeof React.Children)["toArray"]>[number]): c is ReactElement<any> {
return typeof c === "object" && "type" in c; return typeof c === "object" && "type" in c;
} }
@ -36,7 +36,7 @@ function isReactElement(c: ReturnType<(typeof React.Children)["toArray"]>[number
*/ */
export default class NodeAnimator extends React.Component<IProps> { export default class NodeAnimator extends React.Component<IProps> {
private nodes: Record<string, HTMLElement> = {}; private nodes: Record<string, HTMLElement> = {};
private children: { [key: string]: ReactElement } = {}; private children: { [key: string]: ReactElement<any> } = {};
public static defaultProps: Partial<IProps> = { public static defaultProps: Partial<IProps> = {
startStyles: [], startStyles: [],
}; };
@ -68,21 +68,22 @@ export default class NodeAnimator extends React.Component<IProps> {
this.children = {}; this.children = {};
React.Children.toArray(newChildren).forEach((c) => { React.Children.toArray(newChildren).forEach((c) => {
if (!isReactElement(c)) return; if (!isReactElement(c)) return;
const props = c.props as HTMLAttributes<HTMLElement>;
if (oldChildren[c.key!]) { if (oldChildren[c.key!]) {
const old = oldChildren[c.key!]; const old = oldChildren[c.key!];
const oldNode = this.nodes[old.key!]; const oldNode = this.nodes[old.key!];
if (oldNode && oldNode.style.left !== c.props.style.left) { if (oldNode && oldNode.style.left !== props.style!.left) {
this.applyStyles(oldNode, { left: c.props.style.left }); this.applyStyles(oldNode, { left: props.style!.left });
} }
// clone the old element with the props (and children) of the new element // clone the old element with the props (and children) of the new element
// so prop updates are still received by the children. // so prop updates are still received by the children.
this.children[c.key!] = React.cloneElement(old, c.props, c.props.children); this.children[c.key!] = React.cloneElement(old, props, props.children);
} else { } else {
// new element. If we have a startStyle, use that as the style and go through // new element. If we have a startStyle, use that as the style and go through
// the enter animations // the enter animations
const newProps: Partial<IChildProps> = {}; const newProps: Partial<IChildProps> = {};
const restingStyle = c.props.style; const restingStyle = props.style!;
const startStyles = this.props.startStyles; const startStyles = this.props.startStyles;
if (startStyles.length > 0) { if (startStyles.length > 0) {

View file

@ -212,7 +212,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({
scrollIntoView, scrollIntoView,
onKeyDown, onKeyDown,
}) => { }) => {
const [state, dispatch] = useReducer<Reducer<IState, Action>>(reducer, { const [state, dispatch] = useReducer(reducer, {
nodes: [], nodes: [],
}); });
@ -354,7 +354,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({
* nodeRef = inputRef when inputRef argument is provided. * nodeRef = inputRef when inputRef argument is provided.
*/ */
export const useRovingTabIndex = <T extends HTMLElement>( export const useRovingTabIndex = <T extends HTMLElement>(
inputRef?: RefObject<T>, inputRef?: RefObject<T | null>,
): [FocusHandler, boolean, RefCallback<T>, RefObject<T | null>] => { ): [FocusHandler, boolean, RefCallback<T>, RefObject<T | null>] => {
const context = useContext(RovingTabIndexContext); const context = useContext(RovingTabIndexContext);

View file

@ -12,21 +12,21 @@ import React, { ComponentProps, forwardRef, Ref } from "react";
import AccessibleButton from "../../components/views/elements/AccessibleButton"; import AccessibleButton from "../../components/views/elements/AccessibleButton";
type Props<T extends keyof JSX.IntrinsicElements> = ComponentProps<typeof AccessibleButton<T>> & { type Props<T extends React.ElementType> = ComponentProps<typeof AccessibleButton<T>> & {
label?: string; label?: string;
// whether the context menu is currently open // whether the context menu is currently open
isExpanded: boolean; isExpanded: boolean;
}; };
// Semantic component for representing the AccessibleButton which launches a <ContextMenu /> // Semantic component for representing the AccessibleButton which launches a <ContextMenu />
export const ContextMenuButton = forwardRef(function <T extends keyof JSX.IntrinsicElements>( export const ContextMenuButton = forwardRef(function <T extends React.ElementType>(
{ label, isExpanded, children, onClick, onContextMenu, element, ...props }: Props<T>, { label, isExpanded, children, onClick, onContextMenu, element, ...props }: Props<T>,
ref: Ref<HTMLElement>, ref: Ref<HTMLElement>,
) { ) {
return ( return (
<AccessibleButton <AccessibleButton
{...props} {...props}
element={element as keyof JSX.IntrinsicElements} element={element as React.ElementType}
onClick={onClick} onClick={onClick}
onContextMenu={onContextMenu ?? onClick ?? undefined} onContextMenu={onContextMenu ?? onClick ?? undefined}
aria-label={label} aria-label={label}

View file

@ -12,20 +12,20 @@ import React, { ComponentProps, forwardRef, Ref } from "react";
import AccessibleButton from "../../components/views/elements/AccessibleButton"; import AccessibleButton from "../../components/views/elements/AccessibleButton";
type Props<T extends keyof JSX.IntrinsicElements> = ComponentProps<typeof AccessibleButton<T>> & { type Props<T extends React.ElementType> = ComponentProps<typeof AccessibleButton<T>> & {
// whether the context menu is currently open // whether the context menu is currently open
isExpanded: boolean; isExpanded: boolean;
}; };
// Semantic component for representing the AccessibleButton which launches a <ContextMenu /> // Semantic component for representing the AccessibleButton which launches a <ContextMenu />
export const ContextMenuTooltipButton = forwardRef(function <T extends keyof JSX.IntrinsicElements>( export const ContextMenuTooltipButton = forwardRef(function <T extends React.ElementType>(
{ isExpanded, children, onClick, onContextMenu, element, ...props }: Props<T>, { isExpanded, children, onClick, onContextMenu, element, ...props }: Props<T>,
ref: Ref<HTMLElement>, ref: Ref<HTMLElement>,
) { ) {
return ( return (
<AccessibleButton <AccessibleButton
{...props} {...props}
element={element as keyof JSX.IntrinsicElements} element={element as React.ElementType}
onClick={onClick} onClick={onClick}
onContextMenu={onContextMenu ?? onClick ?? undefined} onContextMenu={onContextMenu ?? onClick ?? undefined}
aria-haspopup={true} aria-haspopup={true}

View file

@ -8,16 +8,20 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { RovingAccessibleButton } from "../RovingTabIndex"; import { RovingAccessibleButton } from "../RovingTabIndex";
interface IProps extends React.ComponentProps<typeof RovingAccessibleButton> { type IProps<T extends keyof JSX.IntrinsicElements> = React.ComponentProps<typeof RovingAccessibleButton<T>> & {
label?: string; label?: string;
} };
// Semantic component for representing a role=menuitem // Semantic component for representing a role=menuitem
export const MenuItem: React.FC<IProps> = ({ children, label, ...props }) => { export const MenuItem = <T extends keyof JSX.IntrinsicElements>({
children,
label,
...props
}: IProps<T>): JSX.Element => {
const ariaLabel = props["aria-label"] || label; const ariaLabel = props["aria-label"] || label;
return ( return (

View file

@ -6,22 +6,19 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ComponentProps } from "react"; import React, { ComponentProps, type JSX } from "react";
import AccessibleButton from "../../components/views/elements/AccessibleButton"; import AccessibleButton from "../../components/views/elements/AccessibleButton";
import { useRovingTabIndex } from "../RovingTabIndex"; import { useRovingTabIndex } from "../RovingTabIndex";
import { Ref } from "./types"; import { Ref } from "./types";
type Props<T extends keyof JSX.IntrinsicElements> = Omit< type Props<T extends React.ElementType> = Omit<ComponentProps<typeof AccessibleButton<T>>, "inputRef" | "tabIndex"> & {
ComponentProps<typeof AccessibleButton<T>>,
"inputRef" | "tabIndex"
> & {
inputRef?: Ref; inputRef?: Ref;
focusOnMouseOver?: boolean; focusOnMouseOver?: boolean;
}; };
// Wrapper to allow use of useRovingTabIndex for simple AccessibleButtons outside of React Functional Components. // Wrapper to allow use of useRovingTabIndex for simple AccessibleButtons outside of React Functional Components.
export const RovingAccessibleButton = <T extends keyof JSX.IntrinsicElements>({ export const RovingAccessibleButton = <T extends React.ElementType>({
inputRef, inputRef,
onFocus, onFocus,
onMouseOver, onMouseOver,
@ -33,7 +30,7 @@ export const RovingAccessibleButton = <T extends keyof JSX.IntrinsicElements>({
return ( return (
<AccessibleButton <AccessibleButton
{...props} {...props}
element={element as keyof JSX.IntrinsicElements} element={element as React.ElementType}
onFocus={(event: React.FocusEvent) => { onFocus={(event: React.FocusEvent) => {
onFocusInternal(); onFocusInternal();
onFocus?.(event); onFocus?.(event);

View file

@ -8,6 +8,6 @@ Please see LICENSE files in the repository root for full details.
import { RefObject } from "react"; import { RefObject } from "react";
export type Ref = RefObject<HTMLElement>; export type Ref = RefObject<HTMLElement | null>;
export type FocusHandler = () => void; export type FocusHandler = () => void;

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ReactNode } from "react"; import React, { ReactNode, type JSX } from "react";
import { Text, Heading, Button, Separator } from "@vector-im/compound-web"; import { Text, Heading, Button, Separator } from "@vector-im/compound-web";
import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out"; import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out";

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClientPeg } from "../../../../MatrixClientPeg"; import { MatrixClientPeg } from "../../../../MatrixClientPeg";

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef } from "react"; import React, { createRef, type JSX } from "react";
import FileSaver from "file-saver"; import FileSaver from "file-saver";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { AuthDict, CrossSigningKeys, MatrixError, UIAFlow, UIAResponse } from "matrix-js-sdk/src/matrix"; import { AuthDict, CrossSigningKeys, MatrixError, UIAFlow, UIAResponse } from "matrix-js-sdk/src/matrix";

View file

@ -178,7 +178,9 @@ export default class ExportE2eKeysDialog extends React.Component<IProps, IState>
type="password" type="password"
disabled={disableForm} disabled={disableForm}
autoComplete="new-password" autoComplete="new-password"
fieldRef={(field) => (this.fieldPassword = field)} fieldRef={(field) => {
this.fieldPassword = field;
}}
/> />
</div> </div>
<div className="mx_E2eKeysDialog_inputRow"> <div className="mx_E2eKeysDialog_inputRow">
@ -195,7 +197,9 @@ export default class ExportE2eKeysDialog extends React.Component<IProps, IState>
type="password" type="password"
disabled={disableForm} disabled={disableForm}
autoComplete="new-password" autoComplete="new-password"
fieldRef={(field) => (this.fieldPasswordConfirm = field)} fieldRef={(field) => {
this.fieldPasswordConfirm = field;
}}
/> />
</div> </div>
</div> </div>

View file

@ -30,7 +30,7 @@ export interface ICompletion {
type?: "at-room" | "command" | "community" | "room" | "user"; type?: "at-room" | "command" | "community" | "room" | "user";
completion: string; completion: string;
completionId?: string; completionId?: string;
component: ReactElement; component: ReactElement<any>;
range: ISelectionRange; range: ISelectionRange;
command?: string; command?: string;
suffix?: string; suffix?: string;

View file

@ -8,16 +8,11 @@ Please see LICENSE files in the repository root for full details.
*/ */
import classNames from "classnames"; import classNames from "classnames";
import React, { HTMLAttributes, ReactHTML, ReactNode, WheelEvent } from "react"; import React, { ReactNode, WheelEvent } from "react";
type DynamicHtmlElementProps<T extends keyof JSX.IntrinsicElements> = export type IProps<T extends React.ElementType> = React.ComponentPropsWithoutRef<T> & {
JSX.IntrinsicElements[T] extends HTMLAttributes<{}> ? DynamicElementProps<T> : DynamicElementProps<"div">; element?: T;
type DynamicElementProps<T extends keyof JSX.IntrinsicElements> = Partial<Omit<JSX.IntrinsicElements[T], "ref">>;
export type IProps<T extends keyof JSX.IntrinsicElements> = Omit<DynamicHtmlElementProps<T>, "onScroll"> & {
element: T;
className?: string; className?: string;
onScroll?: (event: Event) => void;
onWheel?: (event: WheelEvent) => void; onWheel?: (event: WheelEvent) => void;
style?: React.CSSProperties; style?: React.CSSProperties;
tabIndex?: number; tabIndex?: number;
@ -25,12 +20,8 @@ export type IProps<T extends keyof JSX.IntrinsicElements> = Omit<DynamicHtmlElem
children: ReactNode; children: ReactNode;
}; };
export default class AutoHideScrollbar<T extends keyof JSX.IntrinsicElements> extends React.Component<IProps<T>> { export default class AutoHideScrollbar<T extends React.ElementType> extends React.Component<IProps<T>> {
public static defaultProps = { public readonly containerRef: React.RefObject<HTMLDivElement | null> = React.createRef();
element: "div" as keyof ReactHTML,
};
public readonly containerRef: React.RefObject<HTMLDivElement> = React.createRef();
public componentDidMount(): void { public componentDidMount(): void {
if (this.containerRef.current && this.props.onScroll) { if (this.containerRef.current && this.props.onScroll) {
@ -55,7 +46,7 @@ export default class AutoHideScrollbar<T extends keyof JSX.IntrinsicElements> ex
const { element, className, onScroll, tabIndex, wrappedRef, children, ...otherProps } = this.props; const { element, className, onScroll, tabIndex, wrappedRef, children, ...otherProps } = this.props;
return React.createElement( return React.createElement(
element, element ?? "div",
{ {
...otherProps, ...otherProps,
ref: this.containerRef, ref: this.containerRef,

View file

@ -22,8 +22,8 @@ interface AutocompleteInputProps {
selection: ICompletion[]; selection: ICompletion[];
onSelectionChange: (selection: ICompletion[]) => void; onSelectionChange: (selection: ICompletion[]) => void;
maxSuggestions?: number; maxSuggestions?: number;
renderSuggestion?: (s: ICompletion) => ReactElement; renderSuggestion?: (s: ICompletion) => ReactElement<any>;
renderSelection?: (m: ICompletion) => ReactElement; renderSelection?: (m: ICompletion) => ReactElement<any>;
additionalFilter?: (suggestion: ICompletion) => boolean; additionalFilter?: (suggestion: ICompletion) => boolean;
} }
@ -163,11 +163,11 @@ export const AutocompleteInput: React.FC<AutocompleteInputProps> = ({
type SelectionItemProps = { type SelectionItemProps = {
item: ICompletion; item: ICompletion;
onClick: (completion: ICompletion) => void; onClick: (completion: ICompletion) => void;
render?: (completion: ICompletion) => ReactElement; render?: (completion: ICompletion) => ReactElement<any>;
}; };
const SelectionItem: React.FC<SelectionItemProps> = ({ item, onClick, render }) => { const SelectionItem: React.FC<SelectionItemProps> = ({ item, onClick, render }) => {
const withContainer = (children: ReactNode): ReactElement => ( const withContainer = (children: ReactNode): ReactElement<any> => (
<span <span
className="mx_AutocompleteInput_editor_selection" className="mx_AutocompleteInput_editor_selection"
data-testid={`autocomplete-selection-item-${item.completionId}`} data-testid={`autocomplete-selection-item-${item.completionId}`}
@ -194,7 +194,7 @@ type SuggestionItemProps = {
item: ICompletion; item: ICompletion;
selection: ICompletion[]; selection: ICompletion[];
onClick: (completion: ICompletion) => void; onClick: (completion: ICompletion) => void;
render?: (completion: ICompletion) => ReactElement; render?: (completion: ICompletion) => ReactElement<any>;
}; };
const SuggestionItem: React.FC<SuggestionItemProps> = ({ item, selection, onClick, render }) => { const SuggestionItem: React.FC<SuggestionItemProps> = ({ item, selection, onClick, render }) => {
@ -204,7 +204,7 @@ const SuggestionItem: React.FC<SuggestionItemProps> = ({ item, selection, onClic
"mx_AutocompleteInput_suggestion--selected": isSelected, "mx_AutocompleteInput_suggestion--selected": isSelected,
}); });
const withContainer = (children: ReactNode): ReactElement => ( const withContainer = (children: ReactNode): ReactElement<any> => (
<div <div
className={classes} className={classes}
// `onClick` cannot be used here as it would lead to focus loss and closing the suggestion list. // `onClick` cannot be used here as it would lead to focus loss and closing the suggestion list.

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { CSSProperties, RefObject, SyntheticEvent, useRef, useState } from "react"; import React, { CSSProperties, RefObject, SyntheticEvent, useRef, useState, type JSX } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import classNames from "classnames"; import classNames from "classnames";
import FocusLock from "react-focus-lock"; import FocusLock from "react-focus-lock";
@ -440,7 +440,7 @@ export default class ContextMenu extends React.PureComponent<React.PropsWithChil
); );
} }
public render(): React.ReactChild { public render(): JSX.Element {
if (this.props.mountAsChild) { if (this.props.mountAsChild) {
// Render as a child of the current parent // Render as a child of the current parent
return this.renderMenu(); return this.renderMenu();
@ -582,13 +582,13 @@ export const alwaysAboveRightOf = (
type ContextMenuTuple<T> = [ type ContextMenuTuple<T> = [
boolean, boolean,
RefObject<T>, RefObject<T | null>,
(ev?: SyntheticEvent) => void, (ev?: SyntheticEvent) => void,
(ev?: SyntheticEvent) => void, (ev?: SyntheticEvent) => void,
(val: boolean) => void, (val: boolean) => void,
]; ];
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint
export const useContextMenu = <T extends any = HTMLElement>(inputRef?: RefObject<T>): ContextMenuTuple<T> => { export const useContextMenu = <T extends any = HTMLElement>(inputRef?: RefObject<T | null>): ContextMenuTuple<T> => {
let button = useRef<T>(null); let button = useRef<T>(null);
if (inputRef) { if (inputRef) {
// if we are given a ref, use it instead of ours // if we are given a ref, use it instead of ours

View file

@ -40,8 +40,8 @@ export default class EmbeddedPage extends React.PureComponent<IProps, IState> {
private unmounted = false; private unmounted = false;
private dispatcherRef?: string; private dispatcherRef?: string;
public constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.state = { this.state = {
page: "", page: "",

View file

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import classNames from "classnames"; import classNames from "classnames";
import React, { FunctionComponent, Key, PropsWithChildren, ReactNode } from "react"; import React, { FunctionComponent, Key, PropsWithChildren, ReactNode, type JSX } from "react";
import { MenuItemRadio } from "../../accessibility/context_menu/MenuItemRadio"; import { MenuItemRadio } from "../../accessibility/context_menu/MenuItemRadio";
import { ButtonEvent } from "../views/elements/AccessibleButton"; import { ButtonEvent } from "../views/elements/AccessibleButton";

View file

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import * as React from "react"; import * as React from "react";
import { useContext, useState } from "react"; import { useContext, useState, type JSX } from "react";
import AutoHideScrollbar from "./AutoHideScrollbar"; import AutoHideScrollbar from "./AutoHideScrollbar";
import { getHomePageUrl } from "../../utils/pages"; import { getHomePageUrl } from "../../utils/pages";

View file

@ -5,13 +5,12 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef } from "react"; import React, { ComponentProps, createRef } from "react";
import AutoHideScrollbar, { IProps as AutoHideScrollbarProps } from "./AutoHideScrollbar"; import AutoHideScrollbar from "./AutoHideScrollbar";
import UIStore, { UI_EVENTS } from "../../stores/UIStore"; import UIStore, { UI_EVENTS } from "../../stores/UIStore";
export type IProps<T extends keyof JSX.IntrinsicElements> = Omit<AutoHideScrollbarProps<T>, "onWheel" | "element"> & { export type IProps<T extends React.ElementType> = Omit<ComponentProps<typeof AutoHideScrollbar<T>>, "onWheel"> & {
element?: T;
// If true, the scrollbar will append mx_IndicatorScrollbar_leftOverflowIndicator // If true, the scrollbar will append mx_IndicatorScrollbar_leftOverflowIndicator
// and mx_IndicatorScrollbar_rightOverflowIndicator elements to the list for positioning // and mx_IndicatorScrollbar_rightOverflowIndicator elements to the list for positioning
// by the parent element. // by the parent element.
@ -30,10 +29,7 @@ interface IState {
rightIndicatorOffset: string; rightIndicatorOffset: string;
} }
export default class IndicatorScrollbar<T extends keyof JSX.IntrinsicElements> extends React.Component< export default class IndicatorScrollbar<T extends React.ElementType> extends React.Component<IProps<T>, IState> {
IProps<T>,
IState
> {
private autoHideScrollbar = createRef<AutoHideScrollbar<any>>(); private autoHideScrollbar = createRef<AutoHideScrollbar<any>>();
private scrollElement?: HTMLDivElement; private scrollElement?: HTMLDivElement;
private likelyTrackpadUser: boolean | null = null; private likelyTrackpadUser: boolean | null = null;

View file

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import * as React from "react"; import * as React from "react";
import { createRef } from "react"; import { createRef, type JSX } from "react";
import classNames from "classnames"; import classNames from "classnames";
import dis from "../../dispatcher/dispatcher"; import dis from "../../dispatcher/dispatcher";

View file

@ -123,9 +123,9 @@ class LoggedInView extends React.Component<IProps, IState> {
public static displayName = "LoggedInView"; public static displayName = "LoggedInView";
protected readonly _matrixClient: MatrixClient; protected readonly _matrixClient: MatrixClient;
protected readonly _roomView: React.RefObject<RoomView>; protected readonly _roomView: React.RefObject<RoomView | null>;
protected readonly _resizeContainer: React.RefObject<HTMLDivElement>; protected readonly _resizeContainer: React.RefObject<HTMLDivElement | null>;
protected readonly resizeHandler: React.RefObject<HTMLDivElement>; protected readonly resizeHandler: React.RefObject<HTMLDivElement | null>;
protected layoutWatcherRef?: string; protected layoutWatcherRef?: string;
protected compactLayoutWatcherRef?: string; protected compactLayoutWatcherRef?: string;
protected backgroundImageWatcherRef?: string; protected backgroundImageWatcherRef?: string;

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ReactNode } from "react"; import React, { ReactNode, type JSX } from "react";
import { NumberSize, Resizable } from "re-resizable"; import { NumberSize, Resizable } from "re-resizable";
import { Direction } from "re-resizable/lib/resizer"; import { Direction } from "re-resizable/lib/resizer";
import { WebPanelResize } from "@matrix-org/analytics-events/types/typescript/WebPanelResize"; import { WebPanelResize } from "@matrix-org/analytics-events/types/typescript/WebPanelResize";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef, lazy } from "react"; import React, { createRef, lazy, type JSX } from "react";
import { import {
ClientEvent, ClientEvent,
createClient, createClient,

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef, ReactNode, TransitionEvent } from "react"; import React, { createRef, ReactNode, TransitionEvent, type JSX } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { Room, MatrixClient, RoomStateEvent, EventStatus, MatrixEvent, EventType } from "matrix-js-sdk/src/matrix"; import { Room, MatrixClient, RoomStateEvent, EventStatus, MatrixEvent, EventType } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
@ -252,8 +252,8 @@ export default class MessagePanel extends React.Component<IProps, IState> {
// A map to allow groupers to maintain consistent keys even if their first event is uprooted due to back-pagination. // A map to allow groupers to maintain consistent keys even if their first event is uprooted due to back-pagination.
public grouperKeyMap = new WeakMap<MatrixEvent, string>(); public grouperKeyMap = new WeakMap<MatrixEvent, string>();
public constructor(props: IProps, context: React.ContextType<typeof RoomContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.state = { this.state = {
// previous positions the read marker has been in, so we can // previous positions the read marker has been in, so we can

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import NotificationsIcon from "@vector-im/compound-design-tokens/assets/web/icons/notifications"; import NotificationsIcon from "@vector-im/compound-design-tokens/assets/web/icons/notifications";
@ -38,8 +38,8 @@ export default class NotificationPanel extends React.PureComponent<IProps, IStat
private card = React.createRef<HTMLDivElement>(); private card = React.createRef<HTMLDivElement>();
public constructor(props: IProps, context: React.ContextType<typeof RoomContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.state = { this.state = {
narrow: false, narrow: false,

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef } from "react"; import React, { createRef, type JSX } from "react";
import UIStore, { UI_EVENTS } from "../../stores/UIStore"; import UIStore, { UI_EVENTS } from "../../stores/UIStore";
import { lerp } from "../../utils/AnimationUtils"; import { lerp } from "../../utils/AnimationUtils";

View file

@ -280,7 +280,7 @@ class PipContainerInner extends React.Component<IProps, IState> {
} }
export const PipContainer: React.FC = () => { export const PipContainer: React.FC = () => {
const movePersistedElement = useRef<() => void>(); const movePersistedElement = useRef<() => void>(undefined);
return <PipContainerInner movePersistedElement={movePersistedElement} />; return <PipContainerInner movePersistedElement={movePersistedElement} />;
}; };

View file

@ -65,8 +65,8 @@ export default class RightPanel extends React.Component<Props, IState> {
public static contextType = MatrixClientContext; public static contextType = MatrixClientContext;
declare public context: React.ContextType<typeof MatrixClientContext>; declare public context: React.ContextType<typeof MatrixClientContext>;
public constructor(props: Props, context: React.ContextType<typeof MatrixClientContext>) { public constructor(props: Props) {
super(props, context); super(props);
this.state = { this.state = {
searchQuery: "", searchQuery: "",

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { forwardRef, useCallback, useContext, useEffect, useRef, useState } from "react"; import React, { forwardRef, useCallback, useContext, useEffect, useRef, useState, type JSX } from "react";
import { import {
ISearchResults, ISearchResults,
IThreadBundledRelationship, IThreadBundledRelationship,
@ -59,7 +59,7 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(
const aborted = useRef(false); const aborted = useRef(false);
// A map from room ID to permalink creator // A map from room ID to permalink creator
const permalinkCreators = useRef(new Map<string, RoomPermalinkCreator>()).current; const permalinkCreators = useRef(new Map<string, RoomPermalinkCreator>()).current;
const innerRef = useRef<ScrollPanel | null>(); const innerRef = useRef<ScrollPanel | null>(undefined);
useEffect(() => { useEffect(() => {
return () => { return () => {

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ReactNode } from "react"; import React, { ReactNode, type JSX } from "react";
import { import {
ClientEvent, ClientEvent,
EventStatus, EventStatus,
@ -91,8 +91,8 @@ export default class RoomStatusBar extends React.PureComponent<IProps, IState> {
public static contextType = MatrixClientContext; public static contextType = MatrixClientContext;
declare public context: React.ContextType<typeof MatrixClientContext>; declare public context: React.ContextType<typeof MatrixClientContext>;
public constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.state = { this.state = {
syncState: this.context.getSyncState(), syncState: this.context.getSyncState(),

View file

@ -15,10 +15,10 @@ interface RoomStatusBarUnsentMessagesProps {
title: ReactNode; title: ReactNode;
description?: string; description?: string;
notificationState: StaticNotificationState; notificationState: StaticNotificationState;
buttons: ReactElement; buttons: ReactElement<any>;
} }
export const RoomStatusBarUnsentMessages = (props: RoomStatusBarUnsentMessagesProps): ReactElement => { export const RoomStatusBarUnsentMessages = (props: RoomStatusBarUnsentMessagesProps): ReactElement<any> => {
return ( return (
<div className="mx_RoomStatusBar mx_RoomStatusBar_unsentMessages"> <div className="mx_RoomStatusBar mx_RoomStatusBar_unsentMessages">
<div role="alert"> <div role="alert">

View file

@ -251,7 +251,7 @@ interface LocalRoomViewProps {
localRoom: LocalRoom; localRoom: LocalRoom;
resizeNotifier: ResizeNotifier; resizeNotifier: ResizeNotifier;
permalinkCreator: RoomPermalinkCreator; permalinkCreator: RoomPermalinkCreator;
roomView: RefObject<HTMLElement>; roomView: RefObject<HTMLElement | null>;
onFileDrop: (dataTransfer: DataTransfer) => Promise<void>; onFileDrop: (dataTransfer: DataTransfer) => Promise<void>;
mainSplitContentType: MainSplitContentType; mainSplitContentType: MainSplitContentType;
} }
@ -262,7 +262,7 @@ interface LocalRoomViewProps {
* @param {LocalRoomViewProps} props Room view props * @param {LocalRoomViewProps} props Room view props
* @returns {ReactElement} * @returns {ReactElement}
*/ */
function LocalRoomView(props: LocalRoomViewProps): ReactElement { function LocalRoomView(props: LocalRoomViewProps): ReactElement<any> {
const context = useScopedRoomContext("room"); const context = useScopedRoomContext("room");
const room = context.room as LocalRoom; const room = context.room as LocalRoom;
const encryptionEvent = props.localRoom.currentState.getStateEvents(EventType.RoomEncryption)[0]; const encryptionEvent = props.localRoom.currentState.getStateEvents(EventType.RoomEncryption)[0];
@ -280,8 +280,8 @@ function LocalRoomView(props: LocalRoomViewProps): ReactElement {
}); });
}; };
let statusBar: ReactElement | null = null; let statusBar: ReactElement<any> | null = null;
let composer: ReactElement | null = null; let composer: ReactElement<any> | null = null;
if (room.isError) { if (room.isError) {
const buttons = ( const buttons = (
@ -340,7 +340,7 @@ interface ILocalRoomCreateLoaderProps {
* @param {ILocalRoomCreateLoaderProps} props Room view props * @param {ILocalRoomCreateLoaderProps} props Room view props
* @return {ReactElement} * @return {ReactElement}
*/ */
function LocalRoomCreateLoader(props: ILocalRoomCreateLoaderProps): ReactElement { function LocalRoomCreateLoader(props: ILocalRoomCreateLoaderProps): ReactElement<any> {
const text = _t("room|creating_room_text", { names: props.names }); const text = _t("room|creating_room_text", { names: props.names });
return ( return (
<div className="mx_RoomView mx_RoomView--local"> <div className="mx_RoomView mx_RoomView--local">
@ -374,16 +374,16 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
public static contextType = SDKContext; public static contextType = SDKContext;
declare public context: React.ContextType<typeof SDKContext>; declare public context: React.ContextType<typeof SDKContext>;
public constructor(props: IRoomProps, context: React.ContextType<typeof SDKContext>) { public constructor(props: IRoomProps) {
super(props, context); super(props);
this.askToJoinEnabled = SettingsStore.getValue("feature_ask_to_join"); this.askToJoinEnabled = SettingsStore.getValue("feature_ask_to_join");
if (!context.client) { if (!this.context.client) {
throw new Error("Unable to create RoomView without MatrixClient"); throw new Error("Unable to create RoomView without MatrixClient");
} }
const llMembers = context.client.hasLazyLoadMembersEnabled(); const llMembers = this.context.client.hasLazyLoadMembersEnabled();
this.state = { this.state = {
roomId: undefined, roomId: undefined,
roomLoading: true, roomLoading: true,
@ -417,7 +417,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
showJoinLeaves: true, showJoinLeaves: true,
showAvatarChanges: true, showAvatarChanges: true,
showDisplaynameChanges: true, showDisplaynameChanges: true,
matrixClientIsReady: context.client?.isInitialSyncComplete(), matrixClientIsReady: this.context.client?.isInitialSyncComplete(),
mainSplitContentType: MainSplitContentType.Timeline, mainSplitContentType: MainSplitContentType.Timeline,
timelineRenderingType: TimelineRenderingType.Room, timelineRenderingType: TimelineRenderingType.Room,
liveTimeline: undefined, liveTimeline: undefined,

View file

@ -19,6 +19,7 @@ import React, {
useMemo, useMemo,
useRef, useRef,
useState, useState,
type JSX,
} from "react"; } from "react";
import { import {
Room, Room,
@ -134,7 +135,7 @@ const Tile: React.FC<ITileProps> = ({
} }
}; };
let button: ReactElement; let button: ReactElement<any>;
if (busy) { if (busy) {
button = ( button = (
<AccessibleButton <AccessibleButton
@ -169,7 +170,7 @@ const Tile: React.FC<ITileProps> = ({
); );
} }
let checkbox: ReactElement | undefined; let checkbox: ReactElement<any> | undefined;
if (onToggleClick) { if (onToggleClick) {
if (hasPermissions) { if (hasPermissions) {
checkbox = <StyledCheckbox checked={!!selected} onChange={onToggleClick} tabIndex={isActive ? 0 : -1} />; checkbox = <StyledCheckbox checked={!!selected} onChange={onToggleClick} tabIndex={isActive ? 0 : -1} />;
@ -187,7 +188,7 @@ const Tile: React.FC<ITileProps> = ({
} }
} }
let avatar: ReactElement; let avatar: ReactElement<any>;
if (joinedRoom) { if (joinedRoom) {
avatar = <RoomAvatar room={joinedRoom} size="20px" />; avatar = <RoomAvatar room={joinedRoom} size="20px" />;
} else { } else {
@ -233,12 +234,12 @@ const Tile: React.FC<ITileProps> = ({
); );
} }
let joinedSection: ReactElement | undefined; let joinedSection: ReactElement<any> | undefined;
if (joinedRoom) { if (joinedRoom) {
joinedSection = <div className="mx_SpaceHierarchy_roomTile_joined">{_t("common|joined")}</div>; joinedSection = <div className="mx_SpaceHierarchy_roomTile_joined">{_t("common|joined")}</div>;
} }
let suggestedSection: ReactElement | undefined; let suggestedSection: ReactElement<any> | undefined;
if (suggested && (!joinedRoom || hasPermissions)) { if (suggested && (!joinedRoom || hasPermissions)) {
suggestedSection = <InfoTooltip tooltip={_t("space|suggested_tooltip")}>{_t("space|suggested")}</InfoTooltip>; suggestedSection = <InfoTooltip tooltip={_t("space|suggested_tooltip")}>{_t("space|suggested")}</InfoTooltip>;
} }
@ -619,7 +620,7 @@ const useIntersectionObserver = (callback: () => void): ((element: HTMLDivElemen
} }
}; };
const observerRef = useRef<IntersectionObserver>(); const observerRef = useRef<IntersectionObserver>(undefined);
return (element: HTMLDivElement) => { return (element: HTMLDivElement) => {
if (observerRef.current) { if (observerRef.current) {
observerRef.current.disconnect(); observerRef.current.disconnect();

View file

@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
import { EventType, RoomType, JoinRule, Preset, Room, RoomEvent } from "matrix-js-sdk/src/matrix"; import { EventType, RoomType, JoinRule, Preset, Room, RoomEvent } from "matrix-js-sdk/src/matrix";
import { KnownMembership } from "matrix-js-sdk/src/types"; import { KnownMembership } from "matrix-js-sdk/src/types";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import React, { useCallback, useContext, useRef, useState } from "react"; import React, { useCallback, useContext, useRef, useState, type JSX } from "react";
import MatrixClientContext from "../../contexts/MatrixClientContext"; import MatrixClientContext from "../../contexts/MatrixClientContext";
import createRoom, { IOpts } from "../../createRoom"; import createRoom, { IOpts } from "../../createRoom";
@ -601,13 +601,13 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
private dispatcherRef?: string; private dispatcherRef?: string;
public constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) { public constructor(props: IProps) {
super(props, context); super(props);
let phase = Phase.Landing; let phase = Phase.Landing;
const creator = this.props.space.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender(); const creator = this.props.space.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
const showSetup = this.props.justCreatedOpts && context.getSafeUserId() === creator; const showSetup = this.props.justCreatedOpts && this.context.getSafeUserId() === creator;
if (showSetup) { if (showSetup) {
phase = phase =

View file

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import classNames from "classnames"; import classNames from "classnames";
import React, { DetailedHTMLProps, HTMLAttributes, ReactNode } from "react"; import React, { DetailedHTMLProps, HTMLAttributes, ReactNode, type JSX } from "react";
interface Props extends DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement> { interface Props extends DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement> {
className?: string; className?: string;

View file

@ -18,6 +18,8 @@ import { NonEmptyArray } from "../../@types/common";
import { RovingAccessibleButton, RovingTabIndexProvider } from "../../accessibility/RovingTabIndex"; import { RovingAccessibleButton, RovingTabIndexProvider } from "../../accessibility/RovingTabIndex";
import { useWindowWidth } from "../../hooks/useWindowWidth"; import { useWindowWidth } from "../../hooks/useWindowWidth";
import type { JSX } from "react";
/** /**
* Represents a tab for the TabbedView. * Represents a tab for the TabbedView.
*/ */

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef, KeyboardEvent } from "react"; import React, { createRef, KeyboardEvent, type JSX } from "react";
import { import {
Thread, Thread,
THREAD_RELATION_TYPE, THREAD_RELATION_TYPE,
@ -86,8 +86,8 @@ export default class ThreadView extends React.Component<IProps, IState> {
// Set by setEventId in ctor. // Set by setEventId in ctor.
private eventId!: string; private eventId!: string;
public constructor(props: IProps, context: React.ContextType<typeof RoomContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.setEventId(this.props.mxEvent); this.setEventId(this.props.mxEvent);
const thread = this.props.room.getThread(this.eventId) ?? undefined; const thread = this.props.room.getThread(this.eventId) ?? undefined;

View file

@ -259,8 +259,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
private callEventGroupers = new Map<string, LegacyCallEventGrouper>(); private callEventGroupers = new Map<string, LegacyCallEventGrouper>();
private initialReadMarkerId: string | null = null; private initialReadMarkerId: string | null = null;
public constructor(props: IProps, context: React.ContextType<typeof RoomContext>) { public constructor(props: IProps) {
super(props, context); super(props);
debuglog("mounting"); debuglog("mounting");

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef, ReactNode } from "react"; import React, { createRef, ReactNode, type JSX } from "react";
import { Room } from "matrix-js-sdk/src/matrix"; import { Room } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../../MatrixClientPeg"; import { MatrixClientPeg } from "../../MatrixClientPeg";
@ -81,10 +81,10 @@ export default class UserMenu extends React.Component<IProps, IState> {
private dispatcherRef?: string; private dispatcherRef?: string;
private themeWatcherRef?: string; private themeWatcherRef?: string;
private readonly dndWatcherRef?: string; private readonly dndWatcherRef?: string;
private buttonRef: React.RefObject<HTMLButtonElement> = createRef(); private buttonRef: React.RefObject<HTMLButtonElement | null> = createRef();
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.state = { this.state = {
contextMenuPosition: null, contextMenuPosition: null,

View file

@ -34,8 +34,8 @@ export default class UserView extends React.Component<IProps, IState> {
public static contextType = MatrixClientContext; public static contextType = MatrixClientContext;
declare public context: React.ContextType<typeof MatrixClientContext>; declare public context: React.ContextType<typeof MatrixClientContext>;
public constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.state = { this.state = {
loading: true, loading: true,
}; };

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { MatrixEvent } from "matrix-js-sdk/src/matrix"; import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import SyntaxHighlight from "../views/elements/SyntaxHighlight"; import SyntaxHighlight from "../views/elements/SyntaxHighlight";

View file

@ -21,7 +21,7 @@ import SdkConfig from "../../SdkConfig";
import { useScopedRoomContext } from "../../contexts/ScopedRoomContext.tsx"; import { useScopedRoomContext } from "../../contexts/ScopedRoomContext.tsx";
interface Props { interface Props {
roomView: RefObject<HTMLElement>; roomView: RefObject<HTMLElement | null>;
resizeNotifier: ResizeNotifier; resizeNotifier: ResizeNotifier;
inviteEvent: MatrixEvent; inviteEvent: MatrixEvent;
} }

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ReactNode } from "react"; import React, { ReactNode, type JSX } from "react";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { sleep } from "matrix-js-sdk/src/utils"; import { sleep } from "matrix-js-sdk/src/utils";
import { LockSolidIcon, CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; import { LockSolidIcon, CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
@ -388,7 +388,9 @@ export default class ForgotPassword extends React.Component<Props, State> {
label={_td("auth|change_password_new_label")} label={_td("auth|change_password_new_label")}
value={this.state.password} value={this.state.password}
minScore={PASSWORD_MIN_SCORE} minScore={PASSWORD_MIN_SCORE}
fieldRef={(field) => (this.fieldPassword = field)} fieldRef={(field) => {
this.fieldPassword = field;
}}
onChange={this.onInputChanged.bind(this, "password")} onChange={this.onInputChanged.bind(this, "password")}
autoComplete="new-password" autoComplete="new-password"
/> />
@ -399,7 +401,9 @@ export default class ForgotPassword extends React.Component<Props, State> {
labelInvalid={_td("auth|reset_password|passwords_mismatch")} labelInvalid={_td("auth|reset_password|passwords_mismatch")}
value={this.state.password2} value={this.state.password2}
password={this.state.password} password={this.state.password}
fieldRef={(field) => (this.fieldPasswordConfirm = field)} fieldRef={(field) => {
this.fieldPasswordConfirm = field;
}}
onChange={this.onInputChanged.bind(this, "password2")} onChange={this.onInputChanged.bind(this, "password2")}
autoComplete="new-password" autoComplete="new-password"
/> />

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ReactNode } from "react"; import React, { ReactNode, type JSX } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { SSOFlow, SSOAction } from "matrix-js-sdk/src/matrix"; import { SSOFlow, SSOAction } from "matrix-js-sdk/src/matrix";

View file

@ -20,7 +20,7 @@ import {
SSOAction, SSOAction,
RegisterResponse, RegisterResponse,
} from "matrix-js-sdk/src/matrix"; } from "matrix-js-sdk/src/matrix";
import React, { Fragment, ReactNode } from "react"; import React, { Fragment, ReactNode, type JSX } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import SplashPage from "../SplashPage"; import SplashPage from "../SplashPage";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { KeyBackupInfo, VerificationRequest } from "matrix-js-sdk/src/crypto-api"; import { KeyBackupInfo, VerificationRequest } from "matrix-js-sdk/src/crypto-api";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { SecretStorageKeyDescription } from "matrix-js-sdk/src/secret-storage"; import { SecretStorageKeyDescription } from "matrix-js-sdk/src/secret-storage";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ChangeEvent, SyntheticEvent } from "react"; import React, { ChangeEvent, SyntheticEvent, type JSX } from "react";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { Optional } from "matrix-events-sdk"; import { Optional } from "matrix-events-sdk";
import { LoginFlow, MatrixError, SSOAction, SSOFlow } from "matrix-js-sdk/src/matrix"; import { LoginFlow, MatrixError, SSOAction, SSOFlow } from "matrix-js-sdk/src/matrix";
@ -66,8 +66,8 @@ export default class SoftLogout extends React.Component<IProps, IState> {
public static contextType = SDKContext; public static contextType = SDKContext;
declare public context: React.ContextType<typeof SDKContext>; declare public context: React.ContextType<typeof SDKContext>;
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.state = { this.state = {
loginView: LoginView.Loading, loginView: LoginView.Loading,

View file

@ -6,13 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import { createContext, Dispatch, ReducerAction, ReducerState } from "react"; import { createContext, Dispatch, ReducerState } from "react";
import type { AuthHeaderReducer } from "./AuthHeaderProvider"; import type { AuthHeaderAction, AuthHeaderReducer } from "./AuthHeaderProvider";
interface AuthHeaderContextType { interface AuthHeaderContextType {
state: ReducerState<AuthHeaderReducer>; state: ReducerState<AuthHeaderReducer>;
dispatch: Dispatch<ReducerAction<AuthHeaderReducer>>; dispatch: Dispatch<AuthHeaderAction>;
} }
export const AuthHeaderContext = createContext<AuthHeaderContextType | undefined>(undefined); export const AuthHeaderContext = createContext<AuthHeaderContextType | undefined>(undefined);

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { Fragment, PropsWithChildren, ReactNode, useContext } from "react"; import React, { Fragment, PropsWithChildren, ReactNode, useContext, type JSX } from "react";
import { AuthHeaderContext } from "./AuthHeaderContext"; import { AuthHeaderContext } from "./AuthHeaderContext";

View file

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import { isEqual } from "lodash"; import { isEqual } from "lodash";
import React, { ComponentProps, PropsWithChildren, Reducer, useReducer } from "react"; import React, { ComponentProps, PropsWithChildren, Reducer, useReducer, type JSX } from "react";
import { AuthHeaderContext } from "./AuthHeaderContext"; import { AuthHeaderContext } from "./AuthHeaderContext";
import { AuthHeaderModifier } from "./AuthHeaderModifier"; import { AuthHeaderModifier } from "./AuthHeaderModifier";
@ -17,7 +17,7 @@ export enum AuthHeaderActionType {
Remove, Remove,
} }
interface AuthHeaderAction { export interface AuthHeaderAction {
type: AuthHeaderActionType; type: AuthHeaderActionType;
value: ComponentProps<typeof AuthHeaderModifier>; value: ComponentProps<typeof AuthHeaderModifier>;
} }
@ -25,7 +25,7 @@ interface AuthHeaderAction {
export type AuthHeaderReducer = Reducer<ComponentProps<typeof AuthHeaderModifier>[], AuthHeaderAction>; export type AuthHeaderReducer = Reducer<ComponentProps<typeof AuthHeaderModifier>[], AuthHeaderAction>;
export function AuthHeaderProvider({ children }: PropsWithChildren<{}>): JSX.Element { export function AuthHeaderProvider({ children }: PropsWithChildren<{}>): JSX.Element {
const [state, dispatch] = useReducer<AuthHeaderReducer>( const [state, dispatch] = useReducer(
(state: ComponentProps<typeof AuthHeaderModifier>[], action: AuthHeaderAction) => { (state: ComponentProps<typeof AuthHeaderModifier>[], action: AuthHeaderAction) => {
switch (action.type) { switch (action.type) {
case AuthHeaderActionType.Add: case AuthHeaderActionType.Add:

View file

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import classNames from "classnames"; import classNames from "classnames";
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef, type JSX } from "react";
type FlexProps = { type FlexProps = {
/** /**
@ -71,7 +71,7 @@ export function Box({
children, children,
...props ...props
}: React.PropsWithChildren<FlexProps>): JSX.Element { }: React.PropsWithChildren<FlexProps>): JSX.Element {
const ref = useRef<HTMLElement>(); const ref = useRef<HTMLElement>(undefined);
useEffect(() => { useEffect(() => {
addOrRemoveProperty(ref, `--mx-box-flex`, flex); addOrRemoveProperty(ref, `--mx-box-flex`, flex);

View file

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import classNames from "classnames"; import classNames from "classnames";
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef, type JSX } from "react";
type FlexProps = { type FlexProps = {
/** /**
@ -64,7 +64,7 @@ export function Flex({
children, children,
...props ...props
}: React.PropsWithChildren<FlexProps>): JSX.Element { }: React.PropsWithChildren<FlexProps>): JSX.Element {
const ref = useRef<HTMLElement>(); const ref = useRef<HTMLElement>(undefined);
useEffect(() => { useEffect(() => {
ref.current!.style.setProperty(`--mx-flex-display`, display); ref.current!.style.setProperty(`--mx-flex-display`, display);

View file

@ -31,8 +31,8 @@ interface IState {
} }
export default abstract class AudioPlayerBase<T extends IProps = IProps> extends React.PureComponent<T, IState> { export default abstract class AudioPlayerBase<T extends IProps = IProps> extends React.PureComponent<T, IState> {
protected seekRef: RefObject<SeekBar> = createRef(); protected seekRef: RefObject<SeekBar | null> = createRef();
protected playPauseRef: RefObject<PlayPauseButton> = createRef(); protected playPauseRef: RefObject<PlayPauseButton | null> = createRef();
public constructor(props: T) { public constructor(props: T) {
super(props); super(props);

View file

@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import classNames from "classnames"; import classNames from "classnames";
import React, { PropsWithChildren } from "react"; import React, { PropsWithChildren, type JSX } from "react";
interface Props { interface Props {
className?: string; className?: string;

View file

@ -7,12 +7,12 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ReactElement } from "react"; import React, { ReactElement, type JSX } from "react";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
const AuthFooter = (): ReactElement => { const AuthFooter = (): ReactElement<any> => {
const brandingConfig = SdkConfig.getObject("branding"); const brandingConfig = SdkConfig.getObject("branding");
const links = brandingConfig?.get("auth_footer_links") ?? [ const links = brandingConfig?.get("auth_footer_links") ?? [
{ text: "Blog", url: "https://element.io/blog" }, { text: "Blog", url: "https://element.io/blog" },

View file

@ -11,7 +11,7 @@ import React from "react";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
export default class AuthHeaderLogo extends React.PureComponent { export default class AuthHeaderLogo extends React.PureComponent {
public render(): React.ReactElement { public render(): React.ReactElement<any> {
const brandingConfig = SdkConfig.getObject("branding"); const brandingConfig = SdkConfig.getObject("branding");
const logoUrl = brandingConfig?.get("auth_header_logo_url") ?? "themes/element/img/logos/element-logo.svg"; const logoUrl = brandingConfig?.get("auth_header_logo_url") ?? "themes/element/img/logos/element-logo.svg";

View file

@ -35,7 +35,7 @@ export default class AuthPage extends React.PureComponent<React.PropsWithChildre
return AuthPage.welcomeBackgroundUrl; return AuthPage.welcomeBackgroundUrl;
} }
public render(): React.ReactElement { public render(): React.ReactElement<any> {
const pageStyle = { const pageStyle = {
background: `center/cover fixed url(${AuthPage.getWelcomeBackgroundUrl()})`, background: `center/cover fixed url(${AuthPage.getWelcomeBackgroundUrl()})`,
}; };

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef } from "react"; import React, { createRef, type JSX } from "react";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";

View file

@ -149,7 +149,7 @@ export default class CountryDropdown extends React.Component<IProps, IState> {
{country.name} (+{country.prefix}) {country.name} (+{country.prefix})
</div> </div>
); );
}) as NonEmptyArray<ReactElement & { key: string }>; }) as NonEmptyArray<ReactElement<any> & { key: string }>;
// default value here too, otherwise we need to handle null / undefined // default value here too, otherwise we need to handle null / undefined
// values between mounting and the initial value propagating // values between mounting and the initial value propagating

View file

@ -15,7 +15,7 @@ import * as Email from "../../../email";
interface IProps extends Omit<IInputProps, "onValidate" | "element"> { interface IProps extends Omit<IInputProps, "onValidate" | "element"> {
id?: string; id?: string;
fieldRef?: RefCallback<Field> | RefObject<Field>; fieldRef?: RefCallback<Field> | RefObject<Field | null>;
value: string; value: string;
autoFocus?: boolean; autoFocus?: boolean;

View file

@ -10,7 +10,7 @@ import classNames from "classnames";
import { MatrixClient } from "matrix-js-sdk/src/matrix"; import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { AuthType, AuthDict, IInputs, IStageStatus } from "matrix-js-sdk/src/interactive-auth"; import { AuthType, AuthDict, IInputs, IStageStatus } from "matrix-js-sdk/src/interactive-auth";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import React, { ChangeEvent, createRef, FormEvent, Fragment } from "react"; import React, { ChangeEvent, createRef, FormEvent, Fragment, type JSX } from "react";
import { Button, Text } from "@vector-im/compound-web"; import { Button, Text } from "@vector-im/compound-web";
import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out"; import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out";

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import { getCurrentLanguage } from "../../../languageHandler"; import { getCurrentLanguage } from "../../../languageHandler";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef, ReactNode } from "react"; import React, { createRef, ReactNode, type JSX } from "react";
import { ClientRendezvousFailureReason, MSC4108FailureReason } from "matrix-js-sdk/src/rendezvous"; import { ClientRendezvousFailureReason, MSC4108FailureReason } from "matrix-js-sdk/src/rendezvous";
import ChevronLeftIcon from "@vector-im/compound-design-tokens/assets/web/icons/chevron-left"; import ChevronLeftIcon from "@vector-im/compound-design-tokens/assets/web/icons/chevron-left";
import CheckCircleSolidIcon from "@vector-im/compound-design-tokens/assets/web/icons/check-circle-solid"; import CheckCircleSolidIcon from "@vector-im/compound-design-tokens/assets/web/icons/check-circle-solid";

View file

@ -14,7 +14,7 @@ import { _t, _td, TranslationKey } from "../../../languageHandler";
interface IProps extends Omit<IInputProps, "onValidate" | "label" | "element"> { interface IProps extends Omit<IInputProps, "onValidate" | "label" | "element"> {
id?: string; id?: string;
fieldRef?: RefCallback<Field> | RefObject<Field>; fieldRef?: RefCallback<Field> | RefObject<Field | null>;
autoComplete?: string; autoComplete?: string;
value: string; value: string;
password: string; // The password we're confirming password: string; // The password we're confirming

View file

@ -22,7 +22,7 @@ interface IProps extends Omit<IInputProps, "onValidate" | "element"> {
className?: string; className?: string;
minScore: 0 | 1 | 2 | 3 | 4; minScore: 0 | 1 | 2 | 3 | 4;
value: string; value: string;
fieldRef?: RefCallback<Field> | RefObject<Field>; fieldRef?: RefCallback<Field> | RefObject<Field | null>;
// Additional strings such as a username used to catch bad passwords // Additional strings such as a username used to catch bad passwords
userInputs?: string[]; userInputs?: string[];

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { SyntheticEvent } from "react"; import React, { SyntheticEvent, type JSX } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
@ -411,7 +411,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
} }
return ( return (
<div> (<div>
<form onSubmit={this.onSubmitForm}> <form onSubmit={this.onSubmitForm}>
{loginType} {loginType}
{loginField} {loginField}
@ -427,7 +427,9 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
disabled={this.props.busy} disabled={this.props.busy}
autoFocus={autoFocusPassword} autoFocus={autoFocusPassword}
onValidate={this.onPasswordValidate} onValidate={this.onPasswordValidate}
ref={(field) => (this[LoginField.Password] = field)} ref={field => {
(this[LoginField.Password] = field);
}}
/> />
{forgotPasswordJsx} {forgotPasswordJsx}
{!this.props.busy && ( {!this.props.busy && (
@ -439,7 +441,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
/> />
)} )}
</form> </form>
</div> </div>)
); );
} }
} }

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { BaseSyntheticEvent, ComponentProps, ReactNode } from "react"; import React, { BaseSyntheticEvent, ComponentProps, ReactNode, type JSX } from "react";
import { MatrixClient, MatrixError } from "matrix-js-sdk/src/matrix"; import { MatrixClient, MatrixError } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
@ -456,7 +456,9 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
: _td("auth|registration|continue_without_email_field_label"); : _td("auth|registration|continue_without_email_field_label");
return ( return (
<EmailField <EmailField
fieldRef={(field) => (this[RegistrationField.Email] = field)} fieldRef={(field) => {
this[RegistrationField.Email] = field;
}}
label={emailLabel} label={emailLabel}
value={this.state.email} value={this.state.email}
validationRules={this.validateEmailRules.bind(this)} validationRules={this.validateEmailRules.bind(this)}
@ -471,7 +473,9 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
return ( return (
<PassphraseField <PassphraseField
id="mx_RegistrationForm_password" id="mx_RegistrationForm_password"
fieldRef={(field) => (this[RegistrationField.Password] = field)} fieldRef={(field) => {
this[RegistrationField.Password] = field;
}}
minScore={PASSWORD_MIN_SCORE} minScore={PASSWORD_MIN_SCORE}
value={this.state.password} value={this.state.password}
onChange={this.onPasswordChange} onChange={this.onPasswordChange}
@ -486,7 +490,9 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
return ( return (
<PassphraseConfirmField <PassphraseConfirmField
id="mx_RegistrationForm_passwordConfirm" id="mx_RegistrationForm_passwordConfirm"
fieldRef={(field) => (this[RegistrationField.PasswordConfirm] = field)} fieldRef={(field) => {
this[RegistrationField.PasswordConfirm] = field;
}}
autoComplete="new-password" autoComplete="new-password"
value={this.state.passwordConfirm} value={this.state.passwordConfirm}
password={this.state.password} password={this.state.password}
@ -514,7 +520,9 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
); );
return ( return (
<Field <Field
ref={(field) => (this[RegistrationField.PhoneNumber] = field)} ref={(field) => {
this[RegistrationField.PhoneNumber] = field;
}}
type="text" type="text"
label={phoneLabel} label={phoneLabel}
value={this.state.phoneNumber} value={this.state.phoneNumber}
@ -529,7 +537,9 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
return ( return (
<Field <Field
id="mx_RegistrationForm_username" id="mx_RegistrationForm_username"
ref={(field) => (this[RegistrationField.Username] = field)} ref={(field) => {
this[RegistrationField.Username] = field;
}}
type="text" type="text"
autoFocus={true} autoFocus={true}
label={_t("common|username")} label={_t("common|username")}

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { EventType, JoinRule, MatrixEvent, Room, RoomEvent, User, UserEvent } from "matrix-js-sdk/src/matrix"; import { EventType, JoinRule, MatrixEvent, Room, RoomEvent, User, UserEvent } from "matrix-js-sdk/src/matrix";
import { UnstableValue } from "matrix-js-sdk/src/NamespacedValue"; import { UnstableValue } from "matrix-js-sdk/src/NamespacedValue";

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { forwardRef, ReactNode, Ref, useContext } from "react"; import React, { forwardRef, ReactNode, Ref, useContext, type JSX } from "react";
import { RoomMember, ResizeMethod } from "matrix-js-sdk/src/matrix"; import { RoomMember, ResizeMethod } from "matrix-js-sdk/src/matrix";
import dis from "../../../dispatcher/dispatcher"; import dis from "../../../dispatcher/dispatcher";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { RoomMember } from "matrix-js-sdk/src/matrix"; import { RoomMember } from "matrix-js-sdk/src/matrix";
import emailPillAvatar from "../../../../res/img/icon-email-pill-avatar.svg"; import emailPillAvatar from "../../../../res/img/icon-email-pill-avatar.svg";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ReactNode, useEffect, useState } from "react"; import React, { ReactNode, useEffect, useState, type JSX } from "react";
import { ClientEvent, Room, RoomMember, RoomStateEvent, UserEvent } from "matrix-js-sdk/src/matrix"; import { ClientEvent, Room, RoomMember, RoomStateEvent, UserEvent } from "matrix-js-sdk/src/matrix";
import { Tooltip } from "@vector-im/compound-web"; import { Tooltip } from "@vector-im/compound-web";

View file

@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
// Exports beacon components which touch maplibre-gs wrapped in React Suspense to enable code splitting // Exports beacon components which touch maplibre-gs wrapped in React Suspense to enable code splitting
import React, { ComponentProps, lazy, Suspense } from "react"; import React, { ComponentProps, lazy, Suspense, type JSX } from "react";
import Spinner from "../elements/Spinner"; import Spinner from "../elements/Spinner";

View file

@ -24,7 +24,7 @@ interface IState {
} }
export default class DialpadContextMenu extends React.Component<IProps, IState> { export default class DialpadContextMenu extends React.Component<IProps, IState> {
private numberEntryFieldRef: React.RefObject<Field> = createRef(); private numberEntryFieldRef: React.RefObject<Field | null> = createRef();
public constructor(props: IProps) { public constructor(props: IProps) {
super(props); super(props);

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ReactNode } from "react"; import React, { ReactNode, type JSX } from "react";
import classNames from "classnames"; import classNames from "classnames";
import ContextMenu, { import ContextMenu, {
@ -17,6 +17,7 @@ import ContextMenu, {
MenuItemRadio, MenuItemRadio,
} from "../../structures/ContextMenu"; } from "../../structures/ContextMenu";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import AccessibleButton from "../elements/AccessibleButton.tsx";
interface IProps extends IContextMenuProps { interface IProps extends IContextMenuProps {
className?: string; className?: string;
@ -31,10 +32,10 @@ interface IOptionListProps {
children: ReactNode; children: ReactNode;
} }
interface IOptionProps extends React.ComponentProps<typeof MenuItem> { type IOptionProps<T extends React.ElementType> = React.ComponentProps<typeof AccessibleButton<T>> & {
iconClassName?: string; iconClassName?: string;
isDestructive?: boolean; isDestructive?: boolean;
} };
interface ICheckboxProps extends React.ComponentProps<typeof MenuItemCheckbox> { interface ICheckboxProps extends React.ComponentProps<typeof MenuItemCheckbox> {
iconClassName: string; iconClassName: string;
@ -110,18 +111,19 @@ export const IconizedContextMenuCheckbox: React.FC<ICheckboxProps> = ({
); );
}; };
export const IconizedContextMenuOption: React.FC<IOptionProps> = ({ export const IconizedContextMenuOption = <T extends React.ElementType>({
element,
label, label,
className, className,
iconClassName, iconClassName,
children, children,
isDestructive, isDestructive,
...props ...props
}) => { }: IOptionProps<T>): JSX.Element => {
return ( return (
<MenuItem <MenuItem
element="li"
{...props} {...props}
element={element ?? "li"}
className={classNames(className, { className={classNames(className, {
mx_IconizedContextMenu_item: true, mx_IconizedContextMenu_item: true,
mx_IconizedContextMenu_itemDestructive: isDestructive, mx_IconizedContextMenu_itemDestructive: isDestructive,

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { createRef, useContext } from "react"; import React, { createRef, useContext, type JSX } from "react";
import { import {
EventStatus, EventStatus,
MatrixEvent, MatrixEvent,
@ -130,8 +130,8 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
private reactButtonRef = createRef<any>(); // XXX Ref to a functional component private reactButtonRef = createRef<any>(); // XXX Ref to a functional component
public constructor(props: IProps, context: React.ContextType<typeof RoomContext>) { public constructor(props: IProps) {
super(props, context); super(props);
this.state = { this.state = {
canRedact: false, canRedact: false,
@ -396,7 +396,6 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
openInMapSiteButton = ( openInMapSiteButton = (
<IconizedContextMenuOption <IconizedContextMenuOption
iconClassName="mx_MessageContextMenu_iconOpenInMapSite" iconClassName="mx_MessageContextMenu_iconOpenInMapSite"
onClick={null}
label={_t("timeline|context_menu|open_in_osm")} label={_t("timeline|context_menu|open_in_osm")}
element="a" element="a"
{...{ {...{

View file

@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { Room } from "matrix-js-sdk/src/matrix"; import { Room } from "matrix-js-sdk/src/matrix";
import React, { useContext } from "react"; import React, { useContext, type JSX } from "react";
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts"; import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import RoomListActions from "../../../actions/RoomListActions"; import RoomListActions from "../../../actions/RoomListActions";

View file

@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/ */
import { Room } from "matrix-js-sdk/src/matrix"; import { Room } from "matrix-js-sdk/src/matrix";
import React from "react"; import React, { type JSX } from "react";
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts"; import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { useNotificationState } from "../../../hooks/useRoomNotificationState"; import { useNotificationState } from "../../../hooks/useRoomNotificationState";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { useContext } from "react"; import React, { useContext, type JSX } from "react";
import { Room, EventType, RoomType } from "matrix-js-sdk/src/matrix"; import { Room, EventType, RoomType } from "matrix-js-sdk/src/matrix";
import { IProps as IContextMenuProps } from "../../structures/ContextMenu"; import { IProps as IContextMenuProps } from "../../structures/ContextMenu";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ComponentProps, useContext } from "react"; import React, { ComponentProps, useContext, type JSX } from "react";
import { ClientWidgetApi, IWidget, MatrixCapabilities } from "matrix-widget-api"; import { ClientWidgetApi, IWidget, MatrixCapabilities } from "matrix-widget-api";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { ApprovalOpts, WidgetLifecycle } from "@matrix-org/react-sdk-module-api/lib/lifecycles/WidgetLifecycle"; import { ApprovalOpts, WidgetLifecycle } from "@matrix-org/react-sdk-module-api/lib/lifecycles/WidgetLifecycle";

View file

@ -423,7 +423,7 @@ export const SubspaceSelector: React.FC<ISubspaceSelectorProps> = ({ title, spac
{space.name || getDisplayAliasForRoom(space) || space.roomId} {space.name || getDisplayAliasForRoom(space) || space.roomId}
</div> </div>
); );
}) as NonEmptyArray<ReactElement & { key: string }> }) as NonEmptyArray<ReactElement<any> & { key: string }>
} }
</Dropdown> </Dropdown>
); );

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { useCallback } from "react"; import React, { useCallback, type JSX } from "react";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import FocusLock from "react-focus-lock"; import FocusLock from "react-focus-lock";
import classNames from "classnames"; import classNames from "classnames";
import { MatrixClient } from "matrix-js-sdk/src/matrix"; import { MatrixClient } from "matrix-js-sdk/src/matrix";

View file

@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import Modal from "../../../Modal"; import Modal from "../../../Modal";
@ -46,7 +46,7 @@ interface IState {
export default class BugReportDialog extends React.Component<IProps, IState> { export default class BugReportDialog extends React.Component<IProps, IState> {
private unmounted: boolean; private unmounted: boolean;
private issueRef: React.RefObject<Field>; private issueRef: React.RefObject<Field | null>;
public constructor(props: IProps) { public constructor(props: IProps) {
super(props); super(props);

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import QuestionDialog from "./QuestionDialog"; import QuestionDialog from "./QuestionDialog";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ComponentProps, useMemo, useState } from "react"; import React, { ComponentProps, useMemo, useState, type JSX } from "react";
import { Room } from "matrix-js-sdk/src/matrix"; import { Room } from "matrix-js-sdk/src/matrix";
import ConfirmUserActionDialog from "./ConfirmUserActionDialog"; import ConfirmUserActionDialog from "./ConfirmUserActionDialog";

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { ChangeEvent, createRef, KeyboardEvent, SyntheticEvent } from "react"; import React, { ChangeEvent, createRef, KeyboardEvent, SyntheticEvent, type JSX } from "react";
import { Room, RoomType, JoinRule, Preset, Visibility } from "matrix-js-sdk/src/matrix"; import { Room, RoomType, JoinRule, Preset, Visibility } from "matrix-js-sdk/src/matrix";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { useRef, useState } from "react"; import React, { useRef, useState, type JSX } from "react";
import { Room, JoinRule } from "matrix-js-sdk/src/matrix"; import { Room, JoinRule } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { AuthType, IAuthData } from "matrix-js-sdk/src/interactive-auth"; import { AuthType, IAuthData } from "matrix-js-sdk/src/interactive-auth";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClient } from "matrix-js-sdk/src/matrix"; import { MatrixClient } from "matrix-js-sdk/src/matrix";

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { useState } from "react"; import React, { useState, type JSX } from "react";
import { _t, _td, TranslationKey } from "../../../languageHandler"; import { _t, _td, TranslationKey } from "../../../languageHandler";
import MatrixClientContext from "../../../contexts/MatrixClientContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { useRef, useState, Dispatch, SetStateAction } from "react"; import React, { useRef, useState, Dispatch, SetStateAction, type JSX } from "react";
import { Room } from "matrix-js-sdk/src/matrix"; import { Room } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { useEffect, useRef, useState } from "react"; import React, { useEffect, useRef, useState, type JSX } from "react";
import QuestionDialog from "./QuestionDialog"; import QuestionDialog from "./QuestionDialog";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React, { useEffect, useMemo, useState } from "react"; import React, { useEffect, useMemo, useState, type JSX } from "react";
import classnames from "classnames"; import classnames from "classnames";
import { import {
IContent, IContent,

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details. Please see LICENSE files in the repository root for full details.
*/ */
import React from "react"; import React, { type JSX } from "react";
import { MatrixClient, UIAResponse } from "matrix-js-sdk/src/matrix"; import { MatrixClient, UIAResponse } from "matrix-js-sdk/src/matrix";
import { AuthType } from "matrix-js-sdk/src/interactive-auth"; import { AuthType } from "matrix-js-sdk/src/interactive-auth";

Some files were not shown because too many files have changed in this diff Show more