diff --git a/com.twin.app.shoptime/assets/icons/ic-category-accessories-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-accessories-nor.png new file mode 100644 index 00000000..699751ce Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-accessories-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-beauty-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-beauty-nor.png new file mode 100644 index 00000000..030e0610 Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-beauty-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-clearance-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-clearance-nor.png new file mode 100644 index 00000000..616e2c7c Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-clearance-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-cw-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-cw-nor.png new file mode 100644 index 00000000..d6f53de1 Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-cw-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-electronics-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-electronics-nor.png new file mode 100644 index 00000000..d321c92f Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-electronics-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-enter-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-enter-nor.png new file mode 100644 index 00000000..14d9ae51 Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-enter-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-fashion-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-fashion-nor.png new file mode 100644 index 00000000..6cbfcf0f Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-fashion-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-garden-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-garden-nor.png new file mode 100644 index 00000000..6172825a Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-garden-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-health-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-health-nor.png new file mode 100644 index 00000000..8d52126c Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-health-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-home-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-home-nor.png new file mode 100644 index 00000000..4e59f70d Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-home-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-jewelry-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-jewelry-nor.png new file mode 100644 index 00000000..f60bdce2 Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-jewelry-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-category-kitchen-nor.png b/com.twin.app.shoptime/assets/icons/ic-category-kitchen-nor.png new file mode 100644 index 00000000..a07a5071 Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-category-kitchen-nor.png differ diff --git a/com.twin.app.shoptime/assets/icons/ic-lnb-right-arrow.png b/com.twin.app.shoptime/assets/icons/ic-lnb-right-arrow.png new file mode 100644 index 00000000..2670ad1e Binary files /dev/null and b/com.twin.app.shoptime/assets/icons/ic-lnb-right-arrow.png differ diff --git a/com.twin.app.shoptime/src/components/TabLayout/TabItem.jsx b/com.twin.app.shoptime/src/components/TabLayout/TabItem.jsx index 7bc3ad7d..951731ba 100644 --- a/com.twin.app.shoptime/src/components/TabLayout/TabItem.jsx +++ b/com.twin.app.shoptime/src/components/TabLayout/TabItem.jsx @@ -1,10 +1,13 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; + +import classNames from "classnames"; +import compose from "ramda/src/compose"; + 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"; -import classNames from "classnames"; -import compose from "ramda/src/compose"; -import { useCallback, useMemo, useRef, useState } from "react"; + import css from "./TabItem.module.less"; const SpottableComponent = Spottable("div"); @@ -19,42 +22,52 @@ const TabItemBase = ({ deActivateTab, className, onClick, + mainExpandend, + lgCatCd, + isSubItem, + subTitle, + showSubTab = false, ...rest }) => { const [focused, setFocused] = useState(false); + // const [subFocused , setSubFocused] = useState(false) + const [pressed, setPressed] = 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 }); } }); + + setPressed(true); + onClick({ index, target }); }, - [target, index, onClick] + [target, index, onClick, isSubItem] ); + + useEffect(() => {}, [pressed]); + const _onFocus = useCallback(() => { setFocused(true); }, [index]); const _onBlur = useCallback(() => { setFocused(false); - }, []); + }, [focused]); const isDivider = useMemo(() => { return !title; }, []); + const onKeyDown = useCallback( (event) => { if (event.key === "ArrowRight") { @@ -69,14 +82,27 @@ const TabItemBase = ({ }, [deActivateTab] ); + const renderIcon = useCallback(() => { if (icons) { const Component = icons; - return ; + return ( + + ); } else { return null; } - }, [focused, selected, expanded]); + }, [focused, expanded]); delete rest.hasChildren; delete rest.getChildren; @@ -85,8 +111,11 @@ const TabItemBase = ({ ref={itemRef} className={classNames( css.tabItem, - focused && css.focused - //!isDivider && selected && css.selected + focused && css.focused, + pressed && css.pressed, + isSubItem && css.subDepth, + pressed && css.arrow, + !isDivider && selected && css.selected )} onKeyDown={onKeyDown} onFocus={_onFocus} @@ -94,13 +123,21 @@ const TabItemBase = ({ onClick={_onClick} spotlightDisabled={isDivider} > - {icons &&
{renderIcon()}
} +
+ {icons &&
{renderIcon()}
} +
+ - {expanded && title && ( - - {title} - - )} + {expanded && ( + + {title} + + )} +
+
); }; diff --git a/com.twin.app.shoptime/src/components/TabLayout/TabItem.module.less b/com.twin.app.shoptime/src/components/TabLayout/TabItem.module.less index 7926577f..786a9834 100644 --- a/com.twin.app.shoptime/src/components/TabLayout/TabItem.module.less +++ b/com.twin.app.shoptime/src/components/TabLayout/TabItem.module.less @@ -1,25 +1,80 @@ +@import "../../style/utils.module.less"; +@import "../../style/CommonStyle.module.less"; + @ICON_SIZE: 48px; + .tabItem{ - padding: 18px 12px 18px 42px; font-size: 36px; display: flex; color: #606060; align-items: center; - + height: 84px; + + padding-left: 42px; + padding-right: 24px; &.focused { + color: #eee; + background: linear-gradient(to right, #cb1253, #e15ba1); + border-radius: 42px; + width: 402px; + z-index: 1; + margin-left: 30px; + position:relative; + > div{ + margin-left:-30px; + } + + &.pressed { color: #eee; - background: linear-gradient(#cb1253, #e15ba1); + background: linear-gradient(to right, #cb1253, #e15ba1); border-radius: 42px; width: 402px; + z-index: 1; + margin-left: 30px; + position:relative; + } + &.selected{ + // margin-left:0; } + } + + &.arrow, &.selected { + &::after { + content: ""; + .size(@w:36px, @h:36px); + .position(@position: absolute, @top: 24px, @right: 18px); + background-image: url('../../../assets/icons/ic-lnb-right-arrow.png'); + background-size: 36px 36px; + + + } + } + &.selected { + color: #eee; + } + + &.subDepth{ + width: 386px; + height: 78px; + margin-left: 0; + + &.focused { + background: rgba(255, 255, 255, .1); + border-radius: 0px; + border-right: 6px solid #c70850; + > div { + padding-left: 30px; + + + +}}} - .icon { position: relative; min-width: @ICON_SIZE; height: @ICON_SIZE; - + > img { position: absolute; top: 50%; @@ -39,15 +94,107 @@ } .text { - width: 100%; - line-height: 36px; - padding-left: 18px; - padding-top: 6px; - flex-grow: 1; - flex-shrink: 1; - overflow: hidden; + line-height: 1.2; + padding-left: 11px; + .font(@fontFamily:@baseFontBold, @fontSize:36px); + + + + &.subItem { + .font (@fontFamily:@baseFontBold, @fontSize:30px); + width: 245px; + + } + } + +.subWrap{ + .flex(); + + + span { + .size(@w: 40px, @h:40px); + background-size: cover; + &.category-icon-1017 { + // LG Electronics + background-image: url("../../../assets/category/ic-category-lgelectronics-nor@3x.png"); + } + + // Garden and Outdoors + &.category-icon-1008 { + background-image: url("../../../assets/icons/ic-category-garden-nor.png"); + } + + // Fashion + &.category-icon-1000 { + background-image: url("../../../assets/icons/ic-category-fashion-nor.png"); + } + + // Beauty + &.category-icon-1003 { + background-image: url("../../../assets/icons/ic-category-beauty-nor.png"); + } + + // Jewelry + &.category-icon-1004 { + background-image: url("../../../assets/icons/ic-category-jewelry-nor.png"); + } + + // Home + &.category-icon-1006 { + background-image: url("../../../assets/icons/ic-category-home-nor.png"); + } + + // Kitchen & Food + &.category-icon-1007 { + background-image: url("../../../assets/icons/ic-category-kitchen-nor.png"); + } + + // Accessories + &.category-icon-1014 { + background-image: url("../../../assets/icons/ic-category-accessories-nor.png"); + } + + // Heaclth & Fitness + &.category-icon-1009 { + background-image: url("../../../assets/icons/ic-category-health-nor.png"); + } + + // Entertainment + &.category-icon-1012 { + background-image: url("../../../assets/icons/ic-category-enter-nor.png"); + } + + // Crafts & Sewing + &.category-icon-1011 { + background-image: url("../../../assets/icons/ic-category-cw-nor.png"); + } + + // Electronics + &.category-icon-1010 { + background-image: url("../../../assets/icons/ic-category-electronics-nor.png"); + } + + // Clearance + &.category-icon-1013 { + background-image: url("../../../assets/icons/ic-category-clearance-nor.png"); + } + } + + + +} + +.layout { + display: flex; + + &.focused, &.selected { + // margin-left: -30px; + } +} + + .marqueeWrap { width: 100%; } diff --git a/com.twin.app.shoptime/src/components/TabLayout/TabLayout.jsx b/com.twin.app.shoptime/src/components/TabLayout/TabLayout.jsx index b1a18d33..8db526a0 100644 --- a/com.twin.app.shoptime/src/components/TabLayout/TabLayout.jsx +++ b/com.twin.app.shoptime/src/components/TabLayout/TabLayout.jsx @@ -9,20 +9,19 @@ import React, { import classNames from "classnames"; import { useDispatch, useSelector } from "react-redux"; -import { panel_names } from "../../utils/Config"; -import TabItem from "./TabItem"; -import css from "./TabLayout.module.less"; +//아이콘 +import { Job } from "@enact/core/util"; //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"; import shopTimeIcon from "../../../assets/icons/ic-lnb-shoptime-symbol@3x.png"; +import { resetPanels } from "../../features/panels/panelsSlice"; +import { panel_names } from "../../utils/Config"; import CartIcon from "./iconComponents/CartIcon"; import CategoryIcon from "./iconComponents/CategoryIcon"; import FeaturedBrandIcon from "./iconComponents/FeaturedBrandIcon"; @@ -32,9 +31,8 @@ import MyPageIcon from "./iconComponents/MyPageIcon"; import OnSaleIcon from "./iconComponents/OnSaleIcon"; import SearchIcon from "./iconComponents/SearchIcon"; import TrendingNowIcon from "./iconComponents/TrendingNowIcon"; - -//이미지 -import { resetPanels } from "../../features/panels/panelsSlice"; +import TabItem from "./TabItem"; +import css from "./TabLayout.module.less"; const Container = SpotlightContainerDecorator( { enterTo: "default-element" }, @@ -52,9 +50,10 @@ const CancelableDiv = Cancelable( ); class TabMenuItem { - constructor(icons = "", title = "", target, children = []) { + constructor(icons = "", title = "", id, target, children = []) { this.icons = icons; this.title = title; + this.id = id; this.target = target; this.children = []; //TabMenuItem if (children && children.length > 0) { @@ -62,6 +61,7 @@ class TabMenuItem { const tabmenu = new TabMenuItem( children[i].icons, children[i].title, + children[i].id, children[i].target, children[i].children ); @@ -110,91 +110,80 @@ export default function TabLayout({ topPanelName, onTabActivated }) { const dispatch = useDispatch(); const [mainExpanded, setMainExpanded] = useState(false); const [mainSelectedIndex, setMainSelectedIndex] = useState(-1); + const [focused, setFocused] = useState(false); const [tabs, setTabs] = useState([]); 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 data = useSelector((state) => state.home.menuData?.data); + const panels = useSelector((state) => state.panels.panels); - const menuItems = useMemo( - () => [ + const menuItems = useMemo(() => { + return [ { icons: CategoryIcon, - title: "", - children: [], }, { icons: MyPageIcon, - title: "", - children: [], }, { icons: SearchIcon, - title: "", target: [{ name: panel_names.SEARCH_PANEL }], }, { icons: HomeIcon, - title: "", target: [{ name: panel_names.HOME_PANEL }], }, { icons: FeaturedBrandIcon, - title: "", - children: [], }, { icons: OnSaleIcon, - title: "", target: [{ name: panel_names.ON_SALE_PANEL }], }, { icons: TrendingNowIcon, - title: "", target: [{ name: panel_names.TRENDING_NOW_PANEL }], }, { icons: HotPicksIcon, - title: "", target: [{ name: panel_names.HOT_PICKS_PANEL }], }, { icons: CartIcon, - title: "", target: [{ name: panel_names.CART_PANEL }], }, - - //메뉴 추가 필요 20240112 chw - ], - [data] - ); + ]; + }, []); const getMenuData = (type) => { let result = []; switch (type) { case "Category": - data?.homeCategory.map((item) => { - result.push(item.lgCatNm); - }); - return result; + result = data?.homeCategory.map((item) => ({ + id: item.lgCatCd, + title: item.lgCatNm, + })); + break; case "GNB": - data?.gnb.map((item) => { - result.push(item.menuNm); - }); - return result; + result = data?.gnb.map((item) => ({ + title: item.menuNm, + })); + break; + case "Featured Brands": - data?.shortFeaturedBrands.map((item) => { - result.push(item.patncLogoPath); - }); - return result; + result = data?.shortFeaturedBrands.map((item) => ({ + title: item.patncLogoPath, + })); + break; case "My Page": - data?.mypage.map((item) => { - result.push(item.menuNm); - }); - return result; + result = data?.mypage.map((item) => ({ + title: item.menuNm, + })); + break; } - return null; + return result; }; const dataDivide = useCallback(() => { @@ -216,22 +205,20 @@ export default function TabLayout({ topPanelName, onTabActivated }) { Cart: 8, }; - return order[a] - order[b]; + return order[a.title] - order[b.title]; }); - for (let i = 0; i < mainTitle.length; i++) { - menuItems[i].title = mainTitle[i]; - } - for (let j = 0; j < keys.length; j++) { const currentKey = keys[j]; - const subTitle = getMenuData(currentKey); + const subData = getMenuData(currentKey); - if (subTitle && subTitle.length > 0) { + if (subData && subData.length > 0) { for (let i = 0; i < mainTitle.length; i++) { - if (mainTitle[i] === currentKey) { - menuItems[i].children = subTitle.map((title) => ({ - title, + menuItems[i].title = mainTitle[i].title; + if (mainTitle[i].title === currentKey) { + menuItems[i].children = subData.map((subItem) => ({ + id: subItem.id, + title: subItem.title, })); } } @@ -247,6 +234,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) { const tabmenu = new TabMenuItem( menuItems[i].icons, menuItems[i].title, + menuItems[i].id, menuItems[i].target, menuItems[i].children ); @@ -287,7 +275,8 @@ export default function TabLayout({ topPanelName, onTabActivated }) { break; } case ACTIVATED_SUB: { - setMainExpanded(false); + if (cursorVisible) { + } break; } case EXTRA_AREA: { @@ -303,7 +292,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) { return prev; }); }, - [cursorVisible, deActivateTab] + [cursorVisible, deActivateTab, focused] ); const onTabBlur = useCallback( @@ -337,6 +326,14 @@ export default function TabLayout({ topPanelName, onTabActivated }) { [cursorVisible] ); + const onFocus = () => { + setFocused(true); + }; + + const onBlur = () => { + setFocused(false); + }; + const handleNavigation = useCallback( ({ index, target }) => { setMainSelectedIndex(index); @@ -355,10 +352,9 @@ export default function TabLayout({ topPanelName, onTabActivated }) { const onClickSubItem = useCallback( ({ index, target }) => { if (target) { - dispatch(resetPanels(target)); deActivateTab(); panelSwitching.current = true; - // panelSwitchingJob.start(panelSwitching); + panelSwitchingJob.start(panelSwitching); } }, [dispatch, deActivateTab] @@ -416,27 +412,24 @@ export default function TabLayout({ topPanelName, onTabActivated }) { }, [tabActivated, showTab]); useEffect(() => {}, [showSubTab, mainSelectedIndex]); - if (!showTab) { return null; } - return ( -
+
{/* collabsed Main */} - + {tabs.map((item, index) => ( {/* expanded Main */} -

- -

+ {tabActivated && tabs.map((item, index) => ( @@ -498,7 +497,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) { onMouseLeave={onTabBlur(ACTIVATED_SUB)} > {showSubTab && - tabs[mainSelectedIndex].children.map((item, index) => { + tabs[mainSelectedIndex]?.children.map((item, index) => { return ( ); })} diff --git a/com.twin.app.shoptime/src/components/TabLayout/TabLayout.module.less b/com.twin.app.shoptime/src/components/TabLayout/TabLayout.module.less index 38fb37d4..2002960d 100644 --- a/com.twin.app.shoptime/src/components/TabLayout/TabLayout.module.less +++ b/com.twin.app.shoptime/src/components/TabLayout/TabLayout.module.less @@ -1,3 +1,6 @@ +@import "../../style/utils.module.less"; +@import "../../style/CommonStyle.module.less"; + .tabLayoutWrap { width: 100%; height: 100%; @@ -5,6 +8,7 @@ left: 0; top: 0; display: flex; + &.hide { width: auto; } @@ -18,40 +22,55 @@ left: 0; z-index: 1; + &.hide { width: auto; z-index: 0; } + } .tabWrap { width: 120px; height: 100%; - //position:fixed; left: 0; top: 0; background-color: #222222; - display: flex; flex-direction: column; justify-content: center; - // padding-top: 104px; - // padding-bottom: 104px; z-index: 1; flex-grow: 0; transition: width 0.5s ease; + + > img { + width: 54px; + height: 54px; + margin: -40px 24px 84px 42px + + } + &.expanded { width: 402px; + + > img { + width: 234px; + height: 54px; + } + } + &.secondDepthLayout { width: 386px; height: calc(100%); opacity: 0.95; - box-shadow: 8px 0 36px rgba(33, 33, 32, 0.08); padding-bottom: unset; - justify-content: flex-start; - left: 402px; + padding-top: 71px; + z-index: 0; + justify-content: flex-start; + + } &.extraArea { flex-grow: 1; @@ -61,25 +80,9 @@ &.hide { width: 0; } + + + } -.logo { - width: 54px; - height: 54px; - 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; - } -} diff --git a/com.twin.app.shoptime/src/components/TabLayout/iconComponents/convertThemeColor.js b/com.twin.app.shoptime/src/components/TabLayout/iconComponents/convertThemeColor.js index ee9d51c1..17959f30 100644 --- a/com.twin.app.shoptime/src/components/TabLayout/iconComponents/convertThemeColor.js +++ b/com.twin.app.shoptime/src/components/TabLayout/iconComponents/convertThemeColor.js @@ -3,7 +3,9 @@ export const convertThemeColor = (iconType) => { const theme = { light: { normal: "#353535", - expanded: "#FEFEFE", + expanded: "#353535", + selected: "#FEFEFE", + focused: "#FEFEFE", }, };