Ref changed folder structure and lib

This commit is contained in:
Lorenzo Iovino 2024-01-10 01:18:38 +01:00
parent f2a8edb15f
commit 26b739726f
18 changed files with 160 additions and 107 deletions

View file

@ -1,7 +1,7 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import {Ng2FittextModule} from '../lib/ng2-fittext.module';
import { Ng2FittextModule } from 'lib';
@NgModule({
declarations: [

6
src/lib/.gitignore vendored
View file

@ -1,6 +0,0 @@
build
coverage
dist
debug.log
node_modules
out-tsc

View file

@ -1,23 +0,0 @@
*.spec.ts
*.tgz
.erector
.gitignore
.npmignore
.vscode
build
coverage
debug.log
DEVELOPMENT.md
dist
karma.conf.js
node_modules
out-tsc
src
tasks
test.ts
tsconfig.*json
tslint.json
typings
typings.json
vendor.ts
webpack

View file

@ -1,171 +0,0 @@
import {
AfterViewChecked,
AfterViewInit,
Directive,
ElementRef,
HostListener,
Input,
Output,
EventEmitter,
OnChanges,
OnInit,
Renderer2,
} from '@angular/core';
@Directive({
selector: '[fittext]',
})
export class Ng2FittextDirective
implements AfterViewInit, OnInit, OnChanges, AfterViewChecked {
@Input('fittext') fittext: any;
@Input('activateOnResize') activateOnResize: boolean = true;
@Input('container') container: HTMLElement | null = null;
@Input('activateOnInputEvents') activateOnInputEvents: boolean = false;
@Input('minFontSize') minFontSize = 7;
@Input('maxFontSize') maxFontSize = 1000;
/* Deprecated */
@Input('useMaxFontSize') useMaxFontSize = true;
@Input('modelToWatch') modelToWatch: any;
@Output() fontSizeChanged: EventEmitter<number> = new EventEmitter();
private fontSize = 1000;
private speed = 1.05;
private done = false;
constructor(public el: ElementRef<HTMLElement>, public renderer: Renderer2) {}
setFontSize(fontSize: number): void {
if (this.isVisible() && !this.isDone()) {
if (fontSize < this.minFontSize) {
fontSize = this.minFontSize;
}
if (fontSize > this.maxFontSize) {
fontSize = this.maxFontSize;
}
this.fontSize = fontSize;
this.fontSizeChanged.emit(fontSize);
this.el.nativeElement.style.setProperty(
'font-size',
fontSize.toString() + 'px'
);
}
}
getFontSize(): number {
return this.fontSize;
}
calculateFontSize(fontSize: number, speed: number): number {
return Math.floor(fontSize / speed);
}
checkOverflow(parent: HTMLElement, children: HTMLElement): boolean {
return (
this.hasXAxisOverflow(parent, children) ||
this.hasYAxisOverflow(parent, children)
);
}
hasXAxisOverflow(parent: HTMLElement, children: HTMLElement): boolean {
return children.scrollWidth - parent.clientWidth > 0;
}
hasYAxisOverflow(parent: HTMLElement, children: HTMLElement): boolean {
return children.clientHeight - parent.clientHeight > 0;
}
@HostListener('window:resize', ['$event'])
onResize(event: Event) {
this.done = false;
if (this.activateOnResize && this.fittext) {
if (this.activateOnInputEvents && this.fittext) {
this.setFontSize(this.getStartFontSizeFromHeight());
} else {
this.setFontSize(this.getStartFontSizeFromWeight());
}
this.ngAfterViewInit();
}
}
@HostListener('input', ['$event'])
onInputEvents(event: Event) {
this.done = false;
if (this.activateOnInputEvents && this.fittext) {
this.setFontSize(this.getStartFontSizeFromHeight());
this.ngAfterViewInit();
}
}
ngOnInit() {
this.done = false;
this.el.nativeElement.style.setProperty('will-change', 'content');
this.ngAfterViewInit();
}
ngAfterViewInit() {
if (this.isVisible() && !this.isDone()) {
if (this.fittext) {
if (this.hasOverflow()) {
if (this.fontSize > this.minFontSize) {
// iterate only until font size is bigger than minimal value
this.setFontSize(this.calculateFontSize(this.fontSize, this.speed));
this.ngAfterViewInit();
}
} else {
this.done = true;
}
}
}
}
ngOnChanges(changes: any): void {
if (changes.modelToWatch) {
// change of model to watch - call ngAfterViewInit where is implemented logic to change size
setTimeout(() => {
this.done = false;
this.setFontSize(this.maxFontSize);
this.ngAfterViewInit();
});
}
}
ngAfterViewChecked() {
if (this.fontSize > this.minFontSize) {
this.setFontSize(this.getStartFontSizeFromHeight());
this.ngAfterViewInit();
}
}
getStartFontSizeFromHeight(): number {
return this.container
? this.container.clientHeight
: this.el.nativeElement.parentElement!.clientHeight;
}
private getStartFontSizeFromWeight(): number {
return this.container
? this.container.clientWidth
: this.el.nativeElement.parentElement!.clientWidth;
}
isDone(): boolean {
return this.done;
}
isVisible(): boolean {
return this.getStartFontSizeFromHeight() > 0;
}
hasOverflow(): boolean {
return this.container
? this.checkOverflow(this.container, this.el.nativeElement)
: this.checkOverflow(
this.el.nativeElement.parentElement!,
this.el.nativeElement
);
}
}

View file

@ -1,312 +0,0 @@
import { Ng2FittextDirective } from '../ng2-fittext.directive';
import { Renderer2, ElementRef } from '@angular/core';
describe('Class: Ng2FittextDirective', () => {
let ng2FittextDirective: Ng2FittextDirective;
let elMock: ElementRef;
let rendererMock: Renderer2;
beforeEach(() => {
elMock = {} as ElementRef;
rendererMock = {} as Renderer2;
ng2FittextDirective = new Ng2FittextDirective(elMock, rendererMock);
});
describe('Method: setFontSize', () => {
let newFontSize: number;
let isVisibleSpy: jasmine.Spy;
let isDoneSpy: jasmine.Spy;
beforeEach(() => {
newFontSize = 100;
isVisibleSpy = spyOn(ng2FittextDirective, 'isVisible').and.returnValue(
true
);
isDoneSpy = spyOn(ng2FittextDirective, 'isDone').and.returnValue(false);
elMock.nativeElement = {
style: {
setProperty: () => {},
},
};
});
it('Should not change the font size if the element is not visible', () => {
isVisibleSpy.and.returnValue(false);
const previousFontSize: number = ng2FittextDirective.getFontSize();
ng2FittextDirective.setFontSize(newFontSize);
expect(ng2FittextDirective.getFontSize()).toEqual(previousFontSize);
});
it('Should not change the font size if the fitting operation is done', () => {
isDoneSpy.and.returnValue(true);
const previousFontSize: number = ng2FittextDirective.getFontSize();
ng2FittextDirective.setFontSize(newFontSize);
expect(ng2FittextDirective.getFontSize()).toEqual(previousFontSize);
});
it('Should use the minFontSize property value if the specified font size is smaller', () => {
const minFontSize: number = ng2FittextDirective.minFontSize;
newFontSize = 5;
ng2FittextDirective.setFontSize(newFontSize);
const currentFontSize: number = ng2FittextDirective.getFontSize();
expect(currentFontSize).toEqual(minFontSize);
});
it('Should use the maxFontSize property value if the specified font size is bigger', () => {
const maxFontSize: number = ng2FittextDirective.maxFontSize;
newFontSize = 1001;
ng2FittextDirective.setFontSize(newFontSize);
const currentFontSize: number = ng2FittextDirective.getFontSize();
expect(currentFontSize).toEqual(maxFontSize);
});
it('Should set a new fontSize value', () => {
newFontSize = 500;
ng2FittextDirective.setFontSize(newFontSize);
const currentFontSize: number = ng2FittextDirective.getFontSize();
expect(currentFontSize).toEqual(newFontSize);
});
it('Should emit the font size change', () => {
newFontSize = 500;
spyOn(ng2FittextDirective.fontSizeChanged, 'emit');
ng2FittextDirective.setFontSize(newFontSize);
expect(ng2FittextDirective.fontSizeChanged.emit).toHaveBeenCalledWith(
newFontSize
);
});
it('Should update the nativeElement with the new font size', () => {
newFontSize = 500;
spyOn(ng2FittextDirective.el.nativeElement.style, 'setProperty');
ng2FittextDirective.setFontSize(newFontSize);
expect(
ng2FittextDirective.el.nativeElement.style.setProperty
).toHaveBeenCalledWith('font-size', `${newFontSize}px`);
});
});
describe('Method: getFontSize', () => {
it('Should return the current font size', () => {
expect(ng2FittextDirective.getFontSize()).toEqual(1000);
});
});
describe('Method: calculateFontSize', () => {
it('Should return the font size rounded down', () => {
expect(ng2FittextDirective.calculateFontSize(10, 3)).toEqual(3);
expect(ng2FittextDirective.calculateFontSize(9, 3)).toEqual(3);
expect(ng2FittextDirective.calculateFontSize(8, 3)).toEqual(2);
});
});
describe('Method: checkOverflow', () => {
let parentElementMock: HTMLElement;
let childrenElementMock: HTMLElement;
let hasXAxisOverflowSpy: jasmine.Spy;
let hasYAxisOverflowSpy: jasmine.Spy;
beforeEach(() => {
parentElementMock = {} as HTMLElement;
childrenElementMock = {} as HTMLElement;
hasXAxisOverflowSpy = spyOn(
ng2FittextDirective,
'hasXAxisOverflow'
).and.returnValue(false);
hasYAxisOverflowSpy = spyOn(
ng2FittextDirective,
'hasYAxisOverflow'
).and.returnValue(false);
});
it('Should return false if no overflow is present', () => {
expect(
ng2FittextDirective.checkOverflow(
parentElementMock,
childrenElementMock
)
).toBe(false);
});
it('Should return true if x axis has overflow', () => {
hasXAxisOverflowSpy.and.returnValue(true);
expect(
ng2FittextDirective.checkOverflow(
parentElementMock,
childrenElementMock
)
).toBe(true);
});
it('Should return true if y axis has overflow', () => {
hasYAxisOverflowSpy.and.returnValue(true);
expect(
ng2FittextDirective.checkOverflow(
parentElementMock,
childrenElementMock
)
).toBe(true);
});
});
describe('Method: getStartFontSizeFromHeight', () => {
it('Should return the container clientHeight value if the container is present', () => {
const containerClientHeight = 10;
ng2FittextDirective.container = {
clientHeight: containerClientHeight,
} as HTMLElement;
expect(ng2FittextDirective.getStartFontSizeFromHeight()).toEqual(
containerClientHeight
);
});
it('Should return the parentElement clientHeight value if no container is present', () => {
const parentlientHeight = 11;
elMock.nativeElement = {
parentElement: {
clientHeight: parentlientHeight,
},
} as HTMLElement;
expect(ng2FittextDirective.getStartFontSizeFromHeight()).toEqual(
parentlientHeight
);
});
});
describe('Method: isDone', () => {
it('Should return the done property value', () => {
const defaultDoneValue = false;
expect(ng2FittextDirective.isDone()).toBe(defaultDoneValue);
});
});
describe('Method: isVisible', () => {
it('Should return the true if getStartFontSizeFromHeight() is greater than zero', () => {
spyOn(ng2FittextDirective, 'getStartFontSizeFromHeight').and.returnValue(
1
);
expect(ng2FittextDirective.isVisible()).toBe(true);
});
it('Should return the false if getStartFontSizeFromHeight() is smaller or equal to zero', () => {
const spy = spyOn(
ng2FittextDirective,
'getStartFontSizeFromHeight'
).and.returnValue(0);
expect(ng2FittextDirective.isVisible()).toBe(false);
spy.and.returnValue(-1);
expect(ng2FittextDirective.isVisible()).toBe(false);
});
});
describe('Method: hasXAxisOverflow', () => {
let parentElementMock: HTMLElement;
let childrenElementMock: HTMLElement;
beforeEach(() => {
parentElementMock = {
clientWidth: 0,
} as HTMLElement;
childrenElementMock = {
scrollWidth: 0,
} as HTMLElement;
});
it('Should return false if no overflow is present on the x axis', () => {
expect(
ng2FittextDirective.hasXAxisOverflow(
parentElementMock,
childrenElementMock
)
).toBe(false);
});
it('Should return true if overflow is present on the x axis', () => {
childrenElementMock = {
scrollWidth: 2,
} as HTMLElement;
expect(
ng2FittextDirective.hasXAxisOverflow(
parentElementMock,
childrenElementMock
)
).toBe(true);
});
});
describe('Method: hasYAxisOverflow', () => {
let parentElementMock: HTMLElement;
let childrenElementMock: HTMLElement;
beforeEach(() => {
parentElementMock = {
clientHeight: 0,
} as HTMLElement;
childrenElementMock = {
clientHeight: 0,
} as HTMLElement;
});
it('Should return false if no overflow is present on the x axis', () => {
expect(
ng2FittextDirective.hasYAxisOverflow(
parentElementMock,
childrenElementMock
)
).toBe(false);
});
it('Should return true if overflow is present on the x axis', () => {
childrenElementMock = {
clientHeight: 2,
} as HTMLElement;
expect(
ng2FittextDirective.hasYAxisOverflow(
parentElementMock,
childrenElementMock
)
).toBe(true);
});
});
describe('Method: hasOverflow', () => {
let containerMock: any;
let parentElementMock: any;
beforeEach(() => {
containerMock = {
isContainer: true,
};
parentElementMock = {
isParentElement: true,
};
ng2FittextDirective.container = { ...containerMock };
ng2FittextDirective.el.nativeElement = {
parentElement: { ...parentElementMock },
} as HTMLElement;
});
it('Should calculate the overflow using the container if is present', () => {
spyOn(ng2FittextDirective, 'checkOverflow').and.callFake(
(parentElement: any, childrenElement: any) => {
expect(parentElement).toEqual(containerMock);
return true;
}
);
expect(ng2FittextDirective.hasOverflow()).toBe(true);
});
it('Should calculate the overflow using the parent element if the container is not present', () => {
if(ng2FittextDirective) {
delete (ng2FittextDirective as any).container;
}
spyOn(ng2FittextDirective, 'checkOverflow').and.callFake(
(parentElement: any, childrenElement: any) => {
expect(parentElement).toEqual(parentElementMock);
return true;
}
);
expect(ng2FittextDirective.hasOverflow()).toBe(true);
});
});
});

View file

@ -1,19 +0,0 @@
import { Ng2FittextDirective } from './directives/ng2-fittext.directive';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
export { Ng2FittextDirective } from './directives/ng2-fittext.directive';
@NgModule({
declarations: [Ng2FittextDirective],
exports: [Ng2FittextDirective],
imports: [CommonModule],
})
export class Ng2FittextModule {
static forRoot() {
return {
ngModule: Ng2FittextModule,
providers: [],
};
}
}

View file

@ -1,39 +0,0 @@
{
"name": "ng2-fittext",
"version": "1.3.2",
"description": "Ng2-fittext: An Angular2+ directive that change the font size until it fit the upper level container dimension.",
"keywords": [
"ng2-fittext",
"fittext",
"angular",
"angular 2",
"angular 4",
"angular 5",
"angular 6",
"angular 7",
"angular 8",
"angular 9",
"angular 10",
"angular 11",
"angular 12",
"angular 13",
"angular 14",
"angular 15",
"angular 16",
"angular 17",
"fit text",
"responsive text",
"responsive font size",
"font size"
],
"author": "Lorenzo Iovino",
"license": "MIT",
"ngPackage": {
"lib": {
"entryFile": "./ng2-fittext.module.ts"
}
},
"repository": {
"url": "https://github.com/thisloke/ng2-fittext.git"
}
}

View file

@ -1,35 +0,0 @@
{
"angularCompilerOptions": {
"strictMetadataEmit": true,
"skipTemplateCodegen": true
},
"compilerOptions": {
"baseUrl": "tsconfig",
"declaration": true,
"stripInternal": true,
"strictNullChecks": true,
"noImplicitAny": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es2015", "dom", "es5"],
"inlineSources": true,
"rootDir": "./src",
"mapRoot": "./",
"module": "es2015",
"moduleResolution": "node",
"outDir": "./dist",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"./node_modules/@types"
],
"paths": {
"@angular/core": ["./node_modules/@angular/core"]
}
},
"files": [
],
"awesomeTypescriptLoaderOptions": {
"forkChecker": true
}
}