@@ -49,8 +49,6 @@ function searchBar($list, setHide, onhideCb, searchFunction) {
4949
5050 function hide ( ) {
5151 actionStack . remove ( "searchbar" ) ;
52-
53- if ( ! $list . parentElement ) return ;
5452 if ( typeof onhideCb === "function" ) onhideCb ( ) ;
5553
5654 $list . content = children ;
@@ -70,6 +68,12 @@ function searchBar($list, setHide, onhideCb, searchFunction) {
7068 */
7169 async function searchNow ( ) {
7270 const val = $searchInput . value . toLowerCase ( ) ;
71+
72+ if ( ! val ) {
73+ $list . content = children ;
74+ return ;
75+ }
76+
7377 let result ;
7478
7579 if ( searchFunction ) {
@@ -89,7 +93,7 @@ function searchBar($list, setHide, onhideCb, searchFunction) {
8993 }
9094
9195 $list . textContent = "" ;
92- $list . append ( ...result ) ;
96+ $list . append ( ...buildSearchContent ( result , val ) ) ;
9397 }
9498
9599 /**
@@ -103,6 +107,63 @@ function searchBar($list, setHide, onhideCb, searchFunction) {
103107 return text . match ( val , "i" ) ;
104108 } ) ;
105109 }
110+
111+ /**
112+ * Keep grouped settings search results in section cards instead of flattening them.
113+ * @param {HTMLElement[] } result
114+ * @param {string } val
115+ * @returns {HTMLElement[] }
116+ */
117+ function buildSearchContent ( result , val ) {
118+ if ( ! val || ! result . length ) return result ;
119+
120+ const groups = new Map ( ) ;
121+ let hasGroups = false ;
122+
123+ result . forEach ( ( $item ) => {
124+ const label = $item . dataset . searchGroup ;
125+ if ( ! label ) return ;
126+ hasGroups = true ;
127+
128+ if ( ! groups . has ( label ) ) {
129+ groups . set ( label , [ ] ) ;
130+ }
131+ groups . get ( label ) . push ( $item ) ;
132+ } ) ;
133+
134+ if ( ! hasGroups ) return result . map ( cloneSearchItem ) ;
135+
136+ const countLabel = `${ result . length } ${ result . length === 1 ? "RESULT" : "RESULTS" } ` ;
137+ const content = [
138+ < div className = "settings-search-summary" > { countLabel } </ div > ,
139+ ] ;
140+
141+ groups . forEach ( ( items , label ) => {
142+ content . push (
143+ < section className = "settings-section settings-search-section" >
144+ < div className = "settings-section-label" > { label } </ div >
145+ < div className = "settings-section-card" >
146+ { items . map ( cloneSearchItem ) }
147+ </ div >
148+ </ section > ,
149+ ) ;
150+ } ) ;
151+
152+ return content ;
153+ }
154+
155+ /**
156+ * Render search results without moving the original list items out of their groups.
157+ * @param {HTMLElement } $item
158+ * @returns {HTMLElement }
159+ */
160+ function cloneSearchItem ( $item ) {
161+ const $clone = $item . cloneNode ( true ) ;
162+ $clone . addEventListener ( "click" , ( ) => {
163+ $item . click ( ) ;
164+ } ) ;
165+ return $clone ;
166+ }
106167}
107168
108169export default searchBar ;
0 commit comments