import { BBox } from '@likec4/core/geometry'; import { DiagramEdge, DiagramNode, DiagramView, DynamicViewDisplayVariant, EdgeId, Fqn, LayoutType, NodeId, NodeNotation as ElementNotation, StepEdgeId, ViewChange, ViewId, WhereOperator } from '@likec4/core/types'; import { EdgeChange, NodeChange, Rect, Viewport } from '@xyflow/system'; import { MouseEvent } from 'react'; import { PartialDeep } from 'type-fest'; import { EnabledFeatures, TogglableFeature } from '../../context/DiagramFeatures'; import { XYFlowInstance, XYStoreApi } from '../../hooks/useXYFlow'; import { OpenSourceParams, ViewPaddings } from '../../LikeC4Diagram.props'; import { Types } from '../types'; import { AlignmentMode } from './aligners'; import { HotKeyEvent, HotkeyActorLogic } from './hotkeyActor'; import { MediaPrintEvent, MediaPrintActorLogic } from './mediaPrintActor'; import { SetupReturn, NonReducibleUnknown, MetaObject } from 'xstate'; import { OverlaysActorLogic } from '../../overlays/overlaysActor'; import { SearchActorLogic } from '../../search/searchActor'; import { EditorActorLogic } from '../../editor'; /** * Navigation history entry represents a current view state, * including viewport, focused node, dynamic view variant, etc. */ export interface NavigationHistoryEntry { viewId: ViewId; viewport: Viewport; viewportChangedManually: boolean; viewportBefore?: null | { wasChangedManually: boolean; value: Viewport; }; focusedNode?: NodeId | null; dynamicViewVariant?: DynamicViewDisplayVariant | null; activeWalkthrough?: null | StepEdgeId; } export interface NavigationHistory { history: ReadonlyArray; currentIndex: number; } export interface Input { view: DiagramView; xystore: XYStoreApi; zoomable: boolean; pannable: boolean; nodesDraggable: boolean; nodesSelectable: boolean; fitViewPadding: ViewPaddings; where: WhereOperator | null; dynamicViewVariant?: DynamicViewDisplayVariant | undefined; features?: EnabledFeatures; } export type ToggledFeatures = { [P in `enable${TogglableFeature}`]?: boolean; }; export interface Context extends Input { xynodes: Types.Node[]; xyedges: Types.Edge[]; features: EnabledFeatures; toggledFeatures: ToggledFeatures; initialized: { xydata: boolean; xyflow: boolean; }; viewport: Viewport; viewportChangedManually: boolean; /** * Viewport before entering focus mode, walkthrough or printing */ viewportBefore: null | { wasChangedManually: boolean; value: Viewport; }; viewportOnManualLayout: null | Viewport; viewportOnAutoLayout: null | Viewport; lastOnNavigate: null | { fromView: ViewId; toView: ViewId; fromNode: NodeId | null; focusOnElement?: Fqn | null; }; navigationHistory: NavigationHistory; lastClickedNode: null | { id: NodeId; clicks: number; timestamp: number; }; focusedNode: NodeId | null; autoUnfocusTimer: boolean; activeElementDetails: null | { fqn: Fqn; fromNode: NodeId | null; nodeRect?: Rect | null; nodeRectScreen?: Rect | null; }; xyflow: XYFlowInstance | null; dynamicViewVariant: DynamicViewDisplayVariant; activeWalkthrough: null | { stepId: StepEdgeId; parallelPrefix: string | null; }; } export type Events = HotKeyEvent | MediaPrintEvent | { type: 'xyflow.init'; instance: XYFlowInstance; } | { type: 'xyflow.applyChanges'; edges?: EdgeChange[]; nodes?: NodeChange[]; } | { type: 'xyflow.viewportMoved'; viewport: Viewport; manually: boolean; } | { type: 'xyflow.nodeClick'; node: Types.Node; } | { type: 'xyflow.edgeClick'; edge: Types.Edge; } | { type: 'xyflow.edgeDoubleClick'; edge: Types.Edge; } | { type: 'xyflow.paneClick'; } | { type: 'xyflow.paneDblClick'; } | { type: 'xyflow.resized'; } | { type: 'xyflow.nodeMouseEnter'; node: Types.Node; } | { type: 'xyflow.nodeMouseLeave'; node: Types.Node; } | { type: 'xyflow.edgeMouseEnter'; edge: Types.Edge; event: MouseEvent; } | { type: 'xyflow.edgeMouseLeave'; edge: Types.Edge; event: MouseEvent; } | { type: 'xyflow.fitDiagram'; duration?: number; bounds?: BBox; } | { type: 'xyflow.setViewport'; duration?: number; viewport: Viewport; } | { type: 'xyflow.centerViewport'; nodeId: NodeId; duration?: number; } | { type: 'xyflow.centerViewport'; edgeId: EdgeId; duration?: number; } | { type: 'update.nodeData'; nodeId: NodeId; data: PartialDeep; } | { type: 'update.edgeData'; edgeId: EdgeId; data: PartialDeep; } | { type: 'update.view'; view: DiagramView; source?: 'editor' | 'external'; } | { type: 'update.view'; view: DiagramView; source?: 'editor' | 'external'; xynodes: Types.Node[]; xyedges: Types.Edge[]; } | { type: 'update.view-bounds'; bounds: BBox; } | { type: 'update.inputs'; inputs: Partial>; } | { type: 'update.features'; features: EnabledFeatures; } | ({ type: 'open.source'; } & OpenSourceParams) | { type: 'open.elementDetails'; fqn: Fqn; fromNode?: NodeId | undefined; } | { type: 'open.relationshipDetails'; params: { edgeId: EdgeId; } | { source: Fqn; target: Fqn; }; } | { type: 'open.relationshipsBrowser'; fqn: Fqn; } | { type: 'open.search'; search?: string; } | { type: 'navigate.to'; viewId: ViewId; fromNode?: NodeId | undefined; focusOnElement?: Fqn | undefined; } | { type: 'navigate.back'; } | { type: 'navigate.forward'; } | { type: 'layout.align'; mode: AlignmentMode; } | { type: 'layout.resetEdgeControlPoints'; } | { type: 'layout.resetManualLayout'; } | { type: 'focus.node'; nodeId: NodeId; autoUnfocus?: boolean; } | { type: 'focus.autoUnfocus'; } | { type: 'switch.dynamicViewVariant'; variant: DynamicViewDisplayVariant; } | { type: 'walkthrough.start'; stepId?: StepEdgeId; } | { type: 'walkthrough.step'; direction: 'next' | 'previous'; } | { type: 'walkthrough.end'; } | { type: 'highlight.node'; nodeId: NodeId; } | { type: 'highlight.edge'; edgeId: EdgeId; } | { type: 'unhighlight.all'; } | { type: 'notations.highlight'; notation: ElementNotation; kind?: string; } | { type: 'notations.unhighlight'; } | { type: 'tag.highlight'; tag: string; } | { type: 'tag.unhighlight'; } | { type: 'toggle.feature'; feature: TogglableFeature; forceValue?: boolean; } | { type: 'trigger.change'; change: ViewChange; } | { type: 'emit.onLayoutTypeChange'; layoutType: LayoutType; } | { type: 'destroy'; }; export type EmittedEvents = { type: 'initialized'; instance: XYFlowInstance; } | { type: 'navigateTo'; viewId: ViewId; } | { type: 'openSource'; params: OpenSourceParams; } | { type: 'paneClick'; } | { type: 'nodeClick'; node: DiagramNode; xynode: Types.Node; } | { type: 'edgeClick'; edge: DiagramEdge; xyedge: Types.Edge; } | { type: 'edgeMouseEnter'; edge: Types.Edge; event: MouseEvent; } | { type: 'edgeMouseLeave'; edge: Types.Edge; event: MouseEvent; } | { type: 'walkthroughStarted'; edge: Types.Edge; } | { type: 'walkthroughStep'; edge: Types.Edge; } | { type: 'walkthroughStopped'; } | { type: 'onLayoutTypeChange'; layoutType: LayoutType; }; export type ActionArg = { context: Context; event: Events; }; export declare const deriveToggledFeatures: (context: Context) => Required; export declare const machine: SetupReturn; export declare const targetState: { idle: string; focused: string; walkthrough: string; printing: string; navigating: string; }; export declare const to: { idle: { target: string; }; focused: { target: string; }; walkthrough: { target: string; }; printing: { target: string; }; navigating: { target: string; }; };