Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recalculate "more" with ResizeObserver #2573

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 7 additions & 35 deletions src/DateContentRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class DateContentRow extends React.Component {

this.containerRef = createRef()
this.headingRowRef = createRef()
this.eventRowRef = createRef()
this.rowContentRef = createRef()

this.slotMetrics = DateSlotMetrics.getSlotMetrics()
}
Expand Down Expand Up @@ -47,12 +47,14 @@ class DateContentRow extends React.Component {

getRowLimit() {
/* Guessing this only gets called on the dummyRow */
const eventHeight = getHeight(this.eventRowRef.current)
const { renderHeader } = this.props
const eventRow = this.rowContentRef.current?.children[renderHeader ? 1 : 0]
if (!eventRow) return undefined
const eventHeight = getHeight(eventRow)
const headingHeight = this.headingRowRef?.current
? getHeight(this.headingRowRef.current)
: 0
const eventSpace = getHeight(this.containerRef.current) - headingHeight

const eventSpace = getHeight(this.containerRef.current) - headingHeight
return Math.max(Math.floor(eventSpace / eventHeight), 1)
}

Expand All @@ -69,33 +71,6 @@ class DateContentRow extends React.Component {
})
}

renderDummy = () => {
let { className, range, renderHeader, showAllEvents } = this.props
return (
<div className={className} ref={this.containerRef}>
<div
className={clsx(
'rbc-row-content',
showAllEvents && 'rbc-row-content-scrollable'
)}
>
{renderHeader && (
<div className="rbc-row" ref={this.headingRowRef}>
{range.map(this.renderHeadingCell)}
</div>
)}
<div className="rbc-row" ref={this.eventRowRef}>
<div className="rbc-row-segment">
<div className="rbc-event">
<div className="rbc-event-content">&nbsp;</div>
</div>
</div>
</div>
</div>
</div>
)
}

render() {
const {
date,
Expand All @@ -104,7 +79,6 @@ class DateContentRow extends React.Component {
className,
selected,
selectable,
renderForMeasure,

accessors,
getters,
Expand All @@ -125,8 +99,6 @@ class DateContentRow extends React.Component {
showAllEvents,
} = this.props

if (renderForMeasure) return this.renderDummy()

let metrics = this.slotMetrics(this.props)
let { levels, extra } = metrics

Expand Down Expand Up @@ -174,6 +146,7 @@ class DateContentRow extends React.Component {
showAllEvents && 'rbc-row-content-scrollable'
)}
role="row"
ref={this.rowContentRef}
>
{renderHeader && (
<div className="rbc-row " ref={this.headingRowRef}>
Expand Down Expand Up @@ -208,7 +181,6 @@ DateContentRow.propTypes = {
rtl: PropTypes.bool,
resizable: PropTypes.bool,
resourceId: PropTypes.any,
renderForMeasure: PropTypes.bool,
renderHeader: PropTypes.func,

container: PropTypes.func,
Expand Down
87 changes: 52 additions & 35 deletions src/Month.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import chunk from 'lodash/chunk'
import { navigate, views } from './utils/constants'
import { notify } from './utils/helpers'
import getPosition from 'dom-helpers/position'
import * as animationFrame from 'dom-helpers/animationFrame'

/* import Popup from './Popup'
import Overlay from 'react-overlays/Overlay' */
Expand All @@ -27,48 +26,50 @@ class MonthView extends React.Component {

this.state = {
rowLimit: 5,
needLimitMeasure: true,
date: null,
}
this.containerRef = createRef()
this.slotRowRef = createRef()
this.slotRowRefs = []

this._bgRows = []
this._pendingSelection = []
}

static getDerivedStateFromProps({ date, localizer }, state) {
return {
date,
needLimitMeasure: localizer.neq(date, state.date, 'month'),
}
}

componentDidMount() {
let running

if (this.state.needLimitMeasure) this.measureRowLimit(this.props)

window.addEventListener(
'resize',
(this._resizeListener = () => {
if (!running) {
animationFrame.request(() => {
running = false
this.setState({ needLimitMeasure: true }) //eslint-disable-line
})
this._sizeObserver = new ResizeObserver(
(entries) => {
const lastHeight = this._lastHeight
for (let entry of entries) {
const curHeight = Math.round(entry.contentRect.height);
if (lastHeight !== curHeight) {
this._lastHeight = curHeight
this.measureRowLimit()
}
}
}),
false
}
)
if (!this.props.showAllEvents) {
this._sizeObserver.observe(this.containerRef.current)
}
}

componentDidUpdate() {
if (this.state.needLimitMeasure) this.measureRowLimit(this.props)
componentDidUpdate(prevProps) {
const { localizer, date, showAllEvents } = this.props

// measure on month change
if (!showAllEvents && localizer.neq(date, prevProps.date, 'month')) {
this.measureRowLimit()
}

// toggle observer
if (!prevProps.showAllEvents && this.props.showAllEvents) {
this._sizeObserver.unobserve(this.containerRef.current)
} else if (prevProps.showAllEvents && !this.props.showAllEvents) {
this._sizeObserver.observe(this.containerRef.current)
}
}

componentWillUnmount() {
window.removeEventListener('resize', this._resizeListener, false)
this._sizeObserver.disconnect()
}

getContainer = () => {
Expand Down Expand Up @@ -98,6 +99,10 @@ class MonthView extends React.Component {
)
}

saveWeekRef = (ref) => {
this.slotRowRefs.push(ref)
}

renderWeek = (week, weekIdx) => {
let {
events,
Expand All @@ -113,7 +118,7 @@ class MonthView extends React.Component {
showAllEvents,
} = this.props

const { needLimitMeasure, rowLimit } = this.state
const { rowLimit } = this.state

// let's not mutate props
const weeksEvents = eventsForWeek(
Expand All @@ -129,7 +134,7 @@ class MonthView extends React.Component {
return (
<DateContentRow
key={weekIdx}
ref={weekIdx === 0 ? this.slotRowRef : undefined}
ref={this.saveWeekRef}
container={this.getContainer}
className="rbc-month-row"
getNow={getNow}
Expand All @@ -144,7 +149,6 @@ class MonthView extends React.Component {
getters={getters}
localizer={localizer}
renderHeader={this.readerDateHeading}
renderForMeasure={needLimitMeasure}
onShowMore={this.handleShowMore}
onSelect={this.handleSelectEvent}
onDoubleClick={this.handleDoubleClickEvent}
Expand Down Expand Up @@ -271,10 +275,23 @@ class MonthView extends React.Component {
}

measureRowLimit() {
this.setState({
needLimitMeasure: false,
rowLimit: this.slotRowRef.current.getRowLimit(),
})
// find first week ref with an event
for (let i = 0; i < this.slotRowRefs.length; i++) {
const rowLimit = this.slotRowRefs[i]?.getRowLimit()
if (rowLimit === undefined) continue
if (rowLimit !== this.state.rowLimit) {
this.setState({
rowLimit,
})
}
return
}
// no events found, reset rowLimit to default 5
if (this.state.rowLimit !== 5) {
this.setState({
rowLimit: 5
})
}
}

handleSelectSlot = (range, slotInfo) => {
Expand Down