ng-primitives 0.95.0 → 0.97.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"ng-primitives-toast.mjs","sources":["../../../../packages/ng-primitives/toast/src/config/toast-config.ts","../../../../packages/ng-primitives/toast/src/toast/toast-context.ts","../../../../packages/ng-primitives/toast/src/toast/toast-options.ts","../../../../packages/ng-primitives/toast/src/toast/toast-manager.ts","../../../../packages/ng-primitives/toast/src/toast/toast-timer.ts","../../../../packages/ng-primitives/toast/src/toast/toast.ts","../../../../packages/ng-primitives/toast/src/ng-primitives-toast.ts"],"sourcesContent":["import { InjectionToken, Provider, inject } from '@angular/core';\nimport { NgpToastPlacement, NgpToastSwipeDirection } from '../toast/toast';\n\nexport interface NgpToastConfig {\n /**\n * The position of the toast.\n */\n placement: NgpToastPlacement;\n\n /**\n * The duration of each toast.\n */\n duration: number;\n\n /**\n * The offset from the top of the viewport in pixels.\n */\n offsetTop: number;\n\n /**\n * The offset from the bottom of the viewport in pixels.\n */\n offsetBottom: number;\n\n /**\n * The offset from the left of the viewport in pixels.\n */\n offsetLeft: number;\n\n /**\n * The offset from the right of the viewport in pixels.\n */\n offsetRight: number;\n\n /**\n * Whether a toast can be dismissed by swiping.\n */\n dismissible: boolean;\n\n /**\n * The amount a toast must be swiped before it is considered dismissed.\n */\n swipeThreshold: number;\n\n /**\n * The default swipe directions supported by the toast.\n */\n swipeDirections: NgpToastSwipeDirection[];\n\n /**\n * The maximum number of toasts that can be displayed at once.\n */\n maxToasts: number;\n\n /**\n * The aria live setting.\n */\n ariaLive: string;\n\n /**\n * The gap between each toast.\n */\n gap: number;\n\n /**\n * The z-index of the toast container.\n * This is used to ensure that the toast container is always on top of other elements.\n */\n zIndex: number;\n}\n\nexport const defaultToastConfig: NgpToastConfig = {\n gap: 14,\n duration: 3000,\n placement: 'top-end',\n offsetTop: 24,\n offsetBottom: 24,\n offsetLeft: 24,\n offsetRight: 24,\n swipeThreshold: 45,\n swipeDirections: ['left', 'right', 'top', 'bottom'],\n dismissible: true,\n maxToasts: 3,\n zIndex: 9999999,\n ariaLive: 'polite',\n};\n\nexport const NgpToastConfigToken = new InjectionToken<NgpToastConfig>('NgpToastConfigToken');\n\n/**\n * Provide the default Toast configuration\n * @param config The Toast configuration\n * @returns The provider\n */\nexport function provideToastConfig(config: Partial<NgpToastConfig>): Provider[] {\n return [\n {\n provide: NgpToastConfigToken,\n useValue: { ...defaultToastConfig, ...config },\n },\n ];\n}\n\n/**\n * Inject the Toast configuration\n * @returns The global Toast configuration\n */\nexport function injectToastConfig(): NgpToastConfig {\n return inject(NgpToastConfigToken, { optional: true }) ?? defaultToastConfig;\n}\n","import { inject, InjectionToken, ValueProvider } from '@angular/core';\n\nconst NgpToastContext = new InjectionToken<unknown>('NgpToastContext');\n\nexport function provideToastContext<T>(context: T): ValueProvider {\n return { provide: NgpToastContext, useValue: context };\n}\n\nexport function injectToastContext<T>(): T {\n return inject(NgpToastContext) as T;\n}\n","import { inject, InjectionToken, Signal, ValueProvider } from '@angular/core';\nimport type { NgpToast, NgpToastSwipeDirection, NgpToastPlacement } from './toast';\n\nconst NgpToastOptions = new InjectionToken<NgpToastOptions>('NgpToastOptions');\n\nexport function provideToastOptions(context: NgpToastOptions): ValueProvider {\n return { provide: NgpToastOptions, useValue: context };\n}\n\nexport function injectToastOptions(): NgpToastOptions {\n return inject(NgpToastOptions);\n}\n\nexport interface NgpToastOptions {\n /**\n * The position of the toast.\n */\n placement: NgpToastPlacement;\n\n /**\n * The duration of the toast in milliseconds.\n */\n duration: number;\n\n /**\n * A function to register the toast instance with the manager.\n * @internal\n */\n register: (toast: NgpToast) => void;\n\n /**\n * Whether the toast region is expanded.\n * @internal\n */\n expanded: Signal<boolean>;\n\n /**\n * Whether the toast supports swipe dismiss.\n * @internal\n */\n dismissible: boolean;\n\n /**\n * The swipe directions supported by the toast.\n * @internal\n */\n swipeDirections: NgpToastSwipeDirection[];\n}\n","import {\n ApplicationRef,\n computed,\n inject,\n Injectable,\n Injector,\n RendererFactory2,\n signal,\n TemplateRef,\n Type,\n ViewContainerRef,\n} from '@angular/core';\nimport { createPortal, NgpPortal } from 'ng-primitives/portal';\nimport { injectToastConfig } from '../config/toast-config';\nimport { NgpToast, NgpToastPlacement, NgpToastSwipeDirection } from './toast';\nimport { provideToastContext } from './toast-context';\nimport { provideToastOptions } from './toast-options';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class NgpToastManager {\n private readonly config = injectToastConfig();\n private readonly applicationRef = inject(ApplicationRef);\n private readonly rendererFactory = inject(RendererFactory2);\n private readonly renderer = this.rendererFactory.createRenderer(null, null);\n private readonly injector = inject(Injector);\n // Map to store containers by placement\n private readonly containers = new Map<string, HTMLElement>();\n\n readonly toasts = signal<NgpToastRecord[]>([]);\n\n /** Signal that tracks which placements are expanded */\n private readonly expanded = signal<NgpToastPlacement[]>([]);\n\n /** Show a toast notification */\n show(toast: TemplateRef<void> | Type<unknown>, options: NgpToastOptions = {}): NgpToastRef {\n // services can't access the view container directly, so this is a workaround\n const viewContainerRef = this.applicationRef.components[0].injector.get(ViewContainerRef);\n\n let instance: NgpToast | null = null;\n const placement = options.placement ?? this.config.placement;\n const duration = options.duration ?? this.config.duration;\n const container = this.getOrCreateContainer(placement);\n\n const portal = createPortal(\n toast,\n viewContainerRef,\n Injector.create({\n parent: this.injector,\n providers: [\n provideToastContext(options.context),\n provideToastOptions({\n placement,\n duration,\n register: (toast: NgpToast) => (instance = toast),\n expanded: computed(() => this.expanded().includes(placement)),\n dismissible: options.dismissible ?? this.config.dismissible,\n swipeDirections: options.swipeDirections ?? this.config.swipeDirections,\n }),\n ],\n }),\n {\n // Hide the toast when the dismiss method is called\n dismiss: () => this.dismiss(instance!),\n context: options.context,\n },\n );\n\n portal.attach(container);\n\n // Add the toast to the list of toasts\n if (!instance) {\n throw new Error('A toast must have the NgpToast directive applied.');\n }\n\n this.toasts.update(toasts => [{ instance: instance!, portal }, ...toasts]);\n\n return {\n dismiss: () => this.dismiss(instance!),\n };\n }\n\n /** Hide a toast notification */\n async dismiss(toast: NgpToast): Promise<void> {\n const ref = this.toasts().find(t => t.instance === toast);\n\n if (ref) {\n // Detach the portal from the container\n await ref.portal.detach();\n\n // Remove the toast from the list of toasts\n this.toasts.update(toasts => toasts.filter(t => t !== ref));\n\n // if there are no more toasts, ensure the container is no longer considered expanded\n if (this.toasts().length === 0) {\n this.expanded.update(expanded => expanded.filter(p => p !== toast.options.placement));\n }\n }\n }\n\n /**\n * Lazily create or get a container for a given placement.\n */\n private getOrCreateContainer(placement: string): HTMLElement {\n if (this.containers.has(placement)) {\n return this.containers.get(placement)!;\n }\n const container = this.createContainer(placement);\n this.containers.set(placement, container);\n return container;\n }\n\n /**\n * Create a section in which toasts will be rendered for a specific placement.\n */\n private createContainer(placement: string): HTMLElement {\n const container = this.renderer.createElement('section') as HTMLElement;\n this.renderer.setAttribute(container, 'aria-live', this.config.ariaLive);\n this.renderer.setAttribute(container, 'aria-atomic', 'false');\n this.renderer.setAttribute(container, 'tabindex', '-1');\n this.renderer.setAttribute(container, 'data-ngp-toast-container', placement);\n container.style.setProperty('position', 'fixed');\n container.style.setProperty('z-index', `${this.config.zIndex}`);\n container.style.setProperty('--ngp-toast-offset-top', `${this.config.offsetTop}px`);\n container.style.setProperty('--ngp-toast-offset-bottom', `${this.config.offsetBottom}px`);\n container.style.setProperty('--ngp-toast-offset-left', `${this.config.offsetLeft}px`);\n container.style.setProperty('--ngp-toast-offset-right', `${this.config.offsetRight}px`);\n container.style.setProperty('--ngp-toast-gap', `${this.config.gap}px`);\n\n // mark the container as expanded\n this.renderer.listen(container, 'mouseenter', () =>\n this.expanded.update(expanded => [...expanded, placement as NgpToastPlacement]),\n );\n\n this.renderer.listen(container, 'mouseleave', () => {\n this.expanded.update(expanded =>\n expanded.filter(p => p !== (placement as NgpToastPlacement)),\n );\n });\n\n // Set placement styles\n switch (placement) {\n case 'top-start':\n container.style.setProperty('top', `${this.config.offsetTop}px`);\n container.style.setProperty('left', `${this.config.offsetLeft}px`);\n break;\n case 'top-center':\n container.style.setProperty('top', `${this.config.offsetTop}px`);\n container.style.setProperty('left', '50%');\n container.style.setProperty('transform', 'translateX(-50%)');\n break;\n case 'top-end':\n container.style.setProperty('top', `${this.config.offsetTop}px`);\n container.style.setProperty('right', `${this.config.offsetRight}px`);\n break;\n case 'bottom-start':\n container.style.setProperty('bottom', `${this.config.offsetBottom}px`);\n container.style.setProperty('left', `${this.config.offsetLeft}px`);\n break;\n case 'bottom-center':\n container.style.setProperty('bottom', `${this.config.offsetBottom}px`);\n container.style.setProperty('left', '50%');\n container.style.setProperty('transform', 'translateX(-50%)');\n break;\n case 'bottom-end':\n container.style.setProperty('bottom', `${this.config.offsetBottom}px`);\n container.style.setProperty('right', `${this.config.offsetRight}px`);\n break;\n default:\n throw new Error(`Unknown toast placement: ${placement}`);\n }\n\n this.renderer.appendChild(document.body, container);\n return container;\n }\n}\n\nexport interface NgpToastOptions<T = unknown> {\n /** The position of the toast */\n placement?: NgpToastPlacement;\n\n /** The duration of the toast in milliseconds */\n duration?: number;\n\n /** Whether the toast is dismissible */\n dismissible?: boolean;\n\n /** The swipe directions supported by the toast */\n swipeDirections?: NgpToastSwipeDirection[];\n\n /** The context to make available to the toast */\n context?: T;\n}\n\ninterface NgpToastRecord {\n instance: NgpToast;\n portal: NgpPortal;\n}\n\ninterface NgpToastRef {\n dismiss(): Promise<void>;\n}\n","class NgpToastTimer {\n private startTime: number | null = null;\n private remaining: number;\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n private isRunning = false;\n\n constructor(\n private duration: number,\n private callback: () => void,\n ) {\n this.remaining = duration;\n }\n\n start(): void {\n if (this.isRunning) return;\n\n this.isRunning = true;\n this.startTime = Date.now();\n\n this.timeoutId = setTimeout(() => {\n this.isRunning = false;\n this.callback();\n }, this.remaining);\n }\n\n pause(): void {\n if (!this.isRunning || this.startTime === null) return;\n\n this.isRunning = false;\n clearTimeout(this.timeoutId!);\n\n const elapsed = Date.now() - this.startTime;\n this.remaining -= elapsed;\n this.startTime = null;\n this.timeoutId = null;\n }\n\n stop(): void {\n this.isRunning = false;\n clearTimeout(this.timeoutId!);\n this.timeoutId = null;\n this.startTime = null;\n this.remaining = this.duration;\n }\n}\n\nexport function toastTimer(duration: number, callback: () => void): NgpToastTimer {\n return new NgpToastTimer(duration, callback);\n}\n","import { InteractivityChecker } from '@angular/cdk/a11y';\nimport {\n afterNextRender,\n computed,\n Directive,\n HostListener,\n inject,\n Injector,\n signal,\n} from '@angular/core';\nimport { explicitEffect, injectDimensions } from 'ng-primitives/internal';\nimport { injectToastConfig } from '../config/toast-config';\nimport { NgpToastManager } from './toast-manager';\nimport { injectToastOptions } from './toast-options';\nimport { toastTimer } from './toast-timer';\n\n@Directive({\n selector: '[ngpToast]',\n exportAs: 'ngpToast',\n host: {\n '[attr.data-position-x]': 'x',\n '[attr.data-position-y]': 'y',\n '[attr.data-visible]': 'visible()',\n '[attr.data-front]': 'index() === 0',\n '[attr.data-swiping]': 'swiping()',\n '[attr.data-swipe-direction]': 'swipeOutDirection()',\n '[attr.data-expanded]': 'options.expanded()',\n '[style.--ngp-toast-gap.px]': 'config.gap',\n '[style.--ngp-toast-z-index]': 'zIndex()',\n '[style.--ngp-toasts-before]': 'index()',\n '[style.--ngp-toast-index]': 'index() + 1',\n '[style.--ngp-toast-height.px]': 'dimensions().height',\n '[style.--ngp-toast-offset.px]': 'offset()',\n '[style.--ngp-toast-front-height.px]': 'frontToastHeight()',\n '[style.--ngp-toast-swipe-amount-x.px]': 'swipeAmount().x',\n '[style.--ngp-toast-swipe-amount-y.px]': 'swipeAmount().y',\n '[style.--ngp-toast-swipe-x]': 'swipeAmount().x',\n '[style.--ngp-toast-swipe-y]': 'swipeAmount().y',\n },\n})\nexport class NgpToast {\n private readonly manager = inject(NgpToastManager);\n private readonly injector = inject(Injector);\n protected readonly config = injectToastConfig();\n /** @internal */\n readonly options = injectToastOptions();\n private readonly interactivityChecker = inject(InteractivityChecker);\n private readonly isInteracting = signal(false);\n\n private pointerStartRef: { x: number; y: number } | null = null;\n private dragStartTime: Date | null = null;\n protected readonly swiping = signal(false);\n protected readonly swipeDirection = signal<'x' | 'y' | null>(null);\n protected readonly swipeAmount = signal({ x: 0, y: 0 });\n\n protected readonly swipeOutDirection = computed(() => {\n const direction = this.swipeDirection();\n if (direction === 'x') {\n return this.swipeAmount().x > 0 ? 'right' : 'left';\n } else if (direction === 'y') {\n return this.swipeAmount().y > 0 ? 'bottom' : 'top';\n }\n return null;\n });\n\n /**\n * Get all toasts that are currently being displayed in the same position.\n */\n private readonly toasts = computed(() =>\n this.manager\n .toasts()\n .filter(toast => toast.instance.options.placement === this.options.placement),\n );\n\n /**\n * The number of toasts that are currently being displayed before this toast.\n */\n protected readonly index = computed(() => {\n return this.toasts().findIndex(toast => toast.instance === this);\n });\n\n /**\n * Determine the position of the toast in the list of toasts.\n * This is the combination of the heights of all the toasts before this one, plus the gap between them.\n */\n protected readonly offset = computed(() => {\n const gap = this.config.gap;\n\n return this.toasts()\n .slice(0, this.index())\n .reduce((acc, toast) => acc + toast.instance.dimensions().height + gap, 0);\n });\n\n /**\n * Determine if this toast is visible.\n * Visible considers the maximum number of toasts that can be displayed at once, and the last x toasts that are currently being displayed.\n */\n protected readonly visible = computed(() => {\n const maxToasts = this.config.maxToasts;\n // determine if this toast is within the maximum number of toasts that can be displayed\n return this.index() < maxToasts || this.toasts().length <= maxToasts;\n });\n\n /**\n * Determine the height of the front toast.\n * This is used to determine the height of the toast when it is not expanded.\n */\n protected readonly frontToastHeight = computed(() => {\n // get the first toast in the list with height - as when a new toast is added, it may not initially have dimensions\n return (\n this.toasts()\n .find(toast => toast.instance.dimensions().height)\n ?.instance.dimensions().height || 0\n );\n });\n\n /**\n * Determine the z-index of the toast. This is the inverse of the index.\n * The first toast will have the highest z-index, and the last toast will have the lowest z-index.\n * This is used to ensure that the first toast is always on top of the others.\n */\n protected readonly zIndex = computed(() => this.toasts().length - this.index());\n\n /**\n * The height of the toast in pixels.\n */\n protected readonly dimensions = injectDimensions();\n\n /**\n * The x position of the toast.\n */\n readonly x = this.options.placement.split('-')[1] || 'end';\n\n /**\n * The y position of the toast.\n */\n readonly y = this.options.placement.split('-')[0] || 'top';\n\n /**\n * The toast timer instance.\n */\n private readonly timer = toastTimer(this.options.duration, () => this.manager.dismiss(this));\n\n constructor() {\n this.options.register(this);\n\n // Start the timer when the toast is created\n this.timer.start();\n\n // Pause the timer when the toast is expanded or when the user is interacting with it\n explicitEffect([this.options.expanded, this.isInteracting], ([expanded, interacting]) => {\n // If the toast is expanded, or if the user is interacting with it, reset the timer\n if (expanded || interacting) {\n this.timer.pause();\n } else {\n this.timer.start();\n }\n });\n }\n\n @HostListener('pointerdown', ['$event'])\n protected onPointerDown(event: PointerEvent): void {\n // right click should not trigger swipe and we check if the toast is dismissible\n if (event.button === 2 || !this.options.dismissible) {\n return;\n }\n\n this.isInteracting.set(true);\n\n // we need to check if the pointer is on an interactive element, if so, we should not start swiping\n if (this.interactivityChecker.isFocusable(event.target as HTMLElement)) {\n return;\n }\n\n this.dragStartTime = new Date();\n // Ensure we maintain correct pointer capture even when going outside of the toast (e.g. when swiping)\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n this.swiping.set(true);\n this.pointerStartRef = { x: event.clientX, y: event.clientY };\n }\n\n @HostListener('pointermove', ['$event'])\n protected onPointerMove(event: PointerEvent): void {\n if (!this.pointerStartRef || !this.options.dismissible) {\n return;\n }\n\n const isHighlighted = window.getSelection()?.toString().length ?? 0 > 0;\n\n if (isHighlighted) {\n return;\n }\n\n const yDelta = event.clientY - this.pointerStartRef.y;\n const xDelta = event.clientX - this.pointerStartRef.x;\n\n const swipeDirections = this.options.swipeDirections;\n\n // Determine swipe direction if not already locked\n if (!this.swipeDirection() && (Math.abs(xDelta) > 1 || Math.abs(yDelta) > 1)) {\n this.swipeDirection.set(Math.abs(xDelta) > Math.abs(yDelta) ? 'x' : 'y');\n }\n\n const swipeAmount = { x: 0, y: 0 };\n\n const getDampening = (delta: number) => {\n const factor = Math.abs(delta) / 20;\n\n return 1 / (1.5 + factor);\n };\n\n // Only apply swipe in the locked direction\n if (this.swipeDirection() === 'y') {\n // Handle vertical swipes\n if (swipeDirections.includes('top') || swipeDirections.includes('bottom')) {\n if (\n (swipeDirections.includes('top') && yDelta < 0) ||\n (swipeDirections.includes('bottom') && yDelta > 0)\n ) {\n swipeAmount.y = yDelta;\n } else {\n // Smoothly transition to dampened movement\n const dampenedDelta = yDelta * getDampening(yDelta);\n // Ensure we don't jump when transitioning to dampened movement\n swipeAmount.y = Math.abs(dampenedDelta) < Math.abs(yDelta) ? dampenedDelta : yDelta;\n }\n }\n } else if (this.swipeDirection() === 'x') {\n // Handle horizontal swipes\n if (swipeDirections.includes('left') || swipeDirections.includes('right')) {\n if (\n (swipeDirections.includes('left') && xDelta < 0) ||\n (swipeDirections.includes('right') && xDelta > 0)\n ) {\n swipeAmount.x = xDelta;\n } else {\n // Smoothly transition to dampened movement\n const dampenedDelta = xDelta * getDampening(xDelta);\n // Ensure we don't jump when transitioning to dampened movement\n swipeAmount.x = Math.abs(dampenedDelta) < Math.abs(xDelta) ? dampenedDelta : xDelta;\n }\n }\n }\n\n this.swipeAmount.set({ x: swipeAmount.x, y: swipeAmount.y });\n\n if (Math.abs(swipeAmount.x) > 0 || Math.abs(swipeAmount.y) > 0) {\n this.swiping.set(true);\n }\n }\n\n @HostListener('pointerup')\n protected onPointerUp(): void {\n this.isInteracting.set(false);\n\n if (\n !this.config.dismissible ||\n !this.pointerStartRef ||\n !this.swiping() ||\n !this.dragStartTime\n ) {\n return;\n }\n\n this.pointerStartRef = null;\n\n const swipeAmountX = this.swipeAmount().x;\n const swipeAmountY = this.swipeAmount().y;\n const timeTaken = new Date().getTime() - this.dragStartTime.getTime();\n\n const swipeAmount = this.swipeDirection() === 'x' ? swipeAmountX : swipeAmountY;\n const velocity = Math.abs(swipeAmount) / timeTaken;\n\n if (Math.abs(swipeAmount) >= this.config.swipeThreshold || velocity > 0.11) {\n afterNextRender({ write: () => this.manager.dismiss(this) }, { injector: this.injector });\n return;\n } else {\n this.swipeAmount.set({ x: 0, y: 0 });\n }\n\n // Reset swipe state\n this.swipeDirection.set(null);\n this.swiping.set(false);\n }\n}\n\nexport type NgpToastSwipeDirection = 'top' | 'right' | 'bottom' | 'left';\n\nexport type NgpToastPlacement =\n | 'top-start'\n | 'top-end'\n | 'top-center'\n | 'bottom-start'\n | 'bottom-end'\n | 'bottom-center';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-primitives-toast.mjs","sources":["../../../../packages/ng-primitives/toast/src/config/toast-config.ts","../../../../packages/ng-primitives/toast/src/toast/toast-context.ts","../../../../packages/ng-primitives/toast/src/toast/toast-options.ts","../../../../packages/ng-primitives/toast/src/toast/toast-manager.ts","../../../../packages/ng-primitives/toast/src/toast/toast-timer.ts","../../../../packages/ng-primitives/toast/src/toast/toast.ts","../../../../packages/ng-primitives/toast/src/ng-primitives-toast.ts"],"sourcesContent":["import { InjectionToken, Provider, inject } from '@angular/core';\nimport { NgpToastPlacement, NgpToastSwipeDirection } from '../toast/toast';\n\nexport interface NgpToastConfig {\n /**\n * The position of the toast.\n */\n placement: NgpToastPlacement;\n\n /**\n * The duration of each toast.\n */\n duration: number;\n\n /**\n * The offset from the top of the viewport in pixels.\n */\n offsetTop: number;\n\n /**\n * The offset from the bottom of the viewport in pixels.\n */\n offsetBottom: number;\n\n /**\n * The offset from the left of the viewport in pixels.\n */\n offsetLeft: number;\n\n /**\n * The offset from the right of the viewport in pixels.\n */\n offsetRight: number;\n\n /**\n * Whether a toast can be dismissed by swiping.\n */\n dismissible: boolean;\n\n /**\n * The amount a toast must be swiped before it is considered dismissed.\n */\n swipeThreshold: number;\n\n /**\n * The default swipe directions supported by the toast.\n */\n swipeDirections: NgpToastSwipeDirection[];\n\n /**\n * The maximum number of toasts that can be displayed at once.\n */\n maxToasts: number;\n\n /**\n * The aria live setting.\n */\n ariaLive: string;\n\n /**\n * The gap between each toast.\n */\n gap: number;\n\n /**\n * The z-index of the toast container.\n * This is used to ensure that the toast container is always on top of other elements.\n */\n zIndex: number;\n}\n\nexport const defaultToastConfig: NgpToastConfig = {\n gap: 14,\n duration: 3000,\n placement: 'top-end',\n offsetTop: 24,\n offsetBottom: 24,\n offsetLeft: 24,\n offsetRight: 24,\n swipeThreshold: 45,\n swipeDirections: ['left', 'right', 'top', 'bottom'],\n dismissible: true,\n maxToasts: 3,\n zIndex: 9999999,\n ariaLive: 'polite',\n};\n\nexport const NgpToastConfigToken = new InjectionToken<NgpToastConfig>('NgpToastConfigToken');\n\n/**\n * Provide the default Toast configuration\n * @param config The Toast configuration\n * @returns The provider\n */\nexport function provideToastConfig(config: Partial<NgpToastConfig>): Provider[] {\n return [\n {\n provide: NgpToastConfigToken,\n useValue: { ...defaultToastConfig, ...config },\n },\n ];\n}\n\n/**\n * Inject the Toast configuration\n * @returns The global Toast configuration\n */\nexport function injectToastConfig(): NgpToastConfig {\n return inject(NgpToastConfigToken, { optional: true }) ?? defaultToastConfig;\n}\n","import { inject, InjectionToken, ValueProvider } from '@angular/core';\n\nconst NgpToastContext = new InjectionToken<unknown>('NgpToastContext');\n\nexport function provideToastContext<T>(context: T): ValueProvider {\n return { provide: NgpToastContext, useValue: context };\n}\n\nexport function injectToastContext<T>(): T {\n return inject(NgpToastContext) as T;\n}\n","import { inject, InjectionToken, Signal, ValueProvider } from '@angular/core';\nimport type { NgpToast, NgpToastSwipeDirection, NgpToastPlacement } from './toast';\n\nconst NgpToastOptions = new InjectionToken<NgpToastOptions>('NgpToastOptions');\n\nexport function provideToastOptions(context: NgpToastOptions): ValueProvider {\n return { provide: NgpToastOptions, useValue: context };\n}\n\nexport function injectToastOptions(): NgpToastOptions {\n return inject(NgpToastOptions);\n}\n\nexport interface NgpToastOptions {\n /**\n * The position of the toast.\n */\n placement: NgpToastPlacement;\n\n /**\n * The duration of the toast in milliseconds.\n */\n duration: number;\n\n /**\n * A function to register the toast instance with the manager.\n * @internal\n */\n register: (toast: NgpToast) => void;\n\n /**\n * Whether the toast region is expanded.\n * @internal\n */\n expanded: Signal<boolean>;\n\n /**\n * Whether the toast supports swipe dismiss.\n * @internal\n */\n dismissible: boolean;\n\n /**\n * The swipe directions supported by the toast.\n * @internal\n */\n swipeDirections: NgpToastSwipeDirection[];\n}\n","import {\n ApplicationRef,\n computed,\n inject,\n Injectable,\n Injector,\n RendererFactory2,\n signal,\n TemplateRef,\n Type,\n ViewContainerRef,\n} from '@angular/core';\nimport { createPortal, NgpPortal } from 'ng-primitives/portal';\nimport { injectToastConfig } from '../config/toast-config';\nimport { NgpToast, NgpToastPlacement, NgpToastSwipeDirection } from './toast';\nimport { provideToastContext } from './toast-context';\nimport { provideToastOptions } from './toast-options';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class NgpToastManager {\n private readonly config = injectToastConfig();\n private readonly applicationRef = inject(ApplicationRef);\n private readonly rendererFactory = inject(RendererFactory2);\n private readonly renderer = this.rendererFactory.createRenderer(null, null);\n private readonly injector = inject(Injector);\n // Map to store containers by placement\n private readonly containers = new Map<string, HTMLElement>();\n\n readonly toasts = signal<NgpToastRecord[]>([]);\n\n /** Signal that tracks which placements are expanded */\n private readonly expanded = signal<NgpToastPlacement[]>([]);\n\n /** Show a toast notification */\n show(toast: TemplateRef<void> | Type<unknown>, options: NgpToastOptions = {}): NgpToastRef {\n // services can't access the view container directly, so this is a workaround\n const viewContainerRef = this.applicationRef.components[0].injector.get(ViewContainerRef);\n\n let instance: NgpToast | null = null;\n const placement = options.placement ?? this.config.placement;\n const duration = options.duration ?? this.config.duration;\n const container = this.getOrCreateContainer(placement);\n\n const portal = createPortal(\n toast,\n viewContainerRef,\n Injector.create({\n parent: this.injector,\n providers: [\n provideToastContext(options.context),\n provideToastOptions({\n placement,\n duration,\n register: (toast: NgpToast) => (instance = toast),\n expanded: computed(() => this.expanded().includes(placement)),\n dismissible: options.dismissible ?? this.config.dismissible,\n swipeDirections: options.swipeDirections ?? this.config.swipeDirections,\n }),\n ],\n }),\n {\n // Hide the toast when the dismiss method is called\n dismiss: () => this.dismiss(instance!),\n context: options.context,\n },\n );\n\n portal.attach(container);\n\n // Add the toast to the list of toasts\n if (!instance) {\n throw new Error('A toast must have the NgpToast directive applied.');\n }\n\n this.toasts.update(toasts => [{ instance: instance!, portal }, ...toasts]);\n\n return {\n dismiss: () => this.dismiss(instance!),\n };\n }\n\n /** Hide a toast notification */\n async dismiss(toast: NgpToast): Promise<void> {\n const ref = this.toasts().find(t => t.instance === toast);\n\n if (ref) {\n // Detach the portal from the container\n await ref.portal.detach();\n\n // Remove the toast from the list of toasts\n this.toasts.update(toasts => toasts.filter(t => t !== ref));\n\n // if there are no more toasts, ensure the container is no longer considered expanded\n if (this.toasts().length === 0) {\n this.expanded.update(expanded => expanded.filter(p => p !== toast.options.placement));\n }\n }\n }\n\n /**\n * Lazily create or get a container for a given placement.\n */\n private getOrCreateContainer(placement: string): HTMLElement {\n if (this.containers.has(placement)) {\n return this.containers.get(placement)!;\n }\n const container = this.createContainer(placement);\n this.containers.set(placement, container);\n return container;\n }\n\n /**\n * Create a section in which toasts will be rendered for a specific placement.\n */\n private createContainer(placement: string): HTMLElement {\n const container = this.renderer.createElement('section') as HTMLElement;\n this.renderer.setAttribute(container, 'aria-live', this.config.ariaLive);\n this.renderer.setAttribute(container, 'aria-atomic', 'false');\n this.renderer.setAttribute(container, 'tabindex', '-1');\n this.renderer.setAttribute(container, 'data-ngp-toast-container', placement);\n container.style.setProperty('position', 'fixed');\n container.style.setProperty('z-index', `${this.config.zIndex}`);\n container.style.setProperty('--ngp-toast-offset-top', `${this.config.offsetTop}px`);\n container.style.setProperty('--ngp-toast-offset-bottom', `${this.config.offsetBottom}px`);\n container.style.setProperty('--ngp-toast-offset-left', `${this.config.offsetLeft}px`);\n container.style.setProperty('--ngp-toast-offset-right', `${this.config.offsetRight}px`);\n container.style.setProperty('--ngp-toast-gap', `${this.config.gap}px`);\n\n // mark the container as expanded\n this.renderer.listen(container, 'mouseenter', () =>\n this.expanded.update(expanded => [...expanded, placement as NgpToastPlacement]),\n );\n\n this.renderer.listen(container, 'mouseleave', () => {\n this.expanded.update(expanded =>\n expanded.filter(p => p !== (placement as NgpToastPlacement)),\n );\n });\n\n // Set placement styles\n switch (placement) {\n case 'top-start':\n container.style.setProperty('top', `${this.config.offsetTop}px`);\n container.style.setProperty('left', `${this.config.offsetLeft}px`);\n break;\n case 'top-center':\n container.style.setProperty('top', `${this.config.offsetTop}px`);\n container.style.setProperty('left', '50%');\n container.style.setProperty('transform', 'translateX(-50%)');\n break;\n case 'top-end':\n container.style.setProperty('top', `${this.config.offsetTop}px`);\n container.style.setProperty('right', `${this.config.offsetRight}px`);\n break;\n case 'bottom-start':\n container.style.setProperty('bottom', `${this.config.offsetBottom}px`);\n container.style.setProperty('left', `${this.config.offsetLeft}px`);\n break;\n case 'bottom-center':\n container.style.setProperty('bottom', `${this.config.offsetBottom}px`);\n container.style.setProperty('left', '50%');\n container.style.setProperty('transform', 'translateX(-50%)');\n break;\n case 'bottom-end':\n container.style.setProperty('bottom', `${this.config.offsetBottom}px`);\n container.style.setProperty('right', `${this.config.offsetRight}px`);\n break;\n default:\n throw new Error(`Unknown toast placement: ${placement}`);\n }\n\n this.renderer.appendChild(document.body, container);\n return container;\n }\n}\n\nexport interface NgpToastOptions<T = unknown> {\n /** The position of the toast */\n placement?: NgpToastPlacement;\n\n /** The duration of the toast in milliseconds */\n duration?: number;\n\n /** Whether the toast is dismissible */\n dismissible?: boolean;\n\n /** The swipe directions supported by the toast */\n swipeDirections?: NgpToastSwipeDirection[];\n\n /** The context to make available to the toast */\n context?: T;\n}\n\ninterface NgpToastRecord {\n instance: NgpToast;\n portal: NgpPortal;\n}\n\nexport interface NgpToastRef {\n dismiss(): Promise<void>;\n}\n","class NgpToastTimer {\n private startTime: number | null = null;\n private remaining: number;\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n private isRunning = false;\n\n constructor(\n private duration: number,\n private callback: () => void,\n ) {\n this.remaining = duration;\n }\n\n start(): void {\n if (this.isRunning) return;\n\n this.isRunning = true;\n this.startTime = Date.now();\n\n this.timeoutId = setTimeout(() => {\n this.isRunning = false;\n this.callback();\n }, this.remaining);\n }\n\n pause(): void {\n if (!this.isRunning || this.startTime === null) return;\n\n this.isRunning = false;\n clearTimeout(this.timeoutId!);\n\n const elapsed = Date.now() - this.startTime;\n this.remaining -= elapsed;\n this.startTime = null;\n this.timeoutId = null;\n }\n\n stop(): void {\n this.isRunning = false;\n clearTimeout(this.timeoutId!);\n this.timeoutId = null;\n this.startTime = null;\n this.remaining = this.duration;\n }\n}\n\nexport function toastTimer(duration: number, callback: () => void): NgpToastTimer {\n return new NgpToastTimer(duration, callback);\n}\n","import { InteractivityChecker } from '@angular/cdk/a11y';\nimport {\n afterNextRender,\n computed,\n Directive,\n HostListener,\n inject,\n Injector,\n signal,\n} from '@angular/core';\nimport { explicitEffect, injectDimensions } from 'ng-primitives/internal';\nimport { injectToastConfig } from '../config/toast-config';\nimport { NgpToastManager } from './toast-manager';\nimport { injectToastOptions } from './toast-options';\nimport { toastTimer } from './toast-timer';\n\n@Directive({\n selector: '[ngpToast]',\n exportAs: 'ngpToast',\n host: {\n '[attr.data-position-x]': 'x',\n '[attr.data-position-y]': 'y',\n '[attr.data-visible]': 'visible()',\n '[attr.data-front]': 'index() === 0',\n '[attr.data-swiping]': 'swiping()',\n '[attr.data-swipe-direction]': 'swipeOutDirection()',\n '[attr.data-expanded]': 'options.expanded()',\n '[style.--ngp-toast-gap.px]': 'config.gap',\n '[style.--ngp-toast-z-index]': 'zIndex()',\n '[style.--ngp-toasts-before]': 'index()',\n '[style.--ngp-toast-index]': 'index() + 1',\n '[style.--ngp-toast-height.px]': 'dimensions().height',\n '[style.--ngp-toast-offset.px]': 'offset()',\n '[style.--ngp-toast-front-height.px]': 'frontToastHeight()',\n '[style.--ngp-toast-swipe-amount-x.px]': 'swipeAmount().x',\n '[style.--ngp-toast-swipe-amount-y.px]': 'swipeAmount().y',\n '[style.--ngp-toast-swipe-x]': 'swipeAmount().x',\n '[style.--ngp-toast-swipe-y]': 'swipeAmount().y',\n },\n})\nexport class NgpToast {\n private readonly manager = inject(NgpToastManager);\n private readonly injector = inject(Injector);\n protected readonly config = injectToastConfig();\n /** @internal */\n readonly options = injectToastOptions();\n private readonly interactivityChecker = inject(InteractivityChecker);\n private readonly isInteracting = signal(false);\n\n private pointerStartRef: { x: number; y: number } | null = null;\n private dragStartTime: Date | null = null;\n protected readonly swiping = signal(false);\n protected readonly swipeDirection = signal<'x' | 'y' | null>(null);\n protected readonly swipeAmount = signal({ x: 0, y: 0 });\n\n protected readonly swipeOutDirection = computed(() => {\n const direction = this.swipeDirection();\n if (direction === 'x') {\n return this.swipeAmount().x > 0 ? 'right' : 'left';\n } else if (direction === 'y') {\n return this.swipeAmount().y > 0 ? 'bottom' : 'top';\n }\n return null;\n });\n\n /**\n * Get all toasts that are currently being displayed in the same position.\n */\n private readonly toasts = computed(() =>\n this.manager\n .toasts()\n .filter(toast => toast.instance.options.placement === this.options.placement),\n );\n\n /**\n * The number of toasts that are currently being displayed before this toast.\n */\n protected readonly index = computed(() => {\n return this.toasts().findIndex(toast => toast.instance === this);\n });\n\n /**\n * Determine the position of the toast in the list of toasts.\n * This is the combination of the heights of all the toasts before this one, plus the gap between them.\n */\n protected readonly offset = computed(() => {\n const gap = this.config.gap;\n\n return this.toasts()\n .slice(0, this.index())\n .reduce((acc, toast) => acc + toast.instance.dimensions().height + gap, 0);\n });\n\n /**\n * Determine if this toast is visible.\n * Visible considers the maximum number of toasts that can be displayed at once, and the last x toasts that are currently being displayed.\n */\n protected readonly visible = computed(() => {\n const maxToasts = this.config.maxToasts;\n // determine if this toast is within the maximum number of toasts that can be displayed\n return this.index() < maxToasts || this.toasts().length <= maxToasts;\n });\n\n /**\n * Determine the height of the front toast.\n * This is used to determine the height of the toast when it is not expanded.\n */\n protected readonly frontToastHeight = computed(() => {\n // get the first toast in the list with height - as when a new toast is added, it may not initially have dimensions\n return (\n this.toasts()\n .find(toast => toast.instance.dimensions().height)\n ?.instance.dimensions().height || 0\n );\n });\n\n /**\n * Determine the z-index of the toast. This is the inverse of the index.\n * The first toast will have the highest z-index, and the last toast will have the lowest z-index.\n * This is used to ensure that the first toast is always on top of the others.\n */\n protected readonly zIndex = computed(() => this.toasts().length - this.index());\n\n /**\n * The height of the toast in pixels.\n */\n protected readonly dimensions = injectDimensions();\n\n /**\n * The x position of the toast.\n */\n readonly x = this.options.placement.split('-')[1] || 'end';\n\n /**\n * The y position of the toast.\n */\n readonly y = this.options.placement.split('-')[0] || 'top';\n\n /**\n * The toast timer instance.\n */\n private readonly timer = toastTimer(this.options.duration, () => this.manager.dismiss(this));\n\n constructor() {\n this.options.register(this);\n\n // Start the timer when the toast is created\n this.timer.start();\n\n // Pause the timer when the toast is expanded or when the user is interacting with it\n explicitEffect([this.options.expanded, this.isInteracting], ([expanded, interacting]) => {\n // If the toast is expanded, or if the user is interacting with it, reset the timer\n if (expanded || interacting) {\n this.timer.pause();\n } else {\n this.timer.start();\n }\n });\n }\n\n @HostListener('pointerdown', ['$event'])\n protected onPointerDown(event: PointerEvent): void {\n // right click should not trigger swipe and we check if the toast is dismissible\n if (event.button === 2 || !this.options.dismissible) {\n return;\n }\n\n this.isInteracting.set(true);\n\n // we need to check if the pointer is on an interactive element, if so, we should not start swiping\n if (this.interactivityChecker.isFocusable(event.target as HTMLElement)) {\n return;\n }\n\n this.dragStartTime = new Date();\n // Ensure we maintain correct pointer capture even when going outside of the toast (e.g. when swiping)\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n this.swiping.set(true);\n this.pointerStartRef = { x: event.clientX, y: event.clientY };\n }\n\n @HostListener('pointermove', ['$event'])\n protected onPointerMove(event: PointerEvent): void {\n if (!this.pointerStartRef || !this.options.dismissible) {\n return;\n }\n\n const isHighlighted = window.getSelection()?.toString().length ?? 0 > 0;\n\n if (isHighlighted) {\n return;\n }\n\n const yDelta = event.clientY - this.pointerStartRef.y;\n const xDelta = event.clientX - this.pointerStartRef.x;\n\n const swipeDirections = this.options.swipeDirections;\n\n // Determine swipe direction if not already locked\n if (!this.swipeDirection() && (Math.abs(xDelta) > 1 || Math.abs(yDelta) > 1)) {\n this.swipeDirection.set(Math.abs(xDelta) > Math.abs(yDelta) ? 'x' : 'y');\n }\n\n const swipeAmount = { x: 0, y: 0 };\n\n const getDampening = (delta: number) => {\n const factor = Math.abs(delta) / 20;\n\n return 1 / (1.5 + factor);\n };\n\n // Only apply swipe in the locked direction\n if (this.swipeDirection() === 'y') {\n // Handle vertical swipes\n if (swipeDirections.includes('top') || swipeDirections.includes('bottom')) {\n if (\n (swipeDirections.includes('top') && yDelta < 0) ||\n (swipeDirections.includes('bottom') && yDelta > 0)\n ) {\n swipeAmount.y = yDelta;\n } else {\n // Smoothly transition to dampened movement\n const dampenedDelta = yDelta * getDampening(yDelta);\n // Ensure we don't jump when transitioning to dampened movement\n swipeAmount.y = Math.abs(dampenedDelta) < Math.abs(yDelta) ? dampenedDelta : yDelta;\n }\n }\n } else if (this.swipeDirection() === 'x') {\n // Handle horizontal swipes\n if (swipeDirections.includes('left') || swipeDirections.includes('right')) {\n if (\n (swipeDirections.includes('left') && xDelta < 0) ||\n (swipeDirections.includes('right') && xDelta > 0)\n ) {\n swipeAmount.x = xDelta;\n } else {\n // Smoothly transition to dampened movement\n const dampenedDelta = xDelta * getDampening(xDelta);\n // Ensure we don't jump when transitioning to dampened movement\n swipeAmount.x = Math.abs(dampenedDelta) < Math.abs(xDelta) ? dampenedDelta : xDelta;\n }\n }\n }\n\n this.swipeAmount.set({ x: swipeAmount.x, y: swipeAmount.y });\n\n if (Math.abs(swipeAmount.x) > 0 || Math.abs(swipeAmount.y) > 0) {\n this.swiping.set(true);\n }\n }\n\n @HostListener('pointerup')\n protected onPointerUp(): void {\n this.isInteracting.set(false);\n\n if (\n !this.config.dismissible ||\n !this.pointerStartRef ||\n !this.swiping() ||\n !this.dragStartTime\n ) {\n return;\n }\n\n this.pointerStartRef = null;\n\n const swipeAmountX = this.swipeAmount().x;\n const swipeAmountY = this.swipeAmount().y;\n const timeTaken = new Date().getTime() - this.dragStartTime.getTime();\n\n const swipeAmount = this.swipeDirection() === 'x' ? swipeAmountX : swipeAmountY;\n const velocity = Math.abs(swipeAmount) / timeTaken;\n\n if (Math.abs(swipeAmount) >= this.config.swipeThreshold || velocity > 0.11) {\n afterNextRender({ write: () => this.manager.dismiss(this) }, { injector: this.injector });\n return;\n } else {\n this.swipeAmount.set({ x: 0, y: 0 });\n }\n\n // Reset swipe state\n this.swipeDirection.set(null);\n this.swiping.set(false);\n }\n}\n\nexport type NgpToastSwipeDirection = 'top' | 'right' | 'bottom' | 'left';\n\nexport type NgpToastPlacement =\n | 'top-start'\n | 'top-end'\n | 'top-center'\n | 'bottom-start'\n | 'bottom-end'\n | 'bottom-center';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -64,10 +64,24 @@ function updateStatus(control, status) {
64
64
  * It supports both classic reactive forms controls and signal-forms interop controls.
65
65
  * @internal
66
66
  */
67
+ /**
68
+ * Sets up event subscription for a given NgControl.
69
+ * Only sets up the subscription - does not call updateStatus.
70
+ */
71
+ function setupEventSubscription(ngControl, status, destroyRef) {
72
+ // For classic controls, also subscribe to the events observable.
73
+ const underlyingControl = ngControl.control;
74
+ if (underlyingControl?.events) {
75
+ underlyingControl.events
76
+ .pipe(safeTakeUntilDestroyed(destroyRef))
77
+ .subscribe(() => updateStatus(ngControl, status));
78
+ }
79
+ }
67
80
  function controlStatus() {
68
81
  const injector = inject(Injector);
69
82
  const destroyRef = inject(DestroyRef);
70
- const control = signal(null, ...(ngDevMode ? [{ debugName: "control" }] : []));
83
+ // Try to inject NgControl immediately for initial state
84
+ const control = signal(inject(NgControl, { optional: true }), ...(ngDevMode ? [{ debugName: "control" }] : []));
71
85
  const status = signal({
72
86
  valid: null,
73
87
  invalid: null,
@@ -77,19 +91,24 @@ function controlStatus() {
77
91
  pending: null,
78
92
  disabled: null,
79
93
  }, ...(ngDevMode ? [{ debugName: "status" }] : []));
94
+ // If we have a control immediately, update initial status
95
+ if (control()) {
96
+ updateStatus(control(), status);
97
+ }
80
98
  onMount(() => {
81
- control.set(inject(NgControl, { optional: true }));
82
- if (!control()) {
99
+ // Get the control (either from initial injection or from mount)
100
+ const mountControl = control() || inject(NgControl, { optional: true });
101
+ if (!mountControl) {
83
102
  return;
84
103
  }
85
- updateStatus(control(), status);
86
- // For classic controls, also subscribe to the events observable.
87
- const underlyingControl = control().control;
88
- if (underlyingControl?.events) {
89
- underlyingControl.events
90
- .pipe(safeTakeUntilDestroyed(destroyRef))
91
- .subscribe(() => updateStatus(control(), status));
104
+ // Update control signal if it wasn't set before
105
+ if (!control()) {
106
+ control.set(mountControl);
92
107
  }
108
+ // Update status to ensure latest values
109
+ updateStatus(mountControl, status);
110
+ // Set up event subscription for reactive updates
111
+ setupEventSubscription(mountControl, status, destroyRef);
93
112
  });
94
113
  // Use an effect to reactively track status changes.
95
114
  // For signal-forms interop controls, the status properties are signals.
@@ -1 +1 @@
1
- {"version":3,"file":"ng-primitives-utils.mjs","sources":["../../../../packages/ng-primitives/utils/src/forms/providers.ts","../../../../packages/ng-primitives/utils/src/observables/take-until-destroyed.ts","../../../../packages/ng-primitives/utils/src/forms/status.ts","../../../../packages/ng-primitives/utils/src/helpers/attributes.ts","../../../../packages/ng-primitives/utils/src/helpers/disposables.ts","../../../../packages/ng-primitives/utils/src/helpers/unique-id.ts","../../../../packages/ng-primitives/utils/src/helpers/validators.ts","../../../../packages/ng-primitives/utils/src/signals/index.ts","../../../../packages/ng-primitives/utils/src/ng-primitives-utils.ts"],"sourcesContent":["import { ExistingProvider, Type } from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\n\n/**\n * A simple helper function to provide a value accessor for a given type.\n * @param type The type to provide the value accessor for\n */\nexport function provideValueAccessor<T>(type: Type<T>): ExistingProvider {\n return { provide: NG_VALUE_ACCESSOR, useExisting: type, multi: true };\n}\n","/* eslint-disable @nx/workspace-take-until-destroyed */\nimport { DestroyRef } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { EMPTY, MonoTypeOperatorFunction, NEVER, pipe } from 'rxjs';\nimport { catchError, defaultIfEmpty, takeUntil } from 'rxjs/operators';\n\n/**\n * The built-in `takeUntilDestroyed` operator does not handle the case when the component is destroyed before the source observable emits.\n * This operator ensures that the source observable completes gracefully without throwing an error.\n * https://github.com/angular/angular/issues/54527#issuecomment-2098254508\n *\n * @internal\n */\nexport function safeTakeUntilDestroyed<T>(destroyRef?: DestroyRef): MonoTypeOperatorFunction<T> {\n return pipe(\n takeUntil(\n NEVER.pipe(\n takeUntilDestroyed(destroyRef),\n catchError(() => EMPTY),\n defaultIfEmpty(null),\n ),\n ),\n );\n}\n","import {\n DestroyRef,\n Injector,\n Signal,\n WritableSignal,\n effect,\n inject,\n signal,\n untracked,\n} from '@angular/core';\nimport { NgControl } from '@angular/forms';\nimport { onMount } from 'ng-primitives/state';\nimport { safeTakeUntilDestroyed } from '../observables/take-until-destroyed';\n\nexport interface NgpControlStatus {\n valid: boolean | null;\n invalid: boolean | null;\n pristine: boolean | null;\n dirty: boolean | null;\n touched: boolean | null;\n pending: boolean | null;\n disabled: boolean | null;\n}\n\n/**\n * Detects an Angular signal-forms interop control without importing any of the new\n * signal-form types. Interop controls expose a `field()` method which returns the\n * underlying FieldState.\n */\nfunction isInteropControl(control: NgControl | null | undefined): boolean {\n return !!control && typeof (control as any).field === 'function';\n}\n\n/**\n * Reads status from a control and updates the status signal.\n * Wrapped in try-catch to handle signal-forms interop controls where\n * the `field` input may not be available yet (throws NG0950).\n */\nfunction updateStatus(control: NgControl, status: WritableSignal<NgpControlStatus>): void {\n try {\n // For interop controls, read directly from the control (which has signal getters).\n // For classic controls, read from the underlying AbstractControl.\n const source = isInteropControl(control) ? control : ((control as any).control ?? control);\n\n const newStatus: NgpControlStatus = {\n valid: source.valid ?? null,\n invalid: source.invalid ?? null,\n pristine: source.pristine ?? null,\n dirty: source.dirty ?? null,\n touched: source.touched ?? null,\n pending: source.pending ?? null,\n disabled: source.disabled ?? null,\n };\n\n untracked(() => status.set(newStatus));\n } catch {\n // NG0950: Required input not available yet. The effect will re-run\n // when the signal input becomes available.\n }\n}\n\n/**\n * A utility function to get the status of an Angular form control as a reactive signal.\n * This function injects the NgControl and returns a signal that reflects the control's status.\n * It supports both classic reactive forms controls and signal-forms interop controls.\n * @internal\n */\nexport function controlStatus(): Signal<NgpControlStatus> {\n const injector = inject(Injector);\n const destroyRef = inject(DestroyRef);\n const control = signal<NgControl | null>(null);\n\n const status = signal<NgpControlStatus>({\n valid: null,\n invalid: null,\n pristine: null,\n dirty: null,\n touched: null,\n pending: null,\n disabled: null,\n });\n\n onMount(() => {\n control.set(inject(NgControl, { optional: true }));\n\n if (!control()) {\n return;\n }\n\n updateStatus(control()!, status);\n\n // For classic controls, also subscribe to the events observable.\n const underlyingControl = (control() as any).control;\n if (underlyingControl?.events) {\n underlyingControl.events\n .pipe(safeTakeUntilDestroyed(destroyRef))\n .subscribe(() => updateStatus(control()!, status));\n }\n });\n\n // Use an effect to reactively track status changes.\n // For signal-forms interop controls, the status properties are signals.\n // For classic controls, this will read the current values and establish\n // no signal dependencies, but we also subscribe to events below.\n effect(\n () => {\n const c = control();\n if (c) {\n updateStatus(c, status);\n }\n },\n { injector },\n );\n\n return status;\n}\n","import { afterRenderEffect, Signal } from '@angular/core';\n\nexport function booleanAttributeBinding(\n element: HTMLElement,\n attribute: string,\n value: Signal<boolean> | undefined,\n): void {\n if (!value) {\n return;\n }\n\n afterRenderEffect({\n write: () =>\n value() ? element.setAttribute(attribute, '') : element.removeAttribute(attribute),\n });\n}\n","import { DestroyRef, inject } from '@angular/core';\n\n/**\n * Disposable functions are a way to manage timers, intervals, and event listeners\n * that should be cleared when a component is destroyed.\n *\n * This is heavily inspired by Headless UI disposables:\n * https://github.com/tailwindlabs/headlessui/blob/main/packages/%40headlessui-react/src/utils/disposables.ts\n */\nexport function injectDisposables() {\n const destroyRef = inject(DestroyRef);\n let isDestroyed = false;\n\n destroyRef.onDestroy(() => (isDestroyed = true));\n\n return {\n /**\n * Set a timeout that will be cleared when the component is destroyed.\n * @param callback The callback to execute\n * @param delay The delay before the callback is executed\n * @returns A function to clear the timeout\n */\n setTimeout: (callback: () => void, delay: number) => {\n if (isDestroyed) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n const id = setTimeout(callback, delay);\n const cleanup = () => clearTimeout(id);\n destroyRef.onDestroy(cleanup);\n return cleanup;\n },\n /**\n * Set an interval that will be cleared when the component is destroyed.\n * @param callback The callback to execute\n * @param delay The delay before the callback is executed\n * @param target\n * @param type\n * @param listener\n * @param options\n * @returns A function to clear the interval\n */\n addEventListener: <K extends keyof HTMLElementEventMap>(\n target: EventTarget,\n type: K,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n ) => {\n if (isDestroyed) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n target.addEventListener(type, listener as EventListenerOrEventListenerObject, options);\n const cleanup = () =>\n target.removeEventListener(type, listener as EventListenerOrEventListenerObject, options);\n destroyRef.onDestroy(cleanup);\n return cleanup;\n },\n /**\n * Set an interval that will be cleared when the component is destroyed.\n * @param callback The callback to execute\n * @param delay The delay before the callback is executed\n * @returns A function to clear the interval\n */\n setInterval: (callback: () => void, delay: number) => {\n if (isDestroyed) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n const id = setInterval(callback, delay);\n const cleanup = () => clearInterval(id);\n destroyRef.onDestroy(cleanup);\n return cleanup;\n },\n /**\n * Set a requestAnimationFrame that will be cleared when the component is destroyed.\n * @param callback The callback to execute\n * @returns A function to clear the requestAnimationFrame\n */\n requestAnimationFrame: (callback: FrameRequestCallback) => {\n if (isDestroyed) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n const id = requestAnimationFrame(callback);\n const cleanup = () => cancelAnimationFrame(id);\n destroyRef.onDestroy(cleanup);\n return cleanup;\n },\n };\n}\n","/**\n * Store a map of unique ids for elements so that there are no collisions.\n */\nconst uniqueIdMap = new Map<string, number>();\n\n/**\n * Generate a unique id for an element\n * @param prefix - The prefix to use for the id\n * @returns The generated id\n */\nexport function uniqueId(prefix: string): string {\n const id = uniqueIdMap.get(prefix) ?? 0;\n uniqueIdMap.set(prefix, id + 1);\n return `${prefix}-${id}`;\n}\n","/**\n * Type validation utilities\n */\n\n/**\n * Checks if a value is a string\n * @param value - The value to check\n * @returns true if the value is a string, false otherwise\n */\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/**\n * Checks if a value is a number\n * @param value - The value to check\n * @returns true if the value is a number, false otherwise\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number';\n}\n\n/**\n * Checks if a value is a boolean\n * @param value - The value to check\n * @returns true if the value is a boolean, false otherwise\n */\nexport function isBoolean(value: unknown): value is boolean {\n return typeof value === 'boolean';\n}\n\n/**\n * Checks if a value is a function\n * @param value - The value to check\n * @returns true if the value is a function, false otherwise\n */\nexport function isFunction(value: unknown): value is CallableFunction {\n return typeof value === 'function';\n}\n\n/**\n * Checks if a value is a plain object (but not null or array)\n * @param value - The value to check\n * @returns true if the value is a plain object, false otherwise\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Checks if a value is undefined\n * @param value - The value to check\n * @returns true if the value is undefined, false otherwise\n */\nexport function isUndefined(value: unknown): value is undefined {\n return typeof value === 'undefined';\n}\n\n/**\n * Checks if a value is null or undefined\n * @param value - The value to check\n * @returns true if the value is null or undefined, false otherwise\n */\nexport function isNil(value: unknown): value is null | undefined {\n return isUndefined(value) || value === null;\n}\n\n/**\n * Checks if a value is not null and not undefined\n * @param value - The value to check\n * @returns true if the value is not null and not undefined, false otherwise\n */\nexport function notNil<T>(value: T | null | undefined): value is T {\n return !isNil(value);\n}\n","import { effect, Injector, Signal, signal, untracked } from '@angular/core';\n\n/**\n * Listen for changes to a signal and call a function when the signal changes.\n * @param source\n * @param fn\n * @param options\n * @param options.injector\n * @internal\n */\nexport function onChange<T>(\n source: Signal<T>,\n fn: (value: T, previousValue: T | null | undefined) => void,\n options?: { injector: Injector },\n): void {\n const previousValue = signal(source());\n\n effect(\n () => {\n const value = source();\n if (value !== previousValue()) {\n untracked(() => fn(value, previousValue()));\n previousValue.set(value);\n }\n },\n { injector: options?.injector },\n );\n\n // call the fn with the initial value\n fn(source(), null);\n}\n\n/**\n * Listen for changes to a boolean signal and call one of two functions when the signal changes.\n * @param source\n * @param onTrue\n * @param onFalse\n * @param options\n */\nexport function onBooleanChange(\n source: Signal<boolean>,\n onTrue?: () => void,\n onFalse?: () => void,\n options?: { injector: Injector },\n): void {\n onChange(source, value => (value ? onTrue?.() : onFalse?.()), options);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-primitives-utils.mjs","sources":["../../../../packages/ng-primitives/utils/src/forms/providers.ts","../../../../packages/ng-primitives/utils/src/observables/take-until-destroyed.ts","../../../../packages/ng-primitives/utils/src/forms/status.ts","../../../../packages/ng-primitives/utils/src/helpers/attributes.ts","../../../../packages/ng-primitives/utils/src/helpers/disposables.ts","../../../../packages/ng-primitives/utils/src/helpers/unique-id.ts","../../../../packages/ng-primitives/utils/src/helpers/validators.ts","../../../../packages/ng-primitives/utils/src/signals/index.ts","../../../../packages/ng-primitives/utils/src/ng-primitives-utils.ts"],"sourcesContent":["import { ExistingProvider, Type } from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\n\n/**\n * A simple helper function to provide a value accessor for a given type.\n * @param type The type to provide the value accessor for\n */\nexport function provideValueAccessor<T>(type: Type<T>): ExistingProvider {\n return { provide: NG_VALUE_ACCESSOR, useExisting: type, multi: true };\n}\n","/* eslint-disable @nx/workspace-take-until-destroyed */\nimport { DestroyRef } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { EMPTY, MonoTypeOperatorFunction, NEVER, pipe } from 'rxjs';\nimport { catchError, defaultIfEmpty, takeUntil } from 'rxjs/operators';\n\n/**\n * The built-in `takeUntilDestroyed` operator does not handle the case when the component is destroyed before the source observable emits.\n * This operator ensures that the source observable completes gracefully without throwing an error.\n * https://github.com/angular/angular/issues/54527#issuecomment-2098254508\n *\n * @internal\n */\nexport function safeTakeUntilDestroyed<T>(destroyRef?: DestroyRef): MonoTypeOperatorFunction<T> {\n return pipe(\n takeUntil(\n NEVER.pipe(\n takeUntilDestroyed(destroyRef),\n catchError(() => EMPTY),\n defaultIfEmpty(null),\n ),\n ),\n );\n}\n","import {\n DestroyRef,\n Injector,\n Signal,\n WritableSignal,\n effect,\n inject,\n signal,\n untracked,\n} from '@angular/core';\nimport { NgControl } from '@angular/forms';\nimport { onMount } from 'ng-primitives/state';\nimport { safeTakeUntilDestroyed } from '../observables/take-until-destroyed';\n\nexport interface NgpControlStatus {\n valid: boolean | null;\n invalid: boolean | null;\n pristine: boolean | null;\n dirty: boolean | null;\n touched: boolean | null;\n pending: boolean | null;\n disabled: boolean | null;\n}\n\n/**\n * Detects an Angular signal-forms interop control without importing any of the new\n * signal-form types. Interop controls expose a `field()` method which returns the\n * underlying FieldState.\n */\nfunction isInteropControl(control: NgControl | null | undefined): boolean {\n return !!control && typeof (control as any).field === 'function';\n}\n\n/**\n * Reads status from a control and updates the status signal.\n * Wrapped in try-catch to handle signal-forms interop controls where\n * the `field` input may not be available yet (throws NG0950).\n */\nfunction updateStatus(control: NgControl, status: WritableSignal<NgpControlStatus>): void {\n try {\n // For interop controls, read directly from the control (which has signal getters).\n // For classic controls, read from the underlying AbstractControl.\n const source = isInteropControl(control) ? control : ((control as any).control ?? control);\n\n const newStatus: NgpControlStatus = {\n valid: source.valid ?? null,\n invalid: source.invalid ?? null,\n pristine: source.pristine ?? null,\n dirty: source.dirty ?? null,\n touched: source.touched ?? null,\n pending: source.pending ?? null,\n disabled: source.disabled ?? null,\n };\n\n untracked(() => status.set(newStatus));\n } catch {\n // NG0950: Required input not available yet. The effect will re-run\n // when the signal input becomes available.\n }\n}\n\n/**\n * A utility function to get the status of an Angular form control as a reactive signal.\n * This function injects the NgControl and returns a signal that reflects the control's status.\n * It supports both classic reactive forms controls and signal-forms interop controls.\n * @internal\n */\n/**\n * Sets up event subscription for a given NgControl.\n * Only sets up the subscription - does not call updateStatus.\n */\nfunction setupEventSubscription(\n ngControl: NgControl,\n status: WritableSignal<NgpControlStatus>,\n destroyRef: DestroyRef,\n): void {\n // For classic controls, also subscribe to the events observable.\n const underlyingControl = (ngControl as any).control;\n if (underlyingControl?.events) {\n underlyingControl.events\n .pipe(safeTakeUntilDestroyed(destroyRef))\n .subscribe(() => updateStatus(ngControl, status));\n }\n}\n\nexport function controlStatus(): Signal<NgpControlStatus> {\n const injector = inject(Injector);\n const destroyRef = inject(DestroyRef);\n\n // Try to inject NgControl immediately for initial state\n const control = signal<NgControl | null>(inject(NgControl, { optional: true }));\n\n const status = signal<NgpControlStatus>({\n valid: null,\n invalid: null,\n pristine: null,\n dirty: null,\n touched: null,\n pending: null,\n disabled: null,\n });\n\n // If we have a control immediately, update initial status\n if (control()) {\n updateStatus(control()!, status);\n }\n\n onMount(() => {\n // Get the control (either from initial injection or from mount)\n const mountControl = control() || inject(NgControl, { optional: true });\n\n if (!mountControl) {\n return;\n }\n\n // Update control signal if it wasn't set before\n if (!control()) {\n control.set(mountControl);\n }\n\n // Update status to ensure latest values\n updateStatus(mountControl, status);\n\n // Set up event subscription for reactive updates\n setupEventSubscription(mountControl, status, destroyRef);\n });\n\n // Use an effect to reactively track status changes.\n // For signal-forms interop controls, the status properties are signals.\n // For classic controls, this will read the current values and establish\n // no signal dependencies, but we also subscribe to events below.\n effect(\n () => {\n const c = control();\n if (c) {\n updateStatus(c, status);\n }\n },\n { injector },\n );\n\n return status;\n}\n","import { afterRenderEffect, Signal } from '@angular/core';\n\nexport function booleanAttributeBinding(\n element: HTMLElement,\n attribute: string,\n value: Signal<boolean> | undefined,\n): void {\n if (!value) {\n return;\n }\n\n afterRenderEffect({\n write: () =>\n value() ? element.setAttribute(attribute, '') : element.removeAttribute(attribute),\n });\n}\n","import { DestroyRef, inject } from '@angular/core';\n\n/**\n * Disposable functions are a way to manage timers, intervals, and event listeners\n * that should be cleared when a component is destroyed.\n *\n * This is heavily inspired by Headless UI disposables:\n * https://github.com/tailwindlabs/headlessui/blob/main/packages/%40headlessui-react/src/utils/disposables.ts\n */\nexport function injectDisposables() {\n const destroyRef = inject(DestroyRef);\n let isDestroyed = false;\n\n destroyRef.onDestroy(() => (isDestroyed = true));\n\n return {\n /**\n * Set a timeout that will be cleared when the component is destroyed.\n * @param callback The callback to execute\n * @param delay The delay before the callback is executed\n * @returns A function to clear the timeout\n */\n setTimeout: (callback: () => void, delay: number) => {\n if (isDestroyed) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n const id = setTimeout(callback, delay);\n const cleanup = () => clearTimeout(id);\n destroyRef.onDestroy(cleanup);\n return cleanup;\n },\n /**\n * Set an interval that will be cleared when the component is destroyed.\n * @param callback The callback to execute\n * @param delay The delay before the callback is executed\n * @param target\n * @param type\n * @param listener\n * @param options\n * @returns A function to clear the interval\n */\n addEventListener: <K extends keyof HTMLElementEventMap>(\n target: EventTarget,\n type: K,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n ) => {\n if (isDestroyed) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n target.addEventListener(type, listener as EventListenerOrEventListenerObject, options);\n const cleanup = () =>\n target.removeEventListener(type, listener as EventListenerOrEventListenerObject, options);\n destroyRef.onDestroy(cleanup);\n return cleanup;\n },\n /**\n * Set an interval that will be cleared when the component is destroyed.\n * @param callback The callback to execute\n * @param delay The delay before the callback is executed\n * @returns A function to clear the interval\n */\n setInterval: (callback: () => void, delay: number) => {\n if (isDestroyed) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n const id = setInterval(callback, delay);\n const cleanup = () => clearInterval(id);\n destroyRef.onDestroy(cleanup);\n return cleanup;\n },\n /**\n * Set a requestAnimationFrame that will be cleared when the component is destroyed.\n * @param callback The callback to execute\n * @returns A function to clear the requestAnimationFrame\n */\n requestAnimationFrame: (callback: FrameRequestCallback) => {\n if (isDestroyed) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n const id = requestAnimationFrame(callback);\n const cleanup = () => cancelAnimationFrame(id);\n destroyRef.onDestroy(cleanup);\n return cleanup;\n },\n };\n}\n","/**\n * Store a map of unique ids for elements so that there are no collisions.\n */\nconst uniqueIdMap = new Map<string, number>();\n\n/**\n * Generate a unique id for an element\n * @param prefix - The prefix to use for the id\n * @returns The generated id\n */\nexport function uniqueId(prefix: string): string {\n const id = uniqueIdMap.get(prefix) ?? 0;\n uniqueIdMap.set(prefix, id + 1);\n return `${prefix}-${id}`;\n}\n","/**\n * Type validation utilities\n */\n\n/**\n * Checks if a value is a string\n * @param value - The value to check\n * @returns true if the value is a string, false otherwise\n */\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/**\n * Checks if a value is a number\n * @param value - The value to check\n * @returns true if the value is a number, false otherwise\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number';\n}\n\n/**\n * Checks if a value is a boolean\n * @param value - The value to check\n * @returns true if the value is a boolean, false otherwise\n */\nexport function isBoolean(value: unknown): value is boolean {\n return typeof value === 'boolean';\n}\n\n/**\n * Checks if a value is a function\n * @param value - The value to check\n * @returns true if the value is a function, false otherwise\n */\nexport function isFunction(value: unknown): value is CallableFunction {\n return typeof value === 'function';\n}\n\n/**\n * Checks if a value is a plain object (but not null or array)\n * @param value - The value to check\n * @returns true if the value is a plain object, false otherwise\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Checks if a value is undefined\n * @param value - The value to check\n * @returns true if the value is undefined, false otherwise\n */\nexport function isUndefined(value: unknown): value is undefined {\n return typeof value === 'undefined';\n}\n\n/**\n * Checks if a value is null or undefined\n * @param value - The value to check\n * @returns true if the value is null or undefined, false otherwise\n */\nexport function isNil(value: unknown): value is null | undefined {\n return isUndefined(value) || value === null;\n}\n\n/**\n * Checks if a value is not null and not undefined\n * @param value - The value to check\n * @returns true if the value is not null and not undefined, false otherwise\n */\nexport function notNil<T>(value: T | null | undefined): value is T {\n return !isNil(value);\n}\n","import { effect, Injector, Signal, signal, untracked } from '@angular/core';\n\n/**\n * Listen for changes to a signal and call a function when the signal changes.\n * @param source\n * @param fn\n * @param options\n * @param options.injector\n * @internal\n */\nexport function onChange<T>(\n source: Signal<T>,\n fn: (value: T, previousValue: T | null | undefined) => void,\n options?: { injector: Injector },\n): void {\n const previousValue = signal(source());\n\n effect(\n () => {\n const value = source();\n if (value !== previousValue()) {\n untracked(() => fn(value, previousValue()));\n previousValue.set(value);\n }\n },\n { injector: options?.injector },\n );\n\n // call the fn with the initial value\n fn(source(), null);\n}\n\n/**\n * Listen for changes to a boolean signal and call one of two functions when the signal changes.\n * @param source\n * @param onTrue\n * @param onFalse\n * @param options\n */\nexport function onBooleanChange(\n source: Signal<boolean>,\n onTrue?: () => void,\n onFalse?: () => void,\n options?: { injector: Injector },\n): void {\n onChange(source, value => (value ? onTrue?.() : onFalse?.()), options);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "ng-primitives",
3
3
  "description": "Angular Primitives is a low-level headless UI component library with a focus on accessibility, customization, and developer experience. ",
4
4
  "license": "Apache-2.0",
5
- "version": "0.95.0",
5
+ "version": "0.97.0",
6
6
  "keywords": [
7
7
  "angular",
8
8
  "primitives",
package/portal/index.d.ts CHANGED
@@ -45,6 +45,48 @@ type NgpOffsetInput = NgpOffset | string;
45
45
  */
46
46
  declare function coerceOffset(value: NgpOffsetInput | null | undefined): NgpOffset;
47
47
 
48
+ /**
49
+ * Options for configuring shift behavior to keep the floating element in view.
50
+ * The shift middleware ensures the floating element stays visible by shifting it
51
+ * within the viewport when it would otherwise overflow.
52
+ */
53
+ interface NgpShiftOptions {
54
+ /**
55
+ * The minimum padding between the floating element and the viewport edges.
56
+ * Prevents the floating element from touching the edges of the viewport.
57
+ * @default 0
58
+ */
59
+ padding?: number;
60
+ /**
61
+ * The limiter function that determines how much the floating element can shift.
62
+ * Common limiters from @floating-ui/dom include:
63
+ * - limitShift: Limits shifting to prevent the reference element from being obscured
64
+ * @default undefined
65
+ */
66
+ limiter?: {
67
+ fn: (state: unknown) => {
68
+ x: number;
69
+ y: number;
70
+ };
71
+ options?: unknown;
72
+ };
73
+ }
74
+ /**
75
+ * Type representing all valid shift values.
76
+ * Can be a boolean (enable/disable), undefined, or an object with detailed options.
77
+ */
78
+ type NgpShift = boolean | NgpShiftOptions | undefined;
79
+ /**
80
+ * Input type for shift that also accepts string representations of booleans
81
+ */
82
+ type NgpShiftInput = NgpShift | string;
83
+ /**
84
+ * Transform function to coerce shift input values to the correct type
85
+ * @param value The input value to coerce
86
+ * @returns The coerced shift value
87
+ */
88
+ declare function coerceShift(value: NgpShiftInput | null | undefined): NgpShift;
89
+
48
90
  /**
49
91
  * Configuration options for creating an overlay
50
92
  * @internal
@@ -68,6 +110,8 @@ interface NgpOverlayConfig<T = unknown> {
68
110
  placement?: Signal<Placement>;
69
111
  /** Offset distance between the overlay and trigger. Can be a number or an object with axis-specific offsets */
70
112
  offset?: NgpOffset;
113
+ /** Shift configuration to keep the overlay in view. Can be a boolean, an object with options, or undefined */
114
+ shift?: NgpShift;
71
115
  /** Whether to enable flip behavior when space is limited */
72
116
  flip?: boolean;
73
117
  /** Delay before showing the overlay in milliseconds */
@@ -385,5 +429,5 @@ declare class NoopScrollStrategy implements ScrollStrategy {
385
429
  disable(): void;
386
430
  }
387
431
 
388
- export { BlockScrollStrategy, NgpComponentPortal, NgpOverlay, NgpPortal, NgpTemplatePortal, NoopScrollStrategy, coerceOffset, createOverlay, createPortal, injectOverlay, injectOverlayContext, provideOverlayContext, setupOverlayArrow };
389
- export type { NgpOffset, NgpOffsetInput, NgpOffsetOptions, NgpOverlayConfig, NgpOverlayContent, NgpOverlayTemplateContext, ScrollStrategy };
432
+ export { BlockScrollStrategy, NgpComponentPortal, NgpOverlay, NgpPortal, NgpTemplatePortal, NoopScrollStrategy, coerceOffset, coerceShift, createOverlay, createPortal, injectOverlay, injectOverlayContext, provideOverlayContext, setupOverlayArrow };
433
+ export type { NgpOffset, NgpOffsetInput, NgpOffsetOptions, NgpOverlayConfig, NgpOverlayContent, NgpOverlayTemplateContext, NgpShift, NgpShiftInput, NgpShiftOptions, ScrollStrategy };
@@ -1,6 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import * as ng_primitives_state from 'ng-primitives/state';
3
- import * as ng_primitives_progress from 'ng-primitives/progress';
2
+ import { Signal } from '@angular/core';
4
3
  import { NumberInput } from '@angular/cdk/coercion';
5
4
 
6
5
  /**
@@ -8,27 +7,12 @@ import { NumberInput } from '@angular/cdk/coercion';
8
7
  * The width of this element can be set to the percentage of the progress value.
9
8
  */
10
9
  declare class NgpProgressIndicator {
11
- /**
12
- * Access the progress state.
13
- */
14
- protected readonly state: _angular_core.Signal<ng_primitives_state.State<ng_primitives_progress.NgpProgress>>;
15
- /**
16
- * Get the percentage of the progress value.
17
- */
18
- protected readonly percentage: _angular_core.Signal<number | null>;
10
+ constructor();
19
11
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgpProgressIndicator, never>;
20
12
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgpProgressIndicator, "[ngpProgressIndicator]", never, {}, {}, never, never, true, never>;
21
13
  }
22
14
 
23
15
  declare class NgpProgressLabel {
24
- /**
25
- * Access the progress state.
26
- */
27
- protected readonly state: _angular_core.Signal<ng_primitives_state.State<ng_primitives_progress.NgpProgress>>;
28
- /**
29
- * Access the element ref.
30
- */
31
- protected readonly elementRef: _angular_core.ElementRef<HTMLElement>;
32
16
  /**
33
17
  * The unique identifier for the progress label.
34
18
  */
@@ -39,19 +23,13 @@ declare class NgpProgressLabel {
39
23
  }
40
24
 
41
25
  declare class NgpProgressTrack {
42
- /**
43
- * Access the progress state.
44
- */
45
- protected readonly state: _angular_core.Signal<ng_primitives_state.State<ng_primitives_progress.NgpProgress>>;
26
+ constructor();
46
27
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgpProgressTrack, never>;
47
28
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgpProgressTrack, "[ngpProgressTrack]", ["ngpProgressTrack"], {}, {}, never, never, true, never>;
48
29
  }
49
30
 
50
31
  declare class NgpProgressValue {
51
- /**
52
- * Access the progress state.
53
- */
54
- protected readonly state: _angular_core.Signal<ng_primitives_state.State<ng_primitives_progress.NgpProgress>>;
32
+ constructor();
55
33
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgpProgressValue, never>;
56
34
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgpProgressValue, "[ngpProgressValue]", ["ngpProgressValue"], {}, {}, never, never, true, never>;
57
35
  }
@@ -86,47 +64,79 @@ declare class NgpProgress {
86
64
  */
87
65
  readonly id: _angular_core.InputSignal<string>;
88
66
  /**
89
- * Determine if the progress is indeterminate.
90
- * @internal
91
- */
92
- readonly indeterminate: _angular_core.Signal<boolean>;
93
- /**
94
- * Determine if the progress is in a progressing state.
95
- * @internal
96
- */
97
- readonly progressing: _angular_core.Signal<boolean>;
98
- /**
99
- * Determine if the progress is complete.
67
+ * The state of the progress bar.
100
68
  * @internal
101
69
  */
102
- readonly complete: _angular_core.Signal<boolean>;
70
+ private readonly state;
103
71
  /**
104
72
  * Get the progress value text.
105
73
  */
106
74
  protected readonly valueText: _angular_core.Signal<string>;
107
- /**
108
- * The label associated with the progress bar.
109
- * @internal
110
- */
111
- readonly label: _angular_core.WritableSignal<NgpProgressLabel | null>;
112
- /**
113
- * The state of the progress bar.
114
- * @internal
115
- */
116
- protected readonly state: ng_primitives_state.CreatedState<NgpProgress>;
117
75
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgpProgress, never>;
118
76
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgpProgress, "[ngpProgress]", never, { "value": { "alias": "ngpProgressValue"; "required": false; "isSignal": true; }; "min": { "alias": "ngpProgressMin"; "required": false; "isSignal": true; }; "max": { "alias": "ngpProgressMax"; "required": false; "isSignal": true; }; "valueLabel": { "alias": "ngpProgressValueLabel"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
119
77
  }
120
78
  type NgpProgressValueTextFn = (value: number, max: number) => string;
121
79
 
122
- /**
123
- * Provides the Progress state.
124
- */
125
- declare const provideProgressState: (options?: ng_primitives_state.CreateStateProviderOptions) => _angular_core.FactoryProvider;
126
- /**
127
- * Injects the Progress state.
128
- */
129
- declare const injectProgressState: <U = NgpProgress>(injectOptions?: _angular_core.InjectOptions) => _angular_core.Signal<ng_primitives_state.State<U>>;
80
+ declare const injectProgressState: {
81
+ (): Signal<{
82
+ max: Signal<number>;
83
+ min: Signal<number>;
84
+ labelId: _angular_core.WritableSignal<string | undefined>;
85
+ valueText: Signal<string>;
86
+ id: Signal<string>;
87
+ value: Signal<number | null>;
88
+ indeterminate: Signal<boolean>;
89
+ progressing: Signal<boolean>;
90
+ complete: Signal<boolean>;
91
+ setLabel: (id: string) => void;
92
+ }>;
93
+ (options: {
94
+ hoisted: true;
95
+ optional?: boolean;
96
+ skipSelf?: boolean;
97
+ }): Signal<{
98
+ max: Signal<number>;
99
+ min: Signal<number>;
100
+ labelId: _angular_core.WritableSignal<string | undefined>;
101
+ valueText: Signal<string>;
102
+ id: Signal<string>;
103
+ value: Signal<number | null>;
104
+ indeterminate: Signal<boolean>;
105
+ progressing: Signal<boolean>;
106
+ complete: Signal<boolean>;
107
+ setLabel: (id: string) => void;
108
+ } | null>;
109
+ (options?: {
110
+ hoisted?: boolean;
111
+ optional?: boolean;
112
+ skipSelf?: boolean;
113
+ }): Signal<{
114
+ max: Signal<number>;
115
+ min: Signal<number>;
116
+ labelId: _angular_core.WritableSignal<string | undefined>;
117
+ valueText: Signal<string>;
118
+ id: Signal<string>;
119
+ value: Signal<number | null>;
120
+ indeterminate: Signal<boolean>;
121
+ progressing: Signal<boolean>;
122
+ complete: Signal<boolean>;
123
+ setLabel: (id: string) => void;
124
+ }> | Signal<{
125
+ max: Signal<number>;
126
+ min: Signal<number>;
127
+ labelId: _angular_core.WritableSignal<string | undefined>;
128
+ valueText: Signal<string>;
129
+ id: Signal<string>;
130
+ value: Signal<number | null>;
131
+ indeterminate: Signal<boolean>;
132
+ progressing: Signal<boolean>;
133
+ complete: Signal<boolean>;
134
+ setLabel: (id: string) => void;
135
+ } | null>;
136
+ };
137
+ declare const provideProgressState: (opts?: {
138
+ inherit?: boolean;
139
+ }) => _angular_core.FactoryProvider;
130
140
 
131
141
  export { NgpProgress, NgpProgressIndicator, NgpProgressLabel, NgpProgressTrack, NgpProgressValue, injectProgressState, provideProgressState };
132
142
  export type { NgpProgressValueTextFn };