feat: 收集箱侧边栏UI美化 — 自定义滚动条、隐藏空分组、优化列表项间距
This commit is contained in:
@@ -5,11 +5,10 @@ import { type ReactNode, useState } from "react";
|
||||
interface MaterialGroupProps {
|
||||
children: ReactNode;
|
||||
count: number;
|
||||
emptyText?: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export function MaterialGroup({ children, count, emptyText, label }: MaterialGroupProps) {
|
||||
export function MaterialGroup({ children, count, label }: MaterialGroupProps) {
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
|
||||
return (
|
||||
@@ -23,17 +22,7 @@ export function MaterialGroup({ children, count, emptyText, label }: MaterialGro
|
||||
({count})
|
||||
</Typography.Text>
|
||||
</div>
|
||||
{!collapsed && (
|
||||
<div className="app-inbox-group-content">
|
||||
{count === 0 && emptyText ? (
|
||||
<Typography.Text className="app-inbox-group-empty" type="secondary">
|
||||
{emptyText}
|
||||
</Typography.Text>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{!collapsed && <div className="app-inbox-group-content">{children}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,13 @@ import {
|
||||
PlusOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Button, Empty, Segmented, Skeleton } from "antd";
|
||||
import "overlayscrollbars/styles/overlayscrollbars.css";
|
||||
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
import type { Material } from "../types";
|
||||
|
||||
import { useIsDark } from "../../../shared/hooks/use-is-dark";
|
||||
import { MaterialCard } from "./MaterialCard";
|
||||
import { MaterialGroup } from "./MaterialGroup";
|
||||
|
||||
@@ -84,6 +87,7 @@ type FilterValue = (typeof STATUS_FILTER_OPTIONS)[number]["value"];
|
||||
|
||||
export function MaterialList({ loading, materials, onAddClick, onDelete, onSelect, selectedId }: MaterialListProps) {
|
||||
const [filterStatus, setFilterStatus] = useState<FilterValue>("all");
|
||||
const isDark = useIsDark();
|
||||
|
||||
const filteredMaterials = useMemo(() => {
|
||||
if (filterStatus === "all") return materials;
|
||||
@@ -106,8 +110,6 @@ export function MaterialList({ loading, materials, onAddClick, onDelete, onSelec
|
||||
[materials],
|
||||
);
|
||||
|
||||
const showAllGroups = filterStatus === "all";
|
||||
|
||||
return (
|
||||
<div className="app-inbox-sidebar">
|
||||
<div className="app-inbox-sidebar-header">
|
||||
@@ -116,7 +118,16 @@ export function MaterialList({ loading, materials, onAddClick, onDelete, onSelec
|
||||
</Button>
|
||||
<Segmented block onChange={(value) => setFilterStatus(value)} options={segmentedOptions} value={filterStatus} />
|
||||
</div>
|
||||
<div className="app-inbox-list">
|
||||
<OverlayScrollbarsComponent
|
||||
className="app-inbox-list"
|
||||
options={{
|
||||
overflow: { x: "hidden", y: "scroll" },
|
||||
scrollbars: {
|
||||
autoHide: "move",
|
||||
theme: isDark ? "os-theme-custom-dark" : "os-theme-custom",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{loading ? (
|
||||
<Skeleton active paragraph={{ rows: 6 }} title={false} />
|
||||
) : materials.length === 0 ? (
|
||||
@@ -125,14 +136,9 @@ export function MaterialList({ loading, materials, onAddClick, onDelete, onSelec
|
||||
<Empty description="当前筛选条件下无素材" image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
||||
) : (
|
||||
groupedMaterials.map((group) => {
|
||||
if (!showAllGroups && group.items.length === 0) return null;
|
||||
if (group.items.length === 0) return null;
|
||||
return (
|
||||
<MaterialGroup
|
||||
count={group.items.length}
|
||||
emptyText="暂无"
|
||||
key={group.key}
|
||||
label={GROUP_LABELS[group.key]}
|
||||
>
|
||||
<MaterialGroup count={group.items.length} key={group.key} label={GROUP_LABELS[group.key]}>
|
||||
{group.items.map((material) => (
|
||||
<MaterialCard
|
||||
key={material.id}
|
||||
@@ -146,7 +152,7 @@ export function MaterialList({ loading, materials, onAddClick, onDelete, onSelec
|
||||
);
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</OverlayScrollbarsComponent>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ body {
|
||||
|
||||
.app-content {
|
||||
overflow: auto;
|
||||
padding: var(--ant-padding-xl) var(--ant-padding-xl);
|
||||
padding: var(--ant-padding) var(--ant-padding-lg);
|
||||
}
|
||||
|
||||
.app-chat-page {
|
||||
@@ -277,7 +277,6 @@ body {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.app-inbox-content {
|
||||
@@ -353,6 +352,8 @@ body {
|
||||
}
|
||||
|
||||
.material-item-time {
|
||||
display: block;
|
||||
margin-top: var(--ant-margin-xxs);
|
||||
font-size: var(--ant-font-size-sm);
|
||||
}
|
||||
|
||||
@@ -396,12 +397,6 @@ body {
|
||||
padding-bottom: var(--ant-padding-xs);
|
||||
}
|
||||
|
||||
.app-inbox-group-empty {
|
||||
display: block;
|
||||
padding: var(--ant-padding-xs) var(--ant-padding);
|
||||
font-size: var(--ant-font-size-sm);
|
||||
}
|
||||
|
||||
.app-inbox-filter-count {
|
||||
margin-left: 4px;
|
||||
font-size: var(--ant-font-size-sm);
|
||||
|
||||
Reference in New Issue
Block a user