71 lines
1.6 KiB
TypeScript
71 lines
1.6 KiB
TypeScript
import { useEffect, useRef, type ReactNode } from "react";
|
|
import { SideSheet } from "@douyinfe/semi-ui-19";
|
|
|
|
/** Parent supplies a bounded flex area; only the data viewport owns scrolling. */
|
|
export function ResearchList({
|
|
label,
|
|
resetKey,
|
|
filters,
|
|
actions,
|
|
pagination,
|
|
children,
|
|
}: {
|
|
label: string;
|
|
resetKey: string;
|
|
filters?: ReactNode;
|
|
actions: ReactNode;
|
|
pagination: ReactNode;
|
|
children: ReactNode;
|
|
}) {
|
|
const viewport = useRef<HTMLDivElement>(null);
|
|
useEffect(() => {
|
|
viewport.current?.scrollTo({ top: 0, left: 0 });
|
|
}, [resetKey]);
|
|
return (
|
|
<section className="research-list" aria-label={label}>
|
|
{filters && <div className="research-list-filters">{filters}</div>}
|
|
<div className="research-list-actions">{actions}</div>
|
|
<div
|
|
ref={viewport}
|
|
className="research-list-scroll"
|
|
tabIndex={0}
|
|
aria-label={`${label}数据区`}
|
|
>
|
|
{children}
|
|
</div>
|
|
<div className="table-pagination">{pagination}</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
/** Keep drafts mounted while closed; inactive workspace pages must hide portals. */
|
|
export function ResearchDetail({
|
|
title,
|
|
visible,
|
|
width = "60%",
|
|
onClose,
|
|
children,
|
|
}: {
|
|
title: string;
|
|
visible: boolean;
|
|
width?: string;
|
|
onClose: () => void;
|
|
children: ReactNode;
|
|
}) {
|
|
return (
|
|
<SideSheet
|
|
title={title}
|
|
className="research-detail"
|
|
placement="right"
|
|
width={width}
|
|
visible={visible}
|
|
onCancel={onClose}
|
|
closeOnEsc
|
|
keepDOM
|
|
motion={false}
|
|
>
|
|
<div className="research-detail-content">{children}</div>
|
|
</SideSheet>
|
|
);
|
|
}
|