@@ -88,8 +88,88 @@ function toggleChildren(ul, toggleBtn) {
8888 toggleBtn . style . fontSize = isClosed ? "1rem" : "0.8rem"
8989}
9090
91+ /* -------------------검색--------------------- */
92+ const searchFeature = document . querySelector ( ".sidebar-feature.search" )
93+ const searchPopup = document . querySelector ( ".search-popup" )
94+
95+ searchFeature . addEventListener ( "click" , ( e ) => {
96+ e . stopPropagation ( )
97+ searchPopup . style . display =
98+ searchPopup . style . display === "block" ? "none" : "block"
99+ if ( searchPopup . style . display === "block" ) {
100+ searchInput . focus ( )
101+ renderSearchResults ( cachedDocuments )
102+ }
103+ } )
104+
105+ // 검색 팝업 내부 HTML
106+ searchPopup . innerHTML = `
107+ <input id="search-input" type="text" placeholder="제목 검색..." />
108+ <ul class="search-results"></ul>
109+ `
110+
111+ const searchInput = searchPopup . querySelector ( "input" )
112+ const searchResults = searchPopup . querySelector ( ".search-results" )
113+
114+ // 문서 데이터 가져오기
115+ let cachedDocuments = [ ]
116+
117+ async function cacheDocuments ( ) {
118+ cachedDocuments = await fetchDocuments ( )
119+ }
120+
121+ cacheDocuments ( )
122+
123+ // 결과 렌더링 함수
124+ function renderSearchResults ( docs , term = "" ) {
125+ searchResults . innerHTML = ""
126+
127+ const results = [ ]
128+
129+ function flatten ( docs ) {
130+ for ( const doc of docs ) {
131+ results . push ( doc )
132+ if ( doc . documents ) flatten ( doc . documents )
133+ }
134+ }
135+
136+ flatten ( docs )
137+
138+ const filtered = term
139+ ? results . filter ( ( doc ) =>
140+ doc . title . toLowerCase ( ) . includes ( term . toLowerCase ( ) ) ,
141+ )
142+ : results
143+
144+ filtered . forEach ( ( doc ) => {
145+ const li = document . createElement ( "li" )
146+ li . textContent = doc . title
147+ li . dataset . id = doc . id
148+ li . addEventListener ( "click" , ( ) => {
149+ searchInput . value = doc . title
150+ searchPopup . style . display = "none"
151+ openDocument ( doc . id )
152+ setActiveDocumentLi ( doc . id )
153+ } )
154+ searchResults . appendChild ( li )
155+ } )
156+ }
157+
158+ // 입력 시 필터링
159+ searchInput . addEventListener ( "input" , ( e ) => {
160+ const term = e . target . value . trim ( )
161+ renderSearchResults ( cachedDocuments , term )
162+ } )
163+
164+ // 외부 클릭 시 팝업 닫기
165+ document . addEventListener ( "mousedown" , ( e ) => {
166+ if ( ! searchPopup . contains ( e . target ) && ! searchFeature . contains ( e . target ) ) {
167+ searchPopup . style . display = "none"
168+ }
169+ } )
170+
91171/* -------------------------------------------- */
92- /* 2 . 트리 렌더링 */
172+ /* 1 . 트리 렌더링 */
93173/* -------------------------------------------- */
94174
95175function renderTree ( documents , parentElement = sidebarTree , depth = 0 ) {
@@ -129,10 +209,6 @@ function renderTree(documents, parentElement = sidebarTree, depth = 0) {
129209 const toggleBtn = document . createElement ( "button" )
130210 toggleBtn . className = "toggle-btn"
131211 toggleBtn . type = "button"
132- toggleBtn . style . backgroundImage = "url(/src/img/toggle.svg)"
133- toggleBtn . style . backgroundRepeat = "no-repeat"
134- toggleBtn . style . backgroundSize = "cover"
135- toggleBtn . style . backgroundPosition = "center"
136212 toggleBtn . style . marginRight = "6px"
137213 toggleBtn . style . fontSize = "0.8rem"
138214 toggleBtn . style . lineHeight = "1"
@@ -247,7 +323,7 @@ function renderTree(documents, parentElement = sidebarTree, depth = 0) {
247323}
248324
249325/* -------------------------------------------- */
250- /* 3 . 루트 Document 생성 */
326+ /* 2 . 루트 Document 생성 */
251327/* -------------------------------------------- */
252328createRootBtn . addEventListener ( "click" , async ( ) => {
253329 const newDoc = await createDocument ( "새 문서" , null )
@@ -256,7 +332,7 @@ createRootBtn.addEventListener("click", async () => {
256332} )
257333
258334/* -------------------------------------------- */
259- /* 4 . 초기 로드 */
335+ /* 3 . 초기 로드 */
260336/* -------------------------------------------- */
261337async function loadTree ( targetDocId = null ) {
262338 const documents = await fetchDocuments ( )
0 commit comments