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
Original file line number Diff line number Diff line change
Expand Up @@ -6337,6 +6337,11 @@
Gets or sets a value indicating whether the element is checked.
</summary>
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentMenuItem.KeepOpen">
<summary>
Gets or sets a value indicates whether the FluentMenu should remain open after an action.
</summary>
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentMenuItem.ChildContent">
<summary>
Gets or sets the content to be rendered inside the component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Accept="image/*"
@bind-ProgressPercent="@ProgressPercent"
OnCompleted="@OnCompletedAsync"
Style="height: 300px; border: 1px dashed var(--accent-fill-rest);">
Style="height: 300px;">
<ChildContent>
<label for="my-file-uploader">
<FluentIcon Value="@(new @Icons.Regular.Size24.ArrowUpload())" />
Expand Down
14 changes: 4 additions & 10 deletions src/Core/Components/InputFile/FluentInputFile.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@

<div class="@ClassValue"
style="@StyleValue"
drop-files="@DropOver"
disabled="@Disabled"
@ondragenter="@(e => DropOver = true)"
@ondragenter:stopPropagation
@ondragover="@(e => DropOver = true)"
@ondragover:stopPropagation
@ondragleave="@(e => DropOver = false)"
@ondragleave:stopPropagation
@ondragend="@(e => DropOver = false)">
@ref="@_containerElement">

<div class="inputfile-content" style="z-index: @(DropOver ? null : 999)">
<div class="inputfile-content" style="@($"z-index: {ZIndex.InputFileDropZone + 1}")">

@ChildContent

Expand All @@ -31,8 +24,9 @@
</div>
</div>

<div style="grid-column: 1; grid-row: 1; @(DropOver ? $"z-index: {ZIndex.InputFileDropZone}" : null)">
<div style="grid-column: 1; grid-row: 1; ">
<InputFile OnChange="OnUploadFilesHandlerAsync"
@ref="@_inputFile"
id="@Id"
multiple=@Multiple
accept="@Accept"
Expand Down
32 changes: 27 additions & 5 deletions src/Core/Components/InputFile/FluentInputFile.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
namespace Microsoft.FluentUI.AspNetCore.Components;

/// <summary />
public partial class FluentInputFile : FluentComponentBase
public partial class FluentInputFile : FluentComponentBase, IAsyncDisposable
{
private ElementReference? _containerElement;
private InputFile? _inputFile;
private IJSObjectReference? _containerInstance;

public static string ResourceLoadingBefore = "Loading...";
public static string ResourceLoadingCompleted = "Completed";
public static string ResourceLoadingCanceled = "Canceled";
Expand Down Expand Up @@ -193,11 +197,16 @@ public async Task ShowFilesDialogAsync()
/// <summary />
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender && !string.IsNullOrEmpty(AnchorId))
if (firstRender)
{
Module ??= await JSRuntime.InvokeAsync<IJSObjectReference>("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration));

await Module.InvokeVoidAsync("attachClickHandler", AnchorId, Id);
if (!string.IsNullOrEmpty(AnchorId))
{
await Module.InvokeVoidAsync("attachClickHandler", AnchorId, Id);
}

_containerInstance = await Module.InvokeAsync<IJSObjectReference>("initializeFileDropZone", _containerElement, _inputFile!.Element);
}
}

Expand All @@ -209,8 +218,6 @@ protected async Task OnUploadFilesHandlerAsync(InputFileChangeEventArgs e)
throw new ApplicationException($"The maximum number of files accepted is {MaximumFileCount}, but {e.FileCount} were supplied.");
}

DropOver = false;

// Use the native Blazor event
if (OnInputFileChange.HasDelegate)
{
Expand Down Expand Up @@ -405,4 +412,19 @@ private async Task UpdateProgressAsync(int percent, string title)
ProgressTitle = title;
}
}

// Unregister the drop zone events
public async ValueTask DisposeAsync()
{
if (_containerInstance != null)
{
await _containerInstance.InvokeVoidAsync("dispose");
await _containerInstance.DisposeAsync();
}

if (Module != null)
{
await Module.DisposeAsync();
}
}
}
4 changes: 3 additions & 1 deletion src/Core/Components/InputFile/FluentInputFile.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
display: grid;
grid-gap: 10px;
background-color: var(--neutral-fill-hover);
border: 1px dashed var(--accent-fill-rest);
}

.fluent-inputfile-container[drop-files] {
border: 2px dashed var(--accent-foreground-focus);
border: 1px solid var(--accent-fill-rest);
}

.fluent-inputfile-container .inputfile-content {
grid-column: 1;
grid-row: 1;
Expand Down
51 changes: 50 additions & 1 deletion src/Core/Components/InputFile/FluentInputFile.razor.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function raiseFluentInputFile(fileInputId) {
export function raiseFluentInputFile(fileInputId) {
var item = document.getElementById(fileInputId);
if (!!item) {
item.click();
Expand All @@ -21,3 +21,52 @@ export function previewImage(inputElem, index, imgElem) {
imgElem.src = url;
imgElem.alt = inputElem.files[index].name;
}

export function initializeFileDropZone(containerElement, inputFile) {
function onDragHover(e) {
e.preventDefault();
containerElement.setAttribute("drop-files", "true");
}

function onDragLeave(e) {
e.preventDefault();
containerElement.removeAttribute("drop-files");
}

// Handle the paste and drop events
function onDrop(e) {
e.preventDefault();
containerElement.removeAttribute("drop-files");

// Set the files property of the input element and raise the change event
inputFile.files = e.dataTransfer.files;
const event = new Event('change', { bubbles: true });
inputFile.dispatchEvent(event);
}

// We'll implement this later
//function onPaste(e) {
// // Set the files property of the input element and raise the change event
// inputFile.files = e.clipboardData.files;
// const event = new Event('change', { bubbles: true });
// inputFile.dispatchEvent(event);
//}

// Register all events
containerElement.addEventListener("dragenter", onDragHover);
containerElement.addEventListener("dragover", onDragHover);
containerElement.addEventListener("dragleave", onDragLeave);
containerElement.addEventListener("drop", onDrop);
//containerElement.addEventListener('paste', onPaste);

// The returned object allows to unregister the events when the Blazor component is destroyed
return {
dispose: () => {
containerElement.removeEventListener('dragenter', onDragHover);
containerElement.removeEventListener('dragover', onDragHover);
containerElement.removeEventListener('dragleave', onDragLeave);
containerElement.removeEventListener("drop", onDrop);
//containerElement.removeEventListener('paste', onPaste);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

<div class="fluent-inputfile-container" blazor:ondragenter="1" blazor:ondragenter:stoppropagation="" blazor:ondragover="2" blazor:ondragover:stoppropagation="" blazor:ondragleave="3" blazor:ondragleave:stoppropagation="" blazor:ondragend="4" b-72uj7bp8pi="">
<div class="inputfile-content" style="z-index: 999" b-72uj7bp8pi="">
Sample description
<div class="inputfile-progress" style="visibility: hidden;" b-72uj7bp8pi="">
<fluent-progress min="0" max="100" value="0" blazor:elementreference="xxx"></fluent-progress>
<br b-72uj7bp8pi="">
<div class="inputfile-content" style="z-index: 991" b-72uj7bp8pi="">
Sample description
<div class="inputfile-progress" style="visibility: hidden;" b-72uj7bp8pi="">
<fluent-progress min="0" max="100" value="0" blazor:elementreference="xxx"></fluent-progress>
<br b-72uj7bp8pi="">
</div>
</div>
</div>
<div style="grid-column: 1; grid-row: 1; " b-72uj7bp8pi="">
<input id="xxx" multiple="" accept="image/*" type="file" blazor:elementreference="xxx">
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<div class="fluent-inputfile-container" disabled="" blazor:ondragenter="1" blazor:ondragenter:stoppropagation="" blazor:ondragover="2" blazor:ondragover:stoppropagation="" blazor:ondragleave="3" blazor:ondragleave:stoppropagation="" blazor:ondragend="4" b-72uj7bp8pi="">
<div class="inputfile-content" style="z-index: 999" b-72uj7bp8pi="">
<div class="inputfile-content" style="z-index: 991" b-72uj7bp8pi="">
Sample description
<div class="inputfile-progress" style="visibility: hidden;" b-72uj7bp8pi="">
<fluent-progress min="0" max="100" value="0" blazor:elementreference="xxx"></fluent-progress>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

<div class="fluent-inputfile-container" blazor:ondragenter="1" blazor:ondragenter:stoppropagation="" blazor:ondragover="2" blazor:ondragover:stoppropagation="" blazor:ondragleave="3" blazor:ondragleave:stoppropagation="" blazor:ondragend="4" b-72uj7bp8pi="">
<div class="inputfile-content" style="z-index: 999" b-72uj7bp8pi="">Sample description
<div class="inputfile-progress" style="" b-72uj7bp8pi="">ProgressFileDetails { Index = 0, Name = , Percentage = 0 }</div>
</div>
<div class="inputfile-content" style="z-index: 991" b-72uj7bp8pi="">
Sample description
<div class="inputfile-progress" style="" b-72uj7bp8pi="">ProgressFileDetails { Index = 0, Name = , Percentage = 0 }</div>
</div>
<div style="grid-column: 1; grid-row: 1; " b-72uj7bp8pi="">
<input id="xxx" accept="" type="file" blazor:elementreference="xxx">
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@

<div class="fluent-inputfile-container" blazor:ondragenter="1" blazor:ondragenter:stoppropagation="" blazor:ondragover="2" blazor:ondragover:stoppropagation="" blazor:ondragleave="3" blazor:ondragleave:stoppropagation="" blazor:ondragend="4" b-72uj7bp8pi="">
<div class="inputfile-content" style="z-index: 999" b-72uj7bp8pi="">Sample description
<div class="inputfile-progress" style="visibility: visible;" b-72uj7bp8pi="">
<fluent-progress min="0" max="100" value="100" blazor:elementreference=""></fluent-progress>
<br b-72uj7bp8pi="">Completed</div>
</div>
<div class="inputfile-content" style="z-index: 991" b-72uj7bp8pi="">
Sample description
<div class="inputfile-progress" style="visibility: visible;" b-72uj7bp8pi="">
<fluent-progress min="0" max="100" value="100" blazor:elementreference=""></fluent-progress>
<br b-72uj7bp8pi="">Completed
</div>
</div>
<div style="grid-column: 1; grid-row: 1; " b-72uj7bp8pi="">
<input id="xxx" multiple="" accept="image/*" type="file" blazor:elementreference="">
</div>
</div>
</div>
1 change: 1 addition & 0 deletions tests/Core/InputFile/FluentInputFileTests.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{
public FluentInputFileTests()
{
JSInterop.Mode = JSRuntimeMode.Loose;
Services.AddSingleton(LibraryConfiguration.ForUnitTests);
}

Expand Down