From aed43fc177bfc2d9864a157de70e18ae562d2505 Mon Sep 17 00:00:00 2001 From: arturovt Date: Wed, 1 Jan 2025 23:27:54 +0200 Subject: [PATCH] refactor: do not export config entry and do some cleanups In this commit, we avoid re-exporting items from the config entry point to prevent bundling these libraries together. Additionally, some functions have been removed because they are only used once. The `OnPush` strategy has also been improved to make it more automatic. --- README.md | 6 +++-- .../helipopper/config/src/public-api.ts | 2 -- .../helipopper/config/src/tippy.types.ts | 8 ------- .../{config/src => src/lib}/inject-tippy.ts | 9 ++++++-- .../helipopper/src/lib/tippy.directive.ts | 17 +++++++++----- .../helipopper/src/lib/tippy.service.ts | 5 +++-- projects/ngneat/helipopper/src/lib/utils.ts | 22 ++++++------------- projects/ngneat/helipopper/src/public-api.ts | 14 +----------- src/app/playground/playground.component.ts | 3 ++- 9 files changed, 35 insertions(+), 51 deletions(-) rename projects/ngneat/helipopper/{config/src => src/lib}/inject-tippy.ts (57%) diff --git a/README.md b/README.md index ad9015f..11b8d95 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,8 @@ export const tooltipVariation = { ### Use `Component` as content ```ts -import { injectTippyRef, TippyInstance } from '@ngneat/helipopper/config'; +import type { TippyInstance } from '@ngneat/helipopper/config'; +import { injectTippyRef } from '@ngneat/helipopper'; @Component() class MyComponent { @@ -315,7 +316,8 @@ tpVisible = new EventEmitter(); ### Create `tippy` Programmatically ```typescript -import { TippyService, TippyInstance } from '@ngneat/helipopper'; +import type { TippyInstance } from '@ngneat/helipopper/config'; +import { TippyService } from '@ngneat/helipopper'; class Component { @ViewChild('inputName') inputName: ElementRef; diff --git a/projects/ngneat/helipopper/config/src/public-api.ts b/projects/ngneat/helipopper/config/src/public-api.ts index 09cfeeb..6b23734 100644 --- a/projects/ngneat/helipopper/config/src/public-api.ts +++ b/projects/ngneat/helipopper/config/src/public-api.ts @@ -9,8 +9,6 @@ export { TippyConfig, TippyLoader, TIPPY_LOADER, - TIPPY_REF, TIPPY_CONFIG, } from './tippy.types'; export { provideTippyLoader, provideTippyConfig } from './providers'; -export { injectTippyRef } from './inject-tippy'; diff --git a/projects/ngneat/helipopper/config/src/tippy.types.ts b/projects/ngneat/helipopper/config/src/tippy.types.ts index d32da24..abb8465 100644 --- a/projects/ngneat/helipopper/config/src/tippy.types.ts +++ b/projects/ngneat/helipopper/config/src/tippy.types.ts @@ -3,10 +3,6 @@ import type { Instance, Props } from 'tippy.js'; import { ElementRef, InjectionToken } from '@angular/core'; import type { ResolveViewRef, ViewOptions } from '@ngneat/overview'; -export const enum TippyErrorCode { - TippyNotProvided = 1, -} - export interface CreateOptions extends Partial, ViewOptions { variation: string; preserveView: boolean; @@ -43,10 +39,6 @@ export const TIPPY_LOADER = new InjectionToken( typeof ngDevMode !== 'undefined' && ngDevMode ? 'TIPPY_LOADER' : '' ); -export const TIPPY_REF = /* @__PURE__ */ new InjectionToken( - typeof ngDevMode !== 'undefined' && ngDevMode ? 'TIPPY_REF' : '' -); - export const TIPPY_CONFIG = new InjectionToken( typeof ngDevMode !== 'undefined' && ngDevMode ? 'TIPPY_CONFIG' : '' ); diff --git a/projects/ngneat/helipopper/config/src/inject-tippy.ts b/projects/ngneat/helipopper/src/lib/inject-tippy.ts similarity index 57% rename from projects/ngneat/helipopper/config/src/inject-tippy.ts rename to projects/ngneat/helipopper/src/lib/inject-tippy.ts index 5c4354b..88f7782 100644 --- a/projects/ngneat/helipopper/config/src/inject-tippy.ts +++ b/projects/ngneat/helipopper/src/lib/inject-tippy.ts @@ -1,6 +1,11 @@ -import { inject } from '@angular/core'; +import { inject, InjectionToken } from '@angular/core'; +import type { TippyInstance } from '@ngneat/helipopper/config'; -import { TIPPY_REF, TippyErrorCode, type TippyInstance } from './tippy.types'; +import { TippyErrorCode } from './utils'; + +export const TIPPY_REF = /* @__PURE__ */ new InjectionToken( + typeof ngDevMode !== 'undefined' && ngDevMode ? 'TIPPY_REF' : '' +); export function injectTippyRef(): TippyInstance { const instance = inject(TIPPY_REF, { optional: true }); diff --git a/projects/ngneat/helipopper/src/lib/tippy.directive.ts b/projects/ngneat/helipopper/src/lib/tippy.directive.ts index e6058b2..86f6927 100644 --- a/projects/ngneat/helipopper/src/lib/tippy.directive.ts +++ b/projects/ngneat/helipopper/src/lib/tippy.directive.ts @@ -48,13 +48,13 @@ import { } from './utils'; import { TIPPY_CONFIG, - TIPPY_REF, TippyConfig, TippyInstance, TippyProps, } from '@ngneat/helipopper/config'; import { TippyFactory } from './tippy.factory'; import { coerceBooleanAttribute } from './coercion'; +import { TIPPY_REF } from './inject-tippy'; // These are the default values used by `tippy.js`. // We are providing them as default input values. @@ -184,8 +184,6 @@ export class TippyDirective implements OnChanges, AfterViewInit, OnInit { alias: 'tpHideOnEscape', }); - readonly detectChangesComponent = input(true, { alias: 'tpDetectChangesComponent' }); - readonly popperWidth = input(undefined, { alias: 'tpPopperWidth', }); @@ -491,9 +489,16 @@ export class TippyDirective implements OnChanges, AfterViewInit, OnInit { ...this.viewOptions$, }); - // We need to call detectChanges for onPush components to update the content - if (this.detectChangesComponent() && isComponent(content)) { - this.viewRef.detectChanges(); + // We need to call `detectChanges` for OnPush components to update their content. + if (isComponent(content)) { + // `ɵcmp` is a component defition set for any component. + // Checking the `onPush` property of the component definition is a + // smarter way to determine whether we need to call `detectChanges()`, + // as users may be unaware of setting the binding. + const isOnPush = (content as { ɵcmp?: { onPush: boolean } }).ɵcmp?.onPush; + if (isOnPush) { + this.viewRef.detectChanges(); + } } let newContent = this.viewRef.getElement(); diff --git a/projects/ngneat/helipopper/src/lib/tippy.service.ts b/projects/ngneat/helipopper/src/lib/tippy.service.ts index dc5fc65..53b9ca7 100644 --- a/projects/ngneat/helipopper/src/lib/tippy.service.ts +++ b/projects/ngneat/helipopper/src/lib/tippy.service.ts @@ -12,12 +12,13 @@ import { CreateOptions, ExtendedTippyInstance, TIPPY_CONFIG, - TIPPY_REF, TippyConfig, TippyInstance, } from '@ngneat/helipopper/config'; -import { normalizeClassName, onlyTippyProps } from './utils'; + +import { TIPPY_REF } from './inject-tippy'; import { TippyFactory } from './tippy.factory'; +import { normalizeClassName, onlyTippyProps } from './utils'; @Injectable({ providedIn: 'root' }) export class TippyService { diff --git a/projects/ngneat/helipopper/src/lib/utils.ts b/projects/ngneat/helipopper/src/lib/utils.ts index aaa7f27..823998c 100644 --- a/projects/ngneat/helipopper/src/lib/utils.ts +++ b/projects/ngneat/helipopper/src/lib/utils.ts @@ -15,6 +15,10 @@ if (typeof window !== 'undefined') { supportsResizeObserver = 'ResizeObserver' in window; } +export const enum TippyErrorCode { + TippyNotProvided = 1, +} + export function inView( host: TippyElement, options: IntersectionObserverInit = { @@ -66,11 +70,7 @@ export function overflowChanges(host: TippyElement) { } export function dimensionsChanges(target: HTMLElement) { - return resizeObserverStrategy(target); -} - -function resizeObserverStrategy(target: HTMLElement): Observable { - return new Observable((subscriber) => { + return new Observable((subscriber) => { if (!supportsResizeObserver) { subscriber.next(); subscriber.complete(); @@ -122,27 +122,19 @@ export function onlyTippyProps(allProps: any) { } export function normalizeClassName(className: string | string[]): string[] { - const classes = isString(className) ? className.split(' ') : className; + const classes = typeof className === 'string' ? className.split(' ') : className; return classes.map((klass) => klass?.trim()).filter(Boolean); } export function coerceCssPixelValue(value: T): string { - if (isNil(value)) { + if (value == null) { return ''; } return typeof value === 'string' ? value : `${value}px`; } -function isString(value: unknown): value is string { - return typeof value === 'string'; -} - -function isNil(value: any): value is undefined | null { - return value === undefined || value === null; -} - function coerceElement(element: TippyElement) { return element instanceof ElementRef ? element.nativeElement : element; } diff --git a/projects/ngneat/helipopper/src/public-api.ts b/projects/ngneat/helipopper/src/public-api.ts index e98bed0..6500311 100644 --- a/projects/ngneat/helipopper/src/public-api.ts +++ b/projects/ngneat/helipopper/src/public-api.ts @@ -1,16 +1,4 @@ export { TippyDirective } from './lib/tippy.directive'; export { TippyService } from './lib/tippy.service'; export { inView, overflowChanges } from './lib/utils'; - -export { - ExtendedTippyInstance, - TippyInstance, - TIPPY_REF, - TippyConfig, - TIPPY_CONFIG, - tooltipVariation, - popperVariation, - withContextMenuVariation, - provideTippyConfig, - injectTippyRef, -} from '@ngneat/helipopper/config'; +export { TIPPY_REF, injectTippyRef } from './lib/inject-tippy'; diff --git a/src/app/playground/playground.component.ts b/src/app/playground/playground.component.ts index b28fd96..5a17b6b 100644 --- a/src/app/playground/playground.component.ts +++ b/src/app/playground/playground.component.ts @@ -8,7 +8,8 @@ import { import { toSignal } from '@angular/core/rxjs-interop'; import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; import { ExampleComponent } from '../example/example.component'; -import { TippyDirective, TippyInstance, TippyService } from '@ngneat/helipopper'; +import type { TippyInstance } from '@ngneat/helipopper/config'; +import { TippyDirective, TippyService } from '@ngneat/helipopper'; import type { Placement } from 'tippy.js'; import { startWith } from 'rxjs'; import { CommonModule } from '@angular/common';