arrow Left/Right key events have added

This commit is contained in:
unknown 2020-08-25 20:58:36 +03:00
parent 77f985dad8
commit af214d6b1b
4 changed files with 58 additions and 24 deletions

View File

@ -379,9 +379,9 @@
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
}, },
"@types/react": { "@types/react": {
"version": "16.9.46", "version": "16.9.47",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.46.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.47.tgz",
"integrity": "sha512-dbHzO3aAq1lB3jRQuNpuZ/mnu+CdD3H0WVaaBQA8LTT3S33xhVBUj232T8M3tAhSWJs/D/UqORYUlJNl/8VQZg==", "integrity": "sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ==",
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"csstype": "^3.0.2" "csstype": "^3.0.2"
@ -513,9 +513,9 @@
"integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA=="
}, },
"csstype": { "csstype": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz",
"integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" "integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag=="
}, },
"dom-accessibility-api": { "dom-accessibility-api": {
"version": "0.3.0", "version": "0.3.0",
@ -780,9 +780,9 @@
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
}, },
"csstype": { "csstype": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz",
"integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" "integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag=="
} }
} }
}, },
@ -799,18 +799,18 @@
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
}, },
"@types/react": { "@types/react": {
"version": "16.9.46", "version": "16.9.47",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.46.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.47.tgz",
"integrity": "sha512-dbHzO3aAq1lB3jRQuNpuZ/mnu+CdD3H0WVaaBQA8LTT3S33xhVBUj232T8M3tAhSWJs/D/UqORYUlJNl/8VQZg==", "integrity": "sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ==",
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
}, },
"csstype": { "csstype": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz",
"integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" "integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag=="
} }
} }
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "gantt-task-react", "name": "gantt-task-react",
"version": "0.1.3", "version": "0.1.4",
"description": "Interactive Gantt Chart for React with TypeScript.", "description": "Interactive Gantt Chart for React with TypeScript.",
"author": "MaTeMaTuK <maksym.vikarii@gmail.com>", "author": "MaTeMaTuK <maksym.vikarii@gmail.com>",
"homepage": "https://github.com/MaTeMaTuK/gantt-task-react", "homepage": "https://github.com/MaTeMaTuK/gantt-task-react",

View File

@ -44,6 +44,7 @@ export const Gantt: React.SFC<GanttProps> = ({
}) => { }) => {
const [ganttTasks, setGanttTasks] = useState<Task[]>(tasks); const [ganttTasks, setGanttTasks] = useState<Task[]>(tasks);
const [scrollY, setScrollY] = useState(0); const [scrollY, setScrollY] = useState(0);
const [scrollX, setScrollX] = useState(0);
const [startDate, endDate] = ganttDateRange(ganttTasks, viewMode); const [startDate, endDate] = ganttDateRange(ganttTasks, viewMode);
const dates = seedDates(startDate, endDate, viewMode); const dates = seedDates(startDate, endDate, viewMode);
@ -57,7 +58,13 @@ export const Gantt: React.SFC<GanttProps> = ({
}; };
const handleScroll = (event: SyntheticEvent<HTMLDivElement>) => { const handleScroll = (event: SyntheticEvent<HTMLDivElement>) => {
setScrollY(event.currentTarget.scrollTop); if (scrollY !== event.currentTarget.scrollTop)
setScrollY(event.currentTarget.scrollTop);
};
const handleScrollX = (event: SyntheticEvent<HTMLDivElement>) => {
if (scrollX !== event.currentTarget.scrollLeft)
setScrollX(event.currentTarget.scrollLeft);
}; };
const handleWheel = (event: React.WheelEvent<HTMLDivElement>) => { const handleWheel = (event: React.WheelEvent<HTMLDivElement>) => {
@ -72,28 +79,38 @@ export const Gantt: React.SFC<GanttProps> = ({
}; };
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => { const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
let newScrollY = 0; event.preventDefault();
let newScrollY = scrollY;
let newScrollX = scrollX;
let isX = true; let isX = true;
switch (event.key) { switch (event.key) {
case "Down": // IE/Edge specific value case "Down": // IE/Edge specific value
case "ArrowDown": case "ArrowDown":
newScrollY = scrollY + rowHeight; newScrollY += rowHeight;
isX = false; isX = false;
break; break;
case "Up": // IE/Edge specific value case "Up": // IE/Edge specific value
case "ArrowUp": case "ArrowUp":
newScrollY = scrollY - rowHeight; newScrollY -= rowHeight;
isX = false; isX = false;
break; break;
case "Left":
case "ArrowLeft": case "ArrowLeft":
// Do something for "left arrow" key press. newScrollX -= columnWidth;
break; break;
case "Right": // IE/Edge specific value case "Right": // IE/Edge specific value
case "ArrowRight": case "ArrowRight":
// Do something for "right arrow" key press. newScrollX += columnWidth;
break; break;
} }
if (isX) { if (isX) {
if (newScrollX < 0) {
setScrollX(0);
} else if (newScrollX > gridWidth) {
setScrollX(gridWidth);
} else {
setScrollX(newScrollX);
}
} else { } else {
if (newScrollY < 0) { if (newScrollY < 0) {
setScrollY(0); setScrollY(0);
@ -177,6 +194,8 @@ export const Gantt: React.SFC<GanttProps> = ({
barProps={barProps} barProps={barProps}
ganttHeight={ganttHeight} ganttHeight={ganttHeight}
scrollY={scrollY} scrollY={scrollY}
scrollX={scrollX}
onScroll={handleScrollX}
/> />
<Scroll <Scroll
ganttFullHeight={ganttFullHeight} ganttFullHeight={ganttFullHeight}

View File

@ -1,4 +1,4 @@
import React, { useRef, useEffect } from "react"; import React, { useRef, useEffect, SyntheticEvent } from "react";
import { GridProps, Grid } from "../grid/grid"; import { GridProps, Grid } from "../grid/grid";
import { CalendarProps, Calendar } from "../calendar/calendar"; import { CalendarProps, Calendar } from "../calendar/calendar";
import { TaskGanttContentProps, TaskGanttContent } from "./task-gantt-content"; import { TaskGanttContentProps, TaskGanttContent } from "./task-gantt-content";
@ -10,6 +10,8 @@ export type TaskGanttProps = {
barProps: TaskGanttContentProps; barProps: TaskGanttContentProps;
ganttHeight: number; ganttHeight: number;
scrollY: number; scrollY: number;
scrollX: number;
onScroll: (event: SyntheticEvent<HTMLDivElement>) => void;
}; };
export const TaskGantt: React.FC<TaskGanttProps> = ({ export const TaskGantt: React.FC<TaskGanttProps> = ({
gridProps, gridProps,
@ -17,9 +19,12 @@ export const TaskGantt: React.FC<TaskGanttProps> = ({
barProps, barProps,
ganttHeight, ganttHeight,
scrollY, scrollY,
scrollX,
onScroll,
}) => { }) => {
const ganttSVGRef = useRef<SVGSVGElement>(null); const ganttSVGRef = useRef<SVGSVGElement>(null);
const horizontalContainerRef = useRef<HTMLDivElement>(null); const horizontalContainerRef = useRef<HTMLDivElement>(null);
const verticalContainerRef = useRef<HTMLDivElement>(null);
const newBarProps = { ...barProps, svg: ganttSVGRef }; const newBarProps = { ...barProps, svg: ganttSVGRef };
useEffect(() => { useEffect(() => {
@ -28,8 +33,18 @@ export const TaskGantt: React.FC<TaskGanttProps> = ({
} }
}, [scrollY]); }, [scrollY]);
useEffect(() => {
if (verticalContainerRef.current) {
verticalContainerRef.current.scrollLeft = scrollX;
}
}, [scrollX]);
return ( return (
<div className={styles.ganttVerticalContainer}> <div
className={styles.ganttVerticalContainer}
ref={verticalContainerRef}
onScroll={onScroll}
>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width={gridProps.gridWidth} width={gridProps.gridWidth}