UNPKG

@rx-angular/template

Version:

**Fully** Reactive Component Template Rendering in Angular. @rx-angular/template aims to be a reflection of Angular's built in renderings just reactive.

1 lines 61.2 kB
{"version":3,"file":"template-virtual-view.mjs","sources":["../../../../libs/template/virtual-view/src/lib/virtual-view.config.ts","../../../../libs/template/virtual-view/src/lib/model.ts","../../../../libs/template/virtual-view/src/lib/assert-injector.ts","../../../../libs/template/virtual-view/src/lib/util.ts","../../../../libs/template/virtual-view/src/lib/virtual-view-cache.ts","../../../../libs/template/virtual-view/src/lib/virtual-view.directive.ts","../../../../libs/template/virtual-view/src/lib/virtual-view-content.directive.ts","../../../../libs/template/virtual-view/src/lib/resize-observer.ts","../../../../libs/template/virtual-view/src/lib/virtual-view-observer.directive.ts","../../../../libs/template/virtual-view/src/lib/virtual-view-placeholder.directive.ts","../../../../libs/template/virtual-view/src/template-virtual-view.ts"],"sourcesContent":["import { InjectionToken, Provider, Signal } from '@angular/core';\nimport { RxStrategyNames } from '@rx-angular/cdk/render-strategies';\n\nexport const VIRTUAL_VIEW_CONFIG_TOKEN =\n new InjectionToken<RxVirtualViewConfig>('VIRTUAL_VIEW_CONFIG_TOKEN', {\n providedIn: 'root',\n factory: () => VIRTUAL_VIEW_CONFIG_DEFAULT,\n });\n\nexport interface RxVirtualViewConfig {\n enabled: boolean | Signal<boolean>;\n keepLastKnownSize: boolean;\n useContentVisibility: boolean;\n useContainment: boolean;\n placeholderStrategy: RxStrategyNames<string>;\n contentStrategy: RxStrategyNames<string>;\n cacheEnabled: boolean;\n startWithPlaceholderAsap: boolean;\n\n /**\n * The scroll margin to observe.\n *\n * Docs: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#scrollmargin\n */\n scrollMargin: string;\n\n /**\n * Whether to enable the visibility after hydration. (DEFAULT: true)\n *\n * If `false`, the elements that were hydrated, won't go back to render placeholder anymore on hydration.\n * You can disable this to avoid destroying components that were just hydrated.\n */\n enableAfterHydration: boolean;\n\n cache: {\n /**\n * The maximum number of contents that can be stored in the cache.\n * Defaults to 20.\n */\n contentCacheSize: number;\n\n /**\n * The maximum number of placeholders that can be stored in the cache.\n * Defaults to 20.\n */\n placeholderCacheSize: number;\n };\n}\n\nexport const VIRTUAL_VIEW_CONFIG_DEFAULT: RxVirtualViewConfig = {\n enabled: true,\n keepLastKnownSize: false,\n useContentVisibility: false,\n useContainment: true,\n placeholderStrategy: 'low',\n contentStrategy: 'normal',\n startWithPlaceholderAsap: false,\n cacheEnabled: true,\n enableAfterHydration: true,\n\n scrollMargin: '100px',\n\n cache: {\n contentCacheSize: 20,\n placeholderCacheSize: 20,\n },\n};\n\n/**\n * Provides a configuration object for the `VirtualView` service.\n *\n * Can be used to customize the behavior of the `VirtualView` service.\n *\n * Default configuration:\n * - contentCacheSize: 20\n * - placeholderCacheSize: 20\n *\n * Example usage:\n *\n * ```ts\n * import { provideVirtualViewConfig } from '@rx-angular/template/virtual-view';\n *\n * const appConfig: ApplicationConfig = {\n * providers: [\n * provideVirtualViewConfig({\n * contentCacheSize: 50,\n * placeholderCacheSize: 50,\n * }),\n * ],\n * };\n * ```\n *\n * @developerPreview\n *\n * @param config - The configuration object.\n * @returns An object that can be provided to the `VirtualView` service.\n */\nexport function provideVirtualViewConfig(\n config: VVConfig | (() => VVConfig),\n): Provider {\n if (typeof config === 'function') {\n return {\n provide: VIRTUAL_VIEW_CONFIG_TOKEN,\n useFactory: () => {\n const cfg = config();\n return {\n ...VIRTUAL_VIEW_CONFIG_DEFAULT,\n ...cfg,\n cache: {\n ...VIRTUAL_VIEW_CONFIG_DEFAULT.cache,\n ...(cfg?.cache ?? {}),\n },\n };\n },\n } satisfies Provider;\n }\n\n return {\n provide: VIRTUAL_VIEW_CONFIG_TOKEN,\n useValue: {\n ...VIRTUAL_VIEW_CONFIG_DEFAULT,\n ...config,\n cache: { ...VIRTUAL_VIEW_CONFIG_DEFAULT.cache, ...(config?.cache ?? {}) },\n },\n } satisfies Provider;\n}\n\ntype VVConfig = Partial<\n RxVirtualViewConfig & { cache?: Partial<RxVirtualViewConfig['cache']> }\n>;\n","import { TemplateRef, ViewContainerRef } from '@angular/core';\nimport { Observable } from 'rxjs';\n\n/**\n * @internal\n */\nexport interface _RxVirtualViewContent {\n viewContainerRef: ViewContainerRef;\n templateRef: TemplateRef<unknown>;\n}\n\n/**\n * @internal\n */\nexport interface _RxVirtualViewPlaceholder {\n templateRef: TemplateRef<unknown>;\n}\n\n/**\n * @internal\n */\nexport abstract class _RxVirtualViewObserver {\n abstract observeElementVisibility(\n virtualView: HTMLElement,\n ): Observable<boolean>;\n abstract observeElementSize(\n element: Element,\n options?: ResizeObserverOptions,\n ): Observable<ResizeObserverEntry>;\n}\n\n/**\n * @internal\n */\nexport abstract class _RxVirtualView {\n abstract registerContent(content: _RxVirtualViewContent): void;\n abstract registerPlaceholder(placeholder: _RxVirtualViewPlaceholder): void;\n}\n","// https://ngxtension.dev/utilities/injectors/assert-injector/\nimport {\n assertInInjectionContext,\n inject,\n Injector,\n runInInjectionContext,\n} from '@angular/core';\n\n/**\n * `assertInjector` extends `assertInInjectionContext` with an optional `Injector`\n * After assertion, `assertInjector` runs the `runner` function with the guaranteed `Injector`\n * whether it is the default `Injector` within the current **Injection Context**\n * or the custom `Injector` that was passed in.\n *\n * @template {() => any} Runner - Runner is a function that can return anything\n * @param {Function} fn - the Function to pass in `assertInInjectionContext`\n * @param {Injector | undefined | null} injector - the optional \"custom\" Injector\n * @param {Runner} runner - the runner fn\n * @returns {ReturnType<Runner>} result - returns the result of the Runner\n *\n * @example\n * ```ts\n * function injectValue(injector?: Injector) {\n * return assertInjector(injectValue, injector, () => 'value');\n * }\n *\n * injectValue(); // string\n * ```\n */\nexport function assertInjector<Runner extends () => any>(\n fn: Function,\n injector: Injector | undefined | null,\n runner: Runner,\n): ReturnType<Runner>;\n/**\n * `assertInjector` extends `assertInInjectionContext` with an optional `Injector`\n * After assertion, `assertInjector` returns a guaranteed `Injector` whether it is the default `Injector`\n * within the current **Injection Context** or the custom `Injector` that was passed in.\n *\n * @param {Function} fn - the Function to pass in `assertInInjectionContext`\n * @param {Injector | undefined | null} injector - the optional \"custom\" Injector\n * @returns Injector\n *\n * @example\n * ```ts\n * function injectDestroy(injector?: Injector) {\n * injector = assertInjector(injectDestroy, injector);\n *\n * return runInInjectionContext(injector, () => {\n * // code\n * })\n * }\n * ```\n */\nexport function assertInjector(\n fn: Function,\n injector: Injector | undefined | null,\n): Injector;\nexport function assertInjector(\n fn: Function,\n injector: Injector | undefined | null,\n runner?: () => any,\n) {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n !injector && assertInInjectionContext(fn);\n const assertedInjector = injector ?? inject(Injector);\n\n if (!runner) return assertedInjector;\n return runInInjectionContext(assertedInjector, runner);\n}\n","// https://ngxtension.dev/utilities/signals/effect-once-if/\nimport {\n CreateEffectOptions,\n effect,\n EffectCleanupRegisterFn,\n EffectRef,\n runInInjectionContext,\n untracked,\n} from '@angular/core';\nimport { assertInjector } from './assert-injector';\n\nexport function effectOnceIf<T = any>(\n condition: () => T,\n execution: (\n valueFromCondition: NonNullable<T>,\n onCleanup: EffectCleanupRegisterFn,\n ) => void,\n options?: Omit<CreateEffectOptions, 'manualCleanup'>,\n): EffectRef {\n const assertedInjector = assertInjector(effectOnceIf, options?.injector);\n return runInInjectionContext(assertedInjector, () => {\n const effectRef = effect((onCleanup) => {\n const hasCondition = condition();\n if (hasCondition) {\n untracked(() => execution(hasCondition, onCleanup));\n effectRef.destroy();\n }\n }, options);\n return effectRef;\n });\n}\n\nexport type EffectOnceIfConditionFn<T> = Parameters<typeof effectOnceIf<T>>[0];\nexport type EffectOnceIfExecutionFn<T> = Parameters<typeof effectOnceIf<T>>[1];\nexport type EffectOnceIfOptions<T> = Parameters<typeof effectOnceIf<T>>[2];\n","import { inject, Injectable, OnDestroy, ViewRef } from '@angular/core';\nimport { VIRTUAL_VIEW_CONFIG_TOKEN } from './virtual-view.config';\n\n/**\n * A service that caches templates and placeholders to optimize view rendering.\n * It makes sure that all cached resources are cleared when the service is destroyed.\n *\n * @developerPreview\n */\n@Injectable()\nexport class VirtualViewCache implements OnDestroy {\n #config = inject(VIRTUAL_VIEW_CONFIG_TOKEN);\n\n // Maximum number of content that can be stored in the cache.\n #contentCacheSize = this.#config.cache.contentCacheSize;\n\n // Cache for storing content views, identified by a unique key, which is the directive instance.\n #contentCache = new Map<unknown, ViewRef>();\n\n // Maximum number of placeholders that can be stored in the cache.\n #placeholderCacheSize = this.#config.cache.placeholderCacheSize;\n\n // Cache for storing placeholder views, identified by a unique key.\n #placeholderCache = new Map<unknown, ViewRef>();\n\n /**\n * Stores a placeholder view in the cache. When the cache reaches its limit,\n * the oldest entry is removed.\n *\n * @param key - The key used to identify the placeholder in the cache.\n * @param view - The ViewRef of the placeholder to cache.\n */\n storePlaceholder(key: unknown, view: ViewRef) {\n if (this.#placeholderCacheSize <= 0) {\n view.destroy();\n return;\n }\n if (this.#placeholderCache.size >= this.#placeholderCacheSize) {\n this.#removeOldestEntry(this.#placeholderCache);\n }\n this.#placeholderCache.set(key, view);\n }\n\n /**\n * Retrieves a cached placeholder view using the specified key.\n *\n * @param key - The key of the placeholder to retrieve.\n * @returns The ViewRef of the cached placeholder, or undefined if not found.\n */\n getPlaceholder(key: unknown) {\n const view = this.#placeholderCache.get(key);\n this.#placeholderCache.delete(key);\n return view;\n }\n\n /**\n * Stores a content view in the cache. When the cache reaches its limit,\n * the oldest entry is removed.\n *\n * @param key - The key used to identify the content in the cache.\n * @param view - The ViewRef of the content to cache.\n */\n storeContent(key: unknown, view: ViewRef) {\n if (this.#contentCacheSize <= 0) {\n view.destroy();\n return;\n }\n if (this.#contentCache.size >= this.#contentCacheSize) {\n this.#removeOldestEntry(this.#contentCache);\n }\n this.#contentCache.set(key, view);\n }\n\n /**\n * Retrieves a cached content view using the specified key.\n *\n * @param key - The key of the content to retrieve.\n * @returns The ViewRef of the cached content, or undefined if not found.\n */\n getContent(key: unknown) {\n const view = this.#contentCache.get(key);\n this.#contentCache.delete(key);\n return view;\n }\n\n /**\n * Clears both content and placeholder caches for a given key.\n *\n * @param key - The key of the content and placeholder to remove.\n */\n clear(key: unknown) {\n this.#contentCache.get(key)?.destroy();\n this.#contentCache.delete(key);\n this.#placeholderCache.get(key)?.destroy();\n this.#placeholderCache.delete(key);\n }\n\n /**\n * Clears all cached resources when the service is destroyed.\n */\n ngOnDestroy() {\n this.#contentCache.forEach((view) => view.destroy());\n this.#placeholderCache.forEach((view) => view.destroy());\n this.#contentCache.clear();\n this.#placeholderCache.clear();\n }\n\n #removeOldestEntry(cache: Map<unknown, ViewRef>) {\n const oldestValue = cache.entries().next().value;\n if (oldestValue !== undefined) {\n const [key, view] = oldestValue;\n view?.destroy();\n cache.delete(key);\n }\n }\n}\n","import {\n AfterContentInit,\n booleanAttribute,\n computed,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n EmbeddedViewRef,\n inject,\n INJECTOR,\n input,\n isSignal,\n OnDestroy,\n output,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n RxStrategyNames,\n RxStrategyProvider,\n} from '@rx-angular/cdk/render-strategies';\nimport { PLATFORM } from '@rx-angular/cdk/ssr';\nimport { finalize, NEVER, Observable, ReplaySubject } from 'rxjs';\nimport { distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';\nimport {\n _RxVirtualView,\n _RxVirtualViewContent,\n _RxVirtualViewObserver,\n _RxVirtualViewPlaceholder,\n} from './model';\nimport { effectOnceIf } from './util';\nimport { VIRTUAL_VIEW_CONFIG_TOKEN } from './virtual-view.config';\nimport { VirtualViewCache } from './virtual-view-cache';\n\n/**\n * The RxVirtualView directive is a directive that allows you to create virtual views.\n *\n * It can be used on an element/component to create a virtual view.\n *\n * It works by using 3 directives:\n * - `rxVirtualViewContent`: The content to render when the virtual view is visible.\n * - `rxVirtualViewPlaceholder`: The placeholder to render when the virtual view is not visible.\n * - `rxVirtualViewObserver`: The directive that observes the virtual view and emits a boolean value indicating whether the virtual view is visible.\n *\n * The `rxVirtualViewObserver` directive is mandatory for the `rxVirtualView` directive to work.\n * And it needs to be a sibling of the `rxVirtualView` directive.\n *\n * @example\n * ```html\n * <div rxVirtualViewObserver>\n * <div rxVirtualView>\n * <div *rxVirtualViewContent>Virtual View 1</div>\n * <div *rxVirtualViewPlaceholder>Loading...</div>\n * </div>\n * </div>\n * ```\n *\n * @developerPreview\n */\n@Directive({\n selector: '[rxVirtualView]',\n host: {\n '[style.--rx-vw-h]': 'height()',\n '[style.--rx-vw-w]': 'width()',\n '[style.min-height]': 'minHeight()',\n '[style.min-width]': 'minWidth()',\n '[style.contain]': 'containment()',\n '[style.contain-intrinsic-width]': 'intrinsicWidth()',\n '[style.contain-intrinsic-height]': 'intrinsicHeight()',\n '[style.content-visibility]': 'useContentVisibility() ? \"auto\" : null',\n },\n exportAs: 'rxVirtualView',\n providers: [{ provide: _RxVirtualView, useExisting: RxVirtualView }],\n})\nexport class RxVirtualView\n implements AfterContentInit, _RxVirtualView, OnDestroy\n{\n readonly #observer = inject(_RxVirtualViewObserver, { optional: true });\n readonly #elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly #strategyProvider = inject<RxStrategyProvider>(RxStrategyProvider);\n readonly #viewCache = inject(VirtualViewCache, { optional: true });\n readonly #destroyRef = inject(DestroyRef);\n readonly #config = inject(VIRTUAL_VIEW_CONFIG_TOKEN);\n readonly #platform = inject(PLATFORM);\n readonly #injector = inject(INJECTOR);\n\n readonly #enabled = computed(() =>\n isSignal(this.#config.enabled)\n ? this.#config.enabled()\n : this.#config.enabled,\n );\n\n #content = signal<_RxVirtualViewContent | null>(null);\n #placeholder = signal<_RxVirtualViewPlaceholder | null>(null);\n\n /**\n * Useful when we want to cache the templates and placeholders to optimize view rendering.\n *\n * Enabled by default.\n */\n readonly cacheEnabled = input(this.#config.cacheEnabled, {\n transform: booleanAttribute,\n });\n\n /**\n * Whether to start with the placeholder asap or not.\n *\n * If `true`, the placeholder will be rendered immediately, without waiting for the content to be visible.\n * This is useful when you want to render the placeholder immediately, but you don't want to wait for the content to be visible.\n *\n * This is to counter concurrent rendering, and to avoid flickering.\n */\n readonly startWithPlaceholderAsap = input(\n this.#config.startWithPlaceholderAsap,\n { transform: booleanAttribute },\n );\n\n /**\n * This will keep the last known size of the host element while the content is visible.\n */\n readonly keepLastKnownSize = input(this.#config.keepLastKnownSize, {\n transform: booleanAttribute,\n });\n\n /**\n * Whether to use content visibility or not.\n *\n * It will add the `content-visibility` CSS class to the host element, together with\n * `contain-intrinsic-width` and `contain-intrinsic-height` CSS properties.\n */\n readonly useContentVisibility = input(this.#config.useContentVisibility, {\n transform: booleanAttribute,\n });\n\n /**\n * Whether to use containment or not.\n *\n * It will add `contain` css property with:\n * - `size layout paint`: if `useContentVisibility` is `true` && placeholder is visible\n * - `content`: if `useContentVisibility` is `false` || content is visible\n */\n readonly useContainment = input(this.#config.useContainment, {\n transform: booleanAttribute,\n });\n\n /**\n * The strategy to use for rendering the placeholder.\n */\n readonly placeholderStrategy = input<RxStrategyNames<string>>(\n this.#config.placeholderStrategy,\n );\n\n /**\n * The strategy to use for rendering the content.\n */\n readonly contentStrategy = input<RxStrategyNames<string>>(\n this.#config.contentStrategy,\n );\n\n /**\n * A function extracting width & height from a ResizeObserverEntry\n */\n readonly extractSize =\n input<(entry: ResizeObserverEntry) => { width: number; height: number }>(\n defaultExtractSize,\n );\n\n /**\n * ResizeObserverOptions\n */\n readonly resizeObserverOptions = input<ResizeObserverOptions>();\n\n /**\n * Emits when the visibility state of the virtual view changes.\n *\n * This output fires whenever the virtual view transitions between showing content and showing placeholder.\n * The emitted value is an object containing the current visibility state of both the content and placeholder.\n *\n * @example\n * ```html\n * <div rxVirtualViewObserver>\n * <div rxVirtualView (visibilityChanged)=\"onVisibilityChanged($event)\">\n * <div *rxVirtualViewContent>Virtual View Content</div>\n * <div *rxVirtualViewPlaceholder>Loading...</div>\n * </div>\n * </div>\n * ```\n *\n * ```typescript\n * onVisibilityChanged(event: { content: boolean; placeholder: boolean }) {\n * console.log('Content visible:', event.content);\n * console.log('Placeholder visible:', event.placeholder);\n * }\n * ```\n */\n readonly visibilityChanged = output<{\n content: boolean;\n placeholder: boolean;\n }>();\n\n /**\n * Returns the current visibility state of the content and placeholder.\n *\n * This getter provides synchronous access to the visibility state, which can be useful\n * when you need to check the current state imperatively or from the template.\n *\n * @returns An object containing:\n * - `content`: `true` if the content is currently visible, `false` otherwise\n * - `placeholder`: `true` if the placeholder is currently visible, `false` otherwise\n *\n * @example\n * ```html\n * <!-- Access visibility state in template using exportAs -->\n * <div rxVirtualViewObserver>\n * <div rxVirtualView #virtualView=\"rxVirtualView\">\n * <div *rxVirtualViewContent>Virtual View Content</div>\n * <div *rxVirtualViewPlaceholder>Loading...</div>\n * </div>\n *\n * <!-- Display visibility state -->\n * <div>\n * Content visible: {{ virtualView.visibility.content }}\n * Placeholder visible: {{ virtualView.visibility.placeholder }}\n * </div>\n * </div>\n * ```\n */\n get visibility() {\n return {\n content: this.#contentIsShown,\n placeholder: !this.#contentIsShown,\n };\n }\n\n readonly #placeholderVisible = signal(false);\n\n #contentIsShown = false;\n\n /**\n * The `_RxVirtualViewContent` directive whose template is currently embedded\n * in the view container. Used to detect runtime content-template swaps (e.g.\n * an `@switch` / `@if` case change inside `rxVirtualView` that replaces the\n * active `*rxVirtualViewContent` while the host element stays mounted) so the\n * new template is rendered instead of leaving the card blank.\n */\n #renderedContent: _RxVirtualViewContent | null = null;\n\n readonly #visible$ = new ReplaySubject<boolean>(1);\n\n readonly size = signal({ width: 0, height: 0 });\n\n readonly width = computed(() =>\n this.#enabled() && this.size().width ? `${this.size().width}px` : null,\n );\n\n readonly height = computed(() =>\n this.#enabled() && this.size().height ? `${this.size().height}px` : null,\n );\n\n readonly containment = computed(() => {\n if (!this.useContainment() || !this.#enabled()) {\n return null;\n }\n return this.useContentVisibility() && this.#placeholderVisible()\n ? 'size layout paint'\n : 'content';\n });\n\n readonly intrinsicWidth = computed(() => {\n if (!this.useContentVisibility() || !this.#enabled()) {\n return null;\n }\n return this.width() === 'auto' ? 'auto' : `auto ${this.width()}`;\n });\n readonly intrinsicHeight = computed(() => {\n if (!this.useContentVisibility() || !this.#enabled()) {\n return null;\n }\n return this.height() === 'auto' ? 'auto' : `auto ${this.height()}`;\n });\n\n readonly minHeight = computed(() => {\n return this.keepLastKnownSize() &&\n this.#placeholderVisible() &&\n this.#enabled()\n ? this.height()\n : null;\n });\n readonly minWidth = computed(() => {\n return this.keepLastKnownSize() &&\n this.#placeholderVisible() &&\n this.#enabled()\n ? this.width()\n : null;\n });\n\n constructor() {\n effectOnceIf(\n () => this.#enabled(),\n () => {\n if (this.#platform.isBrowser && !this.#observer) {\n throw new Error(\n 'RxVirtualView expects you to provide a RxVirtualViewObserver',\n );\n }\n },\n );\n }\n\n ngAfterContentInit() {\n if (this.#enabled()) {\n if (!this.#content()) {\n throw new Error(\n 'RxVirtualView expects you to provide a RxVirtualViewContent',\n );\n }\n if (this.startWithPlaceholderAsap()) {\n this.renderPlaceholder();\n }\n }\n\n // when enabled:\n // - register visibility listener\n // - hide things that are not visible anymore\n if (this.#enabled()) {\n this.#registerRenderingBasedOnVisibility();\n } else if (this.#config.enableAfterHydration) {\n // Disabled now (server / pre-hydration). Once the view becomes enabled\n // (e.g. after hydration) switch to visibility-based rendering.\n effectOnceIf(\n () => this.#enabled(),\n () => this.#registerRenderingBasedOnVisibility(),\n { injector: this.#injector },\n );\n }\n\n // Keep the embedded content in sync with the active *rxVirtualViewContent\n // directive. A single effect covers every case where #content() changes:\n // - the disabled/SSR initial render (show content as soon as available),\n // - deferred content that starts inside an inactive @if/@switch branch,\n // - runtime content-template swaps (e.g. an @switch case change) while the\n // host element stays mounted, in both the disabled and enabled states.\n this.#registerContentSync();\n }\n\n /**\n * Reactively renders the active content directive whenever it changes.\n *\n * While disabled the current content is always shown. While enabled the\n * visibility pipeline owns the initial show/hide (and size handling), so this\n * only re-renders a *swap* that happens while content is already shown —\n * otherwise it would fight the placeholder/visibility logic.\n * @private\n */\n #registerContentSync() {\n effect(\n () => {\n const content = this.#content();\n if (!content || content === this.#renderedContent) {\n return;\n }\n const shouldShow = this.#enabled() ? this.#contentIsShown : true;\n if (shouldShow) {\n this.#renderContent(content);\n }\n },\n { injector: this.#injector },\n );\n }\n\n /**\n * Creates the embedded view for the given content directive and marks it as\n * the currently rendered content. Used for the disabled render and for\n * runtime content-template swaps.\n * @private\n */\n #renderContent(content: _RxVirtualViewContent) {\n this.#contentIsShown = true;\n this.#placeholderVisible.set(false);\n this.#renderedContent = content;\n const view = content.viewContainerRef.createEmbeddedView(\n content.templateRef,\n );\n view.detectChanges();\n this.visibilityChanged.emit({ content: true, placeholder: false });\n }\n\n #registerRenderingBasedOnVisibility() {\n this.#observer\n ?.observeElementVisibility(this.#elementRef.nativeElement)\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe((visible) => this.#visible$.next(visible));\n\n this.#visible$\n .pipe(\n distinctUntilChanged(),\n switchMap((visible) => {\n if (visible) {\n return this.#contentIsShown\n ? NEVER\n : this.showContent$().pipe(\n switchMap((view) => {\n const resize$ = this.#observer!.observeElementSize(\n this.#elementRef.nativeElement,\n this.resizeObserverOptions(),\n );\n view.detectChanges();\n return resize$;\n }),\n map(this.extractSize()),\n tap(({ width, height }) => this.size.set({ width, height })),\n );\n }\n return this.#placeholderVisible() ? NEVER : this.showPlaceholder$();\n }),\n finalize(() => {\n this.#viewCache!.clear(this);\n }),\n takeUntilDestroyed(this.#destroyRef),\n )\n .subscribe();\n }\n\n ngOnDestroy() {\n this.#content.set(null);\n this.#placeholder.set(null);\n this.#renderedContent = null;\n this.#viewCache?.clear(this);\n }\n\n registerContent(content: _RxVirtualViewContent) {\n this.#content.set(content);\n }\n\n registerPlaceholder(placeholder: _RxVirtualViewPlaceholder) {\n this.#placeholder.set(placeholder);\n }\n\n /**\n * Shows the content using the configured rendering strategy (by default: normal).\n * @private\n */\n private showContent$(): Observable<EmbeddedViewRef<unknown>> {\n return this.#strategyProvider.schedule(\n () => {\n this.#contentIsShown = true;\n this.#renderedContent = this.#content();\n this.#placeholderVisible.set(false);\n const placeHolder = this.#content()!.viewContainerRef.detach();\n if (this.cacheEnabled() && placeHolder) {\n this.#viewCache!.storePlaceholder(this, placeHolder);\n } else if (!this.cacheEnabled() && placeHolder) {\n placeHolder.destroy();\n }\n const contentTpl =\n (this.#viewCache!.getContent(this) as EmbeddedViewRef<unknown>) ??\n this.#content()!.templateRef.createEmbeddedView({});\n this.#content()!.viewContainerRef.insert(contentTpl);\n placeHolder?.detectChanges();\n this.visibilityChanged.emit({ content: true, placeholder: false });\n return contentTpl;\n },\n { scope: this, strategy: this.contentStrategy() },\n );\n }\n\n /**\n * Shows the placeholder using the configured rendering strategy (by default: low).\n * @private\n */\n private showPlaceholder$() {\n return this.#strategyProvider.schedule(() => this.renderPlaceholder(), {\n scope: this,\n strategy: this.placeholderStrategy(),\n });\n }\n\n /**\n * Renders a placeholder within the view container, and hides the content.\n *\n * If we already have a content and cache enabled, we store the content in\n * the cache, so we can reuse it later.\n *\n * When we want to render the placeholder, we try to get it from the cache,\n * and if it is not available, we create a new one.\n *\n * Then insert the placeholder into the view container and trigger a CD.\n */\n private renderPlaceholder() {\n this.#placeholderVisible.set(true);\n this.#contentIsShown = false;\n\n const content = this.#content()!.viewContainerRef.detach();\n\n if (content) {\n if (this.cacheEnabled()) {\n this.#viewCache!.storeContent(this, content);\n } else {\n content.destroy();\n }\n\n content?.detectChanges();\n }\n\n if (this.#placeholder()) {\n const placeholderRef =\n this.#viewCache!.getPlaceholder(this) ??\n this.#placeholder()!.templateRef.createEmbeddedView({});\n\n this.#content()!.viewContainerRef.insert(placeholderRef);\n placeholderRef.detectChanges();\n }\n\n this.visibilityChanged.emit({ content: false, placeholder: true });\n }\n}\n\nconst defaultExtractSize = (entry: ResizeObserverEntry) => ({\n width: entry.borderBoxSize[0].inlineSize,\n height: entry.borderBoxSize[0].blockSize,\n});\n","import {\n Directive,\n inject,\n TemplateRef,\n ViewContainerRef,\n} from '@angular/core';\nimport { _RxVirtualViewContent } from './model';\nimport { RxVirtualView } from './virtual-view.directive';\n\n/**\n * The RxVirtualViewTemplate directive is a directive that allows you to create a content template for the virtual view.\n *\n * It can be used on an element/component to create a content template for the virtual view.\n *\n * It needs to be a sibling of the `rxVirtualView` directive.\n *\n * @example\n * ```html\n * <div rxVirtualViewObserver>\n * <div rxVirtualView>\n * <div *rxVirtualViewContent>Virtual View 1</div>\n * <div *rxVirtualViewPlaceholder>Loading...</div>\n * </div>\n * </div>\n * ```\n *\n * @developerPreview\n */\n@Directive({ selector: '[rxVirtualViewContent]', standalone: true })\nexport class RxVirtualViewContent implements _RxVirtualViewContent {\n #virtualView = inject(RxVirtualView);\n viewContainerRef = inject(ViewContainerRef);\n constructor(public templateRef: TemplateRef<unknown>) {\n this.#virtualView.registerContent(this);\n }\n}\n","import { DestroyRef, inject, Injectable } from '@angular/core';\nimport { PLATFORM } from '@rx-angular/cdk/ssr';\nimport { EMPTY, Observable, ReplaySubject, Subject } from 'rxjs';\nimport { distinctUntilChanged, finalize } from 'rxjs/operators';\n\n/**\n * A service that observes the resize of the elements.\n *\n * @developerPreview\n */\n@Injectable()\nexport class RxaResizeObserver {\n #destroyRef = inject(DestroyRef);\n #platform = inject(PLATFORM);\n\n #resizeObserver: ResizeObserver | null = null;\n\n /** @internal */\n #elements = new Map<Element, Subject<ResizeObserverEntry>>();\n\n constructor() {\n if (this.#platform.isBrowser) {\n this.#resizeObserver = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n if (this.#elements.has(entry.target))\n this.#elements.get(entry.target)!.next(entry);\n });\n });\n }\n\n this.#destroyRef.onDestroy(() => {\n this.#elements.clear();\n this.#resizeObserver?.disconnect();\n });\n }\n\n observeElement(\n element: Element,\n options?: ResizeObserverOptions,\n ): Observable<ResizeObserverEntry> {\n if (!this.#resizeObserver) {\n return EMPTY;\n }\n\n const resizeEvent$ = new ReplaySubject<ResizeObserverEntry>(1);\n this.#elements.set(element, resizeEvent$);\n this.#resizeObserver.observe(element, options);\n\n return resizeEvent$.pipe(\n distinctUntilChanged(),\n finalize(() => {\n this.#resizeObserver?.unobserve(element);\n this.#elements.delete(element);\n }),\n );\n }\n}\n","import {\n computed,\n Directive,\n ElementRef,\n inject,\n input,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { PLATFORM } from '@rx-angular/cdk/ssr';\nimport {\n BehaviorSubject,\n combineLatest,\n Observable,\n of,\n ReplaySubject,\n Subject,\n} from 'rxjs';\nimport { distinctUntilChanged, finalize, map } from 'rxjs/operators';\nimport { _RxVirtualViewObserver } from './model';\nimport { RxaResizeObserver } from './resize-observer';\nimport { VIRTUAL_VIEW_CONFIG_TOKEN } from './virtual-view.config';\nimport { VirtualViewCache } from './virtual-view-cache';\n\n/**\n * The RxVirtualViewObserver directive observes the virtual view and emits a boolean value indicating whether the virtual view is visible.\n * This is the container for the RxVirtualView directives.\n *\n * This is a mandatory directive for the RxVirtualView directives to work.\n *\n * @example\n * ```html\n * <div rxVirtualViewObserver>\n * <div rxVirtualView>\n * <div *rxVirtualViewContent>Virtual View 1</div>\n * <div *rxVirtualViewPlaceholder>Loading...</div>\n * </div>\n * </div>\n * ```\n *\n * @developerPreview\n */\n@Directive({\n selector: '[rxVirtualViewObserver]',\n standalone: true,\n providers: [\n VirtualViewCache,\n RxaResizeObserver,\n { provide: _RxVirtualViewObserver, useExisting: RxVirtualViewObserver },\n ],\n})\nexport class RxVirtualViewObserver\n extends _RxVirtualViewObserver\n implements OnInit, OnDestroy\n{\n #config = inject(VIRTUAL_VIEW_CONFIG_TOKEN);\n #platform = inject(PLATFORM);\n #elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n\n #observer: IntersectionObserver | null = null;\n\n #resizeObserver = inject(RxaResizeObserver, { self: true });\n\n /**\n * The root element to observe.\n *\n * If not provided, the root element is the element that the directive is attached to.\n */\n root = input<ElementRef | HTMLElement | null>();\n\n /**\n * The root margin to observe.\n *\n * This is useful when you want to observe the virtual view in a specific area of the root element.\n */\n rootMargin = input('');\n\n /**\n * The scroll margin to observe.\n *\n * This is useful when you want to observe the virtual view in a specific area of the scroll container.\n */\n scrollMargin = input(this.#config.scrollMargin);\n\n /**\n * The threshold to observe.\n *\n * If you want to observe the virtual view when it is partially visible, you can set the threshold to a number between 0 and 1.\n *\n * For example, if you set the threshold to 0.5, the virtual view will be observed when it is half visible.\n */\n threshold = input<number | number[]>(0);\n\n #rootElement = computed(() => {\n const root = this.root();\n if (root) {\n if (root instanceof ElementRef) {\n return root.nativeElement;\n }\n return root;\n } else if (root === null) {\n return null;\n }\n return this.#elementRef.nativeElement;\n });\n\n #elements = new Map<Element, Subject<boolean>>();\n\n #forcedHidden$ = new BehaviorSubject(false);\n\n ngOnInit(): void {\n if (this.#platform.isBrowser) {\n this.#observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (this.#elements.has(entry.target))\n this.#elements.get(entry.target)?.next(entry.isIntersecting);\n });\n },\n {\n root: this.#rootElement(),\n rootMargin: this.rootMargin(),\n // @ts-expect-error - scrollMargin is not available in the type of IntersectionObserverInit\n scrollMargin: this.scrollMargin(),\n threshold: this.threshold(),\n },\n );\n }\n }\n\n ngOnDestroy() {\n this.#elements.clear();\n this.#observer?.disconnect();\n this.#observer = null;\n }\n\n /**\n * Hide all the virtual views.\n *\n * This is useful when you want to hide all the virtual views when the user cannot see them.\n *\n * For example, when the user opens a modal, you can hide all the virtual views to improve performance.\n *\n * **IMPORTANT:**\n *\n * Don't forget to call `showAllVisible()` when you want to show the virtual views again.\n */\n hideAll(): void {\n this.#forcedHidden$.next(true);\n }\n\n /**\n * Show all the virtual views that are currently visible.\n *\n * This needs to be called if `hideAll()` was called before.\n */\n showAllVisible(): void {\n this.#forcedHidden$.next(false);\n }\n\n observeElementVisibility(virtualView: HTMLElement) {\n if (this.#platform.isServer) {\n return of(true);\n }\n\n const isVisible$ = new ReplaySubject<boolean>(1);\n\n // Store the view and the visibility state in the map.\n // This allows us to retrieve the visibility state later.\n this.#elements.set(virtualView, isVisible$);\n\n // Start observing the virtual view immediately.\n this.#observer?.observe(virtualView);\n\n return combineLatest([isVisible$, this.#forcedHidden$]).pipe(\n map(([isVisible, forcedHidden]) => (forcedHidden ? false : isVisible)),\n distinctUntilChanged(),\n finalize(() => {\n this.#observer?.unobserve(virtualView);\n this.#elements.delete(virtualView);\n }),\n );\n }\n\n observeElementSize(\n element: Element,\n options?: ResizeObserverOptions,\n ): Observable<ResizeObserverEntry> {\n return this.#resizeObserver.observeElement(element, options);\n }\n}\n","import { Directive, inject, TemplateRef } from '@angular/core';\nimport { _RxVirtualView, _RxVirtualViewPlaceholder } from './model';\n\n/**\n * The RxVirtualViewPlaceholder directive is a directive that allows you to create a placeholder for the virtual view.\n *\n * It can be used on an element/component to create a placeholder for the virtual view.\n *\n * It needs to be a sibling of the `rxVirtualView` directive.\n *\n * @example\n * ```html\n * <div rxVirtualViewObserver>\n * <div rxVirtualView>\n * <div *rxVirtualViewContent>Virtual View 1</div>\n * <div *rxVirtualViewPlaceholder>Loading...</div>\n * </div>\n * </div>\n * ```\n *\n * @developerPreview\n */\n@Directive({ selector: '[rxVirtualViewPlaceholder]', standalone: true })\nexport class RxVirtualViewPlaceholder implements _RxVirtualViewPlaceholder {\n #virtualView = inject(_RxVirtualView);\n constructor(public templateRef: TemplateRef<unknown>) {\n this.#virtualView.registerPlaceholder(this);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["finalize"],"mappings":"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