UNPKG

react-native-sortables

Version:

Powerful Sortable Components for Flexible Content Reordering in React Native

186 lines (185 loc) 5.95 kB
"use strict"; import React from "react"; import { useMemo } from 'react'; import { StyleSheet } from 'react-native'; import { runOnUI, useAnimatedStyle } from 'react-native-reanimated'; import { DEFAULT_SORTABLE_GRID_PROPS, IS_WEB } from '../constants'; import { useDragEndHandler } from '../hooks'; import { useAnimatableValue } from '../integrations/reanimated'; import { GRID_STRATEGIES, GridLayoutProvider, OrderUpdaterComponent, SharedProvider, useMeasurementsContext, 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 = useMemo(() => ({ height: isVertical, // height is controlled for vertical grids width: !isVertical // width is controlled for horizontal grids }), [isVertical]); const controlledItemDimensions = useMemo(() => ({ height: !isVertical, // height is controlled for horizontal grids width: isVertical // width is controlled for vertical grids }), [isVertical]); 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, controlledItemDimensions: controlledItemDimensions, debug: debug, itemKeys: itemKeys, 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 }, 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 { handleContainerMeasurement } = useMeasurementsContext(); const animatedInnerStyle = useAnimatedStyle(() => isVertical ? { columnGap: IS_WEB ? columnGap.value : 0, flexDirection: 'row', marginHorizontal: IS_WEB ? 0 : -columnGap.value / 2, rowGap: rowGap.value } : { columnGap: columnGap.value, flexDirection: 'column', height: groups * (rowHeight + rowGap.value) - rowGap.value, rowGap: rowGap.value }); const animatedItemStyle = useAnimatedStyle(() => isVertical ? IS_WEB ? { width: `calc((100% - ${columnGap.value * (groups - 1)}px) / ${groups})` } : { flexBasis: `${100 / groups}%`, paddingHorizontal: columnGap.value / 2 } : { height: rowHeight }); return /*#__PURE__*/_jsx(SortableContainer, { ...containerProps, style: [styles.gridContainer, animatedInnerStyle], onLayout: runOnUI((width, height) => { handleContainerMeasurement(width - (isVertical && !IS_WEB ? columnGap.value : 0), height); }), 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, !isVertical && styles.horizontalStyleOverride] }, 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