Further Environment Informations
Component: @progress/kendo-angular-treeview
Severity: regression (worked in v23, broken in v24)
rxjs: 7.8.2
zone.js 0.15.1 (zone-based, not zoneless)
typescript 6.0.3
Summary
When a flat [nodes] array is bound to kendo-treeview and the array reference is replaced after the first change-detection pass, the TreeView keeps rendering the initial nodes and never reflects the new data. In v23.x the same binding updated correctly.
Minimal reproduction (standalone, drop into a blank Angular 22 app / StackBlitz)
import { Component, signal } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { TreeViewModule } from '@progress/kendo-angular-treeview';
interface Node { name: string; }
@Component({
selector: 'app-root',
standalone: true,
imports: [TreeViewModule],
template: `
<button (click)="replaceNodes()">Replace nodes</button>
<p>Plain list (control — reflects the current data):</p>
<ul>
@for (n of nodes(); track n.name) { <li>{{ n.name }}</li> }
</ul>
<p>Kendo TreeView (bug — stays on the initial data):</p>
<kendo-treeview
[nodes]="nodes()"
textField="name"
[kendoTreeViewSelectable]="{ enabled: false }"
>
<ng-template kendoTreeViewNodeTemplate let-dataItem>
{{ dataItem.name }}
</ng-template>
</kendo-treeview>
`,
})
export class AppComponent {
protected readonly nodes = signal<Node[]>([{ name: 'A' }, { name: 'B' }]);
protected replaceNodes(): void {
this.nodes.set([{ name: 'X' }, { name: 'Y' }, { name: 'Z' }]);
}
}
bootstrapApplication(AppComponent).catch(err => console.error(err));
Steps to reproduce
1. Load the component — TreeView renders A, B.
2. Click Replace nodes (assigns a brand-new array [X, Y, Z]).
Expected
The TreeView re-renders and shows X, Y, Z (like the plain <ul> control right above it, which updates correctly — proving the data really changed and change detection ran).
Actual (v24.2.2)
The TreeView still shows A, B. The new [nodes] reference is ignored.
Regression
Identical code updated correctly on @progress/kendo-angular-treeview 23.x. It broke on the upgrade to 24.x. Bisecting across 24.0.0 → 24.2.2 would pinpoint the exact patch.
Current workaround
Force the TreeView to be destroyed and recreated whenever the data reference changes:
@for (nodes of [data()]; track nodes) {
<kendo-treeview [nodes]="nodes" textField="name" ...>...</kendo-treeview>
}
This works but is obviously undesirable (full teardown/rebuild on every data change, loss of internal state).
Hi,
This works with Angular 20, must be a change related to that.
If I assign data to the TreeView synchronously, it works, but e.g. in a setTimeout, it doesn't any more. (I assign the full array, change detection is set to eager.)
Reproduction can be found here: https://codesandbox.io/p/devbox/mutable-glade-39twhs?workspaceId=ws_P4gPDf6RC2r5W8xExWQehV
Best regards,
Michael
`@progress/kendo-intl` incorrectly formats timezone offsets whose minute component is non-zero.
For example, a JavaScript `Date` with the historical Warsaw offset `UTC+01:24` is formatted as `+01:04` instead of `+01:24`.
This affects all tested `Z`, `X`, and `x` timezone format variants.
- `@progress/kendo-angular-intl`: `24.2.0`
- `@progress/kendo-intl`: `3.2.1`
- Browser/Node timezone: `Europe/Warsaw`
- Operating system: Windows
- Format: `yyyy-MM-ddTHH:mm:ssZZZZZ`
The same formatting implementation appears in `@progress/kendo-intl` versions `3.1.2` and `3.2.1`.
const { formatDate } = require('@progress/kendo-intl');
process.env.TZ = 'Europe/Warsaw';
const date = new Date(1900, 0, 1, 16, 0, 0);
console.log(date.toString());
console.log(date.getTimezoneOffset());
console.log(formatDate(date, 'yyyy-MM-ddTHH:mm:ssZZZZZ'));Mon Jan 01 1900 16:00:00 GMT+0124
-84
1900-01-01T16:00:00+01:041900-01-01T16:00:00+01:24Date#getTimezoneOffset() returns -84, meaning the local timezone is 84 minutes ahead of UTC:
84 minutes = 1 hour 24 minutesThe issue is not limited to positive offsets:
getTimezoneOffset() | Expected | Actual |
|---|---|---|
-84 | +01:24 | +01:04 |
210 | -03:30 | -03:05 |
UTC is also formatted differently depending on the token, but that behavior may be intentional:
| Offset | Expected ISO representation | ZZZZZ result |
|---|---|---|
0 | +00:00 or Z | Z |
All applicable format variants use the same incorrect minute calculation:
Z -> +0104
ZZ -> +0104
ZZZ -> +0104
ZZZZ -> GMT+01:04
ZZZZZ -> +01:04
X -> +0104
XX -> +0104
XXX -> +01:04
XXXX -> +0104
XXXXX -> +01:04
x -> +0104
xxx -> +01:04
xxxxx -> +01:04Changing from ZZZZZ to XXXXX or XXX therefore does not resolve the problem.
The current formatter appears to perform approximately this calculation:
const offset = date.getTimezoneOffset() / 60;
const hoursMinutes = Math.abs(offset).toString().split('.');
const minutes = hoursMinutes[1] || 0;For an 84-minute offset:
84 / 60 = 1.4The decimal portion "4" is then treated as four minutes and padded to "04".
However, the fractional part represents a fraction of an hour:
0.4 hours * 60 = 24 minutesLikewise, for 210 minutes:
210 / 60 = 3.5The formatter produces 03:05, although 0.5 hours is 30 minutes.
Timezone offsets should remain integer minute values throughout formatting:
function formatTimeZone(date, info, options) {
const totalMinutes = date.getTimezoneOffset();
const absoluteMinutes = Math.abs(totalMinutes);
const hours = Math.floor(absoluteMinutes / 60);
const minutes = absoluteMinutes % 60;
const sign = totalMinutes <= 0 ? '+' : '-';
// Continue applying shortHours, separator, optionalMinutes,
// localizedName and zZeroOffset options using hours and minutes.
}The important calculations are:
const hours = Math.floor(Math.abs(offsetMinutes) / 60);
const minutes = Math.abs(offsetMinutes) % 60;Converting the offset to a decimal hour and splitting its string representation is not reliable.
it('formats a positive timezone offset with minutes', () => {
const date = new Date(2024, 5, 25, 12, 7, 5);
vi.spyOn(date, 'getTimezoneOffset').mockReturnValue(-84);
expect(formatDate(date, 'yyyy-MM-ddTHH:mm:ssZZZZZ'))
.toBe('2024-06-25T12:07:05+01:24');
});
it('formats a negative timezone offset with minutes', () => {
const date = new Date(2024, 5, 25, 12, 7, 5);
vi.spyOn(date, 'getTimezoneOffset').mockReturnValue(210);
expect(formatDate(date, 'yyyy-MM-ddTHH:mm:ssZZZZZ'))
.toBe('2024-06-25T12:07:05-03:30');
});Other useful cases include:
-345 -> +05:45
-330 -> +05:30
210 -> -03:30
0 -> Z or +00:00, depending on the selected token
This can corrupt serialized date-time values when they are passed to systems that honor the emitted offset, including .NET DateTimeOffset.
Example:
Intended: 1900-01-01T16:00:00+01:24
Emitted: 1900-01-01T16:00:00+01:04These values represent instants 20 minutes apart.
The issue affects:
Date implementation returning a non-whole-hour offset.Examples of modern fractional offsets include UTC+05:30, UTC+05:45, UTC+09:30, and UTC-03:30.
We initially encountered this with Europe/Warsaw and 1900-01-01. The JavaScript runtime correctly reports Warsaw's historical offset as UTC+01:24. The incorrect UTC+01:04 value is introduced only during Kendo formatting.
We have implemented a temporary application-level workaround that formats the date portion with Kendo and calculates the timezone offset directly from integer minutes.
When dateinput format is "d/M/y" and "allowCaretMode" is enabled, users are unable to enter valid dates. Tested with dateinput and datepicker components.
https://stackblitz.com/edit/angular-kendo-dateinput-bug-rdocwtvr
The user should be able to enter a full year, month, and day after typing a valid single-digit day and month.
After entering a single-digit day and month, the input locks up, preventing the user from typing more than one character for the year or month. This prevents users from entering valid dates, making the input unusable in this scenario.
Thanks
The built-in kendoDropDownFilter directive normalizes text using String.prototype.toLowerCase() when caseSensitive: false. This is locale-insensitive and produces incorrect results for languages with non-standard case-folding rules, most notably Turkish.
The correct fix is to use String.prototype.toLocaleLowerCase(locale), which respects locale-specific case rules. The DropDownFilterSettings interface should expose a locale option for this:
filterSettings = {
caseSensitive: false,
operator: 'startsWith',
locale: 'tr-TR' // ← proposed new option
};Affected components: kendoDropDownFilter directive (used with AutoCompleteComponent, ComboBoxComponent, MultiColumnComboBoxComponent, DropDownListComponent, MultiSelectComponent).
Signal Forms are now stable with Angular@22.
It would be nice to have an ability to use all kendo widgets with new form API.
For the Kendo DatePicker, if you try to set the size on a kendo-datepicker with plain text, it will not render and give a console error of "ERROR TypeError: Cannot read properties of undefined (reading 'nativeElement')".
Errors:
// HTML
<kendo-datepicker size="small" ... />
---
But on the other hand, it does work if you create a field of type "DateInputSize" and pass that variable to the size.
Works:// TS
protected size: DateInputSize = 'small';
// HTML
<kendo-datepicker [size]="size" ... />
Hi,
When the first day of the week is changed dynamically through a custom IntlService, the Calendar weekday headers are updated, but the date cells are not repositioned. (The first day is changed as described in your guide: https://www.telerik.com/kendo-angular-ui/components/knowledge-base/calendar-first-day )
Reproduction (forked from your example): https://stackblitz.com/edit/angular-tqvypgwg
Click on "Set first day to Monday ": the weekday headers are updated to start with Monday, but the date cells remain in their previous positions.
Best regards,
Michael
You're docs say
Open the example in a new window to evaluate it with Axe Core or other accessibility tools. for the Kendo angular grid
When i do that i see the attached error, which is the same issue i get in our product when running playwright axe
That suggests to me that it is not WCAG 2.2 compliant
Ensure elements with an ARIA role that require child roles contain them
more information.demo-frame.loaded.demo-module--wrap--718a6 > .demo-module--demoWrap--d1437 > .demo-module--explorerWrap--4bf1f.flex-grow-1 > .demo-module--demoBody--97eee > iframe #k-fbe44131-4768-4755-93c3-e321b714780e<div role="grid" kendodragtargetcontainer="" kendodroptargetcontainer="" mode="manual" class="k-grid-aria-root" id="k-fbe44131-4768-4755-93c3-e321b714780e" aria-label="Data table" aria-rowcount="62" aria-colcount="5">Element has children which are not allowed: div[tabindex]
I have tested kendo grid accessibility with AXE Dev tool. Found following errors that seems difficult to fix.
1)Certain ARIA roles must contain particular children
2)Scrollable region must have keyboard access
Any suggestion to fix these above-mentioned issues could be very helpful. Noticed these issues even exist in kendo grid demos published in kendo documentation. Check the link below
stack blitz link : https://stackblitz.com/edit/angular-uhjyd3x9?file=src%2Findex.html
When a tooltip of a dialog is shown and the dialog is closed, the tooltip is still present and is moved into the top left corner.
We use e.g. `kendo-dialog-titlebar` and the close button has a tooltip.
Hi,
if I use both the features locked columns and sticky rows, the sticky rows do not stick in the locked columns.
For me it would be logical if they would stick there too (now the UI looks inconsistent):
Reproduction (forked from your example): https://stackblitz.com/edit/angular-wak7v99i
Can you please take a look at it?
Best regards,
Michael
Hi,
if I change the [placeholder] input on a kendo-editor, the changes are not reflected.
Reproduction (forked from your example): https://stackblitz.com/edit/angular-uqbchubd
Can you please take a look at it?
Best regards,
Michael
The DrawerAnimation interface isn't exposed in the index file.
DrawerItem, DrawerMode, and DrawerPosition are all exported but DrawerAnimation is missing.
In firefox, open the Kendo Radio Button documentation and slowly resize the window (https://www.telerik.com/kendo-angular-ui/components/inputs/radiobutton)
The radio button will kind of jiggle around and occasionally the white dot in the radio button will become off-center.

This also seems to happen in response to some material bouncy (cubic-bezier) animation transitions.
The directive `kendoGridColumnChooserTool` does not work correctly when having columns which are grouped. See this example: https://stackblitz.com/edit/angular-r9duqpcn?file=src%2Fapp%2Fapp.component.ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {
KENDO_GRID,
KENDO_GRID_EXCEL_EXPORT,
KENDO_GRID_PDF_EXPORT,
} from '@progress/kendo-angular-grid';
import { KENDO_TOOLBAR } from '@progress/kendo-angular-toolbar';
import { KENDO_LABELS } from '@progress/kendo-angular-label';
import { KENDO_INPUTS } from '@progress/kendo-angular-inputs';
import { KENDO_BUTTONS } from '@progress/kendo-angular-buttons';
import { Product } from './model';
import { products } from './products';
@Component({
selector: 'my-app',
standalone: true,
imports: [
FormsModule,
KENDO_GRID_EXCEL_EXPORT,
KENDO_GRID_PDF_EXPORT,
KENDO_GRID,
KENDO_BUTTONS,
KENDO_TOOLBAR,
KENDO_LABELS,
KENDO_INPUTS,
],
template: `
<kendo-grid
[kendoGridBinding]="products"
[pageSize]="5"
[pageable]="true"
[sortable]="{ mode: 'multiple' }"
[style.width.%]="gridWidth"
>
<ng-template kendoGridToolbarTemplate position="bottom">
<kendo-grid-column-chooser></kendo-grid-column-chooser>
</ng-template>
<kendo-toolbar overflow="scroll">
<kendo-toolbar-button kendoGridColumnChooserTool></kendo-toolbar-button>
</kendo-toolbar>
<kendo-grid-column-group title="TestA">
<kendo-grid-column
field="ProductName"
title="Product Name"
></kendo-grid-column>
</kendo-grid-column-group>
<kendo-grid-column-group title="TestB">
<kendo-grid-column
field="UnitPrice"
filter="numeric"
title="Price"
></kendo-grid-column>
<kendo-grid-column
field="Discontinued"
filter="boolean"
title="Discontinued"
></kendo-grid-column>
<kendo-grid-column
field="UnitsInStock"
filter="numeric"
title="Units In Stock"
></kendo-grid-column>
</kendo-grid-column-group>
</kendo-grid>
`,
styles: [
`
.example-info {
background: rgba(83, 146, 228, 0.1);
border-radius: 2px;
margin: 10px auto 10px auto;
padding: 15px;
border-left: 4px solid #5392e4;
font-size: 14px;
}
`,
],
})
export class AppComponent {
public gridWidth: number = 100;
public products: Product[] = products;
}
Hello Support,
There is a feature request for this, but I see this as a bug. The Agenda view in the scheduler is advertised to work perfectly on mobile, but I would expect to see the event column one way or another. Now you can only see timeslots, which is not that useful. Can you fix it by making the event column available, maybe as part of the time as text or some other solution.
Ran this on StackBlitz
import { Component } from '@angular/core';
import {
LegendLabelsContentArgs,
SeriesClickEvent,
} from '@progress/kendo-angular-charts';
import { IntlService } from '@progress/kendo-angular-intl';
@Component({
selector: 'my-app',
template: `
<kendo-chart
(plotAreaClick)="onClick($event)"
[transitions]="false"
title="World Population by Broad Age Groups"
>
<kendo-chart-legend position="bottom"></kendo-chart-legend>
<kendo-chart-series>
<kendo-chart-series-item
type="donut"
[data]="pieData"
field="value"
categoryField="category"
explodeField="exploded"
[labels]="{ visible: true, content: labelContent }"
>
</kendo-chart-series-item>
</kendo-chart-series>
</kendo-chart>
`,
})
export class AppComponent {
public pieData: Array<{
category: string;
value: number;
exploded: boolean;
}> = [
{ category: '0-14', value: 0.2545, exploded: false },
{ category: '15-24', value: 0.1552, exploded: false },
{ category: '25-54', value: 0.4059, exploded: false },
{ category: '55-64', value: 0.0911, exploded: false },
{ category: '65+', value: 0.0933, exploded: false },
];
constructor(private intl: IntlService) {
this.labelContent = this.labelContent.bind(this);
}
public labelContent(args: LegendLabelsContentArgs): string {
return `${args.dataItem.category} years old: ${this.intl.formatNumber(
args.dataItem.value,
'p2'
)}`;
}
public onClick(event: any): void {
console.log('Click');
}
}
When the event is seriesClick, it works as expected, and if I change the type to bar, it works as expected, but when it's as shown as above, the onClick event isn't triggered.
As I have donuts/pies that might not have data in it, I needed to use plotAreaClick (which I have done for the bar charts)
Thanks,
Add support for Angular's Trusted Types to eliminate CSP compatibility issues and errors when using the Kendo UI for Angular components in applications with strict Trusted Types security policies.
At the moment, the internal logic of the Kendo UI for Angular components uses innerHTML in various scenarios, like placeholder content for virtualization, dynamic rendering of icons and indicators, etc.
Thus, when applications have strict CSP with Trusted Types enabled, developers encounter a "This document requires 'TrustedHTML' assignment" error.
Although all content set via innerHTML is internally controlled and secure, the Kendo UI for Angular components should work seamlessly in applications with strict CSP and Trusted Types policies without requiring developers to modify their security configuration.