Skip to content

'DateSelector' #161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
10,270 changes: 1,100 additions & 9,170 deletions .jest-test-results.json

Large diffs are not rendered by default.

18 changes: 11 additions & 7 deletions lib/components/atoms/Select/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ const Select = ({
disabled={disabled}
data-locator={elementLocator || `select-input-${name}-${id}`}
>
{placeholder && <option value="">{placeholder}</option>}
{options.map((opt) => (
<option key={opt} value={opt}>
{placeholder && (
<option value="" disabled selected>
{placeholder}
</option>
)}
{options.map((opt, index) => (
<option key={`${name}_${index.toString()}`} value={opt}>
{opt}
</option>
))}
Expand All @@ -46,10 +50,10 @@ const Select = ({

Select.defaultProps = {
disabled: false,
selectedOption: '',
placeholder: '',
className: '',
elementLocator: '',
selectedOption: null,
placeholder: 'Select',
className: 'select',
elementLocator: null,
};

const StyledSelect: ComponentType<Props> = styled(Select)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exports[`Select Styled component should render correctly 1`] = `
<select
className=""
className="select"
data-locator="select-input-userType-undefined"
disabled={false}
name="userType"
Expand Down Expand Up @@ -304,16 +304,23 @@ exports[`Select Styled component should render correctly 1`] = `
},
}
}
value=""
value={null}
>
<option
key="Option 1"
disabled={true}
selected={true}
value=""
>
Select
</option>
<option
key="userType_0"
value="Option 1"
>
Option 1
</option>
<option
key="Option 2"
key="userType_1"
value="Option 2"
>
Option 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,29 @@

exports[`Select Component should render correctly 1`] = `
<select
className=""
className="select"
data-locator="my-custom-select-locator"
disabled={false}
id="dropdown-1"
name="my-drop"
onChange={[Function]}
value=""
value={null}
>
<option
key="Option 1"
disabled={true}
selected={true}
value=""
>
Select
</option>
<option
key="my-drop_0"
value="Option 1"
>
Option 1
</option>
<option
key="Option 2"
key="my-drop_1"
value="Option 2"
>
Option 2
Expand Down
171 changes: 171 additions & 0 deletions lib/components/molecules/Form/FieldDateSelector/FieldDateSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// @flow
/**
*
* FieldDateSelector
*
*/
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';

import classNames from 'classnames';
import styles from './FieldDateSelector.style';
import type { Props } from './types';
import Select from '../FieldSelect';

const FieldDateSelector = ({
id,
className,
format,
startDate,
endDate,
locale,
dateLabel,
monthLabel,
yearLabel,
}: Props): Node => {
const [selectedDay, setSelectedDay] = useState(new Date().getDate());
const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth());
const [selectedYear, setSelectedYear] = useState(new Date().getFullYear());
const [months, setMonths] = useState([]);

const monthsList = () => {
const date = new Date();
const monthsOptions = [];
for (let i = 0; i < 12; i += 1) {
date.setMonth(i);
monthsOptions.push(date.toLocaleString(locale, { month: 'long' }));
}
return monthsOptions;
};

useEffect(() => {
setMonths(monthsList());
}, []);

useEffect(() => {
setSelectedDay(startDate.getDate());
setSelectedMonth(startDate.getMonth());
setSelectedYear(startDate.getFullYear());
}, [startDate, endDate]);

const range = (start, end, step) => {
const arr = [];
for (let i = start; i <= end; i += step) {
arr.push(i);
}
return arr;
};

const getDay = (date, type) => {
const day = type === 'start' ? 1 : new Date(selectedYear, selectedMonth + 1, 0).getDate();
if (Number(selectedMonth) === date.getMonth() && Number(selectedYear) === date.getFullYear()) {
return date.getDate();
}
return day;
};

const getMonth = (date, type) => {
const month = type === 'start' ? 0 : months.length - 1;
if (Number(selectedYear) === date.getFullYear()) {
return date.getMonth();
}
return month;
};

const getDaysInMonth = () => {
const startDay = getDay(startDate, 'start');
const endDay = getDay(endDate, 'end');
return range(startDay, endDay, 1);
};

const getMonthOptions = () => {
let monthOptions = [...months];
const startMonth = getMonth(startDate, 'start');
const endMonth = getMonth(endDate, 'end');
monthOptions = monthOptions.slice(startMonth, endMonth + 1);
return monthOptions;
};

const getYearOptions = () => {
return range(startDate.getFullYear(), endDate.getFullYear(), 1);
};

const DaySelector = (
<>
<Select
onChange={(e) => {
return setSelectedDay(e.target.value);
}}
id={`${id}-day`}
name="day"
label={dateLabel}
className={`${classNames('date', className)} date-selector-field`}
selectedOption={selectedDay}
options={getDaysInMonth()}
/>
</>
);

const MonthSelector = (
<>
<Select
onChange={(e) => {
return setSelectedMonth(months.indexOf(e.target.value));
}}
id={`${id}-month`}
name="month"
label={monthLabel}
className={`${classNames('Month', className)} date-selector-field`}
selectedOption={months[selectedMonth]}
options={getMonthOptions()}
/>
</>
);

const YearSelector = (
<>
<Select
onChange={(e) => {
return setSelectedYear(e.target.value);
}}
id={`${id}-year`}
name="year"
label={yearLabel}
className={`${classNames('year', className)} date-selector-field`}
selectedOption={selectedYear}
options={getYearOptions()}
/>
</>
);

const renderSelector = (value) => {
switch (value.toLowerCase()) {
case 'mmddyy':
case 'mmddyyyy':
return [MonthSelector, DaySelector, YearSelector];
case 'mmyy':
case 'mmyyyy':
return [MonthSelector, YearSelector];
case 'ddmmyy':
case 'ddmmyyyy':
default:
return [DaySelector, MonthSelector, YearSelector];
}
};
return <div className={className}>{renderSelector(format)}</div>;
};

FieldDateSelector.defaultProps = {
id: 'date-selector',
className: 'date-selector',
format: 'ddmmyy',
startDate: new Date(),
endDate: new Date(new Date().setFullYear(new Date().getFullYear() + 50)),
locale: 'default',
};

export default styled(FieldDateSelector)`
${styles};
`;

export { FieldDateSelector as FieldDateSelectorVanilla };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { css } from 'styled-components';

export default css`
.date-selector-field {
display: inline-block;
padding: 0 5px;
}
${(props) => (props.inheritedStyles ? props.inheritedStyles : '')};
`;
3 changes: 3 additions & 0 deletions lib/components/molecules/Form/FieldDateSelector/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @flow
export { default } from './FieldDateSelector';
export { FieldDateSelectorVanilla } from './FieldDateSelector';
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import { shallow } from 'enzyme';

import { FieldDateSelectorVanilla } from '../index';

import Select from '../../FieldSelect';

describe('<FieldDateSelector />', () => {
let FieldDateSelectorComponent = '';
beforeEach(() => {
FieldDateSelectorComponent = shallow(<FieldDateSelectorVanilla />);
});

test('should render correctly', () => {
expect(FieldDateSelectorComponent).toMatchSnapshot();
});

test('should render the 3 Select Components(date month and year)', () => {
FieldDateSelectorComponent.setProps({
format: 'ddmmyy',
});
expect(FieldDateSelectorComponent.find(Select)).toHaveLength(3);
});

test('should render the 3 Select Components(date month and year)', () => {
FieldDateSelectorComponent.setProps({
format: 'ddmmyyyy',
});
expect(FieldDateSelectorComponent.find(Select)).toHaveLength(3);
});

test('should render the 3 Select Components(month date and year)', () => {
FieldDateSelectorComponent.setProps({
format: 'mmddyy',
});
expect(FieldDateSelectorComponent.find(Select)).toHaveLength(3);
});

test('should render the 3 Select Components(month date and year)', () => {
FieldDateSelectorComponent.setProps({
format: 'mmddyyyy',
});
expect(FieldDateSelectorComponent.find(Select)).toHaveLength(3);
});

test('should render the 2 Select Components(month and year selectors)', () => {
FieldDateSelectorComponent.setProps({
format: 'mmyy',
});
expect(FieldDateSelectorComponent.find(Select)).toHaveLength(2);
});

test('should render the 2 Select Components(month and year selectors)', () => {
FieldDateSelectorComponent.setProps({
format: 'mmyyyy',
});
expect(FieldDateSelectorComponent.find(Select)).toHaveLength(2);
});
});
Loading