UNPKG

react-native-sortables

Version:

Powerful Sortable Components for Flexible Content Reordering in React Native

189 lines (188 loc) 5.98 kB
"use strict"; import React, { createElement as _createElement } from "react"; import { useLayoutEffect, useMemo, useRef } 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, usePropsWithDefaults } from '../hooks'; import { useAnimatableValue, useStableCallbackValues } from '../integrations/reanimated'; import { GRID_STRATEGIES, GridProvider, ItemsProvider, useGridLayoutContext, useMeasurementsContext, useOrderUpdater, useStrategyKey } from '../providers'; import { defaultKeyExtractor, error, orderItems, typedMemo } from '../utils'; import { SortableContainer } from './shared'; import { jsx as _jsx } from "react/jsx-runtime"; function SortableGrid(props) { const { columns, data, keyExtractor = defaultKeyExtractor, onActiveItemDropped, onDragEnd: _onDragEnd, onDragMove, onDragStart, onOrderChange, renderItem, rowHeight, rows, strategy, ...rest } = usePropsWithDefaults(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 items = useMemo(() => data.map(item => [keyExtractor(item), item]), [data, keyExtractor]); const callbacks = useStableCallbackValues({ onActiveItemDropped, onDragMove, onDragStart, onOrderChange }); const onDragEnd = useDragEndHandler(_onDragEnd, { data: params => orderItems(data, items, params, true) }); return /*#__PURE__*/_jsx(ItemsProvider, { items: items, renderItem: renderItem, children: /*#__PURE__*/_createElement(SortableGridInner, { ...rest, ...callbacks, groups: groups, isVertical: isVertical, key: useStrategyKey(strategy), rowHeight: rowHeight // must be specified for horizontal grids , strategy: strategy, onDragEnd: onDragEnd }) }); } const SortableGridInner = typedMemo(function SortableGridInner({ columnGap: _columnGap, debug, dimensionsAnimationType, DropIndicatorComponent, dropIndicatorStyle, groups, isVertical, itemEntering, itemExiting, overflow, rowGap: _rowGap, rowHeight, showDropIndicator, strategy, ...rest }) { const columnGap = useAnimatableValue(_columnGap); const rowGap = 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]); return /*#__PURE__*/_jsx(GridProvider, { ...rest, columnGap: columnGap, controlledContainerDimensions: controlledContainerDimensions, controlledItemDimensions: controlledItemDimensions, debug: debug, isVertical: isVertical, numGroups: groups, rowGap: rowGap, rowHeight: rowHeight, strategy: strategy, children: /*#__PURE__*/_jsx(SortableGridComponent, { columnGap: columnGap, debug: debug, dimensionsAnimationType: dimensionsAnimationType, DropIndicatorComponent: DropIndicatorComponent, dropIndicatorStyle: dropIndicatorStyle, groups: groups, isVertical: isVertical, itemEntering: itemEntering, itemExiting: itemExiting, overflow: overflow, rowGap: rowGap, rowHeight: rowHeight, showDropIndicator: showDropIndicator, strategy: strategy }) }); }); function SortableGridComponent({ columnGap, groups, isVertical, rowGap, rowHeight, strategy, ...rest }) { const { handleContainerMeasurement, resetMeasurements } = useMeasurementsContext(); const { mainGroupSize } = useGridLayoutContext(); const isFirstRenderRef = useRef(true); useOrderUpdater(strategy, GRID_STRATEGIES); useLayoutEffect(() => { if (isFirstRenderRef.current) { isFirstRenderRef.current = false; return; } resetMeasurements(); }, [groups, resetMeasurements]); 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 ?? 0) + rowGap.value) - rowGap.value, rowGap: rowGap.value }); const animatedItemStyle = useAnimatedStyle(() => isVertical ? IS_WEB ? { width: `calc((100% - ${columnGap.value * (groups - 1)}px) / ${groups})` } : { flexBasis: mainGroupSize.value ? undefined : `${100 / groups}%`, paddingHorizontal: columnGap.value / 2 } : { height: rowHeight }); const itemStyle = useMemo(() => [animatedItemStyle, !isVertical && styles.horizontalStyleOverride], [animatedItemStyle, isVertical]); return /*#__PURE__*/_jsx(SortableContainer, { ...rest, containerStyle: [styles.gridContainer, animatedInnerStyle], itemStyle: itemStyle, onLayout: runOnUI((w, h) => { handleContainerMeasurement(w - (isVertical && !IS_WEB ? columnGap.value : 0), h); }) }); } 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