Skip to content

Commit b40ad91

Browse files
authored
feat(module:float-button): add pop animation to float button menu (#9413)
1 parent c0ba8e7 commit b40ad91

File tree

5 files changed

+82
-17
lines changed

5 files changed

+82
-17
lines changed

components/float-button/float-button-group.component.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ describe('nz-float-button-group', () => {
149149
fixture.detectChanges();
150150
expect(resultEl.nativeElement.classList).not.toContain('ant-float-btn-group-right');
151151
});
152+
153+
it('should get correct animation class according to nzPlacement', () => {
154+
fixture.detectChanges();
155+
// @ts-ignore
156+
const { enterAnimation, leaveAnimation } = groupComponent;
157+
expect(enterAnimation()).toBe('ant-float-btn-enter-top');
158+
expect(leaveAnimation()).toBe('ant-float-btn-leave-top');
159+
testComponent.nzPlacement = 'right';
160+
fixture.detectChanges();
161+
expect(enterAnimation()).toBe('ant-float-btn-enter-right');
162+
expect(leaveAnimation()).toBe('ant-float-btn-leave-right');
163+
});
152164
});
153165
});
154166
});

components/float-button/float-button-group.component.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
TemplateRef
1919
} from '@angular/core';
2020

21-
import { fadeMotion } from 'ng-zorro-antd/core/animation';
2221
import { NzFourDirectionType, NzShapeSCType } from 'ng-zorro-antd/core/types';
2322
import { generateClassName } from 'ng-zorro-antd/core/util';
2423
import { NzIconModule } from 'ng-zorro-antd/icon';
@@ -34,13 +33,14 @@ const CLASS_NAME = 'ant-float-btn-group';
3433
exportAs: 'nzFloatButtonGroup',
3534
imports: [NzFloatButtonComponent, NzIconModule, NgTemplateOutlet],
3635
changeDetection: ChangeDetectionStrategy.OnPush,
37-
animations: [fadeMotion],
3836
template: `
3937
@if (!isMenuMode()) {
4038
<ng-container *ngTemplateOutlet="menu"></ng-container>
4139
} @else {
4240
@if (open()) {
43-
<div class="ant-float-btn-group-wrap" @fadeMotion><ng-container *ngTemplateOutlet="menu"></ng-container></div>
41+
<div class="ant-float-btn-group-wrap" [animate.enter]="enterAnimation()" [animate.leave]="leaveAnimation()">
42+
<ng-container *ngTemplateOutlet="menu"></ng-container>
43+
</div>
4444
}
4545
<nz-float-button
4646
class="ant-float-btn-group-trigger"
@@ -77,11 +77,13 @@ export class NzFloatButtonGroupComponent {
7777
readonly nzPlacement = input<NzFourDirectionType>('top');
7878
readonly nzOnOpenChange = output<boolean>();
7979

80-
protected dir = inject(Directionality).valueSignal;
81-
protected open = linkedSignal<boolean>(() => !!this.nzOpen());
82-
protected isMenuMode = computed(() => !!this.nzTrigger() && ['click', 'hover'].includes(this.nzTrigger() as string));
83-
protected isControlledMode = computed(() => this.nzOpen() !== null);
84-
protected class = computed<string[]>(() => {
80+
protected readonly dir = inject(Directionality).valueSignal;
81+
protected readonly open = linkedSignal<boolean>(() => !!this.nzOpen());
82+
protected readonly isMenuMode = computed(
83+
() => !!this.nzTrigger() && ['click', 'hover'].includes(this.nzTrigger() as string)
84+
);
85+
protected readonly isControlledMode = computed(() => this.nzOpen() !== null);
86+
protected readonly class = computed<string[]>(() => {
8587
const shape = this.nzShape();
8688
const dir = this.dir();
8789
const classes = [CLASS_NAME, this.generateClass(shape)];
@@ -95,6 +97,8 @@ export class NzFloatButtonGroupComponent {
9597
}
9698
return classes;
9799
});
100+
protected readonly enterAnimation = computed(() => `ant-float-btn-enter-${this.nzPlacement()}`);
101+
protected readonly leaveAnimation = computed(() => `ant-float-btn-leave-${this.nzPlacement()}`);
98102

99103
constructor() {
100104
effect(() => {

components/float-button/float-button-top.component.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { Subject, Subscription } from 'rxjs';
3131
import { debounceTime, takeUntil } from 'rxjs/operators';
3232

3333
import { fadeMotion } from 'ng-zorro-antd/core/animation';
34-
import { NzConfigService, withConfigFactory } from 'ng-zorro-antd/core/config';
34+
import { withConfigFactory } from 'ng-zorro-antd/core/config';
3535
import { NzScrollService } from 'ng-zorro-antd/core/services';
3636
import { NzShapeSCType } from 'ng-zorro-antd/core/types';
3737
import { fromEventOutsideAngular, generateClassName } from 'ng-zorro-antd/core/util';
@@ -72,13 +72,12 @@ const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: t
7272
encapsulation: ViewEncapsulation.None
7373
})
7474
export class NzFloatButtonTopComponent implements OnInit {
75-
public nzConfigService = inject(NzConfigService);
76-
private scrollSrv = inject(NzScrollService);
77-
private platform = inject(Platform);
78-
private ngZone = inject(NgZone);
79-
private directionality = inject(Directionality);
80-
private destroyRef = inject(DestroyRef);
81-
private document = inject(DOCUMENT);
75+
private readonly scrollSrv = inject(NzScrollService);
76+
private readonly platform = inject(Platform);
77+
private readonly ngZone = inject(NgZone);
78+
private readonly directionality = inject(Directionality);
79+
private readonly destroyRef = inject(DestroyRef);
80+
private readonly document = inject(DOCUMENT);
8281

8382
readonly backTop = viewChild('backTop', { read: ElementRef });
8483

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* stylelint-disable less/no-duplicate-variables */
2+
@import '../../style/themes/index';
3+
4+
@float-btn-prefix-cls: ~'@{ant-prefix}-float-btn';
5+
@animation-duration: 0.3s;
6+
@slide-distance: 40px;
7+
8+
.animation(@direction, @type) {
9+
&-@{type}-@{direction} {
10+
animation: ~"@{type}-@{direction}" @animation-duration ease-in-out;
11+
}
12+
}
13+
14+
.keyframes(@name; @from-opacity; @to-opacity; @from-transform; @to-transform) {
15+
@keyframes @name {
16+
from {
17+
transform: @from-transform;
18+
opacity: @from-opacity;
19+
}
20+
21+
to {
22+
transform: @to-transform;
23+
opacity: @to-opacity;
24+
}
25+
}
26+
}
27+
28+
.@{float-btn-prefix-cls} {
29+
// animation class
30+
.animation(top, enter);
31+
.animation(top, leave);
32+
.animation(bottom, enter);
33+
.animation(bottom, leave);
34+
.animation(left, enter);
35+
.animation(left, leave);
36+
.animation(right, enter);
37+
.animation(right, leave);
38+
39+
// keyframes
40+
.keyframes(enter-top; 0; 1; translateY(@slide-distance); translateY(0));
41+
.keyframes(leave-top; 1; 0; translateY(0); translateY(@slide-distance));
42+
.keyframes(enter-bottom; 0; 1; translateY(-@slide-distance); translateY(0));
43+
.keyframes(leave-bottom; 1; 0; translateY(0); translateY(-@slide-distance));
44+
.keyframes(enter-left; 0; 1; translateX(@slide-distance); translateX(0));
45+
.keyframes(leave-left; 1; 0; translateX(0); translateX(@slide-distance));
46+
.keyframes(enter-right; 0; 1; translateX(-@slide-distance); translateX(0));
47+
.keyframes(leave-right; 1; 0; translateX(0); translateX(-@slide-distance));
48+
}
49+
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
@import './index.less';
1+
@import './index.less';
2+
@import './animation.less';

0 commit comments

Comments
 (0)