Onboarding / Deployment Scripts / Marketing updates
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
export function accordion(node: HTMLElement) {
|
||||
function handleToggle(event: Event) {
|
||||
const target = event.target;
|
||||
|
||||
if (!(target instanceof HTMLDetailsElement) || !target.open || !node.contains(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const details = node.querySelectorAll('details');
|
||||
|
||||
for (const item of details) {
|
||||
if (item !== target) {
|
||||
item.open = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node.addEventListener('toggle', handleToggle, true);
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
node.removeEventListener('toggle', handleToggle, true);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { describe, expect, it, vi, afterEach } from 'vitest';
|
||||
import { reveal } from './reveal';
|
||||
|
||||
class TestIntersectionObserver {
|
||||
static instances: TestIntersectionObserver[] = [];
|
||||
|
||||
callback: IntersectionObserverCallback;
|
||||
disconnect = vi.fn();
|
||||
observe = vi.fn();
|
||||
unobserve = vi.fn();
|
||||
|
||||
constructor(callback: IntersectionObserverCallback) {
|
||||
this.callback = callback;
|
||||
TestIntersectionObserver.instances.push(this);
|
||||
}
|
||||
|
||||
trigger(target: Element, isIntersecting: boolean) {
|
||||
this.callback(
|
||||
[{ isIntersecting, target } as IntersectionObserverEntry],
|
||||
this as unknown as IntersectionObserver
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
describe('reveal action', () => {
|
||||
afterEach(() => {
|
||||
TestIntersectionObserver.instances = [];
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it('toggles visibility as the element enters and leaves the viewport', () => {
|
||||
vi.stubGlobal('IntersectionObserver', TestIntersectionObserver);
|
||||
vi.spyOn(window, 'matchMedia').mockReturnValue({
|
||||
matches: false,
|
||||
media: '(prefers-reduced-motion: reduce)',
|
||||
onchange: null,
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
addEventListener: vi.fn(),
|
||||
removeEventListener: vi.fn(),
|
||||
dispatchEvent: vi.fn()
|
||||
} as MediaQueryList);
|
||||
|
||||
const node = document.createElement('div');
|
||||
document.body.appendChild(node);
|
||||
vi.spyOn(node, 'getBoundingClientRect').mockReturnValue({
|
||||
width: 100,
|
||||
height: 100,
|
||||
top: window.innerHeight + 100,
|
||||
right: 100,
|
||||
bottom: window.innerHeight + 200,
|
||||
left: 0,
|
||||
x: 0,
|
||||
y: window.innerHeight + 100,
|
||||
toJSON() {
|
||||
return {};
|
||||
}
|
||||
} as DOMRect);
|
||||
|
||||
const action = reveal(node, { delay: 40, distance: 32 });
|
||||
const observer = TestIntersectionObserver.instances[0];
|
||||
|
||||
expect(node.classList.contains('reveal-ready')).toBe(true);
|
||||
expect(node.classList.contains('reveal-visible')).toBe(false);
|
||||
expect(node.style.getPropertyValue('--reveal-delay')).toBe('40ms');
|
||||
expect(node.style.getPropertyValue('--reveal-distance')).toBe('32px');
|
||||
|
||||
observer.trigger(node, true);
|
||||
expect(node.classList.contains('reveal-visible')).toBe(true);
|
||||
|
||||
observer.trigger(node, false);
|
||||
expect(node.classList.contains('reveal-visible')).toBe(false);
|
||||
|
||||
action.destroy();
|
||||
expect(observer.disconnect).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
@@ -47,13 +47,18 @@ export function reveal(node: HTMLElement, options: RevealOptions = {}) {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
for (const entry of entries) {
|
||||
if (!entry.isIntersecting) {
|
||||
if (entry.isIntersecting) {
|
||||
node.classList.add('reveal-visible');
|
||||
continue;
|
||||
}
|
||||
|
||||
node.classList.add('reveal-visible');
|
||||
observer.disconnect();
|
||||
break;
|
||||
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
|
||||
const rect = entry.boundingClientRect;
|
||||
const fullyOutOfView = rect.bottom <= 0 || rect.top >= viewportHeight;
|
||||
|
||||
if (fullyOutOfView) {
|
||||
node.classList.remove('reveal-visible');
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user