From 78c956292a973b69b270635feeb7a65f15d31125 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Aug 2020 14:01:04 +0300 Subject: [PATCH] onWheel issue fix --- example/package-lock.json | 24 ++++++------ package.json | 2 +- src/components/gantt/gantt.tsx | 69 ++++++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 33 deletions(-) diff --git a/example/package-lock.json b/example/package-lock.json index ec4c3d9..b5de707 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -379,9 +379,9 @@ "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/react": { - "version": "16.9.47", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.47.tgz", - "integrity": "sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ==", + "version": "16.9.48", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.48.tgz", + "integrity": "sha512-4ykBVswgYitPGMXFRxJCHkxJDU2rjfU3/zw67f8+dB7sNdVJXsrwqoYxz/stkAucymnEEbRPFmX7Ce5Mc/kJCw==", "requires": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -597,9 +597,9 @@ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } @@ -753,9 +753,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } @@ -799,9 +799,9 @@ "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/react": { - "version": "16.9.47", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.47.tgz", - "integrity": "sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ==", + "version": "16.9.48", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.48.tgz", + "integrity": "sha512-4ykBVswgYitPGMXFRxJCHkxJDU2rjfU3/zw67f8+dB7sNdVJXsrwqoYxz/stkAucymnEEbRPFmX7Ce5Mc/kJCw==", "requires": { "@types/prop-types": "*", "csstype": "^3.0.2" diff --git a/package.json b/package.json index 69fdab9..4db3a58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gantt-task-react", - "version": "0.1.5", + "version": "0.1.6", "description": "Interactive Gantt Chart for React with TypeScript.", "author": "MaTeMaTuK ", "homepage": "https://github.com/MaTeMaTuK/gantt-task-react", diff --git a/src/components/gantt/gantt.tsx b/src/components/gantt/gantt.tsx index 8923f31..486f55d 100644 --- a/src/components/gantt/gantt.tsx +++ b/src/components/gantt/gantt.tsx @@ -1,4 +1,4 @@ -import React, { useState, SyntheticEvent } from "react"; +import React, { useState, SyntheticEvent, useRef, useEffect } from "react"; import { ViewMode, GanttProps, Task } from "../../types/public-types"; import { GridProps } from "../grid/grid"; import { ganttDateRange, seedDates } from "../../helpers/date-helper"; @@ -42,10 +42,11 @@ export const Gantt: React.SFC = ({ onDoubleClick, onTaskDelete, }) => { + const wrapperRef = useRef(null); const [ganttTasks, setGanttTasks] = useState(tasks); const [scrollY, setScrollY] = useState(0); const [scrollX, setScrollX] = useState(0); - + const [ignoreScrollEvent, setIgnoreScrollEvent] = useState(false); const [startDate, endDate] = ganttDateRange(ganttTasks, viewMode); const dates = seedDates(startDate, endDate, viewMode); @@ -53,13 +54,43 @@ export const Gantt: React.SFC = ({ const gridWidth = dates.length * columnWidth; const ganttFullHeight = ganttTasks.length * rowHeight; - const onTasksDateChange = (tasks: Task[]) => { - setGanttTasks(tasks); - }; + // scroll events + useEffect(() => { + const handleWheel = (event: WheelEvent) => { + event.preventDefault(); + const newScrollY = scrollY + event.deltaY; + if (newScrollY < 0) { + setScrollY(0); + } else if (newScrollY > ganttFullHeight - ganttHeight) { + setScrollY(ganttFullHeight - ganttHeight); + } else { + setScrollY(newScrollY); + } + setIgnoreScrollEvent(true); + }; - const handleScroll = (event: SyntheticEvent) => { - if (scrollY !== event.currentTarget.scrollTop) + // subscribe if scroll is necessary + if ( + wrapperRef.current && + ganttHeight && + ganttHeight < ganttTasks.length * rowHeight + ) { + wrapperRef.current.addEventListener("wheel", handleWheel, { + passive: false, + }); + } + return () => { + if (wrapperRef.current) { + wrapperRef.current.removeEventListener("wheel", handleWheel); + } + }; + }, [wrapperRef.current, scrollY, ganttHeight, ganttTasks, rowHeight]); + + const handleScrollY = (event: SyntheticEvent) => { + if (scrollY !== event.currentTarget.scrollTop && !ignoreScrollEvent) { setScrollY(event.currentTarget.scrollTop); + } + setIgnoreScrollEvent(false); }; const handleScrollX = (event: SyntheticEvent) => { @@ -67,17 +98,9 @@ export const Gantt: React.SFC = ({ setScrollX(event.currentTarget.scrollLeft); }; - const handleWheel = (event: React.WheelEvent) => { - const newScrollY = scrollY + event.deltaY; - if (newScrollY < 0) { - setScrollY(0); - } else if (newScrollY > ganttFullHeight - ganttHeight) { - setScrollY(ganttFullHeight - ganttHeight); - } else { - setScrollY(scrollY + event.deltaY); - } - }; - + /** + * Handles arrow keys events and transform it to new scroll + */ const handleKeyDown = (event: React.KeyboardEvent) => { event.preventDefault(); let newScrollY = scrollY; @@ -120,6 +143,12 @@ export const Gantt: React.SFC = ({ setScrollY(newScrollY); } } + setIgnoreScrollEvent(true); + }; + + // task change event + const onTasksDateChange = (tasks: Task[]) => { + setGanttTasks(tasks); }; const gridProps: GridProps = { @@ -183,9 +212,9 @@ export const Gantt: React.SFC = ({ return (
{listCellWidth && } = ({ ganttHeight={ganttHeight} headerHeight={headerHeight} scroll={scrollY} - onScroll={handleScroll} + onScroll={handleScrollY} />
);