merge from feature/gnb, TODO: tabLayout 구현

This commit is contained in:
hyunwoo93.cha
2024-01-25 21:24:04 +09:00
parent c919e0b130
commit cdd6a774b6
6 changed files with 229 additions and 87 deletions

View File

@@ -1,3 +1,4 @@
import { Job } from "@enact/core/util";
import { Marquee, MarqueeController } from "@enact/sandstone/Marquee";
import Spottable from "@enact/spotlight/Spottable";
import { getTargetByDirectionFromElement } from "@enact/spotlight/src/target";
@@ -13,13 +14,36 @@ const TabItemBase = ({
expanded = false,
selected = false,
index = 0,
target,
panel,
deActivateTab,
className,
onClick,
...rest
}) => {
const [focused, setFocused] = useState(false);
const itemRef = useRef();
const clearPressedJob = useRef(
new Job((func) => {
// setPressed(false);
setTimeout(func, 100);
}, 100)
);
const _onClick = useCallback(
(ev) => {
// if(ev?.target?.nodeName === 'IMG'){
// return;
// }
clearPressedJob.current.start(() => {
if (onClick) {
onClick({ index, target });
}
});
onClick({ index, target });
},
[target, index, onClick]
);
const _onFocus = useCallback(() => {
setFocused(true);
}, [index]);
@@ -64,6 +88,7 @@ const TabItemBase = ({
onKeyDown={onKeyDown}
onFocus={_onFocus}
onBlur={_onBlur}
onClick={_onClick}
spotlightDisabled={isDivider}
>
{icons && <div className={css.icon}>{renderIcon()}</div>}

View File

@@ -8,7 +8,7 @@
&.focused {
color: #ffffff;
color: #eee;
background: linear-gradient(#cb1253, #e15ba1);
border-radius: 42px;
width: 402px;

View File

@@ -9,13 +9,16 @@ import React, {
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
//아이콘
import { Job } from "@enact/core/util";
import { panel_names } from "../../utils/Config";
import TabItem from "./TabItem";
import css from "./TabLayout.module.less";
//enact
import Skinnable from "@enact/sandstone/Skinnable";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import { Cancelable } from "@enact/ui/Cancelable";
//아이콘
import { Job } from "@enact/core/util";
//이미지
import shoptimeFullIcon from "../../../assets/icons/ic-lnb-logo-shoptime@3x.png";
@@ -29,9 +32,9 @@ import MyPageIcon from "./iconComponents/MyPageIcon";
import OnSaleIcon from "./iconComponents/OnSaleIcon";
import SearchIcon from "./iconComponents/SearchIcon";
import TrendingNowIcon from "./iconComponents/TrendingNowIcon";
import TabItem from "./TabItem";
import css from "./TabLayout.module.less";
import { panel_names } from "../../utils/Config";
//이미지
import { resetPanels } from "../../features/panels/panelsSlice";
const Container = SpotlightContainerDecorator(
{ enterTo: "default-element" },
@@ -84,6 +87,9 @@ const ACTIVATED_MAIN = 1;
const ACTIVATED_SUB = 2;
const EXTRA_AREA = 3;
const MAIN_TITLE = 0;
const SUB_TITLE = 1;
const PANELS_HAS_TAB = [
panel_names.CART_PANEL,
panel_names.CATEGORY_PANEL,
@@ -104,91 +110,149 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
const [tabFocused, setTabFocused] = useState([false, false, false]); //COLLABSED_MAIN, ACTIVATED_MAIN, ACTIVATED_SUB
const panelSwitching = useRef(null);
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const titles = useSelector((state) => state.home.menuData);
console.log("titles", titles);
// const items = useSelector((state) => state.menu.items);
const data = useSelector((state) => state.home.menuData?.data);
const menuItems = useMemo(
() => [
{
title: titles[1],
icons: CategoryIcon,
children: [
{
title: "123123",
target: [],
},
],
},
{
title: titles[0],
icons: MyPageIcon,
children: [
{
title: "123123",
target: [],
},
],
},
{
title: titles[2],
icons: SearchIcon,
children: [
{
title: "12323232",
target: [],
},
],
},
{
title: titles[3],
icons: HomeIcon,
children: [
{
title: "43534543",
target: [],
},
],
},
{
title: titles[8],
icons: FeaturedBrandIcon,
children: [
{
title: "dsadasd",
target: [],
},
],
},
{
title: titles[4],
icons: OnSaleIcon,
title: "",
children: [
{
title: "",
target: [],
target: [{ name: panel_names.CATEGORY_PANEL }],
},
],
},
{
icons: MyPageIcon,
title: "",
children: [
{
title: "",
target: [{ name: panel_names.MY_PAGE_PANEL }],
},
],
},
{
icons: SearchIcon,
title: "",
children: [
{
title: "12323232",
target: [{ name: panel_names.SEARCH_PANEL }],
},
],
},
{
icons: HomeIcon,
title: "",
children: [
{
title: "43534543",
target: [{ name: panel_names.HOME_PANEL }],
},
],
},
{
icons: FeaturedBrandIcon,
title: "",
children: [
{
title: "dsadasd",
target: [{ name: panel_names.FEATURED_BRANDS_PANEL }],
},
],
},
{
icons: OnSaleIcon,
title: "",
children: [
{
title: "",
target: [{ name: panel_names.ON_SALE_PANEL }],
},
],
},
{
title: titles[5],
icons: TrendingNowIcon,
title: "",
children: [
{
title: "",
target: [{ name: panel_names.TRENDING_NOW_PANEL }],
},
],
},
{
title: titles[6],
icons: HotPicksIcon,
title: "",
children: [
{
title: "",
target: [{ name: panel_names.HOT_PICKS_PANEL }],
},
],
},
{
title: titles[7],
icons: CartIcon,
title: "",
children: [
{
title: "",
target: [{ name: panel_names.CART_PANEL }],
},
],
},
// 메뉴 추가 필요 20240112 chw
//메뉴 추가 필요 20240112 chw
],
[mainExpanded]
[data]
);
const getMenuData = (type) => {
let result = [];
switch (type) {
case "gnb":
data?.gnb.map((item) => {
result.push(item.menuNm);
});
console.log("#result", result);
return result;
case "homeCategory":
return "123123";
case "msgInfos":
return result;
case "mypage":
return result;
case "shortCategory":
return result;
case "shortFeaturedBrands":
return result;
}
};
const dataDivide = () => {
if (data) {
// console.log("data", data);
// Object.keys(data).map((key) => {
// title = getMenuData(key);
// return title;
// });
const title = getMenuData("gnb");
// const subTitle = getMenuData(menu);
for (let i = 0; i < menuItems.length; i++) {
menuItems[i].title = title[i];
menuItems[i].children.title = title[i];
}
}
console.log("#menuItems", menuItems);
return menuItems;
};
const makeTabmenu = useCallback(() => {
const t = [];
@@ -203,11 +267,12 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
}
return t;
}, []);
}, [data]);
useEffect(() => {
dataDivide();
setTabs(makeTabmenu());
}, []);
}, [data]);
const deActivateTab = useCallback(() => {
setTabFocused([false, false, false, false]);
@@ -220,7 +285,6 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
switch (type) {
case COLLABSED_MAIN:
case ACTIVATED_MAIN: {
console.log("#tabs[mainSelectedIndex]", tabs[mainSelectedIndex]);
if (!cursorVisible) {
const parent = event.target.parentNode;
const children = parent.childNodes;
@@ -288,22 +352,23 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
const handleNavigation = useCallback(
({ index, target }) => {
console.log(index, target);
setMainSelectedIndex(index);
if (target) {
// dispatch(resetPanels(target));
dispatch(resetPanels(target));
deActivateTab();
// panelSwitching.current = true;
// panelSwitchingJob.start(panelSwitching);
} else if (cursorVisible) {
setMainExpanded(true);
}
},
[cursorVisible, deActivateTab, dispatch]
[deActivateTab, dispatch]
);
const onClickSubItem = useCallback(
({ index, target }) => {
if (target) {
// dispatch(resetPanels(target));
dispatch(resetPanels(target));
deActivateTab();
panelSwitching.current = true;
// panelSwitchingJob.start(panelSwitching);
@@ -370,7 +435,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
}
return (
<>
<div className={css.tabLayoutWrap}>
{/* collabsed Main */}
<Container
className={css.tabWrap}
@@ -409,11 +474,13 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
onBlur={onTabBlur(ACTIVATED_MAIN)}
onMouseLeave={onTabBlur(ACTIVATED_MAIN)}
>
<h1 className={classNames(css.logo, mainExpanded && css.expanded)}>
<img
className={classNames(css.logo, mainExpanded && css.expanded)}
src={mainExpanded ? shoptimeFullIcon : shopTimeIcon}
alt=""
/>
</h1>
{tabActivated &&
tabs.map((item, index) => (
<TabItem
@@ -448,7 +515,6 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
<TabItem
key={"tabitemSubmenu" + index}
onClick={onClickSubItem}
{...item}
expanded={true}
index={index}
isSubItem={true}
@@ -473,6 +539,6 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
)}
</CancelableDiv>
}
</>
</div>
);
}

View File

@@ -1,3 +1,11 @@
.tabLayoutWrap{
width:100%;
height:100%;
position:absolute;
left:0;
top:0;
display:flex;
}
.expandedRootContainer {
position: absolute;
display: flex;
@@ -14,8 +22,11 @@
}
.tabWrap {
width: 120px;height:100%;
//position:fixed;
left:0;
top:0;
background-color: #222222;
width: 120px;
display: flex;
flex-direction: column;
@@ -36,6 +47,7 @@
box-shadow: 8px 0 36px rgba(33, 33, 32, 0.08);
padding-bottom: unset;
justify-content: flex-start;
left:402px;
}
&.extraArea {
flex-grow: 1;
@@ -50,13 +62,21 @@
.logo {
width: 54px;
height: 54px;
margin-left: 42px;
margin-bottom: 84px;
margin:0 0 84px 42px;
transition: width 0.5s ease;
overflow:hidden;
&.expanded {
width: 234px;
height: 54px;
> img{
width:234px;
height:54px;
}
}
> img{
width:54px;
height:54px;
}
}

View File

@@ -73,6 +73,7 @@ export const homeSlice = createSlice({
state.termsData = action.payload;
},
updateMenuData: (state, action) => {
//임시코드
state.menuData = action.payload;
},
},

View File

@@ -1,4 +1,6 @@
import Panels from "@enact/sandstone/Panels";
import platform from "@enact/core/platform";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { addPanels, popPanel } from "../../features/panels/panelsSlice";
@@ -69,7 +71,7 @@ export default function MainView() {
return (
<Component
{...panel.panelInfo}
panelInfo={panel.panelInfo}
spotlightId={panel.name}
isTabActivated={tabActivated}
/>
@@ -110,6 +112,34 @@ export default function MainView() {
}
}, [showLoadingPanel.show, isTermAgreed, dispatch]);
const cursorStateChange = useCallback(
(ev) => {
dispatch(
changeAppStatus({
cursorVisible: ev.visibility || ev.detail.visibility,
})
);
},
[dispatch]
);
useEffect(() => {
document.addEventListener("cursorStateChange", cursorStateChange, false);
if (platform.platformName !== "webos") {
//for debug
dispatch(changeAppStatus({ cursorVisible: !platform.touchscreen }));
} else {
dispatch(
changeAppStatus({
cursorVisible: window.cursorEvent && window.cursorEvent.visibility,
})
);
}
return () => {
document.removeEventListener("cursorStateChange", cursorStateChange);
};
}, []);
return (
<>
<PreloadImage