1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

fix ref logic error

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-04-08 09:06:04 -04:00
parent 9dc5872f77
commit 383a50cdbf
3 changed files with 42 additions and 14 deletions

View File

@ -5,6 +5,7 @@
import "./list.scss";
import type { ForwardedRef } from "react";
import React from "react";
import AnsiUp from "ansi_up";
import DOMPurify from "dompurify";
@ -28,8 +29,12 @@ export interface LogListProps {
const colorConverter = new AnsiUp();
export interface LogListRef {
scrollToItem: (index: number, align: Align) => void;
}
@observer
export class LogList extends React.Component<LogListProps> {
class NonForwardedLogList extends React.Component<LogListProps & { innerRef: ForwardedRef<LogListRef> }> {
@observable isJumpButtonVisible = false;
@observable isLastLineVisible = true;
@ -37,7 +42,7 @@ export class LogList extends React.Component<LogListProps> {
private virtualListRef = React.createRef<VirtualListRef>(); // A reference for VirtualList component
private lineHeight = 18; // Height of a log line. Should correlate with styles in pod-log-list.scss
constructor(props: LogListProps) {
constructor(props: any) {
super(props);
makeObservable(this);
autoBind(this);
@ -51,6 +56,27 @@ export class LogList extends React.Component<LogListProps> {
this.onUserScrolledUp(logs, prevLogs);
}),
]);
this.bindInnerRef({
scrollToItem: this.scrollToItem,
});
}
componentDidUpdate() {
this.bindInnerRef({
scrollToItem: this.scrollToItem,
});
}
componentWillUnmount() {
this.bindInnerRef(null);
}
private bindInnerRef(value: LogListRef | null) {
if (typeof this.props.innerRef === "function") {
this.props.innerRef(value);
} else if (this.props.innerRef && typeof this.props.innerRef === "object") {
this.props.innerRef.current = value;
}
}
onLogsInitialLoad(logs: string[], prevLogs: string[]) {
@ -246,3 +272,7 @@ export class LogList extends React.Component<LogListProps> {
);
}
}
export const LogList = React.forwardRef<LogListRef, LogListProps>((props, ref) => (
<NonForwardedLogList {...props} innerRef={ref} />
));

View File

@ -7,6 +7,7 @@ import React, { createRef, useEffect } from "react";
import { observer } from "mobx-react";
import { InfoPanel } from "../info-panel";
import { LogResourceSelector } from "./resource-selector";
import type { LogListRef } from "./list";
import { LogList } from "./list";
import { LogSearch } from "./search";
import { LogControls } from "./controls";
@ -30,7 +31,7 @@ interface Dependencies {
}
const NonInjectedLogsDockTab = observer(({ className, tab, model, subscribeStores }: Dependencies & LogsDockTabProps) => {
const logListElement = createRef<LogList>();
const logListElement = createRef<LogListRef>();
const data = model.logTabData.get();
useEffect(() => {

View File

@ -7,7 +7,7 @@
// API docs: https://react-window.now.sh
import "./virtual-list.scss";
import type { ForwardedRef, PropsWithoutRef, RefObject } from "react";
import type { ForwardedRef } from "react";
import React, { createRef, forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
import { observer } from "mobx-react";
import type { Align, ListChildComponentProps, ListOnScrollProps } from "react-window";
@ -28,7 +28,7 @@ export interface VirtualListProps<T extends { getId(): string } | string> {
selectedItemId?: string;
getRow?: (uid: T extends string ? number : string) => React.ReactElement | undefined | null;
onScroll?: (props: ListOnScrollProps) => void;
outerRef?: React.Ref<any>;
outerRef?: React.Ref<HTMLDivElement>;
/**
* If specified then AutoSizer will not be used and instead a fixed height
@ -53,7 +53,8 @@ function VirtualListInner<T extends { getId(): string } | string>({
onScroll = noop,
outerRef,
fixedHeight,
}: VirtualListProps<T>, ref: ForwardedRef<VirtualListRef>) {
forwardedRef,
}: VirtualListProps<T> & { forwardedRef?: ForwardedRef<VirtualListRef> }) {
const [overscanCount, setOverscanCount] = useState(initialOffset);
const listRef = createRef<VariableSizeList>();
const prevItems = useRef(items);
@ -75,7 +76,7 @@ function VirtualListInner<T extends { getId(): string } | string>({
}), [selectedItemId, [items]]);
const getItemSize = (index: number) => rowHeights[index];
useImperativeHandle(ref, () => ({
useImperativeHandle(forwardedRef, () => ({
scrollToItem: (index, align) => listRef.current?.scrollToItem(index, align),
}));
@ -130,13 +131,9 @@ function VirtualListInner<T extends { getId(): string } | string>({
);
}
const ForwardedVirtualList = forwardRef(VirtualListInner);
export function VirtualList<T extends { getId(): string } | string>(
props: PropsWithoutRef<VirtualListProps<T>> & { ref?: RefObject<VirtualListRef> },
) {
return <ForwardedVirtualList {...props as never} />;
}
export const VirtualList = forwardRef<VirtualListRef, VirtualListProps<string>>((props, ref) => (
<VirtualListInner {...props} forwardedRef={ref} />
)) as <T extends { getId(): string } | string>(props: VirtualListProps<T> & { ref?: ForwardedRef<VirtualListRef> }) => JSX.Element;
interface RowData<T extends { getId(): string } | string> {
items: T[];