diff --git a/packages/ui-tests/cypress/fixtures/complexRouteMock.json b/packages/ui-tests/cypress/fixtures/complexRouteMock.json
new file mode 100644
index 000000000..ee22b9ea5
--- /dev/null
+++ b/packages/ui-tests/cypress/fixtures/complexRouteMock.json
@@ -0,0 +1,100 @@
+{
+ "route": {
+ "from": {
+ "uri": "webhook",
+ "parameters": {},
+ "steps": [
+ {
+ "to": {
+ "id": "to-2015",
+ "uri": "log",
+ "parameters": {}
+ }
+ },
+ {
+ "choice": {
+ "when": [
+ {
+ "when": {},
+ "steps": [
+ {
+ "to": {
+ "id": "to-1528",
+ "uri": "log",
+ "parameters": {}
+ }
+ }
+ ]
+ },
+ {
+ "id": "when-1938",
+ "simple": "${header.foo} == 1",
+ "steps": [
+ {
+ "log": {
+ "id": "log-2139",
+ "message": "${body}"
+ }
+ }
+ ]
+ }
+ ],
+ "otherwise": {
+ "id": "otherwise-3846",
+ "steps": [
+ {
+ "log": {
+ "id": "log-1723",
+ "message": "${body}"
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "to": {
+ "id": "to-2118",
+ "uri": "aws2-s3",
+ "parameters": {}
+ }
+ },
+ {
+ "doTry": {
+ "id": "doTry-1388",
+ "doCatch": [
+ {
+ "doCatch": {}
+ },
+ {
+ "id": "doCatch-2642",
+ "steps": []
+ }
+ ],
+ "doFinally": {
+ "id": "doFinally-6670",
+ "steps": []
+ },
+ "steps": []
+ }
+ },
+ {
+ "to": {
+ "id": "to-2744",
+ "uri": "log",
+ "parameters": {}
+ }
+ },
+ {
+ "to": {
+ "id": "to-2300",
+ "uri": "kafka",
+ "parameters": {}
+ }
+ }
+ ],
+ "id": "from-5869"
+ },
+ "id": "route-8888"
+ }
+}
diff --git a/packages/ui-tests/stories/Canvas.stories.tsx b/packages/ui-tests/stories/Canvas.stories.tsx
new file mode 100644
index 000000000..6d794b4d1
--- /dev/null
+++ b/packages/ui-tests/stories/Canvas.stories.tsx
@@ -0,0 +1,95 @@
+import {
+ Canvas,
+ CamelRouteVisualEntity,
+ VisibleFlowsContext,
+ VisibleFLowsContextResult,
+ pipeJson,
+ CatalogTilesProvider,
+ CatalogLoaderProvider,
+ PipeVisualEntity,
+ EntitiesProvider,
+ SchemasLoaderProvider,
+ SourceCodeProvider,
+} from '@kaoto-next/ui/testing';
+import { Meta, StoryFn } from '@storybook/react';
+import complexRouteMock from '../cypress/fixtures/complexRouteMock.json';
+
+const emptyPipeJson = {
+ apiVersion: 'camel.apache.org/v1',
+ kind: 'Pipe',
+ metadata: {
+ name: 'new-pipe-template',
+ },
+ spec: {
+ source: {},
+ sink: {},
+ },
+};
+
+const emptyCamelRouteJson = {
+ route: {
+ id: 'route-8888',
+ from: {
+ uri: '',
+ steps: [],
+ },
+ },
+};
+
+const camelRouteEntity = new CamelRouteVisualEntity(complexRouteMock.route);
+const emptyCamelRouteEntity = new CamelRouteVisualEntity(emptyCamelRouteJson.route);
+const pipeEntity = new PipeVisualEntity(pipeJson.spec!);
+const emptyPipeEntity = new PipeVisualEntity(emptyPipeJson.spec!);
+
+const ContextDecorator = (Story: StoryFn) => (
+
+
+
+
+
+
+
+
+
+
+
+);
+
+export default {
+ title: 'Canvas/Canvas',
+ component: Canvas,
+ decorators: [ContextDecorator],
+} as Meta;
+
+const Template: StoryFn = (args) => {
+ const visibleId = args.entities[0].getId();
+ const firstVisibleEntity: unknown = { visibleFlows: { [visibleId]: true } };
+
+ return (
+
+
+
+
+
+ );
+};
+
+export const CamelRouteVisualization = Template.bind({});
+CamelRouteVisualization.args = {
+ entities: [camelRouteEntity],
+};
+
+export const PipeVisualization = Template.bind({});
+PipeVisualization.args = {
+ entities: [pipeEntity],
+};
+
+export const EmptyPipeVisualization = Template.bind({});
+EmptyPipeVisualization.args = {
+ entities: [emptyPipeEntity],
+};
+
+export const EmptyCamelRouteVisualization = Template.bind({});
+EmptyCamelRouteVisualization.args = {
+ entities: [emptyCamelRouteEntity],
+};
diff --git a/packages/ui/src/models/index.ts b/packages/ui/src/models/index.ts
index b03fccdd0..e0f907d0f 100644
--- a/packages/ui/src/models/index.ts
+++ b/packages/ui/src/models/index.ts
@@ -10,3 +10,4 @@ export * from './local-storage-keys';
export * from './react-component';
export * from './schema';
export * from './validation';
+export * from './visualization';
diff --git a/packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts b/packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts
index a9172a532..4b77a32dc 100644
--- a/packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts
+++ b/packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts
@@ -3,7 +3,7 @@ import { JSONSchemaType } from 'ajv';
import cloneDeep from 'lodash/cloneDeep';
import { pipeJson } from '../../../stubs/pipe';
import { EntityType } from '../../camel/entities';
-import { PipeVisualEntity } from './pipe-visual-entity';
+import { PipeVisualEntity } from './';
import { KameletSchemaService } from './support/kamelet-schema.service';
describe('Pipe', () => {
diff --git a/packages/ui/src/models/visualization/index.ts b/packages/ui/src/models/visualization/index.ts
index 9fa94d449..04082605b 100644
--- a/packages/ui/src/models/visualization/index.ts
+++ b/packages/ui/src/models/visualization/index.ts
@@ -1 +1,2 @@
export * from './visualization-node';
+export * from './flows';
diff --git a/packages/ui/src/stubs/index.ts b/packages/ui/src/stubs/index.ts
new file mode 100644
index 000000000..7081b1e04
--- /dev/null
+++ b/packages/ui/src/stubs/index.ts
@@ -0,0 +1,3 @@
+export * from './camel-route';
+export * from './kamelet-binding-route';
+export * from './pipe';
diff --git a/packages/ui/src/testing-api.ts b/packages/ui/src/testing-api.ts
index be1e15e8b..76925a5cf 100644
--- a/packages/ui/src/testing-api.ts
+++ b/packages/ui/src/testing-api.ts
@@ -3,6 +3,7 @@ export * from './layout';
export * from './models/visualization';
export * from './providers';
export * from './utils';
+export * from './stubs';
/** Re-export public components */
export * from './public-api';