react-native-sortables
Version:
Powerful Sortable Components for Flexible Content Reordering in React Native
167 lines (166 loc) • 5.29 kB
JavaScript
"use strict";
import React from "react";
import { useMemo } from 'react';
import { StyleSheet } from 'react-native';
import { useAnimatedStyle, useDerivedValue } from 'react-native-reanimated';
import { DEFAULT_SORTABLE_GRID_PROPS } from '../constants';
import { useAnimatableValue, useDragEndHandler } from '../hooks';
import { GRID_STRATEGIES, GridLayoutProvider, OrderUpdaterComponent, SharedProvider, useGridLayoutContext, useStrategyKey } from '../providers';
import { defaultKeyExtractor, error, getPropsWithDefaults, orderItems, typedMemo, zipArrays } from '../utils';
import { DraggableView, SortableContainer } from './shared';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
function SortableGrid(props) {
const {
rest: {
columnGap,
columns,
data,
keyExtractor = defaultKeyExtractor,
onDragEnd: _onDragEnd,
renderItem,
rowGap,
rowHeight,
rows,
strategy
},
sharedProps: {
debug,
dimensionsAnimationType,
DropIndicatorComponent,
dropIndicatorStyle,
itemEntering,
itemExiting,
overflow,
reorderTriggerOrigin,
showDropIndicator,
...sharedProps
}
} = getPropsWithDefaults(props, DEFAULT_SORTABLE_GRID_PROPS);
const isVertical = rows === undefined;
const groups = rows ?? columns;
if (!isVertical && !rowHeight) {
throw error('rowHeight is required for horizontal Sortable.Grid');
}
if (columns !== undefined && columns < 1) {
throw error('columns must be greater than 0');
}
if (rows !== undefined && rows < 1) {
throw error('rows must be greater than 0');
}
const columnGapValue = useAnimatableValue(columnGap);
const rowGapValue = useAnimatableValue(rowGap);
const controlledContainerDimensions = useDerivedValue(() => ({
height: isVertical,
// height is controlled for vertical grids
width: !isVertical // width is controlled for horizontal grids
}));
const itemKeys = useMemo(() => data.map(keyExtractor), [data, keyExtractor]);
const onDragEnd = useDragEndHandler(_onDragEnd, {
data: params => orderItems(data, itemKeys, params, true)
});
return /*#__PURE__*/_jsx(SharedProvider, {
...sharedProps,
controlledContainerDimensions: controlledContainerDimensions,
debug: debug,
itemKeys: itemKeys,
initialItemsStyleOverride: isVertical ? undefined : styles.horizontalStyleOverride,
onDragEnd: onDragEnd,
children: /*#__PURE__*/_jsxs(GridLayoutProvider, {
columnGap: columnGapValue,
isVertical: isVertical,
numGroups: groups,
numItems: data.length,
rowGap: rowGapValue,
rowHeight: rowHeight // horizontal grid only
,
children: [/*#__PURE__*/_jsx(OrderUpdaterComponent, {
predefinedStrategies: GRID_STRATEGIES,
strategy: strategy,
triggerOrigin: reorderTriggerOrigin,
useAdditionalValues: useGridLayoutContext
}, useStrategyKey(strategy)), /*#__PURE__*/_jsx(SortableGridInner, {
columnGap: columnGapValue,
data: data,
debug: debug,
dimensionsAnimationType: dimensionsAnimationType,
DropIndicatorComponent: DropIndicatorComponent,
dropIndicatorStyle: dropIndicatorStyle,
groups: groups,
isVertical: isVertical,
itemEntering: itemEntering,
itemExiting: itemExiting,
itemKeys: itemKeys,
overflow: overflow,
renderItem: renderItem,
rowGap: rowGapValue,
rowHeight: rowHeight // must be specified for horizontal grids
,
showDropIndicator: showDropIndicator
})]
})
});
}
function SortableGridInner({
columnGap,
data,
groups,
isVertical,
itemEntering,
itemExiting,
itemKeys,
renderItem,
rowGap,
rowHeight,
...containerProps
}) {
const animatedInnerStyle = useAnimatedStyle(() => ({
flexDirection: isVertical ? 'row' : 'column',
height: isVertical ? undefined : groups * (rowHeight + rowGap.value),
marginHorizontal: -columnGap.value / 2,
marginVertical: -rowGap.value / 2
}));
const animatedItemStyle = useAnimatedStyle(() => ({
flexBasis: `${100 / groups}%`,
paddingHorizontal: columnGap.value / 2,
paddingVertical: rowGap.value / 2
}));
return /*#__PURE__*/_jsx(SortableContainer, {
...containerProps,
style: [styles.gridContainer, animatedInnerStyle],
children: zipArrays(data, itemKeys).map(([item, key], index) => /*#__PURE__*/_jsx(SortableGridItem, {
entering: itemEntering ?? undefined,
exiting: itemExiting ?? undefined,
index: index,
item: item,
itemKey: key,
renderItem: renderItem,
style: animatedItemStyle
}, key))
});
}
function SortableGridItem({
index,
item,
renderItem,
...rest
}) {
const children = useMemo(() => renderItem({
index,
item
}), [renderItem, index, item]);
return /*#__PURE__*/_jsx(DraggableView, {
...rest,
children: children
});
}
const styles = StyleSheet.create({
gridContainer: {
flexWrap: 'wrap'
},
horizontalStyleOverride: {
// This is needed to properly adjust the wrapper size to the item width
alignSelf: 'flex-start'
}
});
export default typedMemo(SortableGrid);
//# sourceMappingURL=SortableGrid.js.map