[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:
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user