Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/rules/components-rules.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Canvas components are located in packages/graph/src/components/canvas/ and divid
- **Note:** These Canvas components manage rendering directly onto a `<canvas>` element. They are distinct from React components (even those used *within* the HTML layer at high zoom levels, like `GraphBlock`), although they share some lifecycle concepts managed by the core library. Rules specific to Canvas component rendering might not apply directly to React components used for the HTML layer.

# React Integration
For integration of Canvas components with React, wrappers are used in the packages/graph/src/react-components/ directory. These components allow the use of Canvas in React applications.
For integration of Canvas components with React, wrappers are used in the packages/graph-react/src/ directory. These components allow the use of Canvas in React applications.

# Rendering Layers
Canvas rendering is organized in layers with different priorities:
Expand Down
4 changes: 2 additions & 2 deletions .cursor/rules/event-model-rules.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ The system uses **`CustomEvent`**, and interaction follows a `.on`/`.off`/`.emit
- **Pros:** Automatically handles subscription/unsubscription; provides `detail` and `event` objects.
- **Cons:** Only usable within React function components.
```jsx
import { useGraph, useGraphEvent, GraphCanvas } from '@gravity-ui/graph';
import { useGraph, useGraphEvent, GraphCanvas } from '@gravity-ui/graph-react';

function MyReactComponent() {
const { graph } = useGraph(/* config */);
Expand All @@ -61,7 +61,7 @@ The system uses **`CustomEvent`**, and interaction follows a `.on`/`.off`/`.emit
- **Pros:** Declarative, simple for common cases.
- **Cons:** Limited to the specific events exposed as props.
```jsx
import { GraphCanvas } from '@gravity-ui/graph';
import { GraphCanvas } from '@gravity-ui/graph-react';

// ... assume graph instance is available

Expand Down
4 changes: 2 additions & 2 deletions .cursor/rules/layer-rules.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ this.html.style.transform = `matrix(${camera.scale}, 0, 0, ${camera.scale}, ${ca
## React Integration with useLayer
- **Using `useLayer` Hook:** The recommended way to add and manage layers in React components:
```typescript
import { useLayer } from "@gravity-ui/graph";
import { useLayer } from "@gravity-ui/graph-react";

function MyComponent() {
const { graph } = useGraph(/* config */);
Expand Down Expand Up @@ -219,4 +219,4 @@ protected afterInit() {
}
```

When the layer is unmounted, all handlers are automatically removed.
When the layer is unmounted, all handlers are automatically removed.
8 changes: 4 additions & 4 deletions .cursor/rules/project-rules.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ Project structure:
- Connection Store State: `packages/graph/src/store/connection/ConnectionState.ts` (Exports `ConnectionState`, `TConnection`)
- Base connection component: `packages/graph/src/components/canvas/connections/BaseConnection.ts` (Exports `BaseConnection`)
- **React Integration:**
- `GraphCanvas` component: `packages/graph/src/react-components/GraphCanvas.tsx`
- `useGraph` hook: `packages/graph/src/react-components/hooks/useGraph.ts`
- `GraphBlock` component: `packages/graph/src/react-components/Block.tsx`
- `GraphCanvas` component: `packages/graph-react/src/GraphCanvas.tsx`
- `useGraph` hook: `packages/graph-react/src/hooks/useGraph.ts`
- `GraphBlock` component: `packages/graph-react/src/Block.tsx`

## Technologies
Technology stack:
Expand All @@ -52,7 +52,7 @@ Technology stack:
## Key Components
Key components:
- Graph - main class for graph management (packages/graph/src/graph.ts)
- GraphCanvas - React component for displaying the graph (packages/graph/src/react-components/GraphCanvas.tsx)
- GraphCanvas - React component for displaying the graph (packages/graph-react/src/GraphCanvas.tsx)
- Block - component for representing a graph block
- Connection - component for connections between blocks
- Anchor - components for connection attachment points
Expand Down
4 changes: 2 additions & 2 deletions .cursor/rules/story-rules.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ alwaysApply: false
- Always use `GraphBlock` for rendering graph blocks in the HTML layer unless you have a specific custom renderer.

## Graph Initialization (Recommended Pattern)
- **Use `useGraph` hook:** Initialize the graph instance within your story component using the public `@gravity-ui/graph/react` entrypoint.
- **Use `useGraph` hook:** Initialize the graph instance within your story component using the public `@gravity-ui/graph-react` entrypoint.
```typescript
import { Graph, GraphState } from "@gravity-ui/graph";
import { GraphCanvas, useGraph } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph } from "@gravity-ui/graph-react";

const MyStoryComponent = (props) => {
const { graph } = useGraph({
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
name: playwright-report
path: |
apps/e2e/playwright-report/
packages/graph/playwright-report/
playwright-report/
retention-days: 7

- name: Upload test screenshots
Expand All @@ -59,5 +59,5 @@ jobs:
name: test-results
path: |
apps/e2e/test-results/
packages/graph/test-results/
test-results/
retention-days: 7
3 changes: 2 additions & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"packages/graph": "1.11.3",
"packages/scheduler": "0.0.0"
"packages/scheduler": "0.0.0",
"packages/graph-react": "0.0.0"
}
16 changes: 8 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ The library uses a **hybrid Canvas + React architecture**:

**Key Files**:
- `packages/graph/src/components/canvas/layers/graphLayer/GraphLayer.ts` - Main Canvas rendering
- `packages/graph/src/react-components/layer/ReactLayer.tsx` - React Portal integration
- `packages/graph/src/react-components/GraphCanvas.tsx` - React wrapper component
- `packages/graph-react/src/layer/ReactLayer.tsx` - React Portal integration
- `packages/graph-react/src/GraphCanvas.tsx` - React wrapper component

### Custom Component Framework

Expand Down Expand Up @@ -213,7 +213,7 @@ protected afterInit() {

**In React**:
```typescript
import { useGraphEvent } from '@gravity-ui/graph';
import { useGraphEvent } from '@gravity-ui/graph-react';

function MyComponent() {
const { graph } = useGraph(config);
Expand Down Expand Up @@ -251,7 +251,7 @@ graph.rootStore.settings.setBlockComponents(customBlocks);

### Adding Layers in React
```typescript
import { useLayer } from '@gravity-ui/graph';
import { useLayer } from '@gravity-ui/graph-react';

function MyComponent() {
const { graph } = useGraph(config);
Expand Down Expand Up @@ -952,7 +952,7 @@ private handleBlockSelect = (event: CustomEvent): void => {
Use `useGraphEvent` hook - automatic cleanup.

```typescript
import { useGraphEvent } from "@gravity-ui/graph";
import { useGraphEvent } from "@gravity-ui/graph-react";

function MyComponent() {
const { graph } = useGraph(config);
Expand Down Expand Up @@ -1008,7 +1008,7 @@ useGraphEvent(graph, "block:click", (detail, event) => {

**GraphCanvas - Main Container:**
```tsx
import { GraphCanvas, useGraph } from "@gravity-ui/graph";
import { GraphCanvas, useGraph } from "@gravity-ui/graph-react";

function App() {
const { graph } = useGraph({
Expand Down Expand Up @@ -1075,7 +1075,7 @@ const layer = useLayer(graph, LayerConstructor, props);

**Example:**
```typescript
import { useLayer } from "@gravity-ui/graph";
import { useLayer } from "@gravity-ui/graph-react";

function MyComponent() {
const { graph } = useGraph(config);
Expand Down Expand Up @@ -1177,7 +1177,7 @@ const config: TGraphConfig = {

**Use `useGraph` hook (Recommended):**
```typescript
import { useGraph, GraphCanvas, GraphBlock } from "@gravity-ui/graph";
import { useGraph, GraphCanvas, GraphBlock } from "@gravity-ui/graph-react";
import { useEffect } from "react";

export const MyStory = () => {
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ This repository contains the Gravity UI Graph packages and their development too

## Packages

- [`@gravity-ui/graph`](packages/graph) — the graph editor library, React integration, public Playwright page objects,
documentation, and unit and package-contract tests.
- [`@gravity-ui/graph`](packages/graph) — the framework-independent graph editor, layouts, plugins, and public Playwright page objects.
- [`@gravity-ui/graph-react`](packages/graph-react) — React components, hooks, and their styles, depending on the core public API.
- [`@gravity-ui/graph-scheduler`](packages/scheduler) — private scheduling implementation inlined into the core build.

Shared build tooling lives in `scripts/`; `tests/package-contract` installs the two public tarballs into isolated vanilla and React projects.

## Applications

Expand Down
2 changes: 1 addition & 1 deletion apps/e2e/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Graph } from "@gravity-ui/graph";

type GraphModule = typeof import("@gravity-ui/graph") &
Pick<typeof import("@gravity-ui/graph/react"), "GraphBlock" | "GraphBlockAnchor" | "GraphCanvas"> & {
Pick<typeof import("@gravity-ui/graph-react"), "GraphBlock" | "GraphBlockAnchor" | "GraphCanvas"> & {
React: typeof import("react");
ReactDOM: typeof import("react-dom/client");
};
Expand Down
5 changes: 3 additions & 2 deletions apps/e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
"typecheck": "tsc -p tsconfig.json",
"e2e:bundle": "node build-bundle.js",
"e2e:serve": "node server.js",
"e2e:build": "pnpm --filter @gravity-ui/graph run build && pnpm run e2e:bundle",
"e2e:build": "pnpm --filter @gravity-ui/graph --filter @gravity-ui/graph-react run build && pnpm run e2e:bundle",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:debug": "playwright test --debug",
"test:e2e:ci": "playwright test",
"e2e:dev": "pnpm run e2e:build && concurrently \"pnpm --filter @gravity-ui/graph run dev\" \"pnpm run e2e:serve\""
"e2e:dev": "pnpm run e2e:build && concurrently \"pnpm -w run dev\" \"pnpm run e2e:serve\""
},
"dependencies": {
"@gravity-ui/graph": "workspace:*",
"@gravity-ui/graph-react": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
3 changes: 2 additions & 1 deletion apps/e2e/react-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import React from "react";
import ReactDOM from "react-dom/client";

import "@gravity-ui/graph/styles.css";
import "@gravity-ui/graph-react/styles.css";

export * from "@gravity-ui/graph";
export { GraphBlock, GraphBlockAnchor, GraphCanvas } from "@gravity-ui/graph/react";
export { GraphBlock, GraphBlockAnchor, GraphCanvas } from "@gravity-ui/graph-react";
export { React, ReactDOM };
3 changes: 2 additions & 1 deletion apps/e2e/tests/anchor/anchor-css-variables.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { expect, test } from "@playwright/test";

test.describe("Anchor CSS variables", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/base.html");
// Anchor DOM styles belong to the React package and are loaded by the React fixture.
await page.goto("/react.html");
await page.waitForFunction(() => (window as Window & { graphLibraryLoaded?: boolean }).graphLibraryLoaded === true);
});

Expand Down
1 change: 1 addition & 0 deletions apps/storybook/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { Preview } from "@storybook/react-webpack5";

import "./styles/global.css";
import "@gravity-ui/graph/styles.css";
import "@gravity-ui/graph-react/styles.css";
import "@gravity-ui/uikit/styles/styles.css";

const preview: Preview = {
Expand Down
5 changes: 3 additions & 2 deletions apps/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
"version": "0.0.0",
"private": true,
"scripts": {
"storybook": "concurrently \"pnpm --filter @gravity-ui/graph run dev\" \"storybook dev -p 6006\"",
"storybook": "concurrently \"pnpm -w run dev\" \"storybook dev -p 6006\"",
"build-storybook": "storybook build",
"build": "pnpm run build-storybook",
"typecheck": "tsc -p tsconfig.json --noEmit",
"lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\" \".storybook/**/*.{js,jsx,ts,tsx}\""
},
"dependencies": {
"@gravity-ui/graph": "workspace:*",
"@gravity-ui/graph-react": "workspace:*",
"@gravity-ui/icons": "^2.15.0",
"@gravity-ui/uikit": "^7.19.0",
"@monaco-editor/react": "^4.6.0",
Expand All @@ -29,8 +30,8 @@
"@storybook/react": "^9.1.2",
"@storybook/react-webpack5": "^9.1.2",
"@swc/core": "^1.13.3",
"@types/node": "^20.17.0",
"@types/lodash": "^4.17.13",
"@types/node": "^20.17.0",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@typescript-eslint/eslint-plugin": "5.39.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";

import { Graph } from "@gravity-ui/graph";
import { GraphBlock, GraphBlockAnchor } from "@gravity-ui/graph/react";
import { GraphBlock, GraphBlockAnchor } from "@gravity-ui/graph-react";
import { Database } from "@gravity-ui/icons";
import { Button, Flex, Icon, Text } from "@gravity-ui/uikit";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";

import { ConnectionLayer, ECanDrag, Graph, GraphState, TBlock, TGraphConfig } from "@gravity-ui/graph";
import { GraphBlock, GraphCanvas, HookGraphParams, useGraph, useGraphEvent, useLayer } from "@gravity-ui/graph/react";
import { GraphBlock, GraphCanvas, HookGraphParams, useGraph, useGraphEvent, useLayer } from "@gravity-ui/graph-react";
import {
Flex,
SegmentedRadioGroup,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";

import { Graph } from "@gravity-ui/graph";
import { GraphBlock } from "@gravity-ui/graph/react";
import { GraphBlock } from "@gravity-ui/graph-react";
import { CircleInfo } from "@gravity-ui/icons";
import { Flex, Icon, Text } from "@gravity-ui/uikit";

Expand Down
2 changes: 1 addition & 1 deletion apps/storybook/src/stories/Playground/Toolbox.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";

import { Graph } from "@gravity-ui/graph";
import { useSignal } from "@gravity-ui/graph/react";
import { useSignal } from "@gravity-ui/graph-react";
import { MagnifierMinus, MagnifierPlus, SquareDashed } from "@gravity-ui/icons";
import { Button, Flex, Icon, Tooltip } from "@gravity-ui/uikit";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useLayoutEffect, useState } from "react";

import { ESelectionStrategy, Graph, GraphState, TBlock, TConnection, TGraphConfig } from "@gravity-ui/graph";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph-react";
import { ThemeProvider } from "@gravity-ui/uikit";
import type { Meta, StoryFn } from "@storybook/react-webpack5";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useMemo, useState } from "react";

import { Graph, GraphState, TBlock } from "@gravity-ui/graph";
import { GraphCanvas, useGraph } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph } from "@gravity-ui/graph-react";
import { Button, Flex, ThemeProvider } from "@gravity-ui/uikit";
import type { Meta, StoryFn } from "@storybook/react-webpack5";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect } from "react";

import { BlockGroups, CollapsibleGroup, ECanDrag, Graph, GraphState, TBlock, TConnection } from "@gravity-ui/graph";
import type { BlockGroupsProps, BlockState, TCollapsibleGroup } from "@gravity-ui/graph";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph-react";
import type { Meta, StoryFn } from "@storybook/react-webpack5";

import { useFn } from "../../../useFn";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";

import { BlockGroups, BlockState, ECanDrag, Graph, GraphState, Group, TBlock } from "@gravity-ui/graph";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph-react";
import type { Meta, StoryFn } from "@storybook/react-webpack5";
import groupBy from "lodash/groupBy";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";

import { BlockGroups, Graph, GraphState, Group, TBlock, TGroup } from "@gravity-ui/graph";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph-react";
import type { Meta, StoryFn } from "@storybook/react-webpack5";

import { useFn } from "../../../useFn";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";

import { BlockGroups, BlockState, Graph, GraphState, Group, TBlock } from "@gravity-ui/graph";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph-react";
import type { Meta, StoryFn } from "@storybook/react-webpack5";
import groupBy from "lodash/groupBy";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";

import { BlockGroups, Graph, GraphState, Group, TBlock } from "@gravity-ui/graph";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph, useGraphEvent } from "@gravity-ui/graph-react";
import type { Meta, StoryFn } from "@storybook/react-webpack5";

import { useFn } from "../../../useFn";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
TBlock,
TDefinitionGroup,
} from "@gravity-ui/graph";
import { GraphCanvas, useGraph, useGraphEvent, useLayer } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph, useGraphEvent, useLayer } from "@gravity-ui/graph-react";
import type { Meta, StoryFn } from "@storybook/react-webpack5";

import { useFn } from "../../../useFn";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";

import { ConnectionLayer, Graph, TBlock } from "@gravity-ui/graph";
import { GraphCanvas, useGraph } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph } from "@gravity-ui/graph-react";
import { Flex, Hotkey, Switch, Text, ThemeProvider } from "@gravity-ui/uikit";
import type { Meta, StoryFn } from "@storybook/react-webpack5";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
getFontSize,
getLabelCoords,
} from "@gravity-ui/graph";
import { GraphCanvas, useGraph } from "@gravity-ui/graph/react";
import { GraphCanvas, useGraph } from "@gravity-ui/graph-react";
import { Flex, Switch, ThemeProvider } from "@gravity-ui/uikit";
import type { Meta, StoryFn } from "@storybook/react-webpack5";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useLayoutEffect, useMemo, useState } from "react";

import type { TMouseWheelBehavior, TWheelInputDevice } from "@gravity-ui/graph";
import { ECanDrag, EWheelIntent, Graph, GraphState, TBlock, enableWheelIntentDebug } from "@gravity-ui/graph";
import { GraphBlock, GraphCanvas, HookGraphParams, useGraph, useGraphEvent } from "@gravity-ui/graph/react";
import { GraphBlock, GraphCanvas, HookGraphParams, useGraph, useGraphEvent } from "@gravity-ui/graph-react";
import { Flex, Text, ThemeProvider } from "@gravity-ui/uikit";
import type { Meta, StoryObj } from "@storybook/react-webpack5";

Expand Down
Loading
Loading