react-native-sortables
Version:
Powerful Sortable Components for Flexible Content Reordering in React Native
87 lines (86 loc) • 2.85 kB
JavaScript
;
import { useMemo } from 'react';
import { Platform, StyleSheet } from 'react-native';
import { interpolate, interpolateColor, useAnimatedStyle, useDerivedValue, withTiming } from 'react-native-reanimated';
import { IS_WEB } from '../../../constants';
import { ItemPortalState } from '../../../types';
import { useCommonValuesContext } from '../CommonValuesProvider';
const TELEPORTED_ITEM_STYLE = {
maxHeight: 0,
opacity: 0,
...Platform.select({
android: {
elevation: 0
},
default: {},
native: {
shadowOpacity: 0
}
})
};
const NOT_TELEPORTED_ITEM_STYLE = {
maxHeight: 9999 // 'auto' doesn't trigger onLayout on web/android
};
export default function useItemDecorationStyles(itemKey, isActive, activationAnimationProgress, portalState) {
const {
activationAnimationDuration,
activeItemOpacity,
activeItemScale,
activeItemShadowOpacity,
inactiveAnimationProgress,
inactiveItemOpacity,
inactiveItemScale,
prevActiveItemKey
} = useCommonValuesContext();
const adjustedInactiveProgress = useDerivedValue(() => {
if (portalState?.value === ItemPortalState.TELEPORTED) {
return 0;
}
if (isActive.value || prevActiveItemKey.value === itemKey) {
return withTiming(0, {
duration: activationAnimationDuration.value
});
}
return interpolate(activationAnimationProgress.value, [0, 1], [inactiveAnimationProgress.value, 0]);
});
const animatedStyle = useAnimatedStyle(() => {
if (portalState?.value === ItemPortalState.TELEPORTED) {
return TELEPORTED_ITEM_STYLE;
}
const progress = activationAnimationProgress.value;
const zeroProgressOpacity = interpolate(adjustedInactiveProgress.value, [0, 1], [1, inactiveItemOpacity.value]);
const zeroProgressScale = interpolate(adjustedInactiveProgress.value, [0, 1], [1, inactiveItemScale.value]);
const shadowColor = interpolateColor(interpolate(progress, [0, 1], [0, activeItemShadowOpacity.value]), [0, 1], ['transparent', 'black']);
const shadow = IS_WEB ? {
filter: `drop-shadow(0px 0px 5px ${shadowColor})`
} : {
shadowColor
};
return {
...NOT_TELEPORTED_ITEM_STYLE,
...shadow,
opacity: interpolate(progress, [0, 1], [zeroProgressOpacity, activeItemOpacity.value]),
transform: [{
scale: interpolate(progress, [0, 1], [zeroProgressScale, activeItemScale.value])
}]
};
});
return useMemo(() => [styles.decoration, animatedStyle], [animatedStyle]);
}
const styles = StyleSheet.create({
decoration: Platform.select({
android: {
elevation: 5
},
default: {},
native: {
shadowOffset: {
height: 0,
width: 0
},
shadowOpacity: 1,
shadowRadius: 5
}
})
});
//# sourceMappingURL=useItemDecorationStyles.js.map