Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-atom-trigger",
"version": "2.0.6",
"version": "2.0.7",
"description": "Geometry-based scroll trigger for React with precise enter/leave control. A modern alternative to react-waypoint.",
"keywords": [
"intersection",
Expand Down
68 changes: 16 additions & 52 deletions src/AtomTrigger.observation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,6 @@ function createRegistration(
};
}

function applyObservationConfig(
registration: SentinelRegistration,
config: ObservationConfig,
): void {
registration.node = config.node;
registration.rootMargin = config.rootMargin;
registration.threshold = config.threshold;
registration.once = config.once;
registration.oncePerDirection = config.oncePerDirection;
registration.fireOnInitialVisible = config.fireOnInitialVisible;
}

function applyObservationCallbacks(
registration: SentinelRegistration,
callbacks: ObservationCallbacks,
Expand All @@ -71,40 +59,6 @@ function clearObservationBinding(controller: ObservationController): void {
controller.binding = null;
}

function createObservationConfig(input: {
node: Element;
rootMargin: string;
threshold: number;
once: boolean;
oncePerDirection: boolean;
fireOnInitialVisible: boolean;
}): ObservationConfig {
return {
node: input.node,
rootMargin: input.rootMargin,
threshold: input.threshold,
once: input.once,
oncePerDirection: input.oncePerDirection,
fireOnInitialVisible: input.fireOnInitialVisible,
};
}

function bindingsMatch(
previousBinding: ObservationBinding | null,
nextBinding: ObservationBinding,
): boolean {
return Boolean(
previousBinding &&
previousBinding.node === nextBinding.node &&
previousBinding.target === nextBinding.target &&
previousBinding.rootMargin === nextBinding.rootMargin &&
previousBinding.threshold === nextBinding.threshold &&
previousBinding.once === nextBinding.once &&
previousBinding.oncePerDirection === nextBinding.oncePerDirection &&
previousBinding.fireOnInitialVisible === nextBinding.fireOnInitialVisible,
);
}

export function createObservationController(
config: ObservationConfig,
callbacks: ObservationCallbacks,
Expand Down Expand Up @@ -144,18 +98,18 @@ export function reconcileObservationBinding(
return;
}

const nextConfig = createObservationConfig({
const nextConfig: ObservationConfig = {
node: input.node,
rootMargin: input.rootMargin,
threshold: input.threshold,
once: input.once,
oncePerDirection: input.oncePerDirection,
fireOnInitialVisible: input.fireOnInitialVisible,
});
};

if (input.disabled || !input.target) {
clearObservationBinding(controller);
applyObservationConfig(registration, nextConfig);
Object.assign(registration, nextConfig);
resetObservationState(registration);
return;
}
Expand All @@ -165,14 +119,24 @@ export function reconcileObservationBinding(
target: input.target,
};

if (bindingsMatch(controller.binding, nextBinding)) {
applyObservationConfig(registration, nextConfig);
const bindingUnchanged =
controller.binding !== null &&
controller.binding.node === nextBinding.node &&
controller.binding.target === nextBinding.target &&
controller.binding.rootMargin === nextBinding.rootMargin &&
controller.binding.threshold === nextBinding.threshold &&
controller.binding.once === nextBinding.once &&
controller.binding.oncePerDirection === nextBinding.oncePerDirection &&
controller.binding.fireOnInitialVisible === nextBinding.fireOnInitialVisible;

if (bindingUnchanged) {
Object.assign(registration, nextConfig);
return;
}

resetObservationState(registration);
clearObservationBinding(controller);
applyObservationConfig(registration, nextConfig);
Object.assign(registration, nextConfig);
controller.dispose = registerSentinel(input.target, registration);
controller.binding = nextBinding;
}
Expand Down
7 changes: 1 addition & 6 deletions src/AtomTrigger.scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,10 @@ function createRootScheduler(target: SchedulerTarget): RootScheduler {
return;
}

scheduler.rafId = -1;
const nextFrameId = window.requestAnimationFrame(() => {
scheduler.rafId = window.requestAnimationFrame(() => {
scheduler.rafId = 0;
flushSamples();
});

if (scheduler.rafId === -1) {
scheduler.rafId = nextFrameId;
}
};

const handleScroll = () => {
Expand Down
5 changes: 1 addition & 4 deletions src/testUtils/domEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { cleanup, fireEvent } from '@testing-library/react';
import { vi } from 'vitest';
import { __resetWarningsForTests } from '../AtomTrigger.warnings';

let animationFrameId = 0;
let activeScrollTop = 0;
let activeScrollLeft = 0;
const initialNodeEnv = process.env.NODE_ENV;
Expand Down Expand Up @@ -96,14 +95,12 @@ export function setWindowSize(width: number, height: number): void {

export function prepareDomTestRun(): void {
setActiveScrollPosition(0, 0);
animationFrameId = 0;
setWindowScroll(0, 0);
setWindowSize(1024, 768);

vi.stubGlobal('requestAnimationFrame', (callback: FrameRequestCallback) => {
callback(performance.now());
animationFrameId += 1;
return animationFrameId;
return 0;
});
vi.stubGlobal('cancelAnimationFrame', vi.fn());
}
Expand Down
Loading