### Verify Project Setup with PNPM Commands
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
After copying files, execute 'pnpm install' to resolve and install all project dependencies, followed by 'pnpm dev' to start the local development server and confirm that the project functions correctly.
```Shell
pnpm install
pnpm dev
```
--------------------------------
### Set up Local Development for Axiom and Workflow Builder
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/axiom.md
This guide outlines the steps to set up a local development environment for both the Axiom UI library and the Workflow Builder project. It involves cloning repositories, building Axiom, and linking it to Workflow Builder's frontend for live updates. Ensure you do not commit the linking changes.
```Shell
# 1. Ensure the Axiom repository is cloned next to the Workflow Builder repository.
# 2. Build the distribution files in the Axiom tokens package:
pnpm token prepare
# 3. Build the distribution files in the Axiom repository and keep the process running for live updates:
pnpm ui dev
# 4. Update the Axiom dependency in apps/frontend/package.json to a local link:
# Locate the line with "@synergycodes/axiom" and change it to:
# "@synergycodes/axiom": "link:../../../axiom/packages/ui"
# 5. In apps/frontend/src/global.css, replace the Axiom tokens import path:
# Replace: @import '@synergycodes/axiom/tokens.css';
# With: @import '../../../../axiom/packages/ui/dist/tokens.css';
# 6. If issues persist, refresh dependencies:
pnpm install
```
--------------------------------
### Add Repository to Bitbucket for Workflow Builder Project
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
This step directs users to an external guide for adding a new repository to Bitbucket, ensuring proper infrastructure setup. It also notes that database-related files can be removed if not required by the implementation.
```Text
Follow the steps from this instruction:
https://synergiapro.atlassian.net/wiki/spaces/ENG/pages/3516760077/Dodawanie+projektu+-+repozytorium+infrastructure
If your implementation doesn't require a database, you can delete the related files (check closed PRs to see how others are handling it).
```
--------------------------------
### Deployment Setup (To Be Updated)
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
This section is a placeholder that will be updated with detailed deployment instructions once current deployment issues are fully resolved and a stable process is established.
```Text
`TODO:` This section should be updated after the deployment issues are resolved.
```
--------------------------------
### Install Workflow Builder Project Dependencies with pnpm
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/README.md
This command installs all necessary project dependencies from the root directory using pnpm. It ensures all packages defined in the monorepo are correctly linked and installed, preparing the project for development.
```Shell
pnpm i
```
--------------------------------
### Commit and Push Initial Project Setup
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
Commit all changes with a clear and descriptive message, then push the branch to the remote repository. A well-articulated commit message is crucial for future reference and project history.
```Text
Name your commit clearly (the message will remain visible for many files that may never change), and push it. :)
```
--------------------------------
### Create npm Package.json for Web Component Distribution
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/web-component-wrapper.decision-log.md
This snippet provides an example package.json file to be placed inside the dist/package folder after building the project. It defines the package's metadata, entry points for ES and UMD modules, peer dependencies (React, React DOM), and the files to be included in the npm package, enabling its distribution and consumption.
```json
{
"name": "workflow-builder",
"version": "1.0.0",
"description": "Workflow Builder app",
"main": "workflow-builder.umd.js",
"module": "workflow-builder.es.js",
"style": "frontend.css",
"author": "SynergyCodes",
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"dependencies": {},
"files": [
"workflow-builder.umd.js",
"workflow-builder.es.js",
"frontend.css"
]
}
```
--------------------------------
### Generate Icons via pnpm Install Command
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/icons/README.md
After updating icon sources, execute `pnpm i` in your terminal to trigger the icon generation process. This command activates the `@workflow-builder/icons` package's `prepare` script, which runs the `generate-icons` script to create or update `icons.gen.ts` and associated icon chunks.
```shell
pnpm i
```
--------------------------------
### Start Workflow Builder Application in Development Mode
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/README.md
This command starts the Workflow Builder application in development mode. It typically launches the frontend and any other necessary services, allowing developers to work on the application locally.
```Shell
pnpm dev
```
--------------------------------
### Example Translation JSON File (English)
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/i18n/i18next.decision-log.md
This is an example of a JSON file used by i18next to store English translations. It demonstrates a simple key-value structure for different UI texts.
```JSON
{
"welcomeMessage": "Welcome to Workflow Builder!",
"description": "This application helps you build and manage workflows.",
"greeting": "Hello, {{name}}!"
}
```
--------------------------------
### JSON Schema Conditional Validation Example with if/then/else
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-validation.decision-log.md
This JSON Schema example demonstrates how to implement conditional validation using if/else/then constructs. It ensures that specific fields are required and validated only when certain conditions are met within the data itself, completely independent of whether those fields are visible or enabled in the UI. This approach aligns with the principle of separating validation concerns from UI rendering logic.
```JSON Schema
{
"type": "object",
"properties": {
"paymentMethod": {
"type": "string",
"enum": ["creditCard", "paypal"]
},
"cardNumber": {
"type": "string"
},
"paypalEmail": {
"type": "string",
"format": "email"
}
},
"if": {
"properties": {
"paymentMethod": { "const": "creditCard" }
}
},
"then": {
"required": ["cardNumber"],
"properties": {
"cardNumber": {
"pattern": "^[0-9]{16}$",
"description": "Credit card number (16 digits)"
}
}
},
"else": {
"if": {
"properties": {
"paymentMethod": { "const": "paypal" }
}
},
"then": {
"required": ["paypalEmail"],
"properties": {
"paypalEmail": {
"description": "PayPal email address"
}
}
}
}
}
```
--------------------------------
### Use i18next with React Hooks for Translations
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/i18n/i18next.decision-log.md
This example shows how to use the 'useTranslation' hook from 'react-i18next' within a React functional component to access translated strings and change the application language dynamically.
```JavaScript
import React from 'react';
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t, i18n } = useTranslation();
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
};
return (
{t('welcomeMessage')}
{t('description')}
);
}
export default MyComponent;
```
--------------------------------
### Copy Workflow Builder Content to New Repository
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
Open the existing WorkflowBuilder project, fetch its latest 'master' branch, and then copy all contents of its directory into the newly cloned repository for the new project.
```Text
Open WorkflowBuilder, fetch the latest master branch, and copy the contents of the WorkflowBuilder directory to the new repository.
```
--------------------------------
### Update Pipeline References for New Repository
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
Navigate to the 'tools' directory and replace all occurrences of 'generic-workflow-editor' with the specific name of your new repository. This ensures that pipeline processes correctly reference the new project.
```Text
Find all `generic-workflow-editor` in the `tools` directory and replace them with the name of your repository.
```
--------------------------------
### Configure Development Branches for New Repository
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
Before pushing, create a 'master' branch to be set as the main branch and establish a development branch, mirroring the branching strategy used in the WorkflowBuilder repository.
```Text
Create a new branch `master`, which will be set as the main branch, and set up a development branch, similar to the WorkflowBuilder repository. Don't push it yet.
```
--------------------------------
### Configure Vite for Web Component Library Mode
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/web-component-wrapper.decision-log.md
This snippet shows how to adjust the vite.config.mts file to configure Vite for library mode. This configuration is crucial for bundling the Web Component as an npm package, specifying the entry point, output name, file formats (es, umd), and output directory for distribution.
```typescript
export default defineConfig(({ mode }) => ({
//...
build: {
lib: {
entry: path.resolve(__dirname, './src/main.tsx'),
name: 'WorkflowBuilder',
fileName: (format) => `workflow-builder.${format}.js`,
formats: ['es', 'umd'],
},
outDir: 'dist/package',
},
define: {
'process.env.NODE_ENV': JSON.stringify(
process.env.NODE_ENV || 'development',
),
},
//...
}));
```
--------------------------------
### Grant Developer Access to New Project
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
Contact the infrastructure team or responsible personnel to request and ensure that all other developers working on the project are granted the necessary access permissions to the new repository.
```Text
Ask the people responsible for infrastructure to grant access to other developers on your project.
```
--------------------------------
### Remove Default Workflow Builder Plugins
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
Locate the 'plugins' directory within the project, remove all existing plugins, and then restart the project. This process helps identify and remove any dependent imports that might cause build failures.
```Text
Find the `plugins` directory, remove all plugins, restart the project, and check what failed (probably two imports need to be removed, do that).
Check repository again.
```
--------------------------------
### Override Default Axiom Styles with Figma Tokens
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/docs/setup.md
If design provides Figma tokens, utilize the 'variables2css' plugin to generate custom CSS. This allows replacing the default '@synergycodes/axiom/tokens.css' import with a local './tokens.css' file, enabling project-specific styling and theme adjustments.
```CSS
If the design team gave you access to figma with tokens, override the default ones from Axiom.
Use `variables2css` plugin, after generating tokens you should be able to remove `@import '@synergycodes/axiom/tokens.css';` and add your `./tokens.css`.
You can check `[theme="Light"]` and convert `Light` -> `light` and `Dark` to `dark` if needed.
```
--------------------------------
### Implement Custom Control Component for JSONForm
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This snippet illustrates the implementation of a custom control component for JSONForms. It demonstrates using `` to handle shared control logic and rendering an `` component. This component will be rendered based on the UISchema definition for a 'Text' control.
```typescriptreact
const TextControl = (props: TextControlProps) => {
//...
return (
);
};
```
--------------------------------
### Configure New Icon Sources in generate-icons Script
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/icons/README.md
To expand the set of available icons, modify the `ICON_SOURCES` array in the `generate-icons` script. Add new objects specifying the `path` to directories containing SVG icon files. This allows the icon generation process to include assets from custom locations or external `node_modules` packages.
```typescript
const ICON_SOURCES: IconSource[] = [
//...
{
path: '../../../assets/icons/',
},
{
path: '../../node_modules/some-cool-icons/dist/svg'
}
];
```
--------------------------------
### Update index.html for Web Component Embedding
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/web-component-wrapper.decision-log.md
This snippet modifies the index.html file to replace the original div element with the newly defined workflow-builder custom element. This update enables framework-agnostic integration by allowing the host application to directly use the Web Component, decoupling the React app from a fixed DOM structure.
```html
```
```html
```
--------------------------------
### Implement Custom Layout Component for JSONForm
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This snippet illustrates the implementation of a custom layout component for JSONForms. It shows how to use `` for shared logic and `renderElements()` to display child components, creating a container like an Accordion to group related form elements visually.
```typescriptreact
const AccordionLayout = (props: LayoutProps) => {
const { uischema } = props;
return (
{renderElements(props)}
);
};
```
--------------------------------
### Use Custom Control in UISchema Definition
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This snippet demonstrates how to integrate a custom control into a UISchema definition. It shows how to map a data property (`description`) to the custom 'Text' control using the `scope` property, along with other UI configurations like `label` and `placeholder` within a layout.
```typescript
export const exampleNode: PaletteItem =
{
// ...
uischema: {
type: 'VerticalLayout',
elements: [
{
type: 'Accordion',
label: 'General information',
elements: [
// Usage of the new control
{
label: 'Description',
type: 'Text',
scope: '#/properties/description',
placeholder: 'Type your description here...',
},
],
},
},
};
```
--------------------------------
### Modify main.tsx for Web Component Integration
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/web-component-wrapper.decision-log.md
This snippet transforms the React application's entry point (main.tsx) from directly controlling a #root HTML element to encapsulating it within a custom Web Component. This change allows the Workflow Builder to be embedded anywhere without requiring specific DOM modifications in the host application. It defines a WorkflowBuilder custom element that mounts and unmounts the React app.
```typescript
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement,
);
root.render(
,
);
```
```typescript
class WorkflowBuilder extends HTMLElement {
private root: ReactDOM.Root | null = null;
connectedCallback() {
if (!this.root) {
const container = document.createElement('div');
this.appendChild(container);
this.root = ReactDOM.createRoot(container);
this.root.render(
,
);
}
}
disconnectedCallback() {
if (this.root) {
this.root.unmount();
this.root = null;
}
}
}
customElements.define('workflow-builder', WorkflowBuilder);
```
--------------------------------
### Commit Generated Icon Files to Version Control
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/icons/README.md
Following the icon generation, it is crucial to commit the newly created or modified `icons.gen.ts` file to your version control system. This ensures that the updated icon API and types are tracked and available for other developers and deployment environments.
```shell
git commit -m "feat: generate new icons"
```
--------------------------------
### Use React Icons from @workflow-builder/icons
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/icons/README.md
To integrate an icon into your React component, import the `Icon` component from `@workflow-builder/icons`. Pass the desired icon's `name` as a prop to render it. Additional props can be provided and their types extended directly within the icon's definition file for enhanced flexibility.
```typescriptreact
import { Icon } from "@workflow-builder/icons";
```
--------------------------------
### Configure i18next for React Applications
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/i18n/i18next.decision-log.md
This snippet demonstrates the basic configuration for i18next in a React application, integrating 'react-i18next' and 'i18next-browser-languagedetector'. It sets up translation file loading, language detection order, and caching in localStorage.
```JavaScript
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import enTranslation from './locales/en/translation.json';
import esTranslation from './locales/es/translation.json';
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: {
translation: enTranslation
},
es: {
translation: esTranslation
}
},
fallbackLng: 'en',
debug: true,
detection: {
order: ['querystring', 'cookie', 'localStorage', 'navigator'],
caches: ['localStorage']
},
interpolation: {
escapeValue: false // react already escapes by default
}
});
export default i18n;
```
--------------------------------
### JSONForms Rules for Dynamic UI Element Visibility
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This section refers to the official JSONForms documentation on rules. Rules are used to dynamically control the visibility and enabled/disabled state of form elements based on data conditions, providing dynamic UI behavior within the properties sidebar.
```APIDOC
Rules are used to dynamically toggle visibility of form elements and make them disabled or enabled. This part of JSONForms library is used as it is. Get to know more in the official documentation: https://jsonforms.io/docs/uischema/rules
```
--------------------------------
### JSONSchema Specification Reference for Node Data
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This section provides a reference to the official JSONSchema specification. JSONSchema is used to define the shape of node data, including property types, validation rules, and required fields, ensuring data integrity and consistency for the dynamic properties sidebar.
```APIDOC
JSONSchema is used to define the shape of node data, including property types, validation, and required fields. Refer to the official JSONSchema specification for detailed information: https://json-schema.org/
```
--------------------------------
### Define Node Data Schema with JSONSchema
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This snippet demonstrates how to define the structure and validation rules for node data using JSONSchema. It specifies property types, validation constraints like minimum/maximum for numbers, and required fields. The `PaletteItem['schema']` must include `title` and `subtitle` as default properties for all nodes.
```typescriptreact
export const exampleNode: PaletteItem = {
// ...
schema: {
properties: {
title: {
type: 'string',
},
subtitle: {
type: 'string',
},
age: {
type: 'number',
minimum: 1,
multipleOf: 1,
maximum: 100,
},
},
required: ['firstName', 'secondName'],
},
};
```
--------------------------------
### ReactFlow onSelectionChange Callback API Reference
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/properties-bar/selection.decison-log.md
Documents the `onSelectionChange` callback provided by ReactFlow, which is triggered upon selection changes. This API reference highlights its parameters, return type, and the known limitation regarding potentially outdated object references.
```APIDOC
{
"name": "onSelectionChange",
"type": "function",
"description": "Callback function triggered when the selection of nodes or edges changes in ReactFlow.",
"parameters": [
{
"name": "params",
"type": "object",
"description": "Object containing arrays of selected nodes and edges.",
"properties": [
{
"name": "nodes",
"type": "Node[]",
"description": "Array of currently selected Node objects. Note: These objects may be outdated if underlying node data has changed."
},
{
"name": "edges",
"type": "Edge[]",
"description": "Array of currently selected Edge objects. Note: These objects may be outdated if underlying edge data has changed."
}
]
}
],
"returns": {
"type": "void",
"description": "Does not return a value."
},
"notes": "Due to potential outdated references, it's recommended to store only IDs in an external state management system (e.g., Zustand) and retrieve full objects from the current ReactFlow state."
}
```
--------------------------------
### Define Custom Control Types for JSONForm UI Components
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This snippet shows how to define custom types for new UI controls within JSONForms. It includes the UISchema element type and the corresponding control props, extending base types like `ControlElement` and `InputProps` to specify control-specific properties such as `inputType` and `placeholder`.
```typescriptreact
export type TextControlElement = Override<
ControlElement,
{
type: 'Text';
inputType?: string;
} & Pick
>;
export type TextControlProps = ControlProps;
```
--------------------------------
### Define Custom Layout Types for JSONForm UI Containers
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This snippet demonstrates how to define custom types for new layout components within JSONForms. It extends `BaseLayoutElement` to specify layout-specific properties like `label` and the layout `type` ('Accordion'), enabling structured grouping of UI elements within the form.
```typescriptreact
export type AccordionLayoutElement = Override<
BaseLayoutElement,
{
label: string;
type: 'Accordion';
}
>;
```
--------------------------------
### useSingleSelectedElement React Hook API Reference
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/properties-bar/selection.decison-log.md
Documents the custom `useSingleSelectedElement` React hook. This API reference details its purpose, parameters, return type, and dependencies, emphasizing its role in providing up-to-date selected element data for UI components.
```APIDOC
{
"name": "useSingleSelectedElement",
"type": "ReactHook",
"description": "A custom React hook that computes and returns a single currently selected node or edge from the ReactFlow instance, ensuring the returned object is up-to-date with the latest graph data.",
"parameters": [],
"returns": {
"type": "Node | Edge | null",
"description": "Returns the currently selected Node or Edge object, or null if no single element is selected or found. Prioritizes a node if both a node and an edge are selected (configurable logic)."
},
"dependencies": [
"ReactFlow (for getNodes, getEdges)",
"Zustand (for selectedNodesIds, selectedEdgesIds)"
],
"notes": "This hook incorporates a custom comparison mechanism to optimize re-renders. It is primarily used for features like properties sidebars that display details of a single selected item."
}
```
--------------------------------
### Zustand Store for ReactFlow Selection IDs (TypeScript)
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/properties-bar/selection.decison-log.md
Defines the structure and update logic for a Zustand store to hold selected node and edge IDs, which are updated by ReactFlow's `onSelectionChange` callback. This ensures consistent and up-to-date selection data.
```TypeScript
import { create } from 'zustand';
import { Node, Edge } from 'reactflow';
interface SelectionStore {
selectedNodesIds: string[];
selectedEdgesIds: string[];
onSelectionChange: (nodes: Node[], edges: Edge[]) => void;
}
const useSelectionStore = create((set) => ({
selectedNodesIds: [],
selectedEdgesIds: [],
onSelectionChange: (nodes, edges) => {
set({
selectedNodesIds: nodes.map(node => node.id),
selectedEdgesIds: edges.map(edge => edge.id),
});
},
}));
```
--------------------------------
### Register Custom Control Renderer for JSONForms
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/json-form/form-generation.md
This snippet shows how to register a custom control component with the JSONForms library. It uses `createControlRenderer()` to associate a control type ('Text') with its corresponding React component, making it available for use in UISchema definitions. The renderer must be included in the main renderers array.
```typescriptreact
// ./controls/text-control.tsx
export const textControlRenderer = createControlRenderer('Text', TextControl);
// ./json-form.tsx
const renderers: JsonFormsRendererRegistryEntry[] = [
// ...,
textControlRenderer,
];
```
--------------------------------
### Dynamically Update HTML Lang Attribute for Accessibility
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/i18n/i18next.decision-log.md
This snippet illustrates how to listen for 'languageChanged' events from i18next to dynamically update the 'lang' attribute of the HTML document, improving accessibility for screen readers by indicating the correct document language.
```JavaScript
import { useEffect } from 'react';
import i18n from './i18n'; // Assuming i18n instance is exported from a setup file
function useDetectLanguageChange() {
useEffect(() => {
const updateHtmlLang = (lng) => {
document.documentElement.setAttribute('lang', lng);
};
// Set initial language
updateHtmlLang(i18n.language);
// Listen for language changes
i18n.on('languageChanged', updateHtmlLang);
// Cleanup listener on unmount
return () => {
i18n.off('languageChanged', updateHtmlLang);
};
}, []);
}
// Example usage in a root component or layout:
// function App() {
// useDetectLanguageChange();
// return (/* ... */);
// }
```
--------------------------------
### React Hook for Single Selected Element Retrieval (TypeScript)
Source: https://github.com/workflowbuildersdk/workflowbuilder/blob/main/apps/frontend/src/app/features/properties-bar/selection.decison-log.md
A custom React hook (`useSingleSelectedElement`) designed to retrieve a single, up-to-date selected node or edge from the current ReactFlow state. This hook addresses the issue of outdated references from ReactFlow's `onSelectionChange` by re-computing the element based on stored IDs and current graph data.
```TypeScript
import { useStore, useReactFlow, Node, Edge } from 'reactflow';
import { shallow } from 'zustand/shallow';
// Define the shape of your Zustand selection store (assuming it's defined elsewhere)
interface SelectionState {
selectedNodesIds: string[];
selectedEdgesIds: string[];
}
// Assume useSelectionStore is your Zustand store hook
// const useSelectionStore = create(...);
type SelectedElement = Node | Edge | null;
const useSingleSelectedElement = (): SelectedElement => {
const { getNodes, getEdges } = useReactFlow();
// Get the selected IDs from the Zustand store
const { selectedNodesIds, selectedEdgesIds } = useStore(
(state: SelectionState) => ({
selectedNodesIds: state.selectedNodesIds,
selectedEdgesIds: state.selectedEdgesIds,
}),
shallow // Use shallow comparison for the selector output
);
// Compute the actual selected element from current ReactFlow data
const selectedNode = selectedNodesIds.length > 0
? getNodes().find(node => node.id === selectedNodesIds[0])
: null;
const selectedEdge = selectedEdgesIds.length > 0
? getEdges().find(edge => edge.id === selectedEdgesIds[0])
: null;
// Return only one element, prioritizing node if both are selected (example logic)
return selectedNode || selectedEdge || null;
};
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.