Skip to content

Commit

Permalink
Dialog positioning fixes and two new input options
Browse files Browse the repository at this point in the history
  • Loading branch information
sconix committed May 21, 2018
1 parent 1b59179 commit 0f72e11
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 92 deletions.
51 changes: 29 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,53 +80,60 @@ const DEFAULT_FONT_PICKER_CONFIG: FontPickerConfigInterface = {
```

```javascript
[(fontPicker)] // Selected font ({family, size, style, styles, files}).
[(fontPicker)] // Selected font ({family, size, style, styles, files}).

[fpWidth] // Width of the font picker (Default: '280px').
[fpHeight] // Height of the font picker (Default: '320px').
[fpWidth] // Width of the font picker (Default: '280px').
[fpHeight] // Height of the font picker (Default: '320px').

[fpPosition] // Position of the font picker (Default: 'bottom').
[fpPosition] // Position of the font picker (Default: 'bottom').

[fpAutoLoad] // Auto loads font on change (fontPicker input change).
[fpAutoLoad] // Auto loads font on change (fontPicker input change).

[fpSizeSelect] // Show size selector in the font picker (Default: false).
[fpSizeSelect] // Show size selector in the font picker (Default: false).

[fpStyleSelect] // Show style selector in the font picker (Default: false).
[fpStyleSelect] // Show style selector in the font picker (Default: false).

[fpPresetLabel] // Label for the preset fonts list (Default: undefined).
[fpPresetFonts] // Listing of preset fonts to show (Default: undefined).
[fpPresetLabel] // Label for the preset fonts list (Default: undefined).
[fpPresetFonts] // Listing of preset fonts to show (Default: undefined).

[fpFallbackFont] // Fallback font (Default: {family: 'Roboto', size: 14}).
[fpFallbackFont] // Fallback font (Default: {family: 'Roboto', size: 14}).

[fpCancelButton] // Show cancel button in the font picker (Default: false).
[fpCancelButton] // Show cancel button in the font picker (Default: false).

[fpUploadButton] // Show upload button in the font picker (Default: false).
[fpUploadButton] // Show upload button in the font picker (Default: false).

(fontPickerChange) // Event handler for the font / size / style change.
[fpDialogDisplay] // Dialog positioning mode: 'popup', 'inline' ('popup').
// popup: dialog is shown as popup (fixed positioning).
// inline: dialog is shown permanently (static positioning).

(fontPickerUpload) // Event handler for the font upload button click event.
[fpUseRootViewContainer] // Create dialog component in the root view container (false).
// Note: The root component needs to have public viewContainerRef.

(fontPickerChange) // Event handler for the font / size / style change.

(fontPickerUpload) // Event handler for the font upload button click event.
```

##### Available configuration options (for the global configuration):

```javascript
apiKey // Your Google API key for the Google Web Fonts API.
apiKey // Your Google API key for the Google Web Fonts API.
```

##### Available control / helper functions (provided by the service):

loadFont(font) // Loads the given font (family:style) from Web Fonts.
loadFont(font) // Loads the given font (family:style) from Web Fonts.

getAllFonts(sort) // Returns list of Google Fonts with given sort option:
// 'alpha' | 'date' | 'popularity' | 'style' | 'trending'
getAllFonts(sort) // Returns list of Google Fonts with given sort option:
// 'alpha' | 'date' | 'popularity' | 'style' | 'trending'

##### Available control / helper functions (provided by the directive):

```javascript
loadFont(font) // Loads the (font.family:font.style) form Web Fonts.
loadFont(font) // Loads the (font.family:font.style) form Web Fonts.

openDialog() // Opens the font picker dialog if not already open.
closeDialog() // Closes the font picker dialog if not already closed.
openDialog() // Opens the font picker dialog if not already open.
closeDialog() // Closes the font picker dialog if not already closed.

toggleDialog() // Toggles the open state of the font picker dialog.
toggleDialog() // Toggles the open state of the font picker dialog.
```
2 changes: 1 addition & 1 deletion src/lib/font-picker.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div #dialogPopup [hidden]="!open" class="font-picker" [style.height.px]="fpHeight" [style.width.px]="fpWidth" [style.top.px]="top" [style.left.px]="left" [style.position]="position">
<div class="arrow arrow-{{fpPosition}}" [style.top.px]="arrowTop"></div>
<div *ngIf="fpDialogDisplay=='popup'" class="arrow arrow-{{fpPosition}}" [style.top.px]="arrowTop"></div>

<div class="search-box">
<input class="search-field" placeholder="Search from Google Web Fonts..." [formControl]="searchTerm" />
Expand Down
146 changes: 88 additions & 58 deletions src/lib/font-picker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ export class FontPickerComponent implements OnInit {
private testWidth: number;
private testContainer: any;

private autoWidth: boolean;

private listenerResize: any;
private listenerMouseDown: any;

private directiveInstance: any;
private directiveElementRef: ElementRef;

private useRootViewContainer: boolean = false;

public font: Font;

public open: boolean;
Expand Down Expand Up @@ -73,6 +77,8 @@ export class FontPickerComponent implements OnInit {
public fpUploadButtonText: string;
public fpUploadButtonClass: string;

public fpDialogDisplay: string;

public dialogArrowSize: number = 10;
public dialogArrowOffset: number = 15;

Expand Down Expand Up @@ -141,21 +147,24 @@ export class FontPickerComponent implements OnInit {
}

public setDialog(instance: any, elementRef: ElementRef, defaultFont: FontInterface,
fpPosition: string, fpPositionOffset: string, fpPositionRelativeToArrow: boolean,
fpPresetLabel: string, fpPresetFonts: string[], fpUploadButton: boolean,
fpUploadButtonClass: string, fpUploadButtonText: string, fpStyleSelect: boolean,
fpSizeSelect: boolean, fpCancelButton: boolean, fpCancelButtonClass: string,
fpCancelButtonText: string, fpHeight: string, fpWidth: string): void
fpUseRootViewContainer: boolean, fpPosition: string, fpPositionOffset: string,
fpPositionRelativeToArrow: boolean, fpPresetLabel: string, fpPresetFonts: string[],
fpUploadButton: boolean, fpUploadButtonClass: string, fpUploadButtonText: string,
fpStyleSelect: boolean, fpSizeSelect: boolean, fpCancelButton: boolean,
fpCancelButtonClass: string, fpCancelButtonText: string, fpDialogDisplay: string,
fpHeight: string, fpWidth: string): void
{
this.listLabel = 'Loading fonts...';

this.directiveInstance = instance;
this.directiveElementRef = elementRef;

this.useRootViewContainer = fpUseRootViewContainer;

this.updateDialog(defaultFont, fpPosition, fpPositionOffset, fpPositionRelativeToArrow,
fpPresetLabel, fpPresetFonts, fpUploadButton, fpUploadButtonClass, fpUploadButtonText,
fpStyleSelect, fpSizeSelect, fpCancelButton, fpCancelButtonClass, fpCancelButtonText,
fpHeight, fpWidth);
fpDialogDisplay, fpHeight, fpWidth);

this.service.getAllFonts('popularity').subscribe((fonts: GoogleFontsInterface) => {
this.loading = false;
Expand Down Expand Up @@ -196,7 +205,8 @@ export class FontPickerComponent implements OnInit {
fpPositionRelativeToArrow: boolean, fpPresetLabel: string, fpPresetFonts: string[],
fpUploadButton: boolean, fpUploadButtonClass: string, fpUploadButtonText: string,
fpStyleSelect: boolean, fpSizeSelect: boolean, fpCancelButton: boolean,
fpCancelButtonClass: string, fpCancelButtonText: string, fpHeight: string, fpWidth: string): void
fpCancelButtonClass: string, fpCancelButtonText: string, fpDialogDisplay: string,
fpHeight: string, fpWidth: string): void
{
this.font = new Font(font);
this.initialFont = new Font(font);
Expand All @@ -208,6 +218,11 @@ export class FontPickerComponent implements OnInit {
this.dialogArrowOffset = 0;
}

if (fpDialogDisplay === 'inline') {
this.dialogArrowSize = 0;
this.dialogArrowOffset = 0;
}

this.fpPresetLabel = fpPresetLabel;
this.fpPresetFonts = fpPresetFonts;

Expand All @@ -222,9 +237,13 @@ export class FontPickerComponent implements OnInit {
this.fpUploadButtonText = fpUploadButtonText;
this.fpUploadButtonClass = fpUploadButtonClass;

this.autoWidth = fpWidth === 'auto';

this.fpWidth = parseInt(fpWidth, 10);
this.fpHeight = parseInt(fpHeight, 10);

this.fpDialogDisplay = fpDialogDisplay;

this.setDisplayedFontSource();

this.searchTerm.reset({disabled: (this.fpPresetFonts.length > 0)});
Expand Down Expand Up @@ -421,84 +440,93 @@ export class FontPickerComponent implements OnInit {
}

private setDialogPosition(): void {
let parentNode;
let boxDirective;
if (this.fpDialogDisplay === 'inline') {
this.position = 'relative';
} else {
let position = 'static', transform = '', style;

let position = 'static';
let parentNode: any = null, transformNode: any = null;

let node = this.directiveElementRef.nativeElement;
let node = this.directiveElementRef.nativeElement.parentNode;

const dialogHeight = this.dialogElement.nativeElement.offsetHeight;
const dialogHeight = this.dialogElement.nativeElement.offsetHeight;

while (node !== null && node.tagName !== 'HTML') {
position = window.getComputedStyle(node).getPropertyValue('position');
while (node !== null && node.tagName !== 'HTML') {
style = window.getComputedStyle(node);
position = style.getPropertyValue('position');
transform = style.getPropertyValue('transform');

if (position !== 'static' && parentNode === null) {
parentNode = node;
}
if (position !== 'static' && parentNode === null) {
parentNode = node;
}

if (position === 'fixed') {
break;
}
if (transform && transform !== 'none' && transformNode === null) {
transformNode = node;
}

node = node.parentNode;
}
if (position === 'fixed') {
parentNode = transformNode;

if (position !== 'fixed') {
boxDirective = this.createDialogBox(this.directiveElementRef.nativeElement, true);
break;
}

if (parentNode == null) {
parentNode = node;
node = node.parentNode;
}

const boxParent = this.createDialogBox(parentNode, true);
const boxDirective = this.createDialogBox(this.directiveElementRef.nativeElement, (position !== 'fixed'));

this.top = boxDirective.top - boxParent.top;
this.left = boxDirective.left - boxParent.left;
} else {
boxDirective = this.createDialogBox(this.directiveElementRef.nativeElement, false);
if (this.autoWidth) {
this.fpWidth = this.directiveElementRef.nativeElement.offsetWidth;
}

this.position = 'fixed';
if (this.useRootViewContainer || (position === 'fixed' && !parentNode)) {
this.top = boxDirective.top;
this.left = boxDirective.left;
} else {
if (parentNode === null) {
parentNode = node;
}

this.top = boxDirective.top;
this.left = boxDirective.left;
}
const boxParent = this.createDialogBox(parentNode, (position !== 'fixed'));

if (!this.fpWidth) {
this.fpWidth = boxDirective.width;
}
this.top = boxDirective.top - boxParent.top;
this.left = boxDirective.left - boxParent.left;
}

if (!this.fpHeight) {
this.fpHeight = boxDirective.height;
}
if (position === 'fixed') {
this.position = 'fixed';
}

if (this.fpPosition === 'left') {
this.top += boxDirective.height * this.fpPositionOffset / 100 - this.dialogArrowOffset;
this.left -= this.fpWidth + this.dialogArrowSize;
} else if (this.fpPosition === 'top') {
this.top -= dialogHeight + this.dialogArrowSize;
this.left += this.fpPositionOffset / 100 * boxDirective.width - this.dialogArrowOffset - 1;
this.arrowTop = dialogHeight - 1;
} else if (this.fpPosition === 'bottom') {
this.top += boxDirective.height + this.dialogArrowSize;
this.left += this.fpPositionOffset / 100 * boxDirective.width - this.dialogArrowOffset - 1;
} else {
this.top += boxDirective.height * this.fpPositionOffset / 100 - this.dialogArrowOffset;
this.left += boxDirective.width + this.dialogArrowSize;
if (this.fpPosition === 'left') {
this.top += boxDirective.height * this.fpPositionOffset / 100 - this.dialogArrowOffset;
this.left -= this.fpWidth + this.dialogArrowSize - 2;
} else if (this.fpPosition === 'top') {
this.arrowTop = dialogHeight - 1;

this.top -= dialogHeight + this.dialogArrowSize;
this.left += this.fpPositionOffset / 100 * boxDirective.width - this.dialogArrowOffset;
} else if (this.fpPosition === 'bottom') {
this.top += boxDirective.height + this.dialogArrowSize;
this.left += this.fpPositionOffset / 100 * boxDirective.width - this.dialogArrowOffset;
} else {
this.top += boxDirective.height * this.fpPositionOffset / 100 - this.dialogArrowOffset;
this.left += boxDirective.width + this.dialogArrowSize - 2;
}
}
}

private onResize(event: any): void {
if (this.position === 'fixed') {
this.setDialogPosition();
} else {
} else if (this.fpDialogDisplay !== 'inline') {
this.closeFontPicker();
}
}

private onMouseDown(event: any): void {
if (!this.isDescendant(this.elRef.nativeElement, event.target) &&
event.target !== this.directiveElementRef.nativeElement)
if (this.fpDialogDisplay === 'popup' &&
event.target !== this.directiveElementRef.nativeElement &&
!this.isDescendant(this.elRef.nativeElement, event.target))
{
this.closeFontPicker();
}
Expand All @@ -519,7 +547,9 @@ export class FontPickerComponent implements OnInit {

this.directiveInstance.fontChanged(this.font);

this.closeFontPicker();
if (this.fpDialogDisplay === 'popup') {
this.closeFontPicker();
}
}

public onSelectFont(font: any): void {
Expand Down
Loading

0 comments on commit 0f72e11

Please sign in to comment.