UNPKG

@angular/material

Version:
1 lines 52.3 kB
{"version":3,"file":"_ripple-chunk.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/material/core/ripple/ripple-ref.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/material/core/ripple/ripple-event-manager.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/material/core/ripple/ripple-renderer.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/material/core/ripple/ripple.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/** Possible states for a ripple element. */\nexport enum RippleState {\n FADING_IN,\n VISIBLE,\n FADING_OUT,\n HIDDEN,\n}\n\nexport type RippleConfig = {\n color?: string;\n centered?: boolean;\n radius?: number;\n persistent?: boolean;\n animation?: RippleAnimationConfig;\n terminateOnPointerUp?: boolean;\n};\n\n/**\n * Interface that describes the configuration for the animation of a ripple.\n * There are two animation phases with different durations for the ripples.\n */\nexport interface RippleAnimationConfig {\n /** Duration in milliseconds for the enter animation (expansion from point of contact). */\n enterDuration?: number;\n /** Duration in milliseconds for the exit animation (fade-out). */\n exitDuration?: number;\n}\n\n/**\n * Reference to a previously launched ripple element.\n */\nexport class RippleRef {\n /** Current state of the ripple. */\n state: RippleState = RippleState.HIDDEN;\n\n constructor(\n private _renderer: {fadeOutRipple(ref: RippleRef): void},\n /** Reference to the ripple HTML element. */\n public element: HTMLElement,\n /** Ripple configuration used for the ripple. */\n public config: RippleConfig,\n /* Whether animations are forcibly disabled for ripples through CSS. */\n public _animationForciblyDisabledThroughCss = false,\n ) {}\n\n /** Fades out the ripple element. */\n fadeOut() {\n this._renderer.fadeOutRipple(this);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {normalizePassiveListenerOptions, _getEventTarget} from '@angular/cdk/platform';\nimport {NgZone} from '@angular/core';\n\n/** Options used to bind a passive capturing event. */\nconst passiveCapturingEventOptions = normalizePassiveListenerOptions({\n passive: true,\n capture: true,\n});\n\n/** Manages events through delegation so that as few event handlers as possible are bound. */\nexport class RippleEventManager {\n private _events = new Map<string, Map<HTMLElement, Set<EventListenerObject>>>();\n\n /** Adds an event handler. */\n addHandler(ngZone: NgZone, name: string, element: HTMLElement, handler: EventListenerObject) {\n const handlersForEvent = this._events.get(name);\n\n if (handlersForEvent) {\n const handlersForElement = handlersForEvent.get(element);\n\n if (handlersForElement) {\n handlersForElement.add(handler);\n } else {\n handlersForEvent.set(element, new Set([handler]));\n }\n } else {\n this._events.set(name, new Map([[element, new Set([handler])]]));\n\n ngZone.runOutsideAngular(() => {\n document.addEventListener(name, this._delegateEventHandler, passiveCapturingEventOptions);\n });\n }\n }\n\n /** Removes an event handler. */\n removeHandler(name: string, element: HTMLElement, handler: EventListenerObject) {\n const handlersForEvent = this._events.get(name);\n\n if (!handlersForEvent) {\n return;\n }\n\n const handlersForElement = handlersForEvent.get(element);\n\n if (!handlersForElement) {\n return;\n }\n\n handlersForElement.delete(handler);\n\n if (handlersForElement.size === 0) {\n handlersForEvent.delete(element);\n }\n\n if (handlersForEvent.size === 0) {\n this._events.delete(name);\n document.removeEventListener(name, this._delegateEventHandler, passiveCapturingEventOptions);\n }\n }\n\n /** Event handler that is bound and which dispatches the events to the different targets. */\n private _delegateEventHandler = (event: Event) => {\n const target = _getEventTarget(event);\n\n if (target) {\n this._events.get(event.type)?.forEach((handlers, element) => {\n if (element === target || element.contains(target as Node)) {\n handlers.forEach(handler => handler.handleEvent(event));\n }\n });\n }\n };\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport {\n ElementRef,\n NgZone,\n Component,\n ChangeDetectionStrategy,\n ViewEncapsulation,\n Injector,\n} from '@angular/core';\nimport {Platform, normalizePassiveListenerOptions, _getEventTarget} from '@angular/cdk/platform';\nimport {isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader} from '@angular/cdk/a11y';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {_CdkPrivateStyleLoader} from '@angular/cdk/private';\nimport {RippleRef, RippleState, RippleConfig} from './ripple-ref';\nimport {RippleEventManager} from './ripple-event-manager';\n\n/**\n * Interface that describes the target for launching ripples.\n * It defines the ripple configuration and disabled state for interaction ripples.\n * @docs-private\n */\nexport interface RippleTarget {\n /** Configuration for ripples that are launched on pointer down. */\n rippleConfig: RippleConfig;\n /** Whether ripples on pointer down should be disabled. */\n rippleDisabled: boolean;\n}\n\n/** Interfaces the defines ripple element transition event listeners. */\ninterface RippleEventListeners {\n onTransitionEnd: EventListener;\n onTransitionCancel: EventListener;\n fallbackTimer: ReturnType<typeof setTimeout> | null;\n}\n\n/**\n * Default ripple animation configuration for ripples without an explicit\n * animation config specified.\n */\nexport const defaultRippleAnimationConfig = {\n enterDuration: 225,\n exitDuration: 150,\n};\n\n/**\n * Timeout for ignoring mouse events. Mouse events will be temporary ignored after touch\n * events to avoid synthetic mouse events.\n */\nconst ignoreMouseEventsTimeout = 800;\n\n/** Options used to bind a passive capturing event. */\nconst passiveCapturingEventOptions = normalizePassiveListenerOptions({\n passive: true,\n capture: true,\n});\n\n/** Events that signal that the pointer is down. */\nconst pointerDownEvents = ['mousedown', 'touchstart'];\n\n/** Events that signal that the pointer is up. */\nconst pointerUpEvents = ['mouseup', 'mouseleave', 'touchend', 'touchcancel'];\n\n@Component({\n template: '',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n styleUrl: 'ripple-structure.css',\n host: {'mat-ripple-style-loader': ''},\n})\nexport class _MatRippleStylesLoader {}\n\n/**\n * Helper service that performs DOM manipulations. Not intended to be used outside this module.\n * The constructor takes a reference to the ripple directive's host element and a map of DOM\n * event handlers to be installed on the element that triggers ripple animations.\n * This will eventually become a custom renderer once Angular support exists.\n * @docs-private\n */\nexport class RippleRenderer implements EventListenerObject {\n /** Element where the ripples are being added to. */\n private _containerElement: HTMLElement;\n\n /** Element which triggers the ripple elements on mouse events. */\n private _triggerElement: HTMLElement | null;\n\n /** Whether the pointer is currently down or not. */\n private _isPointerDown = false;\n\n /**\n * Map of currently active ripple references.\n * The ripple reference is mapped to its element event listeners.\n * The reason why `| null` is used is that event listeners are added only\n * when the condition is truthy (see the `_startFadeOutTransition` method).\n */\n private _activeRipples = new Map<RippleRef, RippleEventListeners | null>();\n\n /** Latest non-persistent ripple that was triggered. */\n private _mostRecentTransientRipple: RippleRef | null;\n\n /** Time in milliseconds when the last touchstart event happened. */\n private _lastTouchStartEvent: number;\n\n /** Whether pointer-up event listeners have been registered. */\n private _pointerUpEventsRegistered = false;\n\n /**\n * Cached dimensions of the ripple container. Set when the first\n * ripple is shown and cleared once no more ripples are visible.\n */\n private _containerRect: DOMRect | null;\n\n private static _eventManager = new RippleEventManager();\n\n constructor(\n private _target: RippleTarget,\n private _ngZone: NgZone,\n elementOrElementRef: HTMLElement | ElementRef<HTMLElement>,\n private _platform: Platform,\n injector?: Injector,\n ) {\n // Only do anything if we're on the browser.\n if (_platform.isBrowser) {\n this._containerElement = coerceElement(elementOrElementRef);\n }\n\n if (injector) {\n injector.get(_CdkPrivateStyleLoader).load(_MatRippleStylesLoader);\n }\n }\n\n /**\n * Fades in a ripple at the given coordinates.\n * @param x Coordinate within the element, along the X axis at which to start the ripple.\n * @param y Coordinate within the element, along the Y axis at which to start the ripple.\n * @param config Extra ripple options.\n */\n fadeInRipple(x: number, y: number, config: RippleConfig = {}): RippleRef {\n const containerRect = (this._containerRect =\n this._containerRect || this._containerElement.getBoundingClientRect());\n const animationConfig = {...defaultRippleAnimationConfig, ...config.animation};\n\n if (config.centered) {\n x = containerRect.left + containerRect.width / 2;\n y = containerRect.top + containerRect.height / 2;\n }\n\n const radius = config.radius || distanceToFurthestCorner(x, y, containerRect);\n const offsetX = x - containerRect.left;\n const offsetY = y - containerRect.top;\n const enterDuration = animationConfig.enterDuration;\n\n const ripple = document.createElement('div');\n ripple.classList.add('mat-ripple-element');\n\n ripple.style.left = `${offsetX - radius}px`;\n ripple.style.top = `${offsetY - radius}px`;\n ripple.style.height = `${radius * 2}px`;\n ripple.style.width = `${radius * 2}px`;\n\n // If a custom color has been specified, set it as inline style. If no color is\n // set, the default color will be applied through the ripple theme styles.\n if (config.color != null) {\n ripple.style.backgroundColor = config.color;\n }\n\n ripple.style.transitionDuration = `${enterDuration}ms`;\n\n this._containerElement.appendChild(ripple);\n\n // By default the browser does not recalculate the styles of dynamically created\n // ripple elements. This is critical to ensure that the `scale` animates properly.\n // We enforce a style recalculation by calling `getComputedStyle` and *accessing* a property.\n // See: https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n const computedStyles = window.getComputedStyle(ripple);\n const userTransitionProperty = computedStyles.transitionProperty;\n const userTransitionDuration = computedStyles.transitionDuration;\n\n // Note: We detect whether animation is forcibly disabled through CSS (e.g. through\n // `transition: none` or `display: none`). This is technically unexpected since animations are\n // controlled through the animation config, but this exists for backwards compatibility. This\n // logic does not need to be super accurate since it covers some edge cases which can be easily\n // avoided by users.\n const animationForciblyDisabledThroughCss =\n userTransitionProperty === 'none' ||\n // Note: The canonical unit for serialized CSS `<time>` properties is seconds. Additionally\n // some browsers expand the duration for every property (in our case `opacity` and `transform`).\n userTransitionDuration === '0s' ||\n userTransitionDuration === '0s, 0s' ||\n // If the container is 0x0, it's likely `display: none`.\n (containerRect.width === 0 && containerRect.height === 0);\n\n // Exposed reference to the ripple that will be returned.\n const rippleRef = new RippleRef(this, ripple, config, animationForciblyDisabledThroughCss);\n\n // Start the enter animation by setting the transform/scale to 100%. The animation will\n // execute as part of this statement because we forced a style recalculation before.\n // Note: We use a 3d transform here in order to avoid an issue in Safari where\n // the ripples aren't clipped when inside the shadow DOM (see #24028).\n ripple.style.transform = 'scale3d(1, 1, 1)';\n\n rippleRef.state = RippleState.FADING_IN;\n\n if (!config.persistent) {\n this._mostRecentTransientRipple = rippleRef;\n }\n\n let eventListeners: RippleEventListeners | null = null;\n\n // Do not register the `transition` event listener if fade-in and fade-out duration\n // are set to zero. The events won't fire anyway and we can save resources here.\n if (!animationForciblyDisabledThroughCss && (enterDuration || animationConfig.exitDuration)) {\n this._ngZone.runOutsideAngular(() => {\n const onTransitionEnd = () => {\n // Clear the fallback timer since the transition fired correctly.\n if (eventListeners) {\n eventListeners.fallbackTimer = null;\n }\n clearTimeout(fallbackTimer);\n this._finishRippleTransition(rippleRef);\n };\n const onTransitionCancel = () => this._destroyRipple(rippleRef);\n\n // In some cases where there's a higher load on the browser, it can choose not to dispatch\n // neither `transitionend` nor `transitioncancel` (see b/227356674). This timer serves as a\n // fallback for such cases so that the ripple doesn't become stuck. We add a 100ms buffer\n // because timers aren't precise. Note that another approach can be to transition the ripple\n // to the `VISIBLE` state immediately above and to `FADING_IN` afterwards inside\n // `transitionstart`. We go with the timer because it's one less event listener and\n // it's less likely to break existing tests.\n const fallbackTimer = setTimeout(onTransitionCancel, enterDuration + 100);\n\n ripple.addEventListener('transitionend', onTransitionEnd);\n // If the transition is cancelled (e.g. due to DOM removal), we destroy the ripple\n // directly as otherwise we would keep it part of the ripple container forever.\n // https://www.w3.org/TR/css-transitions-1/#:~:text=no%20longer%20in%20the%20document.\n ripple.addEventListener('transitioncancel', onTransitionCancel);\n eventListeners = {onTransitionEnd, onTransitionCancel, fallbackTimer};\n });\n }\n\n // Add the ripple reference to the list of all active ripples.\n this._activeRipples.set(rippleRef, eventListeners);\n\n // In case there is no fade-in transition duration, we need to manually call the transition\n // end listener because `transitionend` doesn't fire if there is no transition.\n if (animationForciblyDisabledThroughCss || !enterDuration) {\n this._finishRippleTransition(rippleRef);\n }\n\n return rippleRef;\n }\n\n /** Fades out a ripple reference. */\n fadeOutRipple(rippleRef: RippleRef) {\n // For ripples already fading out or hidden, this should be a noop.\n if (rippleRef.state === RippleState.FADING_OUT || rippleRef.state === RippleState.HIDDEN) {\n return;\n }\n\n const rippleEl = rippleRef.element;\n const animationConfig = {...defaultRippleAnimationConfig, ...rippleRef.config.animation};\n\n // This starts the fade-out transition and will fire the transition end listener that\n // removes the ripple element from the DOM.\n rippleEl.style.transitionDuration = `${animationConfig.exitDuration}ms`;\n rippleEl.style.opacity = '0';\n rippleRef.state = RippleState.FADING_OUT;\n\n // In case there is no fade-out transition duration, we need to manually call the\n // transition end listener because `transitionend` doesn't fire if there is no transition.\n if (rippleRef._animationForciblyDisabledThroughCss || !animationConfig.exitDuration) {\n this._finishRippleTransition(rippleRef);\n }\n }\n\n /** Fades out all currently active ripples. */\n fadeOutAll() {\n this._getActiveRipples().forEach(ripple => ripple.fadeOut());\n }\n\n /** Fades out all currently active non-persistent ripples. */\n fadeOutAllNonPersistent() {\n this._getActiveRipples().forEach(ripple => {\n if (!ripple.config.persistent) {\n ripple.fadeOut();\n }\n });\n }\n\n /** Sets up the trigger event listeners */\n setupTriggerEvents(elementOrElementRef: HTMLElement | ElementRef<HTMLElement>) {\n const element = coerceElement(elementOrElementRef);\n\n if (!this._platform.isBrowser || !element || element === this._triggerElement) {\n return;\n }\n\n // Remove all previously registered event listeners from the trigger element.\n this._removeTriggerEvents();\n this._triggerElement = element;\n\n // Use event delegation for the trigger events since they're\n // set up during creation and are performance-sensitive.\n pointerDownEvents.forEach(type => {\n RippleRenderer._eventManager.addHandler(this._ngZone, type, element, this);\n });\n }\n\n /**\n * Handles all registered events.\n * @docs-private\n */\n handleEvent(event: Event) {\n if (event.type === 'mousedown') {\n this._onMousedown(event as MouseEvent);\n } else if (event.type === 'touchstart') {\n this._onTouchStart(event as TouchEvent);\n } else {\n this._onPointerUp();\n }\n\n // If pointer-up events haven't been registered yet, do so now.\n // We do this on-demand in order to reduce the total number of event listeners\n // registered by the ripples, which speeds up the rendering time for large UIs.\n if (!this._pointerUpEventsRegistered) {\n // The events for hiding the ripple are bound directly on the trigger, because:\n // 1. Some of them occur frequently (e.g. `mouseleave`) and any advantage we get from\n // delegation will be diminished by having to look through all the data structures often.\n // 2. They aren't as performance-sensitive, because they're bound only after the user\n // has interacted with an element.\n this._ngZone.runOutsideAngular(() => {\n pointerUpEvents.forEach(type => {\n this._triggerElement!.addEventListener(type, this, passiveCapturingEventOptions);\n });\n });\n\n this._pointerUpEventsRegistered = true;\n }\n }\n\n /** Method that will be called if the fade-in or fade-in transition completed. */\n private _finishRippleTransition(rippleRef: RippleRef) {\n if (rippleRef.state === RippleState.FADING_IN) {\n this._startFadeOutTransition(rippleRef);\n } else if (rippleRef.state === RippleState.FADING_OUT) {\n this._destroyRipple(rippleRef);\n }\n }\n\n /**\n * Starts the fade-out transition of the given ripple if it's not persistent and the pointer\n * is not held down anymore.\n */\n private _startFadeOutTransition(rippleRef: RippleRef) {\n const isMostRecentTransientRipple = rippleRef === this._mostRecentTransientRipple;\n const {persistent} = rippleRef.config;\n\n rippleRef.state = RippleState.VISIBLE;\n\n // When the timer runs out while the user has kept their pointer down, we want to\n // keep only the persistent ripples and the latest transient ripple. We do this,\n // because we don't want stacked transient ripples to appear after their enter\n // animation has finished.\n if (!persistent && (!isMostRecentTransientRipple || !this._isPointerDown)) {\n rippleRef.fadeOut();\n }\n }\n\n /** Destroys the given ripple by removing it from the DOM and updating its state. */\n private _destroyRipple(rippleRef: RippleRef) {\n const eventListeners = this._activeRipples.get(rippleRef) ?? null;\n this._activeRipples.delete(rippleRef);\n\n // Clear out the cached bounding rect if we have no more ripples.\n if (!this._activeRipples.size) {\n this._containerRect = null;\n }\n\n // If the current ref is the most recent transient ripple, unset it\n // avoid memory leaks.\n if (rippleRef === this._mostRecentTransientRipple) {\n this._mostRecentTransientRipple = null;\n }\n\n rippleRef.state = RippleState.HIDDEN;\n if (eventListeners !== null) {\n rippleRef.element.removeEventListener('transitionend', eventListeners.onTransitionEnd);\n rippleRef.element.removeEventListener('transitioncancel', eventListeners.onTransitionCancel);\n if (eventListeners.fallbackTimer !== null) {\n clearTimeout(eventListeners.fallbackTimer);\n }\n }\n rippleRef.element.remove();\n }\n\n /** Function being called whenever the trigger is being pressed using mouse. */\n private _onMousedown(event: MouseEvent) {\n // Screen readers will fire fake mouse events for space/enter. Skip launching a\n // ripple in this case for consistency with the non-screen-reader experience.\n const isFakeMousedown = isFakeMousedownFromScreenReader(event);\n const isSyntheticEvent =\n this._lastTouchStartEvent &&\n Date.now() < this._lastTouchStartEvent + ignoreMouseEventsTimeout;\n\n if (!this._target.rippleDisabled && !isFakeMousedown && !isSyntheticEvent) {\n this._isPointerDown = true;\n this.fadeInRipple(event.clientX, event.clientY, this._target.rippleConfig);\n }\n }\n\n /** Function being called whenever the trigger is being pressed using touch. */\n private _onTouchStart(event: TouchEvent) {\n if (!this._target.rippleDisabled && !isFakeTouchstartFromScreenReader(event)) {\n // Some browsers fire mouse events after a `touchstart` event. Those synthetic mouse\n // events will launch a second ripple if we don't ignore mouse events for a specific\n // time after a touchstart event.\n this._lastTouchStartEvent = Date.now();\n this._isPointerDown = true;\n\n // Use `changedTouches` so we skip any touches where the user put\n // their finger down, but used another finger to tap the element again.\n const touches = event.changedTouches as TouchList | undefined;\n\n // According to the typings the touches should always be defined, but in some cases\n // the browser appears to not assign them in tests which leads to flakes.\n if (touches) {\n for (let i = 0; i < touches.length; i++) {\n this.fadeInRipple(touches[i].clientX, touches[i].clientY, this._target.rippleConfig);\n }\n }\n }\n }\n\n /** Function being called whenever the trigger is being released. */\n private _onPointerUp() {\n if (!this._isPointerDown) {\n return;\n }\n\n this._isPointerDown = false;\n\n // Fade-out all ripples that are visible and not persistent.\n this._getActiveRipples().forEach(ripple => {\n // By default, only ripples that are completely visible will fade out on pointer release.\n // If the `terminateOnPointerUp` option is set, ripples that still fade in will also fade out.\n const isVisible =\n ripple.state === RippleState.VISIBLE ||\n (ripple.config.terminateOnPointerUp && ripple.state === RippleState.FADING_IN);\n\n if (!ripple.config.persistent && isVisible) {\n ripple.fadeOut();\n }\n });\n }\n\n private _getActiveRipples(): RippleRef[] {\n return Array.from(this._activeRipples.keys());\n }\n\n /** Removes previously registered event listeners from the trigger element. */\n _removeTriggerEvents() {\n const trigger = this._triggerElement;\n\n if (trigger) {\n pointerDownEvents.forEach(type =>\n RippleRenderer._eventManager.removeHandler(type, trigger, this),\n );\n\n if (this._pointerUpEventsRegistered) {\n pointerUpEvents.forEach(type =>\n trigger.removeEventListener(type, this, passiveCapturingEventOptions),\n );\n\n this._pointerUpEventsRegistered = false;\n }\n }\n }\n}\n\n/**\n * Returns the distance from the point (x, y) to the furthest corner of a rectangle.\n */\nfunction distanceToFurthestCorner(x: number, y: number, rect: DOMRect) {\n const distX = Math.max(Math.abs(x - rect.left), Math.abs(x - rect.right));\n const distY = Math.max(Math.abs(y - rect.top), Math.abs(y - rect.bottom));\n return Math.sqrt(distX * distX + distY * distY);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {Platform} from '@angular/cdk/platform';\nimport {\n Directive,\n ElementRef,\n InjectionToken,\n Input,\n NgZone,\n OnDestroy,\n OnInit,\n Injector,\n inject,\n} from '@angular/core';\nimport {_CdkPrivateStyleLoader} from '@angular/cdk/private';\nimport {RippleAnimationConfig, RippleConfig, RippleRef} from './ripple-ref';\nimport {RippleRenderer, RippleTarget} from './ripple-renderer';\nimport {_animationsDisabled} from '../animation/animation';\n\n/** Configurable options for `matRipple`. */\nexport interface RippleGlobalOptions {\n /**\n * Whether ripples should be disabled. Ripples can be still launched manually by using\n * the `launch()` method. Therefore focus indicators will still show up.\n */\n disabled?: boolean;\n\n /**\n * Default configuration for the animation duration of the ripples. There are two phases with\n * different durations for the ripples: `enter` and `leave`. The durations will be overwritten\n * by the value of `matRippleAnimation` or if animations are disabled.\n */\n animation?: RippleAnimationConfig;\n\n /**\n * Whether ripples should start fading out immediately after the mouse or touch is released. By\n * default, ripples will wait for the enter animation to complete and for mouse or touch release.\n */\n terminateOnPointerUp?: boolean;\n\n /**\n * A namespace to use for ripple loader to allow multiple instances to exist on the same page.\n */\n namespace?: string;\n}\n\n/** Injection token that can be used to specify the global ripple options. */\nexport const MAT_RIPPLE_GLOBAL_OPTIONS = new InjectionToken<RippleGlobalOptions>(\n 'mat-ripple-global-options',\n);\n\n@Directive({\n selector: '[mat-ripple], [matRipple]',\n exportAs: 'matRipple',\n host: {\n 'class': 'mat-ripple',\n '[class.mat-ripple-unbounded]': 'unbounded',\n },\n})\nexport class MatRipple implements OnInit, OnDestroy, RippleTarget {\n private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private _animationsDisabled = _animationsDisabled();\n\n /** Custom color for all ripples. */\n @Input('matRippleColor') color: string;\n\n /** Whether the ripples should be visible outside the component's bounds. */\n @Input('matRippleUnbounded') unbounded: boolean;\n\n /**\n * Whether the ripple always originates from the center of the host element's bounds, rather\n * than originating from the location of the click event.\n */\n @Input('matRippleCentered') centered: boolean;\n\n /**\n * If set, the radius in pixels of foreground ripples when fully expanded. If unset, the radius\n * will be the distance from the center of the ripple to the furthest corner of the host element's\n * bounding rectangle.\n */\n @Input('matRippleRadius') radius: number = 0;\n\n /**\n * Configuration for the ripple animation. Allows modifying the enter and exit animation\n * duration of the ripples. The animation durations will be overwritten if animations are\n * disabled.\n */\n @Input('matRippleAnimation') animation: RippleAnimationConfig;\n\n /**\n * Whether click events will not trigger the ripple. Ripples can be still launched manually\n * by using the `launch()` method.\n */\n @Input('matRippleDisabled')\n get disabled() {\n return this._disabled;\n }\n set disabled(value: boolean) {\n if (value) {\n this.fadeOutAllNonPersistent();\n }\n this._disabled = value;\n this._setupTriggerEventsIfEnabled();\n }\n private _disabled: boolean = false;\n\n /**\n * The element that triggers the ripple when click events are received.\n * Defaults to the directive's host element.\n */\n @Input('matRippleTrigger')\n get trigger() {\n return this._trigger || this._elementRef.nativeElement;\n }\n set trigger(trigger: HTMLElement) {\n this._trigger = trigger;\n this._setupTriggerEventsIfEnabled();\n }\n private _trigger: HTMLElement;\n\n /** Renderer for the ripple DOM manipulations. */\n private _rippleRenderer: RippleRenderer;\n\n /** Options that are set globally for all ripples. */\n private _globalOptions: RippleGlobalOptions;\n\n /** @docs-private Whether ripple directive is initialized and the input bindings are set. */\n _isInitialized: boolean = false;\n\n constructor(...args: unknown[]);\n\n constructor() {\n const ngZone = inject(NgZone);\n const platform = inject(Platform);\n const globalOptions = inject<RippleGlobalOptions>(MAT_RIPPLE_GLOBAL_OPTIONS, {optional: true});\n const injector = inject(Injector);\n\n // Note: cannot use `inject()` here, because this class\n // gets instantiated manually in the ripple loader.\n this._globalOptions = globalOptions || {};\n this._rippleRenderer = new RippleRenderer(this, ngZone, this._elementRef, platform, injector);\n }\n\n ngOnInit() {\n this._isInitialized = true;\n this._setupTriggerEventsIfEnabled();\n }\n\n ngOnDestroy() {\n this._rippleRenderer._removeTriggerEvents();\n }\n\n /** Fades out all currently showing ripple elements. */\n fadeOutAll() {\n this._rippleRenderer.fadeOutAll();\n }\n\n /** Fades out all currently showing non-persistent ripple elements. */\n fadeOutAllNonPersistent() {\n this._rippleRenderer.fadeOutAllNonPersistent();\n }\n\n /**\n * Ripple configuration from the directive's input values.\n * @docs-private Implemented as part of RippleTarget\n */\n get rippleConfig(): RippleConfig {\n return {\n centered: this.centered,\n radius: this.radius,\n color: this.color,\n animation: {\n ...this._globalOptions.animation,\n ...(this._animationsDisabled ? {enterDuration: 0, exitDuration: 0} : {}),\n ...this.animation,\n },\n terminateOnPointerUp: this._globalOptions.terminateOnPointerUp,\n };\n }\n\n /**\n * Whether ripples on pointer-down are disabled or not.\n * @docs-private Implemented as part of RippleTarget\n */\n get rippleDisabled(): boolean {\n return this.disabled || !!this._globalOptions.disabled;\n }\n\n /** Sets up the trigger event listeners if ripples are enabled. */\n private _setupTriggerEventsIfEnabled() {\n if (!this.disabled && this._isInitialized) {\n this._rippleRenderer.setupTriggerEvents(this.trigger);\n }\n }\n\n /**\n * Launches a manual ripple using the specified ripple configuration.\n * @param config Configuration for the manual ripple.\n */\n launch(config: RippleConfig): RippleRef;\n\n /**\n * Launches a manual ripple at the specified coordinates relative to the viewport.\n * @param x Coordinate along the X axis at which to fade-in the ripple. Coordinate\n * should be relative to the viewport.\n * @param y Coordinate along the Y axis at which to fade-in the ripple. Coordinate\n * should be relative to the viewport.\n * @param config Optional ripple configuration for the manual ripple.\n */\n launch(x: number, y: number, config?: RippleConfig): RippleRef;\n\n /** Launches a manual ripple at the specified coordinated or just by the ripple config. */\n launch(configOrX: number | RippleConfig, y: number = 0, config?: RippleConfig): RippleRef {\n if (typeof configOrX === 'number') {\n return this._rippleRenderer.fadeInRipple(configOrX, y, {...this.rippleConfig, ...config});\n } else {\n return this._rippleRenderer.fadeInRipple(0, 0, {...this.rippleConfig, ...configOrX});\n }\n }\n}\n"],"names":["RippleState","RippleRef","_renderer","element","config","_animationForciblyDisabledThroughCss","state","HIDDEN","constructor","fadeOut","fadeOutRipple","passiveCapturingEventOptions","normalizePassiveListenerOptions","passive","capture","RippleEventManager","_events","Map","addHandler","ngZone","name","handler","handlersForEvent","get","handlersForElement","add","set","Set","runOutsideAngular","document","addEventListener","_delegateEventHandler","removeHandler","delete","size","removeEventListener","event","target","_getEventTarget","type","forEach","handlers","contains","handleEvent","defaultRippleAnimationConfig","enterDuration","exitDuration","ignoreMouseEventsTimeout","pointerDownEvents","pointerUpEvents","_MatRippleStylesLoader","deps","i0","ɵɵFactoryTarget","Component","ɵcmp","ɵɵngDeclareComponent","minVersion","version","isInline","styles","changeDetection","ChangeDetectionStrategy","OnPush","encapsulation","ViewEncapsulation","None","decorators","args","template","host","RippleRenderer","_target","_ngZone","_platform","_containerElement","_triggerElement","_isPointerDown","_activeRipples","_mostRecentTransientRipple","_lastTouchStartEvent","_pointerUpEventsRegistered","_containerRect","_eventManager","elementOrElementRef","injector","isBrowser","coerceElement","_CdkPrivateStyleLoader","load","fadeInRipple","x","y","containerRect","getBoundingClientRect","animationConfig","animation","centered","left","width","top","height","radius","distanceToFurthestCorner","offsetX","offsetY","ripple","createElement","classList","style","color","backgroundColor","transitionDuration","appendChild","computedStyles","window","getComputedStyle","userTransitionProperty","transitionProperty","userTransitionDuration","animationForciblyDisabledThroughCss","rippleRef","transform","FADING_IN","persistent","eventListeners","onTransitionEnd","fallbackTimer","clearTimeout","_finishRippleTransition","onTransitionCancel","_destroyRipple","setTimeout","FADING_OUT","rippleEl","opacity","fadeOutAll","_getActiveRipples","fadeOutAllNonPersistent","setupTriggerEvents","_removeTriggerEvents","_onMousedown","_onTouchStart","_onPointerUp","_startFadeOutTransition","isMostRecentTransientRipple","VISIBLE","remove","isFakeMousedown","isFakeMousedownFromScreenReader","isSyntheticEvent","Date","now","rippleDisabled","clientX","clientY","rippleConfig","isFakeTouchstartFromScreenReader","touches","changedTouches","i","length","isVisible","terminateOnPointerUp","Array","from","keys","trigger","rect","distX","Math","max","abs","right","distY","bottom","sqrt","MAT_RIPPLE_GLOBAL_OPTIONS","InjectionToken","MatRipple","_elementRef","inject","ElementRef","_animationsDisabled","unbounded","disabled","_disabled","value","_setupTriggerEventsIfEnabled","_trigger","nativeElement","_rippleRenderer","_globalOptions","_isInitialized","NgZone","platform","Platform","globalOptions","optional","Injector","ngOnInit","ngOnDestroy","launch","configOrX","Directive","isStandalone","selector","inputs","properties","classAttribute","exportAs","ngImport","Input"],"mappings":"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