Skip to content

Commit

Permalink
Improvements to better support swappable
Browse files Browse the repository at this point in the history
  • Loading branch information
Clauderic Demers committed Oct 25, 2021
1 parent 5f7e58c commit 94cd71d
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 13 deletions.
15 changes: 14 additions & 1 deletion packages/sortable/src/hooks/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import {CSS} from '@dnd-kit/utilities';

import type {AnimateLayoutChanges, SortableTransition} from './types';
import {arrayMove} from '../utilities';

import type {
AnimateLayoutChanges,
NewIndexGetter,
SortableTransition,
} from './types';

export const defaultNewIndexGetter: NewIndexGetter = ({
id,
items,
activeIndex,
overIndex,
}) => arrayMove(items, activeIndex, overIndex).indexOf(id);

export const defaultAnimateLayoutChanges: AnimateLayoutChanges = ({
containerId,
Expand Down
4 changes: 2 additions & 2 deletions packages/sortable/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export {useSortable} from './useSortable';
export type {Arguments as UseSortableArguments} from './useSortable';

export {defaultAnimateLayoutChanges} from './defaults';
export type {AnimateLayoutChanges} from './types';
export {defaultAnimateLayoutChanges, defaultNewIndexGetter} from './defaults';
export type {AnimateLayoutChanges, NewIndexGetter} from './types';
9 changes: 9 additions & 0 deletions packages/sortable/src/hooks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,12 @@ export type AnimateLayoutChanges = (args: {
transition: SortableTransition | null;
wasDragging: boolean;
}) => boolean;

export interface NewIndexGetterArguments {
id: UniqueIdentifier;
items: UniqueIdentifier[];
activeIndex: number;
overIndex: number;
}

export type NewIndexGetter = (args: NewIndexGetterArguments) => number;
13 changes: 10 additions & 3 deletions packages/sortable/src/hooks/useSortable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@ import {CSS, useCombinedRefs} from '@dnd-kit/utilities';

import {Context} from '../components';
import type {SortingStrategy} from '../types';
import {arrayMove, isValidIndex} from '../utilities';
import {isValidIndex} from '../utilities';
import {
defaultAnimateLayoutChanges,
defaultAttributes,
defaultNewIndexGetter,
defaultTransition,
disabledTransition,
transitionProperty,
} from './defaults';
import type {AnimateLayoutChanges, SortableTransition} from './types';
import type {
AnimateLayoutChanges,
NewIndexGetter,
SortableTransition,
} from './types';
import {useDerivedTransform} from './utilities';

export interface Arguments extends UseDraggableArguments {
animateLayoutChanges?: AnimateLayoutChanges;
getNewIndex?: NewIndexGetter;
strategy?: SortingStrategy;
transition?: SortableTransition | null;
}
Expand All @@ -26,6 +32,7 @@ export function useSortable({
attributes: userDefinedAttributes,
disabled,
data: customData,
getNewIndex = defaultNewIndexGetter,
id,
strategy: localStrategy,
transition = defaultTransition,
Expand Down Expand Up @@ -93,7 +100,7 @@ export function useSortable({
: null;
const newIndex =
isValidIndex(activeIndex) && isValidIndex(overIndex)
? arrayMove(items, activeIndex, overIndex).indexOf(id)
? getNewIndex({id, items, activeIndex, overIndex})
: index;
const prevItems = useRef(items);
const itemsHaveChanged = items !== prevItems.current;
Expand Down
14 changes: 11 additions & 3 deletions packages/sortable/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
export {SortableContext} from './components';
export type {SortableContextProps} from './components';
export {useSortable, defaultAnimateLayoutChanges} from './hooks';
export type {UseSortableArguments, AnimateLayoutChanges} from './hooks';
export {
useSortable,
defaultAnimateLayoutChanges,
defaultNewIndexGetter,
} from './hooks';
export type {
UseSortableArguments,
AnimateLayoutChanges,
NewIndexGetter,
} from './hooks';
export {
horizontalListSortingStrategy,
rectSortingStrategy,
rectSwappingStrategy,
verticalListSortingStrategy,
} from './strategies';
export {sortableKeyboardCoordinates} from './sensors';
export {arrayMove} from './utilities';
export {arrayMove, arraySwap} from './utilities';
export type {SortingStrategy} from './types';
11 changes: 11 additions & 0 deletions packages/sortable/src/utilities/arraySwap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Swap an array item to a different position. Returns a new array with the item swapped to the new position.
*/
export function arraySwap<T>(array: T[], from: number, to: number): T[] {
const newArray = array.slice();

newArray[from] = array[to];
newArray[to] = array[from];

return newArray;
}
1 change: 1 addition & 0 deletions packages/sortable/src/utilities/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export {arrayMove} from './arrayMove';
export {arraySwap} from './arraySwap';
export {getSortedRects} from './getSortedRects';
export {isValidIndex} from './isValidIndex';
13 changes: 13 additions & 0 deletions stories/2 - Presets/Sortable/3-Grid.story.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react';
import {MeasuringStrategy} from '@dnd-kit/core';
import {
arraySwap,
AnimateLayoutChanges,
defaultAnimateLayoutChanges,
rectSortingStrategy,
rectSwappingStrategy,
} from '@dnd-kit/sortable';

import {Sortable, Props as SortableProps} from './Sortable';
Expand Down Expand Up @@ -104,6 +106,17 @@ export const ScrollContainer = () => (
</div>
);

export const Swappable = () => (
<Sortable
{...props}
strategy={rectSwappingStrategy}
reorderItems={arraySwap}
getNewIndex={({id, items, activeIndex, overIndex}) =>
arraySwap(items, activeIndex, overIndex).indexOf(id)
}
/>
);

export const PressDelay = () => (
<Sortable
{...props}
Expand Down
17 changes: 13 additions & 4 deletions stories/2 - Presets/Sortable/Sortable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
SortingStrategy,
rectSortingStrategy,
AnimateLayoutChanges,
NewIndexGetter,
} from '@dnd-kit/sortable';

import {createRange} from '../../utilities';
Expand All @@ -40,13 +41,15 @@ export interface Props {
collisionDetection?: CollisionDetection;
Container?: any; // To-do: Fix me
dropAnimation?: DropAnimation | null;
getNewIndex?: NewIndexGetter;
handle?: boolean;
itemCount?: number;
items?: string[];
handle?: boolean;
measuring?: MeasuringConfiguration;
modifiers?: Modifiers;
renderItem?: any;
removable?: boolean;
reorderItems?: typeof arrayMove;
strategy?: SortingStrategy;
useDragOverlay?: boolean;
getItemStyles?(args: {
Expand Down Expand Up @@ -86,6 +89,7 @@ export function Sortable({
collisionDetection = closestCenter,
dropAnimation = defaultDropAnimationConfig,
getItemStyles = () => ({}),
getNewIndex,
handle = false,
itemCount = 16,
items: initialItems,
Expand All @@ -94,6 +98,7 @@ export function Sortable({
modifiers,
removable,
renderItem,
reorderItems = arrayMove,
strategy = rectSortingStrategy,
useDragOverlay = true,
wrapperStyle = () => ({}),
Expand Down Expand Up @@ -186,7 +191,7 @@ export function Sortable({
if (over) {
const overIndex = getIndex(over.id);
if (activeIndex !== overIndex) {
setItems((items) => arrayMove(items, activeIndex, overIndex));
setItems((items) => reorderItems(items, activeIndex, overIndex));
}
}
}}
Expand All @@ -210,6 +215,7 @@ export function Sortable({
onRemove={handleRemove}
animateLayoutChanges={animateLayoutChanges}
useDragOverlay={useDragOverlay}
getNewIndex={getNewIndex}
/>
))}
</Container>
Expand Down Expand Up @@ -253,6 +259,7 @@ export function Sortable({
interface SortableItemProps {
animateLayoutChanges?: AnimateLayoutChanges;
disabled?: boolean;
getNewIndex?: NewIndexGetter;
id: string;
index: number;
handle: boolean;
Expand All @@ -274,9 +281,10 @@ interface SortableItemProps {
export function SortableItem({
disabled,
animateLayoutChanges,
getNewIndex,
handle,
id,
index,
handle,
onRemove,
style,
renderItem,
Expand All @@ -293,9 +301,10 @@ export function SortableItem({
transform,
transition,
} = useSortable({
animateLayoutChanges,
id,
animateLayoutChanges,
disabled,
getNewIndex,
});

return (
Expand Down

0 comments on commit 94cd71d

Please sign in to comment.