[TScroller, TVirtualGridList, AutoScrollArea] autofocus 로직 분리, 가독성 향상을 위한 리팩토링-수정
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import React, { useCallback } from "react";
|
||||
import React, { useCallback, useRef } from "react";
|
||||
|
||||
import classNames from "classnames";
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import { AUTO_SCROLL_GAP } from "../../utils/Config";
|
||||
import css from "./AutoScrollArea.module.less";
|
||||
|
||||
const AutoScrollComponent = Spottable("div");
|
||||
@@ -15,12 +16,92 @@ const POSITION = {
|
||||
bottom: "bottom",
|
||||
};
|
||||
|
||||
export default function AutoScrollArea({ position, onFocus, onBlur }) {
|
||||
export default function AutoScrollArea({
|
||||
position,
|
||||
autoScroll,
|
||||
scrollHorizontalPos,
|
||||
scrollVerticalPos,
|
||||
scrollToRef,
|
||||
scrollPosition,
|
||||
direction,
|
||||
}) {
|
||||
const requestIdRef = useRef();
|
||||
|
||||
const handleFocusAutoScroll = useCallback(() => {
|
||||
if (!autoScroll) return;
|
||||
|
||||
const scrollStep =
|
||||
position === "right" || position === "bottom"
|
||||
? AUTO_SCROLL_GAP
|
||||
: -AUTO_SCROLL_GAP;
|
||||
let start = null;
|
||||
|
||||
const animationScroll = (timestamp) => {
|
||||
if (!start) start = timestamp;
|
||||
const progress = timestamp - start;
|
||||
const step = Math.min(progress / 1000, 1);
|
||||
|
||||
if (direction === "horizontal") {
|
||||
scrollHorizontalPos.current += scrollStep * step;
|
||||
scrollToRef.current({
|
||||
position: { x: scrollHorizontalPos.current },
|
||||
animate: false,
|
||||
});
|
||||
} else if (direction === "vertical") {
|
||||
scrollVerticalPos.current += scrollStep * step;
|
||||
scrollToRef.current({
|
||||
position: { y: scrollVerticalPos.current },
|
||||
animate: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
direction === "horizontal" &&
|
||||
((position === "right" && scrollPosition.current === "right") ||
|
||||
(position === "left" && scrollPosition.current === "left"))
|
||||
) {
|
||||
if (typeof window === "object") {
|
||||
window.cancelAnimationFrame(requestIdRef.current);
|
||||
}
|
||||
} else if (
|
||||
direction === "vertical" &&
|
||||
((position === "bottom" && scrollPosition.current === "bottom") ||
|
||||
(position === "top" && scrollPosition.current === "top"))
|
||||
) {
|
||||
if (typeof window === "object") {
|
||||
window.cancelAnimationFrame(requestIdRef.current);
|
||||
}
|
||||
} else {
|
||||
if (typeof window === "object") {
|
||||
requestIdRef.current = window.requestAnimationFrame(animationScroll);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof window === "object") {
|
||||
requestIdRef.current = window.requestAnimationFrame(animationScroll);
|
||||
}
|
||||
}, [
|
||||
autoScroll,
|
||||
position,
|
||||
scrollHorizontalPos,
|
||||
scrollVerticalPos,
|
||||
scrollToRef,
|
||||
scrollPosition,
|
||||
direction,
|
||||
]);
|
||||
|
||||
const handleBlur = useCallback(() => {
|
||||
if (requestIdRef.current && typeof window === "object") {
|
||||
window.cancelAnimationFrame(requestIdRef.current);
|
||||
}
|
||||
}, [autoScroll, direction]);
|
||||
|
||||
return (
|
||||
<AutoScrollComponent
|
||||
className={classNames(css.autoScrollArea, position && css[position])}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
onFocus={handleFocusAutoScroll}
|
||||
onBlur={handleBlur}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import { useSelector } from "react-redux";
|
||||
|
||||
import { VirtualGridList } from "@enact/sandstone/VirtualList";
|
||||
|
||||
import { AUTO_SCROLL_GAP } from "../../utils/Config";
|
||||
import { scaleH, scaleW } from "../../utils/helperMethods";
|
||||
import AutoScrollArea, { POSITION } from "../AutoScrollArea/AutoScrollArea";
|
||||
import { getRelevantPositions } from "../TScroller/TScroller";
|
||||
import css from "./TVirtualGridList.module.less";
|
||||
|
||||
export default function TVirtualGridList({
|
||||
@@ -36,7 +36,6 @@ export default function TVirtualGridList({
|
||||
const scrollPosition = useRef("top");
|
||||
|
||||
const scrollToRef = useRef(null);
|
||||
const requestIdRef = useRef();
|
||||
const scrollHorizontalPos = useRef(0);
|
||||
const scrollVerticalPos = useRef(0);
|
||||
|
||||
@@ -92,62 +91,7 @@ export default function TVirtualGridList({
|
||||
[cbScrollTo]
|
||||
);
|
||||
|
||||
const handleFocusAutoScroll = useCallback((position) => {
|
||||
if (!autoScroll) return;
|
||||
|
||||
const scrollStep =
|
||||
position === POSITION.right || position === POSITION.bottom
|
||||
? AUTO_SCROLL_GAP
|
||||
: -AUTO_SCROLL_GAP;
|
||||
let start = null;
|
||||
|
||||
const animateScroll = (timestamp) => {
|
||||
if (!start) start = timestamp;
|
||||
const progress = timestamp - start;
|
||||
const step = Math.min(progress / 1000, 1);
|
||||
|
||||
if (direction === "horizontal") {
|
||||
scrollHorizontalPos.current += scrollStep * step;
|
||||
scrollToRef.current({
|
||||
position: { x: scrollHorizontalPos.current },
|
||||
animate: false,
|
||||
});
|
||||
} else if (direction === "vertical") {
|
||||
scrollVerticalPos.current += scrollStep * step;
|
||||
scrollToRef.current({
|
||||
position: { y: scrollVerticalPos.current },
|
||||
animate: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
direction === "horizontal" &&
|
||||
((position === POSITION.right && scrollPosition.current === "right") ||
|
||||
(position === POSITION.left && scrollPosition.current === "left"))
|
||||
) {
|
||||
window.cancelAnimationFrame(requestIdRef.current);
|
||||
} else if (
|
||||
direction === "vertical" &&
|
||||
((position === POSITION.bottom &&
|
||||
scrollPosition.current === "bottom") ||
|
||||
(position === POSITION.top && scrollPosition.current === "top"))
|
||||
) {
|
||||
window.cancelAnimationFrame(requestIdRef.current);
|
||||
} else {
|
||||
requestIdRef.current = window.requestAnimationFrame(animateScroll);
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof window === "object") {
|
||||
requestIdRef.current = window.requestAnimationFrame(animateScroll);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleBlur = useCallback(() => {
|
||||
if (requestIdRef.current && typeof window === "object") {
|
||||
window.cancelAnimationFrame(requestIdRef.current);
|
||||
}
|
||||
}, [autoScroll, direction]);
|
||||
const relevantPositions = getRelevantPositions(direction);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -176,34 +120,20 @@ export default function TVirtualGridList({
|
||||
spotlightId={spotlightId}
|
||||
{...rest}
|
||||
/>
|
||||
{direction === "horizontal" && cursorVisible && autoScroll && (
|
||||
<AutoScrollArea
|
||||
position={POSITION.left}
|
||||
onFocus={() => handleFocusAutoScroll(POSITION.left)}
|
||||
onBlur={handleBlur}
|
||||
/>
|
||||
)}
|
||||
{direction === "horizontal" && cursorVisible && autoScroll && (
|
||||
<AutoScrollArea
|
||||
position={POSITION.right}
|
||||
onFocus={() => handleFocusAutoScroll(POSITION.right)}
|
||||
onBlur={handleBlur}
|
||||
/>
|
||||
)}
|
||||
{direction === "vertical" && cursorVisible && autoScroll && (
|
||||
<AutoScrollArea
|
||||
position={POSITION.top}
|
||||
onFocus={() => handleFocusAutoScroll(POSITION.top)}
|
||||
onBlur={handleBlur}
|
||||
/>
|
||||
)}
|
||||
{direction === "vertical" && cursorVisible && autoScroll && (
|
||||
<AutoScrollArea
|
||||
position={POSITION.bottom}
|
||||
onFocus={() => handleFocusAutoScroll(POSITION.bottom)}
|
||||
onBlur={handleBlur}
|
||||
/>
|
||||
)}
|
||||
{cursorVisible &&
|
||||
autoScroll &&
|
||||
relevantPositions.map((pos) => (
|
||||
<AutoScrollArea
|
||||
key={pos}
|
||||
position={POSITION[pos]}
|
||||
autoScroll={autoScroll}
|
||||
scrollHorizontalPos={scrollHorizontalPos}
|
||||
scrollVerticalPos={scrollVerticalPos}
|
||||
scrollToRef={scrollToRef}
|
||||
scrollPosition={scrollPosition}
|
||||
direction={direction}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user