@@ -378,7 +378,6 @@ function MultiSelectOptionItem({
378378 return (
379379 < div className = "flex items-center" >
380380 < CommandItem
381- value = { option . value }
382381 onSelect = { isReadOnly ? undefined : ( ) => toggleOption ( option . value ) }
383382 role = "option"
384383 aria-selected = { isSelected }
@@ -737,6 +736,28 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
737736 ) ;
738737 } , [ options , searchValue , searchable , isGroupedOptions ] ) ;
739738
739+ const hasFilteredResults = React . useMemo ( ( ) => {
740+ if ( isGroupedOptions ( filteredOptions ) ) {
741+ return filteredOptions . some ( ( group ) => group . options . length > 0 ) ;
742+ }
743+ return filteredOptions . length > 0 ;
744+ } , [ filteredOptions , isGroupedOptions ] ) ;
745+
746+ const filteredOptionValues = React . useMemo ( ( ) => {
747+ if ( isGroupedOptions ( filteredOptions ) ) {
748+ return filteredOptions . flatMap ( ( group ) =>
749+ group . options . map ( ( option ) => option . value ) ,
750+ ) ;
751+ }
752+ return filteredOptions . map ( ( option ) => option . value ) ;
753+ } , [ filteredOptions , isGroupedOptions ] ) ;
754+
755+ const hasSelectedInFiltered = React . useMemo (
756+ ( ) =>
757+ filteredOptionValues . some ( ( value ) => selectedValues . includes ( value ) ) ,
758+ [ filteredOptionValues , selectedValues ] ,
759+ ) ;
760+
740761 const handleInputKeyDown = (
741762 event : React . KeyboardEvent < HTMLInputElement > ,
742763 ) => {
@@ -1191,7 +1212,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
11911212 align = "start"
11921213 onEscapeKeyDown = { ( ) => setIsPopoverOpen ( false ) }
11931214 >
1194- < Command >
1215+ < Command shouldFilter = { false } >
11951216 { searchable && (
11961217 < CommandInput
11971218 placeholder = "Wyszukaj opcję..."
@@ -1214,85 +1235,96 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
12141235 "overscroll-behavior-y-contain" ,
12151236 ) }
12161237 >
1217- < CommandEmpty > { emptyIndicator || "Brak wyników." } </ CommandEmpty > { " " }
1218- { ! hideSelectAll && ! searchValue && (
1219- < CommandGroup >
1220- < CommandItem
1221- key = "all"
1222- onSelect = { toggleAll }
1223- role = "option"
1224- aria-selected = {
1225- selectedValues . length ===
1226- getAllOptions ( ) . filter ( ( opt ) => ! opt . disabled ) . length
1227- }
1228- aria-label = { `Select all ${
1229- getAllOptions ( ) . length
1230- } options`}
1231- className = "cursor-pointer"
1232- >
1233- < div
1234- className = { cn (
1235- "border-primary mr-2 flex h-4 w-4 items-center justify-center rounded-sm border" ,
1236- selectedValues . length ===
1238+ { hasFilteredResults ? (
1239+ < >
1240+ { ! hideSelectAll && ! searchValue && (
1241+ < CommandGroup >
1242+ < CommandItem
1243+ key = "all"
1244+ onSelect = { toggleAll }
1245+ role = "option"
1246+ aria-selected = {
1247+ selectedValues . length ===
12371248 getAllOptions ( ) . filter ( ( opt ) => ! opt . disabled )
12381249 . length
1239- ? "bg-primary"
1240- : "opacity-50 [&_svg]:invisible" ,
1241- ) }
1242- aria-hidden = "true"
1243- >
1244- < CheckIcon className = "text-primary-foreground h-4 w-4" />
1245- </ div >
1246- < span >
1247- (Wybierz wszystkie
1248- { getAllOptions ( ) . length > 20
1249- ? ` – ${ declineNumeric (
1250- getAllOptions ( ) . length ,
1251- "option" ,
1252- { singularCase : GrammaticalCase . Accusative } ,
1253- ) } `
1254- : "" }
1255- )
1256- </ span >
1257- </ CommandItem >
1258- </ CommandGroup >
1259- ) }
1260- { isGroupedOptions ( filteredOptions ) ? (
1261- filteredOptions . map ( ( group ) => (
1262- < CommandGroup key = { group . heading } heading = { group . heading } >
1263- { group . options . map ( ( option ) => (
1264- < MultiSelectOptionItem
1265- key = { option . value }
1266- option = { option }
1267- isReadOnly = { isReadOnly }
1268- selectedValues = { selectedValues }
1269- toggleOption = { toggleOption }
1270- setOptionSelected = { setOptionSelected }
1271- onEditItem = { onEditItem }
1272- />
1273- ) ) }
1274- </ CommandGroup >
1275- ) )
1250+ }
1251+ aria-label = { `Select all ${
1252+ getAllOptions ( ) . length
1253+ } options`}
1254+ className = "cursor-pointer"
1255+ >
1256+ < div
1257+ className = { cn (
1258+ "border-primary mr-2 flex h-4 w-4 items-center justify-center rounded-sm border" ,
1259+ selectedValues . length ===
1260+ getAllOptions ( ) . filter ( ( opt ) => ! opt . disabled )
1261+ . length
1262+ ? "bg-primary"
1263+ : "opacity-50 [&_svg]:invisible" ,
1264+ ) }
1265+ aria-hidden = "true"
1266+ >
1267+ < CheckIcon className = "text-primary-foreground h-4 w-4" />
1268+ </ div >
1269+ < span >
1270+ (Wybierz wszystkie
1271+ { getAllOptions ( ) . length > 20
1272+ ? ` – ${ declineNumeric (
1273+ getAllOptions ( ) . length ,
1274+ "option" ,
1275+ { singularCase : GrammaticalCase . Accusative } ,
1276+ ) } `
1277+ : "" }
1278+ )
1279+ </ span >
1280+ </ CommandItem >
1281+ </ CommandGroup >
1282+ ) }
1283+ { isGroupedOptions ( filteredOptions ) ? (
1284+ filteredOptions . map ( ( group ) => (
1285+ < CommandGroup
1286+ key = { group . heading }
1287+ heading = { group . heading }
1288+ >
1289+ { group . options . map ( ( option ) => (
1290+ < MultiSelectOptionItem
1291+ key = { option . value }
1292+ option = { option }
1293+ isReadOnly = { isReadOnly }
1294+ selectedValues = { selectedValues }
1295+ toggleOption = { toggleOption }
1296+ setOptionSelected = { setOptionSelected }
1297+ onEditItem = { onEditItem }
1298+ />
1299+ ) ) }
1300+ </ CommandGroup >
1301+ ) )
1302+ ) : (
1303+ < CommandGroup >
1304+ { filteredOptions . map ( ( option ) => (
1305+ < MultiSelectOptionItem
1306+ key = { option . value }
1307+ option = { option }
1308+ isReadOnly = { isReadOnly }
1309+ selectedValues = { selectedValues }
1310+ toggleOption = { toggleOption }
1311+ setOptionSelected = { setOptionSelected }
1312+ onEditItem = { onEditItem }
1313+ />
1314+ ) ) }
1315+ </ CommandGroup >
1316+ ) }
1317+ </ >
12761318 ) : (
1277- < CommandGroup >
1278- { filteredOptions . map ( ( option ) => (
1279- < MultiSelectOptionItem
1280- key = { option . value }
1281- option = { option }
1282- isReadOnly = { isReadOnly }
1283- selectedValues = { selectedValues }
1284- toggleOption = { toggleOption }
1285- setOptionSelected = { setOptionSelected }
1286- onEditItem = { onEditItem }
1287- />
1288- ) ) }
1289- </ CommandGroup >
1319+ < div className = "text-muted-foreground px-3 py-6 text-sm" >
1320+ { emptyIndicator || "Brak wyników." }
1321+ </ div >
12901322 ) }
12911323 </ CommandList >
1292- < CommandSeparator />
1324+ < Separator className = "bg-border" />
12931325 < CommandGroup >
12941326 < div className = "flex items-center justify-between" >
1295- { selectedValues . length > 0 && (
1327+ { hasSelectedInFiltered && (
12961328 < >
12971329 < CommandItem
12981330 onSelect = { handleClear }
0 commit comments