diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.new.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.new.jsx
index fbf88f78..ff489037 100644
--- a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.new.jsx
+++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.new.jsx
@@ -17,16 +17,16 @@ import { sendLogGNB, sendLogTotalRecommend } from '../../actions/logActions';
import { getMyRecommandedKeyword } from '../../actions/myPageActions';
import { popPanel, updatePanel } from '../../actions/panelActions';
import { getSearch, resetSearch, searchMain } from '../../actions/searchActions';
-import {
- showErrorToast,
- showInfoToast,
- showSearchErrorToast,
- showSearchSuccessToast,
- showSuccessToast,
- showWarningToast,
-} from '../../actions/toastActions';
+// import {
+// showErrorToast,
+// showInfoToast,
+// showSearchErrorToast,
+// showSearchSuccessToast,
+// showSuccessToast,
+// showWarningToast,
+// } from '../../actions/toastActions';
import TBody from '../../components/TBody/TBody';
-import TInput, { ICONS, KINDS } from '../../components/TInput/TInput';
+import TInput, { ICONS, KINDS } from './TInput/TInput';
import TPanel from '../../components/TPanel/TPanel';
import TScroller from '../../components/TScroller/TScroller';
import TVerticalPagenator from '../../components/TVerticalPagenator/TVerticalPagenator';
@@ -101,6 +101,16 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId, scrollOpt
setInputFocus(false);
}, [inputFocus]);
+ // TInput의 입력 모드 상태 (webOS 키보드가 뜨는지 여부)
+ const [isInputModeActive, setIsInputModeActive] = useState(false);
+ const handleInputModeChange = useCallback((isActive) => {
+ console.log(
+ '[SearchPanel] TInput 입력 모드:',
+ isActive ? '활성화 (키보드 표시)' : '비활성화 (키보드 숨김)'
+ );
+ setIsInputModeActive(isActive);
+ }, []);
+
let searchQueryRef = usePrevious(searchQuery);
let isOnTopRef = usePrevious(isOnTop);
@@ -281,7 +291,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId, scrollOpt
);
// 검색 시작 알림 (선택사항)
- dispatch(showSuccessToast(`"${query}" 검색 중...`, { duration: 2000 }));
+ // dispatch(showSuccessToast(`"${query}" 검색 중...`, { duration: 2000 }));
} else {
dispatch(resetSearch());
}
@@ -473,10 +483,10 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId, scrollOpt
}, []);
// 테스트용 Toast 핸들러들
- const handleTestToasts = useCallback(() => {
- // 간단한 Toast 테스트
- dispatch(showSuccessToast('테스트 메시지입니다', { duration: 3000 }));
- }, [dispatch]);
+ // const handleTestToasts = useCallback(() => {
+ // // 간단한 Toast 테스트
+ // dispatch(showSuccessToast('테스트 메시지입니다', { duration: 3000 }));
+ // }, [dispatch]);
// ProductCard 컴포넌트
const renderItem = useCallback(
@@ -565,28 +575,36 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId, scrollOpt
spotlightId={SPOTLIGHT_IDS.SEARCH_INPUT_LAYER}
>
-
{
- if (showVirtualKeyboard) {
- handleSearchSubmit(searchQuery);
- } else {
- setShowVirtualKeyboard(true);
- }
- }}
- onKeyDown={handleKeydown}
- onKeyUp={cursorPosition}
- spotlightId={SPOTLIGHT_IDS.SEARCH_INPUT_BOX}
- forcedSpotlight="recent-keyword-0"
- tabIndex={0}
- spotlightBoxDisabled={true}
- onFocus={_onFocus}
- onBlur={_onBlur}
- />
+
+ {
+ if (showVirtualKeyboard) {
+ handleSearchSubmit(searchQuery);
+ } else {
+ setShowVirtualKeyboard(true);
+ }
+ }}
+ onKeyDown={handleKeydown}
+ onKeyUp={cursorPosition}
+ spotlightId={SPOTLIGHT_IDS.SEARCH_INPUT_BOX}
+ forcedSpotlight="recent-keyword-0"
+ tabIndex={0}
+ spotlightBoxDisabled={true}
+ onFocus={_onFocus}
+ onBlur={_onBlur}
+ onInputModeChange={handleInputModeChange}
+ />
+
div {
&:focus,
diff --git a/com.twin.app.shoptime/src/views/SearchPanel/TInput/TInput.jsx b/com.twin.app.shoptime/src/views/SearchPanel/TInput/TInput.jsx
new file mode 100644
index 00000000..ead6042a
--- /dev/null
+++ b/com.twin.app.shoptime/src/views/SearchPanel/TInput/TInput.jsx
@@ -0,0 +1,151 @@
+import React, { useCallback, useState } from 'react';
+
+import classNames from 'classnames';
+
+import { InputField } from '@enact/sandstone/Input';
+import Spotlight from '@enact/spotlight';
+import Spottable from '@enact/spotlight/Spottable';
+
+import useScrollReset from '../../../hooks/useScrollReset';
+import TIconButton from '../../../components/TIconButton/TIconButton';
+import css from './TInput.module.less';
+
+const KINDS = { withIcon: 'withIcon' };
+const ICONS = { search: 'search' };
+const BORDER = { none: 'none' };
+const COLOR = { transparent: 'transparent' };
+
+const Container = Spottable('div');
+export default function TInput({
+ kind,
+ icon,
+ border,
+ color,
+ className,
+ spotlightDisabled,
+ spotlightBoxDisabled,
+ spotlightId,
+ disabled,
+ onKeyDown,
+ scrollTop,
+ onIconClick,
+ forcedSpotlight,
+ onFocus,
+ onBlur,
+ onInputModeChange, // 입력 모드 변경 콜백
+ ...rest
+}) {
+ const { handleScrollReset, handleStopScrolling } = useScrollReset(scrollTop);
+
+ // 입력 가능 모드 상태 (webOS 키보드가 뜨는 상태)
+ const [isInputActive, setIsInputActive] = useState(false);
+
+ const handleContainerClick = useCallback((e) => {
+ if (e.key === 'ArrrowLeft' || e.key === 'Left') {
+ Spotlight.focus('spotlight_search');
+ } else {
+ Spotlight.focus('input-field-box');
+ }
+ }, []);
+
+ const handleButtonKeyDown = useCallback((e) => {
+ if (e.key === 'ArrowDown' || e.key === 'Down') {
+ Spotlight.move('down');
+ }
+
+ if (e.key === 'ArrowLeft' || e.key === 'Left') {
+ e.preventDefault();
+ e.stopPropagation();
+ Spotlight.focus('input-field-box');
+ }
+ }, []);
+
+ const handleBoxKeyDown = useCallback((e) => {
+ if (e.key === 'ArrowLeft' || e.key === 'Left') {
+ const currentElement = e.currentTarget;
+ const inputElement = currentElement.querySelector('input');
+
+ if (inputElement.value.length === 0) {
+ e.preventDefault();
+ e.stopPropagation();
+ Spotlight.focus('spotlight_search');
+ }
+ }
+ }, []);
+
+ //focus,blur 추가
+ const _onFocus = useCallback(() => {
+ if (onFocus) {
+ onFocus();
+ }
+ handleScrollReset();
+ }, [onFocus]);
+ const _onBlur = useCallback(() => {
+ if (onBlur) {
+ onBlur();
+ }
+ handleStopScrolling();
+ }, [onBlur]);
+
+ // onActivate: 내부 input에 실제로 포커스가 가서 입력 가능한 상태 (webOS 키보드가 뜨는 시점)
+ const _onActivate = useCallback(() => {
+ console.log('[TInput] Input 모드 활성화 - webOS 키보드 표시됨, isInputActive:', true);
+ setIsInputActive(true);
+ // 부모 컴포넌트에 모드 변경 알림
+ if (onInputModeChange) {
+ onInputModeChange(true);
+ }
+ }, [onInputModeChange]);
+
+ // onDeactivate: 내부 input에서 포커스가 빠져나감 (webOS 키보드가 사라지는 시점)
+ const _onDeactivate = useCallback(() => {
+ console.log('[TInput] Input 모드 비활성화 - webOS 키보드 숨김, isInputActive:', false);
+ setIsInputActive(false);
+ // 부모 컴포넌트에 모드 변경 알림
+ if (onInputModeChange) {
+ onInputModeChange(false);
+ }
+ }, [onInputModeChange]);
+
+ console.log('[TInput Render] isInputActive:', isInputActive);
+
+ return (
+
+
+
+ {kind === 'withIcon' && (
+
+ )}
+
+ );
+}
+
+export { BORDER, COLOR, ICONS, KINDS };
diff --git a/com.twin.app.shoptime/src/views/SearchPanel/TInput/TInput.module.less b/com.twin.app.shoptime/src/views/SearchPanel/TInput/TInput.module.less
new file mode 100644
index 00000000..28fde3b4
--- /dev/null
+++ b/com.twin.app.shoptime/src/views/SearchPanel/TInput/TInput.module.less
@@ -0,0 +1,74 @@
+@import "../../../style/CommonStyle.module.less";
+@import "../../../style/utils.module.less";
+
+.container {
+ width: fit-content;
+ height: fit-content;
+ position: relative;
+
+ // 입력 가능 모드일 때 Container 스타일
+ &.containerActive {
+ .input {
+ background-color: #ffff00 !important; // 노란색 배경
+ }
+ }
+
+ .input {
+ margin-right: 0;
+ margin-left: 0;
+ height: 100px !important;
+ padding: 20px 40px 20px 50px !important;
+ border-radius: 50px;
+ border: none !important; // SearchPanel의 wrapper에서 테두리 처리
+ background-color: #fff !important;
+ width: 100% !important;
+
+ &:focus {
+ box-shadow: none !important; // SearchPanel의 wrapper에서 포커스 처리
+ border: none !important;
+ }
+
+ > div {
+ display: none;
+ }
+
+ > input {
+ font-family: @baseFont;
+ color: @COLOR_GRAY07 !important;
+ height: inherit !important;
+ line-height: inherit !important;
+ }
+ }
+
+ // 입력 가능 모드 (webOS 키보드가 뜨는 상태)
+ // .input과 함께 사용되므로 더 구체적인 선택자 필요
+ .input.inputActive {
+ background-color: #ffff00 !important; // 노란색 배경
+ }
+
+ .withIcon {
+ > div {
+ display: none;
+ }
+ }
+
+ .search {
+ position: absolute;
+ background-repeat: no-repeat;
+ background-position: center top;
+ background-size: cover;
+ width: 40px;
+ height: 40px;
+ top: 50%;
+ right: 30px;
+ transform: translateY(-50%);
+ background-image: url("../../../../assets/images/searchpanel/ico_search_submit.png");
+
+ &:focus {
+ width: 42px;
+ height: 42px;
+ transform: translateY(-50%) scale(1.1);
+ background-position: center bottom;
+ }
+ }
+}
diff --git a/com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx b/com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx
index dbfb05fd..f1306cff 100644
--- a/com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx
+++ b/com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx
@@ -12,7 +12,7 @@ import Spottable from '@enact/spotlight/Spottable';
import micIcon from '../../../../assets/images/searchpanel/image-mic.png';
import { getShopperHouseSearch } from '../../../actions/searchActions';
import TFullPopup from '../../../components/TFullPopup/TFullPopup';
-import TInput, { ICONS, KINDS } from '../../../components/TInput/TInput';
+import TInput, { ICONS, KINDS } from '../TInput/TInput';
import { useWebSpeech } from '../../../hooks/useWebSpeech';
import VoiceListening from './modes/VoiceListening';
import VoiceNotRecognized from './modes/VoiceNotRecognized';
@@ -334,9 +334,9 @@ const VoiceInputOverlay = ({
setCurrentMode(mode);
setVoiceInputMode(null);
- // Overlay 내부로 포커스 이동
+ // 마이크 버튼으로 포커스 이동
setTimeout(() => {
- Spotlight.focus(OVERLAY_SPOTLIGHT_ID);
+ Spotlight.focus(MIC_SPOTLIGHT_ID);
}, 100);
} else {
// Overlay가 닫힐 때 원래 포커스 복원 및 상태 초기화
diff --git a/com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/modes/VoiceNotRecognized.module.less b/com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/modes/VoiceNotRecognized.module.less
index 8d107774..dd951fdf 100644
--- a/com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/modes/VoiceNotRecognized.module.less
+++ b/com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/modes/VoiceNotRecognized.module.less
@@ -26,6 +26,7 @@
font-weight: 700;
letter-spacing: -1px;
color: #fff;
+ line-height: 1.2;
}
}
}