Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tabs): add tabs components API #2256

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ robotMsg.json
.nyc_output
cypress-coverage
instrumented
cy-report
cy-report
.history
6 changes: 1 addition & 5 deletions DEVELOP_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,7 @@ npm run init

# 运行全部单元测试用例(包括所有example的ssr测试)
npm run test
# 运行全部单元测试用例
npm run test:unit
# 运行指定组件单元测试用例,xxx表示组件目录名称, 多个组件用空格分开
# eg: npm run test:unit button affix
npm run test:unit xxx
# 目前项目测试框架以采用 vitest, 如想单个测试,请下载对应的 vitest vscode插件,进行可视化操作

# 运行全部e2e测试用例
npm run test:e2e
Expand Down
19 changes: 18 additions & 1 deletion src/_util/useDragSorter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useCallback, useRef, useState } from 'react';
interface DragSortProps<T> {
sortOnDraggable: boolean;
onDragSort?: (context: DragSortContext<T>) => void;
onCustomDragEnd?: (context: DragSortContext<T>) => void;
onCustomDragStart?: (context: DragSortContext<T>) => void;
onDragOverCheck?: {
x?: boolean;
targetClassNameRegExp?: RegExp;
Expand Down Expand Up @@ -31,7 +33,7 @@ export interface DragSortContext<T> {
}

function useDragSorter<T>(props: DragSortProps<T>): DragSortInnerProps {
const { sortOnDraggable, onDragSort, onDragOverCheck } = props;
const { sortOnDraggable, onDragSort, onCustomDragEnd, onCustomDragStart, onDragOverCheck } = props;
const [draggingIndex, setDraggingIndex] = useState(-1);
const [dragStartData, setDragStartData] = useState(null);
const [isDropped, setIsDropped] = useState(null);
Expand Down Expand Up @@ -70,6 +72,7 @@ function useDragSorter<T>(props: DragSortProps<T>): DragSortInnerProps {
target: record,
targetIndex: index,
});

setDraggingIndex(index);
},
[
Expand Down Expand Up @@ -97,6 +100,13 @@ function useDragSorter<T>(props: DragSortProps<T>): DragSortInnerProps {
nodeWidth: width,
mouseX: e.clientX || 0,
});

onCustomDragStart?.({
currentIndex: index,
current: record,
target: dragStartData,
targetIndex: draggingIndex,
});
}
}

Expand All @@ -110,6 +120,13 @@ function useDragSorter<T>(props: DragSortProps<T>): DragSortInnerProps {
setIsDropped(false);
setDraggingIndex(-1);
setDragStartData(null);

onCustomDragEnd?.({
currentIndex: -1,
current: null,
target: dragStartData,
targetIndex: draggingIndex,
});
}
function getDragProps(index, record: T) {
if (sortOnDraggable) {
Expand Down
2 changes: 2 additions & 0 deletions src/tabs/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const Tabs = forwardRefWithStatics(
x: true,
targetClassNameRegExp: new RegExp(targetClassNameRegExpStr),
},
onCustomDragStart: props?.onDragStart,
onCustomDragEnd: props?.onDragEnd,
});

const memoChildren = useMemo(() => {
Expand Down
14 changes: 12 additions & 2 deletions src/tabs/__tests__/tabs.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,16 @@ describe('Tabs 组件测试', () => {
tagBox.removeChild(reactTag);
});

const onDragStart = vi.fn(() => {
console.log('888---999');
});
const onDragEnd = vi.fn(() => {
console.log('888---999');
});

const { container } = render(
<div>
<Tabs dragSort onDragSort={onDragSort}>
<Tabs dragSort onDragSort={onDragSort} onDragStart={onDragStart} onDragEnd={onDragEnd}>
<TabPanel value={'vue'} label={'vue'}>
<div>vueContent</div>
</TabPanel>
Expand All @@ -336,7 +343,10 @@ describe('Tabs 组件测试', () => {
targetIndex: 0,
},
});
expect(onDragSort).toHaveBeenCalled(1);
expect(onDragSort).toHaveBeenCalled();
expect(onDragStart).toHaveBeenCalled();
waitFor(() => expect(onDragEnd).toHaveBeenCalled());

expect(onDragSort.mock.calls[0][0].target.value).toEqual('vue');
expect(container.querySelectorAll('.t-tabs__nav-item-text-wrapper').item(0).firstChild.nodeValue).toEqual('react');
});
Expand Down
56 changes: 36 additions & 20 deletions src/tabs/_example/drag-sort.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,37 @@ const defaultList = [
];

export default function DragSortExample() {

const [tabList1, setTabList1] = useState([...defaultList]);
const [tabList2, setTabList2] = useState([...defaultList]);

const onDragSort1 = useCallback(debounce(({ currentIndex, targetIndex }) => {
const temp = tabList1[currentIndex];
tabList1[currentIndex] = tabList1[targetIndex];
tabList1[targetIndex] = temp;
setTabList1([...tabList1]);
}, 500), [tabList1]);
const onDragSort1 = useCallback(
debounce((contents) => {
console.log('%c [ onDragSort1 ]-19', 'font-size:13px; background:#671c39; color:#ab607d;', contents);
const temp = tabList1[contents.currentIndex];
tabList1[contents.currentIndex] = tabList1[contents.targetIndex];
tabList1[contents.targetIndex] = temp;
setTabList1([...tabList1]);
}, 500),
[tabList1],
);

const onDragSort2 = useCallback(
debounce(({ currentIndex, targetIndex }) => {
const temp = tabList2[currentIndex];
tabList2[currentIndex] = tabList2[targetIndex];
tabList2[targetIndex] = temp;
setTabList2([...tabList2]);
}, 500),
[tabList2],
);

const onDragStart = useCallback((dragStartContents) => {
console.log('%c [ onDragStart ]-39', 'font-size:13px; background:#1b7980; color:#5fbdc4;', dragStartContents);
}, []);

const onDragSort2 = useCallback(debounce(({ currentIndex, targetIndex }) => {
const temp = tabList2[currentIndex];
tabList2[currentIndex] = tabList2[targetIndex];
tabList2[targetIndex] = temp;
setTabList2([...tabList2]);
}, 500), [tabList2]);
const onDragEnd = useCallback((dragEndContents) => {
console.log('%c [ onDragEnd ]-43', 'font-size:13px; background:#933e71; color:#d782b5;', dragEndContents);
}, []);

return (
<Space direction="vertical" style={{ width: '100%' }}>
Expand All @@ -36,21 +50,23 @@ export default function DragSortExample() {
list={tabList1}
dragSort
onDragSort={onDragSort1}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
/>
<Tabs
dragSort
onDragSort={onDragSort2}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
placement={'top'}
size={'medium'}
defaultValue={1}
>
{
tabList2.map(({ label, value, panel }) =>
<TabPanel key={value} value={value} label={label}>
{panel}
</TabPanel>
)
}
{tabList2.map(({ label, value, panel }) => (
<TabPanel key={value} value={value} label={label}>
{panel}
</TabPanel>
))}
</Tabs>
</Space>
);
Expand Down
2 changes: 2 additions & 0 deletions src/tabs/tabs.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ defaultValue | String / Number | - | uncontrolled property。Typescript:`TabVa
onAdd | Function | | Typescript:`(context: { e: MouseEvent }) => void`<br/> | N
onChange | Function | | Typescript:`(value: TabValue) => void`<br/> | N
onDragSort | Function | | Typescript:`(context: TabsDragSortContext) => void`<br/>trigger on drag sort。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/tabs/type.ts)。<br/>`interface TabsDragSortContext { currentIndex: number; current: TabValue; targetIndex: number; target: TabValue }`<br/> | N
onDragStart | Function | | Typescript:`(context: TabsDragSortContext) => void`<br/>trigger when drag sort starts。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/tabs/type.ts)。<br/>`interface TabsDragSortContext { currentIndex: number; current: TabValue; targetIndex: number; target: TabValue }`<br/> | N
onDragEnd | Function | | Typescript:`(context: TabsDragSortContext) => void`<br/>trigger when drag sort ends。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/tabs/type.ts)。<br/>`interface TabsDragSortContext { currentIndex: number; current: TabValue; targetIndex: number; target: TabValue }`<br/> | N
onRemove | Function | | Typescript:`(options: { value: TabValue; index: number; e: MouseEvent }) => void`<br/> | N

### TabPanel Props
Expand Down
2 changes: 2 additions & 0 deletions src/tabs/tabs.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ defaultValue | String / Number | - | 激活的选项卡值。非受控属性。T
onAdd | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>添加选项卡时触发 | N
onChange | Function | | TS 类型:`(value: TabValue) => void`<br/>激活的选项卡发生变化时触发 | N
onDragSort | Function | | TS 类型:`(context: TabsDragSortContext) => void`<br/>拖拽排序时触发。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/tabs/type.ts)。<br/>`interface TabsDragSortContext { currentIndex: number; current: TabValue; targetIndex: number; target: TabValue }`<br/> | N
onDragStart | Function | | TS 类型:`(context: TabsDragSortContext) => void`<br/>拖拽排序开始时触发。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/tabs/type.ts)。<br/>`interface TabsDragSortContext { currentIndex: number; current: TabValue; targetIndex: number; target: TabValue }`<br/> | N
onDragEnd | Function | | TS 类型:`(context: TabsDragSortContext) => void`<br/>拖拽排序结束时触发。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/tabs/type.ts)。<br/>`interface TabsDragSortContext { currentIndex: number; current: TabValue; targetIndex: number; target: TabValue }`<br/> | N
onRemove | Function | | TS 类型:`(options: { value: TabValue; index: number; e: MouseEvent }) => void`<br/>删除选项卡时触发 | N

### TabPanel Props
Expand Down
8 changes: 8 additions & 0 deletions src/tabs/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ export interface TdTabsProps {
* 拖拽排序时触发
*/
onDragSort?: (context: TabsDragSortContext) => void;
/**
* 拖拽排序开始时出发
*/
onDragStart?: (context: TabsDragSortContext) => void;
/**
* 拖拽排序结束时出发
*/
onDragEnd?: (context: TabsDragSortContext) => void;
/**
* 删除选项卡时触发
*/
Expand Down