Skip to content

Commit 3194090

Browse files
committed
Use href instead of button
1 parent 26080ab commit 3194090

File tree

3 files changed

+21
-18
lines changed

3 files changed

+21
-18
lines changed

src/Components/Web.JS/src/Rendering/BinaryMedia.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,6 @@ export class BinaryMedia {
362362
}
363363
}
364364

365-
if (bytesRead === 0) {
366-
return false;
367-
}
368-
369365
const combined = this.combineChunks(chunks);
370366
const blob = new Blob([combined], { type: mimeType });
371367
const url = URL.createObjectURL(blob);

src/Components/Web/src/Media/FileDownload.cs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
namespace Microsoft.AspNetCore.Components.Web.Media;
88

99
/// <summary>
10-
/// A component that provides a button which, when clicked, downloads the provided media source
10+
/// A component that provides a link which, when activated (clicked), downloads the provided media source
1111
/// either via a save-as dialog or directly, using the same BinaryMedia pipeline as <see cref="Image"/> and <see cref="Video"/>.
1212
/// </summary>
1313
/// <remarks>
1414
/// Unlike <see cref="Image"/> and <see cref="Video"/>, this component does not automatically load the media.
15-
/// It defers loading until the user clicks the button. The stream is then materialized, optionally cached,
16-
/// and a client-side download is triggered.
15+
/// It defers loading until the user activates the link. The stream is then materialized (no caching is performed for downloads)
16+
/// and a client-side download is triggered. Developers can style the link as a button via CSS (e.g., with a framework class).
1717
/// </remarks>
1818
public sealed class FileDownload : MediaComponentBase
1919
{
@@ -23,12 +23,12 @@ public sealed class FileDownload : MediaComponentBase
2323
[Parameter, EditorRequired] public string FileName { get; set; } = default!;
2424

2525
/// <summary>
26-
/// Provides custom button text. Defaults to "Download".
26+
/// Provides custom link text. Defaults to "Download".
2727
/// </summary>
28-
[Parameter] public string? ButtonText { get; set; }
28+
[Parameter] public string? Text { get; set; }
2929

3030
/// <inheritdoc />
31-
protected override string TagName => "button";
31+
protected override string TagName => "a";
3232

3333
/// <inheritdoc />
3434
protected override string TargetAttributeName => string.Empty; // Not used – object URL not tracked for downloads.
@@ -40,13 +40,13 @@ public sealed class FileDownload : MediaComponentBase
4040
protected override bool ShouldAutoLoad => false;
4141

4242
/// <summary>
43-
/// Builds the button element with click handler wiring.
43+
/// Builds the anchor element with click handler wiring. The anchor is given an inert href (if one is not supplied)
44+
/// and the click default action is prevented so navigation does not occur. Styling into a button shape is left to the user.
4445
/// </summary>
4546
protected override void BuildRenderTree(RenderTreeBuilder builder)
4647
{
4748
builder.OpenElement(0, TagName);
4849

49-
// Removed object URL attribute emission; not needed for downloads.
5050
builder.AddAttribute(1, MarkerAttributeName, "");
5151

5252
if (IsLoading)
@@ -58,12 +58,19 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
5858
builder.AddAttribute(2, "data-state", "error");
5959
}
6060

61-
builder.AddAttribute(3, "type", "button");
61+
builder.AddAttribute(3, "href", "javascript:void(0)");
62+
6263
builder.AddAttribute(4, "onclick", EventCallback.Factory.Create(this, OnClickAsync));
63-
builder.AddMultipleAttributes(5, AdditionalAttributes);
64-
builder.AddElementReferenceCapture(6, elementReference => Element = elementReference);
6564

66-
builder.AddContent(7, ButtonText ?? "Download");
65+
if (AdditionalAttributes?.ContainsKey("href") == true)
66+
{
67+
AdditionalAttributes.Remove("href");
68+
}
69+
builder.AddMultipleAttributes(6, AdditionalAttributes);
70+
71+
builder.AddElementReferenceCapture(7, elementReference => Element = elementReference);
72+
73+
builder.AddContent(8, Text ?? "Download");
6774

6875
builder.CloseElement();
6976
}

src/Components/Web/src/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ Microsoft.AspNetCore.Components.Forms.InputHidden.Element.set -> void
88
Microsoft.AspNetCore.Components.Forms.InputHidden.InputHidden() -> void
99
Microsoft.AspNetCore.Components.Web.Internal.IInternalWebJSInProcessRuntime.InvokeJS(in Microsoft.JSInterop.Infrastructure.JSInvocationInfo invocationInfo) -> string!
1010
Microsoft.AspNetCore.Components.Web.Media.FileDownload
11-
Microsoft.AspNetCore.Components.Web.Media.FileDownload.ButtonText.get -> string?
12-
Microsoft.AspNetCore.Components.Web.Media.FileDownload.ButtonText.set -> void
1311
Microsoft.AspNetCore.Components.Web.Media.FileDownload.FileDownload() -> void
1412
Microsoft.AspNetCore.Components.Web.Media.FileDownload.FileName.get -> string!
1513
Microsoft.AspNetCore.Components.Web.Media.FileDownload.FileName.set -> void
14+
Microsoft.AspNetCore.Components.Web.Media.FileDownload.Text.get -> string?
15+
Microsoft.AspNetCore.Components.Web.Media.FileDownload.Text.set -> void
1616
Microsoft.AspNetCore.Components.Web.Media.Image
1717
Microsoft.AspNetCore.Components.Web.Media.Image.Image() -> void
1818
Microsoft.AspNetCore.Components.Web.Media.MediaComponentBase.CancelPreviousLoad() -> void

0 commit comments

Comments
 (0)