From def4934b45804c1ccdeaa4c5c8ddb52b346b0d08 Mon Sep 17 00:00:00 2001 From: forceddd Date: Tue, 16 Apr 2024 00:45:44 +0800 Subject: [PATCH] fix: Correct selection issues * fix: issue 2536 * fix: drag selection upward * fix: keep the original logic --------- Co-authored-by: forceddd --- src/DayColumn.js | 23 ++++++++++------------- src/utils/TimeSlots.js | 13 ++++++++++--- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/DayColumn.js b/src/DayColumn.js index ae75c69a4..ed00cfd63 100644 --- a/src/DayColumn.js +++ b/src/DayColumn.js @@ -14,21 +14,14 @@ import { DayLayoutAlgorithmPropType } from './utils/propTypes' import DayColumnWrapper from './DayColumnWrapper' -let slotMetrics class DayColumn extends React.Component { state = { selecting: false, timeIndicatorPosition: null } intervalTriggered = false - static getDerivedStateFromProps(nextProps) { - slotMetrics = slotMetrics - ? slotMetrics.update(nextProps) - : TimeSlotUtils.getSlotMetrics(nextProps) - - return null - } constructor(...args) { super(...args) + this.slotMetrics = TimeSlotUtils.getSlotMetrics(this.props) this.containerRef = createRef() } @@ -99,7 +92,7 @@ class DayColumn extends React.Component { const current = getNow() if (current >= min && current <= max) { - const top = slotMetrics.getCurrentTimePosition(current) + const top = this.slotMetrics.getCurrentTimePosition(current) this.intervalTriggered = true this.setState({ timeIndicatorPosition: top }) } else { @@ -120,6 +113,9 @@ class DayColumn extends React.Component { components: { eventContainerWrapper: EventContainer, ...components }, } = this.props + this.slotMetrics = this.slotMetrics.update(this.props) + + let { slotMetrics } = this let { selecting, top, height, startDate, endDate } = this.state let selectDates = { start: startDate, end: endDate } @@ -199,6 +195,7 @@ class DayColumn extends React.Component { resizable, } = this.props + const { slotMetrics } = this const { messages } = localizer let styledEvents = DayEventLayout.getStyledEvents({ @@ -294,7 +291,7 @@ class DayColumn extends React.Component { } let selectionState = (point) => { - let currentSlot = slotMetrics.closestSlotFromPoint( + let currentSlot = this.slotMetrics.closestSlotFromPoint( point, getBoundsForNode(node) ) @@ -305,12 +302,12 @@ class DayColumn extends React.Component { let initialSlot = this._initialSlot if (localizer.lte(initialSlot, currentSlot)) { - currentSlot = slotMetrics.nextSlot(currentSlot) + currentSlot = this.slotMetrics.nextSlot(currentSlot) } else if (localizer.gt(initialSlot, currentSlot)) { - initialSlot = slotMetrics.nextSlot(initialSlot) + initialSlot = this.slotMetrics.nextSlot(initialSlot) } - const selectRange = slotMetrics.getRange( + const selectRange = this.slotMetrics.getRange( localizer.min(initialSlot, currentSlot), localizer.max(initialSlot, currentSlot) ) diff --git a/src/utils/TimeSlots.js b/src/utils/TimeSlots.js index b49bc2b9c..c3ce68bd5 100644 --- a/src/utils/TimeSlots.js +++ b/src/utils/TimeSlots.js @@ -68,12 +68,19 @@ export function getSlotMetrics({ }, nextSlot(slot) { - let next = slots[Math.min(slots.indexOf(slot) + 1, slots.length - 1)] + // We cannot guarantee that the slot object must be in slots, + // because after each update, a new slots array will be created. + let next = + slots[ + Math.min( + slots.findIndex((s) => s === slot || localizer.eq(s, slot)) + 1, + slots.length - 1 + ) + ] // in the case of the last slot we won't a long enough range so manually get it - if (next === slot) next = localizer.add(slot, step, 'minutes') + if (localizer.eq(next, slot)) next = localizer.add(slot, step, 'minutes') return next }, - closestSlotToPosition(percent) { const slot = Math.min( slots.length - 1,