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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions examples/FluentUI.Demo.Shared/Microsoft.Fast.Components.FluentUI.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions examples/FluentUI.Demo.Shared/Pages/Drag/DragDropPage.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@page "/Drag"
@using FluentUI.Demo.Shared.Pages.Drag.Examples;

<h1>Drag and Drop</h1>


<p>A web component implementation of a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API" target="_blank" rel="noopener noreferrer">HTML Drag and Drop API</a>.</p>

<p>
The user may select draggable elements with a mouse, drag those elements to a droppable element,
and drop them by releasing the mouse button. A translucent representation of the draggable elements
follows the pointer during the drag operation.
</p>

<h2>Examples</h2>

<DemoSection Title="Usage examples" Component="@typeof(DragDropBasic)"></DemoSection>

<h2>Documentation</h2>

<ApiDocumentation Component="typeof(FluentDragContainer<>)" InstanceType="typeof(object)" GenericLabel="TItem" />
<ApiDocumentation Component="typeof(FluentDropZone<>)" InstanceType="typeof(object)" GenericLabel="TItem" />
<ApiDocumentation Component="typeof(FluentDragEventArgs<>)" InstanceType="typeof(object)" GenericLabel="TItem" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<FluentDragContainer TItem="string"
OnDragEnter="@(e => DemoLogger.WriteLine($"{e.Source.Id} is entered in {e.Target.Id}"))"
OnDragLeave="@(e => DemoLogger.WriteLine($"{e.Source.Id} has left {e.Target.Id}"))"
OnDropEnd="@(e => DemoLogger.WriteLine($"{e.Source.Id} dropped in {e.Target.Id}"))">
<FluentStack>
<FluentDropZone Id="Item1" Draggable="true" Droppable="true">
<div style="width: 50px; height: 50px; background-color: pink;">
Item 1
</div>
</FluentDropZone>
<FluentDropZone Id="Item2" Draggable="true" Droppable="true">
<div style="width: 50px; height: 50px; background-color: lightgreen;">
Item 2
</div>
</FluentDropZone>
</FluentStack>
</FluentDragContainer>
3 changes: 3 additions & 0 deletions examples/FluentUI.Demo.Shared/Shared/DemoNavMenuList.razor
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
<li>
<FluentAnchor Href="Divider" Appearance=Appearance.Neutral>Divider</FluentAnchor>
</li>
<li>
<FluentAnchor Href="Drag" Appearance=Appearance.Neutral>Drag</FluentAnchor>
</li>
<li>
<FluentAnchor Href="Emoji" Appearance=Appearance.Neutral>Emoji</FluentAnchor>
</li>
Expand Down
1 change: 1 addition & 0 deletions examples/FluentUI.Demo.Shared/Shared/DemoNavMenuTree.razor
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
<FluentNavMenuLink Href="/DataGrid" Icon="@FluentIcons.Grid" Text="Data grid" />
<FluentNavMenuLink Href="/Dialog" Icon="@FluentIcons.AppGeneric" Text="Dialog" />
<FluentNavMenuLink Href="/Divider" Icon="@FluentIcons.DividerShort" Text="Divider" />
<FluentNavMenuLink Href="/Drag" Icon="@FluentIcons.Drag" Text="Drag and Drop" />
<FluentNavMenuLink Href="/Emoji" Icon="@FluentIcons.EmojiSmileSlight" Text="Emoji" />
<FluentNavMenuLink Href="/Flipper" Icon="@FluentIcons.NavigationPlay" Text="Flipper" />
<FluentNavMenuLink Href="/Highlighter" Icon="@FluentIcons.Highlight" Text="Highlighter" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<FluentDragContainer TItem="string"
OnDragEnter="@(e => DemoLogger.WriteLine($"{e.Source.Id} is entered in {e.Target.Id}"))"
OnDragLeave="@(e => DemoLogger.WriteLine($"{e.Source.Id} has left {e.Target.Id}"))"
OnDropEnd="@(e => DemoLogger.WriteLine($"{e.Source.Id} dropped in {e.Target.Id}"))">
<FluentStack>
<FluentDropZone Id="Item1" Draggable="true" Droppable="true">
<div style="width: 50px; height: 50px; background-color: pink;">
Item 1
</div>
</FluentDropZone>
<FluentDropZone Id="Item2" Draggable="true" Droppable="true">
<div style="width: 50px; height: 50px; background-color: lightgreen;">
Item 2
</div>
</FluentDropZone>
</FluentStack>
</FluentDragContainer>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

<div>
<div draggable="true" blazor:ondragstart="1" blazor:ondragover="2" blazor:ondragenter="3" blazor:ondragleave="4" blazor:ondrop="5" blazor:ondrop:preventdefault="" b-9aejvkglh2="">Item 1</div>
<div blazor:ondragstart="6" blazor:ondragover="7" blazor:ondragover:preventdefault="" blazor:ondragenter="8" blazor:ondragenter:preventdefault="" blazor:ondragleave="9" blazor:ondragleave:preventdefault="" blazor:ondrop="10" blazor:ondrop:preventdefault="" b-9aejvkglh2="">Item 2</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Bunit;
using Xunit;

namespace Microsoft.Fast.Components.FluentUI.Tests.Drag
{
public class FluentDragTests : TestBase
{
[Fact]
public void FluentDrag_SimpleTest()
{
// Arrange
using var ctx = new TestContext();

// Act
var cut = ctx.RenderComponent<FluentDragContainer<int>>(parameters =>
{
parameters.Add(p => p.OnDragStart, (e) => { });
parameters.Add(p => p.OnDragEnter, (e) => { });
parameters.Add(p => p.OnDragOver, (e) => { });
parameters.Add(p => p.OnDragLeave, (e) => { });
parameters.Add(p => p.OnDropEnd, (e) => { });

parameters.AddChildContent<FluentDropZone<int>>(zone =>
{
zone.Add(p => p.Draggable, true);
zone.Add(p => p.Item, 1);
zone.AddChildContent("Item 1");

zone.Add(p => p.OnDragStart, (e) => { });
zone.Add(p => p.OnDragEnter, (e) => { });
zone.Add(p => p.OnDragOver, (e) => { });
zone.Add(p => p.OnDragLeave, (e) => { });
zone.Add(p => p.OnDropEnd, (e) => { });
});

parameters.AddChildContent<FluentDropZone<int>>(zone =>
{
zone.Add(p => p.Droppable, true);
zone.Add(p => p.Item, 2);
zone.AddChildContent("Item 2");

zone.Add(p => p.OnDragStart, (e) => { });
zone.Add(p => p.OnDragEnter, (e) => { });
zone.Add(p => p.OnDragOver, (e) => { });
zone.Add(p => p.OnDragLeave, (e) => { });
zone.Add(p => p.OnDropEnd, (e) => { });
});
});

// Assert
cut.Verify();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@namespace Microsoft.Fast.Components.FluentUI
@inherits FluentComponentBase

@typeparam TItem
@attribute [CascadingTypeParameter(nameof(TItem))]
<div id=@Id
class=@ClassValue
style=@StyleValue>
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// --------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// --------------------------------------------------------------

using Microsoft.AspNetCore.Components;
using Microsoft.Fast.Components.FluentUI.Utilities;

namespace Microsoft.Fast.Components.FluentUI;

/// <summary />
public partial class FluentDragContainer<TItem> : FluentComponentBase
{
/// <summary />
protected virtual string? ClassValue => new CssBuilder(Class).Build();

/// <summary />
protected virtual string? StyleValue => new StyleBuilder().AddStyle(Style).Build();

/// <summary>
/// Gets or sets the content to be rendered inside the component.
/// </summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }

/// <summary>
/// This event is fired when the user starts dragging an element.
/// </summary>
[Parameter]
public Action<FluentDragEventArgs<TItem>>? OnDragStart { get; set; }

/// <summary>
/// This event is fired when a dragged element enters a valid drop target.
/// </summary>
[Parameter]
public Action<FluentDragEventArgs<TItem>>? OnDragEnter { get; set; }

/// <summary>
/// This event is fired when an element is being dragged over a valid drop target.
/// </summary>
[Parameter]
public Action<FluentDragEventArgs<TItem>>? OnDragOver { get; set; }

/// <summary>
/// This event is fired when a dragged element leaves a valid drop target.
/// </summary>
[Parameter]
public Action<FluentDragEventArgs<TItem>>? OnDragLeave { get; set; }

/// <summary>
/// This event is fired when an element is dropped on a valid drop target.
/// </summary>
[Parameter]
public Action<FluentDragEventArgs<TItem>>? OnDropEnd { get; set; }

/// <summary>
/// property to keep the zone currently dragged.
/// </summary>
internal FluentDropZone<TItem>? StartedZone { get; private set; }

/// <summary />
internal void SetStartedZone(FluentDropZone<TItem>? value)
{
StartedZone = value;
StateHasChanged();
}
}
Loading