@@ -303,6 +303,12 @@ export interface CubeListBoxProps<T>
303303   * Useful for implementing search/filter functionality. 
304304   */ 
305305  filter ?: ( nodes : Iterable < any > )  =>  Iterable < any > ; 
306+ 
307+   /** 
308+    * Label to display when the list is empty (no items available). 
309+    * Defaults to "No items". 
310+    */ 
311+   emptyLabel ?: ReactNode ; 
306312} 
307313
308314const  PROP_STYLES  =  [ ...BASE_STYLES ,  ...OUTER_STYLES ,  ...COLOR_STYLES ] ; 
@@ -508,6 +514,7 @@ export const ListBox = forwardRef(function ListBox<T extends object>(
508514    selectAllLabel, 
509515    allValueProps, 
510516    filter, 
517+     emptyLabel =  'No items' , 
511518    form, 
512519    ...otherProps 
513520  }  =  props ; 
@@ -886,110 +893,121 @@ export const ListBox = forwardRef(function ListBox<T extends object>(
886893      ) } 
887894      { /* Scroll container wrapper */ } 
888895      < ListBoxScrollElement  ref = { scrollRef }  mods = { mods }  { ...focusProps } > 
889-         < ListElement 
890-           qa = { qa  ||  'ListBox' } 
891-           { ...mergedListBoxProps } 
892-           ref = { listRef } 
893-           styles = { listStyles } 
894-           aria-disabled = { isDisabled  ||  undefined } 
895-           mods = { {  sections : hasSections  } } 
896-           style = { 
897-             shouldVirtualize 
898-               ? { 
899-                   position : 'relative' , 
900-                   height : `${ rowVirtualizer . getTotalSize ( )  +  3 }  , 
901-                 } 
902-               : undefined 
903-           } 
904-         > 
905-           { shouldVirtualize 
906-             ? rowVirtualizer . getVirtualItems ( ) . map ( ( virtualItem )  =>  { 
907-                 const  item  =  itemsArray [ virtualItem . index ] ; 
908- 
909-                 return  ( 
910-                   < Option 
911-                     key = { virtualItem . key } 
912-                     size = { size } 
913-                     item = { item } 
914-                     state = { listState } 
915-                     styles = { optionStyles } 
916-                     isParentDisabled = { isDisabled } 
917-                     validationState = { validationState } 
918-                     focusOnHover = { focusOnHover } 
919-                     isCheckable = { isCheckable } 
920-                     // We don't need to measure the element here, because the height is already set by the virtualizer 
921-                     // This is a workaround to avoid glitches when selecting/deselecting items 
922-                     virtualRef = { rowVirtualizer . measureElement  as  any } 
923-                     virtualStyle = { { 
924-                       position : 'absolute' , 
925-                       top : 0 , 
926-                       left : 0 , 
927-                       right : 0 , 
928-                       transform : `translateY(${ virtualItem . start }  , 
929-                     } } 
930-                     virtualIndex = { virtualItem . index } 
931-                     lastFocusSourceRef = { lastFocusSourceRef } 
932-                     onClick = { onOptionClick } 
933-                   /> 
934-                 ) ; 
935-               } ) 
936-             : ( ( )  =>  { 
937-                 const  renderedItems : ReactNode [ ]  =  [ ] ; 
938-                 let  isFirstSection  =  true ; 
939- 
940-                 for  ( const  item  of  listState . collection )  { 
941-                   if  ( item . type  ===  'section' )  { 
942-                     if  ( ! isFirstSection )  { 
896+         { listState . collection . size  ===  0  ? ( 
897+           < ItemBase 
898+             preset = "t4" 
899+             color = "#dark-03" 
900+             size = { size } 
901+             padding = "(.5x - 1bw)" 
902+           > 
903+             { emptyLabel } 
904+           </ ItemBase > 
905+         )  : ( 
906+           < ListElement 
907+             qa = { qa  ||  'ListBox' } 
908+             { ...mergedListBoxProps } 
909+             ref = { listRef } 
910+             styles = { listStyles } 
911+             aria-disabled = { isDisabled  ||  undefined } 
912+             mods = { {  sections : hasSections  } } 
913+             style = { 
914+               shouldVirtualize 
915+                 ? { 
916+                     position : 'relative' , 
917+                     height : `${ rowVirtualizer . getTotalSize ( )  +  3 }  , 
918+                   } 
919+                 : undefined 
920+             } 
921+           > 
922+             { shouldVirtualize 
923+               ? rowVirtualizer . getVirtualItems ( ) . map ( ( virtualItem )  =>  { 
924+                   const  item  =  itemsArray [ virtualItem . index ] ; 
925+ 
926+                   return  ( 
927+                     < Option 
928+                       key = { virtualItem . key } 
929+                       size = { size } 
930+                       item = { item } 
931+                       state = { listState } 
932+                       styles = { optionStyles } 
933+                       isParentDisabled = { isDisabled } 
934+                       validationState = { validationState } 
935+                       focusOnHover = { focusOnHover } 
936+                       isCheckable = { isCheckable } 
937+                       // We don't need to measure the element here, because the height is already set by the virtualizer 
938+                       // This is a workaround to avoid glitches when selecting/deselecting items 
939+                       virtualRef = { rowVirtualizer . measureElement  as  any } 
940+                       virtualStyle = { { 
941+                         position : 'absolute' , 
942+                         top : 0 , 
943+                         left : 0 , 
944+                         right : 0 , 
945+                         transform : `translateY(${ virtualItem . start }  , 
946+                       } } 
947+                       virtualIndex = { virtualItem . index } 
948+                       lastFocusSourceRef = { lastFocusSourceRef } 
949+                       onClick = { onOptionClick } 
950+                     /> 
951+                   ) ; 
952+                 } ) 
953+               : ( ( )  =>  { 
954+                   const  renderedItems : ReactNode [ ]  =  [ ] ; 
955+                   let  isFirstSection  =  true ; 
956+ 
957+                   for  ( const  item  of  listState . collection )  { 
958+                     if  ( item . type  ===  'section' )  { 
959+                       if  ( ! isFirstSection )  { 
960+                         renderedItems . push ( 
961+                           < StyledDivider 
962+                             key = { `divider-${ String ( item . key ) }  } 
963+                             role = "separator" 
964+                             aria-orientation = "horizontal" 
965+                           /> , 
966+                         ) ; 
967+                       } 
968+ 
943969                      renderedItems . push ( 
944-                         < StyledDivider 
945-                           key = { `divider-${ String ( item . key ) }  } 
946-                           role = "separator" 
947-                           aria-orientation = "horizontal" 
970+                         < ListBoxSection 
971+                           key = { item . key } 
972+                           item = { item } 
973+                           state = { listState } 
974+                           optionStyles = { optionStyles } 
975+                           headingStyles = { headingStyles } 
976+                           sectionStyles = { sectionStyles } 
977+                           isParentDisabled = { isDisabled } 
978+                           validationState = { validationState } 
979+                           focusOnHover = { focusOnHover } 
980+                           isCheckable = { isCheckable } 
981+                           size = { size } 
982+                           lastFocusSourceRef = { lastFocusSourceRef } 
983+                           onClick = { onOptionClick } 
948984                        /> , 
949985                      ) ; 
950-                     } 
951986
952-                     renderedItems . push ( 
953-                       < ListBoxSection 
954-                         key = { item . key } 
955-                         item = { item } 
956-                         state = { listState } 
957-                         optionStyles = { optionStyles } 
958-                         headingStyles = { headingStyles } 
959-                         sectionStyles = { sectionStyles } 
960-                         isParentDisabled = { isDisabled } 
961-                         validationState = { validationState } 
962-                         focusOnHover = { focusOnHover } 
963-                         isCheckable = { isCheckable } 
964-                         size = { size } 
965-                         lastFocusSourceRef = { lastFocusSourceRef } 
966-                         onClick = { onOptionClick } 
967-                       /> , 
968-                     ) ; 
969- 
970-                     isFirstSection  =  false ; 
971-                   }  else  { 
972-                     renderedItems . push ( 
973-                       < Option 
974-                         key = { item . key } 
975-                         size = { size } 
976-                         item = { item } 
977-                         state = { listState } 
978-                         styles = { optionStyles } 
979-                         isParentDisabled = { isDisabled } 
980-                         validationState = { validationState } 
981-                         focusOnHover = { focusOnHover } 
982-                         isCheckable = { isCheckable } 
983-                         lastFocusSourceRef = { lastFocusSourceRef } 
984-                         onClick = { onOptionClick } 
985-                       /> , 
986-                     ) ; 
987+                       isFirstSection  =  false ; 
988+                     }  else  { 
989+                       renderedItems . push ( 
990+                         < Option 
991+                           key = { item . key } 
992+                           size = { size } 
993+                           item = { item } 
994+                           state = { listState } 
995+                           styles = { optionStyles } 
996+                           isParentDisabled = { isDisabled } 
997+                           validationState = { validationState } 
998+                           focusOnHover = { focusOnHover } 
999+                           isCheckable = { isCheckable } 
1000+                           lastFocusSourceRef = { lastFocusSourceRef } 
1001+                           onClick = { onOptionClick } 
1002+                         /> , 
1003+                       ) ; 
1004+                     } 
9871005                  } 
988-                 } 
9891006
990-                 return  renderedItems ; 
991-               } ) ( ) } 
992-         </ ListElement > 
1007+                   return  renderedItems ; 
1008+                 } ) ( ) } 
1009+           </ ListElement > 
1010+         ) } 
9931011      </ ListBoxScrollElement > 
9941012      { footer  ? ( 
9951013        < StyledFooter  styles = { footerStyles }  data-size = { size } > 
0 commit comments