Skip to content
This repository was archived by the owner on May 19, 2025. It is now read-only.

Commit 5605173

Browse files
committed
re add classNames feature and fix some bugs
1 parent e3a0693 commit 5605173

File tree

7 files changed

+110
-69
lines changed

7 files changed

+110
-69
lines changed

src/Calendar.js

Lines changed: 68 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React, { PureComponent } from 'react';
22
import PropTypes from 'prop-types';
33
import DayCell, { rangeShape } from './DayCell.js';
4-
import { calcFocusDate } from './utils';
5-
import styles from './styles';
4+
import { calcFocusDate, generateStyles } from './utils';
65
import classnames from 'classnames';
76
import { addMonths, startOfDay, endOfDay, addYears, setYear, setMonth } from 'date-fns';
87
import defaultLocale from 'date-fns/locale/en-US';
8+
import coreStyles from './styles';
99

1010
import {
1111
format,
@@ -27,9 +27,11 @@ class Calendar extends PureComponent {
2727
this.changeShownDate = this.changeShownDate.bind(this);
2828
this.renderDays = this.renderDays.bind(this);
2929
this.handleRangeFocusChange = this.handleRangeFocusChange.bind(this);
30+
this.renderDateDisplay = this.renderDateDisplay.bind(this);
3031
this.state = {
3132
focusedDate: calcFocusDate(null, props),
3233
};
34+
this.styles = generateStyles([coreStyles, props.classNames]);
3335
}
3436
updateShownDate(props) {
3537
const newFocus = calcFocusDate(this.state.focusedDate, props || this.props);
@@ -61,23 +63,23 @@ class Calendar extends PureComponent {
6163
handleRangeFocusChange(rangesIndex, rangeItemIndex) {
6264
this.props.onRangeFocusChange && this.props.onRangeFocusChange([rangesIndex, rangeItemIndex]);
6365
}
64-
renderMonthAndYear(classes, focusedDate) {
66+
renderMonthAndYear(focusedDate) {
6567
const { showMonthArrow, locale, minDate, maxDate } = this.props;
6668
const upLimit = maxDate ? maxDate.getFullYear() : addYears(new Date(), 20).getFullYear();
6769
const downLimit = minDate ? minDate.getFullYear() : addYears(new Date(), -100).getFullYear();
68-
70+
const styles = this.styles;
6971
return (
70-
<div className={classes.monthAndYearWrapper}>
72+
<div className={styles.monthAndYearWrapper}>
7173
{showMonthArrow ? (
7274
<button
7375
type="button"
74-
className={classnames(classes.nextPrevButton, classes.prevButton)}
76+
className={classnames(styles.nextPrevButton, styles.prevButton)}
7577
onClick={() => this.changeShownDate('monthOffset', -1)}>
7678
<i />
7779
</button>
7880
) : null}
79-
<span className={classes.monthAndYearPickers}>
80-
<span className={classes.monthPicker}>
81+
<span className={styles.monthAndYearPickers}>
82+
<span className={styles.monthPicker}>
8183
<select
8284
value={focusedDate.getMonth()}
8385
onChange={e => this.changeShownDate('setMonth', e.target.value)}>
@@ -88,8 +90,8 @@ class Calendar extends PureComponent {
8890
))}
8991
</select>
9092
</span>
91-
<span className={classes.monthAndYearDivider} />
92-
<span className={classes.yearPicker}>
93+
<span className={styles.monthAndYearDivider} />
94+
<span className={styles.yearPicker}>
9395
<select
9496
value={focusedDate.getFullYear()}
9597
onChange={e => this.changeShownDate('setYear', e.target.value)}>
@@ -107,27 +109,64 @@ class Calendar extends PureComponent {
107109
{showMonthArrow ? (
108110
<button
109111
type="button"
110-
className={classnames(classes.nextPrevButton, classes.nextButton)}
112+
className={classnames(styles.nextPrevButton, styles.nextButton)}
111113
onClick={() => this.changeShownDate('monthOffset', +1)}>
112114
<i />
113115
</button>
114116
) : null}
115117
</div>
116118
);
117119
}
118-
renderWeekdays(classes, dateOptions) {
120+
renderWeekdays(dateOptions) {
119121
const now = new Date();
120122
return eachDayOfInterval({
121123
start: startOfWeek(now, dateOptions),
122124
end: endOfWeek(now, dateOptions),
123125
}).map((day, i) => (
124-
<span className={classes.weekDay} key={i}>
126+
<span className={this.styles.weekDay} key={i}>
125127
{format(day, 'ddd', dateOptions)}
126128
</span>
127129
));
128130
}
129-
130-
renderDays(classes, dateOptions, focusedDate) {
131+
renderDateDisplay(dateOptions) {
132+
const { focusedRange, color, ranges } = this.props;
133+
const styles = this.styles;
134+
return (
135+
<div className={styles.dateDisplayWrapper}>
136+
{ranges.map((range, i) => {
137+
if (range.showDateDisplay === false || (range.disabled && !range.showDateDisplay))
138+
return null;
139+
return (
140+
<div className={styles.dateDisplay} key={i} style={{ color: range.color || color }}>
141+
<span
142+
className={classnames(styles.dateDisplayItem, {
143+
[styles.dateDisplayItemActive]: focusedRange[0] === i && focusedRange[1] === 0,
144+
})}
145+
onFocus={() => this.handleRangeFocusChange(i, 0)}>
146+
<input
147+
disabled={range.disabled}
148+
readOnly
149+
value={this.formatDateDisplay(range.startDate, dateOptions, '-')}
150+
/>
151+
</span>
152+
<span
153+
className={classnames(styles.dateDisplayItem, {
154+
[styles.dateDisplayItemActive]: focusedRange[0] === i && focusedRange[1] === 1,
155+
})}
156+
onFocus={() => this.handleRangeFocusChange(i, 1)}>
157+
<input
158+
disabled={range.disabled}
159+
readOnly
160+
value={this.formatDateDisplay(range.endDate, dateOptions, 'Continuous')}
161+
/>
162+
</span>
163+
</div>
164+
);
165+
})}
166+
</div>
167+
);
168+
}
169+
renderDays(dateOptions, focusedDate) {
131170
const now = new Date();
132171
const { specialDays } = this.props;
133172
const minDate = this.props.minDate && startOfDay(this.props.minDate);
@@ -161,61 +200,34 @@ class Calendar extends PureComponent {
161200
key={index}
162201
disabled={isOutsideMinMax}
163202
isPassive={!isWithinInterval(day, { start: startDateOfMonth, end: endDateOfMonth })}
164-
classNames={classes}
203+
styles={this.styles}
165204
/>
166205
);
167206
}
168207
);
169208
}
170209

171-
formatDateDisplay(date, defaultText) {
210+
formatDateDisplay(date, dateOptions, defaultText) {
172211
if (!date) return defaultText;
173-
return format(date, this.props.dateDisplayFormat);
212+
return format(date, this.props.dateDisplayFormat, dateOptions);
174213
}
175214
render() {
215+
const { showDateDisplay } = this.props;
176216
const dateOptions = { locale: this.props.locale };
177-
const { focusedRange, color } = this.props;
178217
return (
179-
<div className={classnames(styles.calendarWrapper, this.props.className)}>
180-
<div className={styles.dateDisplayWrapper}>
181-
{this.props.ranges.map((range, i) => (
182-
<div className={styles.dateDisplay} key={i} style={{ color: range.color || color }}>
183-
<span
184-
className={classnames(styles.dateDisplayItem, {
185-
[styles.dateDisplayItemActive]: focusedRange[0] === i && focusedRange[1] === 0,
186-
})}
187-
onFocus={() => this.handleRangeFocusChange(i, 0)}>
188-
<input
189-
disabled={range.disabled}
190-
readOnly
191-
value={this.formatDateDisplay(range.startDate, '-')}
192-
/>
193-
</span>
194-
<span
195-
className={classnames(styles.dateDisplayItem, {
196-
[styles.dateDisplayItemActive]: focusedRange[0] === i && focusedRange[1] === 1,
197-
})}
198-
onFocus={() => this.handleRangeFocusChange(i, 1)}>
199-
<input
200-
disabled={range.disabled}
201-
readOnly
202-
value={this.formatDateDisplay(range.endDate, 'Continuous')}
203-
/>
204-
</span>
205-
</div>
206-
))}
207-
</div>
208-
{this.renderMonthAndYear(styles, this.state.focusedDate)}
218+
<div className={classnames(this.styles.calendarWrapper, this.props.className)}>
219+
{showDateDisplay && this.renderDateDisplay(dateOptions)}
220+
{this.renderMonthAndYear(this.state.focusedDate)}
209221
<div
210-
className={styles.months}
222+
className={this.styles.months}
211223
onMouseLeave={() => {
212224
this.props.onPreviewChange && this.props.onPreviewChange();
213225
}}>
214226
{new Array(this.props.months).fill(null).map((_, i) => (
215-
<div key={i} className={styles.month}>
216-
<div className={styles.weekDays}>{this.renderWeekdays(styles, dateOptions)}</div>
217-
<div className={styles.days}>
218-
{this.renderDays(styles, dateOptions, addMonths(this.state.focusedDate, i))}
227+
<div key={i} className={this.styles.month}>
228+
<div className={this.styles.weekDays}>{this.renderWeekdays(dateOptions)}</div>
229+
<div className={this.styles.days}>
230+
{this.renderDays(dateOptions, addMonths(this.state.focusedDate, i))}
219231
</div>
220232
</div>
221233
))}
@@ -233,6 +245,7 @@ Calendar.defaultProps = {
233245
ranges: [],
234246
focusedRange: [0, 0],
235247
dateDisplayFormat: 'MMM D,YYYY',
248+
showDateDisplay: true,
236249
showSelectionPreview: true,
237250
displayMode: 'date',
238251
months: 1,
@@ -261,6 +274,7 @@ Calendar.propTypes = {
261274
focusedRange: PropTypes.arrayOf(PropTypes.number),
262275
months: PropTypes.number,
263276
className: PropTypes.string,
277+
showDateDisplay: PropTypes.bool,
264278
showSelectionPreview: PropTypes.bool,
265279
displayMode: PropTypes.oneOf(['dateRange', 'date']),
266280
color: PropTypes.string,

src/DateRange.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
33
import Calendar from './Calendar.js';
4-
import { findNextRangeIndex } from './utils.js';
5-
import styles from './styles';
4+
import { findNextRangeIndex, generateStyles } from './utils.js';
65
import { isBefore, differenceInCalendarDays, addDays, min } from 'date-fns';
76
import classnames from 'classnames';
7+
import coreStyles from './styles';
88

99
class DateRange extends Component {
1010
constructor(props, context) {
@@ -17,13 +17,14 @@ class DateRange extends Component {
1717
focusedRange: [findNextRangeIndex(props.ranges), 0],
1818
preview: null,
1919
};
20+
this.styles = generateStyles([coreStyles, props.classNames]);
2021
}
2122
calcNewSelection(value) {
2223
const { focusedRange } = this.state;
2324
const { ranges, onChange, maxDate, moveRangeOnFirstSelection } = this.props;
2425
const selectedRangeIndex = focusedRange[0];
2526
const selectedRange = ranges[selectedRangeIndex];
26-
if (!selectedRange || !onChange) return;
27+
if (!selectedRange || !onChange) return {};
2728

2829
let { startDate, endDate } = selectedRange;
2930
if (!endDate) endDate = new Date(startDate);
@@ -54,14 +55,14 @@ class DateRange extends Component {
5455
const { focusedRange } = this.state;
5556
const selectedRangeIndex = focusedRange[0];
5657
const selectedRange = ranges[selectedRangeIndex];
57-
5858
const newSelection = this.calcNewSelection(value);
59+
if (!selectedRange) return;
5960
onChange({
6061
[selectedRange.key || `range${selectedRangeIndex + 1}`]: newSelection.range,
6162
});
6263
this.setState({
6364
focusedRange: newSelection.nextFocusRange,
64-
preview: newSelection.range,
65+
preview: null,
6566
});
6667
}
6768
handleRangeFocusChange(focusedRange) {
@@ -72,16 +73,17 @@ class DateRange extends Component {
7273
this.setState({ preview: val });
7374
}
7475
render() {
76+
const selectedRange = this.props.ranges[this.state.focusedRange[0]] || {};
7577
return (
7678
<Calendar
7779
{...this.props}
7880
displayMode="dateRange"
79-
className={classnames(styles.dateRangeWrapper, this.props.className)}
81+
className={classnames(this.styles.dateRangeWrapper, this.props.className)}
8082
onChange={this.setSelection}
8183
focusedRange={this.state.focusedRange}
8284
onRangeFocusChange={this.handleRangeFocusChange}
8385
preview={this.state.preview}
84-
previewColor={this.props.ranges[this.state.focusedRange[0]].color}
86+
previewColor={selectedRange.color}
8587
onPreviewChange={value => {
8688
this.updatePreview(value ? this.calcNewSelection(value).range : null);
8789
}}

src/DateRangePicker.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
33
import DateRange from './DateRange';
44
import DefinedRanges from './DefinedRanges';
5-
import { findNextRangeIndex } from './utils.js';
5+
import { findNextRangeIndex, generateStyles } from './utils.js';
66
import classnames from 'classnames';
7-
import styles from './styles';
7+
import coreStyles from './styles';
88

99
class DateRangePicker extends Component {
1010
constructor(props) {
@@ -13,6 +13,7 @@ class DateRangePicker extends Component {
1313
this.state = {
1414
focusedRange: [findNextRangeIndex(props.ranges), 0],
1515
};
16+
this.styles = generateStyles([coreStyles, props.classNames]);
1617
}
1718
handleChange(range) {
1819
const { focusedRange } = this.state;
@@ -27,21 +28,23 @@ class DateRangePicker extends Component {
2728
render() {
2829
const focusedRangeIndex = this.state.focusedRange[0];
2930
return (
30-
<div className={classnames(styles.dateRangePickerWrapper, this.props.className)}>
31+
<div className={classnames(this.styles.dateRangePickerWrapper, this.props.className)}>
3132
<DefinedRanges
3233
{...this.props}
3334
range={this.props.ranges[focusedRangeIndex] || {}}
3435
onChange={this.handleChange}
3536
onPreviewChange={value => {
3637
this.dateRange.updatePreview(value);
3738
}}
39+
className={undefined}
3840
/>
3941
<DateRange
4042
{...this.props}
4143
ref={t => {
4244
this.dateRange = t;
4345
}}
4446
onRangeFocusChange={focusedRange => this.setState({ focusedRange })}
47+
className={undefined}
4548
/>
4649
</div>
4750
);

src/DayCell.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
33
import classnames from 'classnames';
4-
import styles from './styles';
54
import { startOfDay, format, isSameDay, isAfter, isBefore, endOfDay } from 'date-fns';
65

76
class DayCell extends Component {
@@ -64,6 +63,7 @@ class DayCell extends Component {
6463
isStartOfMonth,
6564
isEndOfMonth,
6665
disabled,
66+
styles,
6767
} = this.props;
6868

6969
return classnames(styles.day, {
@@ -81,7 +81,7 @@ class DayCell extends Component {
8181
});
8282
}
8383
renderPreviewPlaceholder() {
84-
const { preview, day, previewColor, color } = this.props;
84+
const { preview, day, previewColor, color, styles } = this.props;
8585
if (!preview) return null;
8686
const startDate = preview.startDate ? endOfDay(preview.startDate) : null;
8787
const endDate = preview.endDate ? startOfDay(preview.endDate) : null;
@@ -101,6 +101,7 @@ class DayCell extends Component {
101101
);
102102
}
103103
renderSelectionPlaceholders() {
104+
const { styles } = this.props;
104105
if (this.props.displayMode === 'date') {
105106
let isSelected = isSameDay(this.props.day, this.props.date);
106107
return isSelected ? (
@@ -143,6 +144,7 @@ class DayCell extends Component {
143144
));
144145
}
145146
render() {
147+
const { styles } = this.props;
146148
return (
147149
<button
148150
onClick={this.handleMouseEvent}
@@ -179,6 +181,7 @@ export const rangeShape = PropTypes.shape({
179181
key: PropTypes.string,
180182
autoFocus: PropTypes.bool,
181183
disabled: PropTypes.bool,
184+
showDateDisplay: PropTypes.bool,
182185
});
183186

184187
DayCell.propTypes = {
@@ -204,6 +207,7 @@ DayCell.propTypes = {
204207
onMouseOver: PropTypes.func,
205208
color: PropTypes.string,
206209
displayMode: PropTypes.oneOf(['dateRange', 'date']),
210+
styles: PropTypes.object,
207211
};
208212

209213
export default DayCell;

0 commit comments

Comments
 (0)