Remove onSelectItem and space/enter handing from ListView (#30601)
* Remove onSelectItem and space/enter handing from ListView(And therefore memberlist).) * remove unused imports * fix unit test
This commit is contained in:
@@ -29,12 +29,6 @@ export interface IListViewProps<Item, Context>
|
||||
*/
|
||||
items: Item[];
|
||||
|
||||
/**
|
||||
* Callback function called when an item is selected (via Enter/Space key).
|
||||
* @param item - The selected item from the items array
|
||||
*/
|
||||
onSelectItem: (item: Item) => void;
|
||||
|
||||
/**
|
||||
* Function that renders each list item as a JSX element.
|
||||
* @param index - The index of the item in the list
|
||||
@@ -79,7 +73,7 @@ export interface IListViewProps<Item, Context>
|
||||
*/
|
||||
export function ListView<Item, Context = any>(props: IListViewProps<Item, Context>): React.ReactElement {
|
||||
// Extract our custom props to avoid conflicts with Virtuoso props
|
||||
const { items, onSelectItem, getItemComponent, isItemFocusable, getItemKey, context, ...virtuosoProps } = props;
|
||||
const { items, getItemComponent, isItemFocusable, getItemKey, context, ...virtuosoProps } = props;
|
||||
/** Reference to the Virtuoso component for programmatic scrolling */
|
||||
const virtuosoHandleRef = useRef<VirtuosoHandle>(null);
|
||||
/** Reference to the DOM element containing the virtualized list */
|
||||
@@ -186,10 +180,6 @@ export function ListView<Item, Context = any>(props: IListViewProps<Item, Contex
|
||||
} else if (e.code === "ArrowDown" && currentIndex !== undefined) {
|
||||
scrollToItem(currentIndex + 1, true);
|
||||
handled = true;
|
||||
} else if ((e.code === "Enter" || e.code === "Space") && currentIndex !== undefined) {
|
||||
const item = items[currentIndex];
|
||||
onSelectItem(item);
|
||||
handled = true;
|
||||
} else if (e.code === "Home") {
|
||||
scrollToIndex(0);
|
||||
handled = true;
|
||||
@@ -211,7 +201,7 @@ export function ListView<Item, Context = any>(props: IListViewProps<Item, Contex
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
[scrollToIndex, scrollToItem, tabIndexKey, keyToIndexMap, visibleRange, items, onSelectItem],
|
||||
[scrollToIndex, scrollToItem, tabIndexKey, keyToIndexMap, visibleRange, items],
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,8 +38,6 @@ import { isValid3pidInvite } from "../../../RoomInvite";
|
||||
import { type ThreePIDInvite } from "../../../models/rooms/ThreePIDInvite";
|
||||
import { type XOR } from "../../../@types/common";
|
||||
import { useTypedEventEmitter } from "../../../hooks/useEventEmitter";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
|
||||
type Member = XOR<{ member: RoomMember }, { threePidInvite: ThreePIDInvite }>;
|
||||
|
||||
@@ -113,7 +111,6 @@ export interface MemberListViewState {
|
||||
shouldShowSearch: boolean;
|
||||
isLoading: boolean;
|
||||
canInvite: boolean;
|
||||
onClickMember: (member: RoomMember | ThreePIDInvite) => void;
|
||||
onInviteButtonClick: (ev: ButtonEvent) => void;
|
||||
}
|
||||
export function useMemberListViewModel(roomId: string): MemberListViewState {
|
||||
@@ -136,14 +133,6 @@ export function useMemberListViewModel(roomId: string): MemberListViewState {
|
||||
*/
|
||||
const [memberCount, setMemberCount] = useState(0);
|
||||
|
||||
const onClickMember = (member: RoomMember | ThreePIDInvite): void => {
|
||||
dis.dispatch({
|
||||
action: Action.ViewUser,
|
||||
member: member,
|
||||
push: true,
|
||||
});
|
||||
};
|
||||
|
||||
const loadMembers = useMemo(
|
||||
() =>
|
||||
throttle(
|
||||
@@ -278,7 +267,6 @@ export function useMemberListViewModel(roomId: string): MemberListViewState {
|
||||
isPresenceEnabled,
|
||||
isLoading,
|
||||
onInviteButtonClick,
|
||||
onClickMember,
|
||||
shouldShowSearch: totalMemberCount >= 20,
|
||||
canInvite,
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ interface IProps {
|
||||
|
||||
const MemberListView: React.FC<IProps> = (props: IProps) => {
|
||||
const vm = useMemberListViewModel(props.roomId);
|
||||
const { isPresenceEnabled, onClickMember, memberCount } = vm;
|
||||
const { isPresenceEnabled, memberCount } = vm;
|
||||
|
||||
const getItemKey = useCallback((item: MemberWithSeparator): string => {
|
||||
if (item === SEPARATOR) {
|
||||
@@ -80,19 +80,6 @@ const MemberListView: React.FC<IProps> = (props: IProps) => {
|
||||
[isPresenceEnabled, getItemKey, memberCount],
|
||||
);
|
||||
|
||||
const handleSelectItem = useCallback(
|
||||
(item: MemberWithSeparator): void => {
|
||||
if (item !== SEPARATOR) {
|
||||
if (item.member) {
|
||||
onClickMember(item.member);
|
||||
} else {
|
||||
onClickMember(item.threePidInvite);
|
||||
}
|
||||
}
|
||||
},
|
||||
[onClickMember],
|
||||
);
|
||||
|
||||
const isItemFocusable = useCallback((item: MemberWithSeparator): boolean => {
|
||||
return item !== SEPARATOR;
|
||||
}, []);
|
||||
@@ -112,7 +99,6 @@ const MemberListView: React.FC<IProps> = (props: IProps) => {
|
||||
</Form.Root>
|
||||
<ListView
|
||||
items={vm.members}
|
||||
onSelectItem={handleSelectItem}
|
||||
getItemComponent={getItemComponent}
|
||||
getItemKey={getItemKey}
|
||||
isItemFocusable={isItemFocusable}
|
||||
|
||||
@@ -21,7 +21,6 @@ const SEPARATOR_ITEM = "SEPARATOR" as const;
|
||||
type TestItemWithSeparator = TestItem | typeof SEPARATOR_ITEM;
|
||||
|
||||
describe("ListView", () => {
|
||||
const mockOnSelectItem = jest.fn();
|
||||
const mockGetItemComponent = jest.fn();
|
||||
const mockIsItemFocusable = jest.fn();
|
||||
|
||||
@@ -34,7 +33,6 @@ describe("ListView", () => {
|
||||
|
||||
const defaultProps: IListViewProps<TestItemWithSeparator, any> = {
|
||||
items: defaultItems,
|
||||
onSelectItem: mockOnSelectItem,
|
||||
getItemComponent: mockGetItemComponent,
|
||||
isItemFocusable: mockIsItemFocusable,
|
||||
getItemKey: (item) => (typeof item === "string" ? item : item.id),
|
||||
@@ -87,33 +85,6 @@ describe("ListView", () => {
|
||||
});
|
||||
|
||||
describe("Keyboard Navigation", () => {
|
||||
it("should handle Enter key and call onSelectItem when focused", async () => {
|
||||
renderListViewWithHeight();
|
||||
const container = screen.getByRole("grid");
|
||||
|
||||
expect(container.querySelectorAll(".mx_item")).toHaveLength(4);
|
||||
|
||||
// Focus to activate the list and navigate to first focusable item
|
||||
fireEvent.focus(container);
|
||||
|
||||
fireEvent.keyDown(container, { code: "Enter" });
|
||||
|
||||
expect(mockOnSelectItem).toHaveBeenCalledWith(defaultItems[0]);
|
||||
});
|
||||
|
||||
it("should handle Space key and call onSelectItem when focused", () => {
|
||||
renderListViewWithHeight();
|
||||
const container = screen.getByRole("grid");
|
||||
|
||||
expect(container.querySelectorAll(".mx_item")).toHaveLength(4);
|
||||
// Focus to activate the list and navigate to first focusable item
|
||||
fireEvent.focus(container);
|
||||
|
||||
fireEvent.keyDown(container, { code: "Space" });
|
||||
|
||||
expect(mockOnSelectItem).toHaveBeenCalledWith(defaultItems[0]);
|
||||
});
|
||||
|
||||
it("should handle ArrowDown key navigation", () => {
|
||||
renderListViewWithHeight();
|
||||
const container = screen.getByRole("grid");
|
||||
|
||||
Reference in New Issue
Block a user