Implement new automation scrolling with simultaneous X and Y scroll support

This fixes horizontal scroll bar appearing only after scrolling till the end vertically.
Allows for simultaneous X and Y axis scrolling on trackpads and touch devices.

[MAILPOET-5587]
This commit is contained in:
Jan Jakes
2023-10-19 18:02:40 +02:00
committed by Aschepikov
parent 9e036244c4
commit df9e582924
3 changed files with 41 additions and 2 deletions

View File

@@ -3,10 +3,11 @@
display: grid; display: grid;
flex-grow: 1; flex-grow: 1;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
overflow: scroll;
width: 100%;
} }
.mailpoet-automation-editor-automation-wrapper { .mailpoet-automation-editor-automation-wrapper {
overflow: scroll;
padding: 0 20px 50px; padding: 0 20px 50px;
} }

View File

@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useRef, useState } from 'react';
import { import {
__unstableComposite as Composite, __unstableComposite as Composite,
__unstableUseCompositeState as useCompositeState, __unstableUseCompositeState as useCompositeState,
@@ -11,6 +11,7 @@ import { InserterPopover } from '../inserter-popover';
import { storeName } from '../../store'; import { storeName } from '../../store';
import { Statistics } from './statistics'; import { Statistics } from './statistics';
import { Flow } from './flow'; import { Flow } from './flow';
import { useAutomationScroll } from './use-automation-scroll';
type AutomationProps = { type AutomationProps = {
context: 'edit' | 'view'; context: 'edit' | 'view';
@@ -48,6 +49,10 @@ export function Automation({ context }: AutomationProps): JSX.Element {
} }
}, [rendered]); }, [rendered]);
// handle automation scrolling
const automationRef = useRef<HTMLDivElement>();
useAutomationScroll(automationRef);
if (!automationData) { if (!automationData) {
return <EmptyAutomation />; return <EmptyAutomation />;
} }
@@ -56,6 +61,7 @@ export function Automation({ context }: AutomationProps): JSX.Element {
<AutomationContext.Provider value={automationContext}> <AutomationContext.Provider value={automationContext}>
<AutomationCompositeContext.Provider value={compositeState}> <AutomationCompositeContext.Provider value={compositeState}>
<Composite <Composite
ref={automationRef}
state={compositeState} state={compositeState}
role="tree" role="tree"
aria-label={__('Automation', 'mailpoet')} aria-label={__('Automation', 'mailpoet')}

View File

@@ -0,0 +1,32 @@
import { MutableRefObject, useEffect } from 'react';
// Handle automation scrolling, including both X and Y axes simultaneously.
// Use animation frames to sync with browser repaints for smooth scrolling.
export const useAutomationScroll = (
automationRef: MutableRefObject<HTMLDivElement>,
): void =>
useEffect(() => {
const automation = automationRef.current;
if (!automation) {
return undefined;
}
let frameId: number;
const scrollHandler = (event) => {
event.preventDefault();
frameId = requestAnimationFrame(() => {
automation.scrollLeft += event.deltaX;
automation.scrollTop += event.deltaY;
});
};
automation.addEventListener('wheel', scrollHandler, { passive: false });
// cleanup
return () => {
automation.removeEventListener('wheel', scrollHandler);
if (frameId) {
cancelAnimationFrame(frameId);
}
};
}, [automationRef]);