Apply BitFileUpload improvements (#12778) - #12779
Conversation
WalkthroughBitFileUpload now supports richer file metadata, configurable browser uploads, queued and retryable transfers, accessible rendering, customizable styling, expanded demos, and broader automated coverage. ChangesFileUpload improvements
Estimated code review effort: 5 (Critical) | ~120 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (7)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.ts (1)
388-416: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueOptional: cap the directory walk.
collectEntryrecurses without a depth or total-file limit, so a deeply nested (or cyclic, via symlinked directories on some platforms) dropped folder can recurse/iterate unbounded before the change event ever fires. A depth cap plus a max-files guard would bound the worst case.♻️ Sketch
- private static async collectEntry(entry: any, files: File[]): Promise<void> { + private static async collectEntry(entry: any, files: File[], depth: number = 0): Promise<void> { + if (depth > 32 || files.length >= 10000) return;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.ts` around lines 388 - 416, Optionally bound the directory traversal in FileUpload.collectEntry by adding a recursion-depth limit and a maximum collected-file limit. Propagate the current depth through recursive calls, stop walking when either limit is reached, and prevent files beyond the maximum from being added while preserving normal file and directory traversal behavior.src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.scss (1)
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStylelint flags the
.scssextension in@import.
scss/load-partial-extensionfires on this line. If the rest of the repo keeps the extension, consider disabling the rule instead of touching every file; otherwise drop the extension here.🎨 Extension-less import
-@import "../../../Styles/functions.scss"; +@import "../../../Styles/functions";🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.scss` at line 1, Update the FileUpload stylesheet import to comply with the repository’s Stylelint convention: either remove the .scss extension from the `@import` path or, if extensions are intentionally retained across the repository, disable scss/load-partial-extension for this file or rule configuration. Keep the referenced functions partial unchanged.Source: Linters/SAST tools
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor (1)
6-9: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider splitting the page description into shorter sentences.
Both the
PageOutletDescription(used as the meta description, where search engines truncate at ~160 chars) and theDemoPageDescriptionare single ~1000-word run-on blocks. A short lead sentence plus a few sentences would read better and make the meta description usable.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor` around lines 6 - 9, Shorten both the PageOutlet Description and DemoPage Description into concise, readable sentences. Make the PageOutlet text a brief meta description of roughly 160 characters, and replace the DemoPage run-on block with a short lead sentence followed by a few focused sentences covering the primary upload capabilities.src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/FileUpload/BitFileUploadTests.cs (2)
2673-2680: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
HttpClient/handler are never disposed.Each
SetupHttpClientcall leaks a handler for the lifetime of the test context. Registering it so bUnit's container owns disposal (or disposing in cleanup) keeps the suite tidy.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/FileUpload/BitFileUploadTests.cs` around lines 2673 - 2680, Update SetupHttpClient so the registered HttpClient and its FakeHttpMessageHandler are owned and disposed by the test context, using the existing service-registration or cleanup mechanism. Preserve the method’s current status-code setup and return value while ensuring repeated calls do not leak resources.
2119-2141: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftWall-clock
Task.Delaycouples these tests to internal timing thresholds.This test (and Lines 2154, 2445, 2568, plus the 300 ms
AutoRetryDelayrace at Lines 866-887) depends on real elapsed time exceeding the component's speed-sampling / repaint-throttling windows. On a loaded CI agent the ordering can invert, and the sleeps add seconds to the suite. If the component exposed the sampling interval / a time provider as an injectable seam, these could assert deterministically.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/FileUpload/BitFileUploadTests.cs` around lines 2119 - 2141, The upload timing tests, including BitFileUploadShouldMeasureTheSpeedAndTheRemainingTimeOfARunningUpload and the other referenced cases, rely on wall-clock delays and are flaky. Expose the component’s speed-sampling, repaint-throttling, and AutoRetryDelay timing through an injectable interval or time-provider seam, then update the tests to control and advance that seam deterministically instead of using Task.Delay or real-time races.src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor.cs (2)
1340-1344: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueZero-byte file renders as 100% before it is uploaded.
file.Size == 0 → 100makes a freshly selected empty file show a full progress bar. The component itself reports 0% for that case until it settles (seeBitFileUploadShouldNotReportAnEmptyFileAsUploadedBeforeItIsSentinBitFileUploadTests.cs), so the demo helper reads differently from the built-in view. Guarding only the division would keep them aligned. The same logic is duplicated in the embeddedexample27CsharpCode(Line 1948-1953).♻️ Proposed alignment
- if (file.Size == 0 || file.TotalUploadedSize >= file.Size) return 100; + if (file.Size == 0) return file.Status == BitFileUploadStatus.Completed ? 100 : 0; + + if (file.TotalUploadedSize >= file.Size) return 100;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor.cs` around lines 1340 - 1344, Update GetFileUploadPercent so a zero-byte file returns 0% until upload progress is reported, while preserving the 100% result for files whose uploaded size reaches or exceeds their total size and avoiding division by zero. Apply the same logic to the duplicated helper implementation in example27CsharpCode so both demo paths match the built-in component behavior.
1297-1338: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDrop the now-dead
Filesnull guards.
Filesis documented in this same file (Line 1151-1152) as non-nullIReadOnlyList<BitFileInfo>defaulting to[], sobitFileUpload.Files?... ?? trueandif (bitFileUpload.Files is null) return;can never trigger. Since these snippets are copied by users, the simpler form is worth showing (the embeddedexample27CsharpCodeat Line 1939-1946 carries the same guards).♻️ Proposed simplification
- private bool FileUploadIsEmpty() => !bitFileUpload.Files?.Any(f => f.Status != BitFileUploadStatus.Removed) ?? true; + private bool FileUploadIsEmpty() => !bitFileUpload.Files.Any(f => f.Status != BitFileUploadStatus.Removed); @@ - private async Task HandleUploadOnClick() - { - if (bitFileUpload.Files is null) return; - - await bitFileUpload.Upload(); - } + private Task HandleUploadOnClick() => bitFileUpload.Upload();🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor.cs` around lines 1297 - 1338, Remove the unreachable null guards for the non-null Files collection: simplify FileUploadIsEmpty to evaluate the collection directly without ?. or ?? true, and remove the bitFileUpload.Files null-return check from HandleUploadOnClick while preserving the upload call. Apply the same simplification to the duplicated example27CsharpCode snippet.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor.cs`:
- Around line 1664-1666: The headers conditional in the file upload logic is not
target-typed because it uses var with an empty collection expression. Declare
headers explicitly as Dictionary<string, string> while preserving the existing
null and copied-fileHeaders branches.
In `@src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.ts`:
- Around line 227-238: Update the paste handling in setupDragDrop and onPaste so
paste events are captured from window or document rather than only the
non-focusable dropZoneElement. Accept the clipboard files when the
focused/active target belongs to the upload component or its input, while
preserving the existing allowPaste and disabled checks, then register the
listener on the global target.
---
Nitpick comments:
In `@src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.scss`:
- Line 1: Update the FileUpload stylesheet import to comply with the
repository’s Stylelint convention: either remove the .scss extension from the
`@import` path or, if extensions are intentionally retained across the repository,
disable scss/load-partial-extension for this file or rule configuration. Keep
the referenced functions partial unchanged.
In `@src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.ts`:
- Around line 388-416: Optionally bound the directory traversal in
FileUpload.collectEntry by adding a recursion-depth limit and a maximum
collected-file limit. Propagate the current depth through recursive calls, stop
walking when either limit is reached, and prevent files beyond the maximum from
being added while preserving normal file and directory traversal behavior.
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor`:
- Around line 6-9: Shorten both the PageOutlet Description and DemoPage
Description into concise, readable sentences. Make the PageOutlet text a brief
meta description of roughly 160 characters, and replace the DemoPage run-on
block with a short lead sentence followed by a few focused sentences covering
the primary upload capabilities.
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor.cs`:
- Around line 1340-1344: Update GetFileUploadPercent so a zero-byte file returns
0% until upload progress is reported, while preserving the 100% result for files
whose uploaded size reaches or exceeds their total size and avoiding division by
zero. Apply the same logic to the duplicated helper implementation in
example27CsharpCode so both demo paths match the built-in component behavior.
- Around line 1297-1338: Remove the unreachable null guards for the non-null
Files collection: simplify FileUploadIsEmpty to evaluate the collection directly
without ?. or ?? true, and remove the bitFileUpload.Files null-return check from
HandleUploadOnClick while preserving the upload call. Apply the same
simplification to the duplicated example27CsharpCode snippet.
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/FileUpload/BitFileUploadTests.cs`:
- Around line 2673-2680: Update SetupHttpClient so the registered HttpClient and
its FakeHttpMessageHandler are owned and disposed by the test context, using the
existing service-registration or cleanup mechanism. Preserve the method’s
current status-code setup and return value while ensuring repeated calls do not
leak resources.
- Around line 2119-2141: The upload timing tests, including
BitFileUploadShouldMeasureTheSpeedAndTheRemainingTimeOfARunningUpload and the
other referenced cases, rely on wall-clock delays and are flaky. Expose the
component’s speed-sampling, repaint-throttling, and AutoRetryDelay timing
through an injectable interval or time-provider seam, then update the tests to
control and advance that seam deterministically instead of using Task.Delay or
real-time races.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 6779f57b-0544-42ac-82ba-3885a57364f2
📒 Files selected for processing (15)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileInfo.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.tssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUploadClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUploadJsRuntimeExtensions.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUploadStatus.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/_BitFileUploadItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/_BitFileUploadItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/FileUpload/BitFileUploadDemo.razor.scsssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/FileUpload/BitFileUploadTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
| var headers = fileHeaders is null | ||
| ? [] | ||
| : new Dictionary<string, string>(fileHeaders); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
C# conditional expression collection expression [] assigned to var CS0173 error
💡 Result:
The CS0173 error occurs when using a collection expression (e.g., [1][2]) within a conditional (ternary) operator assigned to a variable declared with 'var' because the compiler cannot infer a definitive type for the expression [1][2][3]. When you use 'var', there is no explicit target type to guide the compiler's type inference [1][4]. Because collection expressions are target-typed—meaning their type is determined by the variable or parameter they are assigned to—using them in a conditional expression without an explicit type leaves the compiler unable to resolve a common type between the two branches [1][5]. This frequently manifests when using spread operators (e.g.,.. condition? [...]: []) inside collection literals, where the compiler fails to propagate the outer collection's type to the inner ternary expression [2][3]. To resolve this issue, use one of the following approaches: 1. Explicitly specify the variable type: Instead of 'var', declare the variable with the concrete collection type [1]. // Change this: var list = condition? [1][2]: [4][3]; // To this: List list = condition? [1][2]: [4][3]; 2. Explicitly cast one or both branches: If you must use 'var', cast the expressions to the desired type so the compiler can determine a common type [1][6]. var list = condition? (IEnumerable)[1][2]: [4][3]; This error is a known limitation when the compiler lacks sufficient context to perform target-typing, especially in nested or implicitly typed scenarios [2][3]. In some cases, such as IDE suggestions for collection simplification, this behavior has been tracked and addressed in updates to the.NET SDK and Roslyn compiler [7].
Citations:
- 1: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0173
- 2: Empty collection literals type is undetermined inside spread ternary. dotnet/roslyn#69949
- 3: Collection expression target-type not being used for nested spread expressions. dotnet/roslyn#69277
- 4: Is there any other case of unknown _target type_ than when using
var? dotnet/docs#27515 - 5: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/collection-expressions
- 6: https://stackoverflow.com/questions/61632156/cs0173-compile-error-on-a-ternary-with-different-return-types
- 7: IDE0028 Collection Simplification for List<> with optional values causes CS0173 dotnet/roslyn#71527
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Candidate file =="
fd -a 'BitFileUpload\.razor\.cs$' . || true
echo "== Project files nearby =="
git ls-files | rg '(^|/)([^/]+\.csproj|Directory\.Build\.props|Directory\.Build\.targets)$' | head -100
echo "== File snippet and surrounding headers =="
file=$(fd 'BitFileUpload\.razor\.cs$' . | head -n1 || true)
if [ -n "${file:-}" ]; then
wc -l "$file"
sed -n '1630,1685p' "$file" | cat -n | sed "s/^/$file:/"
fi
echo "== Project files with target frameworks/SDKs =="
for f in $(git ls-files | rg '(^|/)([^/]+\.csproj|Directory\.Build\.props|Directory\.Build\.targets)$'); do
if rg -q 'net8|net9|LangVersion|ImplicitUsings|TargetFramework|TargetFrameworks' "$f"; then
echo "-- $f --"
sed -n '1,120p' "$f"
fi
done
echo "== Deterministic source probe for exact expression pattern =="
python3 - <<'PY'
from pathlib import Path
pats = [
"var headers = fileHeaders is null ? [] : new Dictionary<string, string>(fileHeaders);",
"var headers = fileHeaders is null\n ? []\n : new Dictionary<string, string>(fileHeaders);",
]
for p in pats:
print("exact:", p in pathlib.Path("src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor.cs").read_text() if pathlib.Path("src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor.cs").exists() else "missing")
PYRepository: bitfoundation/bitplatform
Length of output: 6076
🌐 Web query:
C# CS0176 ambiguous conversion conditional expression var collection expression [] CS9176 implicit type 'var' cannot be used in target-typed conversion in conditional expression
💡 Result:
The compiler errors you are encountering relate to two distinct features in C#: static member access and collection expressions. CS0176: Static member cannot be accessed with an instance reference This error occurs when you attempt to access a static member (method, property, or field) using an instance of a class rather than the class name itself [1][2][3]. Fix: Qualify the static member with the name of the class where it is defined [1][2]. Example: // Incorrect var instance = new MyClass; int val = instance.MyStaticMember; // Triggers CS0176 // Correct int val = MyClass.MyStaticMember; // Correct usage CS9176: There is no target type for the collection expression This error occurs because C# collection expressions (e.g., [1][2][3]) are target-typed, meaning they do not have a natural type on their own [4][5][6]. They require a specific destination type to be inferred by the compiler [4][7]. Because of this, you cannot assign a collection expression to a variable declared with 'var' [5][6][7]. Fix: Explicitly declare the type of the variable instead of using 'var' [5][6][7]. Example: // Incorrect var myCollection = [1][2][3]; // Triggers CS9176 // Correct int[] myCollection = [1][2][3]; // Explicit type provided List myOtherCollection = [1][2][3]; // Works with other compatible types Note: If you were attempting to use a conditional expression (ternary operator) involving 'var' and target-typed conversions, ensure that both branches of the conditional operator are explicitly typed or compatible with the target type, as 'var' cannot be used when the compiler cannot infer a common natural type for the expression [4][8][9].
Citations:
- 1: https://unity.huh.how/compiler-errors/cs0176
- 2: https://learn.microsoft.com/ru-ru/dotnet/csharp/misc/cs0176
- 3: https://github.com/thomaslevesque/GenerateCSharpErrors/blob/master/CSharpErrorsAndWarnings.md
- 4: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors
- 5: https://startdebugging.net/2023/08/c-12-collection-expressions/
- 6: https://devblogs.microsoft.com/dotnet/refactor-your-code-with-collection-expressions/
- 7: https://andrewlock.net/behind-the-scenes-of-collection-expressions-part-1-introducing-collection-expressions-in-csharp12/
- 8: Feedback on Collection Expressions dotnet/csharplang#7666
- 9: allow implicit target type deduction dotnet/roslyn#75217
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=$(fd 'BitFileUpload\.razor\.cs$' . | head -n1 || true)
echo "== $file line count and relevant snippet =="
if [ -n "${file:-}" ]; then
wc -l "$file"
sed -n '1645,1675p' "$file" | cat -n
fi
echo "== Direct project LangVersion/TargetFramework info =="
sed -n '1,120p' src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj
if [ -f src/BlazorUI/Directory.Build.props ]; then
sed -n '1,120p' src/BlazorUI/Directory.Build.props
else
sed -n '1,120p' Directory.Build.props
fi
git ls-files Directory.Build.props src/Directory.Build.props | while read -r f; do
echo "-- $f --"
sed -n '1,120p' "$f"
done
echo "== Relevant exact identifiers in source =="
rg -n "var headers = fileHeaders is null|fileHeaders is null \\? \\[\\]|Dicti|C#|csharp" src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj src/BlazorUI/Directory.Build.props src/Directory.Build.props Directory.Build.props src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor.cs 2>/dev/null || trueRepository: bitfoundation/bitplatform
Length of output: 8880
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for f in $(git ls-files | rg '(^|/)Bit\.Build\.props$'); do
echo "-- $f --"
sed -n '1,160p' "$f"
done
echo "== C# conditional collection-expression var probe (if dotnet is available) =="
if command -v dotnet >/dev/null 2>&1; then
tmp="$(mktemp -d)"
cat > "$tmp/Probe.csproj" <<'XML'
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<OutputType>Library</OutputType>
<ImplicitUsings>disable</ImplicitUsings>
</PropertyGroup>
</Project>
XML
cat > "$tmp/Probe.cs" <<'CS'
class Probe
{
static System.Collections.Generic.Dictionary<string, string>? Get(System.Collections.Generic.IReadOnlyDictionary<string, string>? fileHeaders = null)
{
var headers = fileHeaders is null
? []
: new System.Collections.Generic.Dictionary<string, string>(fileHeaders);
return null;
}
}
CS
dotnet build "$tmp/Probe.csproj"
else
echo "dotnet command not available"
fiRepository: bitfoundation/bitplatform
Length of output: 3803
Make the conditional collection expression target-typed.
This runs under <LangVersion>preview</LangVersion> with net8.0/net9.0/net10.0; the [] branch has no natural type while var leaves the ternary without a target type. Declare headers as Dictionary<string, string> or cast one branch so the compiler can resolve the collection expression.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor.cs`
around lines 1664 - 1666, The headers conditional in the file upload logic is
not target-typed because it uses var with an empty collection expression.
Declare headers explicitly as Dictionary<string, string> while preserving the
existing null and copied-fileHeaders branches.
| function onPaste(e: ClipboardEvent) { | ||
| inputElement.files = e.clipboardData!.files; | ||
| const event = new Event('change', { bubbles: true }); | ||
| inputElement.dispatchEvent(event); | ||
| if (!allowPaste || inputElement.disabled) return; | ||
| if (!e.clipboardData || e.clipboardData.files.length === 0) return; | ||
|
|
||
| setFiles(e.clipboardData.files); | ||
| } | ||
|
|
||
| dropZoneElement.addEventListener("dragenter", onDragHover); | ||
| dropZoneElement.addEventListener("dragover", onDragHover); | ||
| dropZoneElement.addEventListener("dragenter", onDragEnter); | ||
| dropZoneElement.addEventListener("dragover", onDragOver); | ||
| dropZoneElement.addEventListener("dragleave", onDragLeave); | ||
| dropZoneElement.addEventListener("drop", onDrop); | ||
| dropZoneElement.addEventListener('paste', onPaste); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd -H 'BitFileUpload.razor$' --exec cat -n {}Repository: bitfoundation/bitplatform
Length of output: 3751
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and inspect FileUpload TS/JS without executing repository code.
fd -H 'BitFileUpload\.(ts|js)$' --exec sh -c '
echo "===== $1 ====="
wc -l "$1"
sed -n "1,120p" "$1" | cat -n
sed -n "180,260p" "$1" | cat -n
' sh {}
# Search for focus/tabindex/contenteditable drop-zone references in FileUpload component files.
echo "===== focused search ====="
rg -n "dropZone|addPointerFocus|focusable|tabindex|contenteditable|allowPaste|paste" src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload || trueRepository: bitfoundation/bitplatform
Length of output: 16824
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "===== JSRuntime extension call ====="
sed -n '55,75p' src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUploadJsRuntimeExtensions.cs | cat -n
echo "===== C# setup/update/cleanup area ====="
sed -n '1120,1215p' src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor.cs | cat -n
sed -n '2048,2073p' src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor.cs | cat -n
echo "===== behavioral probe for paste target based on same DOM shape ====="
python3 - <<'PY'
from pathlib import Path
razor = Path('src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.razor').read_text()
for target in ['dropZoneElement', 'RootElement', 'inputElement']:
print(f"{target}: event listener attached in setupDragDrop? True" if target == "dropZoneElement" or target == "inputElement" else f"{target}: N/A")
lines = razor.splitlines()
# Print element attributes around RootElement/input.
for i, line in enumerate(lines):
if '`@ref`="RootElement"' in line or '`@ref`="_inputRef"' in line or 'tabindex' in line or 'contenteditable' in line:
print(f"line {i+1}: {line.strip()}")
PYRepository: bitfoundation/bitplatform
Length of output: 6974
Make paste work without requiring focus on the drop zone.
setupDragDrop attaches the paste listener to dropZoneElement, but BitFileUpload.razor passes RootElement and that markup is a plain non-focusable div; a paste to the hidden file input is not gated by !e.clipboardData.files.length or inputElement.disabled. Attach paste to window/document and fire setFiles when the active element is the upload component / input, or make this work from the actual focused target rather than assuming the drop zone receives the event.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileUpload/BitFileUpload.ts`
around lines 227 - 238, Update the paste handling in setupDragDrop and onPaste
so paste events are captured from window or document rather than only the
non-focusable dropZoneElement. Accept the clipboard files when the
focused/active target belongs to the upload component or its input, while
preserving the existing allowPaste and disabled checks, then register the
listener on the global target.
closes #12778
Summary by CodeRabbit
New Features
Bug Fixes
Documentation