[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 { 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(
|
||||||
setSelectedPatnrId(patnrId);
|
(patnrId) => {
|
||||||
};
|
if (selectedPatnrId === patnrId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedPatnrId(patnrId);
|
||||||
|
},
|
||||||
|
[selectedPatnrId]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (brandInfo) {
|
if (brandInfo) {
|
||||||
@@ -50,32 +60,40 @@ 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}>
|
||||||
{brandInfo && brandInfo.length > 1 && (
|
<TBody>
|
||||||
<QuickMenu
|
{brandInfo && brandInfo.length > 1 && (
|
||||||
brandInfo={brandInfo}
|
<QuickMenu
|
||||||
onQuickMenuClick={handleQuickMenu}
|
brandInfo={brandInfo}
|
||||||
selectedPatnrId={selectedPatnrId}
|
onQuickMenuClick={handleQuickMenuClick}
|
||||||
/>
|
selectedPatnrId={selectedPatnrId}
|
||||||
)}
|
|
||||||
|
|
||||||
{selectedBrandInfo && (
|
|
||||||
<Banner
|
|
||||||
selectedBrandInfo={selectedBrandInfo}
|
|
||||||
brandTopImgInfo={brandTopImgInfo}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className={css.sectionContainer}>
|
|
||||||
{brandChanInfo && (
|
|
||||||
<LiveChannels
|
|
||||||
brandChanInfo={brandChanInfo[0]}
|
|
||||||
brandChannelCnt={brandChannelCnt}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
|
{selectedBrandInfo && brandTopImgInfo && (
|
||||||
|
<Banner
|
||||||
|
selectedBrandInfo={selectedBrandInfo}
|
||||||
|
brandTopImgInfo={brandTopImgInfo}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={css.sectionContainer}>
|
||||||
|
{brandChanInfo && (
|
||||||
|
<LiveChannels
|
||||||
|
brandChanInfo={brandChanInfo[0]}
|
||||||
|
brandChannelCnt={brandChannelCnt}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</TBody>
|
||||||
</TPanel>
|
</TPanel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
return (
|
||||||
}
|
<QuickMenuItem
|
||||||
|
brandInfo={brandInfo}
|
||||||
onQuickMenuClick(patnrId);
|
index={index}
|
||||||
};
|
selectedPatnrId={selectedPatnrId}
|
||||||
|
onQuickMenuClick={onQuickMenuClick}
|
||||||
useEffect(() => {
|
{...rest}
|
||||||
console.log("@@ brandInfo", brandInfo);
|
/>
|
||||||
// @@pyh Todo, change to logic
|
);
|
||||||
// const element = document.getElementById(selectedPatnrId);
|
},
|
||||||
|
[brandInfo, selectedPatnrId, onQuickMenuClick]
|
||||||
Spotlight.focus("spotlight" + selectedPatnrId);
|
);
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container {...rest} className={css.container}>
|
<Container className={css.container} {...rest}>
|
||||||
<ul>
|
{brandInfo && (
|
||||||
{brandInfo &&
|
<VirtualGridList
|
||||||
brandInfo.map(({ logoImgAlt, logoImgPath, newFlag, patnrId }) => {
|
className={css.virtualGridList}
|
||||||
return (
|
dataSize={brandInfo.length}
|
||||||
<SpottableComponent
|
direction="horizontal"
|
||||||
className={patnrId === selectedPatnrId && css.selected}
|
horizontalScrollbar="hidden"
|
||||||
id={patnrId}
|
itemRenderer={renderItem}
|
||||||
key={patnrId}
|
itemSize={{
|
||||||
onClick={() => handleClick(patnrId)}
|
minWidth: ri.scale(LIST_ITEM_CONF.ITEM_WIDTH),
|
||||||
spotlightId={"spotlight" + patnrId}
|
minHeight: ri.scale(LIST_ITEM_CONF.ITEM_HEIGHT),
|
||||||
>
|
}}
|
||||||
{newFlag === "Y" && (
|
noScrollByWheel
|
||||||
<span className={css.newBagde}>{$L("NEW")}</span>
|
scrollMode="translate"
|
||||||
)}
|
// spacing={ri.scale(LIST_ITEM_CONF.SAPCING)}
|
||||||
<span className={css.outline} />
|
/>
|
||||||
<img src={logoImgPath} alt={logoImgAlt} />
|
)}
|
||||||
</SpottableComponent>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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