[FeaturedBrandsPanel] section, Showroom 추가
Detail Notes : 1. UI, UX 추가
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
getBrandLiveChannelInfo,
|
||||
getBrandRecommendedShowInfo,
|
||||
getBrandSeriesInfo,
|
||||
getBrandShowroom,
|
||||
getBrandTSVInfo,
|
||||
} from "../../actions/brandActions";
|
||||
import { changeAppStatus, setHidePopup } from "../../actions/commonActions";
|
||||
@@ -39,6 +40,7 @@ import LiveChannels from "./LiveChannels/LiveChannels";
|
||||
import QuickMenu from "./QuickMenu/QuickMenu";
|
||||
import RecommendedShows from "./RecommendedShows/RecommendedShows";
|
||||
import Series from "./Series/Series";
|
||||
import Showroom from "./Showroom/Showroom";
|
||||
import TodaysDeals from "./TodaysDeals/TodaysDeals";
|
||||
import UpComing from "./UpComing/UpComing";
|
||||
|
||||
@@ -74,6 +76,7 @@ const TEMPLATE_CODE_CONF = {
|
||||
FEATURED_CREATORS: "BRD00106",
|
||||
SERIES: "BRD00107",
|
||||
CATEGORY: "BRD00108",
|
||||
SHOWROOM: "BRD00109",
|
||||
};
|
||||
|
||||
const STRING_CONF = {
|
||||
@@ -181,6 +184,13 @@ export default function FeaturedBrandsPanel() {
|
||||
(state) => state.brand.brandCategoryInfoData.status
|
||||
);
|
||||
|
||||
const brandShowroomInfo = useSelector(
|
||||
(state) => state.brand.brandShowroomData.data.brandShowroomInfo
|
||||
);
|
||||
const brandShowroomStatus = useSelector(
|
||||
(state) => state.brand.brandShowroomData.status
|
||||
);
|
||||
|
||||
const [selectedPatnrId, setSelectedPatnrId] = useState();
|
||||
const [selectedBrandInfo, setSelectedBrandInfo] = useState();
|
||||
const [selectedCatCd, setSelectedCatCd] = useState();
|
||||
@@ -216,6 +226,7 @@ export default function FeaturedBrandsPanel() {
|
||||
brandCreatorsInfoDataStatus,
|
||||
brandSeriesInfoDataStatus,
|
||||
brandCategoryInfoDataStatus,
|
||||
brandShowroomStatus,
|
||||
].some((status) => status !== "fulfilled"),
|
||||
[
|
||||
brandInfoDataStatus,
|
||||
@@ -227,10 +238,10 @@ export default function FeaturedBrandsPanel() {
|
||||
brandCreatorsInfoDataStatus,
|
||||
brandSeriesInfoDataStatus,
|
||||
brandCategoryInfoDataStatus,
|
||||
brandShowroomStatus,
|
||||
]
|
||||
);
|
||||
|
||||
// loading
|
||||
useEffect(() => {
|
||||
const showLoadingPanel = isLoading
|
||||
? { show: true, type: "wait" }
|
||||
@@ -270,8 +281,6 @@ export default function FeaturedBrandsPanel() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
// @@pyh Todo, test ref
|
||||
const timerRef = useRef();
|
||||
useEffect(() => {
|
||||
if (brandInfo && selectedPatnrId) {
|
||||
setSelectedBrandInfo(findItemByValue(brandInfo, selectedPatnrId));
|
||||
@@ -281,32 +290,26 @@ export default function FeaturedBrandsPanel() {
|
||||
setSelectedCatCdLv1();
|
||||
setSelectedCatCdLv2();
|
||||
|
||||
clearTimeout(timerRef.current);
|
||||
|
||||
dispatch(getBrandLayoutInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandLiveChannelInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandTSVInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandBestSeller({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandRecommendedShowInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandCreatorsInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandSeriesInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(
|
||||
getBrandCategoryInfo({
|
||||
patnrId: selectedPatnrId,
|
||||
})
|
||||
);
|
||||
dispatch(getBrandRecommendedShowInfo({ patnrId: selectedPatnrId }));
|
||||
|
||||
// @@pyh Todo, test timeout
|
||||
timerRef.current = setTimeout(() => {
|
||||
dispatch(getBrandLiveChannelInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandLayoutInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandSeriesInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandTSVInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandBestSeller({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandCreatorsInfo({ patnrId: selectedPatnrId }));
|
||||
}, 50);
|
||||
dispatch(
|
||||
getBrandShowroom({
|
||||
patnrId: selectedPatnrId,
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [brandInfo, dispatch, selectedPatnrId]);
|
||||
|
||||
// @@pyh Todo, test unmounted
|
||||
useEffect(() => {
|
||||
return () => clearTimeout(timerRef.current);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCatCd) {
|
||||
dispatch(
|
||||
@@ -372,7 +375,7 @@ export default function FeaturedBrandsPanel() {
|
||||
scrollTop();
|
||||
}, []);
|
||||
|
||||
// @@pyh Todo, @@test, temporary func, edited later
|
||||
// pyh Todo, test, temporary func, edited later
|
||||
const handlePopupClick = useCallback(() => {
|
||||
dispatch({
|
||||
type: "SET_MY_UPCOMING_USE_ALERT",
|
||||
@@ -382,11 +385,31 @@ export default function FeaturedBrandsPanel() {
|
||||
dispatch(setHidePopup());
|
||||
}, [dispatch]);
|
||||
|
||||
// @@pyh Todo, @@test, temporary func, edited later
|
||||
// pyh Todo, test, temporary func, edited later
|
||||
const handlePopupClose = useCallback(() => {
|
||||
dispatch(setHidePopup());
|
||||
}, [dispatch]);
|
||||
|
||||
// pyh, test func by boss
|
||||
const handleTopButtonClick2 = useCallback(() => {
|
||||
const ar = [1, 2, 4, 9, 11];
|
||||
const randomIndex = Math.floor(Math.random() * ar.length);
|
||||
const randomIndex2 = Math.floor(Math.random() * ar.length);
|
||||
dispatch(
|
||||
getBrandCategoryInfo({
|
||||
patnrId: ar[randomIndex],
|
||||
})
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
dispatch(
|
||||
getBrandRecommendedShowInfo({
|
||||
patnrId: ar[randomIndex2],
|
||||
})
|
||||
);
|
||||
}, 10);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
/* scenario page 98 */
|
||||
<TPanel className={css.tPanel}>
|
||||
@@ -547,6 +570,21 @@ export default function FeaturedBrandsPanel() {
|
||||
setSelectedCatCdLv2={setSelectedCatCdLv2}
|
||||
/>
|
||||
)}
|
||||
|
||||
{hasTemplateCodeWithValue(
|
||||
brandLayoutInfo,
|
||||
TEMPLATE_CODE_CONF.SHOWROOM
|
||||
) &&
|
||||
shouldRenderComponent(brandShowroomInfo) && (
|
||||
<Showroom
|
||||
brandShowroomInfo={brandShowroomInfo}
|
||||
order={getOrderByValue(
|
||||
brandLayoutInfo,
|
||||
TEMPLATE_CODE_CONF.SHOWROOM
|
||||
)}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import React, { memo, useEffect, useMemo, useState } from "react";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import css from "./Showroom.module.less";
|
||||
import ShowroomContents from "./ShowroomContents/ShowroomContents";
|
||||
import ShowroomNav from "./ShowroomNav/ShowroomNav";
|
||||
|
||||
const STRING_CONF = {
|
||||
SHOWROOM: $L("SHOWROOM"),
|
||||
};
|
||||
|
||||
export default memo(function Showroom({
|
||||
brandShowroomInfo,
|
||||
order,
|
||||
selectedPatnrId,
|
||||
}) {
|
||||
const [selectedRoomId, setSelectedRoomId] = useState();
|
||||
|
||||
const orderStyle = useMemo(() => ({ order: order }), [order]);
|
||||
|
||||
const selectedRoomThemeInfos = useMemo(
|
||||
() =>
|
||||
brandShowroomInfo //
|
||||
.find((info) => info.roomId === selectedRoomId)?.roomThemeInfos,
|
||||
[brandShowroomInfo, selectedRoomId]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedRoomId) {
|
||||
setSelectedRoomId(brandShowroomInfo[0]?.roomId);
|
||||
}
|
||||
}, [brandShowroomInfo]);
|
||||
|
||||
return (
|
||||
<div className={css.container} style={orderStyle}>
|
||||
<SectionTitle title={STRING_CONF.SHOWROOM} />
|
||||
<ShowroomNav
|
||||
brandShowroomInfo={brandShowroomInfo}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedRoomId={selectedRoomId}
|
||||
setSelectedRoomId={setSelectedRoomId}
|
||||
/>
|
||||
{selectedRoomThemeInfos &&
|
||||
selectedRoomThemeInfos.map(
|
||||
(
|
||||
{
|
||||
roomThemeProducts,
|
||||
themeExpsOrd,
|
||||
// themeId,
|
||||
themeImgUrl,
|
||||
themeNm,
|
||||
},
|
||||
index
|
||||
) => (
|
||||
<ShowroomContents
|
||||
key={"roomThemeInfos-" + index}
|
||||
roomThemeProducts={roomThemeProducts}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedRoomId={selectedRoomId}
|
||||
themeExpsOrd={themeExpsOrd}
|
||||
// themeId={themeId}
|
||||
themeImgUrl={themeImgUrl}
|
||||
themeNm={themeNm}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
@import "../../../style/CommonStyle.module.less";
|
||||
@import "../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-bottom: 58px;
|
||||
|
||||
> h2 {
|
||||
margin-bottom: 24px;
|
||||
padding-left: 60px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import {
|
||||
getContainerId,
|
||||
setContainerLastFocusedElement,
|
||||
} from "@enact/spotlight/src/container";
|
||||
|
||||
import css from "./ShowroomContents.module.less";
|
||||
import ShowroomProductList from "./ShowroomProductList/ShowroomProductList";
|
||||
import ShowroomThumbnailCard from "./ShowroomThumbnailCard/ShowroomThumbnailCard";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
export default function ShowroomContents({
|
||||
roomThemeProducts,
|
||||
selectedPatnrId,
|
||||
selectedRoomId,
|
||||
themeExpsOrd,
|
||||
// themeId,
|
||||
themeImgUrl,
|
||||
themeNm,
|
||||
...rest
|
||||
}) {
|
||||
useEffect(() => {
|
||||
const containerId = "showroomContentsId-" + themeExpsOrd;
|
||||
const container = document.getElementById(containerId);
|
||||
|
||||
if (container) {
|
||||
const thumbnailCard = container.children[1].children[0].children[0];
|
||||
thumbnailCard &&
|
||||
setContainerLastFocusedElement(thumbnailCard, [containerId]);
|
||||
|
||||
const gridListId = getContainerId(
|
||||
container.children[1].children[1].children[0].children[0]
|
||||
);
|
||||
|
||||
const gridList =
|
||||
container.children[1].children[1].children[0].children[0];
|
||||
gridList && setContainerLastFocusedElement(null, [gridListId]);
|
||||
}
|
||||
}, [selectedPatnrId, selectedRoomId]);
|
||||
|
||||
const handleClick = () => {
|
||||
// pyh, add something later..
|
||||
};
|
||||
|
||||
return (
|
||||
<Container
|
||||
className={css.container}
|
||||
id={"showroomContentsId-" + themeExpsOrd}
|
||||
spotlightId={"showroomContentsId-" + themeExpsOrd}
|
||||
{...rest}
|
||||
>
|
||||
<h3>{themeNm}</h3>
|
||||
<div>
|
||||
<ShowroomThumbnailCard
|
||||
thumbnailUrl={themeImgUrl}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
<ShowroomProductList
|
||||
roomThemeProducts={roomThemeProducts}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedRoomId={selectedRoomId}
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
padding-left: 60px;
|
||||
margin-bottom: 14px;
|
||||
|
||||
> h3 {
|
||||
margin-bottom: -4px;
|
||||
.font(@fontFamily: @arialFontBold, @fontSize: 36px);
|
||||
color: @COLOR_GRAY08;
|
||||
}
|
||||
|
||||
> div {
|
||||
.flex(@justifyCenter: flex-start);
|
||||
.size(@w: 100%, @h: auto);
|
||||
margin-bottom: -8px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import React, { memo, useCallback, useEffect } from "react";
|
||||
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
import { pushPanel } from "../../../../../actions/panelActions";
|
||||
import TItemCard from "../../../../../components/TItemCard/TItemCard";
|
||||
import TVirtualGridList from "../../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../../../hooks/useScrollTo";
|
||||
import { panel_names } from "../../../../../utils/Config";
|
||||
import css from "./ShowroomProductList.module.less";
|
||||
|
||||
export default memo(function ShowroomProductList({
|
||||
roomThemeProducts,
|
||||
selectedPatnrId,
|
||||
selectedRoomId,
|
||||
}) {
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
scrollLeft();
|
||||
}, [selectedPatnrId, selectedRoomId]);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const {
|
||||
offerInfo,
|
||||
patnrId,
|
||||
// prdtExpsOrd,
|
||||
prdtId,
|
||||
prdtImgUrl,
|
||||
prdtNm,
|
||||
priceInfo,
|
||||
} = roomThemeProducts[index];
|
||||
|
||||
const handleClick = () => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: { patnrId, prdtId },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<TItemCard
|
||||
imageAlt={prdtNm}
|
||||
imageSource={prdtImgUrl}
|
||||
onClick={handleClick}
|
||||
offerInfo={offerInfo}
|
||||
priceInfo={priceInfo}
|
||||
productId={prdtId}
|
||||
productName={prdtNm}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[roomThemeProducts, dispatch]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={css.container}>
|
||||
{roomThemeProducts && (
|
||||
<TVirtualGridList
|
||||
cbScrollTo={getScrollTo}
|
||||
className={css.tVirtualGridList}
|
||||
dataSize={roomThemeProducts.length}
|
||||
direction="horizontal"
|
||||
itemHeight={438}
|
||||
itemWidth={324}
|
||||
spacing={18}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
@import "../../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex();
|
||||
overflow: hidden;
|
||||
.size(@w: calc(100% - 663px), @h: 482px);
|
||||
padding-left: 18px;
|
||||
|
||||
// tVirtualGridListContainer
|
||||
> div:nth-child(1) {
|
||||
.size(@w: 100%, @h: inherit);
|
||||
|
||||
> div:nth-child(1) {
|
||||
padding: 22px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "ShowroomProductList.jsx",
|
||||
"style": [
|
||||
"ShowroomProductList.moduel.less"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import React, { memo } from "react";
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import CustomImage from "../../../../../components/CustomImage/CustomImage";
|
||||
import css from "./ShowroomThumbnailCard.module.less";
|
||||
|
||||
const SpottableComponent = Spottable("figure");
|
||||
|
||||
export default memo(function ShowroomThumbnailCard({ thumbnailUrl, ...rest }) {
|
||||
return (
|
||||
<SpottableComponent className={css.card} {...rest}>
|
||||
<CustomImage alt="" delay={0} loading="lazy" src={thumbnailUrl} />
|
||||
</SpottableComponent>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
@import "../../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../../style/utils.module.less";
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
.size(@w: 663px, @h:438px);
|
||||
padding: 18px;
|
||||
background-color: @COLOR_WHITE;
|
||||
border: solid 1px @COLOR_WHITE;
|
||||
border-radius: 12px;
|
||||
|
||||
> img {
|
||||
.size(@w: 627px, @h:402px);
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "ShowroomThumbnailCard.jsx",
|
||||
"style": [
|
||||
"ShowroomThumbnailCard.module.less"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "ShowroomContents.jsx",
|
||||
"style": [
|
||||
"ShowroomContents.module.less"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import {
|
||||
getContainerId,
|
||||
setContainerLastFocusedElement,
|
||||
} from "@enact/spotlight/src/container";
|
||||
|
||||
import TButton, { TYPES } from "../../../../components/TButton/TButton";
|
||||
import TScroller from "../../../../components/TScroller/TScroller";
|
||||
import useScrollReset from "../../../../hooks/useScrollReset";
|
||||
import useScrollTo from "../../../../hooks/useScrollTo";
|
||||
import css from "./ShowroomNav.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"nav"
|
||||
);
|
||||
|
||||
export default function ShowroomNav({
|
||||
brandShowroomInfo,
|
||||
selectedPatnrId,
|
||||
selectedRoomId,
|
||||
setSelectedRoomId,
|
||||
}) {
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
const { handleScrollReset, handleStopScrolling } = useScrollReset(
|
||||
scrollLeft,
|
||||
true
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const containerId = "showroomNavId";
|
||||
const container = document.getElementById(containerId);
|
||||
|
||||
if (container) {
|
||||
const childrenId = getContainerId(container?.children[0].children[0]);
|
||||
childrenId &&
|
||||
setContainerLastFocusedElement(null, [containerId, childrenId]);
|
||||
}
|
||||
|
||||
scrollLeft();
|
||||
}, [selectedPatnrId]);
|
||||
|
||||
const handleBlur = useCallback((index) => {
|
||||
if (index !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleStopScrolling();
|
||||
}, []);
|
||||
|
||||
const handleClick = useCallback((roomId) => {
|
||||
setSelectedRoomId(roomId);
|
||||
}, []);
|
||||
|
||||
const handleFocus = useCallback((index) => {
|
||||
if (index !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleScrollReset();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Container
|
||||
className={css.nav}
|
||||
id={"showroomNavId"}
|
||||
spotlightId={"showroomNavId"}
|
||||
>
|
||||
<TScroller
|
||||
cbScrollTo={getScrollTo}
|
||||
direction="horizontal"
|
||||
noScrollByWheel
|
||||
>
|
||||
<ul>
|
||||
{brandShowroomInfo &&
|
||||
brandShowroomInfo.map(({ roomId, roomNm }, index) => (
|
||||
<li key={"brandShowroomInfo-" + roomId}>
|
||||
<TButton
|
||||
className={
|
||||
selectedRoomId && selectedRoomId === roomId && css.selected
|
||||
}
|
||||
onBlur={() => handleBlur(index)}
|
||||
onClick={() => handleClick(roomId)}
|
||||
onFocus={() => handleFocus(index)}
|
||||
selected={selectedRoomId && selectedRoomId === roomId}
|
||||
type={TYPES.oneDepthCategory}
|
||||
>
|
||||
{roomNm}
|
||||
</TButton>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</TScroller>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.nav {
|
||||
position: relative;
|
||||
.size(@w: 100%, @h: 162px);
|
||||
margin-bottom: 30px;
|
||||
padding-right: 1px;
|
||||
z-index: 2;
|
||||
|
||||
// tScroller
|
||||
> div:nth-child(1) {
|
||||
.size(@w: inherit, @h: inherit);
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
.size(@w: 100%, @h: 144px);
|
||||
background-color: #ddd;
|
||||
content: "";
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: inherit;
|
||||
padding-left: 60px;
|
||||
border-bottom: 18px solid transparent;
|
||||
|
||||
li {
|
||||
flex: none;
|
||||
margin-right: 12px;
|
||||
|
||||
> div {
|
||||
position: relative;
|
||||
|
||||
&.selected {
|
||||
&::before {
|
||||
position: absolute;
|
||||
bottom: -62px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
.size(@w: 0, @h: 0);
|
||||
border-top: 18px solid #ddd;
|
||||
border-right: 18px solid transparent;
|
||||
border-bottom: 18px solid transparent;
|
||||
border-left: 18px solid transparent;
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "ShowroomNav.jsx",
|
||||
"style": [
|
||||
"ShowroomNav.module.less"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "Showroom.jsx",
|
||||
"style": [
|
||||
"Showroom.module.less"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user