Skip to content

Commit

Permalink
feat: use cdk for pop-up
Browse files Browse the repository at this point in the history
  • Loading branch information
HitkoDev committed Jun 13, 2022
1 parent 9435a69 commit 0a3c5ba
Show file tree
Hide file tree
Showing 16 changed files with 244 additions and 284 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ import { ColorPickerModule } from 'nxt-color-picker';
[cpFallbackColor] // Used when the color is not well-formed or is undefined ('#000').

[cpPosition] // Dialog position: DialogPosition (DialogPosition.right).
[cpPositionOffset] // Dialog offset percentage relative to the directive element (0%).
[cpPositionRelativeToArrow] // Dialog position is calculated relative to dialog arrow (false).
[cpPositionOffset] // Dialog offset percentage relative to the directive element (0).

[cpPresetLabel] // Show label for preset colors (true). If string is given, it overrides the default label.
[cpPresetColors] // Array of preset colors to show in the color picker dialog ([]).
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"private": true,
"dependencies": {
"@angular/cdk": "^14.0.1",
"@angular/common": "^14.0.1",
"@angular/compiler": "^14.0.1",
"@angular/core": "^14.0.1",
Expand Down
16 changes: 3 additions & 13 deletions projects/demo/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ <h4><b>based on <a href="https://github.com/Alberplz/angular2-color-picker">angu
<span class="change-me"
[style.color]="color6"
[cpPosition]="'bottom'"
[cpPositionOffset]="'50%'"
[cpPositionRelativeToArrow]="true"
[cpPositionOffset]="0.5"
[(cpColor)]="color6">Change me!</span>
</div>
<div class="col-md-7">
Expand All @@ -134,8 +133,7 @@ <h4><b>based on <a href="https://github.com/Alberplz/angular2-color-picker">angu
<div class="card-body">
<pre><code>&lt;span [style.color]="color"
[cpPosition]="'bottom'"
[cpPositionOffset]="'50%'"
[cpPositionRelativeToArrow]="true"
[cpPositionOffset]="0.5"
[(cpColor)]="color"&gt;Change me!&lt;/span&gt;</code></pre>
</div>
</div>
Expand Down Expand Up @@ -520,18 +518,10 @@ <h4><b>based on <a href="https://github.com/Alberplz/angular2-color-picker">angu
<tr>
<td>cpPositionOffset</td>
<td>
<b>'0%'</b><br>
<b>0</b><br>
Dialog offset (percent) relative to the element that contains the directive.
</td>
</tr>
<tr>
<td>cpPositionRelativeToArrow</td>
<td>
<b>false</b>, true <br>
Dialog position is calculated relative to the dialog (false) or relative to the dialog arrow
(true).
</td>
</tr>
<tr>
<td>cpPresetLabel</td>
<td>
Expand Down
1 change: 1 addition & 0 deletions projects/demo/src/styles.scss
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
@import "bootstrap/dist/css/bootstrap.css";
@import '@angular/cdk/overlay-prebuilt.css';
3 changes: 1 addition & 2 deletions projects/nxt-color-picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ import { ColorPickerModule } from 'nxt-color-picker';
[cpFallbackColor] // Used when the color is not well-formed or is undefined ('#000').

[cpPosition] // Dialog position: DialogPosition (DialogPosition.right).
[cpPositionOffset] // Dialog offset percentage relative to the directive element (0%).
[cpPositionRelativeToArrow] // Dialog position is calculated relative to dialog arrow (false).
[cpPositionOffset] // Dialog offset percentage relative to the directive element (0).

[cpPresetLabel] // Show label for preset colors (true). If string is given, it overrides the default label.
[cpPresetColors] // Array of preset colors to show in the color picker dialog ([]).
Expand Down
1 change: 1 addition & 0 deletions projects/nxt-color-picker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"url": "https://github.com/Liquid-JS/nxt-color-picker.git"
},
"peerDependencies": {
"@angular/cdk": "^14.0.1",
"@angular/common": "^14.0.1",
"@angular/core": "^14.0.1"
},
Expand Down
145 changes: 118 additions & 27 deletions projects/nxt-color-picker/src/lib/color-picker.directive.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ConnectedPosition, Overlay, OverlayRef } from '@angular/cdk/overlay'
import { ComponentPortal } from '@angular/cdk/portal'
import { ApplicationRef, ComponentRef, Directive, ElementRef, EventEmitter, HostListener, Injector, Input, OnChanges, OnDestroy, Output, SimpleChanges, ViewContainerRef } from '@angular/core'
import { composedPath, DirectiveCallbacks } from '../util/helpers'
import { AlphaChannel, ColorMode, DialogDisplay, DialogPosition, InputChangeEvent, OutputFormat, SliderChangeEvent } from '../util/types'
Expand Down Expand Up @@ -57,6 +59,7 @@ export class ColorPickerDirective implements OnChanges, OnDestroy {
this.cpPresetColorsChange.emit(value)
}
}
overlayRef: OverlayRef

private get ignoredElements() {
const ign = Array.isArray(this.cpIgnoredElements) ? this.cpIgnoredElements : [this.cpIgnoredElements]
Expand All @@ -79,8 +82,7 @@ export class ColorPickerDirective implements OnChanges, OnDestroy {
@Input() cpFallbackColor: string = ''

@Input() cpPosition: DialogPosition = DialogPosition.right
@Input() cpPositionOffset: string = '0%'
@Input() cpPositionRelativeToArrow: boolean = false
@Input() cpPositionOffset: number = 0

@Input() cpPresetLabel: boolean | string = true
@Input() cpPresetColors: string[]
Expand Down Expand Up @@ -127,7 +129,8 @@ export class ColorPickerDirective implements OnChanges, OnDestroy {
private injector: Injector,
private appRef: ApplicationRef,
private vcRef: ViewContainerRef,
private elRef: ElementRef
private elRef: ElementRef,
private overlay: Overlay
) { }

@HostListener('focus', ['$event'])
Expand Down Expand Up @@ -155,9 +158,7 @@ export class ColorPickerDirective implements OnChanges, OnDestroy {
}

ngOnDestroy() {
if (this.cmpRef != undefined) {
this.cmpRef.destroy()
}
this.dispose()
}

ngOnChanges(changes: SimpleChanges) {
Expand Down Expand Up @@ -188,42 +189,79 @@ export class ColorPickerDirective implements OnChanges, OnDestroy {
if ((changes.cpPresetLabel || changes.cpPresetColors) && this.dialog) {
this.dialog.setPresetConfig(this.cpPresetLabel, this.cpPresetColors)
}

if (changes.cpDialogDisplay) {
this.dispose()
this.create()
}

if ((changes.cpPosition || changes.cpPositionOffset) && this.cpDialogDisplay == DialogDisplay.popup) {
if (this.overlayRef) {
this.overlayRef.updatePositionStrategy(this.overlay.position()
.flexibleConnectedTo(this.elRef)
.withPositions(this.getPositions(this.cpPositionOffset)))
}
}
}

openDialog() {
if (!this.dialogCreated) {
let vcRef = this.vcRef
this.create()
} else if (this.dialog) {
this.dialog.openDialog(this.cpColor)
}
}

this.dialogCreated = true
closeDialog() {
if (this.dialog && this.cpDialogDisplay == DialogDisplay.popup) {
this.dialog.closeDialog()
}
}

if (this.cpUseRootViewContainer && this.cpDialogDisplay != DialogDisplay.inline) {
const classOfRootComponent = this.appRef.componentTypes[0]
const appInstance = this.injector.get(classOfRootComponent)
private dispose() {
if (this.cmpRef)
this.cmpRef.destroy()
if (this.overlayRef)
this.overlayRef.dispose()

vcRef = appInstance.vcRef || appInstance.viewContainerRef || this.vcRef
this.cmpRef = undefined
this.overlayRef = undefined
}

if (vcRef == this.vcRef) {
console.warn('You are using cpUseRootViewContainer, but the root component is not exposing viewContainerRef! Please expose it by adding \'vcRef: ViewContainerRef\' to the constructor.')
}
}
private create() {
let vcRef = this.vcRef

this.cmpRef = vcRef.createComponent(ColorPickerComponent, { injector: this.injector, index: 0 })
this.dialogCreated = true

this.dialog = this.cmpRef.instance
if (this.cpUseRootViewContainer && this.cpDialogDisplay != DialogDisplay.inline) {
const classOfRootComponent = this.appRef.componentTypes[0]
const appInstance = this.injector.get(classOfRootComponent)

this.setupDialog()
vcRef = appInstance.vcRef || appInstance.viewContainerRef || this.vcRef

if (this.vcRef != vcRef) {
this.cmpRef.changeDetectorRef.detectChanges()
if (vcRef == this.vcRef) {
console.warn('You are using cpUseRootViewContainer, but the root component is not exposing viewContainerRef! Please expose it by adding \'vcRef: ViewContainerRef\' to the constructor.')
}
} else if (this.dialog) {
this.dialog.openDialog(this.cpColor)
}
}

closeDialog() {
if (this.dialog && this.cpDialogDisplay == DialogDisplay.popup) {
this.dialog.closeDialog()
if (this.cpDialogDisplay != DialogDisplay.inline) {
const pos = this.overlay.position()
.flexibleConnectedTo(this.elRef)
.withFlexibleDimensions(false)
.withPush(false)
.withPositions(this.getPositions(this.cpPositionOffset))
this.overlayRef = this.overlay.create({ positionStrategy: pos, scrollStrategy: this.overlay.scrollStrategies.reposition({ autoClose: true }) })
this.cmpRef = this.overlayRef.attach(new ComponentPortal(ColorPickerComponent, null, this.injector))
} else {
this.cmpRef = vcRef.createComponent(ColorPickerComponent, { injector: this.injector, index: 0 })
}

this.dialog = this.cmpRef.instance

this.setupDialog()

if (this.vcRef != vcRef) {
this.cmpRef.changeDetectorRef.detectChanges()
}
}

Expand All @@ -232,4 +270,57 @@ export class ColorPickerDirective implements OnChanges, OnDestroy {
this.dialog.setupDialog({ ...this, callbacks: this._callbacks, elementRef: this.elRef, color: this.cpColor })
}
}

private getPositions(offset = 0) {
const pos: ConnectedPosition[] = []
const position = this.cpPosition || DialogPosition.auto

const bb = this.elRef.nativeElement.getBoundingClientRect()

if (position == DialogPosition.auto || position == DialogPosition.bottom) {
pos.push({
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top',
panelClass: 'color-picker__arrow--bottom',
offsetY: bb.height * offset
})
}

if (position == DialogPosition.auto || position == DialogPosition.top) {
pos.push({
originX: 'start',
originY: 'top',
overlayX: 'start',
overlayY: 'bottom',
panelClass: 'color-picker__arrow--top',
offsetY: -bb.height * offset
})
}

if (position == DialogPosition.auto || position == DialogPosition.left) {
pos.push({
originX: 'start',
originY: 'top',
overlayX: 'end',
overlayY: 'top',
panelClass: 'color-picker__arrow--left',
offsetX: -bb.width * offset
})
}

if (position == DialogPosition.auto || position == DialogPosition.right) {
pos.push({
originX: 'end',
originY: 'top',
overlayX: 'start',
overlayY: 'top',
panelClass: 'color-picker__arrow--right',
offsetX: bb.width * offset
})
}

return pos
}
}
4 changes: 3 additions & 1 deletion projects/nxt-color-picker/src/lib/color-picker.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { OverlayModule } from '@angular/cdk/overlay'
import { ColorPickerDirective } from './color-picker.directive'
import { ColorPickerComponent } from './color-picker/color-picker.component'
import { SliderDirective } from './slider.directive'
Expand All @@ -13,7 +14,8 @@ import { TextDirective } from './text.directive'
ColorPickerDirective
],
imports: [
CommonModule
CommonModule,
OverlayModule
],
exports: [
ColorPickerDirective
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
<div #dialogPopup
class="color-picker"
<div class="color-picker"
(click)="$event.stopPropagation()"
[ngStyle]="cpDialogDisplay == 'inline'
? {
visibility: hidden || !show ? 'hidden' : 'visible'
}
: {
visibility: hidden || !show ? 'hidden' : 'visible',
'top.px': top || 0,
'left.px': left || 0,
position: position || undefined,
width: cpWidth || 'auto',
height: cpHeight || 'auto'
}">
[ngStyle]="{
visibility: !show ? 'hidden' : 'visible',
width: cpWidth || '',
height: cpHeight || ''
}"
*ngIf="show">
<div *ngIf="cpDialogDisplay == dialogDisplay.popup"
class="color-picker__arrow"
[ngClass]="'color-picker__arrow--' + cpPosition"></div>
Expand Down
Loading

0 comments on commit 0a3c5ba

Please sign in to comment.