[FeaturedBrandsPanel] QuickMenu, component 변경

Detail Notes :

1. QuickMenu, Scroller → VirtualGridList 변경
2. QuickMenuItem 생성 및 css 수정
This commit is contained in:
younghoon100.park
2024-02-06 14:43:40 +09:00
parent 5110ad9049
commit 2f1b2606df
6 changed files with 214 additions and 126 deletions

View File

@@ -1,11 +1,14 @@
import React, { useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import Spotlight from "@enact/spotlight";
import { import {
getBrandLayoutInfo, getBrandLayoutInfo,
getBrandLiveChannelInfo, getBrandLiveChannelInfo,
} from "../../actions/brandActions"; } from "../../actions/brandActions";
import TBody from "../../components/TBody/TBody";
import TPanel from "../../components/TPanel/TPanel"; import TPanel from "../../components/TPanel/TPanel";
import Banner from "./Banner/Banner"; import Banner from "./Banner/Banner";
import css from "./FeaturedBrandsPanel.module.less"; import css from "./FeaturedBrandsPanel.module.less";
@@ -37,9 +40,16 @@ export default function FeaturedBrandsPanel() {
// @@pyh Todo, provided by GNB as props or global state // @@pyh Todo, provided by GNB as props or global state
const [selectedPatnrId, setSelectedPatnrId] = useState("1"); const [selectedPatnrId, setSelectedPatnrId] = useState("1");
const handleQuickMenu = (patnrId) => { const handleQuickMenuClick = useCallback(
(patnrId) => {
if (selectedPatnrId === patnrId) {
return;
}
setSelectedPatnrId(patnrId); setSelectedPatnrId(patnrId);
}; },
[selectedPatnrId]
);
useEffect(() => { useEffect(() => {
if (brandInfo) { if (brandInfo) {
@@ -50,18 +60,25 @@ export default function FeaturedBrandsPanel() {
dispatch(getBrandLiveChannelInfo({ patnrId: selectedPatnrId })); dispatch(getBrandLiveChannelInfo({ patnrId: selectedPatnrId }));
}, [selectedPatnrId]); }, [selectedPatnrId]);
useEffect(() => {
if (selectedPatnrId) {
Spotlight.focus("spotlight" + selectedPatnrId);
}
}, [selectedPatnrId]);
return ( return (
/* scenario page 98 */ /* scenario page 98 */
<TPanel className={css.container}> <TPanel className={css.container}>
<TBody>
{brandInfo && brandInfo.length > 1 && ( {brandInfo && brandInfo.length > 1 && (
<QuickMenu <QuickMenu
brandInfo={brandInfo} brandInfo={brandInfo}
onQuickMenuClick={handleQuickMenu} onQuickMenuClick={handleQuickMenuClick}
selectedPatnrId={selectedPatnrId} selectedPatnrId={selectedPatnrId}
/> />
)} )}
{selectedBrandInfo && ( {selectedBrandInfo && brandTopImgInfo && (
<Banner <Banner
selectedBrandInfo={selectedBrandInfo} selectedBrandInfo={selectedBrandInfo}
brandTopImgInfo={brandTopImgInfo} brandTopImgInfo={brandTopImgInfo}
@@ -76,6 +93,7 @@ export default function FeaturedBrandsPanel() {
/> />
)} )}
</div> </div>
</TBody>
</TPanel> </TPanel>
); );
} }

View File

@@ -1,64 +1,61 @@
import React, { useEffect } from 'react'; import React, { useCallback, useEffect } from "react";
import Spotlight from '@enact/spotlight'; import { VirtualGridList } from "@enact/sandstone/VirtualList";
import SpotlightContainerDecorator import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
from '@enact/spotlight/SpotlightContainerDecorator'; import ri from "@enact/ui/resolution";
import Spottable from '@enact/spotlight/Spottable';
import { $L } from '../../../utils/helperMethods'; import QuickMenuItem from "../QuickMenuItem/QuickMenuItem";
import css from './QuickMenu.module.less'; import css from "./QuickMenu.module.less";
const LIST_ITEM_CONF = {
ITEM_WIDTH: 138 * 2,
ITEM_HEIGHT: 138 * 2,
};
const Container = SpotlightContainerDecorator( const Container = SpotlightContainerDecorator(
{ leaveFor: { right: "" }, enterTo: "last-focused" }, { leaveFor: { right: "" }, enterTo: "last-focused" },
"nav" "nav"
); );
const SpottableComponent = Spottable("li");
export default function QuickMenu({ export default function QuickMenu({
brandInfo, brandInfo,
selectedPatnrId, selectedPatnrId,
onQuickMenuClick, onQuickMenuClick,
...rest ...rest
}) { }) {
const handleClick = (patnrId) => { const renderItem = useCallback(
if (selectedPatnrId === patnrId) { ({ index, ...rest }) => {
return;
}
onQuickMenuClick(patnrId);
};
useEffect(() => {
console.log("@@ brandInfo", brandInfo);
// @@pyh Todo, change to logic
// const element = document.getElementById(selectedPatnrId);
Spotlight.focus("spotlight" + selectedPatnrId);
}, []);
return ( return (
<Container {...rest} className={css.container}> <QuickMenuItem
<ul> brandInfo={brandInfo}
{brandInfo && index={index}
brandInfo.map(({ logoImgAlt, logoImgPath, newFlag, patnrId }) => { selectedPatnrId={selectedPatnrId}
return ( onQuickMenuClick={onQuickMenuClick}
<SpottableComponent {...rest}
className={patnrId === selectedPatnrId && css.selected} />
id={patnrId}
key={patnrId}
onClick={() => handleClick(patnrId)}
spotlightId={"spotlight" + patnrId}
>
{newFlag === "Y" && (
<span className={css.newBagde}>{$L("NEW")}</span>
)}
<span className={css.outline} />
<img src={logoImgPath} alt={logoImgAlt} />
</SpottableComponent>
); );
})} },
</ul> [brandInfo, selectedPatnrId, onQuickMenuClick]
);
return (
<Container className={css.container} {...rest}>
{brandInfo && (
<VirtualGridList
className={css.virtualGridList}
dataSize={brandInfo.length}
direction="horizontal"
horizontalScrollbar="hidden"
itemRenderer={renderItem}
itemSize={{
minWidth: ri.scale(LIST_ITEM_CONF.ITEM_WIDTH),
minHeight: ri.scale(LIST_ITEM_CONF.ITEM_HEIGHT),
}}
noScrollByWheel
scrollMode="translate"
// spacing={ri.scale(LIST_ITEM_CONF.SAPCING)}
/>
)}
</Container> </Container>
); );
} }

View File

@@ -2,66 +2,15 @@
@import "../../../style/utils.module.less"; @import "../../../style/utils.module.less";
.container { .container {
.flex(@justifyCenter:flex start);
.size(@w: 100%, @h: 180px); .size(@w: 100%, @h: 180px);
padding: 30px 60px; padding: 18px 60px;
background-color: #e7e7e7; background-color: #e7e7e7;
ul { .virtualGridList {
.flex(@justifyCenter: flex-start); overflow: unset;
gap: 18px;
/* normal */ > div {
li { overflow: unset !important;
position: relative;
.newBagde {
.position(@position: absolute, @top: 0, @right: 0, @bottom: auto, @left: auto);
z-index: 10;
.size(@w: 60px, @h: 30px);
background-color: #f00;
color: #fff;
border-radius: 6px;
font-family: Arial;
font-weight: 600;
font-size: 18px;
text-align: center;
}
.outline {
.position(@position: absolute, @top: 0, @right: auto, @bottom: auto, @left: 0);
.size(@w: 138px, @h:138px);
background-position: center;
background-size: cover;
}
img {
.size(@w: 120px, @h: 120px);
}
/* focused */
&:focus {
border-radius: 60px;
.focusDropShadow();
.outline {
background-image: url("../../../../assets/images/partners/ic-tab-partners-focus@3x.png");
}
img {
.size(@w: 138px, @h: 138px);
}
}
/* selected */
&.selected {
img {
.size(@w: 138px, @h: 138px);
}
.outline {
background-image: url("../../../../assets/images/partners/ic-tab-partners-selected@3x.png");
}
}
} }
} }
} }

View File

@@ -0,0 +1,45 @@
import React, { memo, useCallback } from "react";
import classNames from "classnames";
import Spottable from "@enact/spotlight/Spottable";
import { $L } from "../../../utils/helperMethods";
import css from "./QuickMenuItem.module.less";
const SpottableComponent = Spottable("div");
export default memo(function QuickMenuItem({
brandInfo,
index,
onQuickMenuClick,
selectedPatnrId,
...rest
}) {
const { logoImgAlt, logoImgPath, newFlag, patnrId } = brandInfo[index];
const handleClick = useCallback(
(patnrId) => {
onQuickMenuClick && onQuickMenuClick(patnrId);
},
[selectedPatnrId]
);
return (
<SpottableComponent
className={classNames(
css.item,
patnrId === selectedPatnrId && css.selected
)}
id={patnrId}
key={patnrId}
onClick={() => handleClick(patnrId)}
{...rest}
spotlightId={"spotlight" + patnrId}
>
<img src={logoImgPath} alt={logoImgAlt} />
{newFlag === "Y" && <div>{$L("NEW")}</div>}
<span />
</SpottableComponent>
);
});

View File

@@ -0,0 +1,73 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.item {
/* normal */
position: relative;
.size(@w: 138px, @h: 138px);
.flex();
// partner logo
img {
.size(@w: 120px, @h: 120px);
}
// newBadge
> div {
.position(@position: absolute, @top: 0, @right: 18px);
z-index: 10;
.size(@w: 60px, @h: 30px);
border-radius: 6px;
background-color: #f00;
.font(@fontFamily: @arialFontBold, @fontSize: 18px);
color: @COLOR_WHITE;
text-align: center;
}
// outline
> span {
.position(@position: absolute, @top: 0, @right: 0, @bottom: 0, @left: 0);
.size(@w: 138px, @h:138px);
background-position: center;
background-size: cover;
}
/* focused */
&:focus-within {
border-radius: 100%;
.focusDropShadow();
// partner logo
img {
.size(@w: 138px, @h: 138px);
}
// newBadge
> div {
right: 0;
}
// outline
> span {
background-image: url("../../../../assets/images/partners/ic-tab-partners-focus@3x.png");
}
}
/* selected */
&.selected {
// partner logo
img {
.size(@w: 138px, @h: 138px);
}
// newBadge
> div {
right: 0;
}
// outline
> span {
background-image: url("../../../../assets/images/partners/ic-tab-partners-selected@3x.png");
}
}
}

View File

@@ -0,0 +1,6 @@
{
"main": "QuickMenuItem.jsx",
"styles": [
"QuickMenuItem.module.less"
]
}