탭 컴포넌트 분리/디자인 수정정

This commit is contained in:
yschoi
2025-04-25 16:12:09 +09:00
parent f9ea0d36ce
commit 81afc9f341
5 changed files with 74 additions and 39 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ const Map = () => {
return (
<div className="bg-container">
<Gis treeData={treeData}/>
<Gis treeData={treeData} isSearch={true} />
</div>
);
};
@@ -10,18 +10,18 @@ import proj4 from 'proj4';
import { register } from 'ol/proj/proj4';
import GisApp from './lib/gis.core';
import GisContent from './GisContent';
import GisTree from './GisTree';
import GisLonLat from './GisLonLat';
import GisToolBar from './GisToolBar';
import GisSearch from './GisSearch';
import GisTab from './GisTab';
import MapToggleBtn from './MapToggleBtn';
export const GisContext = createContext({gisCore: null, gisMap: null, treeData:null, checkedLayerIds:null});
export const useGisContext = () => useContext(GisContext);
function Gis({ treeData = [] }) {
function Gis({ treeData = [], isSearch = false }) {
const mapRef = useRef();
const [mapObject, setMapObject] = useState({});
const [tabVisible, setTabVisible] = useState(true);
const gisCore = useMemo(() => new GisApp.core({ targetId: mapRef.current }), []);
//const [treeData, setTreeData] = useState([]);
const checkedLayerIds = useRef([]);
@@ -125,34 +125,20 @@ function Gis({ treeData = [] }) {
}
}
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
return (
<>
<GisContext.Provider value={{gisCore, gisMap, treeData, checkedLayerIds}}>
<>
<div className="h-[calc(100vh-10rem)] flex relative">
<div className="absolute top-0 left-0 z-40 w-[280px] h-[calc(100vh-10rem)] bg-white border rounded-md shadow-md flex flex-col overflow-hidden">
<Tabs defaultValue="layers" className="flex-1 flex flex-col overflow-hidden">
<TabsList className="flex-none border-b mt-2">
<TabsTrigger value="layers" className="flex-1 h-10 px-2 py-2">레이어</TabsTrigger>
<TabsTrigger value="search" className="flex-1 h-10 px-2 py-2">시설검색</TabsTrigger>
</TabsList>
<TabsContent value="layers" className="grow overflow-y-auto p-2 min-h-0">
<GisTree/>
</TabsContent>
<TabsContent value="search" className="grow overflow-y-auto p-2 min-h-0">
<GisSearch/>
</TabsContent>
</Tabs>
</div>
<GisTab visible={tabVisible} setVisible={setTabVisible} isSearch={isSearch} />
<div ref={mapRef} className="gis-map flex-1 relative" style={{ height: '100%', padding: 0 }} />
<GisLonLat/>
<GisToolBar/>
<MapToggleBtn/>
<GisContent/>
</div>
</>
</GisContext.Provider>
</>
);
}
@@ -0,0 +1,67 @@
import React, { useState } from 'react';
import { Tabs, TabsList, TabsTrigger } from '@common/components/ui/tabs';
import GisTree from './GisTree';
import GisSearch from './GisSearch';
import { ChevronLeft, ChevronRight } from 'lucide-react';
function GisTab({ visible, setVisible, isSearch }) {
const [activeTab, setActiveTab] = useState('layers');
return (
<>
<div
className={`absolute top-0 left-0 w-[250px] h-[calc(100vh-10rem)] bg-white border-r border-gray-300 flex flex-col overflow-hidden transition-all duration-300 z-40
${visible ? 'translate-x-0 opacity-100' : '-translate-x-full opacity-0 pointer-events-none'}`}
>
<Tabs value={activeTab} onValueChange={setActiveTab} className="flex-1 flex flex-col overflow-hidden">
<TabsList className="flex-none mt-4 border-none rounded-none">
<TabsTrigger value="layers" className="flex-1 h-10">레이어</TabsTrigger>
{isSearch && (
<TabsTrigger value="search" className="flex-1 h-10">검색</TabsTrigger>
)}
</TabsList>
{/* GisTree는 항상 마운트되며, 탭 상태에 따라 보여주기만 함 */}
<div
className={`grow overflow-y-auto p-2 pt-0 border-none shadow-none ${
activeTab === 'layers' ? 'block' : 'hidden'
}`}
>
<GisTree />
</div>
{/* GisSearch도 동일하게 처리 */}
{isSearch && (
<div
className={`grow overflow-y-auto p-2 pt-0 border-none shadow-none ${
activeTab === 'search' ? 'block' : 'hidden'
}`}
>
<GisSearch />
</div>
)}
</Tabs>
{/* 접기 버튼 */}
<button
onClick={() => setVisible(false)}
className="absolute top-1/2 right-[-3px] transform -translate-y-1/2 z-50 bg-white border border-l border-gray-300 rounded-l-none rounded-r px-1 py-2 shadow-sm"
>
<ChevronLeft size={16} />
</button>
</div>
{/* 열기 버튼 */}
{!visible && (
<button
onClick={() => setVisible(true)}
className="absolute top-1/2 left-[-3px] transform -translate-y-1/2 z-50 bg-white border border-r border-gray-300 rounded-r px-1 py-2 shadow-sm"
>
<ChevronRight size={16} />
</button>
)}
</>
);
}
export default React.memo(GisTab);
@@ -116,22 +116,6 @@ export default React.memo(function GisTree({ checkedNodes = [], setCheckedNodes
});
};
const findUpLyrId = (nodes, targetLyrId) => {
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (node.data && node.data.lyrSn === targetLyrId) {
return node.data.upperLyrSn;
}
if (node.children) {
const upLyrId = findUpLyrId(node.children, targetLyrId);
if (upLyrId) {
return upLyrId;
}
}
}
return null;
};
const makeLegendSrc = layerinfo => {
if(!layerinfo.gobjTy) return null;
@@ -759,8 +759,6 @@
.puGrayTb {
position: relative;
width: 98.3%;
cellpadding: 0;
cellspcing: 0;
margin-top: 5px;
table-layout: fixed;
font-family: Verdana;