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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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')}
|
||||||
|
@@ -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]);
|
Reference in New Issue
Block a user