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

Masonic/Multi Column support [Cleaner Rebase] #99

Open
wants to merge 1 commit into
base: main
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
70 changes: 48 additions & 22 deletions src/DraxList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ import {
import { defaultListItemLongPressDelay } from './params';

interface Shift {
targetValue: number;
animatedValue: Animated.Value;
targetValue: Position;
animatedValue: Animated.ValueXY;
}

interface ListItemPayload {
Expand Down Expand Up @@ -137,8 +137,8 @@ export const DraxList = <T extends unknown>(
itemMeasurements.push(undefined);
registrations.push(undefined);
shifts.push({
targetValue: 0,
animatedValue: new Animated.Value(0),
targetValue: { x: 0, y: 0 },
animatedValue: new Animated.ValueXY({ x: 0, y: 0 }),
});
}
}
Expand Down Expand Up @@ -171,14 +171,15 @@ export const DraxList = <T extends unknown>(
);

// Get shift transform for list item at index.
const getShiftTransform = useCallback(
const getShiftTransformStyle = useCallback(
(index: number) => {
const shift = shiftsRef.current[index]?.animatedValue ?? 0;
return horizontal
? [{ translateX: shift }]
: [{ translateY: shift }];
const shift = shiftsRef.current[index]?.animatedValue;
const transform = shift
? [{ translateX: shift.x }, { translateY: shift.y }]
: [];
return { transform };
},
[horizontal],
[],
);

// Set the currently dragged list item.
Expand Down Expand Up @@ -210,7 +211,7 @@ export const DraxList = <T extends unknown>(
} = itemStyles ?? {};
return (
<DraxView
style={[itemStyle, { transform: getShiftTransform(originalIndex) }]}
style={[itemStyle, getShiftTransformStyle(originalIndex)]}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to tweak this to merge transform styles using the function I added when addressing #35

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you mean this commit (https://github.com/nuclearpasta/react-native-drax/pull/88/files) I probably need to talk this one out, can't wrap my head around how to use it.

draggingStyle={draggingStyle}
dragReleasedStyle={dragReleasedStyle}
{...otherStyleProps}
Expand Down Expand Up @@ -243,7 +244,7 @@ export const DraxList = <T extends unknown>(
originalIndexes,
itemStyles,
viewPropsExtractor,
getShiftTransform,
getShiftTransformStyle,
resetDraggedItem,
itemsDraggable,
renderItemContent,
Expand Down Expand Up @@ -368,8 +369,8 @@ export const DraxList = <T extends unknown>(
() => {
shiftsRef.current.forEach((shift) => {
// eslint-disable-next-line no-param-reassign
shift.targetValue = 0;
shift.animatedValue.setValue(0);
shift.targetValue = { x: 0, y: 0 };
shift.animatedValue.setValue({ x: 0, y: 0 });
});
},
[],
Expand All @@ -380,18 +381,36 @@ export const DraxList = <T extends unknown>(
(
{ index: fromIndex, originalIndex: fromOriginalIndex }: ListItemPayload,
{ index: toIndex }: ListItemPayload,
horizontalShift: boolean
) => {
const contentSize = contentSizeRef.current;
const { width = 50, height = 50 } = itemMeasurementsRef.current[fromOriginalIndex] ?? {};
const offset = horizontal ? width : height;
const posOffset = horizontalShift && contentSize && width < contentSize.x
? { x: width, y: 0 }
: { x: 0, y: height };
const negOffset = {
x: posOffset.x * -1,
y: posOffset.y * -1,
};
originalIndexes.forEach((originalIndex, index) => {
const { width: itemWidth = 0, height: itemHeight = 0 } = itemMeasurementsRef.current[originalIndex] ?? {};
const shift = shiftsRef.current[originalIndex];
let newTargetValue = 0;
if (!shift) {
return;
}
let newTargetValue = { x: 0, y: 0 };
if (index > fromIndex && index <= toIndex) {
newTargetValue = -offset;
newTargetValue = negOffset;
} else if (index < fromIndex && index >= toIndex) {
newTargetValue = offset;
newTargetValue = posOffset;
}
if (shift.targetValue !== newTargetValue) {
// Keep from shifting full width items horizontally
if (contentSize && itemWidth >= contentSize.x) {
if (!itemHeight) return;
newTargetValue.x = 0;
}
if (itemHeight && (shift.targetValue.x !== newTargetValue.x
|| shift.targetValue.y !== newTargetValue.y)) {
shift.targetValue = newTargetValue;
Animated.timing(shift.animatedValue, {
duration: 200,
Expand All @@ -401,7 +420,7 @@ export const DraxList = <T extends unknown>(
}
});
},
[originalIndexes, horizontal],
[originalIndexes],
);

// Calculate absolute position of list item for snapback.
Expand Down Expand Up @@ -573,7 +592,12 @@ export const DraxList = <T extends unknown>(
// Monitor drags to react with item shifts and auto-scrolling.
const onMonitorDragOver = useCallback(
(eventData: DraxMonitorEventData) => {
const { dragged, receiver, monitorOffsetRatio } = eventData;
const {
dragTranslation,
dragged,
receiver,
monitorOffsetRatio
} = eventData;
// First, check if we need to shift items.
if (reorderable && dragged.parentId === id) {
// One of our list items is being dragged.
Expand All @@ -597,8 +621,10 @@ export const DraxList = <T extends unknown>(
draggedToIndex.current = toIndex;
}

const horizontalShift = (Math.abs(dragTranslation.x) > Math.abs(dragTranslation.y))

// Update shift transforms for items in the list.
updateShifts(fromPayload, toPayload ?? fromPayload);
updateShifts(fromPayload, toPayload ?? fromPayload, horizontalShift);
}

// Next, see if we need to auto-scroll.
Expand Down
6 changes: 3 additions & 3 deletions src/DraxProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from './types';
import { getRelativePosition } from './math';

export const DraxProvider: FunctionComponent<DraxProviderProps> = ({ debug = false, children }) => {
export const DraxProvider: FunctionComponent<DraxProviderProps> = ({ debug = false, multicolumn = false, children }) => {
const {
getViewState,
getTrackingStatus,
Expand Down Expand Up @@ -387,10 +387,10 @@ export const DraxProvider: FunctionComponent<DraxProviderProps> = ({ debug = fal
* NOTE: if view is transformed, these will be wrong.
*/
const dragAbsolutePosition = {
x: absoluteX + grabX,
x: multicolumn ? absoluteX : absoluteX + grabX,
y: absoluteY + grabY,
};
const grabOffset = { x: grabX, y: grabY };
const grabOffset = { x: multicolumn ? 0 : grabX, y: grabY };
const grabOffsetRatio = {
x: grabX / width,
y: grabY / height,
Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
StyleProp,
ScrollViewProps,
ListRenderItemInfo,
NativeScrollEvent,
} from 'react-native';
import {
LongPressGestureHandlerStateChangeEvent,
Expand Down Expand Up @@ -583,6 +584,7 @@ export interface DraxContextValue {
/** Optional props that can be passed to a DraxProvider to modify its behavior */
export interface DraxProviderProps {
debug?: boolean;
multicolumn?: boolean;
}

/** Props that are passed to a DraxSubprovider, used internally for nesting views */
Expand Down Expand Up @@ -878,6 +880,9 @@ export interface DraxListProps<TItem> extends Omit<FlatListProps<TItem>, 'render
/** Callback handler for when a list item is moved within the list, reordering the list */
onItemReorder?: DraxListOnItemReorder<TItem>;

/** Callback handler for when list is scrolled */
onScrollProp?: (scrollEvent: NativeScrollEvent) => void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this leftover cruft from other branch work?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah this is another change I added this to our app as well so we could pass in a custom onScroll event. I could put this in another commit if you prefer.


/** Can the list be reordered by dragging items? Defaults to true if onItemReorder is set. */
reorderable?: boolean;

Expand Down