@@ -376,4 +376,149 @@ export function selectBlocksWithConnections(
376376 connection: connectionIds
377377 }, ESelectionStrategy .REPLACE );
378378}
379- ```
379+ ```
380+
381+ ## 7. Component Resolution
382+
383+ ### Overview
384+
385+ Selection buckets support automatic resolution of selected IDs to their corresponding GraphComponent instances. This provides three levels of selection data:
386+
387+ 1 . ** IDs** (` $selected ` ) - Set of selected entity IDs
388+ 2 . ** Entities** (` $selectedEntities ` ) - Resolved entity objects (e.g., ` BlockState ` , ` ConnectionState ` )
389+ 3 . ** Components** (` $selectedComponents ` ) - Resolved ` GraphComponent ` instances (e.g., ` Block ` , ` BaseConnection ` )
390+
391+ ### Resolution Flow
392+
393+ ```
394+ ID → Entity (via resolver) → Component (via getViewComponent())
395+ ```
396+
397+ ### Creating Buckets with Resolvers
398+
399+ ``` typescript
400+ // In BlockListStore
401+ this .blockSelectionBucket = new MultipleSelectionBucket <TBlockId , BlockState >(
402+ " block" ,
403+ (payload , defaultAction ) => {
404+ return this .graph .execut еDefaultEventAction (" blocks-selection-change" , payload , defaultAction );
405+ },
406+ (element ) => element instanceof Block ,
407+ // Resolver function: converts IDs to BlockState instances
408+ (ids ) => ids .map ((id ) => this .getBlockState (id )).filter ((block ) => block !== undefined )
409+ );
410+ ```
411+
412+ ### Using Component Resolution
413+
414+ ``` typescript
415+ // Get selected block IDs
416+ const selectedIds = blockBucket .$selected .value ;
417+ // Type: Set<string | number>
418+
419+ // Get selected BlockState instances
420+ const selectedStates = blockBucket .$selectedEntities .value ;
421+ // Type: BlockState[]
422+
423+ // Get selected Block components (GraphComponent)
424+ const selectedComponents = blockBucket .$selectedComponents .value ;
425+ // Type: GraphComponent[] (actually Block[])
426+ ```
427+
428+ ### Collecting All Selected Components
429+
430+ ``` typescript
431+ // Collect selected components from all buckets
432+ const allSelectedComponents: GraphComponent [] = [];
433+ const selection = graph .selectionService .$selection .value ;
434+
435+ for (const entityType of selection .keys ()) {
436+ const bucket = graph .selectionService .getBucket (entityType );
437+ if (bucket ) {
438+ allSelectedComponents .push (... bucket .$selectedComponents .value );
439+ }
440+ }
441+
442+ // Now work with all selected components (blocks, connections, etc.)
443+ allSelectedComponents .forEach ((component ) => {
444+ const [minX, minY, maxX, maxY] = component .getHitBox ();
445+ // ... use component data
446+ });
447+ ```
448+
449+ ### Store Computed Signals
450+
451+ Stores provide convenient computed signals for accessing selected components:
452+
453+ ``` typescript
454+ // In BlockListStore
455+ public $selectedBlockComponents = computed (() => {
456+ return this .blockSelectionBucket .$selectedComponents .value as Block [];
457+ });
458+
459+ // Usage
460+ const selectedBlocks = graph .rootStore .blocksList .$selectedBlockComponents .value ;
461+ // Type: Block[]
462+
463+ // In ConnectionsStore
464+ public $selectedConnectionComponents = computed (() => {
465+ return this .connectionSelectionBucket .$selectedComponents .value as BaseConnection [];
466+ });
467+
468+ // Usage
469+ const selectedConnections = graph .rootStore .connectionsList .$selectedConnectionComponents .value ;
470+ // Type: BaseConnection[]
471+ ```
472+
473+ ### React Integration
474+
475+ ``` typescript
476+ import { useEffect , useState } from " react" ;
477+ import type { Block } from " @gravity-ui/graph" ;
478+
479+ function SelectedBlocksPanel({ graph }) {
480+ const [selectedBlocks, setSelectedBlocks] = useState <Block []>([]);
481+
482+ useEffect (() => {
483+ if (! graph ) return ;
484+
485+ const bucket = graph .rootStore .blocksList .blockSelectionBucket ;
486+
487+ // Subscribe to component changes
488+ const unsubscribe = bucket .$selectedComponents .subscribe ((components ) => {
489+ setSelectedBlocks (components as Block []);
490+ });
491+
492+ return () => unsubscribe ();
493+ }, [graph ]);
494+
495+ return (
496+ <div >
497+ <h3 >Selected : {selectedBlocks .length}</h3 >
498+ {selectedBlocks .map ((block ) = > (
499+ < div key = {block.getEntityId()}>
500+ Block : {block .getEntityId ()}
501+ < / div >
502+ ))}
503+ < / div >
504+ );
505+ }
506+ ```
507+
508+ ### Type Constraints
509+
510+ All selection buckets have a generic constraint on ` TEntity ` :
511+
512+ ``` typescript
513+ class BaseSelectionBucket <
514+ IDType extends TSelectionEntityId ,
515+ TEntity extends TSelectionEntity = TSelectionEntity
516+ >
517+
518+ // TSelectionEntity allows: GraphComponent | IEntityWithComponent | object
519+ interface IEntityWithComponent <T extends GraphComponent = GraphComponent > {
520+ getViewComponent(): T | undefined ;
521+ }
522+ ```
523+
524+ This ensures type safety while maintaining flexibility for different entity types (BlockState, ConnectionState, etc.).
0 commit comments