From ea4dee882bc211b466ef1f511692fb6ee08804e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Wed, 28 May 2025 09:02:09 +0200 Subject: [PATCH 1/2] chore: initial commit From e867796be894c81dca6bbfbcef72b35bdcc19f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Wed, 28 May 2025 11:44:42 +0200 Subject: [PATCH 2/2] feat: eraser tool --- code/CHANGELOG.md | 41 +----- .../sdk/src/actions/eraser-tool/constants.ts | 10 ++ .../src/actions/eraser-tool/eraser-tool.ts | 121 ++++++++++++++++++ .../sdk/src/actions/eraser-tool/types.ts | 9 ++ .../sdk/src/actions/move-tool/move-tool.ts | 19 ++- code/packages/sdk/src/index.ts | 3 + code/packages/sdk/src/managers/targeting.ts | 51 +++++++- code/packages/sdk/src/nodes/image/image.ts | 6 + code/packages/sdk/src/utils.ts | 10 +- code/packages/sdk/src/weave.ts | 12 ++ .../docs/main/build/actions/brush-tool.mdx | 2 +- .../docs/main/build/actions/eraser-tool.mdx | 64 +++++++++ .../main/build/actions/export-node-tool.mdx | 2 +- .../main/build/actions/export-stage-tool.mdx | 2 +- .../main/build/actions/fit-to-screen-tool.mdx | 2 +- .../build/actions/fit-to-selection-tool.mdx | 2 +- .../docs/main/build/actions/frame-tool.mdx | 2 +- .../docs/main/build/actions/image-tool.mdx | 2 +- .../content/docs/main/build/actions/index.mdx | 7 + .../content/docs/main/build/actions/meta.json | 1 + .../docs/main/build/actions/move-tool.mdx | 2 +- .../docs/main/build/actions/pen-tool.mdx | 2 +- .../main/build/actions/rectangle-tool.mdx | 2 +- .../main/build/actions/selection-tool.mdx | 2 +- .../docs/main/build/actions/text-tool.mdx | 2 +- .../docs/main/build/actions/zoom-in-tool.mdx | 2 +- .../docs/main/build/actions/zoom-out-tool.mdx | 2 +- docs/content/docs/main/build/nodes/frame.mdx | 2 +- docs/content/docs/main/build/nodes/group.mdx | 2 +- docs/content/docs/main/build/nodes/image.mdx | 2 +- docs/content/docs/main/build/nodes/layer.mdx | 2 +- docs/content/docs/main/build/nodes/line.mdx | 2 +- .../docs/main/build/nodes/rectangle.mdx | 2 +- docs/content/docs/main/build/nodes/stage.mdx | 2 +- docs/content/docs/main/build/nodes/text.mdx | 2 +- .../main/build/plugins/connected-users.mdx | 2 +- .../docs/main/build/plugins/context-menu.mdx | 2 +- .../main/build/plugins/copy-paste-nodes.mdx | 2 +- .../main/build/plugins/nodes-selection.mdx | 2 +- .../main/build/plugins/nodes-snapping.mdx | 2 +- .../main/build/plugins/stage-drop-area.mdx | 2 +- .../docs/main/build/plugins/stage-grid.mdx | 2 +- .../docs/main/build/plugins/stage-panning.mdx | 2 +- .../docs/main/build/plugins/stage-resize.mdx | 2 +- .../docs/main/build/plugins/stage-zoom.mdx | 2 +- .../main/build/plugins/users-pointers.mdx | 2 +- .../main/build/plugins/users-selector.mdx | 2 +- docs/content/docs/main/changelog/index.mdx | 1 + .../docs/main/changelog/prerelease/019.0.mdx | 12 ++ .../docs/main/changelog/prerelease/meta.json | 1 + docs/content/docs/main/index.mdx | 10 +- .../sdk/api-reference/actions/eraser-tool.mdx | 30 +++++ .../docs/sdk/api-reference/actions/index.mdx | 7 + .../docs/sdk/api-reference/actions/meta.json | 1 + .../server/weave-azure-web-pubsub-server.mdx | 39 ++++++ 55 files changed, 437 insertions(+), 86 deletions(-) create mode 100644 code/packages/sdk/src/actions/eraser-tool/constants.ts create mode 100644 code/packages/sdk/src/actions/eraser-tool/eraser-tool.ts create mode 100644 code/packages/sdk/src/actions/eraser-tool/types.ts create mode 100644 docs/content/docs/main/build/actions/eraser-tool.mdx create mode 100644 docs/content/docs/main/changelog/prerelease/019.0.mdx create mode 100644 docs/content/docs/sdk/api-reference/actions/eraser-tool.mdx diff --git a/code/CHANGELOG.md b/code/CHANGELOG.md index 4db30363b..f29300182 100644 --- a/code/CHANGELOG.md +++ b/code/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- [#288](https://github.com/InditexTech/weavejs/issues/288) Provide a tool for erasing elements + ## [0.18.0] - 2025-05-27 ### Changed @@ -326,77 +330,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#18](https://github.com/InditexTech/weavejs/issues/18) Fix awareness not working on store-azure-web-pubsub [Unreleased]: https://github.com/InditexTech/weavejs/compare/0.18.0...HEAD - [0.18.0]: https://github.com/InditexTech/weavejs/compare/0.17.0...0.18.0 - [0.17.0]: https://github.com/InditexTech/weavejs/compare/0.16.2...0.17.0 - [0.16.2]: https://github.com/InditexTech/weavejs/compare/0.16.1...0.16.2 - [0.16.1]: https://github.com/InditexTech/weavejs/compare/0.16.0...0.16.1 - [0.16.0]: https://github.com/InditexTech/weavejs/compare/0.15.0...0.16.0 - [0.15.0]: https://github.com/InditexTech/weavejs/compare/0.14.3...0.15.0 - [0.14.3]: https://github.com/InditexTech/weavejs/compare/0.14.2...0.14.3 - [0.14.2]: https://github.com/InditexTech/weavejs/compare/0.14.1...0.14.2 - [0.14.1]: https://github.com/InditexTech/weavejs/compare/0.14.0...0.14.1 - [0.14.0]: https://github.com/InditexTech/weavejs/compare/0.13.1...0.14.0 - [0.13.1]: https://github.com/InditexTech/weavejs/compare/0.13.0...0.13.1 - [0.13.0]: https://github.com/InditexTech/weavejs/compare/0.12.1...0.13.0 - [0.12.1]: https://github.com/InditexTech/weavejs/compare/0.12.0...0.12.1 - [0.12.0]: https://github.com/InditexTech/weavejs/compare/0.11.0...0.12.0 - [0.11.0]: https://github.com/InditexTech/weavejs/compare/0.10.3...0.11.0 - [0.10.3]: https://github.com/InditexTech/weavejs/compare/0.10.2...0.10.3 - [0.10.2]: https://github.com/InditexTech/weavejs/compare/0.10.1...0.10.2 - [0.10.1]: https://github.com/InditexTech/weavejs/compare/0.10.0...0.10.1 - [0.10.0]: https://github.com/InditexTech/weavejs/compare/0.9.3...0.10.0 - [0.9.3]: https://github.com/InditexTech/weavejs/compare/0.9.2...0.9.3 - [0.9.2]: https://github.com/InditexTech/weavejs/compare/0.9.1...0.9.2 - [0.9.1]: https://github.com/InditexTech/weavejs/compare/0.9.0...0.9.1 - [0.9.0]: https://github.com/InditexTech/weavejs/compare/0.8.0...0.9.0 - [0.8.0]: https://github.com/InditexTech/weavejs/compare/0.7.1...0.8.0 - [0.7.1]: https://github.com/InditexTech/weavejs/compare/0.7.0...0.7.1 - [0.7.0]: https://github.com/InditexTech/weavejs/compare/0.6.0...0.7.0 - [0.6.0]: https://github.com/InditexTech/weavejs/compare/0.5.0...0.6.0 - [0.5.0]: https://github.com/InditexTech/weavejs/compare/0.4.0...0.5.0 - [0.4.0]: https://github.com/InditexTech/weavejs/compare/0.3.3...0.4.0 - [0.3.3]: https://github.com/InditexTech/weavejs/compare/0.3.2...0.3.3 - [0.3.2]: https://github.com/InditexTech/weavejs/compare/0.3.1...0.3.2 - [0.3.1]: https://github.com/InditexTech/weavejs/compare/0.3.0...0.3.1 - [0.3.0]: https://github.com/InditexTech/weavejs/compare/0.2.1...0.3.0 - [0.2.1]: https://github.com/InditexTech/weavejs/compare/0.2.0...0.2.1 - [0.2.0]: https://github.com/InditexTech/weavejs/compare/0.1.1...0.2.0 - [0.1.1]: https://github.com/InditexTech/weavejs/compare/0.1.0...0.1.1 - [0.1.0]: https://github.com/InditexTech/weavejs/releases/tag/0.1.0 diff --git a/code/packages/sdk/src/actions/eraser-tool/constants.ts b/code/packages/sdk/src/actions/eraser-tool/constants.ts new file mode 100644 index 000000000..261bebae5 --- /dev/null +++ b/code/packages/sdk/src/actions/eraser-tool/constants.ts @@ -0,0 +1,10 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +export const ERASER_TOOL_ACTION_NAME = 'eraserTool'; + +export const ERASER_TOOL_STATE = { + ['IDLE']: 'idle', + ['ERASING']: 'erasing', +} as const; diff --git a/code/packages/sdk/src/actions/eraser-tool/eraser-tool.ts b/code/packages/sdk/src/actions/eraser-tool/eraser-tool.ts new file mode 100644 index 000000000..cd6225736 --- /dev/null +++ b/code/packages/sdk/src/actions/eraser-tool/eraser-tool.ts @@ -0,0 +1,121 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +import { WeaveAction } from '@/actions/action'; +import { type WeaveEraserToolActionState } from './types'; +import { ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE } from './constants'; +import type { WeaveNodesSelectionPlugin } from '@/plugins/nodes-selection/nodes-selection'; +import { SELECTION_TOOL_ACTION_NAME } from '../selection-tool/constants'; +import type { WeaveNode } from '@/nodes/node'; +import type { WeaveElementInstance } from '@inditextech/weave-types'; + +export class WeaveEraserToolAction extends WeaveAction { + protected initialized: boolean = false; + protected state: WeaveEraserToolActionState; + protected erasing: boolean = false; + protected cancelAction!: () => void; + onPropsChange = undefined; + onInit = undefined; + + constructor() { + super(); + + this.initialized = false; + this.erasing = false; + this.state = ERASER_TOOL_STATE.IDLE; + } + + getName(): string { + return ERASER_TOOL_ACTION_NAME; + } + + private setupEvents() { + const stage = this.instance.getStage(); + + stage.on('click touch', (e) => { + e.evt.preventDefault(); + + if (!this.erasing) { + return; + } + + const nodeIntersected = this.instance.pointIntersectsElement(); + + if (nodeIntersected) { + const realNode = this.instance.resolveNode(nodeIntersected); + + if (!realNode) { + return; + } + + const nodeType = realNode.getAttrs().nodeType; + const nodeHandler = this.instance.getNodeHandler(nodeType); + const nodeSerialized = nodeHandler.serialize( + realNode as WeaveElementInstance + ); + this.instance.removeNode(nodeSerialized); + } + }); + + stage.container().addEventListener('keydown', (e) => { + if ( + e.key === 'Escape' && + this.instance.getActiveAction() === ERASER_TOOL_ACTION_NAME + ) { + this.cancelAction(); + return; + } + }); + + this.initialized = true; + } + + private setState(state: WeaveEraserToolActionState) { + this.state = state; + } + + private setEraser() { + const stage = this.instance.getStage(); + + stage.container().style.cursor = 'crosshair'; + stage.container().focus(); + + this.erasing = true; + + this.setState(ERASER_TOOL_STATE.ERASING); + } + + trigger(cancelAction: () => void): void { + if (!this.instance) { + throw new Error('Instance not defined'); + } + + if (!this.initialized) { + this.setupEvents(); + } + const stage = this.instance.getStage(); + + stage.container().tabIndex = 1; + stage.container().focus(); + + this.cancelAction = cancelAction; + + this.setEraser(); + } + + cleanup(): void { + const stage = this.instance.getStage(); + + stage.container().style.cursor = 'default'; + this.erasing = false; + + const selectionPlugin = + this.instance.getPlugin('nodesSelection'); + if (selectionPlugin) { + this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME); + } + + this.setState(ERASER_TOOL_STATE.IDLE); + } +} diff --git a/code/packages/sdk/src/actions/eraser-tool/types.ts b/code/packages/sdk/src/actions/eraser-tool/types.ts new file mode 100644 index 000000000..0cc9a1c2c --- /dev/null +++ b/code/packages/sdk/src/actions/eraser-tool/types.ts @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +import { ERASER_TOOL_STATE } from './constants'; + +export type WeaveEraserToolActionStateKeys = keyof typeof ERASER_TOOL_STATE; +export type WeaveEraserToolActionState = + (typeof ERASER_TOOL_STATE)[WeaveEraserToolActionStateKeys]; diff --git a/code/packages/sdk/src/actions/move-tool/move-tool.ts b/code/packages/sdk/src/actions/move-tool/move-tool.ts index 2aea63511..075e1685c 100644 --- a/code/packages/sdk/src/actions/move-tool/move-tool.ts +++ b/code/packages/sdk/src/actions/move-tool/move-tool.ts @@ -5,7 +5,8 @@ import { WeaveAction } from '@/actions/action'; import { type WeaveMoveToolActionState } from './types'; import { MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE } from './constants'; -import { WeaveNodesSelectionPlugin } from '@/plugins/nodes-selection/nodes-selection'; +import type { WeaveNodesSelectionPlugin } from '@/plugins/nodes-selection/nodes-selection'; +import { SELECTION_TOOL_ACTION_NAME } from '../selection-tool/constants'; export class WeaveMoveToolAction extends WeaveAction { protected initialized: boolean = false; @@ -26,6 +27,18 @@ export class WeaveMoveToolAction extends WeaveAction { } private setupEvents() { + const stage = this.instance.getStage(); + + stage.container().addEventListener('keydown', (e) => { + if ( + e.key === 'Escape' && + this.instance.getActiveAction() === MOVE_TOOL_ACTION_NAME + ) { + this.cancelAction(); + return; + } + }); + this.initialized = true; } @@ -68,9 +81,7 @@ export class WeaveMoveToolAction extends WeaveAction { const selectionPlugin = this.instance.getPlugin('nodesSelection'); if (selectionPlugin) { - const tr = selectionPlugin.getTransformer(); - this.instance.disablePlugin('nodesSelection'); - tr.hide(); + this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME); } this.setState(MOVE_TOOL_STATE.IDLE); diff --git a/code/packages/sdk/src/index.ts b/code/packages/sdk/src/index.ts index 7728046d9..80511c81f 100644 --- a/code/packages/sdk/src/index.ts +++ b/code/packages/sdk/src/index.ts @@ -39,6 +39,9 @@ export * from './actions/move-tool/types'; export { WeaveSelectionToolAction } from './actions/selection-tool/selection-tool'; export * from './actions/selection-tool/constants'; export * from './actions/selection-tool/types'; +export { WeaveEraserToolAction } from './actions/eraser-tool/eraser-tool'; +export * from './actions/eraser-tool/constants'; +export * from './actions/eraser-tool/types'; export { WeaveRectangleToolAction } from './actions/rectangle-tool/rectangle-tool'; export * from './actions/rectangle-tool/constants'; export * from './actions/rectangle-tool/types'; diff --git a/code/packages/sdk/src/managers/targeting.ts b/code/packages/sdk/src/managers/targeting.ts index ce0f46f35..34c285a89 100644 --- a/code/packages/sdk/src/managers/targeting.ts +++ b/code/packages/sdk/src/managers/targeting.ts @@ -22,6 +22,45 @@ export class WeaveTargetingManager { this.logger.debug('Targeting manager created'); } + resolveNode(node: Konva.Node): Konva.Node | undefined { + const stage = this.instance.getStage(); + + const nodeAttrs = node.getAttrs(); + + // Is an internal node container, continue to its parent + if (nodeAttrs.nodeId) { + const parentNode = stage.findOne(`#${nodeAttrs.nodeId}`); + + if (!parentNode) { + return undefined; + } + + return this.resolveNode(parentNode); + } + // Is a node and not a layer + if (nodeAttrs.nodeType && nodeAttrs.nodeType !== 'layer') { + return node; + } + return undefined; + } + + pointIntersectsElement(point?: Vector2d): Konva.Node | null { + const stage = this.instance.getStage(); + const relativeMousePointer = point + ? point + : stage.getPointerPosition() ?? { x: 0, y: 0 }; + + const mainLayer = this.instance.getMainLayer(); + + if (!mainLayer) { + return null; + } + + const intersectedNode = mainLayer.getIntersection(relativeMousePointer); + + return intersectedNode; + } + pointIntersectsContainerElement( actualLayer?: Konva.Layer | Konva.Group, point?: Vector2d @@ -40,7 +79,17 @@ export class WeaveTargetingManager { for (const node of intersections) { if (node.getAttrs().nodeId) { const parent = stage.findOne(`#${node.getAttrs().nodeId}`); - intersectedNode = parent; + if (!parent) { + continue; + } + const resolvedNode = this.resolveNode(parent); + if ( + resolvedNode && + resolvedNode.getAttrs().containerId && + resolvedNode.getAttrs().id !== actualLayer?.getAttrs().id + ) { + intersectedNode = parent; + } continue; } if ( diff --git a/code/packages/sdk/src/nodes/image/image.ts b/code/packages/sdk/src/nodes/image/image.ts index 47dd9b356..96750347b 100644 --- a/code/packages/sdk/src/nodes/image/image.ts +++ b/code/packages/sdk/src/nodes/image/image.ts @@ -34,6 +34,7 @@ export class WeaveImageNode extends WeaveNode { const groupImageProps = { ...imageProps, }; + delete groupImageProps.children; delete groupImageProps.imageProperties; delete groupImageProps.zIndex; @@ -54,6 +55,7 @@ export class WeaveImageNode extends WeaveNode { const imagePlaceholder = new Konva.Rect({ ...groupImageProps, id: `${id}-placeholder`, + nodeId: id, x: 0, y: 0, scaleX: 1, @@ -73,6 +75,7 @@ export class WeaveImageNode extends WeaveNode { ...internalImageProps, ...imageProperties, id: `${id}-image`, + nodeId: id, x: 0, y: 0, scaleX: 1, @@ -194,6 +197,7 @@ export class WeaveImageNode extends WeaveNode { ...(nodeAttrs.imageProperties ?? {}), name: undefined, id: `${id}-placeholder`, + nodeId: id, x: 0, y: 0, scaleX: 1, @@ -210,6 +214,7 @@ export class WeaveImageNode extends WeaveNode { ...(nodeAttrs.imageProperties ?? {}), name: undefined, id: `${id}-image`, + nodeId: id, x: 0, y: 0, scaleX: 1, @@ -226,6 +231,7 @@ export class WeaveImageNode extends WeaveNode { ...(nodeAttrs.imageProperties ?? {}), name: undefined, id: `${id}-image`, + nodeId: id, x: 0, y: 0, scaleX: 1, diff --git a/code/packages/sdk/src/utils.ts b/code/packages/sdk/src/utils.ts index af2eb31d5..6c39ab12f 100644 --- a/code/packages/sdk/src/utils.ts +++ b/code/packages/sdk/src/utils.ts @@ -71,7 +71,7 @@ export function moveNodeToContainer( instance: Weave, node: Konva.Node ): Konva.Node | undefined { - const nodesIntersected = instance.pointIntersectsContainerElement(); + const nodeIntersected = instance.pointIntersectsContainerElement(); let nodeActualContainer: Konva.Node | undefined = node.getParent() as Konva.Node; @@ -85,14 +85,14 @@ export function moveNodeToContainer( // Move to container if ( !node.getAttrs().containerId && - nodesIntersected && - nodeActualContainer?.getAttrs().id !== nodesIntersected.getAttrs().id + nodeIntersected && + nodeActualContainer?.getAttrs().id !== nodeIntersected.getAttrs().id ) { - layerToMove = nodesIntersected; + layerToMove = nodeIntersected; } // Move to main layer if ( - !nodesIntersected && + !nodeIntersected && nodeActualContainer?.getAttrs().id !== WEAVE_NODE_LAYER_ID ) { layerToMove = instance.getMainLayer(); diff --git a/code/packages/sdk/src/weave.ts b/code/packages/sdk/src/weave.ts index c5ccd9464..8ccefbfe0 100644 --- a/code/packages/sdk/src/weave.ts +++ b/code/packages/sdk/src/weave.ts @@ -498,6 +498,18 @@ export class Weave extends Emittery { // TARGETING MANAGEMENT METHODS PROXIES + resolveNode(node: Konva.Node): WeaveElementInstance | undefined { + const resolvedNode = this.targetingManager.resolveNode(node); + if (resolvedNode) { + return resolvedNode as WeaveElementInstance; + } + return undefined; + } + + pointIntersectsElement(point?: Vector2d): Konva.Node | null { + return this.targetingManager.pointIntersectsElement(point); + } + pointIntersectsContainerElement( actualLayer?: Konva.Layer | Konva.Group, point?: Vector2d diff --git a/docs/content/docs/main/build/actions/brush-tool.mdx b/docs/content/docs/main/build/actions/brush-tool.mdx index bfb6422e3..e8c4c8cc7 100644 --- a/docs/content/docs/main/build/actions/brush-tool.mdx +++ b/docs/content/docs/main/build/actions/brush-tool.mdx @@ -24,7 +24,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/eraser-tool.mdx b/docs/content/docs/main/build/actions/eraser-tool.mdx new file mode 100644 index 000000000..ba6e7653b --- /dev/null +++ b/docs/content/docs/main/build/actions/eraser-tool.mdx @@ -0,0 +1,64 @@ +--- +title: Eraser Tool +description: Activate the deletion of nodes from the canvas +--- + +import { Accordion, Accordions } from "fumadocs-ui/components/accordion"; + +## Introduction + +This action allows users to erase (delete) elements from the Stage canvas. + +## Usage + + + + Start by importing the action with the following import: + + ```ts + import { WeaveEraserToolAction } from "@inditextech/weave-sdk"; + ``` + + + + Then register the action on the Weave class instance. + + ```ts + const instance = new Weave({ + ... + actions: [ + ..., + new WeaveEraserToolAction(), // [!code ++] + ] + }) + ``` + + + + Setup on a button or any element on the UI the user can trigger, an action + to trigger the action. For example on a button on React: + + ```tsx + import { useWeave } from "@inditextech/weave-react"; + + const MyEraserToolTriggerComponent = () => { + const instance = useWeave((state) => state.instance); + + const triggerTool = React.useCallback(() => { + instance.triggerAction("eraserTool"); + }, [instance]) + + return ( + + ) + } + ``` + + + + Finally as an user trigger the UI element that launches the action. + + When enabled the user can click / touch on an element and it will deleted. + + + diff --git a/docs/content/docs/main/build/actions/export-node-tool.mdx b/docs/content/docs/main/build/actions/export-node-tool.mdx index e18d628a1..ec875db1c 100644 --- a/docs/content/docs/main/build/actions/export-node-tool.mdx +++ b/docs/content/docs/main/build/actions/export-node-tool.mdx @@ -18,7 +18,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/export-stage-tool.mdx b/docs/content/docs/main/build/actions/export-stage-tool.mdx index 3c10a88b4..2d2279f67 100644 --- a/docs/content/docs/main/build/actions/export-stage-tool.mdx +++ b/docs/content/docs/main/build/actions/export-stage-tool.mdx @@ -19,7 +19,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/fit-to-screen-tool.mdx b/docs/content/docs/main/build/actions/fit-to-screen-tool.mdx index 340274199..c76c1011c 100644 --- a/docs/content/docs/main/build/actions/fit-to-screen-tool.mdx +++ b/docs/content/docs/main/build/actions/fit-to-screen-tool.mdx @@ -19,7 +19,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/fit-to-selection-tool.mdx b/docs/content/docs/main/build/actions/fit-to-selection-tool.mdx index e753cddbf..9cc24aaad 100644 --- a/docs/content/docs/main/build/actions/fit-to-selection-tool.mdx +++ b/docs/content/docs/main/build/actions/fit-to-selection-tool.mdx @@ -19,7 +19,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/frame-tool.mdx b/docs/content/docs/main/build/actions/frame-tool.mdx index 2dc627050..e95aee024 100644 --- a/docs/content/docs/main/build/actions/frame-tool.mdx +++ b/docs/content/docs/main/build/actions/frame-tool.mdx @@ -19,7 +19,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/image-tool.mdx b/docs/content/docs/main/build/actions/image-tool.mdx index f49e44900..f03825664 100644 --- a/docs/content/docs/main/build/actions/image-tool.mdx +++ b/docs/content/docs/main/build/actions/image-tool.mdx @@ -21,7 +21,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/index.mdx b/docs/content/docs/main/build/actions/index.mdx index 490ed532a..2ce4a1bdd 100644 --- a/docs/content/docs/main/build/actions/index.mdx +++ b/docs/content/docs/main/build/actions/index.mdx @@ -98,6 +98,13 @@ select nodes, move then, resize them, etc. + + +Allows users to erase (delete) elements of the canvas. When enabled the user can click on an +element and it will be erased. + + + ### Nodes Tools diff --git a/docs/content/docs/main/build/actions/meta.json b/docs/content/docs/main/build/actions/meta.json index eba308bd1..eb0db9ccc 100644 --- a/docs/content/docs/main/build/actions/meta.json +++ b/docs/content/docs/main/build/actions/meta.json @@ -3,6 +3,7 @@ "pages": [ "move-tool", "selection-tool", + "eraser-tool", "rectangle-tool", "pen-tool", "brush-tool", diff --git a/docs/content/docs/main/build/actions/move-tool.mdx b/docs/content/docs/main/build/actions/move-tool.mdx index 00ec6800e..33dc64a76 100644 --- a/docs/content/docs/main/build/actions/move-tool.mdx +++ b/docs/content/docs/main/build/actions/move-tool.mdx @@ -17,7 +17,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/pen-tool.mdx b/docs/content/docs/main/build/actions/pen-tool.mdx index 0e06629cd..0fd74fcf9 100644 --- a/docs/content/docs/main/build/actions/pen-tool.mdx +++ b/docs/content/docs/main/build/actions/pen-tool.mdx @@ -23,7 +23,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/rectangle-tool.mdx b/docs/content/docs/main/build/actions/rectangle-tool.mdx index fcdea4169..94c69eb3d 100644 --- a/docs/content/docs/main/build/actions/rectangle-tool.mdx +++ b/docs/content/docs/main/build/actions/rectangle-tool.mdx @@ -17,7 +17,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/selection-tool.mdx b/docs/content/docs/main/build/actions/selection-tool.mdx index f218a2cc5..a4e5c1f4f 100644 --- a/docs/content/docs/main/build/actions/selection-tool.mdx +++ b/docs/content/docs/main/build/actions/selection-tool.mdx @@ -17,7 +17,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/text-tool.mdx b/docs/content/docs/main/build/actions/text-tool.mdx index 099e9fa99..156b7b2fd 100644 --- a/docs/content/docs/main/build/actions/text-tool.mdx +++ b/docs/content/docs/main/build/actions/text-tool.mdx @@ -24,7 +24,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/zoom-in-tool.mdx b/docs/content/docs/main/build/actions/zoom-in-tool.mdx index cfa295dea..1a0e74c3a 100644 --- a/docs/content/docs/main/build/actions/zoom-in-tool.mdx +++ b/docs/content/docs/main/build/actions/zoom-in-tool.mdx @@ -19,7 +19,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/actions/zoom-out-tool.mdx b/docs/content/docs/main/build/actions/zoom-out-tool.mdx index 0a088ade7..047217ffc 100644 --- a/docs/content/docs/main/build/actions/zoom-out-tool.mdx +++ b/docs/content/docs/main/build/actions/zoom-out-tool.mdx @@ -19,7 +19,7 @@ This action needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/nodes/frame.mdx b/docs/content/docs/main/build/nodes/frame.mdx index 5d7c5a617..72e031816 100644 --- a/docs/content/docs/main/build/nodes/frame.mdx +++ b/docs/content/docs/main/build/nodes/frame.mdx @@ -15,7 +15,7 @@ Nodes, making it ideal for modular UIs, flow sections, or structured diagrams. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/nodes/group.mdx b/docs/content/docs/main/build/nodes/group.mdx index 7bffe727f..05a20c4f3 100644 --- a/docs/content/docs/main/build/nodes/group.mdx +++ b/docs/content/docs/main/build/nodes/group.mdx @@ -16,7 +16,7 @@ scene organized and easier to manipulate programmatically. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/nodes/image.mdx b/docs/content/docs/main/build/nodes/image.mdx index 97a607194..a256f1772 100644 --- a/docs/content/docs/main/build/nodes/image.mdx +++ b/docs/content/docs/main/build/nodes/image.mdx @@ -15,7 +15,7 @@ and can be extended with plugins for features like cropping, masking, or annotat ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/nodes/layer.mdx b/docs/content/docs/main/build/nodes/layer.mdx index 4b872e24f..9d0ddf1f9 100644 --- a/docs/content/docs/main/build/nodes/layer.mdx +++ b/docs/content/docs/main/build/nodes/layer.mdx @@ -21,7 +21,7 @@ share the same coordinate space but can be managed and updated independently. Layers, use the stores `initialState` configuration property on server-side. - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/nodes/line.mdx b/docs/content/docs/main/build/nodes/line.mdx index b21067126..28bd34c0f 100644 --- a/docs/content/docs/main/build/nodes/line.mdx +++ b/docs/content/docs/main/build/nodes/line.mdx @@ -16,7 +16,7 @@ flow editors, and visual programming interfaces. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/nodes/rectangle.mdx b/docs/content/docs/main/build/nodes/rectangle.mdx index 890164e65..4037495e4 100644 --- a/docs/content/docs/main/build/nodes/rectangle.mdx +++ b/docs/content/docs/main/build/nodes/rectangle.mdx @@ -16,7 +16,7 @@ or selection. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/nodes/stage.mdx b/docs/content/docs/main/build/nodes/stage.mdx index 5af7cf251..eb0fcd1c7 100644 --- a/docs/content/docs/main/build/nodes/stage.mdx +++ b/docs/content/docs/main/build/nodes/stage.mdx @@ -20,7 +20,7 @@ selection, or snapping—are initialized and managed. use the stores `initialState` configuration property on server-side. - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/nodes/text.mdx b/docs/content/docs/main/build/nodes/text.mdx index b5b8278f2..efbb73cc0 100644 --- a/docs/content/docs/main/build/nodes/text.mdx +++ b/docs/content/docs/main/build/nodes/text.mdx @@ -15,7 +15,7 @@ inline editing. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/connected-users.mdx b/docs/content/docs/main/build/plugins/connected-users.mdx index 27d277172..58fd21580 100644 --- a/docs/content/docs/main/build/plugins/connected-users.mdx +++ b/docs/content/docs/main/build/plugins/connected-users.mdx @@ -19,7 +19,7 @@ This plugin needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/context-menu.mdx b/docs/content/docs/main/build/plugins/context-menu.mdx index 86c8fbfd3..ce0af56c9 100644 --- a/docs/content/docs/main/build/plugins/context-menu.mdx +++ b/docs/content/docs/main/build/plugins/context-menu.mdx @@ -23,7 +23,7 @@ This plugin needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/copy-paste-nodes.mdx b/docs/content/docs/main/build/plugins/copy-paste-nodes.mdx index ceefa09cc..e108c5f56 100644 --- a/docs/content/docs/main/build/plugins/copy-paste-nodes.mdx +++ b/docs/content/docs/main/build/plugins/copy-paste-nodes.mdx @@ -24,7 +24,7 @@ This plugin needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/nodes-selection.mdx b/docs/content/docs/main/build/plugins/nodes-selection.mdx index 36ed5d5c5..fa98d0598 100644 --- a/docs/content/docs/main/build/plugins/nodes-selection.mdx +++ b/docs/content/docs/main/build/plugins/nodes-selection.mdx @@ -18,7 +18,7 @@ interfaces. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/nodes-snapping.mdx b/docs/content/docs/main/build/plugins/nodes-snapping.mdx index c6ff93b7e..d0bd30785 100644 --- a/docs/content/docs/main/build/plugins/nodes-snapping.mdx +++ b/docs/content/docs/main/build/plugins/nodes-snapping.mdx @@ -22,7 +22,7 @@ This plugin needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/stage-drop-area.mdx b/docs/content/docs/main/build/plugins/stage-drop-area.mdx index 31240a423..81c8de4f3 100644 --- a/docs/content/docs/main/build/plugins/stage-drop-area.mdx +++ b/docs/content/docs/main/build/plugins/stage-drop-area.mdx @@ -19,7 +19,7 @@ handling. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/stage-grid.mdx b/docs/content/docs/main/build/plugins/stage-grid.mdx index 10f31b33a..e096e3a79 100644 --- a/docs/content/docs/main/build/plugins/stage-grid.mdx +++ b/docs/content/docs/main/build/plugins/stage-grid.mdx @@ -18,7 +18,7 @@ during interactions. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/stage-panning.mdx b/docs/content/docs/main/build/plugins/stage-panning.mdx index 5e58062bf..f7deacce9 100644 --- a/docs/content/docs/main/build/plugins/stage-panning.mdx +++ b/docs/content/docs/main/build/plugins/stage-panning.mdx @@ -24,7 +24,7 @@ This plugin needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/stage-resize.mdx b/docs/content/docs/main/build/plugins/stage-resize.mdx index a82284c5c..b06ff28e4 100644 --- a/docs/content/docs/main/build/plugins/stage-resize.mdx +++ b/docs/content/docs/main/build/plugins/stage-resize.mdx @@ -17,7 +17,7 @@ flexibility and visibility are key. ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/stage-zoom.mdx b/docs/content/docs/main/build/plugins/stage-zoom.mdx index 72d33b815..bb74285c1 100644 --- a/docs/content/docs/main/build/plugins/stage-zoom.mdx +++ b/docs/content/docs/main/build/plugins/stage-zoom.mdx @@ -24,7 +24,7 @@ This plugin needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/users-pointers.mdx b/docs/content/docs/main/build/plugins/users-pointers.mdx index 418789893..0eaa482b3 100644 --- a/docs/content/docs/main/build/plugins/users-pointers.mdx +++ b/docs/content/docs/main/build/plugins/users-pointers.mdx @@ -24,7 +24,7 @@ This plugin needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/build/plugins/users-selector.mdx b/docs/content/docs/main/build/plugins/users-selector.mdx index 5794701c9..e0de00b67 100644 --- a/docs/content/docs/main/build/plugins/users-selector.mdx +++ b/docs/content/docs/main/build/plugins/users-selector.mdx @@ -24,7 +24,7 @@ This plugin needs also registered on the Weave instance the following: ## Usage - + Start by importing the action with the following import: diff --git a/docs/content/docs/main/changelog/index.mdx b/docs/content/docs/main/changelog/index.mdx index 4825d99fa..e7c687b0f 100644 --- a/docs/content/docs/main/changelog/index.mdx +++ b/docs/content/docs/main/changelog/index.mdx @@ -9,6 +9,7 @@ description: Check out the latest changes to Weave.js. ## Pre-release versions +- [**0.19.0**](/docs/main/changelog/prerelease/0.19.0) - [**0.18.0**](/docs/main/changelog/prerelease/0.18.0) - [**0.17.0**](/docs/main/changelog/prerelease/0.17.0) - [**0.16.2**](/docs/main/changelog/prerelease/0.16.2) diff --git a/docs/content/docs/main/changelog/prerelease/019.0.mdx b/docs/content/docs/main/changelog/prerelease/019.0.mdx new file mode 100644 index 000000000..0f1e60e8e --- /dev/null +++ b/docs/content/docs/main/changelog/prerelease/019.0.mdx @@ -0,0 +1,12 @@ +--- +title: v0.19.0 +description: Improvements to Azure Web PubSub store +--- + +## Metadata + +- **Release date**: 2025-05-28 + +### Added + +- [#288](https://github.com/InditexTech/weavejs/issues/288) Provide a tool for erasing elements diff --git a/docs/content/docs/main/changelog/prerelease/meta.json b/docs/content/docs/main/changelog/prerelease/meta.json index 0c1ccbd34..4273fb988 100644 --- a/docs/content/docs/main/changelog/prerelease/meta.json +++ b/docs/content/docs/main/changelog/prerelease/meta.json @@ -2,6 +2,7 @@ "title": "Prerelease versions", "description": "Detailed changelog for Weave.js pre-release versions", "pages": [ + "0.19.0", "0.18.0", "0.17.0", "0.16.2", diff --git a/docs/content/docs/main/index.mdx b/docs/content/docs/main/index.mdx index 68783ebef..3a17f98e7 100644 --- a/docs/content/docs/main/index.mdx +++ b/docs/content/docs/main/index.mdx @@ -1,7 +1,6 @@ --- title: About Weave.js description: Build collaborative canvas applications - --- import { Accordion, Accordions } from "fumadocs-ui/components/accordion"; @@ -13,14 +12,14 @@ Weave.js is a powerful headless framework for building end-to-end **collaborativ Aimed at developers, it provides all the building blocks and plugins to develop visual collaborative [canvas](/docs/main/glossary#canvas), while handling user interactions to enable real-time collaboration among multiple users. -For a deep dive, refer to [Architecture overview](/docs/main/architecture). + For a deep dive, refer to [Architecture overview](/docs/main/architecture). ## Key features - **Canvas-first rendering** via [Konva.js](/docs/main/architecture#konvajs) & [React Reconciler](/docs/main/architecture#react-reconciler) -- **Real-time collaboration** powered by [Yjs](/docs/main/architecture#yjs) & [SyncedStore](/docs/main/architecture#syncedstore) -- **Extensible plugin system** +- **Real-time collaboration** powered by [Yjs](/docs/main/architecture#yjs) & [SyncedStore](/docs/main/architecture#syncedstore) +- **Extensible plugin system** - **Works with any UI framework** (React helpers included) ## Live showcase @@ -42,7 +41,7 @@ Built using: Here are some common questions developers often ask. - + + + +Allows users to erase (delete) elements of the canvas. When enabled the user can click on an +element and it will be erased. + + + ### Nodes Tools diff --git a/docs/content/docs/sdk/api-reference/actions/meta.json b/docs/content/docs/sdk/api-reference/actions/meta.json index 4f0293393..08a77f728 100644 --- a/docs/content/docs/sdk/api-reference/actions/meta.json +++ b/docs/content/docs/sdk/api-reference/actions/meta.json @@ -4,6 +4,7 @@ "action", "move-tool", "selection-tool", + "eraser-tool", "rectangle-tool", "pen-tool", "brush-tool", diff --git a/docs/content/docs/store-azure-web-pubsub/api-reference/server/weave-azure-web-pubsub-server.mdx b/docs/content/docs/store-azure-web-pubsub/api-reference/server/weave-azure-web-pubsub-server.mdx index d6d6535f8..cf9a28360 100644 --- a/docs/content/docs/store-azure-web-pubsub/api-reference/server/weave-azure-web-pubsub-server.mdx +++ b/docs/content/docs/store-azure-web-pubsub/api-reference/server/weave-azure-web-pubsub-server.mdx @@ -118,6 +118,45 @@ type WeaveAzureWebPubsubServerParams = { persistRoom?: PersistRoom; fetchRoom?: FetchRoom; }; + +interface WebPubSubEventHandlerOptions { + /** + * Custom serving path for the path of the CloudEvents handler. + */ + path?: string; + + /** + * Handle 'connect' event, the service waits for the response to proceed. + */ + handleConnect?: ( + connectRequest: ConnectRequest, + connectResponse: ConnectResponseHandler + ) => void; + + /** + * Handle user events, the service waits for the response to proceed. + */ + handleUserEvent?: ( + userEventRequest: UserEventRequest, + userEventResponse: UserEventResponseHandler + ) => void; + + /** + * Event trigger for "connected" unblocking event. This is an unblocking event and the service does not wait for the response. + */ + onConnected?: (connectedRequest: ConnectedRequest) => void; + + /** + * + * Event triggers for "disconnected" unblocking event. This is an unblocking event and the service does not wait for the response. + */ + onDisconnected?: (disconnectedRequest: DisconnectedRequest) => void; + + /** + * If not specified, by default allow all the endpoints, otherwise only allow specified endpoints + */ + allowedEndpoints?: string[]; +} ``` ## Shared-state initial value