Skip to content

Commit d810291

Browse files
author
Maja Wichrowska
committed
Add renderCalendarDay prop to allow for one-off, hacky customization of day styling
1 parent bab162d commit d810291

30 files changed

+987
-192
lines changed

README.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ onClose: PropTypes.func,
155155
transitionDuration: nonNegativeInteger, // milliseconds
156156

157157
// day presentation and interaction related props
158-
renderDay: PropTypes.func,
158+
renderCalendarDay: PropTypes.func,
159+
renderDayContents: PropTypes.func,
159160
minimumNights: PropTypes.number,
160161
enableOutsideDays: PropTypes.bool,
161162
isDayBlocked: PropTypes.func,
@@ -228,7 +229,8 @@ onClose: PropTypes.func,
228229
transitionDuration: nonNegativeInteger, // milliseconds
229230

230231
// day presentation and interaction related props
231-
renderDay: PropTypes.func,
232+
renderCalendarDay: PropTypes.func,
233+
renderDayContents: PropTypes.func,
232234
enableOutsideDays: PropTypes.bool,
233235
isDayBlocked: PropTypes.func,
234236
isOutsideRange: PropTypes.func,
@@ -278,7 +280,8 @@ The following is a list of other *OPTIONAL* props you may provide to the `DayPic
278280
transitionDuration: nonNegativeInteger, // milliseconds
279281

280282
// day presentation and interaction related props
281-
renderDay: PropTypes.func,
283+
renderCalendarDay: PropTypes.func,
284+
renderDayContents: PropTypes.func,
282285
minimumNights: PropTypes.number,
283286
isOutsideRange: PropTypes.func,
284287
isDayBlocked: PropTypes.func,

css/storybook.scss

+4
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,8 @@ html {
1717
a {
1818
color: #008489;
1919
font-weight: bold;
20+
}
21+
22+
.foo-bar {
23+
background: red !important;
2024
}

examples/DateRangePickerWrapper.jsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ const defaultProps = {
7171
onClose() {},
7272

7373
// day presentation and interaction related props
74-
renderDay: null,
74+
renderCalendarDay: undefined,
75+
renderDayContents: null,
7576
minimumNights: 1,
7677
enableOutsideDays: false,
7778
isDayBlocked: () => false,

examples/DayPickerRangeControllerWrapper.jsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ const propTypes = forbidExtraProps({
3939
onPrevMonthClick: PropTypes.func,
4040
onNextMonthClick: PropTypes.func,
4141
onOutsideClick: PropTypes.func,
42-
renderDay: PropTypes.func,
42+
renderCalendarDay: PropTypes.func,
43+
renderDayContents: PropTypes.func,
4344

4445
// i18n
4546
monthFormat: PropTypes.string,
@@ -54,7 +55,8 @@ const defaultProps = {
5455
initialEndDate: null,
5556

5657
// day presentation and interaction related props
57-
renderDay: null,
58+
renderCalendarDay: undefined,
59+
renderDayContents: null,
5860
minimumNights: 1,
5961
isDayBlocked: () => false,
6062
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),

examples/DayPickerSingleDateControllerWrapper.jsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ const propTypes = forbidExtraProps({
3838
onPrevMonthClick: PropTypes.func,
3939
onNextMonthClick: PropTypes.func,
4040
onOutsideClick: PropTypes.func,
41-
renderDay: PropTypes.func,
41+
renderCalendarDay: PropTypes.func,
42+
renderDayContents: PropTypes.func,
4243

4344
// i18n
4445
monthFormat: PropTypes.string,
@@ -53,7 +54,8 @@ const defaultProps = {
5354
showInput: false,
5455

5556
// day presentation and interaction related props
56-
renderDay: null,
57+
renderCalendarDay: undefined,
58+
renderDayContents: null,
5759
isDayBlocked: () => false,
5860
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
5961
isDayHighlighted: () => false,

examples/PresetDateRangePicker.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ const defaultProps = {
7979
onClose() {},
8080

8181
// day presentation and interaction related props
82-
renderDay: null,
82+
renderDayContents: null,
8383
minimumNights: 0,
8484
enableOutsideDays: false,
8585
isDayBlocked: () => false,

examples/SingleDatePickerWrapper.jsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ const defaultProps = {
6363
onClose() {},
6464

6565
// day presentation and interaction related props
66-
renderDay: null,
66+
renderCalendarDay: undefined,
67+
renderDayContents: null,
6768
enableOutsideDays: false,
6869
isDayBlocked: () => false,
6970
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),

src/components/CalendarDay.jsx

+31-49
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const propTypes = forbidExtraProps({
2323
onDayClick: PropTypes.func,
2424
onDayMouseEnter: PropTypes.func,
2525
onDayMouseLeave: PropTypes.func,
26-
renderDay: PropTypes.func,
26+
renderDayContents: PropTypes.func,
2727
ariaLabelFormat: PropTypes.string,
2828

2929
// internationalization
@@ -40,7 +40,7 @@ const defaultProps = {
4040
onDayClick() {},
4141
onDayMouseEnter() {},
4242
onDayMouseLeave() {},
43-
renderDay: null,
43+
renderDayContents: null,
4444
ariaLabelFormat: 'dddd, LL',
4545

4646
// internationalization
@@ -93,7 +93,7 @@ class CalendarDay extends React.Component {
9393
daySize,
9494
isOutsideDay,
9595
modifiers,
96-
renderDay,
96+
renderDayContents,
9797
tabIndex,
9898
styles,
9999
phrases: {
@@ -137,7 +137,9 @@ class CalendarDay extends React.Component {
137137
return (
138138
<td
139139
{...css(
140-
styles.CalendarDay_container,
140+
styles.CalendarDay,
141+
useDefaultCursor && styles.CalendarDay__defaultCursor,
142+
styles.CalendarDay__default,
141143
isOutsideDay && styles.CalendarDay__outside,
142144
modifiers.has('today') && styles.CalendarDay__today,
143145
modifiers.has('highlighted-calendar') && styles.CalendarDay__highlighted_calendar,
@@ -152,23 +154,17 @@ class CalendarDay extends React.Component {
152154
isOutsideRange && styles.CalendarDay__blocked_out_of_range,
153155
daySizeStyles,
154156
)}
157+
role="button" // eslint-disable-line jsx-a11y/no-noninteractive-element-to-interactive-role
158+
ref={this.setButtonRef}
159+
aria-label={ariaLabel}
160+
onMouseEnter={(e) => { this.onDayMouseEnter(day, e); }}
161+
onMouseLeave={(e) => { this.onDayMouseLeave(day, e); }}
162+
onMouseUp={(e) => { e.currentTarget.blur(); }}
163+
onClick={(e) => { this.onDayClick(day, e); }}
164+
onKeyDown={(e) => { this.onKeyDown(day, e); }}
165+
tabIndex={tabIndex}
155166
>
156-
<button
157-
{...css(
158-
styles.CalendarDay_button,
159-
useDefaultCursor && styles.CalendarDay_button__default,
160-
)}
161-
type="button"
162-
ref={this.setButtonRef}
163-
aria-label={ariaLabel}
164-
onMouseEnter={(e) => { this.onDayMouseEnter(day, e); }}
165-
onMouseLeave={(e) => { this.onDayMouseLeave(day, e); }}
166-
onMouseUp={(e) => { e.currentTarget.blur(); }}
167-
onClick={(e) => { this.onDayClick(day, e); }}
168-
tabIndex={tabIndex}
169-
>
170-
{renderDay ? renderDay(day, modifiers) : day.format('D')}
171-
</button>
167+
{renderDayContents ? renderDayContents(day, modifiers) : day.format('D')}
172168
</td>
173169
);
174170
}
@@ -179,47 +175,33 @@ CalendarDay.defaultProps = defaultProps;
179175

180176
export { CalendarDay as PureCalendarDay };
181177
export default withStyles(({ reactDates: { color, font } }) => ({
182-
CalendarDay_container: {
183-
border: `1px solid ${color.core.borderLight}`,
184-
padding: 0,
185-
boxSizing: 'border-box',
186-
color: color.text,
187-
background: color.background,
188-
189-
':hover': {
190-
background: color.core.borderLight,
191-
border: `1px double ${color.core.borderLight}`,
192-
color: 'inherit',
193-
},
194-
},
195-
196-
CalendarDay_button: {
197-
position: 'relative',
198-
height: '100%',
199-
width: '100%',
200-
textAlign: 'center',
201-
background: 'none',
202-
border: 0,
203-
margin: 0,
204-
padding: 0,
205-
color: 'inherit',
206-
lineHeight: 'normal',
207-
overflow: 'visible',
178+
CalendarDay: {
208179
boxSizing: 'border-box',
209180
cursor: 'pointer',
210-
fontFamily: 'inherit',
211-
fontStyle: 'inherit',
212181
fontSize: font.size,
182+
textAlign: 'center',
213183

214184
':active': {
215185
outline: 0,
216186
},
217187
},
218188

219-
CalendarDay_button__default: {
189+
CalendarDay__defaultCursor: {
220190
cursor: 'default',
221191
},
222192

193+
CalendarDay__default: {
194+
border: `1px solid ${color.core.borderLight}`,
195+
color: color.text,
196+
background: color.background,
197+
198+
':hover': {
199+
background: color.core.borderLight,
200+
border: `1px double ${color.core.borderLight}`,
201+
color: 'inherit',
202+
},
203+
},
204+
223205
CalendarDay__outside: {
224206
border: 0,
225207

src/components/CalendarMonth.jsx

+24-22
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import moment from 'moment';
1111
import { CalendarDayPhrases } from '../defaultPhrases';
1212
import getPhrasePropTypes from '../utils/getPhrasePropTypes';
1313

14+
import CalendarWeek from './CalendarWeek';
1415
import CalendarDay from './CalendarDay';
1516

1617
import calculateDimension from '../utils/calculateDimension';
@@ -40,7 +41,8 @@ const propTypes = forbidExtraProps({
4041
onDayMouseEnter: PropTypes.func,
4142
onDayMouseLeave: PropTypes.func,
4243
renderMonth: PropTypes.func,
43-
renderDay: PropTypes.func,
44+
renderCalendarDay: PropTypes.func,
45+
renderDayContents: PropTypes.func,
4446
firstDayOfWeek: DayOfWeekShape,
4547
setMonthHeight: PropTypes.func,
4648

@@ -64,7 +66,8 @@ const defaultProps = {
6466
onDayMouseEnter() {},
6567
onDayMouseLeave() {},
6668
renderMonth: null,
67-
renderDay: null,
69+
renderCalendarDay: props => (<CalendarDay {...props} />),
70+
renderDayContents: null,
6871
firstDayOfWeek: null,
6972
setMonthHeight() {},
7073

@@ -149,7 +152,8 @@ class CalendarMonth extends React.Component {
149152
onDayMouseEnter,
150153
onDayMouseLeave,
151154
renderMonth,
152-
renderDay,
155+
renderCalendarDay,
156+
renderDayContents,
153157
daySize,
154158
focusedDate,
155159
isFocused,
@@ -189,25 +193,23 @@ class CalendarMonth extends React.Component {
189193
>
190194
<tbody ref={this.setGridRef}>
191195
{weeks.map((week, i) => (
192-
<tr key={i}>
193-
{week.map((day, dayOfWeek) => (
194-
<CalendarDay
195-
day={day}
196-
daySize={daySize}
197-
isOutsideDay={!day || day.month() !== month.month()}
198-
tabIndex={isVisible && isSameDay(day, focusedDate) ? 0 : -1}
199-
isFocused={isFocused}
200-
key={dayOfWeek}
201-
onDayMouseEnter={onDayMouseEnter}
202-
onDayMouseLeave={onDayMouseLeave}
203-
onDayClick={onDayClick}
204-
renderDay={renderDay}
205-
phrases={phrases}
206-
modifiers={modifiers[toISODateString(day)]}
207-
ariaLabelFormat={dayAriaLabelFormat}
208-
/>
209-
))}
210-
</tr>
196+
<CalendarWeek key={i}>
197+
{week.map((day, dayOfWeek) => renderCalendarDay({
198+
key: dayOfWeek,
199+
day,
200+
daySize,
201+
isOutsideDay: !day || day.month() !== month.month(),
202+
tabIndex: isVisible && isSameDay(day, focusedDate) ? 0 : -1,
203+
isFocused,
204+
onDayMouseEnter,
205+
onDayMouseLeave,
206+
onDayClick,
207+
renderDayContents,
208+
phrases,
209+
modifiers: modifiers[toISODateString(day)],
210+
ariaLabelFormat: dayAriaLabelFormat,
211+
}))}
212+
</CalendarWeek>
211213
))}
212214
</tbody>
213215
</table>

src/components/CalendarMonthGrid.jsx

+8-4
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ const propTypes = forbidExtraProps({
4242
onDayMouseLeave: PropTypes.func,
4343
onMonthTransitionEnd: PropTypes.func,
4444
renderMonth: PropTypes.func,
45-
renderDay: PropTypes.func,
45+
renderCalendarDay: PropTypes.func,
46+
renderDayContents: PropTypes.func,
4647
transformValue: PropTypes.string,
4748
daySize: nonNegativeInteger,
4849
focusedDate: momentPropTypes.momentObj, // indicates focusable day
@@ -71,7 +72,8 @@ const defaultProps = {
7172
onDayMouseLeave() {},
7273
onMonthTransitionEnd() {},
7374
renderMonth: null,
74-
renderDay: null,
75+
renderCalendarDay: undefined,
76+
renderDayContents: null,
7577
transformValue: 'none',
7678
daySize: DAY_SIZE,
7779
focusedDate: null,
@@ -231,7 +233,8 @@ class CalendarMonthGrid extends React.Component {
231233
onDayMouseLeave,
232234
onDayClick,
233235
renderMonth,
234-
renderDay,
236+
renderCalendarDay,
237+
renderDayContents,
235238
onMonthTransitionEnd,
236239
firstDayOfWeek,
237240
focusedDate,
@@ -310,7 +313,8 @@ class CalendarMonthGrid extends React.Component {
310313
onDayMouseLeave={onDayMouseLeave}
311314
onDayClick={onDayClick}
312315
renderMonth={renderMonth}
313-
renderDay={renderDay}
316+
renderCalendarDay={renderCalendarDay}
317+
renderDayContents={renderDayContents}
314318
firstDayOfWeek={firstDayOfWeek}
315319
daySize={daySize}
316320
focusedDate={isVisible ? focusedDate : null}

src/components/CalendarWeek.jsx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
import { forbidExtraProps, or, childrenOfType } from 'airbnb-prop-types';
3+
4+
import CalendarDay from './CalendarDay';
5+
import CustomizableCalendarDay from './CustomizableCalendarDay';
6+
7+
const propTypes = forbidExtraProps({
8+
children: or([childrenOfType(CalendarDay), childrenOfType(CustomizableCalendarDay)]).isRequired,
9+
});
10+
11+
export default function CalendarWeek({ children }) {
12+
return (
13+
<tr>
14+
{children}
15+
</tr>
16+
);
17+
}
18+
19+
CalendarWeek.propTypes = propTypes;

0 commit comments

Comments
 (0)