chore(comps): tsdoc update

This commit is contained in:
moklick
2025-02-11 14:19:33 +01:00
parent d8ab3bf0bd
commit 6c937546e4
12 changed files with 298 additions and 4 deletions
@@ -2,6 +2,29 @@ import cc from 'classcat';
import type { ControlButtonProps } from './types';
/**
* You can add buttons to the control panel by using the `<ControlButton />` component
*and pass it as a child to the [`<Controls />`](/api-reference/components/controls) component.
*
* @public
* @example
*```jsx
*import { MagicWand } from '@radix-ui/react-icons'
*import { ReactFlow, Controls, ControlButton } from '@xyflow/react'
*
*export default function Flow() {
* return (
* <ReactFlow nodes={[...]} edges={[...]}>
* <Controls>
* <ControlButton onClick={() => alert('Something magical just happened. ✨')}>
* <MagicWand />
* </ControlButton>
* </Controls>
* </ReactFlow>
* )
*}
*```
*/
export function ControlButton({ children, className, ...rest }: ControlButtonProps) {
return (
<button type="button" className={cc(['react-flow__controls-button', className])} {...rest}>
@@ -125,4 +125,26 @@ function ControlsComponent({
ControlsComponent.displayName = 'Controls';
/**
* The `<Controls />` component renders a small panel that contains convenient
*buttons to zoom in, zoom out, fit the view, and lock the viewport.
*
* @public
* @example
*```tsx
*import { ReactFlow, Controls } from '@xyflow/react'
*
*export default function Flow() {
* return (
* <ReactFlow nodes={[...]} edges={[...]}>
* <Controls />
* </ReactFlow>
* )
*}
*```
*
* @remarks To extend or customise the controls, you can use the [`<ControlButton />`](/api-reference/components/control-button)
*component
*
*/
export const Controls = memo(ControlsComponent);
@@ -178,4 +178,24 @@ function MiniMapComponent<NodeType extends Node = Node>({
MiniMapComponent.displayName = 'MiniMap';
/**
* The `<MiniMap />` component can be used to render an overview of your flow. It
*renders each node as an SVG element and visualizes where the current viewport is
*in relation to the rest of the flow.
*
* @public
* @example
*
* ```jsx
*import { ReactFlow, MiniMap } from '@xyflow/react';
*
*export default function Flow() {
* return (
* <ReactFlow nodes={[...]]} edges={[...]]}>
* <MiniMap nodeStrokeWidth={3} />
* </ReactFlow>
* );
*}
*```
*/
export const MiniMap = memo(MiniMapComponent) as typeof MiniMapComponent;
@@ -203,4 +203,9 @@ export function ResizeControlLine(props: ResizeControlLineProps) {
return <ResizeControl {...props} variant={ResizeControlVariant.Line} />;
}
/**
* To create your own resizing UI, you can use the `NodeResizeControl` component where you can pass children (such as icons).
* @public
*
*/
export const NodeResizeControl = memo(ResizeControl);
@@ -3,6 +3,30 @@ import { ResizeControlVariant, XY_RESIZER_HANDLE_POSITIONS, XY_RESIZER_LINE_POSI
import { NodeResizeControl } from './NodeResizeControl';
import type { NodeResizerProps } from './types';
/**
* The `<NodeResizer />` component can be used to add a resize functionality to your
*nodes. It renders draggable controls around the node to resize in all directions.
* @public
*
* @example
*```jsx
*import { memo } from 'react';
*import { Handle, Position, NodeResizer } from '@xyflow/react';
*
*function ResizableNode({ data }) {
* return (
* <>
* <NodeResizer minWidth={100} minHeight={30} />
* <Handle type="target" position={Position.Left} />
* <div style={{ padding: 10 }}>{data.label}</div>
* <Handle type="source" position={Position.Right} />
* </>
* );
*};
*
*export default memo(ResizableNode);
*```
*/
export function NodeResizer({
nodeId,
isVisible = true,
@@ -38,6 +38,42 @@ const storeSelector = (state: ReactFlowState) => ({
selectedNodesCount: state.nodes.filter((node) => node.selected).length,
});
/**
* This component can render a toolbar or tooltip to one side of a custom node. This
*toolbar doesn't scale with the viewport so that the content is always visible.
*
* @public
* @example
* ```jsx
*import { memo } from 'react';
*import { Handle, Position, NodeToolbar } from '@xyflow/react';
*
*function CustomNode({ data }) {
* return (
* <>
* <NodeToolbar isVisible={data.toolbarVisible} position={data.toolbarPosition}>
* <button>delete</button>
* <button>copy</button>
* <button>expand</button>
* </NodeToolbar>
*
* <div style={{ padding: '10px 20px' }}>
* {data.label}
* </div>
*
* <Handle type="target" position={Position.Left} />
* <Handle type="source" position={Position.Right} />
* </>
* );
*};
*
*export default memo(CustomNode);
*```
* @remarks By default, the toolbar is only visible when a node is selected. If multiple
*nodes are selected it will not be visible to prevent overlapping toolbars or
*clutter. You can override this behavior by setting the `isVisible` prop to
*`true`.
*/
export function NodeToolbar({
nodeId,
children,
@@ -6,6 +6,47 @@ import type { ReactFlowState } from '../../types';
const selector = (s: ReactFlowState) => s.domNode?.querySelector('.react-flow__edgelabel-renderer');
/**
* Edges are SVG-based. If you want to render more complex labels you can use the
*`<EdgeLabelRenderer />` component to access a div based renderer. This component
*is a portal that renders the label in a `<div />` that is positioned on top of
*the edges. You can see an example usage of the component in the [edge label renderer](/examples/edges/edge-label-renderer)
*example.
* @public
*
* @example
*```jsx
*import React from 'react';
*import { getBezierPath, EdgeLabelRenderer, BaseEdge } from '@xyflow/react';
*
*export function CustomEdge({ id, data, ...props }) {
* const [edgePath, labelX, labelY] = getBezierPath(props);
*
* return (
* <>
* <BaseEdge id={id} path={edgePath} />
* <EdgeLabelRenderer>
* <div
* style={{
* position: 'absolute',
* transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
* background: '#ffcc00',
* padding: 10,
* }}
* className="nodrag nopan"
* >
* {data.label}
* </div>
* </EdgeLabelRenderer>
* </>
* );
*};
*```
*
*@remarks The `<EdgeLabelRenderer />` has no pointer events by default. If you want to
*add mouse interactions you need to set the style `pointerEvents: all` and add
*the `nopan` class on the label or the element you want to interact with.
*/
export function EdgeLabelRenderer({ children }: { children: ReactNode }) {
const edgeLabelRenderer = useStore(selector);
@@ -4,6 +4,33 @@ import cc from 'classcat';
import { EdgeText } from './EdgeText';
import type { BaseEdgeProps } from '../../types';
/**
* The `<BaseEdge />` component gets used internally for all the edges. It can be
*used inside a custom edge and handles the invisible helper edge and the edge label
*for you.
*
* @public
* @example
* ```jsx
*import { BaseEdge } from '@xyflow/react';
*
*export function CustomEdge({ sourceX, sourceY, targetX, targetY, ...props }) {
* const [edgePath] = getStraightPath({
* sourceX,
* sourceY,
* targetX,
* targetY,
* });
*
* return <BaseEdge path={edgePath} {...props} />;
*}
*```
*
* @remarks If you want to use an edge marker with the [`<BaseEdge />`](/api-reference/components/base-edge) component,
*you can pass the `markerStart` or `markerEnd` props passed to your custom edge
*through to the [`<BaseEdge />`](/api-reference/components/base-edge) component. You can see all the props
*passed to a custom edge by looking at the [`EdgeProps`](/api-reference/types/edge-props) type.
*/
export function BaseEdge({
path,
labelX,
@@ -73,4 +73,30 @@ function EdgeTextComponent({
EdgeTextComponent.displayName = 'EdgeText';
/**
* You can use the `<EdgeText />` component as a helper component to display text
*within your custom edges.
*
*@public
*
*@example
*```jsx
*import { EdgeText } from '@xyflow/react';
*
*export function CustomEdgeLabel({ label }) {
* return (
* <EdgeText
* x={100}
* y={100}
* label={label}
* labelStyle={{ fill: 'white' }}
* labelShowBg
* labelBgStyle={{ fill: 'red' }}
* labelBgPadding={[2, 4]}
* labelBgBorderRadius={2}
* />
* );
*}
*```
*/
export const EdgeText = memo(EdgeTextComponent);
+23 -1
View File
@@ -250,6 +250,28 @@ function HandleComponent(
}
/**
* The Handle component is a UI element that is used to connect nodes.
* The `<Handle />` component is used in your [custom nodes](/learn/customization/custom-nodes)
*to define connection points.
*
*@public
*
*@example
*
*```jsx
*import { Handle, Position } from '@xyflow/react';
*
*export function CustomNode({ data }) {
* return (
* <>
* <div style={{ padding: '10px 20px' }}>
* {data.label}
* </div>
*
* <Handle type="target" position={Position.Left} />
* <Handle type="source" position={Position.Right} />
* </>
* );
*};
*```
*/
export const Handle = memo(fixedForwardRef(HandleComponent));
+27 -3
View File
@@ -5,10 +5,34 @@ import type { PanelPosition } from '@xyflow/system';
import { useStore } from '../../hooks/useStore';
import type { ReactFlowState } from '../../types';
/**
* The `<Panel />` component helps you position content above the viewport. It is
*used internally by the [`<MiniMap />`](/api-reference/components/minimap) and [`<Controls />`](/api-reference/components/controls)
*components.
*
* @public
*
* @example
* ```jsx
*import { ReactFlow, Background, Panel } from '@xyflow/react';
*
*export default function Flow() {
* return (
* <ReactFlow nodes={[]} fitView>
* <Panel position="top-left">top-left</Panel>
* <Panel position="top-center">top-center</Panel>
* <Panel position="top-right">top-right</Panel>
* <Panel position="bottom-left">bottom-left</Panel>
* <Panel position="bottom-center">bottom-center</Panel>
* <Panel position="bottom-right">bottom-right</Panel>
* </ReactFlow>
* );
*}
*```
*/
export type PanelProps = HTMLAttributes<HTMLDivElement> & {
/**
* Set position of the panel
* @example 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'
* The position of the panel
*/
position?: PanelPosition;
children: ReactNode;
@@ -34,4 +58,4 @@ export const Panel = forwardRef<HTMLDivElement, PanelProps>(
}
);
Panel.displayName = 'Panel'
Panel.displayName = 'Panel';
@@ -6,6 +6,30 @@ import type { ReactFlowState } from '../../types';
const selector = (s: ReactFlowState) => s.domNode?.querySelector('.react-flow__viewport-portal');
/**
* The `<ViewportPortal />` component can be used to add components to the same viewport of the flow where nodes and edges are rendered.
*This is useful when you want to render your own components that are adhere to the same coordinate system as the nodes & edges and are also
*affected by zooming and panning
* @public
* @example
*
* ```jsx
*import React from 'react';
*import { ViewportPortal } from '@xyflow/react';
*
*export default function () {
* return (
* <ViewportPortal>
* <div
* style={{ transform: 'translate(100px, 100px)', position: 'absolute' }}
* >
* This div is positioned at [100, 100] on the flow.
* </div>
* </ViewportPortal>
* );
*}
*```
*/
export function ViewportPortal({ children }: { children: ReactNode }) {
const viewPortalDiv = useStore(selector);