TabLayout 같은패널로 진입시 backkey와 같은기능 로직 추가
This commit is contained in:
@@ -43,6 +43,10 @@
|
||||
max-width: 650px;
|
||||
letter-spacing: -0.75px;
|
||||
}
|
||||
&.extraLarge {
|
||||
min-width: 350px;
|
||||
max-width: 900px;
|
||||
}
|
||||
&.full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import React, { useCallback } from "react";
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import classNames from "classnames";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
|
||||
import { Panel } from "@enact/sandstone/Panels";
|
||||
import { Cancelable } from "@enact/ui/Cancelable";
|
||||
import { Panel } from '@enact/sandstone/Panels';
|
||||
import { Cancelable } from '@enact/ui/Cancelable';
|
||||
|
||||
import { popPanel } from "../../actions/panelActions";
|
||||
import SmoodShowingAnimation from "../SmoodShowingAnimation/SmoodShowingAnimation";
|
||||
import css from "./TPanel.module.less";
|
||||
import { popPanel } from '../../actions/panelActions';
|
||||
import { SpotlightIds } from '../../utils/SpotlightIds';
|
||||
import SmoodShowingAnimation
|
||||
from '../SmoodShowingAnimation/SmoodShowingAnimation';
|
||||
import css from './TPanel.module.less';
|
||||
|
||||
const CancelablePanel = Cancelable(
|
||||
{ modal: true, onCancel: "handleCancel" },
|
||||
@@ -20,6 +25,7 @@ const TPanel = ({
|
||||
children,
|
||||
handleCancel,
|
||||
isTabActivated = true,
|
||||
spotlightId = SpotlightIds.TPANEL,
|
||||
...rest
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -51,6 +57,7 @@ const TPanel = ({
|
||||
isTabActivated && css.isTabActivated,
|
||||
className
|
||||
)}
|
||||
spotlightId={spotlightId}
|
||||
>
|
||||
{children}
|
||||
</CancelablePanel>
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import classNames from "classnames";
|
||||
import compose from "ramda/src/compose";
|
||||
import classNames from 'classnames';
|
||||
import compose from 'ramda/src/compose';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { Job } from "@enact/core/util";
|
||||
import { Marquee, MarqueeController } from "@enact/sandstone/Marquee";
|
||||
import Spotlight from "@enact/spotlight";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
import { Job } from '@enact/core/util';
|
||||
import {
|
||||
Marquee,
|
||||
MarqueeController,
|
||||
} from '@enact/sandstone/Marquee';
|
||||
import Spotlight from '@enact/spotlight';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import css from "./TabItem.module.less";
|
||||
import css from './TabItem.module.less';
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
const TabItemBase = ({
|
||||
@@ -27,9 +36,11 @@ const TabItemBase = ({
|
||||
opened,
|
||||
spotlightId,
|
||||
setLastFocusId,
|
||||
setSelectedTitle,
|
||||
...rest
|
||||
}) => {
|
||||
const [focused, setFocused] = useState(false);
|
||||
const { cursorVisible } = useSelector((state) => state.common.appStatus);
|
||||
const clearPressedJob = useRef(
|
||||
new Job((func) => {
|
||||
setTimeout(func, 100);
|
||||
@@ -40,11 +51,8 @@ const TabItemBase = ({
|
||||
(ev) => {
|
||||
clearPressedJob.current.start(() => {
|
||||
if (onClick) {
|
||||
if (showSubTab) {
|
||||
Spotlight.focus("activatedSub");
|
||||
}
|
||||
|
||||
onClick({ index, target });
|
||||
onClick({ index, target, title });
|
||||
setSelectedTitle(title);
|
||||
if (spotlightId) {
|
||||
setLastFocusId(spotlightId);
|
||||
}
|
||||
@@ -59,7 +67,7 @@ const TabItemBase = ({
|
||||
if (onFocus) {
|
||||
onFocus(index);
|
||||
}
|
||||
}, [index, showSubTab, onFocus]);
|
||||
}, [index, showSubTab, onFocus, cursorVisible]);
|
||||
|
||||
const _onBlur = useCallback(() => {
|
||||
setFocused(false);
|
||||
@@ -95,7 +103,16 @@ const TabItemBase = ({
|
||||
}
|
||||
|
||||
return <Component iconType={iconType} />;
|
||||
}, [focused, expanded, mainSelected, opened, index, icons, selected]);
|
||||
}, [
|
||||
focused,
|
||||
expanded,
|
||||
mainSelected,
|
||||
opened,
|
||||
index,
|
||||
icons,
|
||||
selected,
|
||||
cursorVisible,
|
||||
]);
|
||||
|
||||
delete rest.hasChildren;
|
||||
delete rest.getChildren;
|
||||
@@ -118,7 +135,8 @@ const TabItemBase = ({
|
||||
<div
|
||||
className={classNames(
|
||||
css.itemWrap,
|
||||
(focused || opened) && css.focused,
|
||||
focused && css.focused,
|
||||
expanded && opened && css.opened,
|
||||
expanded && mainSelected && css.selected,
|
||||
expanded && selected && css.selected
|
||||
)}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
&.focused {
|
||||
color: #eee;
|
||||
// background-color: #c70850;
|
||||
background: linear-gradient(to right, #cb1253, #e15ba1);
|
||||
border-radius: 42px;
|
||||
width: 402px;
|
||||
@@ -25,13 +24,10 @@
|
||||
|
||||
&.opened {
|
||||
color: #eee;
|
||||
// background-color: #c70850;
|
||||
// border-radius: 42px;
|
||||
width: 402px;
|
||||
z-index: 1;
|
||||
margin-left: 30px;
|
||||
position: relative;
|
||||
|
||||
margin-left: 30px;
|
||||
&.arrow {
|
||||
&::after {
|
||||
content: "";
|
||||
@@ -45,12 +41,6 @@
|
||||
|
||||
&.selected {
|
||||
color: #eee;
|
||||
// background-color: #4f172c;
|
||||
// border-radius: 42px;
|
||||
// width: 402px;
|
||||
// z-index: 1;
|
||||
// margin-left: 30px;
|
||||
// position: relative;
|
||||
}
|
||||
|
||||
.itemWrap {
|
||||
@@ -58,9 +48,9 @@
|
||||
&.focused {
|
||||
margin-left: -30px;
|
||||
}
|
||||
// &.selected {
|
||||
// margin-left: -30px;
|
||||
// }
|
||||
&.opened {
|
||||
margin-left: -30px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
@@ -93,7 +83,6 @@
|
||||
.font(@fontFamily:@baseFont, @fontSize:30px);
|
||||
font-weight: bold;
|
||||
width: 245px;
|
||||
// word-break:break-all;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import classNames from "classnames";
|
||||
import compose from "ramda/src/compose";
|
||||
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 { Job } from '@enact/core/util';
|
||||
import {
|
||||
Marquee,
|
||||
MarqueeController,
|
||||
} from '@enact/sandstone/Marquee';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import css from "./TabItemSub.module.less";
|
||||
import css from './TabItemSub.module.less';
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
const TabItemBase = ({
|
||||
@@ -24,6 +32,7 @@ const TabItemBase = ({
|
||||
path,
|
||||
spotlightId,
|
||||
setLastFocusId,
|
||||
setSelectedTitle,
|
||||
...rest
|
||||
}) => {
|
||||
const [focused, setFocused] = useState(false);
|
||||
@@ -38,7 +47,8 @@ const TabItemBase = ({
|
||||
(ev) => {
|
||||
clearPressedJob.current.start(() => {
|
||||
if (onClick) {
|
||||
onClick({ index, target });
|
||||
onClick({ index, target, title });
|
||||
setSelectedTitle(title);
|
||||
if (spotlightId) {
|
||||
setLastFocusId(spotlightId);
|
||||
}
|
||||
|
||||
@@ -4,38 +4,44 @@ import React, {
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
} from 'react';
|
||||
|
||||
import classNames from "classnames";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
|
||||
//아이콘
|
||||
import { Job } from "@enact/core/util";
|
||||
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 Skinnable from '@enact/sandstone/Skinnable';
|
||||
import Spotlight from '@enact/spotlight';
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import { Cancelable } from '@enact/ui/Cancelable';
|
||||
|
||||
//이미지
|
||||
import shoptimeFullIcon from "../../../assets/images/icons/ic-lnb-logo-shoptime@3x.png";
|
||||
import shopTimeIcon from "../../../assets/images/icons/ic-lnb-shoptime-symbol@3x.png";
|
||||
import { gnbOpened } from "../../actions/commonActions";
|
||||
import { resetPanels } from "../../actions/panelActions";
|
||||
import { panel_names } from "../../utils/Config";
|
||||
import { SpotlightIds } from "../../utils/SpotlightIds";
|
||||
import TScroller from "../TScroller/TScroller";
|
||||
import CategoryIcon from "./iconComponents/CategoryIcon";
|
||||
import FeaturedBrandIcon from "./iconComponents/FeaturedBrandIcon";
|
||||
import HomeIcon from "./iconComponents/HomeIcon";
|
||||
import HotPicksIcon from "./iconComponents/HotPicksIcon";
|
||||
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 TabItemSub from "./TabItemSub";
|
||||
import css from "./TabLayout.module.less";
|
||||
import shoptimeFullIcon
|
||||
from '../../../assets/images/icons/ic-lnb-logo-shoptime@3x.png';
|
||||
import shopTimeIcon
|
||||
from '../../../assets/images/icons/ic-lnb-shoptime-symbol@3x.png';
|
||||
import { gnbOpened } from '../../actions/commonActions';
|
||||
import { resetPanels } from '../../actions/panelActions';
|
||||
import { panel_names } from '../../utils/Config';
|
||||
import { SpotlightIds } from '../../utils/SpotlightIds';
|
||||
import TScroller from '../TScroller/TScroller';
|
||||
import CategoryIcon from './iconComponents/CategoryIcon';
|
||||
import FeaturedBrandIcon from './iconComponents/FeaturedBrandIcon';
|
||||
import HomeIcon from './iconComponents/HomeIcon';
|
||||
import HotPicksIcon from './iconComponents/HotPicksIcon';
|
||||
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 TabItemSub from './TabItemSub';
|
||||
import css from './TabLayout.module.less';
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: "default-element", preserveId: true },
|
||||
@@ -126,6 +132,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
|
||||
const [mainSelectedIndex, setMainSelectedIndex] = useState(-1);
|
||||
const [secondDepthReduce, setSecondDepthReduce] = useState(false);
|
||||
const [lastFocusId, setLastFocusId] = useState(null);
|
||||
const [selectedTitle, setSelectedTitle] = useState("");
|
||||
const [subTabLastFocusId, setSubTabLastFocusId] = useState(null);
|
||||
const [tabs, setTabs] = useState([]);
|
||||
const [tabFocused, setTabFocused] = useState([false, false, false]); //COLLABSED_MAIN, ACTIVATED_MAIN, ACTIVATED_SUB
|
||||
@@ -395,14 +402,18 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
|
||||
};
|
||||
|
||||
const handleNavigation = useCallback(
|
||||
({ index, target }) => {
|
||||
({ index, target, title }) => {
|
||||
setMainSelectedIndex(index);
|
||||
|
||||
if (selectedTitle === title) {
|
||||
Spotlight.focus(SpotlightIds.TPANEL);
|
||||
deActivateTab();
|
||||
return;
|
||||
}
|
||||
if (index === 3) {
|
||||
dispatch(resetPanels());
|
||||
deActivateTab();
|
||||
Spotlight.focus(SpotlightIds.TBODY);
|
||||
|
||||
return;
|
||||
}
|
||||
if (target) {
|
||||
@@ -414,11 +425,16 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
|
||||
setMainExpanded(true);
|
||||
}
|
||||
},
|
||||
[cursorVisible, deActivateTab, dispatch]
|
||||
[cursorVisible, deActivateTab, dispatch, panels]
|
||||
);
|
||||
|
||||
const onClickSubItem = useCallback(
|
||||
({ index, target }) => {
|
||||
({ index, target, title }) => {
|
||||
if (selectedTitle === title) {
|
||||
Spotlight.focus(SpotlightIds.TPANEL);
|
||||
deActivateTab();
|
||||
return;
|
||||
}
|
||||
if (target) {
|
||||
dispatch(resetPanels(target));
|
||||
deActivateTab();
|
||||
@@ -426,7 +442,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
|
||||
panelSwitchingJob.start(panelSwitching);
|
||||
}
|
||||
},
|
||||
[dispatch, deActivateTab]
|
||||
[dispatch, deActivateTab, selectedTitle]
|
||||
);
|
||||
const onClickExtraArea = useCallback(
|
||||
({ index, target }) => {
|
||||
@@ -589,6 +605,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
|
||||
item.children[0]?.target[0]?.name &&
|
||||
panels[0]?.name === item.children[0]?.target?.[0].name
|
||||
}
|
||||
setSelectedTitle={setSelectedTitle}
|
||||
title={item.title}
|
||||
index={index}
|
||||
opened={mainSelectedIndex === index}
|
||||
@@ -628,6 +645,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
|
||||
lgCatCd={item.id}
|
||||
path={item.path}
|
||||
showSubTab={showSubTab}
|
||||
setSelectedTitle={setSelectedTitle}
|
||||
selected={
|
||||
Array.isArray(item.target) &&
|
||||
item.target[0]?.panelInfo &&
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export const SpotlightIds = {
|
||||
TPANEL: "tpanel",
|
||||
TBODY: "tbody",
|
||||
TITEM_CARD: "tItemCard",
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@ export default function HotelOption({ selectedIndex, setSelectedIndex }) {
|
||||
const hotelInfos = useSelector(
|
||||
(state) => state.home.themeCurationHotelDetailData
|
||||
);
|
||||
const HotelData = useSelector((state) => state.home.HotelData);
|
||||
|
||||
console.log("#hotelInfos", hotelInfos);
|
||||
console.log("#hotelInfos", HotelData);
|
||||
|
||||
useEffect(() => {
|
||||
let label = "";
|
||||
@@ -47,7 +48,7 @@ export default function HotelOption({ selectedIndex, setSelectedIndex }) {
|
||||
return (
|
||||
<div className={css.optionContainer}>
|
||||
<div className={css.topLayer}>
|
||||
<img src={logo} alt="patncLogoPath" />
|
||||
<img src={HotelData?.hotelInfo.patncLogoPath} alt="patncLogoPath" />
|
||||
<div className={css.rating}>
|
||||
<StarRating
|
||||
rating={hotelInfos[selectedIndex]?.hotelDetailInfo.revwGrd}
|
||||
@@ -55,7 +56,9 @@ export default function HotelOption({ selectedIndex, setSelectedIndex }) {
|
||||
<span className={css.line} /> <div>{label}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={css.title}>{hotelInfos[selectedIndex]?.hotelNm}</div>
|
||||
<div className={css.title}>
|
||||
{"HOTELHOTELHOTELHOTELHOTELHOTELHOTELHOTELHOTELHOTEL"}
|
||||
</div>
|
||||
<div className={css.amenities}></div>
|
||||
<div className={css.bottomLayer}>
|
||||
<div>
|
||||
@@ -82,7 +85,9 @@ export default function HotelOption({ selectedIndex, setSelectedIndex }) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<TButton className={css.tbutton}>SEE MORE</TButton>
|
||||
<TButton className={css.tbutton} type="extraLarge">
|
||||
{$L("SEE MORE")}
|
||||
</TButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
.optionContainer {
|
||||
.flex(@direction:column ,@justifyCenter:flex-start,@alignCenter:flex-start);
|
||||
.size(@w: 1026px, @h: 930px);
|
||||
.size(@w: 100% , @h: 990px);
|
||||
background-color: @BG_COLOR_01;
|
||||
padding: 30px 120px 60px 60px;
|
||||
|
||||
.topLayer {
|
||||
width: 100%;
|
||||
width: 846px;
|
||||
.flex(@direction:row ,@justifyCenter:flex-start);
|
||||
text-align: left;
|
||||
color: @COLOR_GRAY03;
|
||||
@@ -42,12 +42,14 @@
|
||||
color: @COLOR_GRAY08;
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
line-height: 1.17;
|
||||
margin: 20px 0 31px 0;
|
||||
}
|
||||
|
||||
.amenities {
|
||||
.size(@w: 846px , @h: 234px);
|
||||
.size(@w: 846px , @h: 344px);
|
||||
background-color: #f2f2f2;
|
||||
margin: 32px 0 20px 0;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
|
||||
.bottomLayer {
|
||||
@@ -83,7 +85,7 @@
|
||||
.qrcodeContainer {
|
||||
.size(@w: 192px , @h: 192px);
|
||||
.flex(@display: flex, @justifyCenter: center, @alignCenter: center, @direction: column);
|
||||
margin-top: 35px;
|
||||
margin-top: 38px;
|
||||
|
||||
div:first-child {
|
||||
.size(@w: 192px, @h: 192px);
|
||||
@@ -91,16 +93,16 @@
|
||||
border-radius: 6px;
|
||||
border: solid 1px #dadada;
|
||||
background-image: linear-gradient(to top, #f5f5f5, #fff);
|
||||
margin: 10px 0 0 6px;
|
||||
margin: 5px 0 0 6px;
|
||||
padding: 16px 16px 16px 16px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
.tooltipBody {
|
||||
.size(@w: 340px , @h: 80px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 340px;
|
||||
height: 80px;
|
||||
padding: 15px 26px 16px 26px;
|
||||
text-align: center;
|
||||
background: @COLOR_GRAY07;
|
||||
border-radius: 10px;
|
||||
@@ -125,6 +127,6 @@
|
||||
}
|
||||
.tbutton {
|
||||
.size(@w: 846px , @h:78px);
|
||||
margin-top: 103px;
|
||||
margin-top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user