Switch from eslint to oxlint (#34166)
* Fix type imports * Fix jsdoc * Fixup types * Fix stray awaits on non-thenables * Fixup imports * Fix splats * Fix this-context on callbacks * Memoise react contexts * Prefer find/flatMap * Make oxlint happier about our React keys * Avoid unsafe default function params * Fixup jsdoc * Fixup contexts * Switch from eslint to oxlint * Some oxlint-related tweaks * Iterate * Partial revert to defer some changes and shrink diff * Iterate * Add eslint-plugin-element-call and enable the copyright rule * Set strictStorePkgContentCheck * Iterate * Make sonar happy * Fix new lints
This commit is contained in:
@@ -68,7 +68,7 @@ export interface VirtualizedListProps<Item, Context> extends Omit<
|
||||
/**
|
||||
* Function to get the key to use for focusing an item.
|
||||
* @param item - The item to get the key for
|
||||
* @return The key to use for focusing the item
|
||||
* @returns The key to use for focusing the item
|
||||
*/
|
||||
getItemKey: (item: Item) => string;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* you will end up with literal "<a>" in your output, rather than HTML. Note that you can also use variable
|
||||
* substitution to insert React components, but you can't use it to translate text between tags.
|
||||
*
|
||||
* @return a React <span> component if any non-strings were used in substitutions, otherwise a string
|
||||
* @returns a React <span> component if any non-strings were used in substitutions, otherwise a string
|
||||
*/
|
||||
import React from "react";
|
||||
import { KEY_SEPARATOR } from "matrix-web-i18n";
|
||||
@@ -204,7 +204,7 @@ export function lookupString(key: TranslationKey): string {
|
||||
* @param {object} variables Variable substitutions, e.g { foo: 'bar' }
|
||||
* @param {object} tags Tag substitutions e.g. { 'a': (sub) => <a>{sub}</a> }
|
||||
*
|
||||
* @return a React <span> component if any non-strings were used in substitutions
|
||||
* @returns a React <span> component if any non-strings were used in substitutions
|
||||
* or translation used a fallback locale, otherwise a string
|
||||
*/
|
||||
// eslint-next-line @typescript-eslint/naming-convention
|
||||
@@ -243,7 +243,7 @@ export function sanitizeForTranslation(text: string): string {
|
||||
* the substitution (e.g. return a React component). In case of a tag replacement, the function receives as
|
||||
* the argument the text inside the element corresponding to the tag.
|
||||
*
|
||||
* @return a React <span> component if any non-strings were used in substitutions, otherwise a string
|
||||
* @returns a React <span> component if any non-strings were used in substitutions, otherwise a string
|
||||
*/
|
||||
export function substitute(text: string, variables?: StringVariables): string;
|
||||
export function substitute(text: string, variables?: RichVariables): React.ReactNode;
|
||||
@@ -277,7 +277,7 @@ export function substitute(text: string, variables?: IVariables, tags?: Tags): s
|
||||
* function which will receive as the argument the capture groups defined in the regexp. E.g.
|
||||
* { 'Hello (.?) World': (sub) => sub.toUpperCase() }
|
||||
*
|
||||
* @return a React <span> component if any non-strings were used in substitutions, otherwise a string
|
||||
* @returns a React <span> component if any non-strings were used in substitutions, otherwise a string
|
||||
*/
|
||||
export function replaceByRegexes(text: string, mapping: IVariables): string;
|
||||
export function replaceByRegexes(text: string, mapping: Tags): React.ReactNode;
|
||||
|
||||
@@ -25,7 +25,7 @@ const Button = (props: HTMLAttributes<HTMLButtonElement>): React.JSX.Element =>
|
||||
return <button {...props} onFocus={onFocus} tabIndex={isActive ? 0 : -1} ref={ref} />;
|
||||
};
|
||||
|
||||
const checkTabIndexes = (buttons: NodeListOf<HTMLElement>, expectations: number[]): void => {
|
||||
const expectTabIndexes = (buttons: NodeListOf<HTMLElement>, expectations: number[]): void => {
|
||||
expect([...buttons].map((b) => b.tabIndex)).toStrictEqual(expectations);
|
||||
};
|
||||
|
||||
@@ -89,16 +89,16 @@ describe("RovingTabIndex", () => {
|
||||
</RovingTabIndexProvider>,
|
||||
);
|
||||
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
|
||||
act(() => container.querySelectorAll("button")[2].focus());
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
|
||||
act(() => container.querySelectorAll("button")[1].focus());
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
|
||||
act(() => container.querySelectorAll("button")[1].blur());
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
|
||||
rerender(
|
||||
<RovingTabIndexProvider>
|
||||
@@ -112,7 +112,7 @@ describe("RovingTabIndex", () => {
|
||||
)}
|
||||
</RovingTabIndexProvider>,
|
||||
);
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, -1, 0, -1]);
|
||||
|
||||
rerender(
|
||||
<RovingTabIndexProvider>
|
||||
@@ -125,7 +125,7 @@ describe("RovingTabIndex", () => {
|
||||
)}
|
||||
</RovingTabIndexProvider>,
|
||||
);
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
});
|
||||
|
||||
it("provides a ref to the dom element", () => {
|
||||
@@ -165,10 +165,10 @@ describe("RovingTabIndex", () => {
|
||||
</RovingTabIndexProvider>,
|
||||
);
|
||||
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
|
||||
act(() => container.querySelectorAll("button")[2].focus());
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
});
|
||||
|
||||
describe("reducer functions as expected", () => {
|
||||
@@ -390,22 +390,22 @@ describe("RovingTabIndex", () => {
|
||||
);
|
||||
|
||||
act(() => container.querySelectorAll("button")[0].focus());
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
|
||||
await userEvent.keyboard("[ArrowDown]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
|
||||
await userEvent.keyboard("[ArrowDown]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
|
||||
await userEvent.keyboard("[ArrowUp]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
|
||||
await userEvent.keyboard("[ArrowUp]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
|
||||
await userEvent.keyboard("[ArrowUp]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
});
|
||||
|
||||
it("handles left/right arrow keys when handleLeftRight=true", async () => {
|
||||
@@ -420,10 +420,10 @@ describe("RovingTabIndex", () => {
|
||||
|
||||
act(() => container.querySelectorAll("button")[0].focus());
|
||||
await userEvent.keyboard("[ArrowRight]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
|
||||
await userEvent.keyboard("[ArrowLeft]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
});
|
||||
|
||||
it("moves between multiple toolbar containers in one roving group", async () => {
|
||||
@@ -446,15 +446,15 @@ describe("RovingTabIndex", () => {
|
||||
|
||||
const buttons = container.querySelectorAll("button");
|
||||
act(() => buttons[1].focus());
|
||||
checkTabIndexes(buttons, [-1, 0, -1, -1]);
|
||||
expectTabIndexes(buttons, [-1, 0, -1, -1]);
|
||||
|
||||
await userEvent.keyboard("[ArrowRight]");
|
||||
expect(buttons[2]).toHaveFocus();
|
||||
checkTabIndexes(buttons, [-1, -1, 0, -1]);
|
||||
expectTabIndexes(buttons, [-1, -1, 0, -1]);
|
||||
|
||||
await userEvent.keyboard("[ArrowLeft]");
|
||||
expect(buttons[1]).toHaveFocus();
|
||||
checkTabIndexes(buttons, [-1, 0, -1, -1]);
|
||||
expectTabIndexes(buttons, [-1, 0, -1, -1]);
|
||||
});
|
||||
|
||||
it("handles Home, End, and loop across multiple toolbar containers", async () => {
|
||||
@@ -477,19 +477,19 @@ describe("RovingTabIndex", () => {
|
||||
|
||||
const buttons = container.querySelectorAll("button");
|
||||
act(() => buttons[2].focus());
|
||||
checkTabIndexes(buttons, [-1, -1, 0, -1]);
|
||||
expectTabIndexes(buttons, [-1, -1, 0, -1]);
|
||||
|
||||
await userEvent.keyboard("[End]");
|
||||
expect(buttons[3]).toHaveFocus();
|
||||
checkTabIndexes(buttons, [-1, -1, -1, 0]);
|
||||
expectTabIndexes(buttons, [-1, -1, -1, 0]);
|
||||
|
||||
await userEvent.keyboard("[ArrowRight]");
|
||||
expect(buttons[0]).toHaveFocus();
|
||||
checkTabIndexes(buttons, [0, -1, -1, -1]);
|
||||
expectTabIndexes(buttons, [0, -1, -1, -1]);
|
||||
|
||||
await userEvent.keyboard("[Home]");
|
||||
expect(buttons[0]).toHaveFocus();
|
||||
checkTabIndexes(buttons, [0, -1, -1, -1]);
|
||||
expectTabIndexes(buttons, [0, -1, -1, -1]);
|
||||
});
|
||||
|
||||
it("handles Home and End when handleHomeEnd=true", async () => {
|
||||
@@ -503,13 +503,13 @@ describe("RovingTabIndex", () => {
|
||||
);
|
||||
|
||||
act(() => container.querySelectorAll("button")[1].focus());
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
|
||||
await userEvent.keyboard("[End]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
|
||||
await userEvent.keyboard("[Home]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
});
|
||||
|
||||
it("loops when handleLoop=true", async () => {
|
||||
@@ -524,10 +524,10 @@ describe("RovingTabIndex", () => {
|
||||
|
||||
act(() => container.querySelectorAll("button")[2].focus());
|
||||
await userEvent.keyboard("[ArrowDown]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
|
||||
await userEvent.keyboard("[ArrowUp]");
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]);
|
||||
});
|
||||
|
||||
it("uses a custom getAction mapper", async () => {
|
||||
@@ -552,7 +552,7 @@ describe("RovingTabIndex", () => {
|
||||
await userEvent.keyboard("j");
|
||||
|
||||
expect(getAction).toHaveBeenCalled();
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]);
|
||||
});
|
||||
|
||||
it("handles input fields when handleInputFields=true", () => {
|
||||
@@ -569,7 +569,7 @@ describe("RovingTabIndex", () => {
|
||||
const input = getByRole("textbox", { name: "Search input" });
|
||||
|
||||
fireEvent.keyDown(input, { key: "ArrowDown" });
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0]);
|
||||
});
|
||||
|
||||
it("moves from an input field with Tab when handleInputFields=false", () => {
|
||||
@@ -586,7 +586,7 @@ describe("RovingTabIndex", () => {
|
||||
act(() => (input as HTMLElement).focus());
|
||||
|
||||
fireEvent.keyDown(input, { key: "Tab" });
|
||||
checkTabIndexes(container.querySelectorAll("button"), [-1, 0]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [-1, 0]);
|
||||
});
|
||||
|
||||
it("stops provider processing when onKeyDown prevents default", () => {
|
||||
@@ -606,7 +606,7 @@ describe("RovingTabIndex", () => {
|
||||
fireEvent.keyDown(container.querySelector('[role="toolbar"]')!, { key: "ArrowDown" });
|
||||
|
||||
expect(onKeyDown).toHaveBeenCalled();
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
});
|
||||
|
||||
it("calls scrollIntoView if specified", async () => {
|
||||
@@ -620,7 +620,7 @@ describe("RovingTabIndex", () => {
|
||||
);
|
||||
|
||||
act(() => container.querySelectorAll("button")[0].focus());
|
||||
checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
expectTabIndexes(container.querySelectorAll("button"), [0, -1, -1]);
|
||||
|
||||
const button = container.querySelectorAll("button")[1];
|
||||
const mock = vi.spyOn(button, "scrollIntoView");
|
||||
|
||||
@@ -153,7 +153,7 @@ export interface LinkedTextOptions {
|
||||
* Generates a linkifyjs options object that is reasonably paired down
|
||||
* to just the essentials required for an Element client.
|
||||
*
|
||||
* @return A `linkifyjs` `Opts` object. Used by `linkifyString` and `linkifyHtml
|
||||
* @returns A `linkifyjs` `Opts` object. Used by `linkifyString` and `linkifyHtml
|
||||
* @see {@link linkifyHtml}
|
||||
* @see {@link linkifyString}
|
||||
*/
|
||||
|
||||
+6
-2
@@ -9,8 +9,12 @@ import React, { type JSX, useEffect } from "react";
|
||||
import { fn } from "storybook/test";
|
||||
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import type { Room } from "./RoomListItemView";
|
||||
import { RoomListItemView, type RoomListItemViewSnapshot, type RoomListItemViewActions } from "./RoomListItemView";
|
||||
import {
|
||||
type Room,
|
||||
RoomListItemView,
|
||||
type RoomListItemViewSnapshot,
|
||||
type RoomListItemViewActions,
|
||||
} from "./RoomListItemView";
|
||||
import { useMockedViewModel } from "../../../../core/viewmodel";
|
||||
import { withViewDocs } from "../../../../../.storybook/withViewDocs";
|
||||
import { defaultSnapshot } from "./default-snapshot";
|
||||
|
||||
+2
-1
@@ -17,9 +17,10 @@ import {
|
||||
FlatVirtualizedList,
|
||||
getContainerAccessibleProps,
|
||||
type VirtualizedListContext,
|
||||
GroupedVirtualizedList,
|
||||
type GroupedVirtualizedListProps,
|
||||
} from "../../core/VirtualizedList";
|
||||
import type { RoomListViewSnapshot, RoomListViewModel } from "../RoomListView";
|
||||
import { GroupedVirtualizedList, type GroupedVirtualizedListProps } from "../../core/VirtualizedList";
|
||||
import { RoomListSectionHeaderView, RoomListStickySectionHeaderView } from "./RoomListSectionHeaderView";
|
||||
import { RoomListSectionHeaderDragOverlayView } from "./RoomListSectionHeaderDragOverlayView";
|
||||
import { RoomListItemWrapper } from "./RoomListItemWrapper";
|
||||
|
||||
@@ -26,7 +26,7 @@ export interface UploadButtonViewSnapshot {
|
||||
}
|
||||
|
||||
export interface UploadButtonViewActions {
|
||||
onUploadOptionSelected(type: string): void;
|
||||
onUploadOptionSelected(this: void, type: string): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ export interface RoomAvatarEventViewActions {
|
||||
/**
|
||||
* Invoked when the user opens the avatar image.
|
||||
*/
|
||||
onAvatarClick(): void;
|
||||
onAvatarClick(this: void): void;
|
||||
}
|
||||
|
||||
export type RoomAvatarEventViewModel = ViewModel<RoomAvatarEventViewSnapshot, RoomAvatarEventViewActions>;
|
||||
|
||||
+2
-1
@@ -19,7 +19,6 @@ import {
|
||||
type ImageBodyViewSnapshot,
|
||||
} from "./ImageBodyView";
|
||||
import imageSrc from "../../../../../../static/image-body/install-spinner.png";
|
||||
import thumbnailSrc from "../../../../../../static/image-body/install-spinner.png";
|
||||
import animatedGifSrc from "../../../../../../static/image-body/install-spinner.gif";
|
||||
const demoBlurhash = "LEHV6nWB2yk8pyo0adR*.7kCMdnj";
|
||||
const imageBodyViewStateOptions = [ImageBodyViewState.ERROR, ImageBodyViewState.HIDDEN, ImageBodyViewState.READY];
|
||||
@@ -29,6 +28,8 @@ const imageBodyViewPlaceholderOptions = [
|
||||
ImageBodyViewPlaceholder.BLURHASH,
|
||||
];
|
||||
|
||||
const thumbnailSrc = imageSrc;
|
||||
|
||||
type ImageBodyViewProps = ImageBodyViewSnapshot &
|
||||
ImageBodyViewActions & {
|
||||
className?: string;
|
||||
|
||||
@@ -28,6 +28,8 @@ type SharedRenderOptions = RenderOptions & {
|
||||
presentation?: Partial<EventPresentation>;
|
||||
};
|
||||
|
||||
const i18nApi = new I18nApi();
|
||||
|
||||
const wrapWithTooltipProvider = (Wrapper: RenderOptions["wrapper"], presentation?: Partial<EventPresentation>) => {
|
||||
return ({ children }: { children: React.ReactNode }) => {
|
||||
const resolvedPresentation: EventPresentation | undefined = presentation
|
||||
@@ -43,12 +45,12 @@ const wrapWithTooltipProvider = (Wrapper: RenderOptions["wrapper"], presentation
|
||||
|
||||
if (Wrapper) {
|
||||
return (
|
||||
<I18nContext.Provider value={new I18nApi()}>
|
||||
<I18nContext.Provider value={i18nApi}>
|
||||
<Wrapper>{content}</Wrapper>
|
||||
</I18nContext.Provider>
|
||||
);
|
||||
} else {
|
||||
return <I18nContext.Provider value={new I18nApi()}>{content}</I18nContext.Provider>;
|
||||
return <I18nContext.Provider value={i18nApi}>{content}</I18nContext.Provider>;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user