@@ -59,6 +59,12 @@ function updateSelectionLabel(label: HTMLElement) {
59
59
}
60
60
}
61
61
62
+ function processMenuItems ( $dropdown , dropdownCall ) {
63
+ const hideEmptyDividers = dropdownCall ( 'setting' , 'hideDividers' ) === 'empty' ;
64
+ const itemsMenu = $dropdown [ 0 ] . querySelector ( '.scrolling.menu' ) || $dropdown [ 0 ] . querySelector ( '.menu' ) ;
65
+ if ( hideEmptyDividers ) hideScopedEmptyDividers ( itemsMenu ) ;
66
+ }
67
+
62
68
// delegate the dropdown's template functions and callback functions to add aria attributes.
63
69
function delegateOne ( $dropdown : any ) {
64
70
const dropdownCall = fomanticDropdownFn . bind ( $dropdown ) ;
@@ -72,6 +78,18 @@ function delegateOne($dropdown: any) {
72
78
// * If the "dropdown icon" is clicked again when the menu is visible, Fomantic calls "blurSearch", so hide the menu
73
79
dropdownCall ( 'internal' , 'blurSearch' , function ( ) { oldBlurSearch . call ( this ) ; dropdownCall ( 'hide' ) } ) ;
74
80
81
+ const oldFilterItems = dropdownCall ( 'internal' , 'filterItems' ) ;
82
+ dropdownCall ( 'internal' , 'filterItems' , function ( ) {
83
+ oldFilterItems . call ( this ) ;
84
+ processMenuItems ( $dropdown , dropdownCall ) ;
85
+ } ) ;
86
+
87
+ const oldShow = dropdownCall ( 'internal' , 'show' ) ;
88
+ dropdownCall ( 'internal' , 'show' , function ( ...args ) {
89
+ oldShow . call ( this , ...args ) ;
90
+ processMenuItems ( $dropdown , dropdownCall ) ;
91
+ } ) ;
92
+
75
93
// the "template" functions are used for dynamic creation (eg: AJAX)
76
94
const dropdownTemplates = { ...dropdownCall ( 'setting' , 'templates' ) , t : performance . now ( ) } ;
77
95
const dropdownTemplatesMenuOld = dropdownTemplates . menu ;
@@ -271,3 +289,58 @@ function attachDomEvents(dropdown: HTMLElement, focusable: HTMLElement, menu: HT
271
289
ignoreClickPreEvents = ignoreClickPreVisible = 0 ;
272
290
} , true ) ;
273
291
}
292
+
293
+ export function hideScopedEmptyDividers ( container : Element ) {
294
+ const visibleItems : Element [ ] = [ ] ;
295
+ const curScopeVisibleItems : Element [ ] = [ ] ;
296
+ let curScope = '' , lastVisibleScope = '' ;
297
+ const isScopedDivider = ( item : Element ) => item . matches ( '.divider' ) && item . hasAttribute ( 'data-scope' ) ;
298
+ const hideDivider = ( item : Element ) => item . classList . add ( 'hidden' , 'transition' ) ; // dropdown has its own classes to hide items
299
+
300
+ const handleScopeSwitch = ( itemScope : string ) => {
301
+ if ( curScopeVisibleItems . length === 1 && isScopedDivider ( curScopeVisibleItems [ 0 ] ) ) {
302
+ hideDivider ( curScopeVisibleItems [ 0 ] ) ;
303
+ } else if ( curScopeVisibleItems . length ) {
304
+ if ( isScopedDivider ( curScopeVisibleItems [ 0 ] ) && lastVisibleScope === curScope ) {
305
+ hideDivider ( curScopeVisibleItems [ 0 ] ) ;
306
+ curScopeVisibleItems . shift ( ) ;
307
+ }
308
+ visibleItems . push ( ...curScopeVisibleItems ) ;
309
+ lastVisibleScope = curScope ;
310
+ }
311
+ curScope = itemScope ;
312
+ curScopeVisibleItems . length = 0 ;
313
+ } ;
314
+
315
+ // hide the scope dividers if the scope items are empty
316
+ for ( const item of container . children ) {
317
+ const itemScope = item . getAttribute ( 'data-scope' ) || '' ;
318
+ if ( itemScope !== curScope ) {
319
+ handleScopeSwitch ( itemScope ) ;
320
+ }
321
+ if ( ! item . classList . contains ( 'filtered' ) && ! item . classList . contains ( 'tw-hidden' ) ) {
322
+ curScopeVisibleItems . push ( item as HTMLElement ) ;
323
+ }
324
+ }
325
+ handleScopeSwitch ( '' ) ;
326
+
327
+ // hide all leading and trailing dividers
328
+ while ( visibleItems . length ) {
329
+ if ( ! visibleItems [ 0 ] . matches ( '.divider' ) ) break ;
330
+ hideDivider ( visibleItems [ 0 ] ) ;
331
+ visibleItems . shift ( ) ;
332
+ }
333
+ while ( visibleItems . length ) {
334
+ if ( ! visibleItems [ visibleItems . length - 1 ] . matches ( '.divider' ) ) break ;
335
+ hideDivider ( visibleItems [ visibleItems . length - 1 ] ) ;
336
+ visibleItems . pop ( ) ;
337
+ }
338
+ // hide all duplicate dividers
339
+ for ( let i = 0 ; i < visibleItems . length ; i ++ ) {
340
+ const item = visibleItems [ i ] ;
341
+ if ( ! item . matches ( '.divider' ) ) continue ;
342
+ if ( i === 0 || i === visibleItems . length - 1 || item . nextElementSibling ?. matches ( '.divider' ) ) {
343
+ hideDivider ( item ) ;
344
+ }
345
+ }
346
+ }
0 commit comments