@@ -65,6 +65,9 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
6565 Record < string , boolean >
6666 > ( initialFolderStates || { } ) ;
6767
68+ const [ searchBasedExpCollapse , setSearchBasedExpCollapse ] = useState <
69+ Record < string , boolean >
70+ > ( { } ) ;
6871 // refs
6972 const searchInputRef = useRef < HTMLInputElement > ( null ) ;
7073 const contentContainerRef = useRef < HTMLDivElement > ( null ) ;
@@ -90,6 +93,7 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
9093 // compute
9194 const defaultFolderScope = '___DEFAULT' ;
9295 const hasCustomSearchQuery = customSearchQuery !== undefined ;
96+ const hasSearchQuery = ( customSearchQuery ?? searchQuery ) !== '' ;
9397 const folderScopedItems = useMemo <
9498 IFolderScopedItem < IGroupedFieldsKeeperItem > [ ]
9599 > ( ( ) => {
@@ -221,6 +225,29 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
221225 sortBasedOnFolder ,
222226 ] ) ;
223227
228+ useEffect ( ( ) => {
229+ if ( ! hasSearchQuery ) {
230+ setSearchBasedExpCollapse ( { } ) ;
231+ return ;
232+ }
233+
234+ if ( Object . keys ( searchBasedExpCollapse ) . length === 0 ) {
235+ const allExpanded : Record < string , boolean > = { } ;
236+ folderScopedItems . forEach ( ( folderItem ) => {
237+ const folderId = folderItem . folderScopeItem ?. id ;
238+ if ( folderId ) {
239+ allExpanded [ folderId ] = false ;
240+ }
241+ } ) ;
242+ setSearchBasedExpCollapse ( allExpanded ) ;
243+ }
244+ } , [ hasSearchQuery ] ) ;
245+
246+ const activeCollapseMap = hasSearchQuery ? searchBasedExpCollapse : collapsedNodes ;
247+ const setActiveCollapseMap = hasSearchQuery
248+ ? setSearchBasedExpCollapse
249+ : setCollapsedNodes ;
250+
224251 useEffect ( ( ) => {
225252 if ( contentContainerRef . current ) {
226253 const markInstance = new Mark ( contentContainerRef . current ) ;
@@ -265,25 +292,19 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
265292
266293 const onExpandCollapseAll = ( isCollapse : boolean ) => {
267294 const collapsedFolders : Record < string , boolean > = { } ;
268- folderScopedItems . map ( ( folderItem ) => {
269- if ( folderItem . folderScopeItem ) {
270- const folderId = folderItem . folderScopeItem . id as string ;
271- collapsedFolders [ folderId ] = isCollapse ;
272- }
295+ folderScopedItems . forEach ( ( folderItem ) => {
296+ const folderId = folderItem . folderScopeItem ?. id as string ;
297+ if ( folderId ) collapsedFolders [ folderId ] = isCollapse ;
273298 } ) ;
274- setCollapsedNodes ( ( prevState ) => {
275- const newState = {
276- ...prevState ,
277- ...collapsedFolders ,
278- } ;
279-
299+
300+ setActiveCollapseMap ( ( prev ) => {
301+ const newState = { ...prev , ...collapsedFolders } ;
280302 if ( onFolderStateChange ) {
281- Object . keys ( collapsedFolders ) . forEach ( folderId => {
282- onFolderStateChange ( folderId , isCollapse , newState ) ;
283- } ) ;
303+ Object . keys ( collapsedFolders ) . forEach ( ( folderId ) =>
304+ onFolderStateChange ( folderId , isCollapse , newState ) ,
305+ ) ;
284306 }
285-
286- return newState ;
307+ return newState ;
287308 } ) ;
288309 } ;
289310 const onKeyDown = (
@@ -345,9 +366,10 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
345366 key = { index }
346367 folderScopedItem = { folderScopedItem }
347368 showFlatFolderScope = { showFlatFolderScope }
369+ hasSearchQuery = { hasSearchQuery }
348370 folderScopedItemsArray = { folderScopedItems }
349- collapsedNodes = { collapsedNodes }
350- setCollapsedNodes = { setCollapsedNodes }
371+ collapsedNodes = { activeCollapseMap }
372+ setCollapsedNodes = { setActiveCollapseMap }
351373 onExpandCollapseAll = { onExpandCollapseAll }
352374 />
353375 ) )
@@ -401,6 +423,7 @@ function FolderScopeItemRenderer(
401423 props : IFieldsKeeperRootBucketProps & {
402424 folderScopedItem : IFolderScopedItem < IGroupedFieldsKeeperItem > ;
403425 showFlatFolderScope : boolean ;
426+ hasSearchQuery : boolean ;
404427 folderScopedItemsArray : IFolderScopedItem < IGroupedFieldsKeeperItem > [ ] ;
405428 collapsedNodes : Record < string , boolean > ;
406429 setCollapsedNodes : React . Dispatch <
@@ -413,9 +436,9 @@ function FolderScopeItemRenderer(
413436 const {
414437 folderScopedItem : { type, folderScopeItem, folderScopeItems } ,
415438 showFlatFolderScope,
439+ hasSearchQuery,
416440 folderScopedItemsArray,
417- collapsedNodes,
418- setCollapsedNodes,
441+ collapsedNodes : activeCollapseMap , setCollapsedNodes : setActive ,
419442 customClassNames,
420443 sortBasedOnFolder = true ,
421444 suffixNodeRenderer,
@@ -495,7 +518,7 @@ function FolderScopeItemRenderer(
495518 if ( rootBucketProps . collapseFoldersOnMount !== undefined ) {
496519 setIsFolderCollapsed ( rootBucketProps . collapseFoldersOnMount ) ;
497520 if ( rootBucketProps . collapseFoldersOnMount ) {
498- setCollapsedNodes ( ( prevState ) => ( {
521+ setActive ( ( prevState ) => ( {
499522 ...prevState ,
500523 [ id ] : true ,
501524 } ) ) ;
@@ -504,10 +527,10 @@ function FolderScopeItemRenderer(
504527 } , [ rootBucketProps . collapseFoldersOnMount , id ] ) ;
505528
506529 useEffect ( ( ) => {
507- if ( Object . keys ( collapsedNodes ) . includes ( id ) ) {
508- setIsFolderCollapsed ( collapsedNodes [ id ] ) ;
530+ if ( Object . keys ( activeCollapseMap ) . includes ( id ) ) {
531+ setIsFolderCollapsed ( activeCollapseMap [ id ] ) ;
509532 }
510- } , [ collapsedNodes ] ) ;
533+ } , [ activeCollapseMap ] ) ;
511534
512535 useEffect ( ( ) => {
513536 setCrossHighlightItemIds (
@@ -576,24 +599,20 @@ function FolderScopeItemRenderer(
576599
577600 setHighlightedItem ( instanceId , null ) ;
578601 const toggleCollapse = ( id : string ) => {
579- setCollapsedNodes ( ( prevState ) => {
602+ setActive ( ( prevState ) => {
580603 const newCollapsed = ! prevState [ id ] ;
581- const newState = {
582- ...prevState ,
583- [ id ] : newCollapsed ,
584- } ;
585-
604+ const newState = { ...prevState , [ id ] : newCollapsed } ;
605+
586606 if ( rootBucketProps . onFolderStateChange ) {
587607 rootBucketProps . onFolderStateChange ( id , newCollapsed , newState ) ;
588608 }
589-
590609 return newState ;
591610 } ) ;
592611
593612 // Move highlight update logic outside of render phase
594613 const highlightedIds = getCrossHighlightIds ( ) ;
595614 const folderIds = getFolderIdsFromValues ( foldersMeta ) ;
596- const updatedHighlightIds = ! collapsedNodes [ id ]
615+ const updatedHighlightIds = ! activeCollapseMap [ id ]
597616 ? [ ...highlightedIds . filter ( ( id ) => folderIds . includes ( id ) ) ]
598617 : highlightedIds ;
599618 setCrossHighlightItemIds ( updatedHighlightIds ) ;
@@ -670,7 +689,7 @@ function FolderScopeItemRenderer(
670689 if ( foldersMeta [ folder ] . isHidden ) {
671690 isHidden = true ;
672691 }
673- if ( collapsedNodes [ folder ] ) {
692+ if ( activeCollapseMap [ folder ] ) {
674693 isCollapsed = true ;
675694 }
676695 } ) ;
@@ -872,7 +891,7 @@ function FolderScopeItemRenderer(
872891 }
873892 if ( isFolderCollapsedOriginal ) {
874893 setIsFolderCollapsed ( false ) ;
875- setCollapsedNodes ( ( prevState ) => ( {
894+ setActive ( ( prevState ) => ( {
876895 ...prevState ,
877896 [ id ] : false ,
878897 } ) ) ;
@@ -1237,30 +1256,37 @@ function GroupedItemRenderer(
12371256
12381257 // State to manage editable field items and their labels
12391258 const [ editableItemId , setEditableItemId ] = useState < string | null > ( null ) ;
1240- const [ editedLabels , setEditedLabels ] = useState < Record < string , string > > ( ( ) => {
1241- const labels : Record < string , string > = { } ;
1259+ const [ editedLabels , setEditedLabels ] = useState < Record < string , string > > (
1260+ ( ) => {
1261+ const labels : Record < string , string > = { } ;
12421262
1243- // 1. Add all real items
1244- allItems . forEach ( ( item ) => {
1245- labels [ item . id ] = item . label ;
1246- } ) ;
1263+ // 1. Add all real items
1264+ allItems . forEach ( ( item ) => {
1265+ labels [ item . id ] = item . label ;
1266+ } ) ;
12471267
1248- // 2. Add group header (if exists)
1249- if ( group && group !== FIELDS_KEEPER_CONSTANTS . NO_GROUP_ID && groupLabel ) {
1250- labels [ group ] = groupLabel ;
1251- }
1268+ // 2. Add group header (if exists)
1269+ if (
1270+ group &&
1271+ group !== FIELDS_KEEPER_CONSTANTS . NO_GROUP_ID &&
1272+ groupLabel
1273+ ) {
1274+ labels [ group ] = groupLabel ;
1275+ }
12521276
1253- // 3. Add flat group header (if exists)
1254- if (
1255- flatGroup &&
1256- flatGroup !== FIELDS_KEEPER_CONSTANTS . NO_GROUP_ID &&
1257- flatGroupLabel
1258- ) {
1259- labels [ flatGroup as string ] = flatGroupLabel as string ;
1260- }
1277+ // 3. Add flat group header (if exists)
1278+ if (
1279+ flatGroup &&
1280+ flatGroup !== FIELDS_KEEPER_CONSTANTS . NO_GROUP_ID &&
1281+ flatGroupLabel
1282+ ) {
1283+ labels [ flatGroup as string ] = flatGroupLabel as string ;
1284+ }
1285+
1286+ return labels ;
1287+ } ,
1288+ ) ;
12611289
1262- return labels ;
1263- } ) ;
12641290 const inputRefs = useRef < Record < string , HTMLInputElement | null > > ( { } ) ;
12651291
12661292 // Click tracking for double-click detection
@@ -1288,9 +1314,11 @@ function GroupedItemRenderer(
12881314 }
12891315 return activeIds ;
12901316 } ;
1317+
12911318 const [ activeHighlightIds , setActiveHighlightIds ] = useState <
12921319 Record < string , IHighlightInfo >
12931320 > ( getInitialActiveHighlightIds ( ) ) ;
1321+
12941322 useEffect ( ( ) => {
12951323 if ( highlightedItem ) {
12961324 setActiveHighlightIds ( ( prev ) => ( {
@@ -1362,28 +1390,28 @@ function GroupedItemRenderer(
13621390 // Update editedLabels when allItems change
13631391 useEffect ( ( ) => {
13641392 setEditedLabels ( ( prev ) => {
1365- const newLabels = { ...prev } ;
1393+ const newLabels = { ...prev } ;
13661394
1367- // Sync real items
1368- allItems . forEach ( ( item ) => {
1369- if ( ! ( item . id in newLabels ) ) {
1370- newLabels [ item . id ] = item . label ;
1371- }
1372- } ) ;
1395+ // Sync real items
1396+ allItems . forEach ( ( item ) => {
1397+ if ( ! ( item . id in newLabels ) ) {
1398+ newLabels [ item . id ] = item . label ;
1399+ }
1400+ } ) ;
13731401
1374- // Sync group header
1375- if ( group && group !== FIELDS_KEEPER_CONSTANTS . NO_GROUP_ID && groupLabel ) {
1376- newLabels [ group ] = groupLabel ;
1377- }
1402+ // Sync group header
1403+ if ( group && group !== FIELDS_KEEPER_CONSTANTS . NO_GROUP_ID && groupLabel ) {
1404+ newLabels [ group ] = groupLabel ;
1405+ }
13781406
1379- // Sync flat group
1380- if ( flatGroup && flatGroup !== FIELDS_KEEPER_CONSTANTS . NO_GROUP_ID && flatGroupLabel ) {
1381- newLabels [ flatGroup as string ] = flatGroupLabel as string ;
1382- }
1407+ // Sync flat group
1408+ if ( flatGroup && flatGroup !== FIELDS_KEEPER_CONSTANTS . NO_GROUP_ID && flatGroupLabel ) {
1409+ newLabels [ flatGroup as string ] = flatGroupLabel as string ;
1410+ }
13831411
1384- return newLabels ;
1385- } ) ;
1386- } , [ allItems , group , groupLabel , flatGroup , flatGroupLabel ] ) ;
1412+ return newLabels ;
1413+ } ) ;
1414+ } , [ allItems , group , groupLabel , flatGroup , flatGroupLabel ] ) ;
13871415
13881416 // Handler functions for inline editing
13891417 const onInputFieldChange = ( fieldId : string , newValue : string ) => {
@@ -1446,8 +1474,6 @@ function GroupedItemRenderer(
14461474 clickTimeoutRef . current = null ;
14471475 } , DOUBLE_CLICK_THRESHOLD ) ;
14481476 } else if ( onFieldItemLabelChange && clickCountRef . current === 2 ) {
1449- console . log ( clickTimeoutRef . current , " clickTimeoutRef.current ++" )
1450- console . log ( fieldItem , " field Item ++" )
14511477 if ( clickTimeoutRef . current ) {
14521478 clearTimeout ( clickTimeoutRef . current ) ;
14531479 clickTimeoutRef . current = null ;
@@ -1498,6 +1524,7 @@ function GroupedItemRenderer(
14981524 const customTargetBucketIdentifier =
14991525 getPriorityTargetBucketToFillFromProps ??
15001526 getPriorityTargetBucketToFillFromContext ;
1527+
15011528 const getPriorityTargetBucketToFill = ( {
15021529 buckets,
15031530 currentFillingItem,
0 commit comments