Skip to content

Commit b1e7c68

Browse files
oburdasovoburdasov
andauthored
feat: new popover-confirm component (#UIM-810) (#729)
* feat: added popover-confirm component based on popover * feat: popover-confirm refactoring * feat: popover-confirm code review fixes * feat: popover-confirm inject text + change dev example * feat(popover): add tests for popover-confirm + fixes (#UIM-810) * feat(popover): add popover-confirm in examples (#UIM-810) * feat(popover): code review fixes (#UIM-810) Co-authored-by: oburdasov <[email protected]>
1 parent 4c31e6b commit b1e7c68

File tree

10 files changed

+348
-31
lines changed

10 files changed

+348
-31
lines changed

packages/mosaic-dev/popover/module.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export class DemoComponent {
3434

3535
ELEMENTS = {
3636
BUTTON: 'button',
37+
CONFIRM_BUTTON: 'confirm-button',
3738
INPUT: 'input',
3839
ICON: 'icon'
3940
};
@@ -50,15 +51,18 @@ export class DemoComponent {
5051
SMALL: 'small'
5152
};
5253

53-
selectedElement: string = 'button';
54+
selectedElement: string = this.ELEMENTS.BUTTON;
5455
selectedPlacement: PopUpPlacements = PopUpPlacements.Left;
55-
selectedTrigger: string = 'click';
56+
selectedTrigger: string = this.TRIGGERS.CLICK;
5657
selectedSize: PopUpSizes = PopUpSizes.Normal;
5758
layoutClass: string = 'layout-row layout-align-center-center';
5859
content: string = 'button text';
5960
userDefinedPlacementPriority: string[] = ['bottom', 'right'];
6061
multipleSelected: string[] = [];
6162

63+
confirmText: string = 'Вы уверены, что хотите продолжить?';
64+
confirmButtonText: string = 'Да';
65+
6266
constructor() {
6367
this.popoverActiveStage = 1;
6468
}
@@ -110,6 +114,10 @@ export class DemoComponent {
110114
get isFallbackActivated(): boolean {
111115
return this.selectedPlacement !== this.activatedPosition && this.activatedPosition !== '';
112116
}
117+
118+
onConfirm() {
119+
alert('confirmed');
120+
}
113121
}
114122

115123
@NgModule({

packages/mosaic-dev/popover/template.html

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,37 +45,38 @@
4545

4646
<mc-form-field id="element" class="mc-form__control">
4747
<mc-select [(value)]="selectedElement" [placeholder]="'Select element'">
48-
<mc-option [value]="'button'">Button</mc-option>
49-
<mc-option [value]="'icon'">Icon</mc-option>
50-
<mc-option [value]="'input'">Input</mc-option>
48+
<mc-option [value]="ELEMENTS.BUTTON">Button</mc-option>
49+
<mc-option [value]="ELEMENTS.CONFIRM_BUTTON">Confirm Button</mc-option>
50+
<mc-option [value]="ELEMENTS.ICON">Icon</mc-option>
51+
<mc-option [value]="ELEMENTS.INPUT">Input</mc-option>
5152
</mc-select>
5253
</mc-form-field>
5354
</div>
5455

55-
<div class="mc-form__row">
56+
<div class="mc-form__row" [style.display]="(selectedElement === ELEMENTS.CONFIRM_BUTTON) ? 'none' : 'initial'">
5657
<label for="trigger" class="mc-form__label">
5758
Choose popover trigger
5859
</label>
5960

6061
<mc-form-field id="trigger" class="mc-form__control">
6162
<mc-select [(value)]="selectedTrigger" [placeholder]="'Select trigger'">
62-
<mc-option [value]="'click'">Click</mc-option>
63-
<mc-option [value]="'hover'">Hover</mc-option>
64-
<mc-option [value]="'focus'">Focus</mc-option>
63+
<mc-option [value]="TRIGGERS.CLICK">Click</mc-option>
64+
<mc-option [value]="TRIGGERS.HOVER">Hover</mc-option>
65+
<mc-option [value]="TRIGGERS.FOCUS">Focus</mc-option>
6566
</mc-select>
6667
</mc-form-field>
6768
</div>
6869

69-
<div class="mc-form__row">
70+
<div class="mc-form__row" [style.display]="(selectedElement === ELEMENTS.CONFIRM_BUTTON) ? 'none' : 'initial'">
7071
<label for="size" class="mc-form__label">
7172
Choose popover size
7273
</label>
7374

7475
<mc-form-field id="size" class="mc-form__control">
7576
<mc-select [(value)]="selectedSize" [placeholder]="'Select size'">
76-
<mc-option [value]="'small'">Small</mc-option>
77-
<mc-option [value]="'normal'">Normal</mc-option>
78-
<mc-option [value]="'large'">Large</mc-option>
77+
<mc-option [value]="SIZE.SMALL">Small</mc-option>
78+
<mc-option [value]="SIZE.NORMAL">Normal</mc-option>
79+
<mc-option [value]="SIZE.LARGE">Large</mc-option>
7980
</mc-select>
8081
</mc-form-field>
8182
</div>
@@ -99,6 +100,26 @@
99100
</mc-select>
100101
</mc-form-field>
101102
</div>
103+
104+
<div class="mc-form__row" [style.display]="(selectedElement === ELEMENTS.CONFIRM_BUTTON) ? 'initial' : 'none'">
105+
<label for="layout" class="mc-form__label">
106+
Set confirm text
107+
</label>
108+
109+
<mc-form-field id="layout" class="mc-form__control">
110+
<input mcInput [(ngModel)]="confirmText"/>
111+
</mc-form-field>
112+
</div>
113+
114+
<div class="mc-form__row" [style.display]="(selectedElement === ELEMENTS.CONFIRM_BUTTON) ? 'initial' : 'none'">
115+
<label for="layout" class="mc-form__label">
116+
Set confirm button text
117+
</label>
118+
119+
<mc-form-field id="layout" class="mc-form__control">
120+
<input mcInput [(ngModel)]="confirmButtonText"/>
121+
</mc-form-field>
122+
</div>
102123
</div>
103124
<div class="flex left-padding layout-align-center-center">
104125
<label for="trigger" class="flex mc-form__label">
@@ -233,6 +254,19 @@ <h3>Configuration:</h3>
233254
(mcPopoverVisibleChange)="onPopoverVisibleChange($event)">
234255
Button
235256
</button>
257+
<button mc-button
258+
*ngSwitchCase="ELEMENTS.CONFIRM_BUTTON"
259+
mcPopoverConfirm
260+
(confirm)="onConfirm()"
261+
[mcPopoverConfirmText]="confirmText"
262+
[mcPopoverConfirmButtonText]="confirmButtonText"
263+
[mcPopoverClass]="'popover-485'"
264+
[mcPopoverPlacement]="selectedPlacement"
265+
[mcPopoverPlacementPriority]="multipleSelected"
266+
(mcPopoverPlacementChange)="onStrategyPlacementChange($event)"
267+
(mcVisibleChange)="onPopoverVisibleChange($event)">
268+
Confirm Button
269+
</button>
236270
<mc-form-field *ngSwitchCase="ELEMENTS.INPUT">
237271
<input mcInput
238272
[(ngModel)]="content"

packages/mosaic-examples/mosaic/popover/popover-overview/popover-overview-example.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<mc-form-field id="element" class="mc-form__control">
4747
<mc-select [(value)]="selectedElement" [placeholder]="'Select element'">
4848
<mc-option [value]="'button'">Button</mc-option>
49+
<mc-option [value]="'confirm-button'">Confirm Button</mc-option>
4950
<mc-option [value]="'icon'">Icon</mc-option>
5051
<mc-option [value]="'input'">Input</mc-option>
5152
</mc-select>
@@ -217,6 +218,17 @@ <h3>Configuration:</h3>
217218
(mcVisibleChange)="onPopoverVisibleChange($event)">
218219
Button
219220
</button>
221+
<button mc-button
222+
*ngSwitchCase="ELEMENTS.CONFIRM_BUTTON"
223+
mcPopoverConfirm
224+
(confirm)="onConfirm()"
225+
[mcPopoverClass]="'popover-485'"
226+
[mcPopoverPlacement]="selectedPlacement"
227+
[mcPopoverPlacementPriority]="multipleSelected"
228+
(mcPopoverPlacementChange)="onStrategyPlacementChange($event)"
229+
(mcVisibleChange)="onPopoverVisibleChange($event)">
230+
Confirm Button
231+
</button>
220232
<mc-form-field *ngSwitchCase="ELEMENTS.INPUT">
221233
<input mcInput
222234
[(ngModel)]="content"

packages/mosaic-examples/mosaic/popover/popover-overview/popover-overview-example.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class PopoverOverviewExample {
2323

2424
ELEMENTS = {
2525
BUTTON: 'button',
26+
CONFIRM_BUTTON: 'confirm-button',
2627
INPUT: 'input',
2728
ICON: 'icon'
2829
};
@@ -92,4 +93,8 @@ export class PopoverOverviewExample {
9293
get isFallbackActivated(): boolean {
9394
return this.selectedPlacement !== this.activatedPosition && this.activatedPosition !== '';
9495
}
96+
97+
onConfirm() {
98+
alert('Подтверждено');
99+
}
95100
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div class="mc-popover-confirm mc-popover"
2+
[ngClass]="classMap"
3+
[@state]="visibility"
4+
(@state.start)="animationStart()"
5+
(@state.done)="animationDone($event)">
6+
<div class="mc-popover__content">
7+
<div>{{ confirmText }}</div>
8+
<button mc-button [color]="themePalette.Primary" (click)="onConfirm.next()">{{confirmButtonText}}</button>
9+
</div>
10+
11+
<div class="mc-popover__arrow"></div>
12+
</div>
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import { Directionality } from '@angular/cdk/bidi';
2+
import { Overlay, ScrollDispatcher } from '@angular/cdk/overlay';
3+
import {
4+
ChangeDetectionStrategy,
5+
ChangeDetectorRef,
6+
Component,
7+
Directive,
8+
ElementRef,
9+
EventEmitter,
10+
Inject,
11+
InjectionToken,
12+
Input,
13+
NgZone,
14+
Optional,
15+
Output,
16+
ViewContainerRef,
17+
ViewEncapsulation
18+
} from '@angular/core';
19+
import { ThemePalette } from '@ptsecurity/mosaic/core';
20+
import { Subject } from 'rxjs';
21+
import { takeUntil } from 'rxjs/operators';
22+
23+
import { mcPopoverAnimations } from './popover-animations';
24+
import { MC_POPOVER_SCROLL_STRATEGY, McPopoverComponent, McPopoverTrigger } from './popover.component';
25+
26+
27+
export const MC_POPOVER_CONFIRM_TEXT = new InjectionToken<string>('');
28+
export const MC_POPOVER_CONFIRM_BUTTON_TEXT = new InjectionToken<string>('');
29+
30+
@Component({
31+
selector: 'mc-popover-confirm-component',
32+
templateUrl: './popover-confirm.component.html',
33+
preserveWhitespaces: false,
34+
styleUrls: ['./popover.scss'],
35+
encapsulation: ViewEncapsulation.None,
36+
changeDetection: ChangeDetectionStrategy.OnPush,
37+
animations: [mcPopoverAnimations.popoverState]
38+
})
39+
export class McPopoverConfirmComponent extends McPopoverComponent {
40+
themePalette = ThemePalette;
41+
42+
onConfirm = new Subject<void>();
43+
confirmButtonText: string;
44+
45+
confirmText: string;
46+
47+
constructor(changeDetectorRef: ChangeDetectorRef) {
48+
super(changeDetectorRef);
49+
}
50+
}
51+
52+
53+
@Directive({
54+
selector: '[mcPopoverConfirm]',
55+
exportAs: 'mcPopoverConfirm',
56+
host: {
57+
'[class.mc-popover_open]': 'isOpen',
58+
'(keydown)': 'handleKeydown($event)',
59+
'(touchend)': 'handleTouchend()'
60+
}
61+
})
62+
export class McPopoverConfirmTrigger extends McPopoverTrigger {
63+
@Output() confirm: EventEmitter<void> = new EventEmitter<void>();
64+
65+
@Input('mcPopoverConfirmText')
66+
get confirmText(): string {
67+
return this._confirmText;
68+
}
69+
70+
set confirmText(value: string) {
71+
this._confirmText = value;
72+
73+
this.updateData();
74+
}
75+
76+
private _confirmText: string;
77+
78+
@Input('mcPopoverConfirmButtonText')
79+
get confirmButtonText(): string {
80+
return this._confirmButtonText;
81+
}
82+
83+
set confirmButtonText(value: string) {
84+
this._confirmButtonText = value;
85+
86+
this.updateData();
87+
}
88+
89+
private _confirmButtonText: string = 'Да';
90+
91+
constructor(
92+
overlay: Overlay,
93+
elementRef: ElementRef,
94+
ngZone: NgZone,
95+
scrollDispatcher: ScrollDispatcher,
96+
hostView: ViewContainerRef,
97+
@Inject(MC_POPOVER_SCROLL_STRATEGY) scrollStrategy,
98+
@Optional() direction: Directionality,
99+
@Optional() @Inject(MC_POPOVER_CONFIRM_TEXT) confirmText: string,
100+
@Optional() @Inject(MC_POPOVER_CONFIRM_BUTTON_TEXT) confirmButtonText: string
101+
) {
102+
super(overlay, elementRef, ngZone, scrollDispatcher, hostView, scrollStrategy, direction);
103+
104+
this.confirmText = confirmText || 'Вы уверены, что хотите продолжить?';
105+
this.confirmButtonText = confirmButtonText || 'Да';
106+
}
107+
108+
updateData() {
109+
if (!this.instance) { return; }
110+
super.updateData();
111+
this.setupButtonEvents();
112+
this.instance.confirmButtonText = this.confirmButtonText;
113+
this.instance.confirmText = this.confirmText;
114+
}
115+
116+
setupButtonEvents() {
117+
this.instance.onConfirm.pipe(takeUntil(this.destroyed)).subscribe(() => {
118+
this.confirm.emit();
119+
this.hide();
120+
});
121+
}
122+
123+
getOverlayHandleComponentType() {
124+
return McPopoverConfirmComponent;
125+
}
126+
}
Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import { OverlayModule } from '@angular/cdk/overlay';
22
import { CommonModule } from '@angular/common';
33
import { NgModule } from '@angular/core';
4+
import { McButtonModule } from '@ptsecurity/mosaic/button';
45

5-
import {
6-
McPopoverComponent,
7-
McPopoverTrigger,
8-
MC_POPOVER_SCROLL_STRATEGY_FACTORY_PROVIDER
9-
} from './popover.component';
6+
import { McPopoverConfirmComponent, McPopoverConfirmTrigger } from './popover-confirm.component';
7+
import { MC_POPOVER_SCROLL_STRATEGY_FACTORY_PROVIDER, McPopoverComponent, McPopoverTrigger } from './popover.component';
108

119

1210
@NgModule({
13-
declarations: [McPopoverComponent, McPopoverTrigger],
14-
exports: [McPopoverComponent, McPopoverTrigger],
15-
imports: [CommonModule, OverlayModule],
11+
declarations: [McPopoverComponent, McPopoverTrigger, McPopoverConfirmComponent, McPopoverConfirmTrigger],
12+
exports: [McPopoverComponent, McPopoverTrigger, McPopoverConfirmComponent, McPopoverConfirmTrigger],
13+
imports: [CommonModule, OverlayModule, McButtonModule],
1614
providers: [MC_POPOVER_SCROLL_STRATEGY_FACTORY_PROVIDER],
17-
entryComponents: [McPopoverComponent]
15+
entryComponents: [McPopoverComponent, McPopoverConfirmComponent]
1816
})
1917
export class McPopoverModule {}

packages/mosaic/popover/popover.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,13 @@ $arrow-offset: calc((var(--mc-popover-size-arrow-size, #{$popover-size-arrow-siz
9292
$arrow-padding: calc(18px - var(--mc-popover-size-trigger-margin, #{$popover-size-trigger-margin}));
9393

9494
@include popUpArrowPositions(mc-popover, $arrow-offset, $arrow-padding);
95+
96+
.mc-popover-confirm .mc-popover__content {
97+
padding: 24px 16px 16px;
98+
99+
button {
100+
margin-top: 16px;
101+
display: block;
102+
margin-left: auto;
103+
}
104+
}

0 commit comments

Comments
 (0)