Bin
2025-12-17 262fecaa75b2909ad244f12c3b079ed3ff4ae329
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { observer } from "mobx-react";
import { isAlive } from "mobx-state-tree";
 
import type { IReactComponent } from "mobx-react/dist/types/IReactComponent";
import { type ExoticComponent, Fragment, type ReactNode, useCallback } from "react";
import { Portal } from "react-konva-utils";
 
type Region = {
  annotation: any;
  hidden: boolean;
  // ...
  setShapeRef(ref: any): void;
  inSelection: boolean;
};
 
type RegionComponentProps = {
  item: Region;
  setShapeRef: (ref: any) => void;
};
 
type Options = {
  renderHidden?: boolean;
  shouldNotUsePortal?: boolean;
};
 
type PortalProps = {
  selector?: string;
  enabled?: boolean;
  children: ReactNode;
};
 
export const AliveRegion = (RegionComponent: IReactComponent<RegionComponentProps>, options?: Options) => {
  const ObservableRegion = observer(RegionComponent);
 
  return observer(({ item, ...rest }: RegionComponentProps) => {
    const canRender = options?.renderHidden || !item.hidden;
    const shouldNotUsePortal = options?.shouldNotUsePortal;
    const Wrapper = (shouldNotUsePortal ? Fragment : Portal) as ExoticComponent<PortalProps>;
    const wrapperProps = shouldNotUsePortal ? {} : { selector: ".selection-regions-layer", enabled: item.inSelection };
    const isInTree = !!item.annotation;
    const setShapeRef = useCallback(
      (ref) => {
        if (isAlive(item)) {
          item.setShapeRef(ref);
        }
      },
      [item],
    );
 
    return isInTree && isAlive(item) && canRender ? (
      <Wrapper {...wrapperProps}>
        <ObservableRegion item={item} {...rest} setShapeRef={setShapeRef} />
      </Wrapper>
    ) : null;
  });
};