[251211] feat: FeaturedBrandsPanel , TopBannerImage Modal

🕐 커밋 시간: 2025. 12. 11. 14:04:14

📊 변경 통계:
  • 총 파일: 3개
  • 추가: +63줄
  • 삭제: -25줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/components/GlobalPopup/GlobalPopup.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.module.less

🔧 주요 변경 내용:
  • UI 컴포넌트 아키텍처 개선
  • 소규모 기능 개선
This commit is contained in:
2025-12-11 14:04:15 +09:00
parent 7971bbc1db
commit f5621b0c55
3 changed files with 63 additions and 25 deletions

View File

@@ -6,6 +6,7 @@
import React, {
useCallback,
useEffect,
useMemo,
} from 'react';
@@ -14,6 +15,8 @@ import {
useSelector,
} from 'react-redux';
import Spotlight from '@enact/spotlight';
import { setHidePopup } from '../../actions/commonActions';
import { getPopupConfig } from '../../constants/popupConfig';
import usePrevious from '../../hooks/usePrevious';
@@ -139,6 +142,18 @@ const GlobalPopup = () => {
setImageDimensions(dimensions);
}, []);
// Spotlight 제어: 팝업 오픈/클로즈 시 포커스 트래핑
useEffect(() => {
if (popupVisible && activePopup === 'topBannerImagePopup') {
console.log("[GLOBAL-POPUP] Pausing Spotlight for modal popup");
Spotlight.pause();
return () => {
console.log("[GLOBAL-POPUP] Resuming Spotlight after modal close");
Spotlight.resume();
};
}
}, [popupVisible, activePopup]);
// 현재 팝업 설정
const currentConfig = useMemo(() => {
if (!activePopup) return null;
@@ -231,27 +246,33 @@ const GlobalPopup = () => {
const popupHeight = '804px';
return (
<div style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: 9999
}}>
<div style={{
width: popupWidth,
height: popupHeight,
backgroundColor: 'white',
borderRadius: '12px',
overflow: 'hidden',
<div
style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
flexDirection: 'column'
}}>
justifyContent: 'center',
alignItems: 'center',
zIndex: 9999
}}
onClick={handlers.handleClose}
>
<div
style={{
width: popupWidth,
height: popupHeight,
backgroundColor: 'white',
borderRadius: '12px',
overflow: 'hidden',
display: 'flex',
flexDirection: 'column'
}}
onClick={(e) => e.stopPropagation()}
>
<TopBannerPopup
title={popupData?.pupBanrImgNm || 'Popup'}
imageUrl={popupData?.pupBanrImgUrl}

View File

@@ -1,4 +1,4 @@
import React, { memo, useCallback, useState } from "react";
import React, { memo, useCallback, useState, useEffect, useRef } from "react";
import { useDispatch } from "react-redux";
import { setHidePopup } from "../../../actions/commonActions";
import css from "./TopBannerPopup.module.less";
@@ -6,6 +6,7 @@ import css from "./TopBannerPopup.module.less";
const TopBannerPopup = memo(({ title, imageUrl, imageAlt, onImageLoad }) => {
const dispatch = useDispatch();
const [imageDimensions, setImageDimensions] = useState({ width: 0, height: 0 });
const closeButtonRef = useRef(null);
const handleImageLoad = useCallback((e) => {
const img = e.target;
@@ -29,6 +30,14 @@ const TopBannerPopup = memo(({ title, imageUrl, imageAlt, onImageLoad }) => {
dispatch(setHidePopup());
}, [dispatch]);
// 팝업이 마운트되었을 때 Close 버튼에 포커스
useEffect(() => {
console.log("[TOP-BANNER-POPUP] Component mounted - focusing close button");
if (closeButtonRef.current) {
closeButtonRef.current.focus();
}
}, []);
return (
<div className={css.container}>
{/* Title Section */}
@@ -48,7 +57,12 @@ const TopBannerPopup = memo(({ title, imageUrl, imageAlt, onImageLoad }) => {
{/* Button Section */}
<div className={css.buttonSection}>
<button className={css.closeButton} onClick={handleClose} aria-label="Close popup">
<button
ref={closeButtonRef}
className={css.closeButton}
onClick={handleClose}
aria-label="Close popup"
>
CLOSE
</button>
</div>

View File

@@ -1,3 +1,6 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.container {
width: 100%;
height: 100%;
@@ -86,12 +89,12 @@
text-align: center;
&:hover {
background: #6a7278;
background: @PRIMARY_COLOR_RED;
}
&:focus {
outline: 2px solid #fff;
outline-offset: 2px;
background: @PRIMARY_COLOR_RED;
outline: none;
}
&:active {