Skip to content

Commit 48029b8

Browse files
committed
Add calendarContainer prop
1 parent e052b4a commit 48029b8

File tree

6 files changed

+128
-9
lines changed

6 files changed

+128
-9
lines changed

docs-site/src/example_components.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import MultiMonth from "./examples/multi_month";
3939
import MultiMonthDrp from "./examples/multi_month_drp";
4040
import MultiMonthInline from "./examples/multi_month_inline";
4141
import Children from "./examples/children";
42+
import CalendarContainer from "./examples/calendar_container";
4243
import Portal from "./examples/portal";
4344
import InlinePortal from "./examples/inline_portal";
4445
import RawChange from "./examples/raw_change";
@@ -240,6 +241,10 @@ export default class exampleComponents extends React.Component {
240241
title: "Children",
241242
component: <Children />
242243
},
244+
{
245+
title: "Calendar container",
246+
component: <CalendarContainer />
247+
},
243248
{
244249
title: "Get raw input value on change",
245250
component: <RawChange />
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import React from "react";
2+
import DatePicker, {
3+
CalendarContainer as OriginalContainer
4+
} from "react-datepicker";
5+
import PropTypes from "prop-types";
6+
import moment from "moment";
7+
8+
export default class CalendarContainer extends React.Component {
9+
constructor(props) {
10+
super(props);
11+
this.state = {
12+
startDate: moment()
13+
};
14+
}
15+
16+
handleChange = date => {
17+
this.setState({
18+
startDate: date
19+
});
20+
};
21+
22+
render() {
23+
return (
24+
<div className="row">
25+
<pre className="column example__code">
26+
<code className="jsx">
27+
{`\
28+
<DatePicker
29+
selected={this.state.startDate}
30+
onChange={this.handleChange}
31+
calendarContainer={MyContainer}
32+
/>
33+
34+
function MyContainer({ className, children }) {
35+
return (
36+
<div style={{ padding: '16px', background: '#216ba5', color: '#fff' }}>
37+
<CalendarContainer className={className}>
38+
<div style={{ background: '#f0f0f0' }}>What is your favorite day?</div>
39+
<div style={{ position: 'relative' }}>
40+
{children}
41+
</div>
42+
</CalendarContainer>
43+
</div>
44+
);
45+
}
46+
`}
47+
</code>
48+
</pre>
49+
<div className="column">
50+
<DatePicker
51+
selected={this.state.startDate}
52+
onChange={this.handleChange}
53+
calendarContainer={MyContainer}
54+
/>
55+
</div>
56+
</div>
57+
);
58+
}
59+
}
60+
61+
// eslint-disable-next-line react/no-multi-comp
62+
function MyContainer({ className, children }) {
63+
return (
64+
<div style={{ padding: "16px", background: "#216ba5", color: "#fff" }}>
65+
<OriginalContainer className={className}>
66+
<div style={{ background: "#f0f0f0" }}>What is your favorite day?</div>
67+
<div style={{ position: "relative" }}>{children}</div>
68+
</OriginalContainer>
69+
</div>
70+
);
71+
}
72+
73+
MyContainer.propTypes = {
74+
className: PropTypes.string,
75+
children: PropTypes.node
76+
};

src/calendar.jsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Time from "./time";
66
import React from "react";
77
import PropTypes from "prop-types";
88
import classnames from "classnames";
9+
import CalendarContainer from "./calendar_container";
910
import {
1011
now,
1112
setMonth,
@@ -51,6 +52,7 @@ export default class Calendar extends React.Component {
5152
adjustDateOnChange: PropTypes.bool,
5253
className: PropTypes.string,
5354
children: PropTypes.node,
55+
container: PropTypes.func,
5456
dateFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.array])
5557
.isRequired,
5658
dayClassName: PropTypes.func,
@@ -293,12 +295,16 @@ export default class Calendar extends React.Component {
293295
};
294296

295297
formatWeekday = (localeData, day) => {
296-
if (this.props.formatWeekDay) {
297-
return getFormattedWeekdayInLocale(localeData, day, this.props.formatWeekDay);
298-
}
299-
return this.props.useWeekdaysShort
300-
? getWeekdayShortInLocale(localeData, day)
301-
: getWeekdayMinInLocale(localeData, day);
298+
if (this.props.formatWeekDay) {
299+
return getFormattedWeekdayInLocale(
300+
localeData,
301+
day,
302+
this.props.formatWeekDay
303+
);
304+
}
305+
return this.props.useWeekdaysShort
306+
? getWeekdayShortInLocale(localeData, day)
307+
: getWeekdayMinInLocale(localeData, day);
302308
};
303309

304310
renderPreviousMonthButton = () => {
@@ -563,20 +569,21 @@ export default class Calendar extends React.Component {
563569
};
564570

565571
render() {
572+
const Container = this.props.container || CalendarContainer;
573+
566574
return (
567-
<div
575+
<Container
568576
className={classnames("react-datepicker", this.props.className, {
569577
"react-datepicker--time-only": this.props.showTimeSelectOnly
570578
})}
571579
>
572-
<div className="react-datepicker__triangle" />
573580
{this.renderPreviousMonthButton()}
574581
{this.renderNextMonthButton()}
575582
{this.renderMonths()}
576583
{this.renderTodayButton()}
577584
{this.renderTimeSection()}
578585
{this.props.children}
579-
</div>
586+
</Container>
580587
);
581588
}
582589
}

src/calendar_container.jsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import PropTypes from "prop-types";
2+
import React from "react";
3+
4+
export default function CalendarContainer({ className, children }) {
5+
return (
6+
<div className={className}>
7+
<div className="react-datepicker__triangle" />
8+
{children}
9+
</div>
10+
);
11+
}
12+
13+
CalendarContainer.propTypes = {
14+
className: PropTypes.string,
15+
children: PropTypes.node
16+
};

src/index.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import {
3636
} from "./date_utils";
3737
import onClickOutside from "react-onclickoutside";
3838

39+
export { default as CalendarContainer } from "./calendar_container";
40+
3941
const outsideClickIgnoreClass = "react-datepicker-ignore-onclickoutside";
4042
const WrappedCalendar = onClickOutside(Calendar);
4143

@@ -61,6 +63,7 @@ export default class DatePicker extends React.Component {
6163
autoComplete: PropTypes.string,
6264
autoFocus: PropTypes.bool,
6365
calendarClassName: PropTypes.string,
66+
calendarContainer: PropTypes.func,
6467
children: PropTypes.node,
6568
className: PropTypes.string,
6669
customInput: PropTypes.element,
@@ -558,6 +561,7 @@ export default class DatePicker extends React.Component {
558561
excludeTimes={this.props.excludeTimes}
559562
timeCaption={this.props.timeCaption}
560563
className={this.props.calendarClassName}
564+
container={this.props.calendarContainer}
561565
yearDropdownItemNumber={this.props.yearDropdownItemNumber}
562566
>
563567
{this.props.children}

test/datepicker_test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ describe("DatePicker", () => {
6969
expect(datePicker.instance().calendar).to.exist;
7070
});
7171

72+
it("should allow the user to pass a wrapper component for the calendar", () => {
73+
var datePicker = mount(<DatePicker calendarContainer={TestWrapper} />);
74+
75+
let dateInput = datePicker.instance().input;
76+
TestUtils.Simulate.focus(ReactDOM.findDOMNode(dateInput));
77+
78+
datePicker.update();
79+
expect(datePicker.find(".test-wrapper").length).to.equal(1);
80+
expect(datePicker.instance().calendar).to.exist;
81+
});
82+
7283
it("should pass a custom class to the popper container", () => {
7384
var datePicker = TestUtils.renderIntoDocument(
7485
<DatePicker popperClassName="some-class-name" />

0 commit comments

Comments
 (0)