react-native-sortables
Version:
Powerful Sortable Components for Flexible Content Reordering in React Native
163 lines (162 loc) • 5.07 kB
JavaScript
;
import React from "react";
import { useMemo } from 'react';
import { StyleSheet } from 'react-native';
import { runOnUI, useAnimatedStyle } from 'react-native-reanimated';
import { DEFAULT_SORTABLE_FLEX_PROPS, EMPTY_OBJECT, IS_WEB } from '../constants';
import { useDragEndHandler } from '../hooks';
import { FLEX_STRATEGIES, FlexLayoutProvider, OrderUpdaterComponent, SharedProvider, useCommonValuesContext, useMeasurementsContext, useStrategyKey } from '../providers';
import { getPropsWithDefaults, orderItems, validateChildren } from '../utils';
import { DraggableView, SortableContainer } from './shared';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const CONTROLLED_ITEM_DIMENSIONS = {
height: false,
width: false
};
function SortableFlex(props) {
const {
rest: {
children,
height,
onDragEnd: _onDragEnd,
strategy,
width,
...styleProps
},
sharedProps: {
debug,
dimensionsAnimationType,
DropIndicatorComponent,
dropIndicatorStyle,
itemEntering,
itemExiting,
overflow,
reorderTriggerOrigin,
showDropIndicator,
...sharedProps
}
} = getPropsWithDefaults(props, DEFAULT_SORTABLE_FLEX_PROPS);
const childrenArray = validateChildren(children);
const itemKeys = childrenArray.map(([key]) => key);
const {
flexDirection,
flexWrap
} = styleProps;
const isColumn = flexDirection.startsWith('column');
const controlledContainerDimensions = useMemo(() => {
if (flexWrap === 'nowrap') {
return {
height: height === undefined,
width: width === undefined
};
}
return {
height: height === undefined,
width: isColumn && width === undefined
};
}, [flexWrap, isColumn, height, width]);
const onDragEnd = useDragEndHandler(_onDragEnd, {
order: params => function (data) {
return orderItems(data, itemKeys, params, true);
}
});
return /*#__PURE__*/_jsx(SharedProvider, {
...sharedProps,
controlledContainerDimensions: controlledContainerDimensions,
controlledItemDimensions: CONTROLLED_ITEM_DIMENSIONS,
debug: debug,
itemKeys: itemKeys,
onDragEnd: onDragEnd,
children: /*#__PURE__*/_jsxs(FlexLayoutProvider, {
...styleProps,
itemsCount: itemKeys.length,
children: [/*#__PURE__*/_jsx(OrderUpdaterComponent, {
predefinedStrategies: FLEX_STRATEGIES,
strategy: strategy,
triggerOrigin: reorderTriggerOrigin
}, useStrategyKey(strategy)), /*#__PURE__*/_jsx(SortableFlexInner, {
childrenArray: childrenArray,
debug: debug,
dimensionsAnimationType: dimensionsAnimationType,
DropIndicatorComponent: DropIndicatorComponent,
dropIndicatorStyle: dropIndicatorStyle,
itemEntering: itemEntering,
itemExiting: itemExiting,
overflow: overflow,
showDropIndicator: showDropIndicator,
style: [styleProps, {
height: height === 'fill' ? undefined : height,
width: width === 'fill' ? undefined : width
}]
})]
})
});
}
function SortableFlexInner({
childrenArray,
itemEntering,
itemExiting,
style,
...containerProps
}) {
const {
usesAbsoluteLayout
} = useCommonValuesContext();
const {
handleContainerMeasurement
} = useMeasurementsContext();
let relativeLayoutStyle = EMPTY_OBJECT;
let baseContainerStyle = style;
// On web reanimated animated style might not override the plan js style
// so we have to filter out flex properties
if (IS_WEB) {
const {
alignItems,
flexDirection,
flexWrap,
justifyContent,
...restStyle
} = StyleSheet.flatten(style);
baseContainerStyle = restStyle;
relativeLayoutStyle = {
alignItems,
flexDirection,
flexWrap,
justifyContent
};
}
const animatedContainerStyle = useAnimatedStyle(() => usesAbsoluteLayout.value ? {
// We need to override them to prevent react-native flex layout
// positioning from interfering with our absolute layout
alignContent: 'flex-start',
alignItems: 'flex-start',
flexDirection: 'row',
justifyContent: 'flex-start',
paddingBottom: 0,
paddingLeft: 0,
paddingRight: 0,
paddingTop: 0
} : relativeLayoutStyle);
return /*#__PURE__*/_jsx(SortableContainer, {
...containerProps,
style: [baseContainerStyle, animatedContainerStyle],
onLayout: runOnUI((width, height) => {
handleContainerMeasurement(width, height);
}),
children: childrenArray.map(([key, child]) => /*#__PURE__*/_jsx(DraggableView, {
entering: itemEntering ?? undefined,
exiting: itemExiting ?? undefined,
itemKey: key,
style: styles.styleOverride,
children: child
}, key))
});
}
const styles = StyleSheet.create({
styleOverride: {
// This is needed to prevent items from stretching (which is default behavior)
alignSelf: 'flex-start'
}
});
export default SortableFlex;
//# sourceMappingURL=SortableFlex.js.map