- Caret:6px CSS 折角(open 切朝向,size 可调),Menu 与 Select 改为复用它, 两处各自的画法删掉,全库只剩一份 - SortableList:可拖拽排序的条目列表(items / activeKey / onSelect / onReorder), 拖拽位置计算从应用里挪进组件,顺序没变不回调 - 展示页:菜单补「折叠箭头」,新增 #sortable 一节并挂到导航 - COMPONENTS.md 契约 3.48 / 3.49、组件地图、README 清单、变更记录同步
89 lines
3.0 KiB
TypeScript
89 lines
3.0 KiB
TypeScript
import { useState } from 'react'
|
|
import { SortableList, Text } from '../../src'
|
|
import { Demo } from '../components/Demo'
|
|
import { PropsTable } from '../components/PropsTable'
|
|
import { Section } from '../components/Section'
|
|
|
|
const INITIAL = [
|
|
{ key: 'pin', label: '常用推荐', meta: 12 },
|
|
{ key: 'movie', label: '推荐电影', meta: 12 },
|
|
{ key: 'ces', label: 'CES 现场报道', meta: 12 },
|
|
{ key: 'tools', label: '开发工具', meta: 5 },
|
|
]
|
|
|
|
export function Sortables() {
|
|
const [items, setItems] = useState(INITIAL)
|
|
const [activeKey, setActiveKey] = useState('pin')
|
|
|
|
const reorder = (keys: string[]) => {
|
|
setItems((current) =>
|
|
keys
|
|
.map((key) => current.find((item) => item.key === key))
|
|
.filter((item): item is (typeof INITIAL)[number] => item !== undefined),
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Section
|
|
id="sortable"
|
|
title="排序列表"
|
|
api="SortableList"
|
|
desc="一列可拖拽排序的条目:拖动改顺序、点击选中,顺序变化通过 onReorder 交回页面。只做鼠标拖拽,需要键盘排序时在外面配上移/下移按钮。"
|
|
>
|
|
<Demo
|
|
title="基础用法"
|
|
desc="拖住左侧手柄上下移动,松手后把新的 key 顺序交给 onReorder;点击选中项会高亮。"
|
|
layout="column"
|
|
code={`const [items, setItems] = useState(INITIAL)
|
|
|
|
<SortableList
|
|
items={items}
|
|
activeKey={activeKey}
|
|
onSelect={setActiveKey}
|
|
onReorder={(keys) => setItems(reorder(keys))}
|
|
/>`}
|
|
>
|
|
<div style={{ width: 280 }}>
|
|
<SortableList
|
|
items={items}
|
|
activeKey={activeKey}
|
|
onSelect={setActiveKey}
|
|
onReorder={reorder}
|
|
/>
|
|
</div>
|
|
</Demo>
|
|
|
|
<Demo
|
|
title="空态"
|
|
desc="items 为空时渲染 emptyText;不传就不显示空态。"
|
|
layout="column"
|
|
code={`<SortableList items={[]} onSelect={() => {}} onReorder={() => {}} emptyText="还没有卡片" />`}
|
|
>
|
|
<div style={{ width: 280 }}>
|
|
<SortableList
|
|
items={[]}
|
|
onSelect={() => undefined}
|
|
onReorder={() => undefined}
|
|
emptyText="还没有卡片"
|
|
/>
|
|
</div>
|
|
</Demo>
|
|
|
|
<PropsTable
|
|
rows={[
|
|
{ name: 'items', type: 'SortableItem[]', required: true, desc: '{ key, label, meta? }' },
|
|
{ name: 'onSelect', type: '(key: string) => void', required: true, desc: '点击选中' },
|
|
{ name: 'onReorder', type: '(keys: string[]) => void', required: true, desc: '拖拽后的完整顺序' },
|
|
{ name: 'activeKey', type: 'string', desc: '当前选中项' },
|
|
{ name: 'disabled', type: 'boolean', defaultValue: 'false', desc: '排序保存中,禁止再次拖动' },
|
|
{ name: 'emptyText', type: 'ReactNode', desc: '空态文案,不传则不渲染' },
|
|
]}
|
|
/>
|
|
|
|
<Text size="sm" tone="muted">
|
|
说明:拖拽只在条目之间生效;松手时若顺序没变不会触发 onReorder。
|
|
</Text>
|
|
</Section>
|
|
)
|
|
}
|