Skip to content

Commit e92799f

Browse files
authored
Merge branch 'master' into gedinakova/pdf-unicode-support
2 parents 9d978d7 + 404ad9a commit e92799f

File tree

14 files changed

+151
-56
lines changed

14 files changed

+151
-56
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Pipe, PipeTransform } from '@angular/core';
2+
import { IFormattingViews } from "./calendar";
3+
4+
@Pipe({
5+
name: 'dayDigit',
6+
standalone: true
7+
})
8+
export class DayDigitPipe implements PipeTransform {
9+
public transform(value: string, formatViews: IFormattingViews): string {
10+
if (!value) {
11+
return '';
12+
}
13+
14+
// strip non-numeric characters that might have been added by the locale formatter (e.g., "25日" -> "25").
15+
if (formatViews.day) {
16+
// Use regex to extract the numeric day value.
17+
// This handles locales that include non-numeric characters (e.g. '25日' in zh-CN).
18+
// match(/\d+/) is preferred over parseInt() as it robustly finds the digits regardless
19+
// of their position (prefix/suffix) in the localized string.
20+
const match = value.match(/\d+/);
21+
return match ? match[0] : value;
22+
}
23+
24+
return value;
25+
}
26+
}

projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
(mouseEnter)="changePreviewRange(day.native)"
8282
(mouseLeave)="clearPreviewRange()"
8383
>
84-
{{ formattedDate(day.native) }}
84+
{{ formattedDate(day.native) | dayDigit:formatViews }}
8585
</igx-day-item>
8686
}
8787
</div>

projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ScrollDirection } from "../calendar";
77
import { KeyboardNavigationService } from '../calendar.services';
88
import { CalendarDay } from 'igniteui-angular/core';
99
import { UIInteractions } from '../../../../test-utils/ui-interactions.spec';
10+
import { DayDigitPipe } from "igniteui-angular/calendar/src/calendar/day-digit.pipe";
1011

1112
const TODAY = new Date(2024, 6, 12);
1213

@@ -114,6 +115,37 @@ describe("Days View Component", () => {
114115
}
115116
});
116117

118+
it("should format date correctly for zh-CN locale programmatically vs template pipe", () => {
119+
const fixture = TestBed.createComponent(InitDaysViewComponent);
120+
const daysView = fixture.componentInstance.instance;
121+
const pipe = new DayDigitPipe();
122+
const date = new Date(2020, 10, 25); // Nov 25
123+
124+
// Initialize component
125+
daysView.formatViews = { day: true, month: true, year: true };
126+
fixture.detectChanges();
127+
128+
// Mock the formatter behavior
129+
// Simulate a locale (like zh-CN) that adds a suffix to the day number.
130+
// Cast to 'any' to overwrite the protected 'formatterDay' property used by formattedDate()
131+
(daysView as any).formatterDay = {
132+
format: () => '25日',
133+
} as Intl.DateTimeFormat;
134+
135+
// 1. Verify Programmatic Access (formattedDate method)
136+
// Should return the raw formatted string from the formatter (with suffix)
137+
const programmaticResult = daysView.formattedDate(date);
138+
expect(programmaticResult).toBe('25日', 'Programmatic API should return the full locale string (including suffix, in this case 日)');
139+
140+
// 2. Verify Pipe Logic
141+
// The pipe takes the formatted string "25日" and strips non-digits to return "25"
142+
const pipeResult = pipe.transform(programmaticResult, daysView.formatViews);
143+
expect(pipeResult).toBe('25', 'Pipe should strip non-numeric characters from the input string');
144+
145+
// 3. Confirm the difference implies the pipe did its job
146+
expect(programmaticResult).not.toEqual(pipeResult);
147+
});
148+
117149
describe("Keyboard navigation", () => {
118150
let fixture: ComponentFixture<InitDaysViewComponent>;
119151
let el: HTMLElement;

projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
import { IgxCalendarBaseDirective } from '../calendar-base';
3838
import { IViewChangingEventArgs } from './days-view.interface';
3939
import { KeyboardNavigationService } from '../calendar.services';
40+
import { DayDigitPipe } from "../day-digit.pipe";
4041

4142
let NEXT_ID = 0;
4243

@@ -52,7 +53,7 @@ let NEXT_ID = 0;
5253
selector: 'igx-days-view',
5354
templateUrl: 'days-view.component.html',
5455
changeDetection: ChangeDetectionStrategy.OnPush,
55-
imports: [IgxDayItemComponent, TitleCasePipe]
56+
imports: [IgxDayItemComponent, TitleCasePipe, DayDigitPipe]
5657
})
5758
export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements AfterContentChecked {
5859
protected el = inject(ElementRef);

projects/igniteui-angular/core/src/core/styles/components/calendar/_calendar-theme.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,6 +2516,7 @@
25162516
letter-spacing: sizable(var(--ig-body-2-letter-spacing), var(--ig-body-2-letter-spacing), var(--ig-body-1-letter-spacing));
25172517
text-transform: sizable(var(--ig-body-2-text-transform), var(--ig-body-2-text-transform), var(--ig-body-1-text-transform));
25182518
margin: 0;
2519+
white-space: nowrap;
25192520
}
25202521
}
25212522

@@ -2528,6 +2529,7 @@
25282529
letter-spacing: sizable(var(--ig-body-2-letter-spacing), var(--ig-body-2-letter-spacing), var(--ig-body-1-letter-spacing));
25292530
text-transform: sizable(var(--ig-body-2-text-transform), var(--ig-body-2-text-transform), var(--ig-body-1-text-transform));
25302531
margin: 0;
2532+
white-space: nowrap;
25312533
}
25322534
}
25332535
}

projects/igniteui-angular/core/src/core/styles/components/slider/_slider-theme.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
// https://github.com/IgniteUI/igniteui-angular/issues/11597
9090
z-index: 0;
9191
height: $slider-height;
92-
flex-grow: 1;
9392
align-items: center;
9493
transition: all .2s $out-quad;
9594
touch-action: pan-y pinch-zoom;

projects/igniteui-angular/core/src/core/styles/components/tabs/_tabs-theme.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
display: flex;
5757
flex-direction: column;
5858
overflow: hidden;
59+
text-align: initial;
5960
}
6061

6162
%tabs-header {
@@ -322,7 +323,7 @@
322323
var-get($theme, 'item-active-hover-background') 1px,
323324
var-get($theme, 'item-active-hover-background') calc(100% - 1px),
324325
var-get($theme, 'border-color') calc(100% - 1px)
325-
);
326+
);
326327
}
327328
}
328329
}

projects/igniteui-angular/directives/src/directives/button/button-base.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import {
99
booleanAttribute,
1010
inject,
1111
AfterViewInit,
12+
OnDestroy
1213
} from '@angular/core';
1314
import { PlatformUtil } from 'igniteui-angular/core';
15+
import { animationFrameScheduler, Subscription } from 'rxjs';
1416

1517
export const IgxBaseButtonType = {
1618
Flat: 'flat',
@@ -20,10 +22,11 @@ export const IgxBaseButtonType = {
2022

2123

2224
@Directive()
23-
export abstract class IgxButtonBaseDirective implements AfterViewInit{
25+
export abstract class IgxButtonBaseDirective implements AfterViewInit, OnDestroy {
2426
private _platformUtil = inject(PlatformUtil);
2527
public element = inject(ElementRef);
26-
private _viewInit = false;
28+
private _viewInit = false;
29+
private _animationScheduler: Subscription;
2730

2831
/**
2932
* Emitted when the button is clicked.
@@ -109,12 +112,16 @@ export abstract class IgxButtonBaseDirective implements AfterViewInit{
109112
if (this._platformUtil.isBrowser && !this._viewInit) {
110113
this._viewInit = true;
111114

112-
requestAnimationFrame(() => {
115+
this._animationScheduler = animationFrameScheduler.schedule(() => {
113116
this.element.nativeElement.style.removeProperty('--_init-transition');
114117
});
115118
}
116119
}
117120

121+
public ngOnDestroy(): void {
122+
this._animationScheduler.unsubscribe();
123+
}
124+
118125
/**
119126
* @hidden
120127
* @internal

projects/igniteui-angular/grids/core/src/columns/column.component.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2672,13 +2672,15 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy
26722672
* @hidden
26732673
* @internal
26742674
*/
2675-
public getConstrainedSizePx(newSize){
2676-
if (this.maxWidth && newSize > this.maxWidthPx) {
2675+
public getConstrainedSizePx(newSize) {
2676+
if (this.maxWidth && newSize >= this.maxWidthPx) {
26772677
this.widthConstrained = true;
26782678
return this.maxWidthPx;
2679-
} else if (this.minWidth && newSize < this.userSetMinWidthPx) {
2679+
} else if (this.minWidth && newSize <= this.userSetMinWidthPx) {
26802680
this.widthConstrained = true;
26812681
return this.userSetMinWidthPx;
2682+
} else if (!this.minWidth && (!this.widthSetByUser || this.width === 'fit-content') && !this.grid.columnWidthSetByUser && (!newSize || newSize <= this.grid.minColumnWidth)) {
2683+
return this.grid.minColumnWidth;
26822684
} else {
26832685
this.widthConstrained = false;
26842686
return newSize;
@@ -2701,11 +2703,11 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy
27012703
} else if (!colWidth || isAutoWidth && !this.autoSize) {
27022704
// no width
27032705
const currentCalcWidth = this.defaultWidth || this.grid.getPossibleColumnWidth();
2704-
this._calcWidth = this.getConstrainedSizePx(currentCalcWidth);
2706+
this._calcWidth = this.getConstrainedSizePx(parseFloat(currentCalcWidth));
27052707
} else {
27062708
let possibleColumnWidth = '';
27072709
if (!this.widthSetByUser && this.userSetMinWidthPx && this.userSetMinWidthPx < this.grid.minColumnWidth) {
2708-
possibleColumnWidth = this.defaultWidth = this.grid.getPossibleColumnWidth(null, this.userSetMinWidthPx);
2710+
possibleColumnWidth = this.defaultWidth = this.grid.getPossibleColumnWidth();
27092711
} else {
27102712
possibleColumnWidth = this.width;
27112713
}

projects/igniteui-angular/grids/core/src/common/grid.interface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ export interface GridType extends IGridDataBindable {
905905
refreshSearch(): void;
906906
getDefaultExpandState(record: any): boolean;
907907
trackColumnChanges(index: number, column: any): any;
908-
getPossibleColumnWidth(baseWidth?: number, minColumnWidth?: number): string;
908+
getPossibleColumnWidth(baseWidth?: number): string;
909909
resetHorizontalVirtualization(): void;
910910
hasVerticalScroll(): boolean;
911911
getVisibleContentHeight(): number;

0 commit comments

Comments
 (0)