TabLayout 같은패널로 진입시 backkey와 같은기능 로직 추가

This commit is contained in:
고동영
2024-03-19 16:29:23 +09:00
parent 64dd9fd05b
commit 7ea701ed3f
9 changed files with 146 additions and 92 deletions

View File

@@ -43,6 +43,10 @@
max-width: 650px;
letter-spacing: -0.75px;
}
&.extraLarge {
min-width: 350px;
max-width: 900px;
}
&.full {
width: 100%;
}

View File

@@ -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>

View File

@@ -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
)}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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 &&

View File

@@ -1,4 +1,5 @@
export const SpotlightIds = {
TPANEL: "tpanel",
TBODY: "tbody",
TITEM_CARD: "tItemCard",

View File

@@ -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>
);
}

View File

@@ -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;
}
}