Skip to content

Commit 49f15c2

Browse files
authored
fix(button): prevent style flickering on initial render (#16137)
1 parent f716f83 commit 49f15c2

File tree

4 files changed

+62
-12
lines changed

4 files changed

+62
-12
lines changed

projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@
6161
$variant
6262
);
6363

64-
$button-transition: color $time ease-in-out,
65-
background-color $time ease-in-out,
66-
border-color $time ease-in-out,
67-
box-shadow $time ease-in-out;
64+
$button-transition: color var(--_init-transition, #{$time}) ease-in-out,
65+
background-color var(--_init-transition, #{$time}) ease-in-out,
66+
border-color var(--_init-transition, #{$time}) ease-in-out,
67+
box-shadow var(--_init-transition, #{$time}) ease-in-out;
6868

6969
$button-disabled-shadow: none;
7070

projects/igniteui-angular/src/lib/core/styles/components/icon-button/_icon-button-theme.scss

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@
7373
-webkit-tap-highlight-color: transparent;
7474
overflow: hidden;
7575
white-space: nowrap;
76-
transition: box-shadow .2s ease-in, background .15s ease-out;
77-
transition-delay: .05s;
76+
transition:
77+
box-shadow var(--_init-transition, .2s) ease-in,
78+
background var(--_init-transition, .15s) ease-out;
79+
transition-delay: var(--_init-transition, .05s);
7880
min-width: unset;
7981
min-height: unset;
8082
font-size: rem(24px, 24px);
@@ -95,7 +97,9 @@
9597
}
9698

9799
@if $variant == 'fluent' {
98-
transition: color .15s ease-out, background .15s ease-out;
100+
transition:
101+
color var(--_init-transition, .15s) ease-out,
102+
background var(--_init-transition, .15s) ease-out;
99103

100104
&::after {
101105
position: absolute;
@@ -109,11 +113,18 @@
109113
}
110114

111115
@if $variant == 'bootstrap' {
112-
transition: box-shadow .15s ease-out, color .15s ease-out, background .15s ease-out;
116+
transition:
117+
box-shadow var(--_init-transition, .15s) ease-out,
118+
color var(--_init-transition, .15s) ease-out,
119+
background var(--_init-transition, .15s) ease-out;
113120
}
114121

115122
@if $variant == 'indigo' {
116-
transition: color .15s ease-in-out, box-shadow .15s ease-in-out, background .15s ease-in-out, border-color .15s ease-in-out;
123+
transition:
124+
color var(--_init-transition, .15s) ease-in-out,
125+
box-shadow var(--_init-transition, .15s) ease-in-out,
126+
background var(--_init-transition, .15s) ease-in-out,
127+
border-color var(--_init-transition, .15s) ease-in-out;
117128
}
118129
}
119130

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
1-
import { Directive, ElementRef, EventEmitter, HostBinding, HostListener, Input, Output, booleanAttribute } from '@angular/core';
1+
import {
2+
Directive,
3+
ElementRef,
4+
EventEmitter,
5+
HostBinding,
6+
HostListener,
7+
Input,
8+
Output,
9+
booleanAttribute,
10+
inject,
11+
afterRenderEffect,
12+
} from '@angular/core';
13+
import { PlatformUtil } from '../../core/utils';
214

315
export const IgxBaseButtonType = {
416
Flat: 'flat',
517
Contained: 'contained',
618
Outlined: 'outlined'
719
} as const;
820

21+
922
@Directive()
1023
export abstract class IgxButtonBaseDirective {
24+
private _platformUtil = inject(PlatformUtil);
25+
1126
/**
1227
* Emitted when the button is clicked.
1328
*/
@@ -79,7 +94,25 @@ export abstract class IgxButtonBaseDirective {
7994
return this.disabled || null;
8095
}
8196

82-
constructor(public element: ElementRef) { }
97+
protected constructor(
98+
public element: ElementRef,
99+
) {
100+
// In browser, set via native API for immediate effect (no-op on server).
101+
// In SSR there is no paint, so there’s no visual rendering or transitions to suppress.
102+
// Fix style flickering https://github.com/IgniteUI/igniteui-angular/issues/14759
103+
if (this._platformUtil.isBrowser) {
104+
afterRenderEffect({
105+
write: () => {
106+
this.element.nativeElement.style.setProperty('--_init-transition', '0s');
107+
},
108+
read: () => {
109+
requestAnimationFrame(() => {
110+
this.element.nativeElement.style.removeProperty('--_init-transition');
111+
});
112+
}
113+
});
114+
}
115+
}
83116

84117
/**
85118
* @hidden

projects/igniteui-angular/src/lib/directives/button/icon-button.directive.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Directive, HostBinding, Input } from '@angular/core';
1+
import {Directive, ElementRef, HostBinding, Input} from '@angular/core';
22
import { IgxBaseButtonType, IgxButtonBaseDirective } from './button-base';
33

44
/**
@@ -78,4 +78,10 @@ export class IgxIconButtonDirective extends IgxButtonBaseDirective {
7878
public get outlined(): boolean {
7979
return this._type === IgxBaseButtonType.Outlined;
8080
}
81+
82+
constructor(
83+
public override element: ElementRef,
84+
) {
85+
super(element);
86+
}
8187
}

0 commit comments

Comments
 (0)