Skip to content

Commit dde86ef

Browse files
authored
chore: Optimize and clean up item cell animated styles (#459)
## Description Moving some code executed in each cell to the common provider and some other cleanup of animated styles.
1 parent fd3ceb3 commit dde86ef

File tree

8 files changed

+46
-33
lines changed

8 files changed

+46
-33
lines changed

packages/react-native-sortables/src/components/shared/DraggableView/ActiveItemPortal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export default function ActiveItemPortal({
5959
<TeleportedItemCell
6060
activationAnimationProgress={activationAnimationProgress}
6161
cellStyle={cellStyle}
62+
innerCellStyle={commonValuesContext.controlledDimensionsStyle}
6263
isActive={isActive}
6364
itemKey={itemKey}>
6465
{children}

packages/react-native-sortables/src/components/shared/DraggableView/DraggableView.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ function DraggableView({
4444
const { handleItemMeasurement, removeItemMeasurements } =
4545
useMeasurementsContext();
4646
const { handleDragEnd } = useDragContext();
47-
const { activeItemKey, customHandle } = commonValuesContext;
47+
const { activeItemKey, controlledDimensionsStyle, customHandle } =
48+
commonValuesContext;
4849

4950
const [isHidden, setIsHidden] = useState(false);
5051
const activationAnimationProgress = useMutableValue(0);
5152
const isActive = useDerivedValue(() => activeItemKey.value === key);
52-
const itemStyles = useItemStyles(key, isActive, activationAnimationProgress);
53+
const layoutStyle = useItemStyles(key, isActive, activationAnimationProgress);
5354
const gesture = useItemPanGesture(key, activationAnimationProgress);
5455

5556
useEffect(() => {
@@ -74,10 +75,11 @@ function DraggableView({
7475
const innerComponent = (
7576
<ItemCell
7677
activationAnimationProgress={activationAnimationProgress}
77-
cellStyle={[style, itemStyles]}
78+
cellStyle={[style, layoutStyle]}
7879
entering={itemEntering ?? undefined}
7980
exiting={itemExiting ?? undefined}
8081
hidden={hidden}
82+
innerCellStyle={controlledDimensionsStyle}
8183
isActive={isActive}
8284
itemKey={key}
8385
onLayout={onLayout}>

packages/react-native-sortables/src/components/shared/DraggableView/ItemCell.tsx

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,21 @@ import {
66
type ViewStyle
77
} from 'react-native';
88
import type { SharedValue } from 'react-native-reanimated';
9-
import Animated, {
10-
useAnimatedStyle,
11-
useDerivedValue
12-
} from 'react-native-reanimated';
9+
import Animated from 'react-native-reanimated';
1310

1411
import { HIDDEN_X_OFFSET } from '../../../constants';
1512
import type {
1613
AnimatedStyleProp,
1714
LayoutAnimation
1815
} from '../../../integrations/reanimated';
19-
import { useCommonValuesContext, useItemDecoration } from '../../../providers';
20-
import type { Dimensions } from '../../../types';
21-
import { resolveDimension } from '../../../utils';
16+
import { useItemDecorationStyle } from '../../../providers';
2217
import AnimatedOnLayoutView from '../AnimatedOnLayoutView';
2318

2419
export type ItemCellProps = PropsWithChildren<{
2520
itemKey: string;
2621
isActive: SharedValue<boolean>;
2722
activationAnimationProgress: SharedValue<number>;
23+
innerCellStyle: AnimatedStyleProp;
2824
cellStyle: AnimatedStyleProp;
2925
onLayout?: (event: LayoutChangeEvent) => void;
3026
hidden?: boolean;
@@ -39,33 +35,17 @@ export default function ItemCell({
3935
entering,
4036
exiting,
4137
hidden,
38+
innerCellStyle,
4239
isActive,
4340
itemKey,
4441
onLayout
4542
}: ItemCellProps) {
46-
const { controlledItemDimensions, itemHeights, itemWidths } =
47-
useCommonValuesContext();
48-
49-
const decoration = useItemDecoration(
43+
const decorationStyle = useItemDecorationStyle(
5044
itemKey,
5145
isActive,
5246
activationAnimationProgress
5347
);
5448

55-
const controlledDimensions = useDerivedValue(() => {
56-
const result: Partial<Dimensions> = {};
57-
if (controlledItemDimensions.width) {
58-
result.width = resolveDimension(itemWidths.value, itemKey) ?? undefined;
59-
}
60-
if (controlledItemDimensions.height) {
61-
result.height = resolveDimension(itemHeights.value, itemKey) ?? undefined;
62-
}
63-
return result;
64-
});
65-
66-
const decorationStyle = useAnimatedStyle(() => decoration.value);
67-
const dimensionsStyle = useAnimatedStyle(() => controlledDimensions.value);
68-
6949
return (
7050
<Animated.View style={cellStyle}>
7151
<AnimatedOnLayoutView
@@ -74,7 +54,7 @@ export default function ItemCell({
7454
style={[
7555
styles.decoration,
7656
decorationStyle,
77-
dimensionsStyle,
57+
innerCellStyle,
7858
hidden && styles.hidden
7959
]}
8060
onLayout={onLayout}>

packages/react-native-sortables/src/components/shared/DraggableView/TeleportedItemCell.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type TeleportedItemCellProps = Pick<
99
| 'activationAnimationProgress'
1010
| 'cellStyle'
1111
| 'children'
12+
| 'innerCellStyle'
1213
| 'isActive'
1314
| 'itemKey'
1415
| 'onLayout'
@@ -18,6 +19,7 @@ export default function TeleportedItemCell({
1819
activationAnimationProgress,
1920
cellStyle,
2021
children,
22+
innerCellStyle,
2123
isActive,
2224
itemKey,
2325
onLayout
@@ -32,6 +34,7 @@ export default function TeleportedItemCell({
3234
<ItemCell
3335
activationAnimationProgress={activationAnimationProgress}
3436
cellStyle={[cellStyle, teleportedItemStyles]}
37+
innerCellStyle={innerCellStyle}
3538
isActive={isActive}
3639
itemKey={itemKey}
3740
onLayout={onLayout}>

packages/react-native-sortables/src/providers/shared/CommonValuesProvider.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { type PropsWithChildren, useEffect, useMemo, useRef } from 'react';
22
import type { View } from 'react-native';
3-
import { useAnimatedRef, useDerivedValue } from 'react-native-reanimated';
3+
import {
4+
useAnimatedRef,
5+
useAnimatedStyle,
6+
useDerivedValue
7+
} from 'react-native-reanimated';
48

59
import type { Animatable } from '../../integrations/reanimated';
610
import {
@@ -82,6 +86,12 @@ const { CommonValuesContext, CommonValuesProvider, useCommonValuesContext } =
8286
const itemHeights = useMutableValue<ItemSizes>(
8387
controlledItemDimensions.height ? null : {}
8488
);
89+
const controlledHeight = useDerivedValue(() =>
90+
controlledItemDimensions.height ? (itemHeights.value as number) : null
91+
);
92+
const controlledWidth = useDerivedValue(() =>
93+
controlledItemDimensions.width ? (itemWidths.value as number) : null
94+
);
8595
const activeItemDimensions = useMutableValue<Dimensions | null>(null);
8696

8797
// DRAG STATE
@@ -133,6 +143,17 @@ const { CommonValuesContext, CommonValuesProvider, useCommonValuesContext } =
133143
}
134144
}, [itemKeys, indexToKey]);
135145

146+
const controlledDimensionsStyle = useAnimatedStyle(() => {
147+
const result: Partial<Dimensions> = {};
148+
if (controlledHeight.value !== null) {
149+
result.height = controlledHeight.value;
150+
}
151+
if (controlledWidth.value !== null) {
152+
result.width = controlledWidth.value;
153+
}
154+
return result;
155+
});
156+
136157
return {
137158
value: {
138159
activationAnimationDuration,
@@ -151,6 +172,7 @@ const { CommonValuesContext, CommonValuesProvider, useCommonValuesContext } =
151172
containerRef,
152173
containerWidth,
153174
controlledContainerDimensions,
175+
controlledDimensionsStyle,
154176
controlledItemDimensions,
155177
customHandle,
156178
dragActivationDelay,

packages/react-native-sortables/src/providers/shared/hooks/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { default as useDebugBoundingBox } from './useDebugBoundingBox';
2-
export { default as useItemDecoration } from './useItemDecoration';
2+
export { default as useItemDecorationStyle } from './useItemDecorationStyle';
33
export { default as useItemDimensions } from './useItemDimensions';
44
export { default as useItemStyles } from './useItemLayoutStyle';
55
export { default as useItemPanGesture } from './useItemPanGesture';

packages/react-native-sortables/src/providers/shared/hooks/useItemDecoration.ts renamed to packages/react-native-sortables/src/providers/shared/hooks/useItemDecorationStyle.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import type { SharedValue } from 'react-native-reanimated';
22
import {
33
interpolate,
44
interpolateColor,
5+
useAnimatedStyle,
56
useDerivedValue,
67
withTiming
78
} from 'react-native-reanimated';
89

910
import { IS_WEB } from '../../../constants';
1011
import { useCommonValuesContext } from '../CommonValuesProvider';
1112

12-
export default function useItemDecoration(
13+
export default function useItemDecorationStyle(
1314
key: string,
1415
isActive: SharedValue<boolean>,
1516
activationAnimationProgress: SharedValue<number>
@@ -37,7 +38,7 @@ export default function useItemDecoration(
3738
);
3839
});
3940

40-
return useDerivedValue(() => {
41+
const decoration = useDerivedValue(() => {
4142
const progress = activationAnimationProgress.value;
4243
const zeroProgressOpacity = interpolate(
4344
adjustedInactiveProgress.value,
@@ -78,4 +79,6 @@ export default function useItemDecoration(
7879
]
7980
};
8081
});
82+
83+
return useAnimatedStyle(() => decoration.value);
8184
}

packages/react-native-sortables/src/types/providers/shared.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
} from 'react-native-gesture-handler';
77
import type {
88
AnimatedRef,
9+
AnimatedStyle,
910
MeasuredDimensions,
1011
SharedValue
1112
} from 'react-native-reanimated';
@@ -62,6 +63,7 @@ export type CommonValuesContextType =
6263
containerHeight: SharedValue<null | number>;
6364
itemWidths: SharedValue<ItemSizes>;
6465
itemHeights: SharedValue<ItemSizes>;
66+
controlledDimensionsStyle: AnimatedStyle<Partial<Dimensions>>;
6567
activeItemDimensions: SharedValue<Dimensions | null>;
6668

6769
// DRAG STATE

0 commit comments

Comments
 (0)