diff --git a/resources/views/finance/journal-entries.blade.php b/resources/views/finance/journal-entries.blade.php
index 4e81b90d..0b7ea3a7 100644
--- a/resources/views/finance/journal-entries.blade.php
+++ b/resources/views/finance/journal-entries.blade.php
@@ -103,7 +103,10 @@
const [isOpen, setIsOpen] = useState(false);
const [search, setSearch] = useState('');
const [highlightIndex, setHighlightIndex] = useState(-1);
+ const [dropdownStyle, setDropdownStyle] = useState({});
const containerRef = useRef(null);
+ const triggerRef = useRef(null);
+ const dropdownRef = useRef(null);
const listRef = useRef(null);
const selectedItem = accountCodes.find(c => c.code === value);
@@ -119,7 +122,8 @@
useEffect(() => {
const handleClickOutside = (e) => {
- if (containerRef.current && !containerRef.current.contains(e.target)) {
+ if (containerRef.current && !containerRef.current.contains(e.target) &&
+ (!dropdownRef.current || !dropdownRef.current.contains(e.target))) {
setIsOpen(false); setSearch(''); setHighlightIndex(-1);
}
};
@@ -127,6 +131,20 @@
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
+ const calcDropdownPos = () => {
+ if (!triggerRef.current) return;
+ const rect = triggerRef.current.getBoundingClientRect();
+ const spaceBelow = window.innerHeight - rect.bottom;
+ const openUp = spaceBelow < 260;
+ setDropdownStyle({
+ position: 'fixed',
+ left: rect.left,
+ width: Math.max(rect.width, 224),
+ zIndex: 9999,
+ ...(openUp ? { bottom: window.innerHeight - rect.top + 4 } : { top: rect.bottom + 4 }),
+ });
+ };
+
const handleSelect = (code) => {
onChange(code.code, code.name);
setIsOpen(false); setSearch(''); setHighlightIndex(-1);
@@ -155,7 +173,7 @@
return (
-
setIsOpen(!isOpen)}
+
{ if (!isOpen) calcDropdownPos(); setIsOpen(!isOpen); }}
className={`w-full px-2 py-1.5 text-xs border rounded cursor-pointer flex items-center justify-between gap-1 ${isOpen ? 'border-emerald-500 ring-2 ring-emerald-500' : 'border-stone-200'} bg-white`}>
{displayText || '계정과목 선택'}
@@ -165,8 +183,8 @@ className={`w-full px-2 py-1.5 text-xs border rounded cursor-pointer flex items-
- {isOpen && (
-
+ {isOpen && ReactDOM.createPortal(
+
setSearch(e.target.value)} onKeyDown={handleKeyDown}
placeholder="코드 또는 이름 검색..." className="w-full px-2 py-1 text-xs border border-stone-200 rounded focus:ring-1 focus:ring-emerald-500 outline-none" autoFocus />
@@ -183,7 +201,8 @@ className={`px-3 py-1.5 text-xs cursor-pointer ${index === highlightIndex ? 'bg-
))}
{filteredCodes.length > 50 &&
+{filteredCodes.length - 50}개 더 있음
}
-
+
,
+ document.body
)}
);
@@ -456,7 +475,10 @@ className="px-4 py-2 text-sm font-medium text-white bg-emerald-600 rounded-lg ho
const [isOpen, setIsOpen] = useState(false);
const [search, setSearch] = useState('');
const [highlightIndex, setHighlightIndex] = useState(-1);
+ const [dropdownStyle, setDropdownStyle] = useState({});
const containerRef = useRef(null);
+ const triggerRef = useRef(null);
+ const dropdownRef = useRef(null);
const listRef = useRef(null);
const displayText = valueName || '';
@@ -470,7 +492,8 @@ className="px-4 py-2 text-sm font-medium text-white bg-emerald-600 rounded-lg ho
useEffect(() => { setHighlightIndex(-1); }, [search]);
useEffect(() => {
const handleClickOutside = (e) => {
- if (containerRef.current && !containerRef.current.contains(e.target)) {
+ if (containerRef.current && !containerRef.current.contains(e.target) &&
+ (!dropdownRef.current || !dropdownRef.current.contains(e.target))) {
setIsOpen(false); setSearch(''); setHighlightIndex(-1);
}
};
@@ -478,6 +501,20 @@ className="px-4 py-2 text-sm font-medium text-white bg-emerald-600 rounded-lg ho
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
+ const calcDropdownPos = () => {
+ if (!triggerRef.current) return;
+ const rect = triggerRef.current.getBoundingClientRect();
+ const spaceBelow = window.innerHeight - rect.bottom;
+ const openUp = spaceBelow < 280;
+ setDropdownStyle({
+ position: 'fixed',
+ left: rect.left,
+ width: Math.max(rect.width, 224),
+ zIndex: 9999,
+ ...(openUp ? { bottom: window.innerHeight - rect.top + 4 } : { top: rect.bottom + 4 }),
+ });
+ };
+
const handleSelect = (partner) => {
onChange(partner.id, partner.name);
setIsOpen(false); setSearch(''); setHighlightIndex(-1);
@@ -506,7 +543,7 @@ className="px-4 py-2 text-sm font-medium text-white bg-emerald-600 rounded-lg ho
return (
-
setIsOpen(!isOpen)}
+
{ if (!isOpen) calcDropdownPos(); setIsOpen(!isOpen); }}
className={`w-full px-2 py-1.5 text-xs border rounded cursor-pointer flex items-center justify-between gap-1 ${isOpen ? 'border-emerald-500 ring-2 ring-emerald-500' : 'border-stone-200'} bg-white`}>
{displayText || '거래처 선택'}
@@ -516,8 +553,8 @@ className={`w-full px-2 py-1.5 text-xs border rounded cursor-pointer flex items-
- {isOpen && (
-
+ {isOpen && ReactDOM.createPortal(
+
-
+
,
+ document.body
)}
);
@@ -962,9 +1000,9 @@ className="px-2.5 py-1 text-xs font-medium bg-amber-100 text-amber-700 rounded-f
return (
-
+
{/* 헤더 */}
-
+
{isEditMode ? `전표 수정 (${existingEntryNo})` : '수동 전표 생성'}
@@ -973,7 +1011,7 @@ className="px-2.5 py-1 text-xs font-medium bg-amber-100 text-amber-700 rounded-f
-
+
{loadingEntry ? (
@@ -1116,7 +1154,7 @@ className={`p-1 rounded ${lines.length <= 2 ? 'text-stone-200 cursor-not-allowed
{/* 하단 버튼 */}
-
+
{isEditMode && (