Skip to content

Commit a0a559d

Browse files
timhwang21Maja Wichrowska
authored and
Maja Wichrowska
committed
Add openDirection prop
Addresses #648. * Add `openDirection` prop to `<DateRangePicker/>`, `<SingleDatePicker/>`, `<DateRangePickerInputController/>`, `<DateRangePickerInput/>`, `<SingleDatePickerInput/>`, `<DateInput/> * Add SCSS variables for input font size, padding, etc. (used in calculation for open-up absolute positioning) * Add stories and tests for new prop
1 parent d0996af commit a0a559d

19 files changed

+211
-21
lines changed

constants.js

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ module.exports = {
1616
ANCHOR_LEFT: 'left',
1717
ANCHOR_RIGHT: 'right',
1818

19+
OPEN_DOWN: 'down',
20+
OPEN_UP: 'up',
21+
1922
DAY_SIZE: 39,
2023
BLOCKED_MODIFIER: 'blocked',
2124
WEEKDAYS: [0, 1, 2, 3, 4, 5, 6],

css/DateInput.scss

+31-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
$caret-top: $react-dates-spacing-vertical-picker - $react-dates-width-tooltip-arrow / 2;
1+
$input-height: $react-dates-input-line-height + $react-dates-input-padding * 2 + $react-dates-input-displaytext-padding-vertical * 2;
2+
$caret-top-down: $react-dates-spacing-vertical-picker - $react-dates-width-tooltip-arrow / 2;
3+
$caret-top-up: $input-height - $react-dates-spacing-vertical-picker;
24

35
.DateInput {
46
// font
57
font-weight: 200;
6-
font-size: 18px;
7-
line-height: 24px;
8+
font-size: $react-dates-input-font-size;
9+
line-height: $react-dates-input-line-height;
810
color: $react-dates-color-placeholder-text;
911
margin: 0;
10-
padding: 8px;
12+
padding: $react-dates-input-padding;
1113

1214
background: $react-dates-color-white;
1315
position: relative;
@@ -23,21 +25,40 @@ $caret-top: $react-dates-spacing-vertical-picker - $react-dates-width-tooltip-ar
2325
position: absolute;
2426
bottom: auto;
2527
border: $react-dates-width-tooltip-arrow / 2 solid transparent;
26-
border-top: 0;
2728
left: 22px;
2829
z-index: $react-dates-z-index + 2;
2930
}
3031

31-
.DateInput--with-caret::before {
32-
top: $caret-top;
32+
.DateInput--open-down.DateInput--with-caret::before,
33+
.DateInput--open-down.DateInput--with-caret::after {
34+
border-top: 0;
35+
}
36+
37+
.DateInput--open-down.DateInput--with-caret::before {
38+
top: $caret-top-down;
3339
border-bottom-color: rgba(0, 0, 0, 0.1);
3440
}
3541

36-
.DateInput--with-caret::after {
37-
top: $caret-top + 1;
42+
.DateInput--open-down.DateInput--with-caret::after {
43+
top: $caret-top-down + 1;
3844
border-bottom-color: $react-dates-color-white;
3945
}
4046

47+
.DateInput--open-up.DateInput--with-caret::before,
48+
.DateInput--open-up.DateInput--with-caret::after {
49+
border-bottom: 0;
50+
}
51+
52+
.DateInput--open-up.DateInput--with-caret::before {
53+
top: $caret-top-up;
54+
border-top-color: rgba(0, 0, 0, 0.1);
55+
}
56+
57+
.DateInput--open-up.DateInput--with-caret::after {
58+
top: $caret-top-up - 1;
59+
border-top-color: $react-dates-color-white;
60+
}
61+
4162
.DateInput--disabled {
4263
background: $react-dates-color-gray-lighter;
4364
}
@@ -60,7 +81,7 @@ $caret-top: $react-dates-spacing-vertical-picker - $react-dates-width-tooltip-ar
6081
}
6182

6283
.DateInput__display-text {
63-
padding: 4px 8px;
84+
padding: $react-dates-input-displaytext-padding-vertical $react-dates-input-displaytext-padding-horizontal;
6485
white-space: nowrap;
6586
overflow: hidden;
6687
}

css/DateRangePicker.scss

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@
2020
z-index: $react-dates-z-index + 1;
2121
background-color: $react-dates-color-white;
2222
position: absolute;
23-
top: $react-dates-spacing-vertical-picker;
2423
}
2524

26-
.DateRangePicker__picker--rtl {
25+
.DateRangePicker__picker--rtl {
2726
direction: rtl;
2827
}
2928

@@ -35,6 +34,14 @@
3534
right: 0;
3635
}
3736

37+
.DateRangePicker__picker--open-down {
38+
top: $react-dates-spacing-vertical-picker;
39+
}
40+
41+
.DateRangePicker__picker--open-up {
42+
bottom: $react-dates-spacing-vertical-picker;
43+
}
44+
3845
.DateRangePicker__picker--portal {
3946
background-color: rgba(0, 0, 0, 0.3);
4047
position: fixed;

css/SingleDatePicker.scss

+8-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
z-index: $react-dates-z-index + 1;
1010
background-color: $react-dates-color-white;
1111
position: absolute;
12-
top: $react-dates-spacing-vertical-picker;
1312
}
1413

1514
.SingleDatePicker__picker--rtl {
@@ -24,6 +23,14 @@
2423
right: 0;
2524
}
2625

26+
.SingleDatePicker__picker--open-down {
27+
top: $react-dates-spacing-vertical-picker;
28+
}
29+
30+
.SingleDatePicker__picker--open-up {
31+
bottom: $react-dates-spacing-vertical-picker;
32+
}
33+
2734
.SingleDatePicker__picker--portal {
2835
background-color: rgba(0, 0, 0, 0.3);
2936
position: fixed;

css/variables.scss

+6
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,9 @@ $react-dates-color-text-focus: #007a87 !default;
2626
$react-dates-color-focus: #99ede6 !default;
2727

2828
$react-dates-z-index: 0 !default;
29+
30+
$react-dates-input-font-size: 18px !default;
31+
$react-dates-input-line-height: 24px !default;
32+
$react-dates-input-padding: 8px !default;
33+
$react-dates-input-displaytext-padding-horizontal: 8px !default;
34+
$react-dates-input-displaytext-padding-vertical: 4px !default;

src/components/DateInput.jsx

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import cx from 'classnames';
55
import throttle from 'lodash/throttle';
66
import isTouchDevice from 'is-touch-device';
77

8+
import openDirectionShape from '../shapes/OpenDirectionShape';
9+
import { OPEN_DOWN, OPEN_UP } from '../../constants';
10+
811
const propTypes = forbidExtraProps({
912
id: PropTypes.string.isRequired,
1013
placeholder: PropTypes.string, // also used as label
@@ -15,6 +18,7 @@ const propTypes = forbidExtraProps({
1518
disabled: PropTypes.bool,
1619
required: PropTypes.bool,
1720
readOnly: PropTypes.bool,
21+
openDirection: openDirectionShape,
1822
showCaret: PropTypes.bool,
1923

2024
onChange: PropTypes.func,
@@ -38,6 +42,7 @@ const defaultProps = {
3842
disabled: false,
3943
required: false,
4044
readOnly: null,
45+
openDirection: OPEN_DOWN,
4146
showCaret: false,
4247

4348
onChange() {},
@@ -151,6 +156,7 @@ export default class DateInput extends React.Component {
151156
disabled,
152157
required,
153158
readOnly,
159+
openDirection,
154160
} = this.props;
155161

156162
const displayText = displayValue || inputValue || dateString || placeholder || '';
@@ -162,6 +168,8 @@ export default class DateInput extends React.Component {
162168
className={cx('DateInput', {
163169
'DateInput--with-caret': showCaret && focused,
164170
'DateInput--disabled': disabled,
171+
'DateInput--open-down': openDirection === OPEN_DOWN,
172+
'DateInput--open-up': openDirection === OPEN_UP,
165173
})}
166174
>
167175
<input

src/components/DateRangePicker.jsx

+8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import {
2929
VERTICAL_ORIENTATION,
3030
ANCHOR_LEFT,
3131
ANCHOR_RIGHT,
32+
OPEN_DOWN,
33+
OPEN_UP,
3234
DAY_SIZE,
3335
ICON_BEFORE_POSITION,
3436
} from '../../constants';
@@ -61,6 +63,7 @@ const defaultProps = {
6163
renderMonth: null,
6264
orientation: HORIZONTAL_ORIENTATION,
6365
anchorDirection: ANCHOR_LEFT,
66+
openDirection: OPEN_DOWN,
6467
horizontalMargin: 0,
6568
withPortal: false,
6669
withFullScreenPortal: false,
@@ -208,12 +211,15 @@ export default class DateRangePicker extends React.Component {
208211
withPortal,
209212
withFullScreenPortal,
210213
anchorDirection,
214+
openDirection,
211215
isRTL,
212216
} = this.props;
213217

214218
const dayPickerClassName = cx('DateRangePicker__picker', {
215219
'DateRangePicker__picker--direction-left': anchorDirection === ANCHOR_LEFT,
216220
'DateRangePicker__picker--direction-right': anchorDirection === ANCHOR_RIGHT,
221+
'DateRangePicker__picker--open-down': openDirection === OPEN_DOWN,
222+
'DateRangePicker__picker--open-up': openDirection === OPEN_UP,
217223
'DateRangePicker__picker--horizontal': orientation === HORIZONTAL_ORIENTATION,
218224
'DateRangePicker__picker--vertical': orientation === VERTICAL_ORIENTATION,
219225
'DateRangePicker__picker--portal': withPortal || withFullScreenPortal,
@@ -419,6 +425,7 @@ export default class DateRangePicker extends React.Component {
419425
disabled,
420426
required,
421427
readOnly,
428+
openDirection,
422429
phrases,
423430
isOutsideRange,
424431
minimumNights,
@@ -459,6 +466,7 @@ export default class DateRangePicker extends React.Component {
459466
disabled={disabled}
460467
required={required}
461468
readOnly={readOnly}
469+
openDirection={openDirection}
462470
reopenPickerOnClearDates={reopenPickerOnClearDates}
463471
keepOpenOnDateSelect={keepOpenOnDateSelect}
464472
isOutsideRange={isOutsideRange}

src/components/DateRangePickerInput.jsx

+13-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import cx from 'classnames';
55

66
import { DateRangePickerInputPhrases } from '../defaultPhrases';
77
import getPhrasePropTypes from '../utils/getPhrasePropTypes';
8+
import openDirectionShape from '../shapes/OpenDirectionShape';
89

910
import DateInput from './DateInput';
1011
import IconPositionShape from '../shapes/IconPositionShape';
@@ -14,7 +15,13 @@ import LeftArrow from '../svg/arrow-left.svg';
1415
import CloseButton from '../svg/close.svg';
1516
import CalendarIcon from '../svg/calendar.svg';
1617

17-
import { START_DATE, END_DATE, ICON_BEFORE_POSITION, ICON_AFTER_POSITION } from '../../constants';
18+
import {
19+
START_DATE,
20+
END_DATE,
21+
ICON_BEFORE_POSITION,
22+
ICON_AFTER_POSITION,
23+
OPEN_DOWN,
24+
} from '../../constants';
1825

1926
const propTypes = forbidExtraProps({
2027
startDateId: PropTypes.string,
@@ -45,6 +52,7 @@ const propTypes = forbidExtraProps({
4552
disabled: PropTypes.bool,
4653
required: PropTypes.bool,
4754
readOnly: PropTypes.bool,
55+
openDirection: openDirectionShape,
4856
showCaret: PropTypes.bool,
4957
showDefaultInputIcon: PropTypes.bool,
5058
inputIconPosition: IconPositionShape,
@@ -88,6 +96,7 @@ const defaultProps = {
8896
disabled: false,
8997
required: false,
9098
readOnly: false,
99+
openDirection: OPEN_DOWN,
91100
showCaret: false,
92101
showDefaultInputIcon: false,
93102
inputIconPosition: ICON_BEFORE_POSITION,
@@ -154,6 +163,7 @@ export default class DateRangePickerInput extends React.Component {
154163
disabled,
155164
required,
156165
readOnly,
166+
openDirection,
157167
showCaret,
158168
showDefaultInputIcon,
159169
inputIconPosition,
@@ -202,6 +212,7 @@ export default class DateRangePickerInput extends React.Component {
202212
disabled={disabled}
203213
required={required}
204214
readOnly={readOnly}
215+
openDirection={openDirection}
205216
showCaret={showCaret}
206217

207218
onChange={onStartDateChange}
@@ -230,6 +241,7 @@ export default class DateRangePickerInput extends React.Component {
230241
disabled={disabled}
231242
required={required}
232243
readOnly={readOnly}
244+
openDirection={openDirection}
233245
showCaret={showCaret}
234246

235247
onChange={onEndDateChange}

src/components/DateRangePickerInputController.jsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import moment from 'moment';
44

55
import momentPropTypes from 'react-moment-proptypes';
66
import { forbidExtraProps, nonNegativeInteger } from 'airbnb-prop-types';
7+
import openDirectionShape from '../shapes/OpenDirectionShape';
78

89
import { DateRangePickerInputPhrases } from '../defaultPhrases';
910
import getPhrasePropTypes from '../utils/getPhrasePropTypes';
@@ -19,7 +20,7 @@ import toISODateString from '../utils/toISODateString';
1920
import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay';
2021
import isBeforeDay from '../utils/isBeforeDay';
2122

22-
import { START_DATE, END_DATE, ICON_BEFORE_POSITION } from '../../constants';
23+
import { START_DATE, END_DATE, ICON_BEFORE_POSITION, OPEN_DOWN } from '../../constants';
2324

2425
const propTypes = forbidExtraProps({
2526
startDate: momentPropTypes.momentObj,
@@ -40,6 +41,7 @@ const propTypes = forbidExtraProps({
4041
disabled: PropTypes.bool,
4142
required: PropTypes.bool,
4243
readOnly: PropTypes.bool,
44+
openDirection: openDirectionShape,
4345

4446
keepOpenOnDateSelect: PropTypes.bool,
4547
reopenPickerOnClearDates: PropTypes.bool,
@@ -86,6 +88,7 @@ const defaultProps = {
8688
disabled: false,
8789
required: false,
8890
readOnly: false,
91+
openDirection: OPEN_DOWN,
8992

9093
keepOpenOnDateSelect: false,
9194
reopenPickerOnClearDates: false,
@@ -238,6 +241,7 @@ export default class DateRangePickerInputController extends React.Component {
238241
disabled,
239242
required,
240243
readOnly,
244+
openDirection,
241245
isFocused,
242246
phrases,
243247
onArrowDown,
@@ -266,6 +270,7 @@ export default class DateRangePickerInputController extends React.Component {
266270
disabled={disabled}
267271
required={required}
268272
readOnly={readOnly}
273+
openDirection={openDirection}
269274
showCaret={showCaret}
270275
showDefaultInputIcon={showDefaultInputIcon}
271276
inputIconPosition={inputIconPosition}

0 commit comments

Comments
 (0)