@sandlada/mdc
Version:
@sandlada/mdc is an open source component library that follows the Material Design 3 design specifications.
82 lines • 3.03 kB
TypeScript
/**
* @license
* Copyright 2026 Kai-Orion & Sandlada
* SPDX-License-Identifier: MIT
*/
import { type ReactiveController, type ReactiveControllerHost } from 'lit';
/**
* Configuration options for {@link OpacityTransitionController}.
*/
export interface OpacityTransitionOptions {
/**
* Returns the target element whose opacity is animated.
* May return `null` before the element has been rendered.
*/
target: () => HTMLElement | null;
/**
* Animation duration in milliseconds.
* @default 300
*/
duration?: number;
/**
* CSS easing function for the animation.
* @default 'cubic-bezier(0.2, 0, 0.2, 1)'
*/
easing?: string;
}
/**
* A `ReactiveController` that fades a target element's opacity from 0 → 1
* whenever its content changes.
*
* ### Trigger sources
* - **Light DOM mutations** (e.g. slotted text content changes, slot child
* additions / removals): detected via a `MutationObserver` on the host.
* Animation is deferred to the next animation frame so that any concurrent
* Lit re-renders complete before we start the fade.
* - **Lit re-renders** (e.g. shadow DOM structural changes): detected via
* `hostUpdated()`. Skipped when a mutation rAF is already pending to avoid
* animating twice for the same visual change.
*
* ### Animation
* Uses the Web Animations API (`element.animate()`). The animation holds
* `opacity: 0` for the first 15 % of the duration, then fades to `opacity: 1`
* over the remaining time. When a new change arrives while an animation is
* running, the old animation is cancelled and a new one starts immediately.
*
* @example
* ```ts
* private readonly opacityController = new OpacityTransitionController(this, {
* target: () => this.labelElement,
* duration: 250,
* })
* ```
*/
export declare class OpacityTransitionController implements ReactiveController {
private readonly host;
private readonly options;
/** Currently running WAAPI animation, if any. */
private currentAnimation;
private mutationObserver;
/** Non-null when a measurement rAF is already queued (coalescing guard). */
private rafId;
/** Set to `true` after the first `hostUpdated` so we skip animating on initial render. */
private hasRendered;
constructor(host: ReactiveControllerHost & Element, options: OpacityTransitionOptions);
hostConnected(): void;
hostDisconnected(): void;
/**
* Handles Lit re-render triggered changes. Defers to any already-queued
* mutation rAF to avoid double-animating.
*/
hostUpdated(): void;
/**
* MutationObserver callback for light DOM changes (slotted text / children).
* Defers to the next animation frame so that Lit re-renders triggered by
* the same mutation complete before we start the fade.
*/
private readonly onMutation;
private animate;
private cancelAnimation;
private cancelPendingRaf;
}
//# sourceMappingURL=opacity-transition-controller.d.ts.map