[서치] howaboutthese 스타일 수정

- marquee부분은 아직 해결 못함.
This commit is contained in:
junghoon86.park
2025-10-23 20:59:06 +09:00
parent fa2bcb7866
commit bfe9ecce8b
4 changed files with 182 additions and 179 deletions

View File

@@ -1,25 +1,29 @@
import React, { useCallback, useMemo } from 'react';
import React, {
useCallback,
useMemo,
} from 'react';
import PropTypes from 'prop-types';
import { useDispatch } from 'react-redux';
import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable';
import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator';
import { getShopperHouseSearch } from '../../../actions/searchActions';
import icShoptime from '../../../../assets/images/icons/ic-shoptime.png';
import { getShopperHouseSearch } from '../../../actions/searchActions';
import css from './HowAboutThese.module.less';
const OverlayContainer = SpotlightContainerDecorator(
{
enterTo: 'default-element',
restrict: 'self-only',
enterTo: "default-element",
restrict: "self-only",
},
'div'
"div"
);
const SpottableBubble = Spottable('div');
const SpottableSeeMoreButton = Spottable('div');
const SpottableBubble = Spottable("div");
const SpottableSeeMoreButton = Spottable("div");
const HowAboutThese = ({ relativeQueries = [], onQueryClick, onClose }) => {
const dispatch = useDispatch();
@@ -29,18 +33,18 @@ const HowAboutThese = ({ relativeQueries = [], onQueryClick, onClose }) => {
return relativeQueries.length > 0
? relativeQueries
: [
'What are some luxury skincare products',
'Popular makeup gift sets suitable for mother',
'Which anti-aging cosmetics in 50s or 60s',
'Elegant fragrance or cosmetic bundles',
'What beauty brands offer special gift boxes',
"What are some luxury skincare products",
"Popular makeup gift sets suitable for mother",
"Which anti-aging cosmetics in 50s or 60s",
"Elegant fragrance or cosmetic bundles",
"What beauty brands offer special gift boxes",
];
}, [relativeQueries]);
// 검색어 클릭 핸들러
const handleQueryClick = useCallback(
(query) => {
console.log('[HowAboutThese] Query clicked:', query);
console.log("[HowAboutThese] Query clicked:", query);
// 외부에서 전달된 onQueryClick이 있으면 사용
if (onQueryClick) {
@@ -61,7 +65,9 @@ const HowAboutThese = ({ relativeQueries = [], onQueryClick, onClose }) => {
// "COLLAPSE" 버튼 클릭 핸들러 (Full 버전을 Small로 축소)
const handleCollapseClick = useCallback(() => {
console.log('[HowAboutThese] Collapse clicked - 축소하여 Small 버전으로 전환');
console.log(
"[HowAboutThese] Collapse clicked - 축소하여 Small 버전으로 전환"
);
if (onClose) {
onClose();
}
@@ -72,27 +78,31 @@ const HowAboutThese = ({ relativeQueries = [], onQueryClick, onClose }) => {
const remainingQueries = queries.slice(1);
return (
<OverlayContainer className={css.container}>
{/* Header Section */}
<div className={css.header}>
<div className={css.headerLeft}>
<div className={css.headerContent}>
{/* 아이콘 */}
<div className={css.iconPlaceholder}>
<img src={icShoptime} alt="Shoptime" className={css.icon} />
</div>
<div className={css.titleContainer}>
<div className={css.title}>How about these?</div>
<OverlayContainer className={css.bgcontainer}>
<div className={css.container}>
{/* Header Section */}
<div className={css.header}>
<div className={css.headerLeft}>
<div className={css.headerContent}>
{/* 아이콘 */}
<div className={css.iconPlaceholder}>
<img src={icShoptime} alt="Shoptime" className={css.icon} />
</div>
<div className={css.titleContainer}>
<div className={css.title}>How about these?</div>
</div>
</div>
</div>
</div>
<div className={css.headerRight}>
<SpottableSeeMoreButton className={css.seeMoreButton} onClick={handleCollapseClick}>
<span className={css.seeMoreText}>COLLAPSE</span>
</SpottableSeeMoreButton>
<div className={css.headerRight}>
<SpottableSeeMoreButton
className={css.seeMoreButton}
onClick={handleCollapseClick}
>
<span className={css.seeMoreText}>COLLAPSE</span>
</SpottableSeeMoreButton>
</div>
</div>
</div>
{/* Bubbles Section */}
<div className={css.bubblesContainer}>
{/* 첫 번째 버블 - 핑크색 */}

View File

@@ -1,35 +1,34 @@
@import "../../../style/CommonStyle.module.less";
.container {
@import "../../../style/utils.module.less";
.bgcontainer {
width: 100%;
height: 860px;
padding: 32px 60px; // Increased top/bottom padding from 30px to 32px to accommodate 2px focus border
display: inline-flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
height: calc(100vh - 210px);
background: linear-gradient(
360deg,
rgba(221.25, 221.25, 221.25, 0) 0%,
rgba(221.25, 221.25, 221.25, 0.85) 57%,
rgba(221.25, 221.25, 221.25, 0) 2%,
rgba(221.25, 221.25, 221.25, 0.85) 58%,
rgba(221.25, 221.25, 221.25, 0.9) 80%,
rgba(221, 221, 221, 0.9) 100%
),
linear-gradient(
360deg,
rgba(221.25, 221.25, 221.25, 0) 35%,
#DDDDDD 80%,
#DDDDDD 100%
);
}
.container {
width: 100%;
height: 128px;
padding: 32px 60px;
background: #dddddd;
display: inline-flex;
justify-content: flex-start;
align-items: center;
}
/* Header Section */
.header {
align-self: stretch;
display: inline-flex;
justify-content: flex-start;
width: 100%;
height: 48px;
position: relative;
flex-shrink: 0; // 고정 너비 유지
display: flex;
align-items: center;
margin-bottom: 19px;
}
.headerLeft {
@@ -47,9 +46,7 @@
.iconPlaceholder {
width: 48px;
height: 48px;
position: absolute;
left: 0;
top: 0;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
@@ -74,13 +71,10 @@
.title {
color: #272727;
font-size: 24px;
font-family: 'Roboto', sans-serif;
font-family: "Roboto", sans-serif;
font-weight: 700;
text-align: center;
display: flex;
justify-content: center;
flex-direction: column;
word-wrap: break-word;
white-space: nowrap; // ⭐ 1줄로 표시
line-height: 1; // 텍스트 높이 조정
}
.headerRight {
@@ -109,20 +103,15 @@
transition: background-color 0.2s ease;
&:focus {
outline: 2px solid @PRIMARY_COLOR_RED;
outline-offset: 2px;
background: @PRIMARY_COLOR_RED;
box-shadow: 0 0 22px rgba(0, 0, 0, 0.5);
}
&:hover {
background: #666666;
}
}
.seeMoreText {
color: white;
font-size: 24px;
font-family: 'LG Smart UI', sans-serif;
font-family: "LG Smart UI", sans-serif;
font-weight: 700;
line-height: 24px;
text-align: center;
@@ -133,10 +122,12 @@
.bubblesContainer {
align-self: stretch;
display: flex;
flex-direction: column;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
overflow: hidden;
overflow: auto hidden;
width: 100%;
padding: 0 60px;
}
.bubblesContainer > * + * {
@@ -145,36 +136,38 @@
/* Primary Bubble (Pink) */
.bubblePrimary {
max-width: 500px;
height: 64px;
padding: 16px 20px;
background: #CE1C5E;
padding: 0px 20px;
background: @COLOR_WHITE;
border-radius: 30px;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
outline: 1px solid #C70850;
outline-offset: -1px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
border: 2px solid @COLOR_WHITE;
text-align: left;
line-height: 64px;
cursor: pointer;
transition: all 0.2s ease;
box-sizing: border-box;
&:focus {
outline: 2px solid @PRIMARY_COLOR_RED;
outline-offset: 2px;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25), 0 0 0 2px @PRIMARY_COLOR_RED, 0 0 22px rgba(0, 0, 0, 0.5);
}
.elip(1);
&:focus,
&:hover {
background: #b91a52;
transform: translateY(-1px);
box-shadow: 0 0 22px rgba(0, 0, 0, 0.5);
background: #ce1c5e;
border: 2px solid @PRIMARY_COLOR_RED;
.bubbleText {
color: #fff;
}
}
&:active {
transform: translateY(0);
.bubbleText {
color: black;
font-size: 24px;
font-family: "LG Smart UI", sans-serif;
font-weight: 700;
line-height: 24px;
text-align: center;
word-wrap: break-word;
width: 100%;
}
> * + * {
margin-top: 20px;
}
@@ -182,51 +175,49 @@
/* Secondary Bubbles (White) */
.bubbleSecondary {
padding: 20px;
background: white;
border-radius: 100px;
outline: 1px solid #DADADA;
outline-offset: -1px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
max-width: 500px;
height: 64px;
padding: 0px 20px;
background: @COLOR_WHITE;
border-radius: 30px;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
border: 2px solid @COLOR_WHITE;
text-align: left;
line-height: 64px;
cursor: pointer;
transition: all 0.2s ease;
box-sizing: border-box;
&:focus {
outline: 2px solid @PRIMARY_COLOR_RED;
outline-offset: 2px;
box-shadow: 0 0 22px rgba(0, 0, 0, 0.5);
}
.elip(1);
&:focus,
&:hover {
background: #f8f8f8;
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 22px rgba(0, 0, 0, 0.5);
background: #ce1c5e;
border: 2px solid @PRIMARY_COLOR_RED;
.bubbleText {
color: #fff;
}
}
&:active {
transform: translateY(0);
.bubbleText {
color: black;
font-size: 24px;
font-family: "LG Smart UI", sans-serif;
font-weight: 700;
line-height: 24px;
text-align: center;
word-wrap: break-word;
width: 100%;
}
> * + * {
margin-top: 10px;
}
}
.bubbleText {
color: #EAEAEA;
color: black;
font-size: 24px;
font-family: 'LG Smart UI', sans-serif;
font-family: "LG Smart UI", sans-serif;
font-weight: 700;
line-height: 24px;
text-align: center;
word-wrap: break-word;
width: 100%;
.bubbleSecondary & {
color: black;
}
}
}

View File

@@ -3,23 +3,25 @@ import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { useDispatch } from 'react-redux';
import Marquee from '@enact/sandstone/Marquee';
import Spottable from '@enact/spotlight/Spottable';
import { getShopperHouseSearch } from '../../../actions/searchActions';
import icShoptime from '../../../../assets/images/icons/ic-shoptime.png';
import { getShopperHouseSearch } from '../../../actions/searchActions';
import TButton from '../../../components/TButton/TButton.jsx';
import css from './HowAboutThese.small.module.less';
const SpottableBubble = Spottable('div');
const SpottableSeeMoreButton = Spottable('div');
const Bubble = ({ query, onClick }) => (
<SpottableBubble className={css.bubble} onClick={() => onClick(query)}>
<div className={css.bubble} onClick={() => onClick(query)}>
<div className={css.bubbleText}>{query}</div>
</SpottableBubble>
</div>
);
const HowAboutTheseSmall = ({ relativeQueries = [], onQueryClick, onSeeMoreClick }) => {
const HowAboutTheseSmall = ({
relativeQueries = [],
onQueryClick,
onSeeMoreClick,
}) => {
const dispatch = useDispatch();
// 기본 relativeQueries가 없는 경우를 위한 fallback
@@ -27,15 +29,15 @@ const HowAboutTheseSmall = ({ relativeQueries = [], onQueryClick, onSeeMoreClick
relativeQueries.length > 0
? relativeQueries
: [
'What are some luxury skincare products',
'Popular makeup gift sets suitable for mother',
'Which anti-aging cosmetics in 50s or 60s',
"What are some luxury skincare products",
"Popular makeup gift sets suitable for mother",
"Which anti-aging cosmetics in 50s or 60s",
];
// 검색어 클릭 핸들러
const handleQueryClick = useCallback(
(query) => {
console.log('[HowAboutTheseSmall] Query clicked:', query);
console.log("[HowAboutTheseSmall] Query clicked:", query);
// 외부에서 전달된 onQueryClick이 있으면 사용
if (onQueryClick) {
@@ -51,7 +53,7 @@ const HowAboutTheseSmall = ({ relativeQueries = [], onQueryClick, onSeeMoreClick
// "SEE MORE" 버튼 클릭 핸들러
const handleSeeMoreClick = useCallback(() => {
console.log('[HowAboutTheseSmall] See More clicked');
console.log("[HowAboutTheseSmall] See More clicked");
// 외부에서 전달된 onSeeMoreClick이 있으면 사용
if (onSeeMoreClick) {
@@ -60,11 +62,11 @@ const HowAboutTheseSmall = ({ relativeQueries = [], onQueryClick, onSeeMoreClick
}
// 기본 동작: 확장된 뷰 표시 (나중에 구현)
console.log('[HowAboutTheseSmall] TODO: Show expanded view');
console.log("[HowAboutTheseSmall] TODO: Show expanded view");
}, [onSeeMoreClick]);
// 첫 번째 두 개의 쿼리만 표시 (small 버전)
const displayQueries = queries.slice(0, 2);
// 첫 번째 다섯개까지 쿼리만 표시 (small 버전)
const displayQueries = queries.slice(0, 5);
return (
<div className={css.container}>
@@ -80,26 +82,24 @@ const HowAboutTheseSmall = ({ relativeQueries = [], onQueryClick, onSeeMoreClick
</div>
{/* Bubbles Section */}
<div className={css.bubblesContainer}>
<Marquee className={css.bubblesContainer} marqueeOn="render">
{displayQueries.map((query, index) => (
<Bubble
key={`query-${index}`}
query={query}
onClick={handleQueryClick}
/>
))}
{/* Fade 효과를 위한 추가 요소 (피그마 디자인 참고) */}
{/* {queries.length > 2 && (
<div className={css.fadeContainer}>
<div className={css.fadeOverlay} />
<Bubble query={queries[2]} onClick={handleQueryClick} />
<div
className={css.bubble}
key={index}
onClick={() => handleQueryClick(query)}
>
<div className={css.bubbleText}>{query}</div>
</div>
)} */}
</div>
))}
</Marquee>
{/* See More Button */}
<TButton className={css.seeMoreButton} size="small" onClick={handleSeeMoreClick}>
<TButton
className={css.seeMoreButton}
size="small"
onClick={handleSeeMoreClick}
>
<div className={css.seeMoreText}>SEE MORE</div>
</TButton>
</div>

View File

@@ -1,12 +1,13 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.container {
width: 100%;
height: 100%;
padding: 32px 60px; // 상하 32px (30px + 2px for focus border), 좌우 60px
background: #DDDDDD;
background: #dddddd;
display: inline-flex;
justify-content: flex-start;
justify-content: space-between;
align-items: center;
}
@@ -51,7 +52,7 @@
.title {
color: #272727;
font-size: 24px;
font-family: 'Roboto', sans-serif;
font-family: "Roboto", sans-serif;
font-weight: 700;
white-space: nowrap; // ⭐ 1줄로 표시
line-height: 1; // 텍스트 높이 조정
@@ -59,37 +60,39 @@
/* Bubbles Section */
.bubblesContainer {
flex: 1 1 0;
overflow: hidden;
display: flex; // horizontal layout
justify-content: flex-start;
align-items: flex-start;
width: 1200px;
height: 64px;
> div {
> div {
display: flex;
justify-content: space-between;
}
}
}
.bubblesContainer > * + * {
margin-left: 15px;
}
// .bubblesContainer > * + * {
// margin-left: 15px;
// }
.bubble {
flex: none;
margin-right: 15px;
padding: 16px;
background: white;
border-radius: 100px;
border: 4px solid #DADADA;
display: inline-flex;
border: 4px solid #dadada;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
cursor: pointer;
transition: all 0.2s ease;
flex-shrink: 0; // 버블이 줄어들지 않도록
width: 300px;
.elip(@clamp:1);
&:focus {
border: 4px solid @PRIMARY_COLOR_RED;
}
&:hover {
background: #f8f8f8;
transform: translateY(-1px);
}
> * + * {
@@ -113,7 +116,7 @@
position: absolute;
background: linear-gradient(90deg, black 0%, rgba(102, 102, 102, 0) 60%);
border-radius: 100px;
border: 1px solid #DADADA;
border: 1px solid #dadada;
pointer-events: none; // 클릭 방지
}
@@ -127,12 +130,12 @@
text-align: center;
color: black;
font-size: 24px;
font-family: 'LG Smart UI', sans-serif;
font-family: "LG Smart UI", sans-serif;
font-weight: 700;
line-height: 24px;
white-space: nowrap; // ✨ 텍스트를 한 줄로 유지
text-overflow: ellipsis; // ✨ 넘치는 부분 "..." 표시
overflow: hidden; // ✨ 넘친 부분 숨김
white-space: nowrap; // ✨ 텍스트를 한 줄로 유지
text-overflow: ellipsis; // ✨ 넘치는 부분 "..." 표시
overflow: hidden; // ✨ 넘친 부분 숨김
}
/* See More Button */
@@ -149,8 +152,7 @@
flex-shrink: 0; // 고정 너비 유지
&:focus {
outline: 2px solid @PRIMARY_COLOR_RED;
outline-offset: 2px;
background: @PRIMARY_COLOR_RED;
box-shadow: 0 0 22px rgba(0, 0, 0, 0.5);
}
@@ -163,8 +165,8 @@
text-align: center;
color: white;
font-size: 24px;
font-family: 'LG Smart UI', sans-serif;
font-family: "LG Smart UI", sans-serif;
font-weight: 700;
line-height: 24px;
word-wrap: break-word;
}
}