import { DiagramEdge, DiagramNode, DynamicViewDisplayVariant, LayoutedView, LayoutType, WhereOperator } from '@likec4/core/types';
import { ReactFlowProps } from '@xyflow/react';
import { MouseEvent as ReactMouseEvent, ReactNode } from 'react';
import { CamelCasedProperties, SetRequired } from 'type-fest';
import { DiagramApi } from './hooks/useDiagram';
import { XYFlowInstance } from './hooks/useXYFlow';
import { Types } from './likec4diagram/types';
import type * as t from '@likec4/core/types';
type Any = t.aux.Any;
type Unknown = t.aux.UnknownLayouted;
type ViewId = t.aux.ViewId;
type Fqn = t.aux.Fqn;
type RelationId = t.aux.RelationId;
type DeploymentFqn = t.aux.DeploymentFqn;
type StrictViewId = t.aux.StrictViewId;
export type NodeRenderers = Partial>;
export type { WhereOperator };
export type DiagramNodeWithNavigate = SetRequired, 'navigateTo'>;
export type ElementIconRendererProps = {
node: {
id: string;
title: string;
icon?: string | null | undefined;
};
className?: string;
};
export type ElementIconRenderer = (props: ElementIconRendererProps) => ReactNode;
export type LikeC4ColorScheme = 'light' | 'dark';
export type OverrideReactFlowProps = Pick, 'paneClickDistance' | 'nodeClickDistance' | 'selectionKeyCode' | 'panActivationKeyCode' | 'multiSelectionKeyCode' | 'zoomActivationKeyCode' | 'snapToGrid' | 'snapGrid' | 'onlyRenderVisibleElements' | 'nodesDraggable' | 'nodesFocusable' | 'elementsSelectable' | 'selectNodesOnDrag' | 'panOnDrag' | 'preventScrolling' | 'zoomOnScroll' | 'zoomOnPinch' | 'panOnScroll' | 'panOnScrollSpeed' | 'panOnScrollMode' | 'zoomOnDoubleClick' | 'nodeDragThreshold'>;
export type PaddingUnit = 'px' | '%';
export type PaddingWithUnit = `${number}${PaddingUnit}` | number;
export type ViewPaddings = {
top?: PaddingWithUnit;
right?: PaddingWithUnit;
bottom?: PaddingWithUnit;
left?: PaddingWithUnit;
x?: PaddingWithUnit;
y?: PaddingWithUnit;
};
/**
* Padding around the diagram
*
* @example
* {
* top: '8px',
* right: '8px',
* bottom: '8px',
* left: '8px',
* }
*
* {
* x: '16px',
* y: '16px',
* }
*/
export type ViewPadding = PaddingWithUnit | ViewPaddings;
export interface LikeC4DiagramProperties {
view: LayoutedView;
className?: string | undefined;
/**
* Enable/disable panning
* @default true
*/
pannable?: boolean | undefined;
/**
* Enable/disable zooming
* @default true
*/
zoomable?: boolean | undefined;
/**
* Show/hide panel with top left controls
*
* @default true
*/
controls?: boolean | undefined;
/**
* If set, initial viewport will show all nodes & edges
* @default true
*/
fitView?: boolean | undefined;
/**
* Padding around the diagram (number - pixels)
* @default 16 - 16px
*
* @see {@link ViewPadding}
*
* @example
* ```tsx
*
*
*
* ```
*/
fitViewPadding?: ViewPadding | undefined;
/**
* If not readonly, or `enableFocusMode`, `onNavigateTo` or `onNodeClick` are set - nodes will be selectable
*
* @default false
*/
nodesSelectable?: boolean | undefined;
/**
* Initial width of the diagram
* (supposed to be used during SSR)
*/
initialWidth?: number | undefined;
/**
* Initial height of the diagram
* (supposed to be used during SSR)
*/
initialHeight?: number | undefined;
/**
* Background pattern
* @default 'dots'
*/
background?: 'transparent' | 'solid' | 'dots' | 'lines' | 'cross' | undefined;
/**
* Show back/forward history navigation buttons
* @default true if `onNavigateTo` is set
*/
showNavigationButtons?: undefined | boolean;
/**
* Display notations in the bottom right corner
* (Active if only notations are present)
*
* @default false
*/
enableNotations?: boolean | undefined;
/**
* Display dropdown with details on relationship's label click
* @default false
*/
enableRelationshipDetails?: boolean | undefined;
/**
* If double click on a node should enable focus mode, i.e. highlight incoming/outgoing edges
* @default false
*/
enableFocusMode?: boolean | undefined;
/**
* Enable search popup for elements and views
* @default true
*/
enableSearch?: boolean | undefined;
/**
* Enable modal with element details
* @default false
*/
enableElementDetails?: boolean | undefined;
/**
* Experimental feature to browse relationships
*
* @default false
*/
enableRelationshipBrowser?: boolean | undefined;
/**
* If Walkthrough for dynamic views should be enabled
* @default false
*/
enableDynamicViewWalkthrough?: boolean | undefined;
/**
* Enable "Compare with auto layout" action when view was manually modified and out of sync with latest model
* @default true if `onLayoutTypeChange` is set, false otherwise
*/
enableCompareWithLatest?: boolean | undefined;
/**
* Default dynamic view display variant
* @default 'diagram'
*/
dynamicViewVariant?: DynamicViewDisplayVariant | undefined;
/**
* Display element tags in the bottom left corner
* @default false
*/
enableElementTags?: boolean | undefined;
/**
* Display element notes, if they are present in the view
*
* @default true
*/
enableNotes?: boolean | undefined;
/**
* Improve performance by hiding certain elements and reducing visual effects (disable mix-blend, shadows, animations)
* Enable it if you have a large or static view
* - `auto` - will be `true` if view has more then 3000 * 2000 pixels
*
* @default 'auto'
*/
reduceGraphics?: 'auto' | boolean | undefined;
/**
* Render icon for an element, bundled or remote
* By default, if icon is http:// or https://, it will be rendered as an image
*
* Consider using `IconRendererProvider`
*/
renderIcon?: ElementIconRenderer | undefined;
/**
* Override node renderers
*/
renderNodes?: NodeRenderers | undefined;
/**
* Dynamic filter, applies both to nodes and edges
*/
where?: WhereOperator | undefined;
/**
* Override ReactFlow props
*/
reactFlowProps?: OverrideReactFlowProps | undefined;
}
export type OpenSourceParams = {
element: Fqn;
property?: string;
} | {
relation: RelationId;
} | {
deployment: DeploymentFqn;
property?: string;
} | {
view: StrictViewId;
} | {
view: StrictViewId;
astPath: string;
};
/**
* "Go to source" action
*/
export type OnOpenSource = (params: OpenSourceParams) => void;
export type OnNavigateTo = (to: ViewId, event?: ReactMouseEvent, element?: DiagramNodeWithNavigate) => void;
export type OnNodeClick = (node: DiagramNode, event: ReactMouseEvent) => void;
export type OnEdgeClick = (edge: DiagramEdge, event: ReactMouseEvent) => void;
/**
* On pane/canvas click (not on any node or edge)
*/
export type OnCanvasClick = (event: ReactMouseEvent) => void;
export type OnCanvasContextMenu = (event: ReactMouseEvent) => void;
export type OnInitialized = (params: {
diagram: DiagramApi;
xyflow: XYFlowInstance;
}) => void;
export type OnLayoutTypeChange = (layoutType: LayoutType) => void;
export interface LikeC4DiagramEventHandlers {
onNavigateTo?: OnNavigateTo | null | undefined;
onNodeClick?: OnNodeClick | null | undefined;
onNodeContextMenu?: OnNodeClick | null | undefined;
onCanvasContextMenu?: OnCanvasContextMenu | null | undefined;
onEdgeClick?: OnEdgeClick | null | undefined;
onEdgeContextMenu?: OnEdgeClick | null | undefined;
onCanvasClick?: OnCanvasClick | null | undefined;
onCanvasDblClick?: OnCanvasClick | null | undefined;
onLogoClick?: null | undefined | (() => void);
onOpenSource?: OnOpenSource | null | undefined;
onInitialized?: OnInitialized | null | undefined;
/**
* Triggered when user changes layout type (e.g. from 'manual' to 'auto')
* Expected another `view` to be passed to the diagram
*
* @param layoutType new layout type
*/
onLayoutTypeChange?: OnLayoutTypeChange | null | undefined;
}