Skip to content

Commit

Permalink
Add renderCalendarDay prop to allow for one-off, hacky customization …
Browse files Browse the repository at this point in the history
…of day styling
  • Loading branch information
Maja Wichrowska committed Dec 11, 2017
1 parent bab162d commit d810291
Show file tree
Hide file tree
Showing 30 changed files with 987 additions and 192 deletions.
9 changes: 6 additions & 3 deletions README.md
Expand Up @@ -155,7 +155,8 @@ onClose: PropTypes.func,
transitionDuration: nonNegativeInteger, // milliseconds

// day presentation and interaction related props
renderDay: PropTypes.func,
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,
minimumNights: PropTypes.number,
enableOutsideDays: PropTypes.bool,
isDayBlocked: PropTypes.func,
Expand Down Expand Up @@ -228,7 +229,8 @@ onClose: PropTypes.func,
transitionDuration: nonNegativeInteger, // milliseconds

// day presentation and interaction related props
renderDay: PropTypes.func,
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,
enableOutsideDays: PropTypes.bool,
isDayBlocked: PropTypes.func,
isOutsideRange: PropTypes.func,
Expand Down Expand Up @@ -278,7 +280,8 @@ The following is a list of other *OPTIONAL* props you may provide to the `DayPic
transitionDuration: nonNegativeInteger, // milliseconds

// day presentation and interaction related props
renderDay: PropTypes.func,
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,
minimumNights: PropTypes.number,
isOutsideRange: PropTypes.func,
isDayBlocked: PropTypes.func,
Expand Down
4 changes: 4 additions & 0 deletions css/storybook.scss
Expand Up @@ -17,4 +17,8 @@ html {
a {
color: #008489;
font-weight: bold;
}

.foo-bar {
background: red !important;
}
3 changes: 2 additions & 1 deletion examples/DateRangePickerWrapper.jsx
Expand Up @@ -71,7 +71,8 @@ const defaultProps = {
onClose() {},

// day presentation and interaction related props
renderDay: null,
renderCalendarDay: undefined,
renderDayContents: null,
minimumNights: 1,
enableOutsideDays: false,
isDayBlocked: () => false,
Expand Down
6 changes: 4 additions & 2 deletions examples/DayPickerRangeControllerWrapper.jsx
Expand Up @@ -39,7 +39,8 @@ const propTypes = forbidExtraProps({
onPrevMonthClick: PropTypes.func,
onNextMonthClick: PropTypes.func,
onOutsideClick: PropTypes.func,
renderDay: PropTypes.func,
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,

// i18n
monthFormat: PropTypes.string,
Expand All @@ -54,7 +55,8 @@ const defaultProps = {
initialEndDate: null,

// day presentation and interaction related props
renderDay: null,
renderCalendarDay: undefined,
renderDayContents: null,
minimumNights: 1,
isDayBlocked: () => false,
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
Expand Down
6 changes: 4 additions & 2 deletions examples/DayPickerSingleDateControllerWrapper.jsx
Expand Up @@ -38,7 +38,8 @@ const propTypes = forbidExtraProps({
onPrevMonthClick: PropTypes.func,
onNextMonthClick: PropTypes.func,
onOutsideClick: PropTypes.func,
renderDay: PropTypes.func,
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,

// i18n
monthFormat: PropTypes.string,
Expand All @@ -53,7 +54,8 @@ const defaultProps = {
showInput: false,

// day presentation and interaction related props
renderDay: null,
renderCalendarDay: undefined,
renderDayContents: null,
isDayBlocked: () => false,
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
isDayHighlighted: () => false,
Expand Down
2 changes: 1 addition & 1 deletion examples/PresetDateRangePicker.jsx
Expand Up @@ -79,7 +79,7 @@ const defaultProps = {
onClose() {},

// day presentation and interaction related props
renderDay: null,
renderDayContents: null,
minimumNights: 0,
enableOutsideDays: false,
isDayBlocked: () => false,
Expand Down
3 changes: 2 additions & 1 deletion examples/SingleDatePickerWrapper.jsx
Expand Up @@ -63,7 +63,8 @@ const defaultProps = {
onClose() {},

// day presentation and interaction related props
renderDay: null,
renderCalendarDay: undefined,
renderDayContents: null,
enableOutsideDays: false,
isDayBlocked: () => false,
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
Expand Down
80 changes: 31 additions & 49 deletions src/components/CalendarDay.jsx
Expand Up @@ -23,7 +23,7 @@ const propTypes = forbidExtraProps({
onDayClick: PropTypes.func,
onDayMouseEnter: PropTypes.func,
onDayMouseLeave: PropTypes.func,
renderDay: PropTypes.func,
renderDayContents: PropTypes.func,
ariaLabelFormat: PropTypes.string,

// internationalization
Expand All @@ -40,7 +40,7 @@ const defaultProps = {
onDayClick() {},
onDayMouseEnter() {},
onDayMouseLeave() {},
renderDay: null,
renderDayContents: null,
ariaLabelFormat: 'dddd, LL',

// internationalization
Expand Down Expand Up @@ -93,7 +93,7 @@ class CalendarDay extends React.Component {
daySize,
isOutsideDay,
modifiers,
renderDay,
renderDayContents,
tabIndex,
styles,
phrases: {
Expand Down Expand Up @@ -137,7 +137,9 @@ class CalendarDay extends React.Component {
return (
<td
{...css(
styles.CalendarDay_container,
styles.CalendarDay,
useDefaultCursor && styles.CalendarDay__defaultCursor,
styles.CalendarDay__default,
isOutsideDay && styles.CalendarDay__outside,
modifiers.has('today') && styles.CalendarDay__today,
modifiers.has('highlighted-calendar') && styles.CalendarDay__highlighted_calendar,
Expand All @@ -152,23 +154,17 @@ class CalendarDay extends React.Component {
isOutsideRange && styles.CalendarDay__blocked_out_of_range,
daySizeStyles,
)}
role="button" // eslint-disable-line jsx-a11y/no-noninteractive-element-to-interactive-role
ref={this.setButtonRef}
aria-label={ariaLabel}
onMouseEnter={(e) => { this.onDayMouseEnter(day, e); }}
onMouseLeave={(e) => { this.onDayMouseLeave(day, e); }}
onMouseUp={(e) => { e.currentTarget.blur(); }}
onClick={(e) => { this.onDayClick(day, e); }}
onKeyDown={(e) => { this.onKeyDown(day, e); }}
tabIndex={tabIndex}
>
<button
{...css(
styles.CalendarDay_button,
useDefaultCursor && styles.CalendarDay_button__default,
)}
type="button"
ref={this.setButtonRef}
aria-label={ariaLabel}
onMouseEnter={(e) => { this.onDayMouseEnter(day, e); }}
onMouseLeave={(e) => { this.onDayMouseLeave(day, e); }}
onMouseUp={(e) => { e.currentTarget.blur(); }}
onClick={(e) => { this.onDayClick(day, e); }}
tabIndex={tabIndex}
>
{renderDay ? renderDay(day, modifiers) : day.format('D')}
</button>
{renderDayContents ? renderDayContents(day, modifiers) : day.format('D')}
</td>
);
}
Expand All @@ -179,47 +175,33 @@ CalendarDay.defaultProps = defaultProps;

export { CalendarDay as PureCalendarDay };
export default withStyles(({ reactDates: { color, font } }) => ({
CalendarDay_container: {
border: `1px solid ${color.core.borderLight}`,
padding: 0,
boxSizing: 'border-box',
color: color.text,
background: color.background,

':hover': {
background: color.core.borderLight,
border: `1px double ${color.core.borderLight}`,
color: 'inherit',
},
},

CalendarDay_button: {
position: 'relative',
height: '100%',
width: '100%',
textAlign: 'center',
background: 'none',
border: 0,
margin: 0,
padding: 0,
color: 'inherit',
lineHeight: 'normal',
overflow: 'visible',
CalendarDay: {
boxSizing: 'border-box',
cursor: 'pointer',
fontFamily: 'inherit',
fontStyle: 'inherit',
fontSize: font.size,
textAlign: 'center',

':active': {
outline: 0,
},
},

CalendarDay_button__default: {
CalendarDay__defaultCursor: {
cursor: 'default',
},

CalendarDay__default: {
border: `1px solid ${color.core.borderLight}`,
color: color.text,
background: color.background,

':hover': {
background: color.core.borderLight,
border: `1px double ${color.core.borderLight}`,
color: 'inherit',
},
},

CalendarDay__outside: {
border: 0,

Expand Down
46 changes: 24 additions & 22 deletions src/components/CalendarMonth.jsx
Expand Up @@ -11,6 +11,7 @@ import moment from 'moment';
import { CalendarDayPhrases } from '../defaultPhrases';
import getPhrasePropTypes from '../utils/getPhrasePropTypes';

import CalendarWeek from './CalendarWeek';
import CalendarDay from './CalendarDay';

import calculateDimension from '../utils/calculateDimension';
Expand Down Expand Up @@ -40,7 +41,8 @@ const propTypes = forbidExtraProps({
onDayMouseEnter: PropTypes.func,
onDayMouseLeave: PropTypes.func,
renderMonth: PropTypes.func,
renderDay: PropTypes.func,
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,
firstDayOfWeek: DayOfWeekShape,
setMonthHeight: PropTypes.func,

Expand All @@ -64,7 +66,8 @@ const defaultProps = {
onDayMouseEnter() {},
onDayMouseLeave() {},
renderMonth: null,
renderDay: null,
renderCalendarDay: props => (<CalendarDay {...props} />),
renderDayContents: null,
firstDayOfWeek: null,
setMonthHeight() {},

Expand Down Expand Up @@ -149,7 +152,8 @@ class CalendarMonth extends React.Component {
onDayMouseEnter,
onDayMouseLeave,
renderMonth,
renderDay,
renderCalendarDay,
renderDayContents,
daySize,
focusedDate,
isFocused,
Expand Down Expand Up @@ -189,25 +193,23 @@ class CalendarMonth extends React.Component {
>
<tbody ref={this.setGridRef}>
{weeks.map((week, i) => (
<tr key={i}>
{week.map((day, dayOfWeek) => (
<CalendarDay
day={day}
daySize={daySize}
isOutsideDay={!day || day.month() !== month.month()}
tabIndex={isVisible && isSameDay(day, focusedDate) ? 0 : -1}
isFocused={isFocused}
key={dayOfWeek}
onDayMouseEnter={onDayMouseEnter}
onDayMouseLeave={onDayMouseLeave}
onDayClick={onDayClick}
renderDay={renderDay}
phrases={phrases}
modifiers={modifiers[toISODateString(day)]}
ariaLabelFormat={dayAriaLabelFormat}
/>
))}
</tr>
<CalendarWeek key={i}>
{week.map((day, dayOfWeek) => renderCalendarDay({
key: dayOfWeek,
day,
daySize,
isOutsideDay: !day || day.month() !== month.month(),
tabIndex: isVisible && isSameDay(day, focusedDate) ? 0 : -1,
isFocused,
onDayMouseEnter,
onDayMouseLeave,
onDayClick,
renderDayContents,
phrases,
modifiers: modifiers[toISODateString(day)],
ariaLabelFormat: dayAriaLabelFormat,
}))}
</CalendarWeek>
))}
</tbody>
</table>
Expand Down
12 changes: 8 additions & 4 deletions src/components/CalendarMonthGrid.jsx
Expand Up @@ -42,7 +42,8 @@ const propTypes = forbidExtraProps({
onDayMouseLeave: PropTypes.func,
onMonthTransitionEnd: PropTypes.func,
renderMonth: PropTypes.func,
renderDay: PropTypes.func,
renderCalendarDay: PropTypes.func,
renderDayContents: PropTypes.func,
transformValue: PropTypes.string,
daySize: nonNegativeInteger,
focusedDate: momentPropTypes.momentObj, // indicates focusable day
Expand Down Expand Up @@ -71,7 +72,8 @@ const defaultProps = {
onDayMouseLeave() {},
onMonthTransitionEnd() {},
renderMonth: null,
renderDay: null,
renderCalendarDay: undefined,
renderDayContents: null,
transformValue: 'none',
daySize: DAY_SIZE,
focusedDate: null,
Expand Down Expand Up @@ -231,7 +233,8 @@ class CalendarMonthGrid extends React.Component {
onDayMouseLeave,
onDayClick,
renderMonth,
renderDay,
renderCalendarDay,
renderDayContents,
onMonthTransitionEnd,
firstDayOfWeek,
focusedDate,
Expand Down Expand Up @@ -310,7 +313,8 @@ class CalendarMonthGrid extends React.Component {
onDayMouseLeave={onDayMouseLeave}
onDayClick={onDayClick}
renderMonth={renderMonth}
renderDay={renderDay}
renderCalendarDay={renderCalendarDay}
renderDayContents={renderDayContents}
firstDayOfWeek={firstDayOfWeek}
daySize={daySize}
focusedDate={isVisible ? focusedDate : null}
Expand Down
19 changes: 19 additions & 0 deletions src/components/CalendarWeek.jsx
@@ -0,0 +1,19 @@
import React from 'react';
import { forbidExtraProps, or, childrenOfType } from 'airbnb-prop-types';

import CalendarDay from './CalendarDay';
import CustomizableCalendarDay from './CustomizableCalendarDay';

const propTypes = forbidExtraProps({
children: or([childrenOfType(CalendarDay), childrenOfType(CustomizableCalendarDay)]).isRequired,
});

export default function CalendarWeek({ children }) {
return (
<tr>
{children}
</tr>
);
}

CalendarWeek.propTypes = propTypes;

0 comments on commit d810291

Please sign in to comment.