From 86115ba2ad668e8cfc2c801174f69c69504b7b03 Mon Sep 17 00:00:00 2001 From: Olexandr Hoshylyk Date: Mon, 15 Nov 2021 09:07:53 +0200 Subject: [PATCH 1/3] Add resizing and dragging events --- .size-snapshot.json | 22 ++++++------- .../dragAndDrop/EventContainerWrapper.js | 31 +++++++++++++++++-- src/addons/dragAndDrop/README.md | 6 ++-- src/addons/dragAndDrop/withDragAndDrop.js | 4 +++ 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/.size-snapshot.json b/.size-snapshot.json index a7a886045..0b3580b57 100644 --- a/.size-snapshot.json +++ b/.size-snapshot.json @@ -1,25 +1,25 @@ { "./dist/react-big-calendar.js": { - "bundled": 535473, - "minified": 165496, - "gzipped": 51033 + "bundled": 535914, + "minified": 165681, + "gzipped": 51085 }, "./dist/react-big-calendar.min.js": { - "bundled": 463447, - "minified": 143731, - "gzipped": 45351 + "bundled": 463813, + "minified": 143869, + "gzipped": 45380 }, "dist/react-big-calendar.esm.js": { - "bundled": 219707, - "minified": 99686, - "gzipped": 24772, + "bundled": 220128, + "minified": 99887, + "gzipped": 24828, "treeshaked": { "rollup": { - "code": 63234, + "code": 63372, "import_statements": 1412 }, "webpack": { - "code": 66700 + "code": 66838 } } } diff --git a/src/addons/dragAndDrop/EventContainerWrapper.js b/src/addons/dragAndDrop/EventContainerWrapper.js index d6fa56176..e04169d47 100644 --- a/src/addons/dragAndDrop/EventContainerWrapper.js +++ b/src/addons/dragAndDrop/EventContainerWrapper.js @@ -70,7 +70,21 @@ class EventContainerWrapper extends React.Component { const { duration } = eventTimes(event, accessors, this.props.localizer) let newEnd = this.props.localizer.add(newSlot, duration, 'milliseconds') - this.update(event, slotMetrics.getRange(newSlot, newEnd, false, true)) + const positionData = slotMetrics.getRange(newSlot, newEnd, false, true) + + // Skip updates, when return "false" in onDragging event + if ( + this.context.draggable.onDragging && + this.context.draggable.onDragging({ + event, + start: positionData.startDate, + end: positionData.endDate, + resourceId: this.props.resource, + }) === false + ) { + return + } + this.update(event, positionData) } handleResize(point, bounds) { @@ -85,7 +99,20 @@ class EventContainerWrapper extends React.Component { end = localizer.max(newTime, slotMetrics.closestSlotFromDate(start)) } - this.update(event, slotMetrics.getRange(start, end)) + const positionData = slotMetrics.getRange(start, end) + + // Skip updates, when return "false" in onResizing event + if ( + this.context.draggable.onResizing && + this.context.draggable.onResizing({ + event, + start: positionData.startDate, + end: positionData.endDate, + }) === false + ) { + return + } + this.update(event, positionData) } handleDropFromOutside = (point, boundaryBox) => { diff --git a/src/addons/dragAndDrop/README.md b/src/addons/dragAndDrop/README.md index d7db7fe63..40a5c7544 100644 --- a/src/addons/dragAndDrop/README.md +++ b/src/addons/dragAndDrop/README.md @@ -23,12 +23,14 @@ return ( Set `resizable` to false in your calendar if you don't want events to be resizable. `resizable` is set to true by default. -The HOC adds `onEventDrop`, `onEventResize`, and `onDragStart` callback properties if the events are +The HOC adds `onEventDrop`, `onEventResize`, `onEventResizing`, `onEventDragging` and `onDragStart` callback properties if the events are moved or resized. These callbacks are called with these signatures: ```js function onEventDrop({ event, start, end, allDay }) {...} - function onEventResize(type, { event, start, end, allDay }) {...} // type is always 'drop' + function onEventDragging({ event, start, end, resourceId }) {...} // when return "false" prevent dragging + function onEventResize({ event, start, end, allDay }) {...} + function onEventResizing({ event, start, end }) {...} // when return "false" prevent resizing function onDragStart({ event, action, direction }) {...} ``` diff --git a/src/addons/dragAndDrop/withDragAndDrop.js b/src/addons/dragAndDrop/withDragAndDrop.js index 77d418615..597abbbf0 100644 --- a/src/addons/dragAndDrop/withDragAndDrop.js +++ b/src/addons/dragAndDrop/withDragAndDrop.js @@ -19,6 +19,8 @@ export default function withDragAndDrop(Calendar) { onDragStart: PropTypes.func, onDragOver: PropTypes.func, onDropFromOutside: PropTypes.func, + onEventResizing: PropTypes.func, + onEventDragging: PropTypes.func, dragFromOutsideItem: PropTypes.func, @@ -57,6 +59,8 @@ export default function withDragAndDrop(Calendar) { onEnd: this.handleInteractionEnd, onBeginAction: this.handleBeginAction, onDropFromOutside: this.props.onDropFromOutside, + onResizing: this.props.onEventResizing, + onDragging: this.props.onEventDragging, dragFromOutsideItem: this.props.dragFromOutsideItem, draggableAccessor: this.props.draggableAccessor, resizableAccessor: this.props.resizableAccessor, From ceec8189ca8bfc31f65b32ea9025a9dbe2979248 Mon Sep 17 00:00:00 2001 From: Olexandr Hoshylyk Date: Tue, 23 Nov 2021 11:36:10 +0200 Subject: [PATCH 2/3] Add resourceId to dayPropGetter --- .size-snapshot.json | 22 +++++++++++----------- src/BackgroundCells.js | 3 ++- src/Calendar.js | 2 +- src/DayColumn.js | 2 +- src/TimeGridHeader.js | 6 +++--- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.size-snapshot.json b/.size-snapshot.json index 0b3580b57..ce5dec024 100644 --- a/.size-snapshot.json +++ b/.size-snapshot.json @@ -1,25 +1,25 @@ { "./dist/react-big-calendar.js": { - "bundled": 535914, - "minified": 165681, - "gzipped": 51085 + "bundled": 536073, + "minified": 165753, + "gzipped": 51124 }, "./dist/react-big-calendar.min.js": { - "bundled": 463813, - "minified": 143869, - "gzipped": 45380 + "bundled": 463960, + "minified": 143941, + "gzipped": 45412 }, "dist/react-big-calendar.esm.js": { - "bundled": 220128, - "minified": 99887, - "gzipped": 24828, + "bundled": 220285, + "minified": 99959, + "gzipped": 24846, "treeshaked": { "rollup": { - "code": 63372, + "code": 63444, "import_statements": 1412 }, "webpack": { - "code": 66838 + "code": 66910 } } } diff --git a/src/BackgroundCells.js b/src/BackgroundCells.js index b87c05ac3..ab4d30186 100644 --- a/src/BackgroundCells.js +++ b/src/BackgroundCells.js @@ -39,6 +39,7 @@ class BackgroundCells extends React.Component { date: currentDate, components: { dateCellWrapper: Wrapper }, localizer, + resourceId, } = this.props let { selecting, startIdx, endIdx } = this.state let current = getNow() @@ -47,7 +48,7 @@ class BackgroundCells extends React.Component {
{range.map((date, index) => { let selected = selecting && index >= startIdx && index <= endIdx - const { className, style } = getters.dayProp(date) + const { className, style } = getters.dayProp(date, resourceId) return ( diff --git a/src/Calendar.js b/src/Calendar.js index 79b3ed55a..74a55513a 100644 --- a/src/Calendar.js +++ b/src/Calendar.js @@ -580,7 +580,7 @@ class Calendar extends React.Component { * position may break the calendar in unexpected ways. * * ```js - * (date: Date) => { className?: string, style?: Object } + * (date: Date, resourceId) => { className?: string, style?: Object } * ``` */ dayPropGetter: PropTypes.func, diff --git a/src/DayColumn.js b/src/DayColumn.js index c6cd68b89..5580bceca 100644 --- a/src/DayColumn.js +++ b/src/DayColumn.js @@ -122,7 +122,7 @@ class DayColumn extends React.Component { let selectDates = { start: startDate, end: endDate } - const { className, style } = dayProp(max) + const { className, style } = dayProp(max, resource) const DayColumnWrapperComponent = components.dayColumnWrapper || DayColumnWrapper diff --git a/src/TimeGridHeader.js b/src/TimeGridHeader.js index ef511caa6..60f0c1e5f 100644 --- a/src/TimeGridHeader.js +++ b/src/TimeGridHeader.js @@ -14,7 +14,7 @@ class TimeGridHeader extends React.Component { notify(this.props.onDrillDown, [date, view]) } - renderHeaderCells(range) { + renderHeaderCells(range, resourceId) { let { localizer, getDrilldownView, @@ -29,7 +29,7 @@ class TimeGridHeader extends React.Component { let drilldownView = getDrilldownView(date) let label = localizer.format(date, 'dayFormat') - const { className, style } = dayProp(date) + const { className, style } = dayProp(date, resourceId) let header = ( @@ -164,7 +164,7 @@ class TimeGridHeader extends React.Component { range.length <= 1 ? ' rbc-time-header-cell-single-day' : '' }`} > - {this.renderHeaderCells(range)} + {this.renderHeaderCells(range, id)}
Date: Tue, 23 Nov 2021 12:48:53 +0200 Subject: [PATCH 3/3] Remove findDOMNode from the library --- .size-snapshot.json | 24 ++++++++++++------------ src/BackgroundCells.js | 10 +++++----- src/DateContentRow.js | 10 +++++----- src/DayColumn.js | 18 +++++++++++------- src/DayColumnWrapper.js | 9 +++++++-- src/Month.js | 7 ++++--- src/TimeGrid.js | 10 +++------- src/TimeGutter.js | 5 +++-- 8 files changed, 50 insertions(+), 43 deletions(-) diff --git a/.size-snapshot.json b/.size-snapshot.json index ce5dec024..e2b141397 100644 --- a/.size-snapshot.json +++ b/.size-snapshot.json @@ -1,25 +1,25 @@ { "./dist/react-big-calendar.js": { - "bundled": 536073, - "minified": 165753, - "gzipped": 51124 + "bundled": 536336, + "minified": 165961, + "gzipped": 51120 }, "./dist/react-big-calendar.min.js": { - "bundled": 463960, - "minified": 143941, - "gzipped": 45412 + "bundled": 464134, + "minified": 144076, + "gzipped": 45392 }, "dist/react-big-calendar.esm.js": { - "bundled": 220285, - "minified": 99959, - "gzipped": 24846, + "bundled": 220577, + "minified": 100058, + "gzipped": 24882, "treeshaked": { "rollup": { - "code": 63444, - "import_statements": 1412 + "code": 63685, + "import_statements": 1372 }, "webpack": { - "code": 66910 + "code": 66874 } } } diff --git a/src/BackgroundCells.js b/src/BackgroundCells.js index ab4d30186..63638a232 100644 --- a/src/BackgroundCells.js +++ b/src/BackgroundCells.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types' import React from 'react' -import { findDOMNode } from 'react-dom' import clsx from 'clsx' import { notify } from './utils/helpers' @@ -14,6 +13,7 @@ class BackgroundCells extends React.Component { this.state = { selecting: false, } + this.ref = React.createRef() } componentDidMount() { @@ -45,7 +45,7 @@ class BackgroundCells extends React.Component { let current = getNow() return ( -
+
{range.map((date, index) => { let selected = selecting && index >= startIdx && index <= endIdx const { className, style } = getters.dayProp(date, resourceId) @@ -72,13 +72,13 @@ class BackgroundCells extends React.Component { } _selectable() { - let node = findDOMNode(this) + let node = this.ref.current let selector = (this._selector = new Selection(this.props.container, { longPressThreshold: this.props.longPressThreshold, })) let selectorClicksHandler = (point, actionType) => { - if (!isEvent(findDOMNode(this), point)) { + if (!isEvent(this.ref.current, point)) { let rowBox = getBoundsForNode(node) let { range, rtl } = this.props @@ -129,7 +129,7 @@ class BackgroundCells extends React.Component { selector.on('beforeSelect', box => { if (this.props.selectable !== 'ignoreEvents') return - return !isEvent(findDOMNode(this), box) + return !isEvent(this.ref.current, box) }) selector.on('click', point => selectorClicksHandler(point, 'click')) diff --git a/src/DateContentRow.js b/src/DateContentRow.js index d8e96887b..7fe3a5084 100644 --- a/src/DateContentRow.js +++ b/src/DateContentRow.js @@ -3,7 +3,6 @@ import getHeight from 'dom-helpers/height' import qsa from 'dom-helpers/querySelectorAll' import PropTypes from 'prop-types' import React from 'react' -import { findDOMNode } from 'react-dom' import BackgroundCells from './BackgroundCells' import EventRow from './EventRow' @@ -17,6 +16,7 @@ class DateContentRow extends React.Component { super(...args) this.slotMetrics = DateSlotMetrics.getSlotMetrics() + this.ref = React.createRef() } handleSelectSlot = slot => { @@ -28,7 +28,7 @@ class DateContentRow extends React.Component { handleShowMore = (slot, target) => { const { range, onShowMore } = this.props let metrics = this.slotMetrics(this.props) - let row = qsa(findDOMNode(this), '.rbc-row-bg')[0] + let row = qsa(this.ref.current, '.rbc-row-bg')[0] let cell if (row) cell = row.children[slot - 1] @@ -47,13 +47,13 @@ class DateContentRow extends React.Component { getContainer = () => { const { container } = this.props - return container ? container() : findDOMNode(this) + return container ? container() : this.ref.current } getRowLimit() { let eventHeight = getHeight(this.eventRow) let headingHeight = this.headingRow ? getHeight(this.headingRow) : 0 - let eventSpace = getHeight(findDOMNode(this)) - headingHeight + let eventSpace = getHeight(this.ref.current) - headingHeight return Math.max(Math.floor(eventSpace / eventHeight), 1) } @@ -152,7 +152,7 @@ class DateContentRow extends React.Component { } return ( -
+
{ - let node = findDOMNode(this) + let node = this.dayColumnRef.current const { longPressThreshold, localizer } = this.props - let selector = (this._selector = new Selection(() => findDOMNode(this), { - longPressThreshold: longPressThreshold, - })) + let selector = (this._selector = new Selection( + () => this.dayColumnRef.current, + { + longPressThreshold: longPressThreshold, + } + )) let maybeSelect = box => { let onSelecting = this.props.onSelecting @@ -310,7 +314,7 @@ class DayColumn extends React.Component { } let selectorClicksHandler = (box, actionType) => { - if (!isEvent(findDOMNode(this), box)) { + if (!isEvent(this.dayColumnRef.current, box)) { const { startDate, endDate } = selectionState(box) this._selectSlot({ startDate, @@ -328,7 +332,7 @@ class DayColumn extends React.Component { selector.on('beforeSelect', box => { if (this.props.selectable !== 'ignoreEvents') return - return !isEvent(findDOMNode(this), box) + return !isEvent(this.dayColumnRef.current, box) }) selector.on('click', box => selectorClicksHandler(box, 'click')) diff --git a/src/DayColumnWrapper.js b/src/DayColumnWrapper.js index 2d8ca9f18..15c70000e 100644 --- a/src/DayColumnWrapper.js +++ b/src/DayColumnWrapper.js @@ -1,11 +1,16 @@ import React from 'react' +import PropTypes from 'prop-types' -const DayColumnWrapper = ({ children, className, style }) => { +const DayColumnWrapper = ({ children, className, style, innerRef }) => { return ( -
+
{children}
) } +DayColumnWrapper.propTypes = { + innerRef: PropTypes.object.isRequired, +} + export default DayColumnWrapper diff --git a/src/Month.js b/src/Month.js index 87264306f..94ee30e3f 100644 --- a/src/Month.js +++ b/src/Month.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types' import React from 'react' -import { findDOMNode } from 'react-dom' import clsx from 'clsx' import chunk from 'lodash/chunk' @@ -28,6 +27,7 @@ class MonthView extends React.Component { this._bgRows = [] this._pendingSelection = [] this.slotRowRef = React.createRef() + this.ref = React.createRef() this.state = { rowLimit: 5, needLimitMeasure: true, @@ -69,7 +69,7 @@ class MonthView extends React.Component { } getContainer = () => { - return findDOMNode(this) + return this.ref.current } render() { @@ -84,6 +84,7 @@ class MonthView extends React.Component { className={clsx('rbc-month-view', className)} role="table" aria-label="Month View" + ref={this.ref} >
{this.renderHeaders(weeks[0])} @@ -290,7 +291,7 @@ class MonthView extends React.Component { this.clearSelection() if (popup) { - let position = getPosition(cell, findDOMNode(this)) + let position = getPosition(cell, this.ref.current) this.setState({ overlay: { date, events, position, target }, diff --git a/src/TimeGrid.js b/src/TimeGrid.js index b250b83b5..9dfab1515 100644 --- a/src/TimeGrid.js +++ b/src/TimeGrid.js @@ -2,7 +2,6 @@ import PropTypes from 'prop-types' import clsx from 'clsx' import * as animationFrame from 'dom-helpers/animationFrame' import React, { Component } from 'react' -import { findDOMNode } from 'react-dom' import memoize from 'memoize-one' import DayColumn from './DayColumn' @@ -23,6 +22,7 @@ export default class TimeGrid extends Component { this.scrollRef = React.createRef() this.contentRef = React.createRef() + this.gutterRef = React.createRef() this._scrollRatio = null } @@ -83,10 +83,6 @@ export default class TimeGrid extends Component { } } - gutterRef = ref => { - this.gutter = ref && findDOMNode(ref) - } - handleSelectAlldayEvent = (...args) => { //cancel any pending selections so only the event click goes through. this.clearSelection() @@ -260,7 +256,7 @@ export default class TimeGrid extends Component { > { - const width = getWidth(this.gutter) + const width = getWidth(this.gutterRef.current) if (width && this.state.gutterWidth !== width) { this.setState({ gutterWidth: width }) diff --git a/src/TimeGutter.js b/src/TimeGutter.js index 7f6757fab..156dddbad 100644 --- a/src/TimeGutter.js +++ b/src/TimeGutter.js @@ -36,10 +36,10 @@ export default class TimeGutter extends Component { } render() { - const { resource, components, getters } = this.props + const { resource, components, getters, innerRef } = this.props return ( -
+
{this.slotMetrics.groups.map((grp, idx) => { return (