Skip to content

Commit 055cdd0

Browse files
authored
fix: correct TimeGutter ref (#2204)
Corrects issue with TimeGutter ref in TimeGrid views #2201
1 parent 779060a commit 055cdd0

File tree

2 files changed

+60
-61
lines changed

2 files changed

+60
-61
lines changed

src/TimeGrid.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ export default class TimeGrid extends Component {
283283
}
284284
this.measureGutterAnimationFrameRequest = window.requestAnimationFrame(
285285
() => {
286-
const width = getWidth(this.gutter)
286+
const width = getWidth(this.gutterRef?.current)
287287

288288
if (width && this.state.gutterWidth !== width) {
289289
this.setState({ gutterWidth: width })

src/TimeGutter.js

Lines changed: 59 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,77 @@
1+
import React, { useState, useEffect } from 'react'
12
import clsx from 'clsx'
23
import PropTypes from 'prop-types'
3-
import React, { Component } from 'react'
44

55
import * as TimeSlotUtils from './utils/TimeSlots'
66
import TimeSlotGroup from './TimeSlotGroup'
77

8-
/**
9-
* Since the TimeGutter only displays the 'times' of slots in a day, and is separate
10-
* from the Day Columns themselves, we check to see if the range contains an offset difference
11-
* and, if so, change the beginning and end 'date' by a day to properly display the slots times
12-
* used.
13-
*/
14-
function adjustForDST({ min, max, localizer }) {
15-
if (localizer.getTimezoneOffset(min) !== localizer.getTimezoneOffset(max)) {
16-
return {
17-
start: localizer.add(min, -1, 'day'),
18-
end: localizer.add(max, -1, 'day'),
19-
}
20-
}
21-
return { start: min, end: max }
22-
}
23-
24-
export default class TimeGutter extends Component {
25-
constructor(...args) {
26-
super(...args)
27-
28-
const { min, max, timeslots, step, localizer } = this.props
29-
const { start, end } = adjustForDST({ min, max, localizer })
30-
this.slotMetrics = TimeSlotUtils.getSlotMetrics({
31-
min: start,
32-
max: end,
8+
const TimeGutter = ({
9+
min,
10+
max,
11+
timeslots,
12+
step,
13+
localizer,
14+
getNow,
15+
resource,
16+
components,
17+
getters,
18+
gutterRef,
19+
}) => {
20+
const [slotMetrics, setSlotMetrics] = useState(
21+
TimeSlotUtils.getSlotMetrics({
22+
min,
23+
max,
3324
timeslots,
3425
step,
3526
localizer,
3627
})
37-
}
28+
)
3829

39-
UNSAFE_componentWillReceiveProps(nextProps) {
40-
const { min, max, localizer } = nextProps
41-
const { start, end } = adjustForDST({ min, max, localizer })
42-
this.slotMetrics = this.slotMetrics.update({
43-
...nextProps,
44-
min: start,
45-
max: end,
46-
})
47-
}
30+
useEffect(() => {
31+
if (slotMetrics) {
32+
setSlotMetrics(
33+
slotMetrics.update({
34+
min,
35+
max,
36+
timeslots,
37+
step,
38+
localizer,
39+
})
40+
)
41+
}
42+
/**
43+
* We don't want this to fire when slotMetrics is updated as it would recursively bomb
44+
*/
45+
// eslint-disable-next-line react-hooks/exhaustive-deps
46+
}, [min, max, timeslots, step])
4847

49-
renderSlot = (value, idx) => {
50-
if (idx !== 0) return null
51-
const { localizer, getNow } = this.props
48+
const renderSlot = (value, idx) => {
49+
if (idx) return null // don't return the first (0) idx
5250

53-
const isNow = this.slotMetrics.dateIsInGroup(getNow(), idx)
51+
const isNow = slotMetrics.dateIsInGroup(getNow(), idx)
5452
return (
5553
<span className={clsx('rbc-label', isNow && 'rbc-now')}>
5654
{localizer.format(value, 'timeGutterFormat')}
5755
</span>
5856
)
5957
}
6058

61-
render() {
62-
const { resource, components, getters } = this.props
63-
64-
return (
65-
<div className="rbc-time-gutter rbc-time-column">
66-
{this.slotMetrics.groups.map((grp, idx) => {
67-
return (
68-
<TimeSlotGroup
69-
key={idx}
70-
group={grp}
71-
resource={resource}
72-
components={components}
73-
renderSlot={this.renderSlot}
74-
getters={getters}
75-
/>
76-
)
77-
})}
78-
</div>
79-
)
80-
}
59+
return (
60+
<div className="rbc-time-gutter rbc-time-column" ref={gutterRef}>
61+
{slotMetrics.groups.map((grp, idx) => {
62+
return (
63+
<TimeSlotGroup
64+
key={idx}
65+
group={grp}
66+
resource={resource}
67+
components={components}
68+
renderSlot={renderSlot}
69+
getters={getters}
70+
/>
71+
)
72+
})}
73+
</div>
74+
)
8175
}
8276

8377
TimeGutter.propTypes = {
@@ -91,4 +85,9 @@ TimeGutter.propTypes = {
9185

9286
localizer: PropTypes.object.isRequired,
9387
resource: PropTypes.string,
88+
gutterRef: PropTypes.any,
9489
}
90+
91+
export default React.forwardRef((props, ref) => (
92+
<TimeGutter gutterRef={ref} {...props} />
93+
))

0 commit comments

Comments
 (0)