Skip to content

Commit 47ad297

Browse files
author
pipeline
committed
v20.1.57 is released
1 parent 7398d82 commit 47ad297

File tree

298 files changed

+2574
-1456
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

298 files changed

+2574
-1456
lines changed

controls/base/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
## [Unreleased]
44

5+
## 20.1.56 (2022-05-17)
6+
7+
### Common
8+
9+
#### Bug Fixes
10+
11+
- `F173666` - The issue with sanitize html while creating a appointment in scheduler has been resolve.
12+
513
## 20.1.55 (2022-05-12)
614

715
### Common

controls/base/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@syncfusion/ej2-base",
3-
"version": "20.1.55",
3+
"version": "20.1.56",
44
"description": "A common package of Essential JS 2 base libraries, methods and class definitions",
55
"author": "Syncfusion Inc.",
66
"license": "SEE LICENSE IN license",

controls/base/src/sanitize-helper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export class SanitizeHtmlHelper {
169169
this.removeXssAttrs();
170170
const tempEleValue: string = this.wrapElement.innerHTML;
171171
this.removeElement();
172-
return tempEleValue;
172+
return tempEleValue.replace('&', '&');
173173
}
174174

175175
private static removeElement(): void {

controls/base/themestudio/styles/inplace-editor/inplace-editor/_theme.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@
136136
border: 1px solid darken($gray-600, 10%);
137137
}
138138
}
139+
@else if $inplace-skin == 'bootstrap5' {
140+
141+
&:hover {
142+
background-color: darken($gray-600, 7.5%);
143+
border: 1px solid darken($gray-600, 10%);
144+
}
145+
}
146+
139147

140148
@if $inplace-skin == 'bootstrap4' {
141149

controls/calendars/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
## [Unreleased]
44

5+
## 20.1.57 (2022-05-24)
6+
7+
### DateRangePicker
8+
9+
#### Bug Fixes
10+
11+
- `#I378357` - Issue with "tab key navigation is not working between calendars" has been resolved.
12+
513
## 19.3.46 (2021-10-19)
614

715
### TimePicker

controls/calendars/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@syncfusion/ej2-calendars",
3-
"version": "20.1.52",
3+
"version": "20.1.57",
44
"description": "A complete package of date or time components with built-in features such as date formatting, inline editing, multiple (range) selection, range restriction, month and year selection, strict mode, and globalization.",
55
"author": "Syncfusion Inc.",
66
"license": "SEE LICENSE IN license",

controls/calendars/spec/daterangepicker/daterangepicker.spec.ts

Lines changed: 316 additions & 276 deletions
Large diffs are not rendered by default.

controls/calendars/spec/datetimepicker/datetimepicker.spec.ts

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4140,5 +4140,145 @@ describe('EJ2-56658:change event is not triggered while remove the selected time
41404140
});
41414141

41424142
});
4143+
describe('EJ2-59142', () => {
4144+
let datetimepicker: any;
4145+
let keyEventArgs: any = {
4146+
preventDefault: (): void => { /** NO Code */ },
4147+
stopPropagation:(): void=>{},
4148+
action: 'ArrowLeft',
4149+
code: 'ArrowLeft',
4150+
key: 'ArrowLeft'
4151+
};
4152+
beforeEach(() => {
4153+
let ele: HTMLElement = createElement('input', { id: 'dateTime' });
4154+
document.body.appendChild(ele);
4155+
});
4156+
afterEach(() => {
4157+
if (datetimepicker) {
4158+
datetimepicker.destroy();
4159+
}
4160+
document.body.innerHTML = '';
4161+
});
4162+
it('Typing a value in the Datetime picker mask is not working properly.', () => {
4163+
datetimepicker = new DateTimePicker({
4164+
placeholder: 'Select a date and time',
4165+
format: 'dd/MM/yyyy',
4166+
enableMask: true,
4167+
value: new Date('01/01/2020')
4168+
});
4169+
datetimepicker.appendTo('#dateTime');
4170+
datetimepicker.focusIn();
4171+
expect(datetimepicker.element.value).toBe('01/01/2020');
4172+
datetimepicker.element.selectionStart = 0;
4173+
datetimepicker.element.selectionEnd = 2;
4174+
datetimepicker.element.value = '0/01/2020';
4175+
datetimepicker.element.selectionStart = 1;
4176+
datetimepicker.inputHandler();
4177+
expect(datetimepicker.element.value).toBe('0/01/2020');
4178+
expect(datetimepicker.element.selectionStart === 0).toBe(true);
4179+
expect(datetimepicker.element.selectionEnd === 1).toBe(true);
4180+
datetimepicker.element.value = '4/01/2020';
4181+
datetimepicker.element.selectionStart = 1;
4182+
datetimepicker.inputHandler();
4183+
expect(datetimepicker.element.value).toBe('04/01/2020');
4184+
expect(datetimepicker.element.selectionStart === 3).toBe(true);
4185+
expect(datetimepicker.element.selectionEnd === 5).toBe(true);
4186+
datetimepicker.element.value = '04/0/2020';
4187+
datetimepicker.element.selectionStart = 4;
4188+
datetimepicker.inputHandler();
4189+
expect(datetimepicker.element.value).toBe('04/0/2020');
4190+
expect(datetimepicker.element.selectionStart === 3).toBe(true);
4191+
expect(datetimepicker.element.selectionEnd === 4).toBe(true);
4192+
datetimepicker.element.value = '04/5/2020';
4193+
datetimepicker.element.selectionStart = 4;
4194+
datetimepicker.inputHandler();
4195+
expect(datetimepicker.element.value).toBe('04/05/2020');
4196+
expect(datetimepicker.element.selectionStart === 6).toBe(true);
4197+
expect(datetimepicker.element.selectionEnd === 10).toBe(true);
4198+
datetimepicker.format = 'MM/dd/yyyy';
4199+
datetimepicker.dataBind();
4200+
datetimepicker.element.selectionStart = 0;
4201+
datetimepicker.element.selectionEnd = 2;
4202+
datetimepicker.element.value = '1/01/2020';
4203+
datetimepicker.element.selectionStart = 1;
4204+
datetimepicker.inputHandler();
4205+
expect(datetimepicker.element.value).toBe('01/01/2020');
4206+
expect(datetimepicker.element.selectionStart === 0).toBe(true);
4207+
expect(datetimepicker.element.selectionEnd === 2).toBe(true);
4208+
datetimepicker.element.value = '2/01/2020';
4209+
datetimepicker.element.selectionStart = 1;
4210+
datetimepicker.inputHandler();
4211+
expect(datetimepicker.element.value).toBe('12/01/2020');
4212+
datetimepicker.element.selectionStart = 3;
4213+
datetimepicker.element.selectionEnd = 5;
4214+
datetimepicker.element.value = '12/1/2020';
4215+
datetimepicker.element.selectionStart = 4;
4216+
datetimepicker.inputHandler();
4217+
expect(datetimepicker.element.value).toBe('12/01/2020');
4218+
expect(datetimepicker.element.selectionStart === 3).toBe(true);
4219+
expect(datetimepicker.element.selectionEnd === 5).toBe(true);
4220+
datetimepicker.element.value = '12/0/2020';
4221+
datetimepicker.element.selectionStart = 4;
4222+
datetimepicker.inputHandler();
4223+
expect(datetimepicker.element.value).toBe('12/10/2020');
4224+
expect(datetimepicker.element.selectionStart === 6).toBe(true);
4225+
expect(datetimepicker.element.selectionEnd === 10).toBe(true);
4226+
datetimepicker.keydownHandler(keyEventArgs);
4227+
expect(datetimepicker.element.selectionStart).toBe(3);
4228+
expect(datetimepicker.element.selectionEnd).toBe(5);
4229+
datetimepicker.element.value = '12/0/2020';
4230+
datetimepicker.element.selectionStart = 4;
4231+
datetimepicker.inputHandler();
4232+
expect(datetimepicker.element.value).toBe('12/0/2020');
4233+
expect(datetimepicker.element.selectionStart === 3).toBe(true);
4234+
expect(datetimepicker.element.selectionEnd === 4).toBe(true);
4235+
datetimepicker.element.value = '12/6/2020';
4236+
datetimepicker.element.selectionStart = 4;
4237+
datetimepicker.inputHandler();
4238+
expect(datetimepicker.element.value).toBe('12/06/2020');
4239+
expect(datetimepicker.element.selectionStart === 6).toBe(true);
4240+
expect(datetimepicker.element.selectionEnd === 10).toBe(true);
4241+
datetimepicker.format = 'yyyy-MM-dd';
4242+
datetimepicker.dataBind();
4243+
expect(datetimepicker.element.value).toBe('2020-01-01');
4244+
datetimepicker.element.selectionStart = 5;
4245+
datetimepicker.element.selectionEnd = 7;
4246+
datetimepicker.element.value = '2020-0-01';
4247+
datetimepicker.element.selectionStart = 6;
4248+
datetimepicker.inputHandler();
4249+
expect(datetimepicker.element.value).toBe('2020-0-01');
4250+
expect(datetimepicker.element.selectionStart === 5).toBe(true);
4251+
expect(datetimepicker.element.selectionEnd === 6).toBe(true);
4252+
datetimepicker.element.value = '2020-9-01';
4253+
datetimepicker.element.selectionStart = 6;
4254+
datetimepicker.inputHandler();
4255+
expect(datetimepicker.element.value).toBe('2020-09-01');
4256+
expect(datetimepicker.element.selectionStart === 8).toBe(true);
4257+
expect(datetimepicker.element.selectionEnd === 10).toBe(true);
4258+
datetimepicker.element.value = '2020-09-1';
4259+
datetimepicker.inputHandler();
4260+
expect(datetimepicker.element.value).toBe('2020-09-01');
4261+
expect(datetimepicker.element.selectionStart === 8).toBe(true);
4262+
expect(datetimepicker.element.selectionEnd === 10).toBe(true);
4263+
datetimepicker.element.value = '2020-09-0';
4264+
datetimepicker.inputHandler();
4265+
expect(datetimepicker.element.value).toBe('2020-09-10');
4266+
datetimepicker.keydownHandler(keyEventArgs);
4267+
expect(datetimepicker.element.selectionStart === 5).toBe(true);
4268+
expect(datetimepicker.element.selectionEnd === 7).toBe(true);
4269+
datetimepicker.element.value = '2020-1-10';
4270+
datetimepicker.element.selectionStart = 6;
4271+
datetimepicker.inputHandler();
4272+
expect(datetimepicker.element.value).toBe('2020-01-10');
4273+
expect(datetimepicker.element.selectionStart === 5).toBe(true);
4274+
expect(datetimepicker.element.selectionEnd === 7).toBe(true);
4275+
datetimepicker.element.value = '2020-2-10';
4276+
datetimepicker.element.selectionStart = 6;
4277+
datetimepicker.inputHandler();
4278+
expect(datetimepicker.element.value).toBe('2020-12-10');
4279+
expect(datetimepicker.element.selectionStart === 8).toBe(true);
4280+
expect(datetimepicker.element.selectionEnd === 10).toBe(true);
4281+
});
4282+
});
41434283
});
41444284

controls/calendars/src/calendar/calendar.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,10 @@ export class CalendarBase extends Component<HTMLElement> implements INotifyPrope
568568
duration: 400,
569569
isCenterRipple: true
570570
});
571+
if (this.getModuleName() === 'daterangepicker') {
572+
attributes(this.previousIcon, {tabIndex: '-1'});
573+
attributes(this.nextIcon, {tabIndex: '-1'});
574+
}
571575
attributes(this.nextIcon, <{ [key: string]: string }>ariaNextAttrs);
572576
this.headerTitleElement = this.createElement('div', { className: '' + LINK + ' ' + TITLE });
573577
attributes(this.headerTitleElement, <{ [key: string]: string }>ariaTitleAttrs);
@@ -685,7 +689,7 @@ export class CalendarBase extends Component<HTMLElement> implements INotifyPrope
685689
this.todayElement = this.createElement('button', { attrs: { role: 'button' } });
686690
rippleEffect(this.todayElement);
687691
this.updateFooter();
688-
addClass([this.todayElement], [BTN, TODAY, FLAT, PRIMARY, CSS]);
692+
addClass([this.todayElement], [BTN, TODAY, FLAT, PRIMARY, CSS]);
689693
if ((!(+new Date(minimum.setHours(0, 0, 0, 0)) <= +this.todayDate &&
690694
+this.todayDate <= +new Date(maximum.setHours(0, 0, 0, 0)))) || (this.todayDisabled)) {
691695
addClass([this.todayElement], DISABLED);

controls/calendars/src/datepicker/datepicker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export class DatePicker extends Calendar implements IInput {
9090
protected isIconClicked : boolean = false;
9191
protected isDynamicValueChanged: boolean = false;
9292
protected moduleName: string = this.getModuleName();
93+
protected isFocused: boolean = false;
9394
/**
9495
* Specifies the width of the DatePicker component.
9596
*
@@ -1004,6 +1005,7 @@ export class DatePicker extends Calendar implements IInput {
10041005
}
10051006
}
10061007
private inputFocusHandler(): void {
1008+
this.isFocused = true;
10071009
if (!this.enabled) {
10081010
return;
10091011
}

controls/calendars/src/daterangepicker/daterangepicker.ts

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ export class DateRangePicker extends CalendarBase {
901901
this.validationAttribute(this.element, this.inputElement);
902902
}
903903
this.checkHtmlAttributes(false);
904-
merge(this.defaultKeyConfigs, { shiftTab: 'shift+tab' });
904+
merge(this.defaultKeyConfigs, { shiftTab: 'shift+tab' , tab: 'tab' });
905905
const start: Date = this.checkDateValue(new Date(this.checkValue(this.startValue)));
906906
this.setProperties({ startDate: start }, true); // persist the value propeerty.
907907
this.setProperties({ endValue: this.checkDateValue(new Date(this.checkValue(this.endValue))) }, true);
@@ -1604,8 +1604,10 @@ export class DateRangePicker extends CalendarBase {
16041604
}
16051605
}
16061606
}
1607-
private keyCalendarUpdate(isLeftCalendar: boolean, ele: HTMLElement): HTMLElement {
1608-
this.removeFocusedDate();
1607+
private keyCalendarUpdate(isLeftCalendar: boolean, ele: HTMLElement, isRemoveFocus: boolean = true): HTMLElement {
1608+
if (isRemoveFocus) {
1609+
this.removeFocusedDate();
1610+
}
16091611
if (isLeftCalendar) {
16101612
this.leftCalCurrentDate = new Date(+this.currentDate);
16111613
ele = this.leftCalendar;
@@ -1698,8 +1700,37 @@ export class DateRangePicker extends CalendarBase {
16981700
}
16991701
this.keyNavigation(ele, e);
17001702
break;
1703+
case 'tab':
1704+
if (this.tabKeyValidation(ele, LEFTCALENDER)) {
1705+
ele = this.keyCalendarUpdate(false, ele, false);
1706+
const focusedCell: HTMLElement = ele.querySelector('.e-focused-date');
1707+
if (isNullOrUndefined(focusedCell)) {
1708+
this.currentDate = this.firstCellToFocus(this.rightCalendar);
1709+
}
1710+
this.keyboardNavigate(0, view, e, max, min);
1711+
this.keyNavigation(ele, e);
1712+
}
1713+
break;
1714+
case 'shiftTab':
1715+
if (this.tabKeyValidation(ele, RIGHTCALENDER)) {
1716+
ele = this.keyCalendarUpdate(true, ele, false);
1717+
const focusedCell: HTMLElement = ele.querySelector('.e-focused-date');
1718+
if (isNullOrUndefined(focusedCell)) {
1719+
this.currentDate = this.firstCellToFocus(this.leftCalendar);
1720+
}
1721+
this.keyboardNavigate(0, view, e, max, min);
1722+
this.keyNavigation(ele, e);
1723+
}
1724+
break;
17011725
}
17021726
}
1727+
private firstCellToFocus(calendar: HTMLElement): Date {
1728+
const focusAbleEle: HTMLElement = calendar.children[1].firstElementChild.querySelector('td.e-cell:not(.e-week-number):not(.e-disabled):not(.e-other-month)');
1729+
const focusEleID: string = focusAbleEle && focusAbleEle.id ? focusAbleEle.id.split('_')[0] : null;
1730+
const currentFirstDay: Date = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), 1);
1731+
const focusDate: Date = focusEleID ? new Date(+focusEleID) : currentFirstDay;
1732+
return focusDate;
1733+
}
17031734
private keyInputHandler(e: KeyboardEventArgs, value?: Date): void {
17041735
let date: Date;
17051736
let view: number = this.getViewNumber(this.currentView());
@@ -1876,19 +1907,39 @@ export class DateRangePicker extends CalendarBase {
18761907
this.presetElement.focus();
18771908
this.removeFocusedDate();
18781909
}
1879-
e.preventDefault();
1910+
if (isLeftCalendar) {
1911+
e.preventDefault();
1912+
}
1913+
if (this.tabKeyValidation(ele, RIGHTCALENDER)) {
1914+
this.currentDate = new Date(+this.leftCalCurrentDate);
1915+
this.navInCalendar(e, isLeftCalendar, leftDateLimit, rightDateLimit, ele);
1916+
}
18801917
break;
18811918
case 'spacebar':
18821919
if (this.applyButton && !this.applyButton.disabled) {
18831920
this.applyFunction(e);
18841921
}
18851922
break;
1923+
case 'tab':
1924+
if (this.tabKeyValidation(ele, LEFTCALENDER)) {
1925+
this.currentDate = new Date(+this.rightCalCurrentDate);
1926+
this.navInCalendar(e, isLeftCalendar, leftDateLimit, rightDateLimit, ele);
1927+
}
1928+
break;
18861929
default:
18871930
this.navInCalendar(e, isLeftCalendar, leftDateLimit, rightDateLimit, ele);
18881931
this.checkMinMaxDays();
18891932
}
18901933
this.presetHeight();
18911934
}
1935+
private tabKeyValidation(ele: HTMLElement, calendarPos: string): boolean {
1936+
const isLeftCalendar: boolean = ele.classList.contains(calendarPos);
1937+
const rightHeader: HTMLElement = this.rightCalendar.querySelector('.e-header');
1938+
const leftHeader: HTMLElement = this.leftCalendar.querySelector('.e-header');
1939+
const isRightMonth: boolean = rightHeader ? rightHeader.classList.contains('e-month') : false;
1940+
const isLeftMonth: boolean = leftHeader ? leftHeader.classList.contains('e-month') : false;
1941+
return isLeftCalendar && isLeftMonth && isRightMonth && !this.isMobile;
1942+
}
18921943
private keyNavigation(calendar: HTMLElement, e: KeyboardEventArgs): void {
18931944
this.bindCalendarCellEvents(calendar);
18941945
if (calendar.classList.contains(LEFTCALENDER)) {
@@ -2595,9 +2646,9 @@ export class DateRangePicker extends CalendarBase {
25952646
}
25962647
this.removeFocusedDate();
25972648
}
2598-
private updateControl(calendar: HTMLElement): void {
2649+
private updateControl(calendar: HTMLElement, customDate: Date = null): void {
25992650
if (calendar.classList.contains(RIGHTCALENDER)) {
2600-
this.rightCalCurrentDate = new Date(+this.currentDate);
2651+
this.rightCalCurrentDate = new Date(+(customDate ? customDate : this.currentDate));
26012652
} else {
26022653
this.leftCalCurrentDate = new Date(+this.currentDate);
26032654
}
@@ -2918,7 +2969,7 @@ export class DateRangePicker extends CalendarBase {
29182969
this.rightCalNextIcon = <HTMLElement>this.calendarElement.querySelector('.' + RIGHTCALENDER + ' .' + NEXTICON);
29192970
this.rightTitle = <HTMLElement>this.calendarElement.querySelector('.' + RIGHTCALENDER + ' .' + TITLE);
29202971
remove(this.calendarElement.querySelector('.' + RIGHTCALENDER + ' .' + ICONCONTAINER));
2921-
this.calendarElement.querySelector('table').setAttribute('tabindex', '-1');
2972+
this.calendarElement.querySelector('table').setAttribute('tabindex', '0');
29222973
this.calendarElement.querySelector('.' + RIGHTCALENDER + ' .' + HEADER).appendChild(this.rightCalNextIcon);
29232974
this.calendarElement.querySelector('.' + RIGHTCALENDER + ' .' + HEADER).appendChild(this.rightCalPrevIcon);
29242975
prepend([this.rightCalPrevIcon], this.calendarElement.querySelector('.' + RIGHTCALENDER + ' .' + HEADER));
@@ -3027,7 +3078,8 @@ export class DateRangePicker extends CalendarBase {
30273078
this.updateControl(this.leftCalendar);
30283079
this.updateCalendarElement(this.rightCalendar);
30293080
super.navigateTo.call(this, view, this.rightCalCurrentDate);
3030-
this.updateControl(this.rightCalendar);
3081+
const customDate: Date = this.rightCalCurrentDate ? this.rightCalCurrentDate : this.currentDate;
3082+
this.updateControl(this.rightCalendar, customDate);
30313083
this.updateNavIcons();
30323084
this.calendarIconEvent();
30333085
this.calendarIconRipple();

controls/calendars/src/maskbase/interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ export interface IMaskedDateTime extends Component<HTMLElement> {
2222
cldrTimeFormat(): string
2323
calendarMode: CalendarType;
2424
globalize: Internationalization;
25+
isFocused: boolean;
2526
}

0 commit comments

Comments
 (0)