@kne/react-calendar 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +14 -2
- package/dist/index.css.map +1 -1
- package/dist/index.js +291 -104
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +297 -110
- package/dist/index.modern.js.map +1 -1
- package/package.json +1 -1
package/dist/index.modern.js
CHANGED
|
@@ -4,7 +4,7 @@ import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
|
4
4
|
import useControlValue from '@kne/use-control-value';
|
|
5
5
|
import { Popover, Space, Button, Badge, List, Tag, Card, Spin, Empty, Tooltip, Calendar } from 'antd';
|
|
6
6
|
import { createWithIntlProvider, useIntl } from '@kne/react-intl';
|
|
7
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import FormInfo, { Input, TextArea, Form, SubmitButton } from '@kne/form-info';
|
|
9
9
|
|
|
10
10
|
function _extends() {
|
|
@@ -897,20 +897,43 @@ const ViewPanel = ({
|
|
|
897
897
|
});
|
|
898
898
|
};
|
|
899
899
|
|
|
900
|
-
const LONG_PRESS_DELAY =
|
|
901
|
-
const
|
|
900
|
+
const LONG_PRESS_DELAY = 400;
|
|
901
|
+
const SCROLL_CANCEL_THRESHOLD = 12;
|
|
902
|
+
const TAP_MOVE_THRESHOLD = 8;
|
|
902
903
|
const getPopoverKey = slot => slot ? `form:${slot.key}` : null;
|
|
903
|
-
const
|
|
904
|
-
const
|
|
905
|
-
|
|
906
|
-
if (!slotElement || !(container != null && container.contains(slotElement))) {
|
|
904
|
+
const getSlotIndexFromPoint = (container, clientX, clientY) => {
|
|
905
|
+
const slotElements = container == null || container.querySelectorAll == null ? void 0 : container.querySelectorAll('[data-slot-index]');
|
|
906
|
+
if (!(slotElements != null && slotElements.length)) {
|
|
907
907
|
return null;
|
|
908
908
|
}
|
|
909
|
-
|
|
909
|
+
let closestIndex = null;
|
|
910
|
+
let closestDistance = Infinity;
|
|
911
|
+
for (const candidate of slotElements) {
|
|
912
|
+
const rect = candidate.getBoundingClientRect();
|
|
913
|
+
const index = Number(candidate.getAttribute('data-slot-index'));
|
|
914
|
+
if (Number.isNaN(index)) {
|
|
915
|
+
continue;
|
|
916
|
+
}
|
|
917
|
+
if (clientY >= rect.top && clientY <= rect.bottom && clientX >= rect.left && clientX <= rect.right) {
|
|
918
|
+
return index;
|
|
919
|
+
}
|
|
920
|
+
if (clientX < rect.left || clientX > rect.right) {
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
const centerY = (rect.top + rect.bottom) / 2;
|
|
924
|
+
const distance = Math.abs(clientY - centerY);
|
|
925
|
+
if (distance < closestDistance) {
|
|
926
|
+
closestDistance = distance;
|
|
927
|
+
closestIndex = index;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
return closestIndex;
|
|
910
931
|
};
|
|
911
|
-
const
|
|
912
|
-
|
|
913
|
-
|
|
932
|
+
const clearDocumentTextSelection = () => {
|
|
933
|
+
const selection = document.getSelection == null ? void 0 : document.getSelection();
|
|
934
|
+
if (selection && !selection.isCollapsed) {
|
|
935
|
+
selection.removeAllRanges();
|
|
936
|
+
}
|
|
914
937
|
};
|
|
915
938
|
const useScheduleSelectionGesture = ({
|
|
916
939
|
slots,
|
|
@@ -930,9 +953,14 @@ const useScheduleSelectionGesture = ({
|
|
|
930
953
|
const touchStateRef = useRef(null);
|
|
931
954
|
const slotsDataRef = useRef(slots);
|
|
932
955
|
const selectedSlotsRef = useRef(selectedSlots);
|
|
956
|
+
const allowMultiSelectRef = useRef(allowMultiSelect);
|
|
933
957
|
const suppressTriggerUntilRef = useRef(0);
|
|
958
|
+
const suppressMouseUntilRef = useRef(0);
|
|
959
|
+
const scrollLockRef = useRef(null);
|
|
960
|
+
const handlersRef = useRef({});
|
|
934
961
|
slotsDataRef.current = slots;
|
|
935
962
|
selectedSlotsRef.current = selectedSlots;
|
|
963
|
+
allowMultiSelectRef.current = allowMultiSelect;
|
|
936
964
|
const selectedKeys = useMemo(() => new Set(selectedSlots.map(slot => slot.key)), [selectedSlots]);
|
|
937
965
|
const selectedAnchorKey = (_selectedSlots = selectedSlots[selectedSlots.length - 1]) == null ? void 0 : _selectedSlots.key;
|
|
938
966
|
const formPopoverKey = selectedAnchorKey ? `form:${selectedAnchorKey}` : null;
|
|
@@ -942,16 +970,55 @@ const useScheduleSelectionGesture = ({
|
|
|
942
970
|
longPressTimerRef.current = null;
|
|
943
971
|
}
|
|
944
972
|
}, []);
|
|
973
|
+
const unlockContainerScroll = useCallback(() => {
|
|
974
|
+
const container = slotsRef.current;
|
|
975
|
+
if (!container || scrollLockRef.current == null) {
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
const scrollTop = scrollLockRef.current;
|
|
979
|
+
container.style.overflow = '';
|
|
980
|
+
container.style.touchAction = '';
|
|
981
|
+
container.scrollTop = scrollTop;
|
|
982
|
+
scrollLockRef.current = null;
|
|
983
|
+
}, []);
|
|
984
|
+
const lockContainerScroll = useCallback(() => {
|
|
985
|
+
const container = slotsRef.current;
|
|
986
|
+
if (!container || scrollLockRef.current != null) {
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
scrollLockRef.current = container.scrollTop;
|
|
990
|
+
container.style.overflow = 'hidden';
|
|
991
|
+
container.style.touchAction = 'none';
|
|
992
|
+
}, []);
|
|
993
|
+
const resetGestureState = useCallback(() => {
|
|
994
|
+
clearLongPress();
|
|
995
|
+
const container = slotsRef.current;
|
|
996
|
+
const touchState = touchStateRef.current;
|
|
997
|
+
if (container && (touchState == null ? void 0 : touchState.pointerId) != null && container.hasPointerCapture != null && container.hasPointerCapture(touchState.pointerId)) {
|
|
998
|
+
try {
|
|
999
|
+
container.releasePointerCapture(touchState.pointerId);
|
|
1000
|
+
} catch (_unused) {
|
|
1001
|
+
// Ignore capture release errors on stale pointers.
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
draggingRef.current = false;
|
|
1005
|
+
dragStartIndexRef.current = null;
|
|
1006
|
+
touchStateRef.current = null;
|
|
1007
|
+
container == null || container.classList.remove('schedule-calendar-touch-dragging');
|
|
1008
|
+
unlockContainerScroll();
|
|
1009
|
+
setDragging(false);
|
|
1010
|
+
}, [clearLongPress, unlockContainerScroll]);
|
|
945
1011
|
const selectSlots = useCallback(nextSlots => {
|
|
946
1012
|
selectedSlotsRef.current = nextSlots;
|
|
947
1013
|
if (!nextSlots.length) {
|
|
948
1014
|
setActivePopoverKey(null);
|
|
1015
|
+
resetGestureState();
|
|
949
1016
|
}
|
|
950
1017
|
setSelectedSlots(nextSlots);
|
|
951
1018
|
onSlotRangeChange == null || onSlotRangeChange(nextSlots, {
|
|
952
1019
|
action: nextSlots.length ? 'select' : 'clear'
|
|
953
1020
|
});
|
|
954
|
-
}, [onSlotRangeChange, setSelectedSlots]);
|
|
1021
|
+
}, [onSlotRangeChange, resetGestureState, setSelectedSlots]);
|
|
955
1022
|
const getSelectableRange = useCallback((startIndex, endIndex) => {
|
|
956
1023
|
const [start, end] = [Math.min(startIndex, endIndex), Math.max(startIndex, endIndex)];
|
|
957
1024
|
return slotsDataRef.current.slice(start, end + 1).filter(slot => slot.status === 'free');
|
|
@@ -963,13 +1030,18 @@ const useScheduleSelectionGesture = ({
|
|
|
963
1030
|
}
|
|
964
1031
|
}, []);
|
|
965
1032
|
const startSlotSelection = useCallback((slot, index, {
|
|
966
|
-
showPopover: _showPopover = true
|
|
1033
|
+
showPopover: _showPopover = true,
|
|
1034
|
+
lockScroll: _lockScroll = false
|
|
967
1035
|
} = {}) => {
|
|
968
1036
|
var _slotsRef$current;
|
|
1037
|
+
clearDocumentTextSelection();
|
|
969
1038
|
setActivePopoverKey(getPopoverKey(slot));
|
|
970
1039
|
draggingRef.current = true;
|
|
971
1040
|
dragStartIndexRef.current = index;
|
|
972
1041
|
(_slotsRef$current = slotsRef.current) == null || _slotsRef$current.classList.add('schedule-calendar-touch-dragging');
|
|
1042
|
+
if (_lockScroll) {
|
|
1043
|
+
lockContainerScroll();
|
|
1044
|
+
}
|
|
973
1045
|
setDragging(true);
|
|
974
1046
|
selectSlots([slot]);
|
|
975
1047
|
if (!_showPopover) {
|
|
@@ -977,44 +1049,58 @@ const useScheduleSelectionGesture = ({
|
|
|
977
1049
|
setActivePopoverKey(null);
|
|
978
1050
|
}
|
|
979
1051
|
onFreeSlotClick == null || onFreeSlotClick(slot);
|
|
980
|
-
}, [onFreeSlotClick, selectSlots]);
|
|
1052
|
+
}, [lockContainerScroll, onFreeSlotClick, selectSlots]);
|
|
981
1053
|
const finishSelection = useCallback(({
|
|
982
1054
|
fromTouch: _fromTouch = false
|
|
983
1055
|
} = {}) => {
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
dragStartIndexRef.current = null;
|
|
988
|
-
(_slotsRef$current2 = slotsRef.current) == null || _slotsRef$current2.classList.remove('schedule-calendar-touch-dragging');
|
|
989
|
-
setDragging(false);
|
|
990
|
-
if (selectedSlotsRef.current.length) {
|
|
1056
|
+
const hadSelection = selectedSlotsRef.current.length > 0;
|
|
1057
|
+
resetGestureState();
|
|
1058
|
+
if (hadSelection) {
|
|
991
1059
|
if (_fromTouch) {
|
|
992
1060
|
suppressTriggerUntilRef.current = Date.now() + 500;
|
|
993
1061
|
}
|
|
994
1062
|
showFormPopoverForSlots(selectedSlotsRef.current);
|
|
995
1063
|
}
|
|
996
|
-
}, [
|
|
1064
|
+
}, [resetGestureState, showFormPopoverForSlots]);
|
|
997
1065
|
const updateSelectionRange = useCallback(index => {
|
|
998
1066
|
const startIndex = dragStartIndexRef.current;
|
|
999
|
-
if (startIndex === null || !
|
|
1067
|
+
if (startIndex === null || !allowMultiSelectRef.current) {
|
|
1000
1068
|
return;
|
|
1001
1069
|
}
|
|
1002
1070
|
const nextSlots = getSelectableRange(startIndex, index);
|
|
1003
1071
|
selectSlots(nextSlots);
|
|
1004
|
-
}, [
|
|
1072
|
+
}, [getSelectableRange, selectSlots]);
|
|
1073
|
+
const shouldIgnoreMouseSelectionEvent = useCallback(() => {
|
|
1074
|
+
return !!touchStateRef.current || Date.now() < suppressMouseUntilRef.current;
|
|
1075
|
+
}, []);
|
|
1005
1076
|
const handleMouseDown = useCallback((event, slot, index) => {
|
|
1077
|
+
if (shouldIgnoreMouseSelectionEvent()) {
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1006
1080
|
if (slot.status !== 'free') {
|
|
1007
1081
|
return;
|
|
1008
1082
|
}
|
|
1009
1083
|
event.preventDefault();
|
|
1010
1084
|
startSlotSelection(slot, index);
|
|
1011
|
-
}, [startSlotSelection]);
|
|
1085
|
+
}, [shouldIgnoreMouseSelectionEvent, startSlotSelection]);
|
|
1012
1086
|
const handleMouseEnter = useCallback(index => {
|
|
1013
|
-
if (!draggingRef.current) {
|
|
1087
|
+
if (shouldIgnoreMouseSelectionEvent() || !draggingRef.current) {
|
|
1014
1088
|
return;
|
|
1015
1089
|
}
|
|
1016
1090
|
updateSelectionRange(index);
|
|
1017
|
-
}, [updateSelectionRange]);
|
|
1091
|
+
}, [shouldIgnoreMouseSelectionEvent, updateSelectionRange]);
|
|
1092
|
+
const handleMouseUp = useCallback(() => {
|
|
1093
|
+
if (shouldIgnoreMouseSelectionEvent()) {
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
finishSelection();
|
|
1097
|
+
}, [finishSelection, shouldIgnoreMouseSelectionEvent]);
|
|
1098
|
+
const handleMouseLeave = useCallback(() => {
|
|
1099
|
+
if (shouldIgnoreMouseSelectionEvent()) {
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
finishSelection();
|
|
1103
|
+
}, [finishSelection, shouldIgnoreMouseSelectionEvent]);
|
|
1018
1104
|
const handlePopoverOpenChange = useCallback((open, currentPopoverKey, {
|
|
1019
1105
|
isForm: _isForm = false
|
|
1020
1106
|
} = {}) => {
|
|
@@ -1032,26 +1118,79 @@ const useScheduleSelectionGesture = ({
|
|
|
1032
1118
|
return prevKey === currentPopoverKey ? null : prevKey;
|
|
1033
1119
|
});
|
|
1034
1120
|
}, [selectSlots]);
|
|
1121
|
+
handlersRef.current = {
|
|
1122
|
+
clearLongPress,
|
|
1123
|
+
finishSelection,
|
|
1124
|
+
onFreeSlotClick,
|
|
1125
|
+
resetGestureState,
|
|
1126
|
+
selectSlots,
|
|
1127
|
+
showFormPopoverForSlots,
|
|
1128
|
+
startSlotSelection,
|
|
1129
|
+
updateSelectionRange
|
|
1130
|
+
};
|
|
1035
1131
|
useEffect(() => {
|
|
1036
1132
|
const container = slotsRef.current;
|
|
1037
1133
|
if (!container) {
|
|
1038
1134
|
return undefined;
|
|
1039
1135
|
}
|
|
1040
|
-
const
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1136
|
+
const releasePointerCapture = pointerId => {
|
|
1137
|
+
if (pointerId == null || !(container.hasPointerCapture != null && container.hasPointerCapture(pointerId))) {
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
try {
|
|
1141
|
+
container.releasePointerCapture(pointerId);
|
|
1142
|
+
} catch (_unused2) {
|
|
1143
|
+
// Ignore capture release errors on stale pointers.
|
|
1045
1144
|
}
|
|
1145
|
+
};
|
|
1146
|
+
const clearPendingTouch = () => {
|
|
1147
|
+
handlersRef.current.clearLongPress();
|
|
1046
1148
|
touchStateRef.current = null;
|
|
1047
1149
|
};
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1150
|
+
const isStillOnSameSlot = (touchState, clientX, clientY) => {
|
|
1151
|
+
const currentIndex = getSlotIndexFromPoint(container, clientX, clientY);
|
|
1152
|
+
return currentIndex === touchState.index;
|
|
1153
|
+
};
|
|
1154
|
+
const shouldCancelPendingGesture = (touchState, clientX, clientY) => {
|
|
1155
|
+
const moveX = Math.abs(clientX - touchState.x);
|
|
1156
|
+
const moveY = Math.abs(clientY - touchState.y);
|
|
1157
|
+
if (moveY > SCROLL_CANCEL_THRESHOLD) {
|
|
1158
|
+
return true;
|
|
1159
|
+
}
|
|
1160
|
+
if (!isStillOnSameSlot(touchState, clientX, clientY)) {
|
|
1161
|
+
return true;
|
|
1162
|
+
}
|
|
1163
|
+
if (!allowMultiSelectRef.current && (moveX > TAP_MOVE_THRESHOLD || moveY > TAP_MOVE_THRESHOLD)) {
|
|
1164
|
+
return true;
|
|
1165
|
+
}
|
|
1166
|
+
return false;
|
|
1167
|
+
};
|
|
1168
|
+
const activateLongPress = touchState => {
|
|
1169
|
+
var _slotsRef$current2;
|
|
1170
|
+
if (!isStillOnSameSlot(touchState, touchState.lastX, touchState.lastY)) {
|
|
1050
1171
|
return;
|
|
1051
1172
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1173
|
+
touchState.longPressed = true;
|
|
1174
|
+
touchState.active = true;
|
|
1175
|
+
clearDocumentTextSelection();
|
|
1176
|
+
try {
|
|
1177
|
+
container.setPointerCapture(touchState.pointerId);
|
|
1178
|
+
} catch (_unused3) {
|
|
1179
|
+
// Continue when capture is unavailable.
|
|
1180
|
+
}
|
|
1181
|
+
(_slotsRef$current2 = slotsRef.current) == null || _slotsRef$current2.classList.add('schedule-calendar-touch-dragging');
|
|
1182
|
+
handlersRef.current.startSlotSelection(touchState.slot, touchState.index, {
|
|
1183
|
+
showPopover: false,
|
|
1184
|
+
lockScroll: true
|
|
1185
|
+
});
|
|
1186
|
+
};
|
|
1187
|
+
const handlePointerDown = event => {
|
|
1188
|
+
var _event$target;
|
|
1189
|
+
if (event.pointerType === 'mouse' || event.isPrimary === false) {
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
const slotElement = (_event$target = event.target) == null || _event$target.closest == null ? void 0 : _event$target.closest('[data-slot-index]');
|
|
1193
|
+
if (!slotElement || !container.contains(slotElement)) {
|
|
1055
1194
|
return;
|
|
1056
1195
|
}
|
|
1057
1196
|
const index = Number(slotElement.getAttribute('data-slot-index'));
|
|
@@ -1059,115 +1198,138 @@ const useScheduleSelectionGesture = ({
|
|
|
1059
1198
|
if (Number.isNaN(index) || (slot == null ? void 0 : slot.status) !== 'free') {
|
|
1060
1199
|
return;
|
|
1061
1200
|
}
|
|
1062
|
-
|
|
1201
|
+
handlersRef.current.resetGestureState();
|
|
1063
1202
|
touchStateRef.current = {
|
|
1064
|
-
|
|
1065
|
-
x:
|
|
1066
|
-
y:
|
|
1203
|
+
pointerId: event.pointerId,
|
|
1204
|
+
x: event.clientX,
|
|
1205
|
+
y: event.clientY,
|
|
1206
|
+
lastX: event.clientX,
|
|
1207
|
+
lastY: event.clientY,
|
|
1067
1208
|
slot,
|
|
1068
1209
|
index,
|
|
1069
1210
|
moved: false,
|
|
1070
1211
|
longPressed: false,
|
|
1071
|
-
active: false
|
|
1212
|
+
active: false,
|
|
1213
|
+
selectionTriggered: false
|
|
1072
1214
|
};
|
|
1215
|
+
if (!allowMultiSelectRef.current) {
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1073
1218
|
longPressTimerRef.current = window.setTimeout(() => {
|
|
1074
|
-
var _slotsRef$current4;
|
|
1075
1219
|
const touchState = touchStateRef.current;
|
|
1076
|
-
if (!touchState) {
|
|
1220
|
+
if (!touchState || touchState.pointerId !== event.pointerId || touchState.moved) {
|
|
1077
1221
|
return;
|
|
1078
1222
|
}
|
|
1079
|
-
touchState
|
|
1080
|
-
touchState.active = true;
|
|
1081
|
-
(_slotsRef$current4 = slotsRef.current) == null || _slotsRef$current4.classList.add('schedule-calendar-touch-dragging');
|
|
1082
|
-
startSlotSelection(slot, index, {
|
|
1083
|
-
showPopover: false
|
|
1084
|
-
});
|
|
1223
|
+
activateLongPress(touchState);
|
|
1085
1224
|
longPressTimerRef.current = null;
|
|
1086
1225
|
}, LONG_PRESS_DELAY);
|
|
1087
1226
|
};
|
|
1088
|
-
const
|
|
1227
|
+
const handlePointerMove = event => {
|
|
1089
1228
|
const touchState = touchStateRef.current;
|
|
1090
|
-
if (!touchState) {
|
|
1091
|
-
return;
|
|
1092
|
-
}
|
|
1093
|
-
const touch = Array.from(event.touches).find(item => item.identifier === touchState.identifier) || event.touches[0];
|
|
1094
|
-
if (!touch) {
|
|
1229
|
+
if (!touchState || event.pointerId !== touchState.pointerId) {
|
|
1095
1230
|
return;
|
|
1096
1231
|
}
|
|
1232
|
+
touchState.lastX = event.clientX;
|
|
1233
|
+
touchState.lastY = event.clientY;
|
|
1097
1234
|
if (!touchState.active) {
|
|
1098
|
-
|
|
1099
|
-
const moveY = Math.abs(touch.clientY - touchState.y);
|
|
1100
|
-
if (moveX > MOVE_THRESHOLD || moveY > MOVE_THRESHOLD) {
|
|
1235
|
+
if (shouldCancelPendingGesture(touchState, event.clientX, event.clientY)) {
|
|
1101
1236
|
touchState.moved = true;
|
|
1102
|
-
|
|
1237
|
+
clearPendingTouch();
|
|
1103
1238
|
}
|
|
1104
1239
|
return;
|
|
1105
1240
|
}
|
|
1106
1241
|
event.preventDefault();
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
if (!Number.isNaN(index)) {
|
|
1113
|
-
updateSelectionRange(index);
|
|
1242
|
+
event.stopPropagation();
|
|
1243
|
+
clearDocumentTextSelection();
|
|
1244
|
+
const index = getSlotIndexFromPoint(container, event.clientX, event.clientY);
|
|
1245
|
+
if (index !== null) {
|
|
1246
|
+
handlersRef.current.updateSelectionRange(index);
|
|
1114
1247
|
}
|
|
1115
1248
|
};
|
|
1116
|
-
const
|
|
1249
|
+
const handlePointerUp = event => {
|
|
1117
1250
|
const touchState = touchStateRef.current;
|
|
1118
|
-
if (!touchState) {
|
|
1119
|
-
return;
|
|
1120
|
-
}
|
|
1121
|
-
const touch = Array.from(event.changedTouches || []).find(item => item.identifier === touchState.identifier) || getTouchPoint(event);
|
|
1122
|
-
if (!touch) {
|
|
1123
|
-
clearTouchState();
|
|
1251
|
+
if (!touchState || event.pointerId !== touchState.pointerId) {
|
|
1124
1252
|
return;
|
|
1125
1253
|
}
|
|
1254
|
+
releasePointerCapture(event.pointerId);
|
|
1255
|
+
suppressMouseUntilRef.current = Date.now() + 700;
|
|
1126
1256
|
if (touchState.active) {
|
|
1127
1257
|
event.preventDefault();
|
|
1258
|
+
touchState.selectionTriggered = true;
|
|
1259
|
+
const index = getSlotIndexFromPoint(container, event.clientX, event.clientY);
|
|
1260
|
+
if (index !== null) {
|
|
1261
|
+
handlersRef.current.updateSelectionRange(index);
|
|
1262
|
+
}
|
|
1128
1263
|
suppressTriggerUntilRef.current = Date.now() + 500;
|
|
1129
|
-
finishSelection({
|
|
1264
|
+
handlersRef.current.finishSelection({
|
|
1130
1265
|
fromTouch: true
|
|
1131
1266
|
});
|
|
1132
|
-
touchStateRef.current = null;
|
|
1133
1267
|
return;
|
|
1134
1268
|
}
|
|
1135
|
-
|
|
1136
|
-
|
|
1269
|
+
handlersRef.current.clearLongPress();
|
|
1270
|
+
const quickTap = !touchState.moved && !touchState.longPressed && Math.abs(event.clientX - touchState.x) <= TAP_MOVE_THRESHOLD && Math.abs(event.clientY - touchState.y) <= TAP_MOVE_THRESHOLD && isStillOnSameSlot(touchState, event.clientX, event.clientY);
|
|
1271
|
+
const {
|
|
1272
|
+
slot
|
|
1273
|
+
} = touchState;
|
|
1274
|
+
touchStateRef.current = null;
|
|
1137
1275
|
if (quickTap) {
|
|
1276
|
+
touchState.selectionTriggered = true;
|
|
1138
1277
|
suppressTriggerUntilRef.current = Date.now() + 500;
|
|
1139
|
-
selectSlots([
|
|
1140
|
-
showFormPopoverForSlots([
|
|
1141
|
-
onFreeSlotClick == null || onFreeSlotClick(
|
|
1278
|
+
handlersRef.current.selectSlots([slot]);
|
|
1279
|
+
handlersRef.current.showFormPopoverForSlots([slot]);
|
|
1280
|
+
handlersRef.current.onFreeSlotClick == null || handlersRef.current.onFreeSlotClick(slot);
|
|
1281
|
+
return;
|
|
1142
1282
|
}
|
|
1283
|
+
handlersRef.current.resetGestureState();
|
|
1143
1284
|
};
|
|
1144
1285
|
const handleContextMenu = event => {
|
|
1145
|
-
|
|
1286
|
+
var _touchStateRef$curren;
|
|
1287
|
+
if ((_touchStateRef$curren = touchStateRef.current) != null && _touchStateRef$curren.active || draggingRef.current) {
|
|
1146
1288
|
event.preventDefault();
|
|
1147
1289
|
}
|
|
1148
1290
|
};
|
|
1149
|
-
|
|
1291
|
+
const handleSelectStart = event => {
|
|
1292
|
+
var _touchStateRef$curren2;
|
|
1293
|
+
if (!((_touchStateRef$curren2 = touchStateRef.current) != null && _touchStateRef$curren2.active) && !draggingRef.current) {
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
event.preventDefault();
|
|
1297
|
+
};
|
|
1298
|
+
const handleTouchMove = event => {
|
|
1299
|
+
var _touchStateRef$curren3;
|
|
1300
|
+
if (!draggingRef.current && !((_touchStateRef$curren3 = touchStateRef.current) != null && _touchStateRef$curren3.active)) {
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
event.preventDefault();
|
|
1304
|
+
};
|
|
1305
|
+
const touchOptions = {
|
|
1306
|
+
passive: false,
|
|
1307
|
+
capture: true
|
|
1308
|
+
};
|
|
1309
|
+
container.addEventListener('pointerdown', handlePointerDown, {
|
|
1150
1310
|
passive: true
|
|
1151
1311
|
});
|
|
1152
|
-
container.addEventListener('
|
|
1312
|
+
container.addEventListener('pointermove', handlePointerMove, {
|
|
1153
1313
|
passive: false
|
|
1154
1314
|
});
|
|
1155
|
-
container.addEventListener('
|
|
1315
|
+
container.addEventListener('pointerup', handlePointerUp, {
|
|
1156
1316
|
passive: false
|
|
1157
1317
|
});
|
|
1158
|
-
container.addEventListener('
|
|
1318
|
+
container.addEventListener('pointercancel', handlePointerUp, {
|
|
1159
1319
|
passive: false
|
|
1160
1320
|
});
|
|
1321
|
+
container.addEventListener('touchmove', handleTouchMove, touchOptions);
|
|
1161
1322
|
container.addEventListener('contextmenu', handleContextMenu);
|
|
1323
|
+
container.addEventListener('selectstart', handleSelectStart);
|
|
1162
1324
|
return () => {
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
container.removeEventListener('
|
|
1325
|
+
var _touchStateRef$curren4;
|
|
1326
|
+
releasePointerCapture((_touchStateRef$curren4 = touchStateRef.current) == null ? void 0 : _touchStateRef$curren4.pointerId);
|
|
1327
|
+
handlersRef.current.clearLongPress();
|
|
1328
|
+
handlersRef.current.resetGestureState();
|
|
1329
|
+
longPressTimerRef.current = null;
|
|
1330
|
+
container.removeEventListener('touchmove', handleTouchMove, touchOptions);
|
|
1169
1331
|
};
|
|
1170
|
-
}, [
|
|
1332
|
+
}, []);
|
|
1171
1333
|
return {
|
|
1172
1334
|
activePopoverKey,
|
|
1173
1335
|
dragging,
|
|
@@ -1180,6 +1342,8 @@ const useScheduleSelectionGesture = ({
|
|
|
1180
1342
|
finishSelection,
|
|
1181
1343
|
handleMouseDown,
|
|
1182
1344
|
handleMouseEnter,
|
|
1345
|
+
handleMouseUp,
|
|
1346
|
+
handleMouseLeave,
|
|
1183
1347
|
handlePopoverOpenChange
|
|
1184
1348
|
};
|
|
1185
1349
|
};
|
|
@@ -1259,6 +1423,7 @@ const SlotItem = ({
|
|
|
1259
1423
|
if (content) {
|
|
1260
1424
|
const customNode = /*#__PURE__*/jsx("div", {
|
|
1261
1425
|
"data-slot-index": slot.index,
|
|
1426
|
+
"data-slot-status": slot.status,
|
|
1262
1427
|
onContextMenu: onContextMenu,
|
|
1263
1428
|
onMouseDown: onMouseDown,
|
|
1264
1429
|
onPointerDown: onPointerDown,
|
|
@@ -1318,19 +1483,10 @@ const SlotItem = ({
|
|
|
1318
1483
|
}
|
|
1319
1484
|
return node;
|
|
1320
1485
|
};
|
|
1321
|
-
const
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
}),
|
|
1326
|
-
"data-slot-index": slot.index,
|
|
1327
|
-
disabled: slot.status === 'disabled',
|
|
1328
|
-
onContextMenu: onContextMenu,
|
|
1329
|
-
onMouseDown: onMouseDown,
|
|
1330
|
-
onPointerDown: onPointerDown,
|
|
1331
|
-
onMouseEnter: onMouseEnter,
|
|
1332
|
-
onMouseUp: onMouseUp,
|
|
1333
|
-
onClick: onClick,
|
|
1486
|
+
const slotClassName = classNames(style$1['slot-item'], style$1[`slot-${slot.status}`], {
|
|
1487
|
+
[style$1['slot-selected']]: selected
|
|
1488
|
+
});
|
|
1489
|
+
const slotChildren = /*#__PURE__*/jsxs(Fragment, {
|
|
1334
1490
|
children: [/*#__PURE__*/jsx("span", {
|
|
1335
1491
|
className: style$1['slot-dot']
|
|
1336
1492
|
}), /*#__PURE__*/jsx("span", {
|
|
@@ -1354,6 +1510,36 @@ const SlotItem = ({
|
|
|
1354
1510
|
children: slot.events.map(event => event.title).join('、')
|
|
1355
1511
|
}) : null]
|
|
1356
1512
|
});
|
|
1513
|
+
const slotHandlers = {
|
|
1514
|
+
onContextMenu,
|
|
1515
|
+
onMouseDown,
|
|
1516
|
+
onPointerDown,
|
|
1517
|
+
onMouseEnter,
|
|
1518
|
+
onMouseUp,
|
|
1519
|
+
onClick
|
|
1520
|
+
};
|
|
1521
|
+
const inner = slot.status === 'disabled' ? /*#__PURE__*/jsx("button", {
|
|
1522
|
+
type: "button",
|
|
1523
|
+
className: slotClassName,
|
|
1524
|
+
"data-slot-index": slot.index,
|
|
1525
|
+
"data-slot-status": slot.status,
|
|
1526
|
+
disabled: true,
|
|
1527
|
+
onContextMenu: onContextMenu,
|
|
1528
|
+
onMouseDown: onMouseDown,
|
|
1529
|
+
onPointerDown: onPointerDown,
|
|
1530
|
+
onMouseEnter: onMouseEnter,
|
|
1531
|
+
onMouseUp: onMouseUp,
|
|
1532
|
+
onClick: onClick,
|
|
1533
|
+
children: slotChildren
|
|
1534
|
+
}) : /*#__PURE__*/jsx("div", _extends({
|
|
1535
|
+
role: "button",
|
|
1536
|
+
tabIndex: 0,
|
|
1537
|
+
className: slotClassName,
|
|
1538
|
+
"data-slot-index": slot.index,
|
|
1539
|
+
"data-slot-status": slot.status
|
|
1540
|
+
}, slotHandlers, {
|
|
1541
|
+
children: slotChildren
|
|
1542
|
+
}));
|
|
1357
1543
|
return wrapWithPopover(inner);
|
|
1358
1544
|
};
|
|
1359
1545
|
|
|
@@ -1392,9 +1578,10 @@ const SchedulePanel = ({
|
|
|
1392
1578
|
selectedKeys,
|
|
1393
1579
|
selectSlots,
|
|
1394
1580
|
slotsRef,
|
|
1395
|
-
finishSelection,
|
|
1396
1581
|
handleMouseDown,
|
|
1397
1582
|
handleMouseEnter,
|
|
1583
|
+
handleMouseUp,
|
|
1584
|
+
handleMouseLeave,
|
|
1398
1585
|
handlePopoverOpenChange
|
|
1399
1586
|
} = useScheduleSelectionGesture({
|
|
1400
1587
|
slots,
|
|
@@ -1467,8 +1654,8 @@ const SchedulePanel = ({
|
|
|
1467
1654
|
[style$1['slots-dragging']]: dragging
|
|
1468
1655
|
}),
|
|
1469
1656
|
onScroll: onScroll,
|
|
1470
|
-
onMouseUp:
|
|
1471
|
-
onMouseLeave:
|
|
1657
|
+
onMouseUp: handleMouseUp,
|
|
1658
|
+
onMouseLeave: handleMouseLeave,
|
|
1472
1659
|
children: [/*#__PURE__*/jsx(PanelScrollShadow, {
|
|
1473
1660
|
visible: scrolled
|
|
1474
1661
|
}), /*#__PURE__*/jsx("div", {
|
|
@@ -1498,7 +1685,7 @@ const SchedulePanel = ({
|
|
|
1498
1685
|
},
|
|
1499
1686
|
onMouseDown: event => handleMouseDown(event, slot, index),
|
|
1500
1687
|
onMouseEnter: () => handleMouseEnter(index),
|
|
1501
|
-
onMouseUp:
|
|
1688
|
+
onMouseUp: handleMouseUp,
|
|
1502
1689
|
onClick: undefined
|
|
1503
1690
|
}, slot.key);
|
|
1504
1691
|
})
|