pagenator

This commit is contained in:
yonghyon
2024-06-03 22:52:15 +09:00
parent 76d1a813ee
commit 2aa04e489a
10 changed files with 241 additions and 200 deletions

View File

@@ -1,6 +1,6 @@
/** /**
* TVerticalPagenator * TVerticalPagenator
* * checking data-wheel-point and data-spotlight-id
* @module TVerticalPagenator * @module TVerticalPagenator
*/ */
@@ -13,35 +13,35 @@ import * as HelperMethods from "../../utils/helperMethods";
import usePrevious from '../../hooks/usePrevious'; import usePrevious from '../../hooks/usePrevious';
import Spotlight from '@enact/spotlight'; import Spotlight from '@enact/spotlight';
const DEBOUNCE_DELAY = 10;
const TVerticalPagenator = ({ const TVerticalPagenator = ({
className, className,
spotlightId, spotlightId,
defaultPageIndex=0, defaultContainerId=null,
enableFocusAction=true, enableFocusAction=true,
children, children,
disabled, disabled,
pageSpotIds = [], onScrollStatusChanged,
onPageChanged, onFocusedContainerId,
visible = "hidden", scrollbarVisible = "hidden",
scrollPositionRef,
cbChangePageRef, cbChangePageRef,
scrollTop=false,
topMargin=0, topMargin=0,
...rest ...rest
}) => { }) => {
const [pageIndex, setPageIndex] = useState(!defaultPageIndex ? 0: defaultPageIndex); const [_defaultContainerId,_] = useState(defaultContainerId);
const pagenatorRef = useRef(null); const pagenatorRef = useRef(null);
const pageIndexRef = usePrevious(pageIndex);
const isScrolling = useRef(false); const isScrolling = useRef(false);
const scrollTopPositionRef = useRef(0); const scrollTopPositionRef = useRef(-1);
const scrollTo = useRef(null); const scrollTo = useRef(null);
const cursorVisible = useSelector((state) => state.common.appStatus.cursorVisible); const cursorVisible = useSelector((state) => state.common.appStatus.cursorVisible);
const cursorVisibleRef = usePrevious(cursorVisible); const cursorVisibleRef = usePrevious(cursorVisible);
const disabledRef = usePrevious(disabled); const disabledRef = usePrevious(disabled);
const pageSpotIdsRef = usePrevious(pageSpotIds); const topMarginRef = usePrevious(topMargin);
const initialRenderedRef = useRef(false); const initialRenderedRef = useRef(false);
const lastScrollOffset = useRef(0); const onFocusedContainerIdRef = usePrevious(onFocusedContainerId);
const scrollStatus = useRef("top");
const lastEventTimeRef = useRef(0);
useEffect(() => { useEffect(() => {
if(spotlightId){ if(spotlightId){
@@ -49,6 +49,39 @@ const TVerticalPagenator = ({
} }
}, [spotlightId]); }, [spotlightId]);
const findCurrentWheelPoint = useCallback((node)=>{
if(pagenatorRef.current && pagenatorRef.current.contains(node)){
return node.closest('[data-wheel-point="true"]');
}else{
return null;
}
},[]);
const findNextWheelPoint = useCallback((ev)=>{
let matchedNode = null;
if(pagenatorRef.current){
const nodes = pagenatorRef.current.querySelectorAll(`[data-wheel-point="true"]`);
for(let i=0; i<nodes.length; i++){
if(scrollTopPositionRef.current < (nodes[i].offsetTop-topMarginRef.current)){
matchedNode = nodes[i];
break;
}
}
}
return matchedNode;
},[]);
const findPrevWheelPoint = useCallback((ev)=>{
let matchedNode = null;
if(pagenatorRef.current){
const nodes = pagenatorRef.current.querySelectorAll(`[data-wheel-point="true"]`);
for(let i=nodes.length-1; i>=0; i--){
if(scrollTopPositionRef.current > (nodes[i].offsetTop-topMarginRef.current)){
matchedNode = nodes[i];
break;
}
}
}
return matchedNode;
},[]);
const onFocusItem = useCallback((ev)=>{ const onFocusItem = useCallback((ev)=>{
if(!pagenatorRef.current){ if(!pagenatorRef.current){
return; return;
@@ -58,24 +91,33 @@ const TVerticalPagenator = ({
if (cursorVisibleRef.current) { if (cursorVisibleRef.current) {
return; return;
} }
pageSpotIds.forEach((element, index) => { const node = findCurrentWheelPoint(ev.target);
const pageNode = document.querySelector(`[data-spotlight-id="${element}"]`); if(node){
if(pageNode.contains(ev.target)) setTimeout(() => {
setPageIndex(index); moveToNode(node, true, false);
} }, 0);
); }
},[pageSpotIds]); },[moveToNode]);
const handleWheel = useCallback((ev) => { const handleWheel = useCallback((ev) => {
const now = Date.now();
if (now - lastEventTimeRef.current < DEBOUNCE_DELAY) {
// <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD> <20>̳<EFBFBD><CCB3><EFBFBD> <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>
return;
}
lastEventTimeRef.current = now;
if(pagenatorRef.current.contains(ev.target)){ if(pagenatorRef.current.contains(ev.target)){
ev.stopPropagation(); ev.stopPropagation();
if(disabledRef.current){ if(disabledRef.current){
return; return;
} }
let newIndex = ev.deltaY > 0 ? pageIndexRef.current+1: pageIndexRef.current -1; const node = ev.deltaY > 0 ? findNextWheelPoint():findPrevWheelPoint();
newIndex = Math.max(newIndex, 0); if(node){
newIndex = Math.min(newIndex, pageSpotIdsRef.current.length-1); setTimeout(() => {
setPageIndex(newIndex); moveToNode(node, true, true);
}, 0);
}
} }
}, []); }, []);
@@ -91,62 +133,90 @@ const TVerticalPagenator = ({
document.removeEventListener('wheel', handleWheel); document.removeEventListener('wheel', handleWheel);
}; };
}, []); }, []);
const moveToNode = useCallback((node, animate=true, focus=enableFocusAction)=>{
const moveToPage = useCallback((index=0, animate=true, focus=enableFocusAction)=>{ if(typeof node === 'string'){
if(pageSpotIds[index]){ node = pagenatorRef.current.querySelector(`[data-spotlight-id="${node}"]`);
const currentNode = document.querySelector( }
`[data-spotlight-id="${pageSpotIds[index]}"]` if(node){
); const distance = Math.round(node.offsetTop - HelperMethods.scaleH(topMarginRef.current));
if(currentNode){ const targetTop = distance >=0 ? distance:0;
const distance = Math.round(currentNode.offsetTop - HelperMethods.scaleH(topMargin)); const currentSpot = Spotlight.getCurrent();
const targetTop = distance >=0 ? distance:0; if(scrollTopPositionRef.current === targetTop){
scrollTo.current && scrollTo.current({ position:{x:0,y: targetTop}, animate: animate, focus: focus }); return;
if(focus){ }
Spotlight.focus(currentNode); scrollTopPositionRef.current = targetTop;
} scrollTo.current && scrollTo.current({ position:{x:0,y: targetTop}, animate: animate, focus: focus || !currentSpot, align: 'top' });
if(focus || !currentSpot){
Spotlight.focus(node);
}
if(onFocusedContainerIdRef.current){
onFocusedContainerIdRef.current(node.getAttribute('data-spotlight-id'));
} }
} }
if(onPageChanged){ },[enableFocusAction]);
onPageChanged(index);
}
},[topMargin, pageSpotIds, onPageChanged, enableFocusAction]);
useEffect(() => { useEffect(() => {
let node = _defaultContainerId;
// console.log('yhcho TVerticalPagenator _defaultContainerId changed ', _defaultContainerId);
if(!_defaultContainerId){
node = pagenatorRef.current.querySelector(`[data-wheel-point="true"]`); //to top
}
if(!initialRenderedRef.current){ if(!initialRenderedRef.current){
moveToPage(pageIndex, false); moveToNode(node, false);
setTimeout(() => { setTimeout(() => {
moveToPage(pageIndex, false); moveToNode(node, false);
}, 100); }, 100);
}else{ }else{
moveToPage(pageIndex, true); moveToNode(node, true);
} }
initialRenderedRef.current = true; initialRenderedRef.current = true;
}, [pageIndex]); }, [_defaultContainerId]);
useEffect(() => { useEffect(() => {
if(cbChangePageRef){ if(cbChangePageRef){
cbChangePageRef.current = (index, animate=false)=>{ cbChangePageRef.current = (_spotlightId, animate=false)=>{
moveToPage(index, animate); let node = null;
setPageIndex(index ? index : 0); if(!_spotlightId){ //to top
node = pagenatorRef.current.querySelector(`[data-wheel-point="true"]`);
}else{
node = pagenatorRef.current.querySelector(`[data-spotlight-id="${_spotlightId}"]`);
}
if(node){
setTimeout(() => {
moveToNode(node, animate);
}, 0);
}
}; };
} }
}, [cbChangePageRef, moveToPage]); }, [cbChangePageRef]);
const _onScrollStart = useCallback(() => { const _onScrollStart = useCallback(() => {
isScrolling.current = true; isScrolling.current = true;
}, []); }, []);
const _onScrollStop = useCallback(() => { const _onScrollStop = useCallback((ev) => {
isScrolling.current = false; isScrolling.current = false;
scrollTopPositionRef.current = ev.scrollTop;
}, []); }, []);
const _onScroll = useCallback((ev) => { const _onScroll = useCallback((ev) => {
isScrolling.current = true; isScrolling.current = true;
scrollTopPositionRef.current = ev.scrollTop; let prevScrollStatus = scrollStatus.current;
if(scrollPositionRef){ const scroller = pagenatorRef.current?.childNodes?.[0];
scrollPositionRef.current = ev.scrollTop; if(scroller){
if(ev.scrollTop <=0){
scrollStatus.current = "top";
}else if(ev.scrollTop + scroller.offsetHeight >= scroller.scrollHeight){
scrollStatus.current = "end";
}else{
scrollStatus.current = "middle";
}
} }
}, [scrollPositionRef]); if(prevScrollStatus !== scrollStatus.current && onScrollStatusChanged){
onScrollStatusChanged(scrollStatus.current);
}
}, [onScrollStatusChanged]);
if(!spotlightId){ if(!spotlightId){
console.warn('TVerticalPagenator has no spotlightId'); console.warn('TVerticalPagenator has no spotlightId');
return null; return null;
@@ -157,10 +227,10 @@ const TVerticalPagenator = ({
id={spotlightId} id={spotlightId}
spotlightId={spotlightId} spotlightId={spotlightId}
className={classNames(css.verticalPagenator, className)} className={classNames(css.verticalPagenator, className)}
focusableScrollbar={visible !== "hidden"} focusableScrollbar={scrollbarVisible !== "hidden"}
noScrollByWheel={true} noScrollByWheel={true}
noScrollByDrag={true} noScrollByDrag={true}
verticalScrollbar={visible} verticalScrollbar={scrollbarVisible}
onFocus={onFocusItem} onFocus={onFocusItem}
cbScrollTo={getScrollTo} cbScrollTo={getScrollTo}
onScroll={_onScroll} onScroll={_onScroll}

View File

@@ -113,7 +113,7 @@ const BestSeller = ({ order, scrollTopBody, spotlightId, handleItemFocus }) => {
}, [handleItemFocus]); }, [handleItemFocus]);
return ( return (
<Container className={css.bestSellerWrap} style={orderStyle} spotlightId={spotlightId}> <Container className={css.bestSellerWrap} style={orderStyle} spotlightId={spotlightId} data-wheel-point={true}>
<SectionTitle <SectionTitle
title={$L("BEST SELLER")} title={$L("BEST SELLER")}
data-title-index="homeBestSellerTitle" data-title-index="homeBestSellerTitle"

View File

@@ -193,7 +193,7 @@ export default function HomeBanner({
}, [handleItemFocus]); }, [handleItemFocus]);
return ( return (
<Container className={css.container} spotlightId={spotlightId} style={orderStyle}> <Container className={css.container} spotlightId={spotlightId} data-wheel-point={true} style={orderStyle} >
<div className={css.homeTemplateBox}> <div className={css.homeTemplateBox}>
<ContainerBasic <ContainerBasic
className={css.smallBox} className={css.smallBox}

View File

@@ -84,7 +84,7 @@ const HomeOnSale = ({ order, scrollTopBody, handleItemFocus,spotlightId, ...rest
}, [handleItemFocus]); }, [handleItemFocus]);
return ( return (
<Container {...rest} className={css.container} style={orderStyle} spotlightId={spotlightId}> <Container {...rest} className={css.container} style={orderStyle} spotlightId={spotlightId} data-wheel-point={true}>
<div className={css.onSaleWrap}> <div className={css.onSaleWrap}>
<SectionTitle <SectionTitle
className={css.subTitle} className={css.subTitle}

View File

@@ -51,11 +51,7 @@ export default function HomePanel({ isOnTop }) {
const { sendLogGNB } = useLogService(); const { sendLogGNB } = useLogService();
const dispatch = useDispatch(); const dispatch = useDispatch();
const [pageIndex, setPageIndex] = useState(0); const [btnDisabled, setBtnDisabled] = useState(true);
const pageIndexRef = usePrevious(pageIndex);
const spotYoffsetRef = useRef(0);
const cbChangePageRef = useRef(null);
const [btnActive, setBtnActive] = useState(true);
const [arrowBottom, setArrowBottom] = useState(true); const [arrowBottom, setArrowBottom] = useState(true);
useDebugKey({ isLandingPage: true }); useDebugKey({ isLandingPage: true });
@@ -94,7 +90,9 @@ export default function HomePanel({ isOnTop }) {
const webOSVersion = useSelector( const webOSVersion = useSelector(
(state) => state.common.appStatus.webOSVersion (state) => state.common.appStatus.webOSVersion
); );
const [focusedContainerId, setFocusedContainerId] = useState(homeSpotlight?.focusedContainerId);
const focusedContainerIdRef = usePrevious(focusedContainerId);
const cbChangePageRef = useRef(null);
const selectTemplate = useMemo(()=>{ const selectTemplate = useMemo(()=>{
if (homeTopDisplayInfos) { if (homeTopDisplayInfos) {
return homeTopDisplayInfos[0].shptmTmplCd; return homeTopDisplayInfos[0].shptmTmplCd;
@@ -155,7 +153,7 @@ export default function HomePanel({ isOnTop }) {
spotId = "banner03"; spotId = "banner03";
} }
if(cbChangePageRef.current){ if(cbChangePageRef.current){
cbChangePageRef.current(0); cbChangePageRef.current(0, true);
} }
return Spotlight.focus(spotId); return Spotlight.focus(spotId);
} }
@@ -207,37 +205,7 @@ export default function HomePanel({ isOnTop }) {
}, [dispatch, eventPopInfosData]); }, [dispatch, eventPopInfosData]);
useEffect(() => { useEffect(() => {
let timer;
if (homeSpotlight) {
if(cbChangePageRef.current){
cbChangePageRef.current(homeSpotlight.pageIndex);
}
timer = setTimeout(() => {
Spotlight.resume();
if(cbChangePageRef.current){ //call again after some seconds
cbChangePageRef.current(homeSpotlight.pageIndex);
}
if (homeSpotlight.currentCatCd) {
Spotlight.focus("spotlightId-" + homeSpotlight.currentCatCd);
}
if (homeSpotlight.currentSpot) {
Spotlight.focus(homeSpotlight.currentSpot);
}
setBtnActive(false);
setFirstSpot(true);
}, 300);
} else {
setBtnActive(false);
}
return () => { return () => {
clearTimeout(timer);
const c = Spotlight.getCurrent(); const c = Spotlight.getCurrent();
let targetSpotlightId = null; let targetSpotlightId = null;
let targetSpotlightCatcd = null; let targetSpotlightCatcd = null;
@@ -260,7 +228,7 @@ export default function HomePanel({ isOnTop }) {
currentSpot: currentSpot, currentSpot: currentSpot,
currentCatCd: targetSpotlightCatcd, currentCatCd: targetSpotlightCatcd,
currentCateName: targetSpotlightCateNm, currentCateName: targetSpotlightCateNm,
pageIndex: pageIndexRef.current, focusedContainerId: focusedContainerIdRef.current,
}, },
}) })
); );
@@ -273,40 +241,38 @@ export default function HomePanel({ isOnTop }) {
} }
}, [firstSpot]); }, [firstSpot]);
const doSendLogGNB = useCallback((index)=>{ const doSendLogGNB = useCallback((containerId)=>{
let nowMenu = null; let nowMenu = null;
if(pageSpotIds[index]){ switch(containerId){
switch(pageSpotIds[index]){ case TEMPLATE_CODE_CONF.TOP:
case TEMPLATE_CODE_CONF.TOP: nowMenu=LOG_MENU.HOME_TOP;
nowMenu=LOG_MENU.HOME_TOP; break;
break; case TEMPLATE_CODE_CONF.CATEGORY_ITEM:
case TEMPLATE_CODE_CONF.CATEGORY_ITEM: nowMenu=LOG_MENU.HOME_CATEGORY;
nowMenu=LOG_MENU.HOME_CATEGORY; break;
break; case TEMPLATE_CODE_CONF.ON_SALE:
case TEMPLATE_CODE_CONF.ON_SALE: nowMenu=LOG_MENU.HOME_ON_SALE;
nowMenu=LOG_MENU.HOME_ON_SALE; break;
break; case TEMPLATE_CODE_CONF.POPULAR_SHOW:
case TEMPLATE_CODE_CONF.POPULAR_SHOW: nowMenu=LOG_MENU.HOME_POPULAR_SHOWS;
nowMenu=LOG_MENU.HOME_POPULAR_SHOWS; break;
break; case TEMPLATE_CODE_CONF.BEST_SELLER:
case TEMPLATE_CODE_CONF.BEST_SELLER: nowMenu=LOG_MENU.HOME_BEST_SELLER;
nowMenu=LOG_MENU.HOME_BEST_SELLER; break;
break;
}
} }
if(nowMenu){ if(nowMenu){
sendLogGNB(nowMenu); sendLogGNB(nowMenu);
} }
},[pageSpotIds, sendLogGNB]); },[pageSpotIds, sendLogGNB]);
const handleItemFocus = useCallback((index)=> () => { const handleItemFocus = useCallback((containerId)=> () => {
doSendLogGNB(index); doSendLogGNB(containerId);
}, },
[doSendLogGNB] [doSendLogGNB]
); );
useEffect(() => { useEffect(() => {
doSendLogGNB(pageIndex); doSendLogGNB(focusedContainerId);
}, [pageIndex]); }, [focusedContainerId]);
const renderPageItem = useCallback(()=>{ const renderPageItem = useCallback(()=>{
return ( return (
@@ -322,7 +288,7 @@ export default function HomePanel({ isOnTop }) {
selectTemplate={selectTemplate} selectTemplate={selectTemplate}
firstSpot={firstSpot} firstSpot={firstSpot}
className={css.homeBannerWrap} className={css.homeBannerWrap}
handleItemFocus={handleItemFocus(idx)} handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
/> />
) )
} }
@@ -333,7 +299,7 @@ export default function HomePanel({ isOnTop }) {
spotlightId={el.shptmApphmDspyOptCd} spotlightId={el.shptmApphmDspyOptCd}
catCd={cateCd} catCd={cateCd}
cateNm={cateNm} cateNm={cateNm}
handleItemFocus={handleItemFocus(idx)} handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
/> />
) )
} }
@@ -342,7 +308,7 @@ export default function HomePanel({ isOnTop }) {
<HomeOnSale <HomeOnSale
key={el.shptmApphmDspyOptCd} key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd} spotlightId={el.shptmApphmDspyOptCd}
handleItemFocus={handleItemFocus(idx)} handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
/> />
) )
} }
@@ -351,7 +317,7 @@ export default function HomePanel({ isOnTop }) {
<PopularShow <PopularShow
key={el.shptmApphmDspyOptCd} key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd} spotlightId={el.shptmApphmDspyOptCd}
handleItemFocus={handleItemFocus(idx)} handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
/> />
) )
} }
@@ -360,7 +326,7 @@ export default function HomePanel({ isOnTop }) {
<BestSeller <BestSeller
key={el.shptmApphmDspyOptCd} key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd} spotlightId={el.shptmApphmDspyOptCd}
handleItemFocus={handleItemFocus(idx)} handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
/> />
) )
} }
@@ -373,21 +339,38 @@ export default function HomePanel({ isOnTop }) {
size={null} size={null}
type={TYPES.topButton} type={TYPES.topButton}
spotlightId={"home-top-btn"} spotlightId={"home-top-btn"}
spotlightDisabled={btnActive} spotlightDisabled={btnDisabled}
aria-label="Move to Top, Button" aria-label="Move to Top, Button"
/> />
</> </>
); );
},[sortedHomeLayoutInfo, selectTemplate, cateCd,cateNm, handleItemFocus, handleTopButtonClick, btnActive]); },[sortedHomeLayoutInfo, selectTemplate, cateCd,cateNm, handleItemFocus, handleTopButtonClick, btnDisabled]);
const onPageChanged = useCallback((index) => { const onScrollStatusChanged = useCallback((status) => {
if(pageSpotIds.length <=index+1){ if(status === 'end'){
setArrowBottom(false); setArrowBottom(false);
}else{ }else{
setArrowBottom(true); setArrowBottom(true);
} }
setPageIndex(index); }, []);
}, [pageSpotIds]); const onFocusedContainerId = useCallback((containerId) => {
setFocusedContainerId(containerId);
if (!firstSpot && homeSpotlight) {
setTimeout(() => {
Spotlight.resume();
setFirstSpot(true);
if (homeSpotlight.currentCatCd) {
Spotlight.focus("spotlightId-" + homeSpotlight.currentCatCd);
}
if (homeSpotlight?.currentSpot) {
Spotlight.focus(homeSpotlight.currentSpot);
}
setBtnDisabled(false);
}, 0);
} else if(!firstSpot){
setBtnDisabled(false);
}
}, [homeSpotlight, firstSpot]);
return ( return (
<> <>
@@ -401,11 +384,10 @@ export default function HomePanel({ isOnTop }) {
<TVerticalPagenator <TVerticalPagenator
className={css.tVerticalPagenator} className={css.tVerticalPagenator}
spotlightId={'home_verticalPagenator'} spotlightId={'home_verticalPagenator'}
defaultPageIndex={homeSpotlight?.pageIndex ?? 0} defaultContainerId={homeSpotlight?.focusedContainerId}
disabled={!isOnTop} disabled={!isOnTop}
pageSpotIds={pageSpotIds} onScrollStatusChanged={onScrollStatusChanged}
onPageChanged={onPageChanged} onFocusedContainerId={onFocusedContainerId}
scrollPositionRef={spotYoffsetRef}
cbChangePageRef={cbChangePageRef} cbChangePageRef={cbChangePageRef}
topMargin={36}> topMargin={36}>
{renderPageItem()} {renderPageItem()}

View File

@@ -13,7 +13,7 @@
} }
} }
.tButton { .tButton {
margin-top: 60px; margin-top: -20px;
} }
} }
.arrow { .arrow {

View File

@@ -125,7 +125,7 @@ const PopularShow = ({
}, [handleItemFocus]); }, [handleItemFocus]);
return ( return (
<Container className={css.popularShow} style={orderStyle} spotlightId={spotlightId}> <Container className={css.popularShow} style={orderStyle} spotlightId={spotlightId} data-wheel-point={true}>
<SectionTitle <SectionTitle
className={css.subTitle} className={css.subTitle}
title={$L("POPULAR SHOW")} title={$L("POPULAR SHOW")}

View File

@@ -28,7 +28,7 @@ import css from "../../HomePanel/SubCategory/SubCategory.module.less";
const SpottableComponent = Spottable("div"); const SpottableComponent = Spottable("div");
const Container = SpotlightContainerDecorator( const Container = SpotlightContainerDecorator(
{ {
enterTo: "last-focused", enterTo: null,
}, },
"div" "div"
); );
@@ -231,7 +231,7 @@ const SubCategory = ({
} }
}, [handleItemFocus]); }, [handleItemFocus]);
return ( return (
<Container style={orderStyle} spotlightId={spotlightId}> <Container style={orderStyle} spotlightId={spotlightId} data-wheel-point={true}>
<ContainerBasic> <ContainerBasic>
<CategoryNav <CategoryNav
categoryInfos={categoryInfos} categoryInfos={categoryInfos}

View File

@@ -20,7 +20,7 @@ export default memo(function OnSaleContents({
selectedLgCatCd, selectedLgCatCd,
}) { }) {
return ( return (
<Container className={css.container} spotlightId={spotlightId}> <Container className={css.container} spotlightId={spotlightId} data-wheel-point={true}>
<SectionTitle <SectionTitle
data-title-index={contentsIndex} data-title-index={contentsIndex}
title={saleNm} title={saleNm}

View File

@@ -61,7 +61,7 @@ export default function OnSalePanel({ panelInfo }) {
const previousPanelIsDetail = Object.keys(panelInfo).length > 4; const previousPanelIsDetail = Object.keys(panelInfo).length > 4;
const cbChangePageRef = useRef(null); const cbChangePageRef = useRef(null);
const pageIndexRef = useRef(0); const focusedContainerIdRef = useRef(0);
useEffect(() => { useEffect(() => {
sendLogGNB(LOG_MENU.ON_SALE); sendLogGNB(LOG_MENU.ON_SALE);
@@ -197,7 +197,7 @@ export default function OnSalePanel({ panelInfo }) {
isReadyForInitialFocusTarget, isReadyForInitialFocusTarget,
panelInfo, panelInfo,
previousPanelIsDetail, previousPanelIsDetail,
previousPanelIsHome, previousPanelIsHome
]); ]);
useEffect(() => { useEffect(() => {
@@ -277,7 +277,7 @@ export default function OnSalePanel({ panelInfo }) {
exprOrd, exprOrd,
lgCatCd, lgCatCd,
targetId, targetId,
pageIndex: pageIndexRef.current, focusedContainerId: focusedContainerIdRef.current,
}, },
}) })
); );
@@ -286,33 +286,22 @@ export default function OnSalePanel({ panelInfo }) {
}, [dispatch]); }, [dispatch]);
const handleTopButtonClick = useCallback(() => { const handleTopButtonClick = useCallback(() => {
if (cbChangePageRef.current) { if(cbChangePageRef.current){
if (!firstFocusableTarget) { cbChangePageRef.current(0, true);
cbChangePageRef.current(0, true);
return;
}
setIsTopButtonClicked(true);
setTimeout(() => {
Spotlight.focus(firstFocusableTarget);
setIsTopButtonClicked(false);
});
} }
if (!firstFocusableTarget) {
return;
}
setIsTopButtonClicked(true);
setTimeout(() => {
Spotlight.focus(firstFocusableTarget);
setIsTopButtonClicked(false);
});
}, [firstFocusableTarget]); }, [firstFocusableTarget]);
const pageSpotIds = useMemo(() => { const onFocusedContainerId = useCallback((containerId) => {
const spots = []; focusedContainerIdRef.current = containerId;
if (saleInfos) {
for (let i = 0; i < saleInfos.length; i++) {
spots.push("sale-info-" + i);
}
}
return spots;
}, [saleInfos]);
const onPageChanged = useCallback((index) => {
pageIndexRef.current = index;
}, []); }, []);
const onSaleNavClicked = useCallback((ev) => { const onSaleNavClicked = useCallback((ev) => {
@@ -339,40 +328,40 @@ export default function OnSalePanel({ panelInfo }) {
/> />
<TBody className={css.tBody} scrollable={false}> <TBody className={css.tBody} scrollable={false}>
{saleInfos && ( {saleInfos &&
<TVerticalPagenator <TVerticalPagenator
className={css.tVerticalPagenator} className={css.tVerticalPagenator}
spotlightId={"onSale_verticalPagenator"} spotlightId={'onSale_verticalPagenator'}
enableFocusAction={false} enableFocusAction={false}
defaultPageIndex={panelInfo?.pageIndex ?? 0} defaultContainerId={panelInfo?.focusedContainerId}
pageSpotIds={pageSpotIds} onFocusedContainerId={onFocusedContainerId}
onPageChanged={onPageChanged} cbChangePageRef={cbChangePageRef}
cbChangePageRef={cbChangePageRef} topMargin={36}>
topMargin={36} <>
> {saleInfos.map(
{saleInfos.map( ({ saleNm, saleProductInfos }, contentsIndex) => (
({ saleNm, saleProductInfos }, contentsIndex) => ( <OnSaleContents
<OnSaleContents contentsIndex={contentsIndex}
contentsIndex={contentsIndex} isTopButtonClicked={isTopButtonClicked}
isTopButtonClicked={isTopButtonClicked} key={"sale-info-" + contentsIndex}
key={"sale-info-" + contentsIndex} spotlightId={"sale-info-" + contentsIndex}
spotlightId={"sale-info-" + contentsIndex} saleNm={saleNm}
saleNm={saleNm} saleProductInfos={saleProductInfos}
saleProductInfos={saleProductInfos} selectedLgCatCd={selectedLgCatCd}
selectedLgCatCd={selectedLgCatCd} />
/> )
) )}
)} {saleInfos.length > 1 && (
{saleInfos.length > 1 && ( <TButton
<TButton onClick={handleTopButtonClick}
onClick={handleTopButtonClick} size={null}
size={null} type={TYPES.topButton}
type={TYPES.topButton} ariaLabel="Move to Top"
ariaLabel="Move to Top" />
/> )}
)} </>
</TVerticalPagenator> </TVerticalPagenator>
)} }
</TBody> </TBody>
</> </>
)} )}