From f9ddd6cefc5ac95e347bc2cea7c1a99c5e25b192 Mon Sep 17 00:00:00 2001 From: LeonVay Date: Mon, 25 May 2020 11:33:25 +0300 Subject: [PATCH] fix(popover): Popover wrong left positioning --- packages/mosaic-dev/popover/module.ts | 50 ++- packages/mosaic-dev/popover/styles.scss | 84 ++++ packages/mosaic-dev/popover/template.html | 399 ++++++++++++------- packages/mosaic/popover/popover.component.ts | 19 +- 4 files changed, 410 insertions(+), 142 deletions(-) diff --git a/packages/mosaic-dev/popover/module.ts b/packages/mosaic-dev/popover/module.ts index 1b6e06db7..fe8f975cd 100644 --- a/packages/mosaic-dev/popover/module.ts +++ b/packages/mosaic-dev/popover/module.ts @@ -6,6 +6,10 @@ import { McButtonModule } from '@ptsecurity/mosaic/button'; import { McPopoverModule } from '@ptsecurity/mosaic/popover'; import { McIconModule } from '../../mosaic/icon/'; +import { FormsModule } from '@angular/forms'; +import { McInputModule } from '@ptsecurity/mosaic/input'; +import { McFormFieldModule } from '@ptsecurity/mosaic/form-field'; +import { McSelectModule } from '@ptsecurity/mosaic/select'; /* tslint:disable:no-trailing-whitespace */ @@ -20,6 +24,31 @@ export class DemoComponent { isPopoverVisibleLeft: boolean = false; + ELEMENTS = { + BUTTON: 'button', + INPUT: 'input', + ICON: 'icon' + }; + + TRIGGERS = { + CLICK: 'click', + FOCUS: 'focus', + HOVER: 'hover' + }; + + SIZE = { + LARGE: 'large', + NORMAL: 'normal', + SMALL: 'small' + }; + + selectedElement: string = 'button'; + selectedPlacement: string = 'top'; + selectedTrigger: string = 'click'; + selectedSize: string = 'normal'; + layoutClass: string = 'flex layout-row layout-align-start-center'; + content: string = 'button text'; + constructor() { this.popoverActiveStage = 1; } @@ -44,6 +73,21 @@ export class DemoComponent { onPopoverVisibleChange() { console.log('onPopoverVisibleChange'); // tslint:disable-line:no-console } + + setPlacement(placement: string) { + console.log(placement); + this.selectedPlacement = placement; + } + + + showElement(): string { + return this.selectedElement; + } + + activated(value: string): boolean { + console.log(value, this.selectedPlacement); + return this.selectedPlacement === value; + } } @NgModule({ @@ -54,9 +98,13 @@ export class DemoComponent { BrowserModule, BrowserAnimationsModule, A11yModule, + FormsModule, + McFormFieldModule, + McSelectModule, McPopoverModule, McButtonModule, - McIconModule + McIconModule, + McInputModule ], bootstrap: [ DemoComponent diff --git a/packages/mosaic-dev/popover/styles.scss b/packages/mosaic-dev/popover/styles.scss index 3a2f9fac5..261f25526 100644 --- a/packages/mosaic-dev/popover/styles.scss +++ b/packages/mosaic-dev/popover/styles.scss @@ -16,6 +16,90 @@ app { justify-content: center; align-items: stretch; padding: 0 10%; + + .padding-32 { + padding: 32px; + } + + .visual-box { + height: 100px; + width: 240px; + border: 1px solid #575757; + position: relative; + margin: 50px; + + .visual-box--clickable { + height: 12px; + width: 12px; + position: absolute; + background: #4dc3ff; + cursor: pointer; + } + + .active { + background: red; + } + + &_placement-top-left { + top: -6px; + left: 10px; + } + + &_placement-top { + top: -6px; + left: calc(50% - 6px); + } + + &_placement-top-right { + top: -6px; + right: 10px; + } + + &_placement-left-top { + top: 10px; + left: -6px; + } + + &_placement-left { + top: calc(50% - 6px); + left: -6px; + } + + &_placement-left-bottom { + bottom: 10px; + left: -6px; + } + + &_placement-bottom-right { + bottom: -6px; + right: 10px; + } + + &_placement-bottom { + bottom: -6px; + right: calc(50% - 6px); + } + + &_placement-bottom-left { + bottom: -6px; + left: 10px; + } + + &_placement-right-bottom { + right: -6px; + bottom: 10px; + } + + &_placement-right { + right: -6px; + bottom: calc(50% - 6px); + } + + &_placement-right-top { + right: -6px; + top: 10px; + } + } } .popover-485 { diff --git a/packages/mosaic-dev/popover/template.html b/packages/mosaic-dev/popover/template.html index 36538387b..622d96e16 100644 --- a/packages/mosaic-dev/popover/template.html +++ b/packages/mosaic-dev/popover/template.html @@ -25,144 +25,271 @@ -
- - - -
+
+
+ + + Button + Icon + Input + + + + + Click + Hover + Focus + + + + + Small + Normal + Large + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Configuration:

+
    +
  • Popover size: {{selectedSize}}
  • +
  • Popover trigger: {{selectedTrigger}}
  • +
  • Popover anchor placement: {{selectedPlacement}}
  • +
  • Popover anchored element: {{selectedElement}}
  • +
  • Layout positioning: {{layoutClass}}
  • +
-
-
- - - - rightBottom - - -
+
+
-
- - - -
+ + + + + + + -
- - - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/mosaic/popover/popover.component.ts b/packages/mosaic/popover/popover.component.ts index fae01d2f5..5967a68c1 100644 --- a/packages/mosaic/popover/popover.component.ts +++ b/packages/mosaic/popover/popover.component.ts @@ -440,6 +440,10 @@ export class McPopover implements OnInit, OnDestroy { private manualListeners = new Map(); private readonly destroyed = new Subject(); + // @ts-ignore + private readonly resizeObserver = new ResizeObserver(() => { + setTimeout(() => this.updatePosition()); + }); constructor( private overlay: Overlay, @@ -681,12 +685,16 @@ export class McPopover implements OnInit, OnDestroy { this.updatePosition(); this.popover.show(); + this.resizeObserver + .observe(document.querySelector('.mc-popover__container')); } } hide(): void { if (this.popover) { this.popover.hide(); + this.resizeObserver + .unobserve(document.querySelector('.mc-popover__container')); } } @@ -703,21 +711,22 @@ export class McPopover implements OnInit, OnDestroy { position.withPositions([ {...origin.main, ...overlay.main}, {...origin.fallback, ...overlay.fallback} - ]); + ]).withPush(true); - // - // FIXME: Необходимо в некоторых моментах форсировать позиционировать только после рендеринга всего контента - // if (reapplyPosition) { setTimeout(() => { position.reapplyLastPosition(); }); + } else { + setTimeout( () => { + position.apply(); + }); } } /** * Returns the origin position and a fallback position based on the user's position preference. - * The fallback position is the inverse of the origin (e.g. `'below' -> 'above'`). + * The fallback position is the inverse of the origin (e.g. `'top' -> 'bottom'`). */ getOrigin(): {main: OriginConnectionPosition; fallback: OriginConnectionPosition} { let originPosition: OriginConnectionPosition;