Skip to content

Commit 37f08e4

Browse files
authored
Merge pull request #56 from KainosSoftwareLtd/feature/IMTA-12974-show-calendar-plainly-automatically
Auto scroll to show calendar in full when opened
2 parents c77309c + 0413bb8 commit 37f08e4

File tree

5 files changed

+75
-1
lines changed

5 files changed

+75
-1
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,19 @@ datePicker(selector, {
171171
});
172172
```
173173

174+
### autoScroll
175+
176+
Type: boolean
177+
178+
Can be set to `true` to let the window scroll automatically to show the calendar in full when opened. False by default.
179+
180+
Using it in your code:
181+
```javascript
182+
datePicker(selector, {
183+
autoScroll: true,
184+
});
185+
```
186+
174187
## Callbacks
175188

176189
The datepicker currently supports the following optional callbacks

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"dist",
77
"src/scss/datepicker.scss"
88
],
9-
"version": "1.2.0",
9+
"version": "1.3.0",
1010
"description": "GOV.UK datepicker",
1111
"scripts": {
1212
"build": "webpack --config ./bin/webpack.dev.js",

src/__tests__/datepicker.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-param-reassign */
12
import $ from 'jquery';
23
import { DateTime } from 'luxon';
34

@@ -52,6 +53,7 @@ describe('Date picker', () => {
5253

5354
afterEach(() => {
5455
document.body.innerHTML = '';
56+
window.innerHeight = 768;
5557
});
5658

5759
describe('Initialisation', () => {
@@ -1085,4 +1087,43 @@ describe('Date picker', () => {
10851087
expect(expectedDate.getFullYear()).toEqual(today.getFullYear());
10861088
});
10871089
});
1090+
1091+
describe('Auto scroll', () => {
1092+
it('should not attempt to scroll calendar into view if autoScroll is set to false and calendar is not in view', () => {
1093+
testScrollsCalendarIntoView(false, false, 0);
1094+
});
1095+
1096+
it('should not scroll calendar into view if autoScroll is set to true but calendar is already in view', () => {
1097+
testScrollsCalendarIntoView(true, true, 0);
1098+
});
1099+
1100+
it('should scroll calendar into view if autoScroll is set to true and calendar is not in view', () => {
1101+
testScrollsCalendarIntoView(true, false, 1);
1102+
});
1103+
1104+
const testScrollsCalendarIntoView = (isAutoScrollOn, isInView, expectedScrolls) => {
1105+
datePicker(document.querySelector('.date-picker'), {
1106+
autoScroll: isAutoScrollOn,
1107+
});
1108+
1109+
const revealButton = document.querySelector('.date-picker__reveal');
1110+
const calendar = document.querySelector('.date-picker__dialog');
1111+
calendar.scrollIntoView = jest.fn();
1112+
positionCalendarInViewport(calendar, isInView);
1113+
1114+
$(revealButton).trigger('click');
1115+
1116+
expect(calendar.scrollIntoView.mock.calls.length).toBe(expectedScrolls);
1117+
};
1118+
1119+
const positionCalendarInViewport = (calendar, isInView) => {
1120+
calendar.getBoundingClientRect = () => ({
1121+
bottom: 100,
1122+
top: 100,
1123+
left: 100,
1124+
right: 100,
1125+
});
1126+
window.innerHeight = (isInView === true) ? 110 : 90;
1127+
};
1128+
});
10881129
});

src/demo.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ datePicker(document.querySelector('.date-picker-welsh'), {
2929

3030
datePicker(document.querySelector('.date-picker-style-two'), {
3131
theme: 'digital-scotland',
32+
autoScroll: true,
3233
});
3334

3435
datePicker(document.querySelector('.date-picker-icon'), {

src/js/datepicker.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,9 +542,28 @@ function datePicker(datePickerElement, options = {}, callbacks = {}) {
542542
setFocusDay(getDateFromInputs());
543543
showCalender();
544544
renderDOM();
545+
scrollCalendarIntoView();
545546
preventDefault = true;
546547
}
547548

549+
function scrollCalendarIntoView() {
550+
if (options.autoScroll === true) {
551+
const calendar = elements.dialog;
552+
if (!elementInViewport(calendar)) {
553+
calendar.scrollIntoView(false);
554+
}
555+
}
556+
}
557+
558+
function elementInViewport(element) {
559+
const bounding = element.getBoundingClientRect();
560+
561+
return bounding.top >= 0
562+
&& bounding.left >= 0
563+
&& bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
564+
&& bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight);
565+
}
566+
548567
switch (event.type) {
549568
case 'keydown':
550569
switch (event.keyCode) {

0 commit comments

Comments
 (0)