react-native-week-schedule-1
Version:
184 lines (183 loc) • 5.86 kB
JavaScript
;
import { useEffect, useMemo } from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import { grid } from "../../utils/grid.js";
import { useTableItem } from "../../hooks/useTableItem.js";
import { getStyles } from "./styles.js";
import { formatNumberString } from "../../utils/formatNumberString.js";
import { isIOS } from "../../utils/Utils.js";
import { divideDate } from "react-native-week-schedule-1";
import { jsx as _jsx } from "react/jsx-runtime";
export const Item = ({
item,
currentItem,
titleKey,
dataKey,
scrollY,
contentHeight,
overlappingIds = [],
onDragEnd,
onPress,
scrollOnDrag
}) => {
const styles = useMemo(() => getStyles(), []);
const {
top,
left,
height
} = useTableItem(item);
const width = grid.cellWight / (overlappingIds.length || 1);
const fullWidth = grid.cellWight;
const title = item?.[titleKey];
const offset = useSharedValue({
x: left,
y: top
});
const animationY = useSharedValue(0);
const inProgress = useSharedValue(0);
useEffect(() => {
offset.value = {
x: left,
y: top
};
}, [left, offset, top]);
const additionalOffset = useMemo(() => {
const prev = [];
overlappingIds.forEach(overlappingItem => {
if (!(overlappingItem && item?.[dataKey])) return;
if (overlappingItem >= item?.[dataKey]) return;
prev.push(overlappingItem);
});
return width * prev.length;
}, [item, dataKey, width, overlappingIds]);
const handleOnPress = () => {
onPress?.(item);
};
const animatedStyles = useAnimatedStyle(() => {
let valueX = offset.value.x;
if (offset.value.x < 0) {
valueX = 0;
} else if (offset.value.x > fullWidth * 6) {
valueX = fullWidth * 6;
}
return {
transform: [{
translateX: valueX
}, {
translateY: offset.value.y
}]
};
});
const onEnd = () => {
const date = new Date(item.date);
const time = Math.floor(offset.value.y / grid.cellHeight) < 0 ? 0 : Math.floor(offset.value.y / grid.cellHeight);
const day = Math.floor(offset.value.x / grid.cellWight) < 0 ? 0 : Math.floor(offset.value.x / grid.cellWight);
const monthDate = date.getDate() + (day - new Date(item.date).getDay());
const [year, month] = divideDate(item.date);
const lastDay = new Date(year, month, 0).getDate();
const dragValue = {
time,
day,
item,
date: `${year}-${formatNumberString(month)}-${formatNumberString(monthDate)}T${formatNumberString(time)}:00:00`
};
if (monthDate <= 0) {
const m = month === 1 ? 12 : month + 1;
const d = new Date(year, m + 1, 0).getDate() - 1 - Math.abs(monthDate);
onDragEnd?.({
...dragValue,
date: `${year}-${formatNumberString(month - 1)}-${formatNumberString(d)}T${formatNumberString(time)}:00:00`
});
return;
}
;
if (monthDate > lastDay) {
const d = monthDate - lastDay;
const m = month === 12 ? 1 : month + 1;
onDragEnd?.({
...dragValue,
date: `${year}-${formatNumberString(m)}-${formatNumberString(d)}T${formatNumberString(time)}:00:00`
});
return;
}
;
onDragEnd?.(dragValue);
};
const handleScroll = itemY => {
const difference = itemY - scrollY.value;
if (difference < 15 && !inProgress.value && itemY) {
inProgress.value = 1;
scrollOnDrag(scrollY.value - 100);
const destination = itemY - 100 > 0 ? animationY.value - (isIOS ? 100 : 0) : animationY.value - itemY;
animationY.value = withTiming(destination, {
duration: 250
});
setTimeout(() => {
inProgress.value = 0;
}, 500);
}
const isNeedScrollDown = scrollY.value + contentHeight - (itemY + height) < 40;
if (isNeedScrollDown && !inProgress.value) {
inProgress.value = 1;
scrollOnDrag(scrollY.value + 100);
const destination = grid.cellHeight * 24 - (itemY + height + 100) < 0 ? animationY.value + grid.cellHeight * 24 - (itemY + height) : animationY.value + (isIOS ? 100 : 0);
animationY.value = withTiming(destination, {
duration: 250
});
setTimeout(() => {
inProgress.value = 0;
}, 700);
}
};
const gesture = Gesture.Pan().onUpdate(event => {
offset.value = {
x: event.translationX + left,
y: event.translationY + top + animationY.value < 0 ? 0 : event.translationY + top + animationY.value
};
runOnJS(handleScroll)(offset.value.y);
}).onEnd(() => {
offset.value = {
x: offset.value.x,
y: offset.value.y
};
}).onFinalize(() => {
animationY.value = 0;
runOnJS(onEnd)();
});
return currentItem?.[dataKey] === item[dataKey] ? /*#__PURE__*/_jsx(GestureDetector, {
gesture: gesture,
children: /*#__PURE__*/_jsx(Animated.View, {
style: [{
width: grid.cellWight,
zIndex: 1
}, animatedStyles],
children: /*#__PURE__*/_jsx(View, {
style: [styles.container, styles.selectedContainer, {
backgroundColor: item.color ?? grid.colors.primary,
height,
width: grid.cellWight
}],
children: /*#__PURE__*/_jsx(Text, {
style: styles.text,
children: title
})
})
})
}) : /*#__PURE__*/_jsx(TouchableOpacity, {
style: [styles.container, {
backgroundColor: item.color ?? grid.colors.primary,
width,
height,
top,
left: left + additionalOffset
}],
onPress: handleOnPress,
children: /*#__PURE__*/_jsx(Text, {
style: styles.text,
children: title
})
});
};
//# sourceMappingURL=index.js.map