Files
shoptime/com.twin.app.shoptime/src/views/DetailPanel/components/CustomDropDown.new.jsx
junghoon86.park 80c593e6f0 [상품 상세]
- 상풉 옵션별 ID노출 처리.
2025-12-08 20:10:02 +09:00

157 lines
4.6 KiB
JavaScript

import React, {
useCallback,
useEffect,
useState,
} from 'react';
import classNames from 'classnames';
import Spotlight from '@enact/spotlight';
import Spottable from '@enact/spotlight/Spottable';
import iconDownArrow
from '../../../../assets/images/btn/btn-dropdown-nor@3x.png';
import styles from './CustomDropDown.new.module.less';
const SpottableDiv = Spottable('div');
const CustomDropDown = ({
className,
options = [],
selectedIndex = 0,
onSelect,
spotlightId,
placeholder = 'Select option',
onSpotlightUp,
disabled = false,
}) => {
const [isOpen, setIsOpen] = useState(false);
// 옵션을 표준화 (문자열 또는 객체 처리)
const normalizeOption = (option) => {
if (typeof option === 'string') {
return { label: option, disabled: false, imageUrl: null };
}
return { ...option, imageUrl: option.imageUrl || null };
};
const normalizedOptions = options.map(normalizeOption);
const handleToggle = useCallback(() => {
const newIsOpen = !isOpen;
setIsOpen(newIsOpen);
if (!newIsOpen) {
setTimeout(() => {
if (spotlightId) {
Spotlight.focus(spotlightId);
}
}, 50);
}
}, [isOpen, spotlightId]);
const handleOptionSelect = useCallback(
(index, optionDisabled) => {
// disabled된 옵션은 선택 불가
if (optionDisabled) {
return;
}
setIsOpen(false);
if (onSelect) {
onSelect({ selected: index });
}
setTimeout(() => {
if (spotlightId) {
Spotlight.focus(spotlightId);
}
}, 50);
},
[onSelect, spotlightId]
);
const selectedOption = normalizedOptions[selectedIndex];
const selectedLabel = selectedOption?.label || placeholder;
const selectedId = selectedOption?.prodOptCdCval ? selectedOption?.prodOptCdCval : null;
const selectedImage = selectedOption?.imageUrl;
return (
<div className={`${styles.custom_dropdown} ${className || ''}`}>
<SpottableDiv
className={`${styles.custom_dropdown__button} ${
isOpen ? styles.custom_dropdown__button_expanded : ''
}`}
onClick={handleToggle}
spotlightId={spotlightId}
onSpotlightUp={onSpotlightUp}
spotlightDisabled={disabled}
>
<div className={styles.custom_dropdown__content}>
{selectedImage && (
<img
src={selectedImage}
alt=""
className={styles.custom_dropdown__image}
/>
)}
<div className={styles.custom_dropdown__text}>{selectedLabel} {selectedId ? `ID : ${selectedId}` : ''}</div>
</div>
<div className={styles.custom_dropdown__icon}>
<img src={iconDownArrow} alt="dropdown arrow" />
</div>
</SpottableDiv>
{isOpen && (
<div className={styles.custom_dropdown__list}>
{normalizedOptions
.slice()
.reverse()
.map((option, reverseIndex) => {
const originalIndex = normalizedOptions.length - 1 - reverseIndex;
const isOptionDisabled = option.disabled;
return (
<SpottableDiv
key={originalIndex}
className={classNames(
styles.custom_dropdown__option,
originalIndex === selectedIndex
? styles.custom_dropdown__option_selected
: '',
isOptionDisabled
? styles.custom_dropdown__option_disabled
: ''
)}
onClick={() =>
handleOptionSelect(originalIndex, isOptionDisabled)
}
spotlightDisabled={isOptionDisabled}
>
{option.imageUrl && (
<img
src={option.imageUrl}
className={styles.custom_dropdown__image}
/>
)}
<span className={styles.custom_dropdown__optname}>
{option.label} {option.prodOptCdCval ? `ID : ${option.prodOptCdCval}` : ''}
</span>
{isOptionDisabled ? (
<span className={styles.custom_dropdown__lasttxt}>
SOLD OUT
</span>
) : (
<span className={styles.custom_dropdown__lasttxt}>
{option.price}
</span>
)}
</SpottableDiv>
);
})}
</div>
)}
</div>
);
};
export default CustomDropDown;