Skip to content

Commit

Permalink
feat(DateTimePicker): Add DateTimePicker component
Browse files Browse the repository at this point in the history
  • Loading branch information
MariaAga committed Apr 17, 2019
1 parent 30204e4 commit 08ab016
Show file tree
Hide file tree
Showing 50 changed files with 4,742 additions and 0 deletions.
70 changes: 70 additions & 0 deletions packages/patternfly-3/patternfly-react/less/_date-time-picker.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.bootstrap-datetimepicker-widget.date-time-picker-pf.top {
margin-top: -10px;
}

.bootstrap-datetimepicker-widget.date-time-picker-pf.bottom {
margin-top: 10px !important;
}

.bootstrap-datetimepicker-widget.date-picker-pf,
.bootstrap-datetimepicker-widget.date-time-picker-pf {
max-width: none;

.arrow {
left: 10% !important;
}

.popover-content {
color: $color-pf-black-900;
padding: 0;
}

.clock-btn {
border: 0;
box-shadow: none;
color: #363636;
display: block;
padding-bottom: 4px;
padding-top: 4px;
}

table td {
.today-button {
padding: 0 16px 0 0;
border: 0;
background-color: transparent;

span {
height: 24px;
line-height: 24px;
color: @color-pf-blue-400;
}
}
}

&.bootstrap-timepicker-widget {
width: 16em;

.popover-content {
padding-left: 0;
}
}

&.date-picker-pf {
.popover-content {
padding: 10px;
}
}

.timepicker {
table td {
height: initial;
line-height: initial;
}
}

.timepicker-hours .table-condensed>tbody>tr>td,
.timepicker-minutes .table-condensed>tbody>tr>td {
padding: 7px 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
.bootstrap-datetimepicker-widget.date-time-picker-pf.top {
margin-top: -10px;
}

.bootstrap-datetimepicker-widget.date-time-picker-pf.bottom {
margin-top: 10px !important;
}

.bootstrap-datetimepicker-widget.date-picker-pf,
.bootstrap-datetimepicker-widget.date-time-picker-pf {
max-width: none;

.arrow {
left: 10% !important;
}

.popover-content {
color: $color-pf-black-900;
padding: 0;
}

.clock-btn {
border: 0;
box-shadow: none;
color: #363636;
display: block;
padding-bottom: 4px;
padding-top: 4px;
}

table td {
.today-button {
padding: 0 16px 0 0;
border: 0;
background-color: transparent;

span {
height: 24px;
line-height: 24px;
color: $color-pf-blue-400;
}
}
}

&.bootstrap-timepicker-widget {
width: 16em;

.popover-content {
padding-left: 0;
}
}

&.date-picker-pf {
.popover-content {
padding: 10px;
}
}

.datepicker tr td span {
height: 53px;
}

.timepicker {
table td {
height: initial;
line-height: initial;
}
}

.timepicker-hours .table-condensed>tbody>tr>td,
.timepicker-minutes .table-condensed>tbody>tr>td {
padding: 7px 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
@import 'login-page';
@import 'dual-list-selector';
@import 'breadcrumbswitcher-popover';
@import 'date-time-picker';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const YEAR = 'YEAR';
export const MONTH = 'MONTH';
export const DAY = 'DAY';
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { addMonths } from './helpers';
import MonthView from './MonthView';
import YearView from './YearView';
import DecadeView from './DecadeView';

class DateInput extends React.Component {
state = {
selectedDate: new Date(this.props.date),
date: new Date(this.props.date),
typeOfDateInput: this.props.typeOfDateInput
};
static getDerivedStateFromProps(nextProps, prevState) {
const nextDate = new Date(nextProps.date);
const prevDate = new Date(prevState.selectedDate);
const nextType = new Date(nextProps.date);
return Date.parse(nextDate) === Date.parse(prevDate)
? null
: {
selectedDate: nextDate,
date: nextDate,
typeOfDateInput: nextType
};
}
getPrevMonth = () => {
const { date } = this.state;
this.setState({ date: addMonths(date, -1) });
};
getNextMonth = () => {
const { date } = this.state;
this.setState({ date: addMonths(date, 1) });
};
setSelected = day => {
this.setState({
selectedDate: day,
date: day
});
this.props.setSelected(day);
};
toggleDateView = (type = null) => {
this.setState({
typeOfDateInput: type
});
};
getDateViewByType = type => {
const { date, locale, weekStartsOn, setSelected } = this.props;
const parsedDate = Date.parse(date) ? date : new Date();
switch (type) {
case 'D':
return <DecadeView date={parsedDate} setSelected={setSelected} toggleDateView={this.toggleDateView} />;
case 'Y':
return (
<YearView date={parsedDate} setSelected={setSelected} locale={locale} toggleDateView={this.toggleDateView} />
);
default:
return (
<MonthView
date={parsedDate}
setSelected={setSelected}
locale={locale}
weekStartsOn={weekStartsOn}
toggleDateView={this.toggleDateView}
/>
);
}
};
render() {
const { className } = this.props;
const { typeOfDateInput } = this.state;
return <div className={classNames('datepicker', className)}>{this.getDateViewByType(typeOfDateInput)}</div>;
}
}

DateInput.propTypes = {
date: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
setSelected: PropTypes.func,
locale: PropTypes.string,
weekStartsOn: PropTypes.number,
className: PropTypes.string,
typeOfDateInput: PropTypes.string
};

DateInput.defaultProps = {
setSelected: null,
date: new Date(),
locale: 'en-US',
weekStartsOn: 1,
className: '',
typeOfDateInput: 'M'
};
export default DateInput;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { mount, shallow } from 'enzyme';
import DateInput from './DateInput';
import { isEqualDate } from './helpers';

test('DateInput is working properly', () => {
const component = mount(<DateInput date="1/21/2019, 2:22:31 PM" />);

expect(component.render()).toMatchSnapshot();
});

test('DateInput changes selected on click', () => {
const setSelected = jest.fn();
const component = mount(<DateInput date="1/21/2019, 2:22:31 PM" setSelected={setSelected} />);
component
.find('.weekend')
.first()
.simulate('click');
expect(setSelected).toBeCalledWith(new Date('2019-01-04 14:22:31'));
});

test('DateInput toggles view to years', () => {
const component = mount(<DateInput date="1/21/2019, 2:22:31 PM" />);
component
.find('.picker-switch')
.first()
.simulate('click');
expect(component.render()).toMatchSnapshot();
});
test('DateInput toggles view to decades', () => {
const component = mount(<DateInput date="1/21/2019, 2:22:31 PM" />);
component
.find('.picker-switch')
.first()
.simulate('click');
component
.find('.picker-switch')
.first()
.simulate('click');
expect(component.render()).toMatchSnapshot();
});

test('DateInput is working properly with wrong date format', () => {
const component = shallow(<DateInput date="ABC" />);
expect(isEqualDate(component.get(0).props.children.props.date, new Date())).toBeTruthy();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

const Day = ({ day, setSelected, classNamesArray }) => {
const date = day.getDate();
return (
<td
className={classNames('day', classNamesArray)}
data-day={date}
onClick={() => {
setSelected(day);
}}
>
{date}
</td>
);
};

Day.propTypes = {
day: PropTypes.instanceOf(Date).isRequired,
classNamesArray: PropTypes.object,
setSelected: PropTypes.func
};

Day.defaultProps = {
setSelected: null,
classNamesArray: []
};
export default Day;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { mount } from 'enzyme';
import Day from './Day';

test('Day is working properly', () => {
const day = new Date('2019-01-04 14:22:31');
const currDate = new Date('2019-01-02 12:22:31');
const selectedDate = new Date('2019-01-05 18:22:31');
const component = mount(
<table>
<tbody>
<tr>
<Day day={day} currDate={currDate} selectedDate={selectedDate} classNamesArray={{ weekend: true }} />
</tr>
</tbody>
</table>
);

expect(component.render()).toMatchSnapshot();
});
Loading

0 comments on commit 08ab016

Please sign in to comment.