-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Popover): implementa la direttiva popover
ref #23
- Loading branch information
Showing
54 changed files
with
2,100 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { browser, ElementFinder } from 'protractor'; | ||
import { PopoverPage } from './popover.po'; | ||
import { timeout } from 'q'; | ||
|
||
describe('Popover', () => { | ||
let page: PopoverPage; | ||
|
||
beforeEach(async() => { | ||
page = new PopoverPage(); | ||
await page.go(); | ||
}); | ||
|
||
it('dovrebbe iniziare creato e visualizzato', async () => { | ||
expect(await page.existsStandardExamplePopover()).toBeFalsy(); | ||
|
||
await page.clickOverStandardExample(); | ||
expect(await page.existsStandardExamplePopover()).toBeTruthy(); | ||
expect(await page.getStandardExamplePopoverClass()).toBe('popover bs-popover-right'); | ||
|
||
await page.clickOverStandardExample(); | ||
expect(await page.existsStandardExamplePopover()).toBeTruthy(); | ||
expect(await page.getStandardExamplePopoverClass()).toBe('popover bs-popover-right'); | ||
}); | ||
|
||
it('dovrebbe iniziare creato e visualizzato in alto', async () => { | ||
expect(await page.existsStandardExamplePopover()).toBeFalsy(); | ||
|
||
await page.clickOverTopPlacement(); | ||
await page.clickOverStandardExample(); | ||
|
||
expect(await page.existsStandardExamplePopover()).toBeTruthy(); | ||
expect(await page.getPlacementExamplePopoverClass()).toBe('popover bs-popover-top'); | ||
}); | ||
|
||
it('dovrebbe iniziare creato e visualizzato a destra', async () => { | ||
expect(await page.existsStandardExamplePopover()).toBeFalsy(); | ||
|
||
await page.clickOverRightPlacement(); | ||
await page.clickOverStandardExample(); | ||
|
||
expect(await page.existsStandardExamplePopover()).toBeTruthy(); | ||
expect(await page.getPlacementExamplePopoverClass()).toBe('popover bs-popover-right'); | ||
}); | ||
|
||
it('dovrebbe iniziare creato e visualizzato a sinistra', async () => { | ||
expect(await page.existsStandardExamplePopover()).toBeFalsy(); | ||
|
||
await page.clickOverLeftPlacement(); | ||
await page.clickOverStandardExample(); | ||
|
||
expect(await page.existsStandardExamplePopover()).toBeTruthy(); | ||
expect(await page.getPlacementExamplePopoverClass()).toBe('popover bs-popover-left'); | ||
}); | ||
|
||
it('dovrebbe iniziare creato e visualizzato in basso', async () => { | ||
expect(await page.existsStandardExamplePopover()).toBeFalsy(); | ||
|
||
await page.clickOverBottomPlacement(); | ||
await page.clickOverStandardExample(); | ||
|
||
expect(await page.existsStandardExamplePopover()).toBeTruthy(); | ||
expect(await page.getPlacementExamplePopoverClass()).toBe('popover bs-popover-bottom'); | ||
}); | ||
|
||
it('dovrebbe iniziare creato e visualizzato a destra, poi in alto e successivamente a sinistra, ed infine in basso', async () => { | ||
await page.clickOverStandardExample(); | ||
expect(await page.existsPlacementExamplePopover()).toBeTruthy(); | ||
expect(await page.getPlacementExamplePopoverClass()).toBe('popover bs-popover-right'); | ||
|
||
await page.clickOverTopPlacement(); | ||
expect(await page.getPlacementExamplePopoverClass()).toBe('popover bs-popover-top'); | ||
|
||
await page.clickOverLeftPlacement(); | ||
expect(await page.getPlacementExamplePopoverClass()).toBe('popover bs-popover-left'); | ||
|
||
await page.clickOverBottomPlacement(); | ||
expect(await page.getPlacementExamplePopoverClass()).toBe('popover bs-popover-bottom'); | ||
}); | ||
|
||
it('dovrebbe iniziare creato e visualizzato, per poi essere chiuso con un click successivo', async () => { | ||
await page.clickOverFocusTrigger(); | ||
|
||
await page.clickOverStandardExample(); | ||
const isPresent = await page.existsFocusExamplePopover(); | ||
expect(isPresent).toBeTruthy(); | ||
|
||
await page.clickOverFocusTrigger(); | ||
|
||
const isHidden = await page.getFocusExamplePopoverClass(); | ||
expect(isHidden).toBeTruthy(); | ||
}); | ||
|
||
it('dovrebbe iniziare creato e visualizzato, per poi essere distrutto ed infine ricreato e rivisualizzato', async () => { | ||
await page.clickOverStandardExample(); | ||
const isPresent = await page.existsDisposableExamplePopover(); | ||
expect(isPresent).toBeTruthy(); | ||
|
||
await page.clickOverDisposeButton(); | ||
|
||
const isDisposed = await page.existsDisposableExamplePopover(); | ||
expect(isDisposed).toBeFalsy(); | ||
|
||
await page.clickOverStandardExample(); | ||
expect(await page.existsDisposableExamplePopover()).toBeTruthy(); | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { browser, by, element } from 'protractor'; | ||
|
||
export class PopoverPage { | ||
private readonly POPOVER_URL = '/#/componenti/popover'; | ||
private readonly ID_EXAMPLE_TAB = 'popover-examples-tab'; | ||
|
||
private readonly ID_POPOVER_INTERACTIVE_BUTTON = 'popover-interactive-button'; | ||
private readonly ID_POPOVER_DISPOSE_BUTTON = 'popover-disposing-button'; | ||
|
||
private readonly ID_RADIO_FOCUS = this.getLabelForAttribute('radio-5'); | ||
|
||
private readonly ID_RADIO_RIGHT = this.getLabelForAttribute('radio-7'); | ||
private readonly ID_RADIO_TOP = this.getLabelForAttribute('radio-8'); | ||
private readonly ID_RADIO_LEFT = this.getLabelForAttribute('radio-9'); | ||
private readonly ID_RADIO_BOTTOM = this.getLabelForAttribute('radio-10'); | ||
|
||
private readonly ID_POPOVER_STANDARD = 'it-popover-0'; | ||
|
||
async go() { | ||
await browser.get(this.POPOVER_URL); | ||
await browser.executeScript(`document.querySelector('header').remove()`); | ||
await element(by.id(this.ID_EXAMPLE_TAB)).click(); | ||
return await browser.sleep(500); | ||
} | ||
|
||
private getLabelForAttribute(attr: string) { | ||
return `[for="${attr}"]`; | ||
} | ||
|
||
async click(elementId: string) { | ||
await element(by.css(elementId)).click(); | ||
} | ||
|
||
async clickOverStandardExample() { | ||
await element(by.id(this.ID_POPOVER_INTERACTIVE_BUTTON)).click(); | ||
} | ||
|
||
async clickOverTopPlacement() { | ||
await this.click(this.ID_RADIO_TOP); | ||
} | ||
|
||
async clickOverRightPlacement() { | ||
await this.click(this.ID_RADIO_RIGHT); | ||
} | ||
|
||
async clickOverBottomPlacement() { | ||
await this.click(this.ID_RADIO_BOTTOM); | ||
} | ||
|
||
async clickOverLeftPlacement() { | ||
await this.click(this.ID_RADIO_LEFT); | ||
} | ||
|
||
async existsStandardExamplePopover() { | ||
return await element(by.id(this.ID_POPOVER_STANDARD)).isPresent(); | ||
} | ||
|
||
async getStandardExamplePopoverClass() { | ||
return await element(by.id(this.ID_POPOVER_STANDARD)).getAttribute('class'); | ||
} | ||
|
||
async existsPlacementExamplePopover() { | ||
return await element(by.id(this.ID_POPOVER_STANDARD)).isPresent(); | ||
} | ||
|
||
async getPlacementExamplePopoverClass() { | ||
return await element(by.id(this.ID_POPOVER_STANDARD)).getAttribute('class'); | ||
} | ||
|
||
async clickOverDisposeButton() { | ||
await element(by.id(this.ID_POPOVER_DISPOSE_BUTTON)).click(); | ||
} | ||
|
||
async existsDisposableExamplePopover() { | ||
return await element(by.id(this.ID_POPOVER_STANDARD)).isPresent(); | ||
} | ||
|
||
async getDisposableExamplePopoverClass() { | ||
return await element(by.id(this.ID_POPOVER_STANDARD)).getAttribute('class'); | ||
} | ||
|
||
async clickOverFocusTrigger() { | ||
await this.click(this.ID_RADIO_FOCUS); | ||
} | ||
|
||
async existsFocusExamplePopover() { | ||
return await element(by.id(this.ID_POPOVER_STANDARD)).isPresent(); | ||
} | ||
|
||
async getFocusExamplePopoverClass() { | ||
return await element(by.id(this.ID_POPOVER_STANDARD)).getAttribute('hidden'); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
projects/design-angular-kit/src/lib/popover/popover.component.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
:host.bs-popover-top .arrow, :host.bs-popover-bottom .arrow { | ||
left: 50%; | ||
margin-left: -5px; | ||
} | ||
|
||
:host.bs-popover-top-left .arrow, :host.bs-popover-bottom-left .arrow { | ||
left: 2em; | ||
} | ||
|
||
:host.bs-popover-top-right .arrow, :host.bs-popover-bottom-right .arrow { | ||
left: auto; | ||
right: 2em; | ||
} | ||
|
||
:host.bs-popover-left .arrow, :host.bs-popover-right .arrow { | ||
top: 50%; | ||
margin-top: -5px; | ||
} | ||
|
||
:host.bs-popover-left-top .arrow, :host.bs-popover-right-top .arrow { | ||
top: 0.7em; | ||
} | ||
|
||
:host.bs-popover-left-bottom .arrow, :host.bs-popover-right-bottom .arrow { | ||
top: auto; | ||
bottom: 0.7em; | ||
} |
5 changes: 5 additions & 0 deletions
5
projects/design-angular-kit/src/lib/popover/popover.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<div class="arrow"></div> | ||
<h3 class="popover-header">{{title}}</h3> | ||
<div class="popover-body"> | ||
<ng-content></ng-content> | ||
</div> |
81 changes: 81 additions & 0 deletions
81
projects/design-angular-kit/src/lib/popover/popover.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/** | ||
* @license | ||
* Copyright Angular ng-bootstrap team All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://raw.githubusercontent.com/ng-bootstrap/ng-bootstrap/master/LICENSE | ||
*/ | ||
import { | ||
Component, ChangeDetectionStrategy, | ||
ElementRef, Renderer2, Input, HostBinding, | ||
ChangeDetectorRef, TemplateRef, ViewContainerRef | ||
} from '@angular/core'; | ||
import { Placement } from './positioning'; | ||
import { ContentRef } from './popup'; | ||
|
||
@Component({ | ||
selector: 'it-popover-window', | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
templateUrl: './popover.component.html', | ||
styleUrls: ['./popover.component.css'] | ||
}) | ||
export class PopoverComponent { | ||
@Input() placement: Placement = 'right'; | ||
|
||
@Input() | ||
get title() { return this._title; } | ||
set title(value: string) { | ||
this._title = value; | ||
this._changeDetectorRef.detectChanges(); | ||
} | ||
private _title: string; | ||
|
||
@Input() @HostBinding('id') id: string; | ||
@Input() @HostBinding('hidden') hidden = false; | ||
|
||
@HostBinding('attr.role') role = 'tooltip'; | ||
@HostBinding('class') get myCssClass(): string { | ||
return 'popover bs-popover-' + this.placement.split('-')[0] + ' bs-popover-' + this.placement; | ||
} | ||
|
||
constructor( | ||
private _element: ElementRef<HTMLElement>, private _renderer: Renderer2, | ||
private _changeDetectorRef: ChangeDetectorRef, private _viewContainerRef: ViewContainerRef | ||
) {} | ||
|
||
applyPlacement(_placement: Placement) { | ||
// Rimuovi le classi della posizione precedente | ||
this._renderer.removeClass(this._element.nativeElement, 'bs-popover-' + this.placement.toString().split('-')[0]); | ||
this._renderer.removeClass(this._element.nativeElement, 'bs-popover-' + this.placement.toString()); | ||
|
||
// Imposta la nuova posizione | ||
this.placement = _placement; | ||
|
||
// Applica le classi della nuova posizione | ||
this._renderer.addClass(this._element.nativeElement, 'bs-popover-' + this.placement.toString().split('-')[0]); | ||
this._renderer.addClass(this._element.nativeElement, 'bs-popover-' + this.placement.toString()); | ||
} | ||
|
||
setNewContent(content: string | TemplateRef<any>, context?: any) { | ||
const contentElement = this._element.nativeElement.querySelector('.popover-body'); | ||
|
||
let newContent: ContentRef; | ||
if (!content) { | ||
newContent = new ContentRef([]); | ||
} else if (content instanceof TemplateRef) { | ||
const viewRef = this._viewContainerRef.createEmbeddedView(<TemplateRef<PopoverComponent>>content, context); | ||
newContent = new ContentRef([viewRef.rootNodes], viewRef); | ||
} else { | ||
newContent = new ContentRef([[this._renderer.createText(`${content}`)]]); | ||
} | ||
|
||
const childNodes = contentElement.childNodes; | ||
for (let i = 0; i < childNodes.length; i++) { | ||
this._renderer.removeChild(contentElement, childNodes[i]); | ||
} | ||
|
||
newContent.nodes.forEach(newNode => { | ||
newNode.forEach(newChild => this._renderer.appendChild(contentElement, newChild)); | ||
}); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
projects/design-angular-kit/src/lib/popover/popover.config.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* @license | ||
* Copyright Angular ng-bootstrap team All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://raw.githubusercontent.com/ng-bootstrap/ng-bootstrap/master/LICENSE | ||
*/ | ||
import { Injectable } from '@angular/core'; | ||
import { PlacementArray } from './positioning'; | ||
import { INTERACTION_TRIGGERS } from '../models/InteractionTrigger'; | ||
|
||
/** | ||
* Servizio di configurazione per la direttiva ItPopover. | ||
* Il servizio può essere iniettato, tipicamente in un root component, per impostare i valori delle proprietà in | ||
* modo tale da fornire i valori di default per tutti i popover utilizzati in un'applicazione. | ||
*/ | ||
@Injectable({providedIn: 'root'}) | ||
export class PopoverConfig { | ||
placement: PlacementArray = 'right'; | ||
triggers = INTERACTION_TRIGGERS.CLICK; | ||
container: string; | ||
disablePopover = false; | ||
} |
Oops, something went wrong.