Skip to content
This repository was archived by the owner on Apr 11, 2025. It is now read-only.

Commit c0c170c

Browse files
committed
♻️ refactor: 初步完成组件重构
1 parent f2f0b80 commit c0c170c

File tree

19 files changed

+425
-97
lines changed

19 files changed

+425
-97
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React from 'react';
2+
import { DragOverlay } from '@dnd-kit/core';
3+
import { Item } from './components';
4+
import type { FC } from 'react';
5+
6+
import type { SortableItem, SortableProps } from './types';
7+
8+
interface DraggingOverlayProps
9+
extends Pick<
10+
SortableProps,
11+
| 'adjustScale'
12+
| 'dropAnimation'
13+
| 'renderItem'
14+
| 'handle'
15+
| 'wrapperStyle'
16+
| 'getItemStyles'
17+
> {
18+
dragging: boolean;
19+
item: SortableItem;
20+
activeIndex: number;
21+
activeId: string;
22+
}
23+
24+
const DraggingOverlay: FC<DraggingOverlayProps> = ({
25+
dragging,
26+
dropAnimation,
27+
adjustScale,
28+
item,
29+
renderItem,
30+
handle,
31+
getItemStyles,
32+
wrapperStyle,
33+
activeIndex,
34+
activeId,
35+
}) => {
36+
return (
37+
<DragOverlay adjustScale={adjustScale} dropAnimation={dropAnimation}>
38+
{dragging ? (
39+
<Item
40+
value={item.id}
41+
handle={handle}
42+
renderItem={renderItem}
43+
wrapperStyle={wrapperStyle({
44+
index: activeIndex,
45+
isDragging: true,
46+
id: item.id,
47+
})}
48+
style={getItemStyles({
49+
id: item.id,
50+
index: activeIndex,
51+
isSorting: activeId !== null,
52+
isDragging: true,
53+
overIndex: -1,
54+
isDragOverlay: true,
55+
})}
56+
dragOverlay
57+
/>
58+
) : null}
59+
</DragOverlay>
60+
);
61+
};
62+
63+
export default DraggingOverlay;

packages/sortable-list/src/Item/components/Action/index.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/sortable-list/src/Item/components/Handle/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/sortable-list/src/Item/index.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/sortable-list/src/Sortable.tsx

Lines changed: 65 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import type { FC } from 'react';
2-
import React, { useCallback, useState } from 'react';
2+
import React from 'react';
33
import { createPortal } from 'react-dom';
44

55
import {
66
closestCenter,
7-
DragOverlay,
87
DndContext,
98
KeyboardSensor,
109
MouseSensor,
@@ -14,16 +13,20 @@ import {
1413
} from '@dnd-kit/core';
1514

1615
import {
17-
arrayMove,
1816
SortableContext,
1917
sortableKeyboardCoordinates,
2018
} from '@dnd-kit/sortable';
21-
import useMergeState from 'use-merge-value';
2219

23-
import { Item } from './Item';
24-
import { Wrapper } from './Wrapper';
20+
import { Wrapper } from './components';
21+
2522
import SortableItem from './SortableItem';
26-
import type { SortableItemList, SortableProps } from './types';
23+
import DraggingOverlay from './DraggingOverlay';
24+
25+
import type { SortableProps } from './types';
26+
27+
import { useSortableList } from './hooks/useSortableList';
28+
import { useActiveItem } from './hooks/useActiveItem';
29+
import { getIndexOfActiveItem } from './utils';
2730

2831
export const Sortable: FC<SortableProps> = ({
2932
activationConstraint,
@@ -44,20 +47,12 @@ export const Sortable: FC<SortableProps> = ({
4447
modifiers,
4548
removable,
4649
renderItem,
47-
reorderItems = arrayMove,
4850
strategy,
4951
style,
5052
useDragOverlay = true,
5153
wrapperStyle = () => ({}),
54+
direction,
5255
}) => {
53-
const [items, setItems] = useMergeState<SortableItemList>([], {
54-
value: controlledItems,
55-
defaultValue: defaultItems,
56-
onChange: onItemChange,
57-
});
58-
59-
const [activeId, setActiveId] = useState<string | null>(null);
60-
6156
const sensors = useSensors(
6257
useSensor(MouseSensor, {
6358
activationConstraint,
@@ -70,96 +65,82 @@ export const Sortable: FC<SortableProps> = ({
7065
}),
7166
);
7267

73-
const getIndex = items.indexOf.bind(items);
74-
const activeIndex = activeId ? getIndex(activeId) : -1;
68+
const { items, dispatchSortable } = useSortableList({
69+
value: controlledItems,
70+
defaultValue: defaultItems,
71+
onChange: onItemChange,
72+
});
7573

76-
const handleRemove = useCallback(
77-
(id: string) => {
78-
if (!removable) return;
74+
const { deactivateItem, activateItem, activeId, isDragging } =
75+
useActiveItem();
7976

80-
const newItem = items.filter((item) => item.id !== id);
81-
setItems(newItem);
82-
},
83-
[removable, items],
84-
);
77+
const activeIndex = getIndexOfActiveItem(items, activeId);
78+
79+
const handleRemove = (id: string) => {
80+
if (!removable) return;
81+
82+
dispatchSortable({ type: 'removeItem', id });
83+
};
8584

8685
return (
8786
<DndContext
8887
sensors={sensors}
8988
collisionDetection={collisionDetection}
9089
onDragStart={({ active }) => {
91-
if (!active) {
92-
return;
93-
}
90+
if (!active) return;
9491

95-
setActiveId(active.id);
92+
activateItem(active.id);
9693
}}
9794
onDragEnd={({ over }) => {
98-
setActiveId(null);
99-
10095
if (over) {
101-
const overIndex = getIndex(over.id);
102-
if (activeIndex !== overIndex) {
103-
const newItems = reorderItems(items, activeIndex, overIndex);
96+
const endIndex = getIndexOfActiveItem(items, over.id);
10497

105-
setItems(newItems);
106-
}
98+
dispatchSortable({
99+
type: 'reorder',
100+
startIndex: activeIndex,
101+
endIndex,
102+
});
107103
}
104+
deactivateItem();
108105
}}
109-
onDragCancel={() => setActiveId(null)}
106+
onDragCancel={() => deactivateItem()}
110107
measuring={measuring}
111108
modifiers={modifiers}
112109
>
113-
<Wrapper style={style}>
114-
<SortableContext items={items} strategy={strategy}>
115-
<Container>
116-
{items.map((value, index) => (
117-
<SortableItem
118-
key={value.id}
119-
id={value.id}
120-
handle={handle}
121-
index={index}
122-
style={getItemStyles}
123-
wrapperStyle={wrapperStyle}
124-
disabled={isDisabled(value.id)}
125-
renderItem={renderItem}
126-
onRemove={handleRemove}
127-
animateLayoutChanges={animateLayoutChanges}
128-
useDragOverlay={useDragOverlay}
129-
getNewIndex={getNewIndex}
130-
/>
131-
))}
132-
</Container>
133-
</SortableContext>
134-
</Wrapper>
110+
<SortableContext items={items} strategy={strategy}>
111+
<Container style={style}>
112+
{items.map((value, index) => (
113+
<SortableItem
114+
key={value.id}
115+
id={value.id}
116+
handle={handle}
117+
index={index}
118+
style={getItemStyles}
119+
wrapperStyle={wrapperStyle}
120+
disabled={isDisabled(value.id)}
121+
renderItem={renderItem}
122+
onRemove={handleRemove}
123+
animateLayoutChanges={animateLayoutChanges}
124+
useDragOverlay={useDragOverlay}
125+
getNewIndex={getNewIndex}
126+
/>
127+
))}
128+
</Container>
129+
</SortableContext>
135130
{useDragOverlay
136131
? createPortal(
137-
<DragOverlay
132+
<DraggingOverlay
138133
adjustScale={adjustScale}
139134
dropAnimation={dropAnimation}
140-
>
141-
{activeId ? (
142-
<Item
143-
value={items[activeIndex]}
144-
handle={handle}
145-
renderItem={renderItem}
146-
wrapperStyle={wrapperStyle({
147-
index: activeIndex,
148-
isDragging: true,
149-
id: items[activeIndex].id,
150-
})}
151-
style={getItemStyles({
152-
id: items[activeIndex].id,
153-
index: activeIndex,
154-
isSorting: activeId !== null,
155-
isDragging: true,
156-
overIndex: -1,
157-
isDragOverlay: true,
158-
})}
159-
dragOverlay
160-
/>
161-
) : null}
162-
</DragOverlay>,
135+
dragging={isDragging}
136+
activeId={activeId}
137+
activeIndex={activeIndex}
138+
item={items[activeIndex]}
139+
getItemStyles={getItemStyles}
140+
wrapperStyle={wrapperStyle}
141+
handle={handle}
142+
renderItem={renderItem}
143+
/>,
163144
document.body,
164145
)
165146
: null}

packages/sortable-list/src/SortableItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import React from 'react';
44
import type { AnimateLayoutChanges, NewIndexGetter } from '@dnd-kit/sortable';
55
import { useSortable } from '@dnd-kit/sortable';
66

7-
import { Item } from './Item';
7+
import { Item } from './components';
88

99
interface SortableItemProps {
1010
animateLayoutChanges?: AnimateLayoutChanges;

packages/sortable-list/src/Item/components/Action/Action.module.css renamed to packages/sortable-list/src/components/Action/index.less

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$focused-outline-color: #4c9ffe;
1+
@focused-outline-color: #4c9ffe;
22

33
.Action {
44
display: flex;
@@ -45,6 +45,6 @@ $focused-outline-color: #4c9ffe;
4545
&:focus-visible {
4646
outline: none;
4747
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0),
48-
0 0px 0px 2px $focused-outline-color;
48+
0 0px 0px 2px @focused-outline-color;
4949
}
5050
}

packages/sortable-list/src/Item/Item.tsx renamed to packages/sortable-list/src/components/Item/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import classNames from 'classnames';
33
import type { DraggableSyntheticListeners } from '@dnd-kit/core';
44
import type { Transform } from '@dnd-kit/utilities';
55

6-
import { Handle, Remove } from './components';
6+
import { Handle } from '../Handle';
7+
import { Remove } from '../Remove';
78

89
import styles from './index.less';
910

@@ -76,6 +77,7 @@ export const Item = React.memo(
7677
};
7778
}, [dragOverlay]);
7879

80+
// @ts-ignore
7981
return renderItem ? (
8082
renderItem({
8183
dragOverlay: Boolean(dragOverlay),

packages/sortable-list/src/Item/components/Remove/Remove.tsx renamed to packages/sortable-list/src/components/Remove/Remove.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22

3-
import {Action, ActionProps} from '../Action';
3+
import type { ActionProps } from '../Action';
4+
import { Action } from '../Action';
45

56
export function Remove(props: ActionProps) {
67
return (

0 commit comments

Comments
 (0)