[FeaturedBrandsPanel] QuickMenu, component 변경
Detail Notes : 1. QuickMenu, Scroller → VirtualGridList 변경 2. QuickMenuItem 생성 및 css 수정
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import Spotlight from "@enact/spotlight";
|
||||
|
||||
import {
|
||||
getBrandLayoutInfo,
|
||||
getBrandLiveChannelInfo,
|
||||
} from "../../actions/brandActions";
|
||||
import TBody from "../../components/TBody/TBody";
|
||||
import TPanel from "../../components/TPanel/TPanel";
|
||||
import Banner from "./Banner/Banner";
|
||||
import css from "./FeaturedBrandsPanel.module.less";
|
||||
@@ -37,9 +40,16 @@ export default function FeaturedBrandsPanel() {
|
||||
// @@pyh Todo, provided by GNB as props or global state
|
||||
const [selectedPatnrId, setSelectedPatnrId] = useState("1");
|
||||
|
||||
const handleQuickMenu = (patnrId) => {
|
||||
setSelectedPatnrId(patnrId);
|
||||
};
|
||||
const handleQuickMenuClick = useCallback(
|
||||
(patnrId) => {
|
||||
if (selectedPatnrId === patnrId) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSelectedPatnrId(patnrId);
|
||||
},
|
||||
[selectedPatnrId]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (brandInfo) {
|
||||
@@ -50,32 +60,40 @@ export default function FeaturedBrandsPanel() {
|
||||
dispatch(getBrandLiveChannelInfo({ patnrId: selectedPatnrId }));
|
||||
}, [selectedPatnrId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedPatnrId) {
|
||||
Spotlight.focus("spotlight" + selectedPatnrId);
|
||||
}
|
||||
}, [selectedPatnrId]);
|
||||
|
||||
return (
|
||||
/* scenario page 98 */
|
||||
<TPanel className={css.container}>
|
||||
{brandInfo && brandInfo.length > 1 && (
|
||||
<QuickMenu
|
||||
brandInfo={brandInfo}
|
||||
onQuickMenuClick={handleQuickMenu}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
/>
|
||||
)}
|
||||
|
||||
{selectedBrandInfo && (
|
||||
<Banner
|
||||
selectedBrandInfo={selectedBrandInfo}
|
||||
brandTopImgInfo={brandTopImgInfo}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className={css.sectionContainer}>
|
||||
{brandChanInfo && (
|
||||
<LiveChannels
|
||||
brandChanInfo={brandChanInfo[0]}
|
||||
brandChannelCnt={brandChannelCnt}
|
||||
<TBody>
|
||||
{brandInfo && brandInfo.length > 1 && (
|
||||
<QuickMenu
|
||||
brandInfo={brandInfo}
|
||||
onQuickMenuClick={handleQuickMenuClick}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{selectedBrandInfo && brandTopImgInfo && (
|
||||
<Banner
|
||||
selectedBrandInfo={selectedBrandInfo}
|
||||
brandTopImgInfo={brandTopImgInfo}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className={css.sectionContainer}>
|
||||
{brandChanInfo && (
|
||||
<LiveChannels
|
||||
brandChanInfo={brandChanInfo[0]}
|
||||
brandChannelCnt={brandChannelCnt}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</TBody>
|
||||
</TPanel>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,64 +1,61 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
|
||||
import Spotlight from '@enact/spotlight';
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
import { VirtualGridList } from "@enact/sandstone/VirtualList";
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import ri from "@enact/ui/resolution";
|
||||
|
||||
import { $L } from '../../../utils/helperMethods';
|
||||
import css from './QuickMenu.module.less';
|
||||
import QuickMenuItem from "../QuickMenuItem/QuickMenuItem";
|
||||
import css from "./QuickMenu.module.less";
|
||||
|
||||
const LIST_ITEM_CONF = {
|
||||
ITEM_WIDTH: 138 * 2,
|
||||
ITEM_HEIGHT: 138 * 2,
|
||||
};
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"nav"
|
||||
);
|
||||
|
||||
const SpottableComponent = Spottable("li");
|
||||
|
||||
export default function QuickMenu({
|
||||
brandInfo,
|
||||
selectedPatnrId,
|
||||
onQuickMenuClick,
|
||||
...rest
|
||||
}) {
|
||||
const handleClick = (patnrId) => {
|
||||
if (selectedPatnrId === patnrId) {
|
||||
return;
|
||||
}
|
||||
|
||||
onQuickMenuClick(patnrId);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("@@ brandInfo", brandInfo);
|
||||
// @@pyh Todo, change to logic
|
||||
// const element = document.getElementById(selectedPatnrId);
|
||||
|
||||
Spotlight.focus("spotlight" + selectedPatnrId);
|
||||
}, []);
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
return (
|
||||
<QuickMenuItem
|
||||
brandInfo={brandInfo}
|
||||
index={index}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
onQuickMenuClick={onQuickMenuClick}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[brandInfo, selectedPatnrId, onQuickMenuClick]
|
||||
);
|
||||
|
||||
return (
|
||||
<Container {...rest} className={css.container}>
|
||||
<ul>
|
||||
{brandInfo &&
|
||||
brandInfo.map(({ logoImgAlt, logoImgPath, newFlag, patnrId }) => {
|
||||
return (
|
||||
<SpottableComponent
|
||||
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>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,66 +2,15 @@
|
||||
@import "../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex(@justifyCenter:flex start);
|
||||
.size(@w: 100%, @h: 180px);
|
||||
padding: 30px 60px;
|
||||
padding: 18px 60px;
|
||||
background-color: #e7e7e7;
|
||||
|
||||
ul {
|
||||
.flex(@justifyCenter: flex-start);
|
||||
gap: 18px;
|
||||
.virtualGridList {
|
||||
overflow: unset;
|
||||
|
||||
/* normal */
|
||||
li {
|
||||
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");
|
||||
}
|
||||
}
|
||||
> div {
|
||||
overflow: unset !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
});
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "QuickMenuItem.jsx",
|
||||
"styles": [
|
||||
"QuickMenuItem.module.less"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user