From a48098f4de2f6e7682b862d14f35df90554383e6 Mon Sep 17 00:00:00 2001 From: desig9stein Date: Mon, 8 Dec 2025 14:06:22 +0200 Subject: [PATCH 1/6] fix(calendar): ensure text in calendar components does not wrap unexpectedly --- .../src/core/styles/components/calendar/_calendar-theme.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/projects/igniteui-angular/core/src/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/core/src/core/styles/components/calendar/_calendar-theme.scss index cf67ef36662..9492cf98962 100644 --- a/projects/igniteui-angular/core/src/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/core/src/core/styles/components/calendar/_calendar-theme.scss @@ -2516,6 +2516,7 @@ letter-spacing: sizable(var(--ig-body-2-letter-spacing), var(--ig-body-2-letter-spacing), var(--ig-body-1-letter-spacing)); text-transform: sizable(var(--ig-body-2-text-transform), var(--ig-body-2-text-transform), var(--ig-body-1-text-transform)); margin: 0; + white-space: nowrap; } } @@ -2528,6 +2529,7 @@ letter-spacing: sizable(var(--ig-body-2-letter-spacing), var(--ig-body-2-letter-spacing), var(--ig-body-1-letter-spacing)); text-transform: sizable(var(--ig-body-2-text-transform), var(--ig-body-2-text-transform), var(--ig-body-1-text-transform)); margin: 0; + white-space: nowrap; } } } From 2f8d7ae38ccc9487789073f421e3b0c0cba85a3f Mon Sep 17 00:00:00 2001 From: desig9stein Date: Tue, 9 Dec 2025 14:10:08 +0200 Subject: [PATCH 2/6] fix(calendar): update days formatting logic to extract day part and add additional locales in sample --- .../src/calendar/days-view/days-view.component.ts | 3 ++- src/app/calendar/calendar.sample.ts | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts index d704c218e5f..7886a1252f3 100644 --- a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts @@ -446,7 +446,8 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af */ public formattedDate(value: Date): string { if (this.formatViews.day) { - return this.formatterDay.format(value); + const dateParts = this.formatterDay.formatToParts(value); + return dateParts.find(part => part.type === 'day')?.value ?? value.getDate().toString(); } return `${value.getDate()}`; diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index b24ae47380c..098dfcf5241 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -19,6 +19,7 @@ import { DateRange, DateRangeDescriptor, DateRangeType, + IFormattingViews, } from 'igniteui-angular'; import { Properties, @@ -62,6 +63,12 @@ export class CalendarSampleComponent implements OnInit { year: 'numeric', }; + protected formatViews: IFormattingViews = { + day: true, + month: true, + year: true + }; + public panelConfig: PropertyPanelConfig = { locale: { label: 'Change Locale', @@ -87,6 +94,10 @@ export class CalendarSampleComponent implements OnInit { { value: 'ja-JP', label: 'JP' + }, + { + value: 'zh-ZH', + label: 'ZH' } ], defaultValue: 'en-US' From 303cedec83cbe1a12f6a6643da4266bf1d76a143 Mon Sep 17 00:00:00 2001 From: desig9stein Date: Tue, 9 Dec 2025 14:17:24 +0200 Subject: [PATCH 3/6] fix(calendar): correct locale codes in sample for Chinese regions --- src/app/calendar/calendar.sample.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index 098dfcf5241..83f6c5b9b6d 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -96,8 +96,8 @@ export class CalendarSampleComponent implements OnInit { label: 'JP' }, { - value: 'zh-ZH', - label: 'ZH' + value: 'zh-CN', + label: 'CN' } ], defaultValue: 'en-US' From f5737f6239bf1aa39d1bb6b4eb019e5dde03f5ff Mon Sep 17 00:00:00 2001 From: desig9stein Date: Wed, 10 Dec 2025 13:37:22 +0200 Subject: [PATCH 4/6] fix(calendar): add DayDigitPipe to handle non-numeric day characters in locales like zh-CN - Introduced DayDigitPipe to strip non-numeric characters from localized day strings. - Updated `IgxDaysViewComponent` to use the new pipe in the day formatting logic. - Added a test to verify correct formatting for zh-CN locale. --- .../calendar/src/calendar/day-digit.pipe.ts | 23 +++++++++++++ .../days-view/days-view.component.html | 2 +- .../days-view/days-view.component.spec.ts | 32 +++++++++++++++++++ .../calendar/days-view/days-view.component.ts | 6 ++-- src/app/calendar/calendar.sample.html | 1 + 5 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts diff --git a/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts b/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts new file mode 100644 index 00000000000..f746af1c34e --- /dev/null +++ b/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts @@ -0,0 +1,23 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { IFormattingViews } from "igniteui-angular/calendar"; + +@Pipe({ name: 'dayDigit' }) +export class DayDigitPipe implements PipeTransform { + public transform(value: string, formatViews: IFormattingViews): string { + if (!value) { + return ''; + } + + // strip non-numeric characters that might have been added by the locale formatter (e.g., "25日" -> "25"). + if (formatViews.day) { + // Use regex to extract the numeric day value. + // This handles locales that include non-numeric characters (e.g. '25日' in zh-CN). + // match(/\d+/) is preferred over parseInt() as it robustly finds the digits regardless + // of their position (prefix/suffix) in the localized string. + const match = value.match(/\d+/); + return match ? match[0] : value; + } + + return value; + } +} diff --git a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.html b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.html index 96a403d93b3..a1ee994727d 100644 --- a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.html +++ b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.html @@ -81,7 +81,7 @@ (mouseEnter)="changePreviewRange(day.native)" (mouseLeave)="clearPreviewRange()" > - {{ formattedDate(day.native) }} + {{ formattedDate(day.native) | dayDigit:formatViews }} } diff --git a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.spec.ts b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.spec.ts index cf2fac8ad27..33397177da8 100644 --- a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.spec.ts +++ b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.spec.ts @@ -7,6 +7,7 @@ import { ScrollDirection } from "../calendar"; import { KeyboardNavigationService } from '../calendar.services'; import { CalendarDay } from 'igniteui-angular/core'; import { UIInteractions } from '../../../../test-utils/ui-interactions.spec'; +import { DayDigitPipe } from "igniteui-angular/calendar/src/calendar/day-digit.pipe"; const TODAY = new Date(2024, 6, 12); @@ -114,6 +115,37 @@ describe("Days View Component", () => { } }); + it("should format date correctly for zh-CN locale programmatically vs template pipe", () => { + const fixture = TestBed.createComponent(InitDaysViewComponent); + const daysView = fixture.componentInstance.instance; + const pipe = new DayDigitPipe(); + const date = new Date(2020, 10, 25); // Nov 25 + + // Initialize component + daysView.formatViews = { day: true, month: true, year: true }; + fixture.detectChanges(); + + // Mock the formatter behavior + // Simulate a locale (like zh-CN) that adds a suffix to the day number. + // Cast to 'any' to overwrite the protected 'formatterDay' property used by formattedDate() + (daysView as any).formatterDay = { + format: () => '25日', + } as Intl.DateTimeFormat; + + // 1. Verify Programmatic Access (formattedDate method) + // Should return the raw formatted string from the formatter (with suffix) + const programmaticResult = daysView.formattedDate(date); + expect(programmaticResult).toBe('25日', 'Programmatic API should return the full locale string (including suffix, in this case 日)'); + + // 2. Verify Pipe Logic + // The pipe takes the formatted string "25日" and strips non-digits to return "25" + const pipeResult = pipe.transform(programmaticResult, daysView.formatViews); + expect(pipeResult).toBe('25', 'Pipe should strip non-numeric characters from the input string'); + + // 3. Confirm the difference implies the pipe did its job + expect(programmaticResult).not.toEqual(pipeResult); + }); + describe("Keyboard navigation", () => { let fixture: ComponentFixture; let el: HTMLElement; diff --git a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts index 7886a1252f3..c9b5243e38d 100644 --- a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts @@ -37,6 +37,7 @@ import { import { IgxCalendarBaseDirective } from '../calendar-base'; import { IViewChangingEventArgs } from './days-view.interface'; import { KeyboardNavigationService } from '../calendar.services'; +import { DayDigitPipe } from "igniteui-angular/calendar/src/calendar/day-digit.pipe"; let NEXT_ID = 0; @@ -52,7 +53,7 @@ let NEXT_ID = 0; selector: 'igx-days-view', templateUrl: 'days-view.component.html', changeDetection: ChangeDetectionStrategy.OnPush, - imports: [IgxDayItemComponent, TitleCasePipe] + imports: [IgxDayItemComponent, TitleCasePipe, DayDigitPipe] }) export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements AfterContentChecked { protected el = inject(ElementRef); @@ -446,8 +447,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af */ public formattedDate(value: Date): string { if (this.formatViews.day) { - const dateParts = this.formatterDay.formatToParts(value); - return dateParts.find(part => part.type === 'day')?.value ?? value.getDate().toString(); + return this.formatterDay.format(value); } return `${value.getDate()}`; diff --git a/src/app/calendar/calendar.sample.html b/src/app/calendar/calendar.sample.html index b381413e398..f56f8b3fff0 100644 --- a/src/app/calendar/calendar.sample.html +++ b/src/app/calendar/calendar.sample.html @@ -14,6 +14,7 @@ [showWeekNumbers]="properties.showWeekNumbers" [hasHeader]="!properties.hideHeader" [formatOptions]="formatOptions" + [formatViews]="formatViews" [disabledDates]="disabledDates" [specialDates]="specialDates" (selected)="onSelection($event)" From 536682d463924bbec8d40a352445fd2a71fc865d Mon Sep 17 00:00:00 2001 From: desig9stein Date: Wed, 10 Dec 2025 13:55:24 +0200 Subject: [PATCH 5/6] chore(calendar): update DayDigitPipe paths - Updated `DayDigitPipe` import paths to use relative paths. --- .../igniteui-angular/calendar/src/calendar/day-digit.pipe.ts | 2 +- .../calendar/src/calendar/days-view/days-view.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts b/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts index f746af1c34e..3f52eb4cace 100644 --- a/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts +++ b/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts @@ -1,5 +1,5 @@ import { Pipe, PipeTransform } from '@angular/core'; -import { IFormattingViews } from "igniteui-angular/calendar"; +import { IFormattingViews } from "./calendar"; @Pipe({ name: 'dayDigit' }) export class DayDigitPipe implements PipeTransform { diff --git a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts index c9b5243e38d..56343ead24e 100644 --- a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts @@ -37,7 +37,7 @@ import { import { IgxCalendarBaseDirective } from '../calendar-base'; import { IViewChangingEventArgs } from './days-view.interface'; import { KeyboardNavigationService } from '../calendar.services'; -import { DayDigitPipe } from "igniteui-angular/calendar/src/calendar/day-digit.pipe"; +import { DayDigitPipe } from "../day-digit.pipe"; let NEXT_ID = 0; From 54d2846165e0ccdc3bebcfa8486eec0be27675be Mon Sep 17 00:00:00 2001 From: desig9stein Date: Wed, 10 Dec 2025 13:58:12 +0200 Subject: [PATCH 6/6] chore(calendar): mark DayDigitPipe as standalone --- .../igniteui-angular/calendar/src/calendar/day-digit.pipe.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts b/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts index 3f52eb4cace..392ddbf98b5 100644 --- a/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts +++ b/projects/igniteui-angular/calendar/src/calendar/day-digit.pipe.ts @@ -1,7 +1,10 @@ import { Pipe, PipeTransform } from '@angular/core'; import { IFormattingViews } from "./calendar"; -@Pipe({ name: 'dayDigit' }) +@Pipe({ + name: 'dayDigit', + standalone: true +}) export class DayDigitPipe implements PipeTransform { public transform(value: string, formatViews: IFormattingViews): string { if (!value) {