Skip to content

Commit 8f02af9

Browse files
author
akaidc2
committed
display index updates to most currently modified date within range array
header click events work correctly now based upon multidate and withRange
1 parent c104d28 commit 8f02af9

File tree

5 files changed

+75
-32
lines changed

5 files changed

+75
-32
lines changed

src/Calendar/withMultipleRanges.js

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import classNames from 'classnames';
33
import {withDefaultProps} from './';
44
import {sanitizeDate, withImmutableProps} from '../utils';
55
import isBefore from 'date-fns/is_before';
6-
import enhanceHeader from '../Header/withRange';
6+
import enhanceHeader from '../Header/withMultipleRanges';
77
import format from 'date-fns/format';
88
import parse from 'date-fns/parse';
99
import styles from '../Day/Day.scss';
1010

1111
let isTouchDevice = false;
1212

13-
export const EVENT_TYPE = {
13+
export const EVENT_TYPES = {
1414
DELETE: 4,
1515
END: 3,
1616
HOVER: 2,
@@ -50,6 +50,7 @@ export const enhanceDay = withPropsOnChange(['selected'], ({date, selected, them
5050
// Enhancer to handle selecting and displaying multiple dates
5151
export const withMultipleRanges = compose(
5252
withDefaultProps,
53+
withState('displayIndex', 'setDisplayIndex', 0),
5354
withState('scrollDate', 'setScrollDate', getInitialDate),
5455
withState('displayKey', 'setDisplayKey', getInitialDate),
5556
withState('selectionStart', 'setSelectionStart', null),
@@ -62,23 +63,25 @@ export const withMultipleRanges = compose(
6263
DayComponent: enhanceDay(DayComponent),
6364
HeaderComponent: enhanceHeader(HeaderComponent),
6465
})),
65-
withProps(({displayKey, passThrough, selected, setDisplayKey, ...props}) => ({
66+
withProps(({displayKey, passThrough, selected, setDisplayKey, setDisplayIndex, displayIndex, ...props}) => ({
6667
/* eslint-disable sort-keys */
6768
passThrough: {
6869
...passThrough,
6970
Day: {
70-
onClick: (date) => handleSelect(date, {selected, ...props}),
71+
onClick: (date) => handleSelect(date, {selected, setDisplayIndex, ...props}),
7172
handlers: {
7273
onMouseOver: !isTouchDevice && props.selectionStart
7374
? (e) => handleMouseOver(e, {selected, ...props})
7475
: null,
7576
},
7677
},
7778
Years: {
78-
selected: selected && selected[displayKey],
79-
onSelect: (date) => handleYearSelect(date, {displayKey, selected, ...props}),
79+
selected: selected[displayIndex] && parse(selected[displayIndex][displayKey]),
80+
onSelect: (date, e, callback) => handleYearSelect(date, callback),
8081
},
8182
Header: {
83+
setDisplayIndex,
84+
displayIndex,
8285
onYearClick: (date, e, key) => setDisplayKey(key || 'start'),
8386
},
8487
},
@@ -98,42 +101,40 @@ function getSortedSelection({start, end}) {
98101
: {start: end, end: start};
99102
}
100103

101-
function handleSelect(date, {onSelect, selected, selectionStart, setSelectionStart, selectionStartIdx, setSelectionStartIdx}) {
104+
function handleSelect(date, {onSelect, selected, selectionStart, setSelectionStart, selectionStartIdx, setSelectionStartIdx, setDisplayIndex}) {
102105
const positionOfDate = determineIfDateAlreadySelected(date, selected);
106+
const funcs = {onSelect, setSelectionStart, setSelectionStartIdx, setDisplayIndex};
103107

104108
if(positionOfDate.value && !selectionStart) { //selecting an already defined range
105109
const selectedDate = selected[positionOfDate.index];//not clone so modding this is modding selected
106110
selectedDate.end = date; //not possible to have start/end reversed when clicking on already set range
107-
selectedDate.eventType = EVENT_TYPE.START;
108111

109-
onSelect(selected);
110-
setSelectionStart(selectedDate.start);
111-
setSelectionStartIdx(positionOfDate.index);//grab index of selected and set in state
112-
} else if (selectionStart) { //ending new date range
112+
updateSelectedState(positionOfDate.index, selectedDate.start, positionOfDate.index, selected, funcs);//grab index of selected and set in state
113+
} else if (selectionStart) { //ending date range selection
113114
if (positionOfDate.value === PositionTypes.START && !(date < selectionStart)) { //if in process and selecting start, assume they want to cancel
114-
selected[selectionStartIdx].eventType = EVENT_TYPE.DELETE
115-
onSelect(selected); //call twice to notify parent component something is about to be deleted
116-
onSelect([...selected.slice(0, positionOfDate.index), ...selected.slice(positionOfDate.index+1)]);
115+
const displayIdx = positionOfDate.index > 0 ? positionOfDate.index -1 : 0;
116+
updateSelectedState(displayIdx, null, null, [...selected.slice(0, positionOfDate.index), ...selected.slice(positionOfDate.index+1)], funcs);
117117
} else {
118118
selected[selectionStartIdx] = { //modifying passed in object without clone due to immediate set state
119-
eventType: EVENT_TYPE.END,
120119
...getSortedSelection({
121120
start: selectionStart,
122121
end: date,
123122
}),
124123
};
125-
onSelect(selected);
124+
updateSelectedState(positionOfDate.index, null, null, selected, funcs);
126125
}
127-
setSelectionStart(null);
128-
setSelectionStartIdx(null);
129126
} else { //starting new date range
130-
onSelect(selected.concat({eventType:EVENT_TYPE.START, start: date, end: date}));
131-
132-
setSelectionStart(date);
133-
setSelectionStartIdx(selected.length);//accounts for increase due to concat
127+
updateSelectedState(selected.length, date, selected.length, selected.concat({eventType:EVENT_TYPES.START, start: date, end: date}), funcs)//length accounts for increase due to concat
134128
}
135129
}
136130

131+
function updateSelectedState(displayIdx, selectStart, selectStartIdx, selected, {onSelect, setSelectionStart, setSelectionStartIdx, setDisplayIndex}) {
132+
onSelect(selected);
133+
setDisplayIndex(displayIdx);
134+
setSelectionStart(selectStart);
135+
setSelectionStartIdx(selectStartIdx);
136+
}
137+
137138
function handleMouseOver(e, {onSelect, selectionStart, selectionStartIdx, selected}) {
138139
const dateStr = e.target.getAttribute('data-date');
139140
const date = dateStr && parse(dateStr);
@@ -142,7 +143,7 @@ function handleMouseOver(e, {onSelect, selectionStart, selectionStartIdx, select
142143
if (selectionStartIdx === null) { return; }
143144

144145
selected[selectionStartIdx] = {
145-
eventType: EVENT_TYPE.HOVER,
146+
eventType: EVENT_TYPES.HOVER,
146147
...getSortedSelection({
147148
start: selectionStart,
148149
end: date,
@@ -151,12 +152,8 @@ function handleMouseOver(e, {onSelect, selectionStart, selectionStartIdx, select
151152
onSelect(selected);
152153
}
153154

154-
function handleYearSelect(date, {displayKey, onSelect, selected, setScrollDate}) {
155-
156-
setScrollDate(date);
157-
onSelect(getSortedSelection(
158-
Object.assign({}, selected, {[displayKey]: parse(date)}))
159-
);
155+
function handleYearSelect(date, callback) {
156+
callback(parse(date));
160157
}
161158

162159
function getInitialDate({selected}) { //add

src/Calendar/withRange.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const withRange = compose(
6969
onSelect: (date) => handleYearSelect(date, {displayKey, selected, ...props}),
7070
},
7171
Header: {
72-
onYearClick: (date, e, key) => setDisplayKey(key || 'start'),
72+
onYearClick: (date, e, key) => setDisplayKey( key || 'start'),
7373
},
7474
},
7575
selected: {

src/Header/defaultSelectionRenderer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default function defaultSelectionRenderer(value, {
1515
scrollToDate,
1616
setDisplay,
1717
shouldAnimate,
18+
idx,
1819
}) {
1920
const date = parse(value);
2021
const values = date && [

src/Header/withMultipleRanges.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import {withImmutableProps} from '../utils';
3+
import defaultSelectionRenderer from './defaultSelectionRenderer';
4+
import styles from './Header.scss';
5+
import Slider from './Slider';
6+
7+
export default withImmutableProps(({renderSelection}) => ({
8+
renderSelection: (values, props) => {
9+
if (!values.length || !values[0].start && !values[0].end) {
10+
return null;
11+
}
12+
13+
const dates = values.sort(function (a, b) {
14+
return a.start > b.start;
15+
});
16+
const index = props.displayIndex;
17+
18+
const dateFormat = props.locale && props.locale.headerFormat || 'MMM Do';
19+
20+
const dateElements = values.map((value, idx) => {
21+
if (value.start === value.end) {
22+
return defaultSelectionRenderer(value.start, {...props, key: value.start+idx});
23+
} else {
24+
return (
25+
<div key={value.start+idx} className={styles.range} style={{color: props.theme.headerColor}}>
26+
{defaultSelectionRenderer(value.start, {...props, dateFormat, idx, key: 'start', shouldAnimate: false})}
27+
{defaultSelectionRenderer(value.end, {...props, dateFormat, idx, key: 'end', shouldAnimate: false})}
28+
</div>
29+
);
30+
}
31+
});
32+
return (
33+
<Slider
34+
index={index !== -1 ? index : dates.length - 1}
35+
onChange={chIndex =>
36+
props.setDisplayIndex(chIndex, () =>
37+
setTimeout(() => props.scrollToDate(dates[chIndex].start, 0, true), 50)
38+
)
39+
}
40+
>
41+
{dateElements}
42+
</Slider>
43+
);
44+
},
45+
}));

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export {withDateSelection} from './Calendar/withDateSelection';
77
export {withKeyboardSupport} from './Calendar/withKeyboardSupport';
88
export {withMultipleDates, defaultMultipleDateInterpolation} from './Calendar/withMultipleDates';
99
export {withRange, EVENT_TYPE} from './Calendar/withRange';
10-
export {withMultipleRanges} from './Calendar/withMultipleRanges';
10+
export {withMultipleRanges, EVENT_TYPES} from './Calendar/withMultipleRanges';
1111

1212
/*
1313
* By default, Calendar is a controlled component.

0 commit comments

Comments
 (0)