@reactodia/workspace
Version:
Reactodia Workspace -- library for visual interaction with graphs in a form of a diagram.
253 lines (238 loc) • 6.67 kB
text/typescript
import type * as React from 'react';
import type { LinkTypeIri } from '../data/model';
import type { Element, ElementTemplateState, Link } from './elements';
import type { SizeProvider, Vector } from './geometry';
import type { GraphStructure } from './model';
/**
* Provides a custom type style for an element with specific set of types.
*
* @param types sorted array of element type IRIs
* @returns custom type style for the specific combination of element types or
* `undefined` if default style should be used
*/
export type TypeStyleResolver = (types: ReadonlyArray<string>) => TypeStyle | undefined;
/**
* Provides a custom template to render an element on the canvas.
*/
export type ElementTemplateResolver = (element: Element) =>
ElementTemplate | ElementTemplateComponent | undefined;
/**
* Provides a custom rendering on a diagram for links of specific type.
*/
export type LinkTemplateResolver = (linkTypeId: LinkTypeIri) => LinkTemplate | undefined;
/**
* Common style for a type or set of types to display in various parts of the UI.
*
* @see {@link TypeStyleResolver}
*/
export interface TypeStyle {
/**
* CSS color string.
*/
readonly color?: string;
/**
* Icon image URL.
*/
readonly icon?: string;
/**
* Whether the icon is assumed to be monochrome, so it can be
* inverted for the dark theme.
*
* @default false
*/
readonly iconMonochrome?: boolean;
}
/**
* Custom template to render a single diagram element.
*/
export interface ElementTemplate {
/**
* Assumed shape type for the rendered diagram element to
* correctly connect links and other geometry calculations.
*
* @default "rect"
*/
readonly shape?: 'rect' | 'ellipse';
/**
* Renders the element on the normal (non-SVG) canvas layer.
*
* **Note**: this should be a pure function, not a React component by itself.
*/
readonly renderElement: (props: TemplateProps) => React.ReactNode;
}
/**
* Custom React component to render a single diagram element.
*
* @see {@link ElementTemplate}
*/
export type ElementTemplateComponent = React.ComponentType<TemplateProps>;
/**
* Props for a custom {@link ElementTemplate} component.
*
* @see {@link ElementTemplate}
*/
export interface TemplateProps {
/**
* Target element ID ({@link Element.id}).
*/
readonly elementId: string;
/**
* Target element to render.
*/
readonly element: Element;
/**
* Specifies whether element is in the expanded state.
*
* Same as {@link Element.isExpanded}.
*/
readonly isExpanded: boolean;
/**
* Template-specific state for the element.
*
* Same as {@link Element.elementState}.
*/
readonly elementState?: ElementTemplateState;
}
/**
* Custom template to render links with the same link type.
*/
export interface LinkTemplate {
/**
* SVG path marker style at the source of the link.
*/
markerSource?: LinkMarkerStyle;
/**
* SVG path marker style at the target of the link.
*/
markerTarget?: LinkMarkerStyle;
/**
* SVG path spline type between source and target elements:
* - `straight`: a spline with straight line segments,
* - `smooth`: a spline with cubic-bezier curve segments.
*
* @default "smooth"
*/
spline?: 'straight' | 'smooth';
/**
* Renders the link component on SVG canvas layer.
*
* **Note**: this should be a pure function, not a React component by itself.
*/
readonly renderLink: (props: LinkTemplateProps) => React.ReactNode;
}
/**
* Custom style for SVG path markers at link ends.
*
* @see {@link LinkTemplate}
*/
export interface LinkMarkerStyle {
/**
* SVG path geometry for the marker.
*/
readonly d?: string;
/**
* SVG marker width (px).
*/
readonly width?: number;
/**
* SVG marker height (px).
*/
readonly height?: number;
/**
* SVG marker fill (background) color.
*/
readonly fill?: string;
/**
* SVG marker stroke (line) color.
*/
readonly stroke?: string;
/**
* SVG marker stroke (line) thickness.
*/
readonly strokeWidth?: string | number;
}
/**
* Props for custom link template rendering.
*
* @see {@link LinkTemplate.renderLink}
*/
export interface LinkTemplateProps {
/**
* Target link to render.
*/
link: Link;
/**
* SVG path for the link geometry.
*/
path: string;
/**
* Provides paper position along the link at the specified offset.
*
* Offset of `0.0` corresponds to the source
* and `1.0` corresponds to the target of the link.
*/
getPathPosition: (offset: number) => Vector;
/**
* SVG path marker for the link source.
*/
markerSource: string;
/**
* SVG path marker for the link target.
*/
markerTarget: string;
/**
* Route data (geometry) for the link.
*/
route?: RoutedLink;
}
/**
* Provides custom geometry for links based on connections between elements
* and their positions and sizes.
*
* @category Core
*/
export interface LinkRouter {
/**
* Computes route data for each link of the specified `graph`.
*/
route(graph: GraphStructure, sizeProvider: SizeProvider): RoutedLinks;
}
/**
* Maps {@link Link.id} to the route data for that link.
*/
export type RoutedLinks = Map<string, RoutedLink>;
/**
* Route data (geometry) for a link.
*/
export interface RoutedLink {
/**
* Target link ID ({@link Link.id}).
*/
readonly linkId: string;
/**
* Override for the link vertices ({@link Link.vertices}).
*/
readonly vertices: ReadonlyArray<Vector>;
/**
* Override for default text alignment for all link labels.
*/
readonly labelTextAnchor?: 'start' | 'middle' | 'end';
}
/**
* Provides a strategy to rename diagram links (change labels).
*/
export interface RenameLinkProvider {
/**
* Returns `true` if the target link has editable label.
*/
canRename(link: Link): boolean;
/**
* Gets changed label for the link if renamed,
* otherwise `undefined`.
*/
getLabel(link: Link): string | undefined;
/**
* Sets changed label for the link.
*/
setLabel(link: Link, label: string): void;
}