Skip to content

Commit 6325f33

Browse files
author
pipeline
committed
v29.2.5 is released
1 parent 4fb2df8 commit 6325f33

File tree

164 files changed

+2738
-1977
lines changed

Some content is hidden

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

164 files changed

+2738
-1977
lines changed

controls/barcodegenerator/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## [Unreleased]
44

5-
## 29.2.4 (2025-05-14)
5+
## 29.2.5 (2025-05-21)
66

77
### Barcode
88

controls/base/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## [Unreleased]
44

5-
## 29.2.4 (2025-05-14)
5+
## 29.2.5 (2025-05-21)
66

77
### Common
88

controls/buttons/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+
## 29.2.5 (2025-05-21)
6+
7+
### Switch
8+
9+
#### Bug Fixes
10+
11+
- `#I959152` - Fixed the issue of the click event being triggered twice when placing a switch within a label tag. Additionally, resolved a script error that occurred when placing the switch within a dialog.
12+
513
## 29.1.33 (2025-03-25)
614

715
### Chip

controls/buttons/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-buttons",
3-
"version": "29.1.33",
3+
"version": "29.2.4",
44
"description": "A package of feature-rich Essential JS 2 components such as Button, CheckBox, RadioButton and Switch.",
55
"author": "Syncfusion Inc.",
66
"license": "SEE LICENSE IN license",

controls/buttons/spec/check-box.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,13 @@ describe('CheckBox', () => {
804804
checkbox.getLabel();
805805
checkbox.appendTo('#checkbox');
806806
});
807-
807+
it('Vue CheckBox with updateVueArrayModel function', function () {
808+
checkbox = new CheckBox({ indeterminate: null });
809+
checkbox.isVue = true;
810+
checkbox.value = ['games', 'volleyball'];
811+
checkbox.appendTo('#checkbox');
812+
checkbox.element.value = 'volleyball';
813+
checkbox.updateVueArrayModel();
814+
});
808815
});
809816
});

controls/buttons/spec/switch.spec.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -434,22 +434,25 @@ describe('Switch', () => {
434434

435435
describe('Parent element click event prevented while clicking on switch component', () => {
436436
let switchBtn: Switch;
437-
let input: HTMLElement;
438-
let parentElement: HTMLElement;
437+
let input: HTMLElement; let input1: HTMLElement;
438+
let parentElement: HTMLElement; let parentElement1: HTMLElement;
439439
let parentChecked: boolean = false;
440440
beforeEach(() => {
441-
parentElement = createElement('div', {
442-
id: 'form'
443-
}) as HTMLElement;
441+
parentElement = createElement('div', { id: 'form' }) as HTMLElement;
442+
parentElement1 = createElement('label', { id: 'label1' }) as HTMLElement;
444443
input = createElement('input', { id: 'switch1' }) as HTMLElement;
444+
input1 = createElement('input', { id: 'switch2' }) as HTMLElement;
445445
parentElement.appendChild(input);
446+
parentElement1.appendChild(input1);
446447
parentElement.onclick = function () {
447448
parentChecked = true;
448449
}
449450
document.body.appendChild(parentElement);
451+
document.body.appendChild(parentElement1);
450452
});
451453
afterEach(() => {
452454
parentElement.remove();
455+
parentElement1.remove();
453456
switchBtn.destroy();
454457
})
455458
it('ej2-918217: Parent element click event prevented while clicking on switch component in angular platforms.', () => {
@@ -459,6 +462,27 @@ describe('Switch', () => {
459462
switchBtn.click();
460463
expect(parentChecked).toBeTruthy();
461464
});
465+
it('959152: Click event trigger twice when we placed switch component within the label tag', () => {
466+
switchBtn = new Switch({
467+
checked: true
468+
}, '#switch2');
469+
switchBtn.element.parentElement.click();
470+
expect(switchBtn.checked).toEqual(false);
471+
});
472+
it('Coverage improvement for switch focus handler', () => {
473+
switchBtn = new Switch({
474+
checked: true
475+
}, '#switch1');
476+
switchBtn.isAngular = true;
477+
(switchBtn as any).mouseLeaveHandler();
478+
const keyArgs: KeyboardEvent = new KeyboardEvent('keyup', {
479+
key: 'space',
480+
code: 'Space',
481+
bubbles: true,
482+
cancelable: true
483+
});
484+
(switchBtn as any).switchFocusHandler(keyArgs);
485+
});
462486
});
463487

464488
describe('Switch in HTML5 forms', () => {

controls/buttons/src/check-box/check-box.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -591,15 +591,17 @@ export class CheckBox extends Component<HTMLInputElement> implements INotifyProp
591591

592592
protected unWireEvents(): void {
593593
const wrapper: Element = this.wrapper;
594-
EventHandler.remove(wrapper, 'click', this.clickHandler);
595594
EventHandler.remove(this.element, 'keyup', this.keyUpHandler);
596595
EventHandler.remove(this.element, 'focus', this.focusHandler);
597596
EventHandler.remove(this.element, 'focusout', this.focusOutHandler);
598-
const label: Element = wrapper.getElementsByTagName('label')[0];
599-
if (label) {
600-
EventHandler.remove(label, 'mousedown', this.labelMouseDownHandler);
601-
EventHandler.remove(label, 'mouseup', this.labelMouseUpHandler);
602-
EventHandler.remove(label, 'mouseleave', this.labelMouseLeaveHandler);
597+
if (wrapper) {
598+
EventHandler.remove(wrapper, 'click', this.clickHandler);
599+
const label: Element = wrapper.getElementsByTagName('label')[0];
600+
if (label) {
601+
EventHandler.remove(label, 'mousedown', this.labelMouseDownHandler);
602+
EventHandler.remove(label, 'mouseup', this.labelMouseUpHandler);
603+
EventHandler.remove(label, 'mouseleave', this.labelMouseLeaveHandler);
604+
}
603605
}
604606
const formElem: HTMLFormElement = <HTMLFormElement>closest(this.element, 'form');
605607
if (formElem) {

controls/buttons/src/radio-button/radio-button.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -527,11 +527,13 @@ export class RadioButton extends Component<HTMLInputElement> implements INotifyP
527527
EventHandler.remove(this.element, 'focus', this.focusHandler);
528528
EventHandler.remove(this.element, 'focusout', this.focusOutHandler);
529529
EventHandler.remove(this.element, 'keyup', this.keyUpHandler);
530-
const rippleLabel: Element = label.getElementsByTagName('label')[0];
531-
if (rippleLabel) {
532-
EventHandler.remove(rippleLabel, 'mousedown', this.labelMouseDownHandler);
533-
EventHandler.remove(rippleLabel, 'mouseup', this.labelMouseUpHandler);
534-
EventHandler.remove(rippleLabel, 'mouseleave', this.labelMouseLeaveHandler);
530+
if (label) {
531+
const rippleLabel: Element = label.getElementsByTagName('label')[0];
532+
if (rippleLabel) {
533+
EventHandler.remove(rippleLabel, 'mousedown', this.labelMouseDownHandler);
534+
EventHandler.remove(rippleLabel, 'mouseup', this.labelMouseUpHandler);
535+
EventHandler.remove(rippleLabel, 'mouseleave', this.labelMouseLeaveHandler);
536+
}
535537
}
536538
if (this.formElement) {
537539
EventHandler.remove(this.formElement, 'reset', this.formResetHandler);

controls/buttons/src/switch/switch.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ export class Switch extends Component<HTMLInputElement> implements INotifyProper
167167
}
168168
}
169169
private clickHandler(evt?: Event): void {
170+
if (evt && this.element.closest('label')) {
171+
if (evt.target !== this.element) { return; }
172+
}
170173
this.isDrag = false;
171174
this.focusOutHandler();
172175
const beforeChangeEventArgs: BeforeChangeEventArgs = { event: evt, cancel: false, checked: this.checked };
@@ -191,7 +194,9 @@ export class Switch extends Component<HTMLInputElement> implements INotifyProper
191194
if (this.formElement) {
192195
EventHandler.remove(this.formElement, 'reset', this.formResetHandler);
193196
}
194-
destroy(this, this.getWrapper() as Element, this.tagName);
197+
if (this.getWrapper()) {
198+
destroy(this, this.getWrapper() as Element, this.tagName);
199+
}
195200
if (this.refreshing) {
196201
['e-control', 'e-switch', 'e-lib'].forEach((key: string) => {
197202
this.element.classList.add(key);
@@ -514,14 +519,18 @@ export class Switch extends Component<HTMLInputElement> implements INotifyProper
514519
}
515520
private unWireEvents(): void {
516521
const wrapper: Element = this.getWrapper() as Element;
517-
EventHandler.remove(wrapper, 'click', this.clickHandler);
518-
EventHandler.remove(this.element, 'focus', this.focusHandler);
519-
EventHandler.remove(this.element, 'focusout', this.focusOutHandler);
520-
EventHandler.remove(this.element, 'mouseup', this.delegateMouseUpHandler);
521-
EventHandler.remove(this.element, 'keyup', this.delegateKeyUpHandler);
522-
EventHandler.remove(wrapper, 'mousedown mouseup', this.rippleHandler);
523-
EventHandler.remove(wrapper, 'mouseleave', this.mouseLeaveHandler);
524-
EventHandler.remove(wrapper, 'touchstart touchmove touchend', this.switchMouseUp);
522+
if (wrapper) {
523+
EventHandler.remove(wrapper, 'click', this.clickHandler);
524+
EventHandler.remove(wrapper, 'mousedown mouseup', this.rippleHandler);
525+
EventHandler.remove(wrapper, 'mouseleave', this.mouseLeaveHandler);
526+
EventHandler.remove(wrapper, 'touchstart touchmove touchend', this.switchMouseUp);
527+
}
528+
if (this.element) {
529+
EventHandler.remove(this.element, 'focus', this.focusHandler);
530+
EventHandler.remove(this.element, 'focusout', this.focusOutHandler);
531+
EventHandler.remove(this.element, 'mouseup', this.delegateMouseUpHandler);
532+
EventHandler.remove(this.element, 'keyup', this.delegateKeyUpHandler);
533+
}
525534
}
526535

527536
/**

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+
## 29.2.5 (2025-05-21)
6+
7+
### DatePicker
8+
9+
#### Bug Fixes
10+
11+
- `#I711579` - Fixed an issue where the DatePicker popup did not close on mobile devices when clicking outside of it.
12+
513
## 29.1.40 (2025-04-29)
614

715
### DateRangePicker

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": "29.1.40",
3+
"version": "29.2.4",
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/src/datepicker/datepicker.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,10 +1145,13 @@ export class DatePicker extends Calendar implements IInput {
11451145
const target: HTMLElement = <HTMLElement>e.target;
11461146
if (!(closest(target, '.e-datepicker.e-popup-wrapper')) && !isNullOrUndefined(this.inputWrapper)
11471147
&& !(closest(target, '.' + INPUTCONTAINER) === this.inputWrapper.container)
1148-
&& (!target.classList.contains('e-day'))
1149-
&& (!target.classList.contains('e-dlg-overlay'))) {
1148+
&& (!target.classList.contains('e-day'))) {
11501149
this.hide(e);
1151-
this.focusOut();
1150+
if (target.classList.contains('e-dlg-overlay')) {
1151+
e.preventDefault();
1152+
} else {
1153+
this.focusOut();
1154+
}
11521155
} else if (closest(target, '.e-datepicker.e-popup-wrapper')) {
11531156
// Fix for close the popup when select the previously selected value.
11541157
if ( target.classList.contains('e-day')

controls/calendars/src/datetimepicker/datetimepicker.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,10 +1180,14 @@ export class DateTimePicker extends DatePicker {
11801180
event.preventDefault();
11811181
}
11821182
if (!(closest(target, '[id="' + (this.popupObject && this.popupObject.element.id + '"]'))) && target !== this.inputElement
1183-
&& target !== this.timeIcon && !isNullOrUndefined(this.inputWrapper) && target !== this.inputWrapper.container && !target.classList.contains('e-dlg-overlay')) {
1183+
&& target !== this.timeIcon && !isNullOrUndefined(this.inputWrapper) && target !== this.inputWrapper.container) {
11841184
if (this.isTimePopupOpen()) {
11851185
this.hide(event);
1186-
this.focusOut();
1186+
if (target.classList.contains('e-dlg-overlay')) {
1187+
event.preventDefault();
1188+
} else {
1189+
this.focusOut();
1190+
}
11871191
}
11881192
} else if (target !== this.inputElement) {
11891193
if (!Browser.isDevice) {

controls/calendars/src/timepicker/timepicker.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,11 +2454,14 @@ export class TimePicker extends Component<HTMLElement> implements IInput {
24542454
if (!(closest(target, '[id="' + this.popupObj.element.id + '"]')) && target !== this.inputElement
24552455
&& target !== (this.inputWrapper && this.inputWrapper.buttons[0]) &&
24562456
target !== (this.inputWrapper && this.inputWrapper.clearButton) &&
2457-
target !== (this.inputWrapper && this.inputWrapper.container)
2458-
&& (!target.classList.contains('e-dlg-overlay'))) {
2457+
target !== (this.inputWrapper && this.inputWrapper.container)) {
24592458
if (this.isPopupOpen()) {
24602459
this.hide();
2461-
this.focusOut();
2460+
if (target.classList.contains('e-dlg-overlay')) {
2461+
event.preventDefault();
2462+
} else {
2463+
this.focusOut();
2464+
}
24622465
}
24632466
} else if (target !== this.inputElement) {
24642467
if (!Browser.isDevice) {

controls/charts/CHANGELOG.md

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

33
## [Unreleased]
44

5+
## 29.2.5 (2025-05-21)
6+
7+
### Chart
8+
9+
#### Features
10+
11+
- `#I668455` - Provided support for setting offset values for labels in category axes.
12+
13+
#### Bug Fixes
14+
15+
- `#I722486` - Chart empty point mode now works properly in ASP.NET MVC Chart.
16+
- `#I725935` - Console error no longer occurs when toggling combination line and stacked area series.
17+
518
## 29.2.4 (2025-05-14)
619

720
### Chart

controls/charts/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-charts",
3-
"version": "29.1.41",
3+
"version": "29.2.4",
44
"description": "Feature-rich chart control with built-in support for over 25 chart types, technical indictors, trendline, zooming, tooltip, selection, crosshair and trackball.",
55
"author": "Syncfusion Inc.",
66
"license": "SEE LICENSE IN license",

controls/charts/src/chart/axis/axis-model.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,14 @@ export interface AxisModel {
762762
*/
763763
description?: string;
764764

765+
/**
766+
* Specifies an offset value that determines where the first label appears on the category axis.
767+
* This helps control the alignment of axis labels by shifting the starting position.
768+
*
769+
* @default null
770+
*/
771+
intervalOffset?: number;
772+
765773
/**
766774
* The `tabIndex` value for the axis, determining its position in the tab order.
767775
*

controls/charts/src/chart/axis/axis.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,15 @@ export class Axis extends ChildProperty<Axis> {
936936
@Property(null)
937937
public description: string;
938938

939+
/**
940+
* Specifies an offset value that determines where the first label appears on the category axis.
941+
* This helps control the alignment of axis labels by shifting the starting position.
942+
*
943+
* @default null
944+
*/
945+
@Property(null)
946+
public intervalOffset: number;
947+
939948
/**
940949
* The `tabIndex` value for the axis, determining its position in the tab order.
941950
*

controls/charts/src/chart/axis/category-axis.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export class Category extends NiceInterval {
100100
/** Generate axis labels */
101101
axis.visibleLabels = [];
102102
axis.visibleRange.interval = axis.visibleRange.interval < 1 ? 1 : axis.visibleRange.interval;
103-
let tempInterval: number = Math.ceil(axis.visibleRange.min);
103+
let tempInterval: number = axis.intervalOffset ? axis.intervalOffset : Math.ceil(axis.visibleRange.min);
104104
let labelStyle: Font;
105105
if (axis.zoomFactor < 1 || axis.zoomPosition > 0) {
106106
tempInterval = axis.visibleRange.min - (axis.visibleRange.min % axis.visibleRange.interval);

controls/charts/src/chart/series/stacking-area-series.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class StackingAreaSeries extends LineBase {
5757
if (visiblePoints[i as number].visible && withInRange(visiblePoints[i - 1], visiblePoints[i as number],
5858
visiblePoints[i + 1], series)) {
5959
const startvalue: number = series.index > 0 && index !== undefined ?
60-
this.chart.visibleSeries[index as number].stackedValues.endValues[pointIndex as number] :
60+
this.chart.visibleSeries[series.index as number].stackedValues.endValues[pointIndex as number] :
6161
stackedvalue.startValues[pointIndex as number];
6262
point1 = getCoordinate(
6363
visiblePoints[i as number].xValue, (!series.visible && series.isLegendClicked) ? startvalue :
@@ -118,7 +118,8 @@ export class StackingAreaSeries extends LineBase {
118118
const previousSeries: Series = this.getPreviousSeries(series);
119119
if (previousSeries.emptyPointSettings.mode !== 'Drop' || !previousSeries.points[j as number].isEmpty) {
120120
point2 = getCoordinate(visiblePoints[j as number].xValue, (!series.visible && series.isLegendClicked && series.index > 0
121-
&& index !== undefined) ? this.chart.visibleSeries[index as number].stackedValues.endValues[pointIndex as number]
121+
&& index !== undefined) ?
122+
this.chart.visibleSeries[series.index as number].stackedValues.endValues[pointIndex as number]
122123
: stackedvalue.startValues[pointIndex as number], xAxis, yAxis, isInverted, series);
123124
if (stackedvalue.startValues[pointIndex as number] === stackedvalue.endValues[pointIndex as number]) {
124125
point2.y = Math.floor(point2.y);

controls/charts/src/common/model/base-model.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ export interface EmptyPointSettingsModel {
612612
* @default Gap
613613
*/
614614

615-
mode?: EmptyPointMode | AccEmptyPointMode;
615+
mode?: EmptyPointMode;
616616

617617
}
618618

controls/charts/src/common/model/base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ export class EmptyPointSettings extends ChildProperty<EmptyPointSettings> {
671671
*/
672672

673673
@Property('Gap')
674-
public mode: EmptyPointMode | AccEmptyPointMode;
674+
public mode: EmptyPointMode;
675675
}
676676

677677
/**

controls/diagrams/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#### Bug Fixes
1010

11-
- `#I952617` - Connectors in the layout will now render with the correct appearance when a specific type is explicitly defined in the `getConnectorDefaults` function.
11+
- `#I713407` - Connectors in the layout will now render with the correct appearance when a specific type is explicitly defined in the `getConnectorDefaults` function.
1212
- `#F196439` - Independent nodes in complex hierarchical trees will now render without overlapping other nodes.
1313
- `#I700206` - Now connectors will not overlap nodes of varying size in layout.
1414
- `#I713490` - Now the nodes will have property defined in `getNodeDefaults` on performing undo and redo.

0 commit comments

Comments
 (0)