@@ -59,6 +59,12 @@ function updateSelectionLabel(label: HTMLElement) {
5959 }
6060}
6161
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+
6268// delegate the dropdown's template functions and callback functions to add aria attributes.
6369function delegateOne ( $dropdown : any ) {
6470 const dropdownCall = fomanticDropdownFn . bind ( $dropdown ) ;
@@ -72,6 +78,18 @@ function delegateOne($dropdown: any) {
7278 // * If the "dropdown icon" is clicked again when the menu is visible, Fomantic calls "blurSearch", so hide the menu
7379 dropdownCall ( 'internal' , 'blurSearch' , function ( ) { oldBlurSearch . call ( this ) ; dropdownCall ( 'hide' ) } ) ;
7480
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+
7593 // the "template" functions are used for dynamic creation (eg: AJAX)
7694 const dropdownTemplates = { ...dropdownCall ( 'setting' , 'templates' ) , t : performance . now ( ) } ;
7795 const dropdownTemplatesMenuOld = dropdownTemplates . menu ;
@@ -271,3 +289,58 @@ function attachDomEvents(dropdown: HTMLElement, focusable: HTMLElement, menu: HT
271289 ignoreClickPreEvents = ignoreClickPreVisible = 0 ;
272290 } , true ) ;
273291}
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