Skip to content

Commit

Permalink
feat(DateInput): add month picker
Browse files Browse the repository at this point in the history
  • Loading branch information
lesha1201 committed Aug 28, 2019
1 parent c539e0b commit c18aaf3
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 47 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions e2e/__tests__/date-input.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ const SUITES = [

await input.click();

await (await iframe.waitForXPath('//input')).click();
await input.click();
}),
baisy.suite('Components/DateInput', 'common', 'open month picker')
.setRootHeight(600)
.setEnhancer(async (iframe) => {
const input = await iframe.waitForXPath('(//input)[7]');

await input.click();

await (await iframe.waitForXPath('//input')).click();
await input.click();
}),
Expand Down
39 changes: 25 additions & 14 deletions src/components/DateInput/DateInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type DateInputProps = {
stretch?: boolean,
clearable?: boolean,
disabled?: boolean,
isMonthPicker?: boolean,
placeholder?: string,
};

Expand All @@ -34,32 +35,42 @@ class DateInput extends React.Component<DateInputProps, DateInputState> {
constructor(props: DateInputProps) {
super(props);

const dateFormat = this.getDateFormat();

this.state = {
textValue: utils.fromISOToViewFormat(props.value, props.withTime),
textValue: utils.fromISOToViewFormat(props.value, dateFormat),
isOpen: false,
};
}

componentDidUpdate(prevProps: DateInputProps) {
const { value, withTime } = this.props;
const { value } = this.props;
const dateFormat = this.getDateFormat();

if (value !== prevProps.value) {
this.setState({
textValue: utils.fromISOToViewFormat(value, withTime),
textValue: utils.fromISOToViewFormat(value, dateFormat),
});
}
}

getDateFormat() {
const { isMonthPicker, withTime } = this.props;

return isMonthPicker ? utils.YEAR_MONTH_FORMAT : withTime ? utils.DATETIME_FORMAT : utils.DATE_FORMAT;
}

onChangeText = ({ target: { value }}: Object) => {
const { withTime } = this.props;
const dateFormat = this.getDateFormat();

this.setState({ textValue: value });

if (!value) {
this.props.onChange(null);
return;
} else {
const luxonValue = utils.fromViewFormatToLuxon(value, withTime);
const luxonValue = utils.fromViewFormatToLuxon(value, dateFormat);

if (luxonValue && luxonValue.isValid) {
value = utils.fromLuxonToISO(luxonValue, withTime);
Expand All @@ -70,13 +81,13 @@ class DateInput extends React.Component<DateInputProps, DateInputState> {
};

onBlur = () => {
const { withTime } = this.props;
const { textValue } = this.state;
const dateFormat = this.getDateFormat();

const luxonValue = utils.fromViewFormatToLuxon(textValue, withTime);
const luxonValue = utils.fromViewFormatToLuxon(textValue, dateFormat);

if (luxonValue && !luxonValue.isValid) {
this.setState({ textValue: utils.fromISOToViewFormat(this.props.value, withTime) });
this.setState({ textValue: utils.fromISOToViewFormat(this.props.value, dateFormat) });
}
}

Expand All @@ -93,17 +104,17 @@ class DateInput extends React.Component<DateInputProps, DateInputState> {
};

collectProps() {
const { value, withTime, withPortal, ...rest } = this.props;

const dateFormat = withTime ? utils.DATETIME_FORMAT : utils.DATE_FORMAT;
const { value, withTime, withPortal, isMonthPicker, ...rest } = this.props;

return {
selected: utils.fromISOtoJSDate(value),
dateFormat,
dateFormat: this.getDateFormat(),
...rest,
showTimeSelect: withTime,
showMonthYearPicker: isMonthPicker,
onChange: this.onChangeDate,
inline: true,
todayButton: isMonthPicker ? 'Current' : 'Today',
};
}

Expand All @@ -122,10 +133,10 @@ class DateInput extends React.Component<DateInputProps, DateInputState> {
render() {
const collectedProps = this.collectProps();

const { value, withTime, withPortal, stretch, onChange, clearable, disabled, placeholder, ...rest } = this.props;
const { value, withTime, withPortal, stretch, onChange, clearable, disabled, placeholder, isMonthPicker, ...rest } = this.props;

const { textValue, isOpen } = this.state;
const mask = withTime ? utils.DATETIME_MASK : utils.DATE_MASK;
const mask = isMonthPicker ? utils.YEAR_MONTH_MASK : withTime ? utils.DATETIME_MASK : utils.DATE_MASK;

return (
<Dropdown
Expand All @@ -151,7 +162,7 @@ class DateInput extends React.Component<DateInputProps, DateInputState> {
boundariesElement: 'viewport',
},
}}>
<DatePicker { ...collectedProps } todayButton="Today" />
<DatePicker { ...collectedProps } />
</Dropdown.Body>
</Dropdown>
);
Expand Down
3 changes: 3 additions & 0 deletions src/components/DateInput/DateInput.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export default (asStory) => {
<StateContainer value={ null }>
<DateInput placeholder="mm/dd/yyyy" disabled />
</StateContainer>
<StateContainer value="2019-08">
<DateInput placeholder="mm/yyyy" isMonthPicker clearable />
</StateContainer>
</Column>
));
});
Expand Down
75 changes: 46 additions & 29 deletions src/components/DateInput/DateInput.theme.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { css } from '@emotion/core';

import { createThemeTag } from '../../theme/createThemeTag';

// eslint-disable-next-line
const [_, theme] = createThemeTag('dateInput', ({ COLORS }: *) => ({
globals: `
globals: css`
.react-datepicker {
border: 1px solid ${COLORS.PRIMARY_BORDER_COLOR};
box-shadow: 0 2px 10px 0 rgba(208,215,221,0.5);
box-shadow: 0 2px 10px 0 rgba(208, 215, 221, 0.5);
display: flex;
padding-bottom: 32px;
font-size: 12px;
font-family: inherit;
color: ${COLORS.PRIMARY_TEXT_COLOR};
}
.react-datepicker__header,
Expand All @@ -31,8 +36,6 @@ const [_, theme] = createThemeTag('dateInput', ({ COLORS }: *) => ({
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-family: Poppins;
color: ${COLORS.PRIMARY_TEXT_COLOR};
}
Expand All @@ -44,25 +47,22 @@ const [_, theme] = createThemeTag('dateInput', ({ COLORS }: *) => ({
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-family: Poppins;
color: ${COLORS.PRIMARY_TEXT_COLOR};
margin-left: 4px;
margin-right: 4px;
}
.react-datepicker__day--selected {
border-radius: 24px;
background-color: ${COLORS.LIGHT_BLUE};
color: ${COLORS.LIGHT_PRIMARY_TEXT_COLOR};
}
.react-datepicker__day:hover {
border-radius: 24px;
}
.react-datepicker__time-list-item--selected {
background-color: ${COLORS.LIGHT_BLUE} !important;
.react-datepicker__time-container
.react-datepicker__time
.react-datepicker__time-box
ul.react-datepicker__time-list
li.react-datepicker__time-list-item--selected {
background-color: ${COLORS.LIGHT_BLUE};
font-weight: 600;
}
.react-datepicker__week {
Expand All @@ -85,57 +85,75 @@ const [_, theme] = createThemeTag('dateInput', ({ COLORS }: *) => ({
.react-datepicker__header--time {
border-bottom: 1px solid ${COLORS.PRIMARY_BORDER_COLOR};
height: 32px;
}
.react-datepicker-time__header {
font-size: 12px;
font-family: Poppins;
color: ${COLORS.PRIMARY_TEXT_COLOR};
font-weight: 600;
}
.react-datepicker__day--today {
font-size: 12px;
font-family: Poppins;
color: ${COLORS.PRIMARY_TEXT_COLOR};
font-weight: 600;
}
.react-datepicker__day--selected {
border-radius: 24px;
background-color: ${COLORS.LIGHT_BLUE};
color: ${COLORS.LIGHT_PRIMARY_TEXT_COLOR};
}
.react-datepicker__today-button {
position: absolute;
bottom: 0;
width: 100%;
height: 32px;
font-size: 12px;
font-family: Poppins;
color: ${COLORS.PRIMARY_TEXT_COLOR};
font-weight: 600;
border-top: 1px solid ${COLORS.PRIMARY_BORDER_COLOR};
}
.react-datepicker__header {
padding: 0;
height: 64px;
border-bottom: 1px solid ${COLORS.PRIMARY_BORDER_COLOR};
padding-top: 6px;
}
.react-datepicker__day-names {
height: 32px;
font-size: 12px;
display: flex;
border-bottom: 1px solid ${COLORS.PRIMARY_BORDER_COLOR};
margin-top: 6px;
}
.react-datepicker__current-month {
.react-datepicker-year-header {
padding-bottom: 6px;
}
.react-datepicker__current-month,
.react-datepicker-year-header {
font-size: 13px;
font-weight: 600;
font-family: Poppins;
color: ${COLORS.PRIMARY_TEXT_COLOR};
}
.react-datepicker__month-wrapper {
display: flex;
}
.react-datepicker__month-text {
flex: 1;
padding: 6px 0;
}
.react-datepicker__month--selected,
.react-datepicker__month--in-selecting-range,
.react-datepicker__month--in-range {
background-color: ${COLORS.LIGHT_BLUE};
color: ${COLORS.LIGHT_PRIMARY_TEXT_COLOR};
}
.react-datepicker__time-list-item {
align-items: center;
display: flex;
font-size: 12px;
height: 32px !important;
justify-content: center;
padding: 0 !important;
Expand All @@ -145,7 +163,6 @@ const [_, theme] = createThemeTag('dateInput', ({ COLORS }: *) => ({
.react-datepicker__current-month {
align-items: center;
display: flex;
height: 32px;
justify-content: center;
padding: 0;
}
Expand Down
10 changes: 6 additions & 4 deletions src/components/DateInput/DateInput.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

import { DateTime } from 'luxon';

export const YEAR_MONTH_MASK = '99/9999';
export const DATE_MASK = '99/99/9999';
export const DATETIME_MASK = '99/99/9999, 99:99 aa';

export const YEAR_MONTH_FORMAT = 'MM/yyyy';
export const DATE_FORMAT = 'MM/dd/yyyy';
export const DATETIME_FORMAT = 'MM/dd/yyyy, hh:mm a';

export const fromISOToViewFormat = (value: ?string, withTime: ?boolean) => {
export const fromISOToViewFormat = (value: ?string, dateFormat: ?string) => {
if (value) {
value = DateTime.fromISO(value);

if (value.isValid) {
value = value.toFormat(withTime ? DATETIME_FORMAT : DATE_FORMAT);
value = value.toFormat(dateFormat || DATE_FORMAT);
} else {
value = '';
}
Expand Down Expand Up @@ -52,9 +54,9 @@ export const fromJSDateToISO = (value: ?Date, withTime: ?boolean) => {
return value;
};

export const fromViewFormatToLuxon = (value: ?string, withTime: ?boolean) => {
export const fromViewFormatToLuxon = (value: ?string, dateFormat: ?string) => {
if (value) {
value = DateTime.fromFormat(value, withTime ? DATETIME_FORMAT : DATE_FORMAT);
value = DateTime.fromFormat(value, dateFormat || DATE_FORMAT);
} else {
value = null;
}
Expand Down

0 comments on commit c18aaf3

Please sign in to comment.