Skip to content

Commit

Permalink
Calendar bugfixes (#543)
Browse files Browse the repository at this point in the history
  • Loading branch information
smhigley authored May 1, 2018
1 parent b463499 commit ed1e664
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 28 deletions.
17 changes: 11 additions & 6 deletions src/calendar/DatePicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export class DatePickerBase<P extends DatePickerProperties = DatePickerPropertie
event.which === Keys.Enter ||
event.which === Keys.Space
) {
event.preventDefault();
this._monthPopupOpen && this._closeMonthPopup();
this._yearPopupOpen && this._closeYearPopup();
}
Expand Down Expand Up @@ -216,18 +217,20 @@ export class DatePickerBase<P extends DatePickerProperties = DatePickerPropertie

return this.properties.monthNames.map((monthName, i) => v('label', {
key: `${this._idBase}_month_radios_${i}`,
classes: this.theme([ css.monthRadio, i === month ? css.monthRadioChecked : null ])
classes: this.theme([ css.monthRadio, i === month ? css.monthRadioChecked : null ]),
for: this._getMonthInputKey(i),
onmouseup: this._closeMonthPopup
}, [
v('input', {
checked: i === month,
classes: this.theme(css.monthRadioInput),
id: this._getMonthInputKey(i),
key: this._getMonthInputKey(i),
name: `${this._idBase}_month_radios`,
tabIndex: this._monthPopupOpen ? 0 : -1,
type: 'radio',
value: `${i}`,
onchange: this._onMonthRadioChange,
onmouseup: this._closeMonthPopup
onchange: this._onMonthRadioChange
}),
v('abbr', {
classes: this.theme(css.monthRadioLabel),
Expand Down Expand Up @@ -255,18 +258,20 @@ export class DatePickerBase<P extends DatePickerProperties = DatePickerPropertie
for (let i = yearLimits.first; i < yearLimits.last; i++) {
radios.push(v('label', {
key: `${this._idBase}_year_radios_${i}`,
classes: this.theme([ css.yearRadio, i === year ? css.yearRadioChecked : null ])
classes: this.theme([ css.yearRadio, i === year ? css.yearRadioChecked : null ]),
for: this._getYearInputKey(i),
onmouseup: this._closeYearPopup
}, [
v('input', {
checked: i === year,
classes: this.theme(css.yearRadioInput),
id: this._getYearInputKey(i),
key: this._getYearInputKey(i),
name: `${this._idBase}_year_radios`,
tabIndex: this._yearPopupOpen ? 0 : -1,
type: 'radio',
value: `${i}`,
onchange: this._onYearRadioChange,
onmouseup: this._closeYearPopup
onchange: this._onYearRadioChange
}),
v('abbr', {
classes: this.theme(css.yearRadioLabel)
Expand Down
1 change: 1 addition & 0 deletions src/calendar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ export class CalendarBase<P extends CalendarProperties = CalendarProperties> ext
year,
onPopupChange: (open: boolean) => {
this._popupOpen = open;
this.invalidate();
},
onRequestMonthChange: (requestMonth: number) => {
onMonthChange && onMonthChange(requestMonth);
Expand Down
15 changes: 13 additions & 2 deletions src/calendar/tests/functional/Calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { assert } = intern.getPlugin('chai');
import { Remote } from 'intern/lib/executors/Node';
import keys from '@theintern/leadfoot/keys';
import * as css from '../../../theme/calendar.m.css';
import * as baseCss from '../../../common/styles/base.m.css';

const DELAY = 500;

Expand Down Expand Up @@ -49,6 +50,11 @@ registerSuite('Calendar', {
assert.strictEqual(hidden, 'false', 'The month dialog should open on first click');
})
.end()
.findByCssSelector(`.${css.dateGrid}`)
.getAttribute('class')
.then((className: string) => {
assert.include(className, baseCss.visuallyHidden, 'date grid is hidden when month popup is open');
})
.getActiveElement()
.getAttribute('value')
.then((value: string) => {
Expand Down Expand Up @@ -83,6 +89,11 @@ registerSuite('Calendar', {
assert.strictEqual(hidden, 'false', 'The month dialog should open on first click');
})
.end()
.findByCssSelector(`.${css.dateGrid}`)
.getAttribute('class')
.then((className: string) => {
assert.include(className, baseCss.visuallyHidden, 'date grid is hidden when month popup is open');
})
.getActiveElement()
.getAttribute('value')
.then((value: string) => {
Expand All @@ -101,10 +112,10 @@ registerSuite('Calendar', {
.click()
.sleep(DELAY)
.end()
.findByCssSelector(`.${css.monthTrigger}`)
.getActiveElement()
.getVisibleText()
.then(label => {
assert.include(label, 'January', 'Clicking first month radio changes label text to January');
assert.include(label, 'January', 'Clicking first month radio focuses button and changes text to January');
})
.end()
.findByCssSelector(`.${css.monthGrid}`)
Expand Down
47 changes: 27 additions & 20 deletions src/calendar/tests/unit/DatePicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,26 @@ const requiredProps = {
let customProps: any = {};

const compareKey = { selector: 'label,input', property: 'key', comparator: (property: any) => typeof property === 'string' };
const compareFor = { selector: 'label', property: 'for', comparator: (property: any) => typeof property === 'string' };
const compareName = { selector: 'input', property: 'name', comparator: (property: any) => typeof property === 'string' };

const monthRadios = function(open?: boolean) {
return DEFAULT_MONTHS.map((monthName, i) => v('label', {
key: '',
classes: [ css.monthRadio, i === 5 ? css.monthRadioChecked : null ]
classes: [ css.monthRadio, i === 5 ? css.monthRadioChecked : null ],
for: '',
onmouseup: noop
}, [
v('input', {
checked: i === 5,
classes: css.monthRadioInput,
id: '',
key: '',
name: '',
tabIndex: open ? 0 : -1,
type: 'radio',
value: `${i}`,
onchange: noop,
onmouseup: noop
onchange: noop
}),
v('abbr', {
classes: css.monthRadioLabel,
Expand All @@ -58,18 +61,20 @@ const yearRadios = function(open?: boolean, yearStart = 2000, yearEnd = 2020, ch
for (let i = yearStart; i < yearEnd; i++) {
radios.push(v('label', {
key: '',
classes: [ css.yearRadio, i === checkedYear ? css.yearRadioChecked : null ]
classes: [ css.yearRadio, i === checkedYear ? css.yearRadioChecked : null ],
for: '',
onmouseup: noop
}, [
v('input', {
checked: i === checkedYear,
classes: css.yearRadioInput,
id: '',
tabIndex: open ? 0 : -1,
type: 'radio',
key: '',
name: '',
value: `${ i }`,
onchange: noop,
onmouseup: noop
onchange: noop
}),
v('abbr', {
classes: css.yearRadioLabel
Expand Down Expand Up @@ -203,7 +208,7 @@ registerSuite('Calendar DatePicker', {
'Popup should render with default properties'() {
const h = harness(() => w(DatePicker, {
...requiredProps
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareName ]);
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareFor, compareName ]);

h.expect(() => expected());
},
Expand All @@ -218,7 +223,7 @@ registerSuite('Calendar DatePicker', {
renderMonthLabel: () => { return 'bar'; },
...customProps,
...requiredProps
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareName ]);
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareFor, compareName ]);

h.expect(() => expected(false, false, { yearStart: 2000, yearEnd: 2025, monthLabel: 'bar'}));
},
Expand All @@ -228,7 +233,7 @@ registerSuite('Calendar DatePicker', {
...requiredProps
};
const h = harness(() => w(DatePicker, properties), [
compareKey, compareName, compareId, compareAriaLabelledBy, compareAriaControls
compareKey, compareFor, compareName, compareId, compareAriaLabelledBy, compareAriaControls
]);
h.expect(expected);

Expand Down Expand Up @@ -294,19 +299,21 @@ registerSuite('Calendar DatePicker', {
classes: baseCss.visuallyHidden
}, [ DEFAULT_LABELS.chooseMonth ]),
...DEFAULT_MONTHS.map((monthName, i) => v('label', {
for: '',
key: '',
classes: [ css.monthRadio, i === 5 ? css.monthRadioChecked : null ]
classes: [ css.monthRadio, i === 5 ? css.monthRadioChecked : null ],
onmouseup: noop
}, [
v('input', {
checked: i === 5,
classes: css.monthRadioInput,
id: '',
key: '',
name: '',
tabIndex: -1,
type: 'radio',
value: `${i}`,
onchange: noop,
onmouseup: noop
onchange: noop
}),
v('abbr', {
classes: css.monthRadioLabel,
Expand Down Expand Up @@ -388,7 +395,7 @@ registerSuite('Calendar DatePicker', {
const h = harness(() => w(DatePicker, {
onPopupChange: (open: boolean) => { isOpen = open; },
...requiredProps
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareName ]);
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareFor, compareName ]);
h.expect(() => expected(false, false));

h.trigger('@month-button', 'onclick', stubEvent);
Expand All @@ -405,7 +412,7 @@ registerSuite('Calendar DatePicker', {
const h = harness(() => w(DatePicker, {
onPopupChange: (open: boolean) => { isOpen = open; },
...requiredProps
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareName ]);
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareFor, compareName ]);
h.expect(() => expected(false, false));

// escape key
Expand Down Expand Up @@ -443,7 +450,7 @@ registerSuite('Calendar DatePicker', {
const h = harness(() => w(DatePicker, {
onPopupChange: (open: boolean) => { isOpen = open; },
...requiredProps
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareName ]);
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareFor, compareName ]);
h.expect(() => expected(false, false));

// escape key
Expand Down Expand Up @@ -479,7 +486,7 @@ registerSuite('Calendar DatePicker', {
'Clicking buttons changes year page'() {
const h = harness(() => w(DatePicker, {
...requiredProps
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareName ]);
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareFor, compareName ]);
h.trigger('@year-button', 'onclick', stubEvent);
h.expect(() => expected(false, true));

Expand All @@ -497,15 +504,15 @@ registerSuite('Calendar DatePicker', {
...requiredProps,
onPopupChange: (open: boolean) => { isOpen = open; },
onRequestMonthChange: (month: number) => { currentMonth = month; }
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareName ]);
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareFor, compareName ]);

h.trigger('@month-button', 'onclick', stubEvent);
assert.isTrue(isOpen, 'Month popup opens when clicking month button');

h.trigger(`.${css.monthRadio}:nth-of-type(7) input`, 'onchange', { ...stubEvent, target: { value: 6 } });
assert.strictEqual(currentMonth, 6, 'Change event on July sets month value');

h.trigger(`.${css.monthRadio}:nth-of-type(7) input`, 'onmouseup', stubEvent);
h.trigger(`.${css.monthRadio}:nth-of-type(7)`, 'onmouseup', stubEvent);
assert.isFalse(isOpen, 'Clicking radios closes popup');
},

Expand All @@ -516,15 +523,15 @@ registerSuite('Calendar DatePicker', {
...requiredProps,
onPopupChange: (open: boolean) => { isOpen = open; },
onRequestYearChange: (year: number) => { currentYear = year; }
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareName ]);
}), [ compareId, compareAriaLabelledBy, compareAriaControls, compareKey, compareFor, compareName ]);

h.trigger('@year-button', 'onclick', stubEvent);
assert.isTrue(isOpen, 'Year popup opens when clicking month button');

h.trigger(`.${css.yearRadio}:nth-of-type(2) input`, 'onchange', { ...stubEvent, target: { value: 2001 } });
assert.strictEqual(currentYear, 2001, 'Change event on second year radio changes year to 2001');

h.trigger(`.${css.yearRadio}:nth-of-type(2) input`, 'onmouseup', stubEvent);
h.trigger(`.${css.yearRadio}:nth-of-type(2)`, 'onmouseup', stubEvent);
assert.isFalse(isOpen, 'Clicking radios closes popup');
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/split-pane/styles/split-pane.m.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import '../../common/styles/variables.css';

.rootFixed {
align-content: stretch;
align-items: stretch;
Expand Down

0 comments on commit ed1e664

Please sign in to comment.