Skip to content

Commit

Permalink
[KOA-4741]: Enable calendar range support (Skyscanner#2268)
Browse files Browse the repository at this point in the history
* [skip ci][KOA-4741]: Adding calendar range support

* [KOA-4759]: Add new props to support ranges (Skyscanner#2269)

* [KOA 4760] range logic implementation (Skyscanner#2280)

* [KOA-4759]: Add new props to support ranges (Skyscanner#2269)

* [KOA-4760]: Add range logic implementation to calendar

* [KOA-4761]: Implement range styles (Skyscanner#2282)

* [KOA-4761]: Implement range styles for Calendar

* [KOA-4761]: Updating snapshots for calendar and adjusting regex

* Fixing widths being of fixed size

* [KOA-4761]: Cleaning up changes as part of range implementation (Skyscanner#2289)

* [KOA-4761]: Implement range styles for Calendar

* [KOA-4761]: Updating snapshots for calendar and adjusting regex

* Fixing widths being of fixed size

* [KOA-4761]: Cleaning up changes as part of range implementation

* Adding updated snapshot tests
  • Loading branch information
olliecurtis authored Nov 15, 2021
1 parent 0c3af4c commit 04e8372
Show file tree
Hide file tree
Showing 58 changed files with 4,065 additions and 2,786 deletions.
10 changes: 10 additions & 0 deletions .spelling
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ BORDER_RADIUS_STYLES.none
BORDER_RADIUS_STYLES.sm
borderlessBackground
buttonType
CALENDAR_SELECTION_TYPE.single
cellType
CELL_TYPES
CELL_TYPES.default
Expand Down Expand Up @@ -378,6 +379,12 @@ RATING_TYPES.default
RATING_TYPES.pill
renderFlag
renderTarget
rowType
ROW_TYPES.start
ROW_TYPES.middle
ROW_TYPES.end
ROW_TYPES.both
selectionConfiguration
selectedDates
selectedId
selectedIndex
Expand All @@ -387,6 +394,9 @@ SELECTION_TYPES
SELECTION_TYPES.single
SELECTION_TYPES.multiple
SELECTION_TYPES.range
SELECTION_TYPES.start
SELECTION_TYPES.middle
SELECTION_TYPES.end
showIndicator
showTitle
showUnderline
Expand Down
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.
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.
2 changes: 1 addition & 1 deletion .storybook/storyshots-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const getMatchOptions = () => ({

initStoryshots({
suite: 'Visual tests',
storyNameRegex: /Visual\stest$/i,
storyNameRegex: /Visual\stest\s?([a-z]*)?/i,
test: imageSnapshot({
storybookUrl: `file://${path.resolve(__dirname, '../dist-storybook')}`,
getMatchOptions,
Expand Down
30 changes: 30 additions & 0 deletions UNRELEASED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
**Breaking:**

- bpk-component-calendar:
- bpk-component-datepicker:
- bpk-component-scrollable-calendar:
- Added range support to BpkCalendar
- Added new `selectionConfiguration` property to Backpack calendar to allow for range support.
- `selectedDate` has been deprecated in favour of `selectionConfiguration`. instead of passing `selectedDate` you would now provide the following
```js
selectedConfiguration: {
type: CALENDAR_SELECTION_TYPE.single,
date: new Date() // or the value you passed to `selectedDate`.
}
```
- `selectionStart` and `selectionEnd` has been deprecated in favour of `selectionConfiguration`. instead of passing `selectionStart` and `selectionEnd` you would now provide the following
```js
selectedConfiguration: {
type: CALENDAR_SELECTION_TYPE.range,
startDate: new Date() // or the value you passed to `selectionStart`.
endDate: new Date() // or the value you passed to `selectionEnd`.
}
```
- Added styles to support range logic.
- Updated calendar to Figma styles.
- `showWeekendSeparator` prop has now been deprecated as its no longer part of the calendar design so can be removed.

**Fixed:**

- bpk-component-scrollable-calendar:
- Fixed a reintroduced functionality of auto scrolling the calendar when a date is clicked, when the library was changed from `react-window` to `react-virtualized`
59 changes: 47 additions & 12 deletions packages/bpk-component-calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,20 @@ export default class App extends Component {
constructor () {
super();


this.state = {
selectedDate: null
}
selectionConfiguration: {
type: CALENDAR_SELECTION_TYPE.single,
date: null,
}
};
}

handleDateSelect = (date) => {
this.setState({
selectedDate: date
selectionConfiguration: {
type: this.props.selectionConfiguration.type,
date: date,
},
});
}

Expand All @@ -51,7 +56,7 @@ export default class App extends Component {
id='dateInput'
type={INPUT_TYPES.text}
name='date'
value={(this.state.selectedDate || '').toString()}
value={(this.state.selectionConfiguration.date || '').toString()}
placeholder='Departure date'
/>
<BpkCalendar
Expand All @@ -64,7 +69,7 @@ export default class App extends Component {
changeMonthLabel="Change month"
nextMonthLabel="Next month"
previousMonthLabel="Previous month"
date={this.state.selectedDate}
selectionConfiguration={this.state.selectionConfiguration}
/>
</div>
)
Expand Down Expand Up @@ -172,8 +177,7 @@ withCalendarState(composeCalendar(
| minDate | Date | false | new Date() |
| onDateSelect | func | false | null |
| onMonthChange | func | false | null |
| selectedDate | Date | false | null |
| showWeekendSeparator | bool | false | true |
| selectionConfiguration| object | false | { type: CALENDAR_SELECTION_TYPE.single, date: null } |
| navProps | object | false | null |
| headerProps | object | false | null |
| gridProps | object | false | null |
Expand Down Expand Up @@ -208,10 +212,8 @@ in place while the rest of the grid transitions when changing months.

| Property | PropType | Required | Default Value |
| --------------------- | -------------------- | -------- | ---------------- |
| showWeekendSeparator | bool | true | - |
| daysOfWeek | object | true | - |
| weekStartsOn | number | true | - |
| showWeekendSeparator | bool | false | false |
| className | string | false | null |
| weekDayKey | string | false | nameAbbr |

Expand All @@ -227,6 +229,7 @@ The BpkCalendarGrid component displays a month as a table.
| formatMonth | func | true | - |
| month | Date | true | - |
| weekStartsOn | number | true | - |
| selectionConfiguration| object | false | { type: CALENDAR_SELECTION_TYPE.single, date: null } |
| focusedDate | Date | false | null |
| isKeyboardFocusable | bool | false | true |
| markOutsideDays | bool | false | true |
Expand All @@ -236,8 +239,6 @@ The BpkCalendarGrid component displays a month as a table.
| onDateClick | func | false | null |
| onDateKeyDown | func | false | null |
| preventKeyboardFocus | bool | false | false |
| selectedDate | Date | false | null |
| showWeekendSeparator | bool | false | true |

### BpkCalendarDate

Expand All @@ -257,6 +258,8 @@ The BpkCalendarDate component is used to render the content of a cell
| onClick | func | false | null |
| onDateKeyDown | func | false | null |
| preventKeyboardFocus | bool | false | true |
| rowType | oneOf(ROW_TYPES.start, ROW_TYPES.middle, ROW_TYPES.end, ROW_TYPES.both) | false | null |
| selectionType | oneOf(SELECTION_TYPES.single, SELECTION_TYPES.start, SELECTION_TYPES.middle, SELECTION_TYPES.end) | false | SELECTION_TYPES.single |
| style | object | false | null |

#### `cellType` prop
Expand All @@ -268,8 +271,40 @@ This prop determines what the colour date cell is to be displayed.
- `CELL_TYPES.negative` - sets the calendar cell to `Panjin`
- `CELL_TYPES.default` - sets the calendar cell to `Sky Gray Tint 02`

#### `selectionType` prop

This property determines which selected styles will be applied to the date cell. If using ranges use `start`, `middle` and `end` to apply the correct range styles.

- `SELECTION_TYPES.single` - When the date is selected individually i.e. Not as part of a range
- `SELECTION_TYPES.start` - When a start date is selected in a range calendar i.e. First date in the range
- `SELECTION_TYPES.middle` - When a date is in a range between start and end date i.e. Date in the middle of two dates
- `SELECTION_TYPES.end` - When an end date is selected in a range calendar i.e. Last date in the range

### Prop details

#### selectionConfiguration

An object to indicate which configuration of the calendar is being used. Choices are `single` date selection or `range` date selection.

##### Single date

```json
{
type: CALENDAR_SELECTION_TYPE.single,
date: date e.g. new Date()
}
```

##### Range

```json
{
type: CALENDAR_SELECTION_TYPE.range,
startDate: date e.g. new Date(),
endDate: date e.g. new Date()
}
```

#### daysOfWeek

An array of objects describing the days of the week:
Expand Down
23 changes: 18 additions & 5 deletions packages/bpk-component-calendar/coloured-calendar-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import {
CELL_TYPES,
composeCalendar,
withCalendarState,
CustomPropTypes,
CALENDAR_SELECTION_TYPE,
} from './index';

const prices = [
Expand Down Expand Up @@ -90,22 +92,28 @@ class ColoredCalendar extends Component {
constructor(props) {
super(props);

const date = this.props.selectTodaysDate ? new Date() : null;

this.state = {
date,
selectionConfiguration: {
type: CALENDAR_SELECTION_TYPE.single,
date: new Date(),
},
};
}

render() {
return (
<StatefulCalendar
{...this.props}
selectedDate={this.state.date}
onDateSelect={date => {
this.setState({ date });
this.setState({
selectionConfiguration: {
type: this.props.selectionConfiguration.type,
date,
},
});
action('Selected day')(date);
}}
selectionConfiguration={this.state.selectionConfiguration}
onMonthChange={action('Changed month')}
/>
);
Expand All @@ -114,10 +122,15 @@ class ColoredCalendar extends Component {

ColoredCalendar.propTypes = {
selectTodaysDate: PropTypes.bool,
selectionConfiguration: CustomPropTypes.SelectionConfiguration,
};

ColoredCalendar.defaultProps = {
selectTodaysDate: true,
selectionConfiguration: {
type: CALENDAR_SELECTION_TYPE.single,
date: new Date(),
},
};

export default ColoredCalendar;
86 changes: 84 additions & 2 deletions packages/bpk-component-calendar/examples-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
colorSkyGrayTint04,
colorMonteverde,
} from '@skyscanner/bpk-foundations-web/tokens/base.es6';
import { action } from 'bpk-storybook-utils';

import { withButtonAlignment, withRtlSupport } from '../bpk-component-icon';
import SmallLongArrowRightIcon from '../bpk-component-icon/sm/long-arrow-right';
Expand All @@ -37,11 +38,13 @@ import SmallLongArrowLeftIcon from '../bpk-component-icon/sm/long-arrow-left';
import { dateToBoundaries, startOfDay, addDays } from './src/date-utils';
import { formatMonth, formatDateFull, weekDays } from './test-utils';

import {
import BpkCalendar, {
BpkCalendarGrid,
BpkCalendarGridHeader,
withCalendarState,
composeCalendar,
CustomPropTypes,
CALENDAR_SELECTION_TYPE,
} from './index';

const LeftIcon = withButtonAlignment(withRtlSupport(SmallLongArrowLeftIcon));
Expand Down Expand Up @@ -245,4 +248,83 @@ MonthViewCalendar.defaultProps = {
returnDate: startOfDay(addDays(new Date(), 4)),
};

export default MonthViewCalendar;
class CalendarContainer extends Component {
constructor(props) {
super(props);

if (this.props.selectionConfiguration.type === 'range') {
this.state = {
selectionConfiguration: {
type: this.props.selectionConfiguration.type,
startDate: this.props.selectionConfiguration.startDate,
endDate: this.props.selectionConfiguration.endDate,
},
};
} else {
this.state = {
selectionConfiguration: {
type: this.props.selectionConfiguration.type,
date: this.props.selectionConfiguration.date,
},
};
}
}

render() {
return (
<BpkCalendar
{...this.props}
onDateSelect={(startDate, endDate = null) => {
if (this.props.selectionConfiguration.type === 'range') {
if (startDate && !endDate) {
this.setState({
selectionConfiguration: {
type: this.props.selectionConfiguration.type,
startDate,
endDate: null,
},
});
action('Selected day')(startDate);
}
if (startDate && endDate) {
this.setState({
selectionConfiguration: {
type: this.props.selectionConfiguration.type,
startDate,
endDate,
},
});
action('Selected end day')(endDate);
}
} else {
this.setState({
selectionConfiguration: {
type: this.props.selectionConfiguration.type,
date: startDate,
},
});
action('Selected day')(startDate);
}
}}
selectionConfiguration={this.state.selectionConfiguration}
onMonthChange={action('Changed month')}
/>
);
}
}

CalendarContainer.propTypes = {
selectTodaysDate: PropTypes.bool,
selectionConfiguration: CustomPropTypes.SelectionConfiguration,
};

CalendarContainer.defaultProps = {
selectTodaysDate: true,
selectionConfiguration: {
type: CALENDAR_SELECTION_TYPE.single,
date: null,
},
};

export default CalendarContainer;
export { MonthViewCalendar };
Loading

0 comments on commit 04e8372

Please sign in to comment.