Skip to content

Commit

Permalink
Merge pull request #1192 from airbnb/maja-calc-height-based-on-weeks-…
Browse files Browse the repository at this point in the history
…instead-of-DOM

Change month height calculation to be based on number of weeks instead of DOM calculations
  • Loading branch information
majapw authored Jun 5, 2018
2 parents 2e13fdc + 0bd08cb commit ef42df2
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 87 deletions.
31 changes: 13 additions & 18 deletions src/components/CalendarMonth.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const propTypes = forbidExtraProps({
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,
firstDayOfWeek: DayOfWeekShape,
setMonthHeight: PropTypes.func,
setMonthTitleHeight: PropTypes.func,
verticalBorderSpacing: nonNegativeInteger,

focusedDate: momentPropTypes.momentObj, // indicates focusable day
Expand All @@ -70,7 +70,7 @@ const defaultProps = {
renderCalendarDay: props => (<CalendarDay {...props} />),
renderDayContents: null,
firstDayOfWeek: null,
setMonthHeight() {},
setMonthTitleHeight: null,

focusedDate: null,
isFocused: false,
Expand All @@ -95,12 +95,11 @@ class CalendarMonth extends React.Component {
};

this.setCaptionRef = this.setCaptionRef.bind(this);
this.setGridRef = this.setGridRef.bind(this);
this.setMonthHeight = this.setMonthHeight.bind(this);
this.setMonthTitleHeight = this.setMonthTitleHeight.bind(this);
}

componentDidMount() {
this.setMonthHeightTimeout = setTimeout(this.setMonthHeight, 0);
this.setMonthTitleHeightTimeout = setTimeout(this.setMonthTitleHeight, 0);
}

componentWillReceiveProps(nextProps) {
Expand All @@ -123,27 +122,23 @@ class CalendarMonth extends React.Component {
}

componentWillUnmount() {
if (this.setMonthHeightTimeout) {
clearTimeout(this.setMonthHeightTimeout);
if (this.setMonthTitleHeightTimeout) {
clearTimeout(this.setMonthTitleHeightTimeout);
}
}

setMonthHeight() {
const { setMonthHeight } = this.props;
const captionHeight = calculateDimension(this.captionRef, 'height', true, true);
const gridHeight = calculateDimension(this.gridRef, 'height');

setMonthHeight(captionHeight + gridHeight + 1);
setMonthTitleHeight() {
const { setMonthTitleHeight } = this.props;
if (setMonthTitleHeight) {
const captionHeight = calculateDimension(this.captionRef, 'height', true, true);
setMonthTitleHeight(captionHeight);
}
}

setCaptionRef(ref) {
this.captionRef = ref;
}

setGridRef(ref) {
this.gridRef = ref;
}

render() {
const {
month,
Expand Down Expand Up @@ -199,7 +194,7 @@ class CalendarMonth extends React.Component {
)}
role="presentation"
>
<tbody ref={this.setGridRef}>
<tbody>
{weeks.map((week, i) => (
<CalendarWeek key={i}>
{week.map((day, dayOfWeek) => renderCalendarDay({
Expand Down
49 changes: 12 additions & 37 deletions src/components/CalendarMonthGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ const propTypes = forbidExtraProps({
renderMonth: PropTypes.func,
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,
transformValue: PropTypes.string,
translationValue: PropTypes.number,
daySize: nonNegativeInteger,
focusedDate: momentPropTypes.momentObj, // indicates focusable day
isFocused: PropTypes.bool, // indicates whether or not to move focus to focusable day
firstDayOfWeek: DayOfWeekShape,
setCalendarMonthHeights: PropTypes.func,
setMonthTitleHeight: PropTypes.func,
isRTL: PropTypes.bool,
transitionDuration: nonNegativeInteger,
verticalBorderSpacing: nonNegativeInteger,
Expand All @@ -75,12 +75,12 @@ const defaultProps = {
renderMonth: null,
renderCalendarDay: undefined,
renderDayContents: null,
transformValue: 'none',
translationValue: null,
daySize: DAY_SIZE,
focusedDate: null,
isFocused: false,
firstDayOfWeek: null,
setCalendarMonthHeights() {},
setMonthTitleHeight: null,
isRTL: false,
transitionDuration: 200,
verticalBorderSpacing: undefined,
Expand Down Expand Up @@ -112,8 +112,6 @@ class CalendarMonthGrid extends React.Component {
months: getMonths(props.initialMonth, props.numberOfMonths, withoutTransitionMonths),
};

this.calendarMonthHeights = [];

this.isTransitionEndSupported = isTransitionEndSupported();
this.onTransitionEnd = this.onTransitionEnd.bind(this);
this.setContainerRef = this.setContainerRef.bind(this);
Expand All @@ -122,16 +120,11 @@ class CalendarMonthGrid extends React.Component {
}

componentDidMount() {
const { setCalendarMonthHeights } = this.props;
this.removeEventListener = addEventListener(
this.container,
'transitionend',
this.onTransitionEnd,
);

this.setCalendarMonthHeightsTimeout = setTimeout(() => {
setCalendarMonthHeights(this.calendarMonthHeights);
}, 0);
}

componentWillReceiveProps(nextProps) {
Expand Down Expand Up @@ -172,12 +165,11 @@ class CalendarMonthGrid extends React.Component {
return shallowCompare(this, nextProps, nextState);
}

componentDidUpdate(prevProps) {
componentDidUpdate() {
const {
isAnimating,
transitionDuration,
onMonthTransitionEnd,
setCalendarMonthHeights,
} = this.props;

// For IE9, immediately call onMonthTransitionEnd instead of
Expand All @@ -186,19 +178,10 @@ class CalendarMonthGrid extends React.Component {
if ((!this.isTransitionEndSupported || !transitionDuration) && isAnimating) {
onMonthTransitionEnd();
}

if (!isAnimating && prevProps.isAnimating) {
this.setCalendarMonthHeightsTimeout = setTimeout(() => {
setCalendarMonthHeights(this.calendarMonthHeights);
}, 0);
}
}

componentWillUnmount() {
if (this.removeEventListener) this.removeEventListener();
if (this.setCalendarMonthHeightsTimeout) {
clearTimeout(this.setCalendarMonthHeightsTimeout);
}
}

onTransitionEnd() {
Expand All @@ -210,18 +193,6 @@ class CalendarMonthGrid extends React.Component {
this.container = ref;
}

setMonthHeight(height, i) {
if (this.calendarMonthHeights[i]) {
if (i === 0) {
this.calendarMonthHeights = [height].concat(this.calendarMonthHeights.slice(0, -1));
} else if (i === this.calendarMonthHeights.length - 1) {
this.calendarMonthHeights = this.calendarMonthHeights.slice(1).concat(height);
}
} else {
this.calendarMonthHeights[i] = height;
}
}

render() {
const {
enableOutsideDays,
Expand All @@ -231,7 +202,7 @@ class CalendarMonthGrid extends React.Component {
numberOfMonths,
monthFormat,
orientation,
transformValue,
translationValue,
daySize,
onDayMouseEnter,
onDayMouseLeave,
Expand All @@ -249,6 +220,7 @@ class CalendarMonthGrid extends React.Component {
dayAriaLabelFormat,
transitionDuration,
verticalBorderSpacing,
setMonthTitleHeight,
} = this.props;

const { months } = this.state;
Expand All @@ -262,6 +234,9 @@ class CalendarMonthGrid extends React.Component {
calendarMonthWidth :
(numberOfMonths + 2) * calendarMonthWidth;

const transformType = (isVertical || isVerticalScrollable) ? 'translateY' : 'translateX';
const transformValue = `${transformType}(${translationValue}px)`;

return (
<div
{...css(
Expand Down Expand Up @@ -303,7 +278,7 @@ class CalendarMonthGrid extends React.Component {
},
showForAnimation && isVertical && {
position: 'absolute',
top: -this.calendarMonthHeights[0],
top: -translationValue,
},
!isVisible && !isAnimating && styles.CalendarMonthGrid_month__hidden,
)}
Expand All @@ -326,7 +301,7 @@ class CalendarMonthGrid extends React.Component {
focusedDate={isVisible ? focusedDate : null}
isFocused={isFocused}
phrases={phrases}
setMonthHeight={(height) => { this.setMonthHeight(height, i); }}
setMonthTitleHeight={setMonthTitleHeight}
dayAriaLabelFormat={dayAriaLabelFormat}
verticalBorderSpacing={verticalBorderSpacing}
/>
Expand Down
Loading

0 comments on commit ef42df2

Please sign in to comment.