@(Node.Title ?? "Title")
@foreach (var port in Node.Ports)
{
@@ -11,4 +11,12 @@
[Parameter]
public NodeModel Node { get; set; } = null!;
+ private string GenerateStyle()
+ {
+ if (Node.Size is not null)
+ {
+ return $"width: {Node.Size.Width}px; height: {Node.Size.Height}px";
+ }
+ return string.Empty;
+ }
}
\ No newline at end of file
diff --git a/src/Blazor.Diagrams/wwwroot/default.styles.css b/src/Blazor.Diagrams/wwwroot/default.styles.css
index b095bbe4e..2b355029a 100644
--- a/src/Blazor.Diagrams/wwwroot/default.styles.css
+++ b/src/Blazor.Diagrams/wwwroot/default.styles.css
@@ -127,4 +127,28 @@ g.diagram-group.default.selected > rect {
transform: translate(-50%, -50%);
}
+.default-node-resizer {
+ width: 5px;
+ height: 5px;
+ background-color: #f5f5f5;
+ border: 1px solid #6e9fd4;
+ position: absolute;
+}
+
+.default-node-resizer.bottomright {
+ cursor: nwse-resize;
+}
+
+.default-node-resizer.topright {
+ cursor: nesw-resize;
+}
+
+.default-node-resizer.bottomleft {
+ cursor: nesw-resize;
+}
+
+.default-node-resizer.topleft {
+ cursor: nwse-resize;
+}
+
/*# sourceMappingURL=wwwroot\default.styles.css.map */
diff --git a/src/Blazor.Diagrams/wwwroot/default.styles.min.css b/src/Blazor.Diagrams/wwwroot/default.styles.min.css
index c44adedc3..e794e823e 100644
--- a/src/Blazor.Diagrams/wwwroot/default.styles.min.css
+++ b/src/Blazor.Diagrams/wwwroot/default.styles.min.css
@@ -1 +1 @@
-.default-node{width:100px;height:80px;border-radius:10px;background-color:#f5f5f5;border:1px solid #e8e8e8;-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;}.default-node.selected{border:1px solid #6e9fd4;}.default-node.selected .diagram-port{border:1px solid #6e9fd4;}.default-node .diagram-port,.default.diagram-group .diagram-port{width:20px;height:20px;margin:-10px;border-radius:50%;background-color:#f5f5f5;border:1px solid #d4d4d4;cursor:pointer;position:absolute;}.default-node .diagram-port:hover,.default-node .diagram-port.has-links,.default.diagram-group .diagram-port.has-links{background-color:#000;}.default-node .diagram-port.bottom,.default.diagram-group .diagram-port.bottom{bottom:0;left:50%;}.default-node .diagram-port.bottomleft,.default.diagram-group .diagram-port.bottomleft{bottom:0;left:0;}.default-node .diagram-port.bottomright,.default.diagram-group .diagram-port.bottomright{bottom:0;right:0;}.default-node .diagram-port.top,.default.diagram-group .diagram-port.top{top:0;left:50%;}.default-node .diagram-port.topleft,.default.diagram-group .diagram-port.topleft{top:0;left:0;}.default-node .diagram-port.topright,.default.diagram-group .diagram-port.topright{top:0;right:0;}.default-node .diagram-port.left,.default.diagram-group .diagram-port.left{left:0;top:50%;}.default-node .diagram-port.right,.default.diagram-group .diagram-port.right{right:0;top:50%;}.diagram-navigator.default{position:absolute;bottom:10px;right:10px;border:3px solid #9ba8b0;border-radius:15px;padding:20px;background-color:#fff;}div.diagram-group.default{outline:2px solid #000;background:#c6c6c6;}div.diagram-group.default.selected{outline:2px solid #6e9fd4;}g.diagram-group.default rect{outline:2px solid #000;fill:#c6c632;}g.diagram-group.default.selected>rect{outline:2px solid #008000;}.diagram-link div.default-link-label{display:inline-block;color:#fff;background-color:#6e9fd4;border-radius:.25rem;padding:.25rem;text-align:center;font-size:.875rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;min-width:3rem;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);}
\ No newline at end of file
+.default-node{width:100px;height:80px;border-radius:10px;background-color:#f5f5f5;border:1px solid #e8e8e8;-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;}.default-node.selected{border:1px solid #6e9fd4;}.default-node.selected .diagram-port{border:1px solid #6e9fd4;}.default-node .diagram-port,.default.diagram-group .diagram-port{width:20px;height:20px;margin:-10px;border-radius:50%;background-color:#f5f5f5;border:1px solid #d4d4d4;cursor:pointer;position:absolute;}.default-node .diagram-port:hover,.default-node .diagram-port.has-links,.default.diagram-group .diagram-port.has-links{background-color:#000;}.default-node .diagram-port.bottom,.default.diagram-group .diagram-port.bottom{bottom:0;left:50%;}.default-node .diagram-port.bottomleft,.default.diagram-group .diagram-port.bottomleft{bottom:0;left:0;}.default-node .diagram-port.bottomright,.default.diagram-group .diagram-port.bottomright{bottom:0;right:0;}.default-node .diagram-port.top,.default.diagram-group .diagram-port.top{top:0;left:50%;}.default-node .diagram-port.topleft,.default.diagram-group .diagram-port.topleft{top:0;left:0;}.default-node .diagram-port.topright,.default.diagram-group .diagram-port.topright{top:0;right:0;}.default-node .diagram-port.left,.default.diagram-group .diagram-port.left{left:0;top:50%;}.default-node .diagram-port.right,.default.diagram-group .diagram-port.right{right:0;top:50%;}.diagram-navigator.default{position:absolute;bottom:10px;right:10px;border:3px solid #9ba8b0;border-radius:15px;padding:20px;background-color:#fff;}div.diagram-group.default{outline:2px solid #000;background:#c6c6c6;}div.diagram-group.default.selected{outline:2px solid #6e9fd4;}g.diagram-group.default rect{outline:2px solid #000;fill:#c6c632;}g.diagram-group.default.selected>rect{outline:2px solid #008000;}.diagram-link div.default-link-label{display:inline-block;color:#fff;background-color:#6e9fd4;border-radius:.25rem;padding:.25rem;text-align:center;font-size:.875rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;min-width:3rem;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);}.default-node-resizer{width:5px;height:5px;background-color:#f5f5f5;border:1px solid #6e9fd4;position:absolute;}.default-node-resizer.bottomright{cursor:nwse-resize;}.default-node-resizer.topright{cursor:nesw-resize;}.default-node-resizer.bottomleft{cursor:nesw-resize;}.default-node-resizer.topleft{cursor:nwse-resize;}
\ No newline at end of file
diff --git a/src/Blazor.Diagrams/wwwroot/default.styles.min.css.gz b/src/Blazor.Diagrams/wwwroot/default.styles.min.css.gz
index 905f20cd3..3c43a8a10 100644
Binary files a/src/Blazor.Diagrams/wwwroot/default.styles.min.css.gz and b/src/Blazor.Diagrams/wwwroot/default.styles.min.css.gz differ
diff --git a/src/Blazor.Diagrams/wwwroot/style.min.css.gz b/src/Blazor.Diagrams/wwwroot/style.min.css.gz
index e72cb7d8a..4a312feec 100644
Binary files a/src/Blazor.Diagrams/wwwroot/style.min.css.gz and b/src/Blazor.Diagrams/wwwroot/style.min.css.gz differ
diff --git a/tests/Blazor.Diagrams.Core.Tests/Controls/ResizeControlTests.cs b/tests/Blazor.Diagrams.Core.Tests/Controls/ResizeControlTests.cs
new file mode 100644
index 000000000..dcd9bab14
--- /dev/null
+++ b/tests/Blazor.Diagrams.Core.Tests/Controls/ResizeControlTests.cs
@@ -0,0 +1,75 @@
+using Blazor.Diagrams.Core.Controls.Default;
+using Blazor.Diagrams.Core.Events;
+using Blazor.Diagrams.Core.Models.Base;
+using Blazor.Diagrams.Core.Positions.Resizing;
+using Moq;
+using Xunit;
+
+namespace Blazor.Diagrams.Core.Tests.Controls
+{
+ public class ResizeControlTests
+ {
+ [Fact]
+ public void GetPosition_ShouldUseResizeProviderGetPosition()
+ {
+ var resizeProvider = new Mock
();
+ var control = new ResizeControl(resizeProvider.Object);
+ var model = new Mock();
+
+ control.GetPosition(model.Object);
+
+ resizeProvider.Verify(m => m.GetPosition(model.Object), Times.Once);
+ }
+
+ [Fact]
+ public void OnPointerDown_ShouldInvokeResizeStart()
+ {
+ var resizeProvider = new Mock();
+ var control = new ResizeControl(resizeProvider.Object);
+ var diagram = Mock.Of();
+ var model = Mock.Of();
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 0, 0, 0, 0, 0, 0, string.Empty, true);
+
+ control.OnPointerDown(diagram, model, eventArgs);
+
+ resizeProvider.Verify(m => m.OnResizeStart(diagram, model, eventArgs), Times.Once);
+ }
+
+ [Fact]
+ public void OnPointerDown_ShouldAddEventHandlers()
+ {
+ var resizeProvider = new Mock();
+ var control = new ResizeControl(resizeProvider.Object);
+ var diagram = new TestDiagram();
+ var model = Mock.Of();
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 0, 0, 0, 0, 0, 0, string.Empty, true);
+
+ control.OnPointerDown(diagram, model, eventArgs);
+
+ diagram.TriggerPointerMove(model, eventArgs);
+ resizeProvider.Verify(m => m.OnPointerMove(model, eventArgs), Times.Once);
+
+ diagram.TriggerPointerUp(model, eventArgs);
+ resizeProvider.Verify(m => m.OnResizeEnd(model, eventArgs), Times.Once);
+ }
+
+ [Fact]
+ public void OnPointerUp_ShouldRemoveEventHandlers()
+ {
+ var resizeProvider = new Mock();
+ var control = new ResizeControl(resizeProvider.Object);
+ var diagram = new TestDiagram();
+ var model = Mock.Of();
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 0, 0, 0, 0, 0, 0, string.Empty, true);
+
+ control.OnPointerDown(diagram, model, eventArgs);
+ diagram.TriggerPointerUp(model, eventArgs);
+
+ diagram.TriggerPointerMove(model, eventArgs);
+ resizeProvider.Verify(m => m.OnPointerMove(model, eventArgs), Times.Never);
+
+ diagram.TriggerPointerUp(model, eventArgs);
+ resizeProvider.Verify(m => m.OnResizeEnd(model, eventArgs), Times.Once);
+ }
+ }
+}
diff --git a/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/BottomLeftResizerProviderTests.cs b/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/BottomLeftResizerProviderTests.cs
new file mode 100644
index 000000000..79ef6c17b
--- /dev/null
+++ b/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/BottomLeftResizerProviderTests.cs
@@ -0,0 +1,82 @@
+using Blazor.Diagrams.Core.Controls.Default;
+using Blazor.Diagrams.Core.Events;
+using Blazor.Diagrams.Core.Geometry;
+using Blazor.Diagrams.Core.Models;
+using Blazor.Diagrams.Core.Positions.Resizing;
+using FluentAssertions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Blazor.Diagrams.Core.Tests.Positions.Resizing
+{
+ public class BottomLeftResizerProviderTests
+ {
+ [Fact]
+ public void DragResizer_ShouldResizeNode()
+ {
+ // setup
+ var diagram = new TestDiagram();
+ diagram.SetContainer(new Rectangle(0, 0, 1000, 400));
+ var node = new NodeModel(position: new Point(0, 0));
+ node.Size = new Size(100, 200);
+ var control = new ResizeControl(new BottomLeftResizerProvider());
+ diagram.Controls.AddFor(node).Add(control);
+ diagram.SelectModel(node, false);
+
+ // before resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(100);
+ node.Size.Height.Should().Be(200);
+
+ // resize
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ control.OnPointerDown(diagram, node, eventArgs);
+ eventArgs = new PointerEventArgs(10, 15, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+
+ // after resize
+ node.Position.X.Should().Be(10);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(90);
+ node.Size.Height.Should().Be(215);
+ }
+
+ [Fact]
+ public void DragResizer_SmallerThanMinSize_SetsNodeToMinSize()
+ {
+ // setup
+ var diagram = new TestDiagram();
+ diagram.SetContainer(new Rectangle(0, 0, 1000, 400));
+ var node = new NodeModel(position: new Point(0, 0));
+ node.Size = new Size(100, 200);
+ var control = new ResizeControl(new BottomLeftResizerProvider());
+ diagram.Controls.AddFor(node).Add(control);
+ diagram.SelectModel(node, false);
+
+ // before resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(100);
+ node.Size.Height.Should().Be(200);
+
+ // resize
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ control.OnPointerDown(diagram, node, eventArgs);
+ eventArgs = new PointerEventArgs(99, -199, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+ eventArgs = new PointerEventArgs(300, -300, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+
+ // after resize
+ node.Position.X.Should().Be(99);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(0);
+ node.Size.Height.Should().Be(0);
+ }
+ }
+}
diff --git a/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/BottomRightResizerProviderTests.cs b/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/BottomRightResizerProviderTests.cs
new file mode 100644
index 000000000..20ab27770
--- /dev/null
+++ b/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/BottomRightResizerProviderTests.cs
@@ -0,0 +1,80 @@
+using Blazor.Diagrams.Core.Controls.Default;
+using Blazor.Diagrams.Core.Events;
+using Blazor.Diagrams.Core.Geometry;
+using Blazor.Diagrams.Core.Models;
+using Blazor.Diagrams.Core.Positions.Resizing;
+using FluentAssertions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Blazor.Diagrams.Core.Tests.Positions.Resizing
+{
+ public class BottomRightResizerProviderTests
+ {
+ [Fact]
+ public void DragResizer_ShouldResizeNode()
+ {
+ // setup
+ var diagram = new TestDiagram();
+ diagram.SetContainer(new Rectangle(0, 0, 1000, 400));
+ var node = new NodeModel(position: new Point(0, 0));
+ node.Size = new Size(100, 200);
+ var control = new ResizeControl(new BottomRightResizerProvider());
+ diagram.Controls.AddFor(node).Add(control);
+ diagram.SelectModel(node, false);
+
+ // before resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(100);
+ node.Size.Height.Should().Be(200);
+
+ // resize
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ control.OnPointerDown(diagram, node, eventArgs);
+ eventArgs = new PointerEventArgs(10, 15, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+
+ // after resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(110);
+ node.Size.Height.Should().Be(215);
+ }
+
+ [Fact]
+ public void DragResizer_SmallerThanMinSize_SetsNodeToMinSize()
+ {
+ // setup
+ var diagram = new TestDiagram();
+ diagram.SetContainer(new Rectangle(0, 0, 1000, 400));
+ var node = new NodeModel(position: new Point(0, 0));
+ node.Size = new Size(100, 200);
+ var control = new ResizeControl(new BottomRightResizerProvider());
+ diagram.Controls.AddFor(node).Add(control);
+ diagram.SelectModel(node, false);
+
+ // before resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(100);
+ node.Size.Height.Should().Be(200);
+
+ // resize
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ control.OnPointerDown(diagram, node, eventArgs);
+ eventArgs = new PointerEventArgs(-300, -300, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+
+ // after resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(0);
+ node.Size.Height.Should().Be(0);
+ }
+ }
+}
diff --git a/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/TopLeftResizerProviderTests.cs b/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/TopLeftResizerProviderTests.cs
new file mode 100644
index 000000000..1cc715d59
--- /dev/null
+++ b/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/TopLeftResizerProviderTests.cs
@@ -0,0 +1,82 @@
+using Blazor.Diagrams.Core.Controls.Default;
+using Blazor.Diagrams.Core.Events;
+using Blazor.Diagrams.Core.Geometry;
+using Blazor.Diagrams.Core.Models;
+using Blazor.Diagrams.Core.Positions.Resizing;
+using FluentAssertions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Blazor.Diagrams.Core.Tests.Positions.Resizing
+{
+ public class TopLeftResizerProviderTests
+ {
+ [Fact]
+ public void DragResizer_ShouldResizeNode()
+ {
+ // setup
+ var diagram = new TestDiagram();
+ diagram.SetContainer(new Rectangle(0, 0, 1000, 400));
+ var node = new NodeModel(position: new Point(0, 0));
+ node.Size = new Size(100, 200);
+ var control = new ResizeControl(new TopLeftResizerProvider());
+ diagram.Controls.AddFor(node).Add(control);
+ diagram.SelectModel(node, false);
+
+ // before resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(100);
+ node.Size.Height.Should().Be(200);
+
+ // resize
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ control.OnPointerDown(diagram, node, eventArgs);
+ eventArgs = new PointerEventArgs(10, 15, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+
+ // after resize
+ node.Position.X.Should().Be(10);
+ node.Position.Y.Should().Be(15);
+ node.Size.Width.Should().Be(90);
+ node.Size.Height.Should().Be(185);
+ }
+
+ [Fact]
+ public void DragResizer_SmallerThanMinSize_SetsNodeToMinSize()
+ {
+ // setup
+ var diagram = new TestDiagram();
+ diagram.SetContainer(new Rectangle(0, 0, 1000, 400));
+ var node = new NodeModel(position: new Point(0, 0));
+ node.Size = new Size(100, 200);
+ var control = new ResizeControl(new TopLeftResizerProvider());
+ diagram.Controls.AddFor(node).Add(control);
+ diagram.SelectModel(node, false);
+
+ // before resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(100);
+ node.Size.Height.Should().Be(200);
+
+ // resize
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ control.OnPointerDown(diagram, node, eventArgs);
+ eventArgs = new PointerEventArgs(99, 199, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+ eventArgs = new PointerEventArgs(300, 300, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+
+ // after resize
+ node.Position.X.Should().Be(99);
+ node.Position.Y.Should().Be(199);
+ node.Size.Width.Should().Be(0);
+ node.Size.Height.Should().Be(0);
+ }
+ }
+}
diff --git a/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/TopRightResizerProviderTests.cs b/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/TopRightResizerProviderTests.cs
new file mode 100644
index 000000000..a138d524f
--- /dev/null
+++ b/tests/Blazor.Diagrams.Core.Tests/Positions/Resizing/TopRightResizerProviderTests.cs
@@ -0,0 +1,82 @@
+using Blazor.Diagrams.Core.Controls.Default;
+using Blazor.Diagrams.Core.Events;
+using Blazor.Diagrams.Core.Geometry;
+using Blazor.Diagrams.Core.Models;
+using Blazor.Diagrams.Core.Positions.Resizing;
+using FluentAssertions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Blazor.Diagrams.Core.Tests.Positions.Resizing
+{
+ public class TopRightResizerProviderTests
+ {
+ [Fact]
+ public void DragResizer_ShouldResizeNode()
+ {
+ // setup
+ var diagram = new TestDiagram();
+ diagram.SetContainer(new Rectangle(0, 0, 1000, 400));
+ var node = new NodeModel(position: new Point(0, 0));
+ node.Size = new Size(100, 200);
+ var control = new ResizeControl(new TopRightResizerProvider());
+ diagram.Controls.AddFor(node).Add(control);
+ diagram.SelectModel(node, false);
+
+ // before resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(100);
+ node.Size.Height.Should().Be(200);
+
+ // resize
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ control.OnPointerDown(diagram, node, eventArgs);
+ eventArgs = new PointerEventArgs(10, 15, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+
+ // after resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(15);
+ node.Size.Width.Should().Be(110);
+ node.Size.Height.Should().Be(185);
+ }
+
+ [Fact]
+ public void DragResizer_SmallerThanMinSize_SetsNodeToMinSize()
+ {
+ // setup
+ var diagram = new TestDiagram();
+ diagram.SetContainer(new Rectangle(0, 0, 1000, 400));
+ var node = new NodeModel(position: new Point(0, 0));
+ node.Size = new Size(100, 200);
+ var control = new ResizeControl(new TopRightResizerProvider());
+ diagram.Controls.AddFor(node).Add(control);
+ diagram.SelectModel(node, false);
+
+ // before resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(0);
+ node.Size.Width.Should().Be(100);
+ node.Size.Height.Should().Be(200);
+
+ // resize
+ var eventArgs = new PointerEventArgs(0, 0, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ control.OnPointerDown(diagram, node, eventArgs);
+ eventArgs = new PointerEventArgs(-99, 199, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+ eventArgs = new PointerEventArgs(-300, 300, 0, 0, false, false, false, 1, 1, 1, 1, 1, 1, "arrow", true);
+ diagram.TriggerPointerMove(null, eventArgs);
+
+ // after resize
+ node.Position.X.Should().Be(0);
+ node.Position.Y.Should().Be(199);
+ node.Size.Width.Should().Be(0);
+ node.Size.Height.Should().Be(0);
+ }
+ }
+}
diff --git a/tests/Blazor.Diagrams.Tests/Components/Controls/ResizeControlWidgetTests.cs b/tests/Blazor.Diagrams.Tests/Components/Controls/ResizeControlWidgetTests.cs
new file mode 100644
index 000000000..bf51e541c
--- /dev/null
+++ b/tests/Blazor.Diagrams.Tests/Components/Controls/ResizeControlWidgetTests.cs
@@ -0,0 +1,25 @@
+using Blazor.Diagrams.Components.Controls;
+using Blazor.Diagrams.Core.Controls.Default;
+using Blazor.Diagrams.Core.Positions.Resizing;
+using Bunit;
+using Moq;
+using Xunit;
+
+namespace Blazor.Diagrams.Tests.Components.Controls
+{
+ public class ResizeControlWidgetTests
+ {
+ [Fact]
+ public void ShouldRenderDiv()
+ {
+ using var ctx = new TestContext();
+ var providerMock = Mock.Of();
+
+ var cut = ctx.RenderComponent(parameters =>
+ parameters.Add(w => w.Control, new ResizeControl(providerMock))
+ );
+
+ cut.MarkupMatches("");
+ }
+ }
+}