diff --git a/README.md b/README.md index 332181ba28..c76b22d3ea 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ![License](https://img.shields.io/github/license/bitfoundation/bitplatform.svg) ![Release CI Status](https://github.com/bitfoundation/bitplatform/actions/workflows/bit.ci.release.yml/badge.svg) ![NuGet version](https://img.shields.io/nuget/v/bit.blazorui.svg?logo=nuget) -[![Nuget downloads](https://img.shields.io/badge/packages_download-8.2M-blue.svg?logo=nuget)](https://www.nuget.org/profiles/bit-foundation) +[![Nuget downloads](https://img.shields.io/badge/packages_download-8.8M-blue.svg?logo=nuget)](https://www.nuget.org/profiles/bit-foundation) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/bitfoundation/bitplatform.svg)](http://isitmaintained.com/project/bitfoundation/bitplatform "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/bitfoundation/bitplatform.svg)](http://isitmaintained.com/project/bitfoundation/bitplatform "Percentage of issues still open") [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/bitfoundation/bitplatform) diff --git a/src/Besql/Bit.Besql/wwwroot/bit-besql.js b/src/Besql/Bit.Besql/wwwroot/bit-besql.js index 8517272e5c..4bcc3d7bc6 100644 --- a/src/Besql/Bit.Besql/wwwroot/bit-besql.js +++ b/src/Besql/Bit.Besql/wwwroot/bit-besql.js @@ -1,5 +1,5 @@ var BitBesql = window.BitBesql || {}; -BitBesql.version = window['bit-besql version'] = '10.4.1'; +BitBesql.version = window['bit-besql version'] = '10.4.2'; BitBesql.persist = async function besqlPersist(fileName) { diff --git a/src/Bit.Build.props b/src/Bit.Build.props index a0afbd7a9d..1a06617a3b 100644 --- a/src/Bit.Build.props +++ b/src/Bit.Build.props @@ -27,7 +27,7 @@ https://github.com/bitfoundation/bitplatform - 10.4.1 + 10.4.2 $(ReleaseVersion) https://github.com/bitfoundation/bitplatform/releases/tag/v-$(ReleaseVersion) $([System.String]::Copy($(ReleaseVersion)).Replace('-pre-', '.')) diff --git a/src/BlazorES2019/Bit.BlazorES2019/buildTransitive/Bit.BlazorES2019.targets b/src/BlazorES2019/Bit.BlazorES2019/buildTransitive/Bit.BlazorES2019.targets index 4259c5ce12..a5f4c51749 100644 --- a/src/BlazorES2019/Bit.BlazorES2019/buildTransitive/Bit.BlazorES2019.targets +++ b/src/BlazorES2019/Bit.BlazorES2019/buildTransitive/Bit.BlazorES2019.targets @@ -1,13 +1,13 @@ - - + + PreserveNewest PreserveNewest wwwroot\_framework\%(Filename)%(Extension) - - + + PreserveNewest PreserveNewest wwwroot\_framework\%(Filename)%(Extension) diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor index 43f8c2d2dc..a3e59460a4 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor @@ -26,7 +26,7 @@ TItem="(int RowIndex, TGridItem Data)" ItemsProvider="@ProvideVirtualizedItems" ItemContent="@(item => builder => RenderRow(builder, item.RowIndex, item.Data))" - Placeholder="@(placeholderContext => builder => RenderPlaceholderRow(builder, placeholderContext))" /> + Placeholder="@(placeholderContext => builder => RenderPlaceholderRow(builder, placeholderContext))" /> } else { @@ -71,6 +71,24 @@ } private void RenderRow(RenderTreeBuilder __builder, int rowIndex, TGridItem item) + { + if (RowTemplate is null) + { + RenderOriginalRow(__builder, rowIndex, item); + } + else + { + var args = new BitDataGridRowTemplateArgs + { + RowIndex = rowIndex, + RowItem = item, + OriginalRow = (builder) => RenderOriginalRow(builder, rowIndex, item) + }; + __builder.AddContent(0, RowTemplate(args)); + } + } + + private void RenderOriginalRow(RenderTreeBuilder __builder, int rowIndex, TGridItem item) { @foreach (var col in _columns) diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor.cs index 47ba97a8de..64ba6a6192 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor.cs @@ -173,6 +173,12 @@ public BitDataGrid() /// [Parameter] public Func? RowStyleSelector { get; set; } + /// + /// Optional template to customize row rendering. Receives with + /// set to the default row content; call it to render the original cells or replace with custom content. + /// + [Parameter] public RenderFragment>? RowTemplate { get; set; } + /// /// A theme name, with default value "default". This affects which styling rules match the table. /// diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGridRowTemplateArgs.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGridRowTemplateArgs.cs new file mode 100644 index 0000000000..724790881d --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGridRowTemplateArgs.cs @@ -0,0 +1,24 @@ +namespace Bit.BlazorUI; + +/// +/// Arguments passed to the render fragment. +/// +/// The type of data represented by each row in the grid. +public class BitDataGridRowTemplateArgs +{ + /// + /// A render fragment that produces the original row markup (the default <tr> with all column cells). + /// Render this in your custom template to include the default row, or omit it to replace entirely. + /// + public required RenderFragment OriginalRow { get; set; } + + /// + /// The 1-based row index used for accessibility (e.g. aria-rowindex). + /// + public int RowIndex { get; set; } + + /// + /// The data item for this row. + /// + public T RowItem { get; set; } = default!; +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/package-lock.json b/src/BlazorUI/Bit.BlazorUI.Extras/package-lock.json index 2053d773b0..6508d3a5d0 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/package-lock.json +++ b/src/BlazorUI/Bit.BlazorUI.Extras/package-lock.json @@ -5,15 +5,15 @@ "packages": { "": { "devDependencies": { - "esbuild": "0.27.2", + "esbuild": "0.27.3", "sass": "1.97.3", "typescript": "5.9.3" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", - "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", "cpu": [ "ppc64" ], @@ -28,9 +28,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", - "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", "cpu": [ "arm" ], @@ -45,9 +45,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", - "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", "cpu": [ "arm64" ], @@ -62,9 +62,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", - "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", "cpu": [ "x64" ], @@ -79,9 +79,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", - "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", "cpu": [ "arm64" ], @@ -96,9 +96,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", - "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", "cpu": [ "x64" ], @@ -113,9 +113,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", - "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", "cpu": [ "arm64" ], @@ -130,9 +130,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", - "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", "cpu": [ "x64" ], @@ -147,9 +147,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", - "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", "cpu": [ "arm" ], @@ -164,9 +164,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", - "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", "cpu": [ "arm64" ], @@ -181,9 +181,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", - "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", "cpu": [ "ia32" ], @@ -198,9 +198,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", - "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", "cpu": [ "loong64" ], @@ -215,9 +215,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", - "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", "cpu": [ "mips64el" ], @@ -232,9 +232,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", - "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", "cpu": [ "ppc64" ], @@ -249,9 +249,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", - "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", "cpu": [ "riscv64" ], @@ -266,9 +266,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", - "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", "cpu": [ "s390x" ], @@ -283,9 +283,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", - "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", "cpu": [ "x64" ], @@ -300,9 +300,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", - "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", "cpu": [ "arm64" ], @@ -317,9 +317,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", - "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", "cpu": [ "x64" ], @@ -334,9 +334,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", - "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", "cpu": [ "arm64" ], @@ -351,9 +351,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", - "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", "cpu": [ "x64" ], @@ -368,9 +368,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", - "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", "cpu": [ "arm64" ], @@ -385,9 +385,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", - "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", "cpu": [ "x64" ], @@ -402,9 +402,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", - "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", "cpu": [ "arm64" ], @@ -419,9 +419,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", - "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", "cpu": [ "ia32" ], @@ -436,9 +436,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", - "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", "cpu": [ "x64" ], @@ -784,9 +784,9 @@ } }, "node_modules/esbuild": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", - "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -797,32 +797,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" } }, "node_modules/fill-range": { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/package.json b/src/BlazorUI/Bit.BlazorUI.Extras/package.json index 272e232e53..5e8810bec4 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/package.json +++ b/src/BlazorUI/Bit.BlazorUI.Extras/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "esbuild": "0.27.2", + "esbuild": "0.27.3", "sass": "1.97.3", "typescript": "5.9.3" } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ActionButton/BitActionButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ActionButton/BitActionButton.razor.cs index 97b8768ed7..24e2eebb79 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ActionButton/BitActionButton.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ActionButton/BitActionButton.razor.cs @@ -98,8 +98,8 @@ public partial class BitActionButton : BitComponentBase /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OnIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: Icon="BitIconInfo.Fa("solid house")" - /// Material: Icon="BitIconInfo.Material("home")" /// Custom CSS: Icon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? Icon { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/Button/BitButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/Button/BitButton.razor.cs index 6cb034961f..baf556a38d 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/Button/BitButton.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/Button/BitButton.razor.cs @@ -125,8 +125,8 @@ public partial class BitButton : BitComponentBase /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OnIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: Icon="BitIconInfo.Fa("solid house")" - /// Material: Icon="BitIconInfo.Material("home")" /// Custom CSS: Icon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? Icon { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ButtonGroup/BitButtonGroupItem.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ButtonGroup/BitButtonGroupItem.cs index 3830f30e0d..d3261bc033 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ButtonGroup/BitButtonGroupItem.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ButtonGroup/BitButtonGroupItem.cs @@ -17,8 +17,8 @@ public class BitButtonGroupItem /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: Icon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: Icon = BitIconInfo.Fa("solid house") - /// Material: Icon = BitIconInfo.Material("home") /// Custom CSS: Icon = BitIconInfo.Css("my-icon-class") /// public BitIconInfo? Icon { get; set; } @@ -47,8 +47,8 @@ public class BitButtonGroupItem /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OffIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: OffIcon = BitIconInfo.Fa("solid house") - /// Material: OffIcon = BitIconInfo.Material("home") /// Custom CSS: OffIcon = BitIconInfo.Css("my-icon-class") /// public BitIconInfo? OffIcon { get; set; } @@ -77,8 +77,8 @@ public class BitButtonGroupItem /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OnIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: OnIcon = BitIconInfo.Fa("solid house") - /// Material: OnIcon = BitIconInfo.Material("home") /// Custom CSS: OnIcon = BitIconInfo.Css("my-icon-class") /// public BitIconInfo? OnIcon { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ButtonGroup/BitButtonGroupOption.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ButtonGroup/BitButtonGroupOption.cs index 80dc75ea53..51615525c4 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ButtonGroup/BitButtonGroupOption.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ButtonGroup/BitButtonGroupOption.cs @@ -22,8 +22,8 @@ public partial class BitButtonGroupOption : ComponentBase, IDisposable /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: Icon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: Icon="BitIconInfo.Fa("solid house")" - /// Material: Icon="BitIconInfo.Material("home")" /// Custom CSS: Icon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? Icon { get; set; } @@ -52,8 +52,8 @@ public partial class BitButtonGroupOption : ComponentBase, IDisposable /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OffIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: OffIcon="BitIconInfo.Fa("solid house")" - /// Material: OffIcon="BitIconInfo.Material("home")" /// Custom CSS: OffIcon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? OffIcon { get; set; } @@ -82,8 +82,8 @@ public partial class BitButtonGroupOption : ComponentBase, IDisposable /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OnIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: OnIcon="BitIconInfo.Fa("solid house")" - /// Material: OnIcon="BitIconInfo.Material("home")" /// Custom CSS: OnIcon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? OnIcon { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonItem.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonItem.cs index db554990d7..3c55c80d49 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonItem.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonItem.cs @@ -16,8 +16,8 @@ public class BitMenuButtonItem /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: Icon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: Icon = BitIconInfo.Fa("solid house") - /// Material: Icon = BitIconInfo.Material("home") /// Custom CSS: Icon = BitIconInfo.Css("my-icon-class") /// public BitIconInfo? Icon { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonOption.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonOption.cs index 34f07f5795..4d7072e599 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonOption.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonOption.cs @@ -21,8 +21,8 @@ public class BitMenuButtonOption : ComponentBase, IDisposable /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OnIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: Icon="BitIconInfo.Fa("solid house")" - /// Material: Icon="BitIconInfo.Material("home")" /// Custom CSS: Icon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? Icon { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ToggleButton/BitToggleButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ToggleButton/BitToggleButton.razor.cs index 066142b429..3b3088d984 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ToggleButton/BitToggleButton.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/ToggleButton/BitToggleButton.razor.cs @@ -60,8 +60,8 @@ public partial class BitToggleButton : BitComponentBase /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: Icon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: Icon="BitIconInfo.Fa("solid house")" - /// Material: Icon="BitIconInfo.Material("home")" /// Custom CSS: Icon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? Icon { get; set; } @@ -102,8 +102,8 @@ public partial class BitToggleButton : BitComponentBase /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OffIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: OffIcon="BitIconInfo.Fa("solid house")" - /// Material: OffIcon="BitIconInfo.Material("home")" /// Custom CSS: OffIcon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? OffIcon { get; set; } @@ -132,8 +132,8 @@ public partial class BitToggleButton : BitComponentBase /// For built-in Fluent UI icons, use instead. /// /// + /// Bootstrap: OnIcon="BitIconInfo.Bi("gear-fill")" /// FontAwesome: OnIcon="BitIconInfo.Fa("solid house")" - /// Material: OnIcon="BitIconInfo.Material("home")" /// Custom CSS: OnIcon="BitIconInfo.Css("my-icon-class")" /// [Parameter] public BitIconInfo? OnIcon { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInput.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInput.razor.cs index 33d41b9f82..1b4e6db7a1 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInput.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInput.razor.cs @@ -1,8 +1,9 @@ namespace Bit.BlazorUI; /// -/// A file input component that wraps the HTML file input element, enabling file selection with support for validation, drag-and-drop, and customization. -/// The selected files can be accessed and processed from the C# context. +/// BitFileInput is a file input component that wraps the HTML file input element and enables file selection +/// with support for validation, drag-and-drop, and customization. +/// The selected files' metadata and content can be accessed and processed from C# code. /// public partial class BitFileInput : BitComponentBase { @@ -18,85 +19,83 @@ public partial class BitFileInput : BitComponentBase /// - /// Specifies the accepted file types using MIME types or file extensions (e.g., "image/*", ".pdf,.doc"). - /// This value is applied to the HTML input element's accept attribute. + /// Accepted file types for the file browser using MIME types or file extensions (e.g., "image/*", ".pdf,.doc"). + /// Applied to the underlying HTML input element's accept attribute. /// [Parameter] public string? Accept { get; set; } /// - /// Specifies the allowed file extensions for validation (e.g., [".jpg", ".png", ".pdf"]). + /// Allowed file extensions for validation purposes (e.g., [".jpg", ".png", ".pdf"]). /// Use ["*"] to allow all file types. Files not matching these extensions will be marked as invalid. /// [Parameter] public IReadOnlyCollection AllowedExtensions { get; set; } = ["*"]; /// - /// When enabled, newly selected files are appended to the existing file list instead of replacing it. + /// Whether to append newly selected files to the existing file list instead of replacing it. /// [Parameter] public bool Append { get; set; } /// - /// When enabled, the file input is automatically reset (cleared) before opening the file browser dialog. - /// This allows selecting the same file multiple times consecutively. + /// Whether the file input is automatically reset (cleared) before opening the file browser dialog, + /// allowing the same file to be selected multiple times consecutively. /// [Parameter] public bool AutoReset { get; set; } /// - /// When enabled, the file list displaying selected files is hidden from the UI. + /// Whether to hide the file list that displays the selected files in the UI. /// [Parameter] public bool HideFileList { get; set; } /// - /// When enabled, the default browse button label is hidden from the UI. + /// Whether to hide the default browse button label from the UI. /// [Parameter] public bool HideLabel { get; set; } /// - /// The text displayed on the browse button. Defaults to "Browse" if not specified. + /// The text displayed on the browse button. Defaults to "Browse". /// [Parameter] public string? Label { get; set; } /// - /// A custom Razor template for the browse button area, allowing full customization of the file selection UI. + /// Custom Razor template for the browse button area, allowing full customization of the file selection trigger UI. /// [Parameter] public RenderFragment? LabelTemplate { get; set; } /// - /// The maximum allowed file size in bytes for validation. + /// Maximum allowed file size in bytes for validation. /// Files exceeding this size will be marked as invalid. Set to 0 for no size limit. /// [Parameter] public long MaxSize { get; set; } /// - /// The error message displayed when a file exceeds the maximum size limit. - /// Defaults to "The file size is larger than the max size" if not specified. + /// Custom error message displayed when a file exceeds the maximum size limit. + /// Defaults to "The file size is larger than the max size". /// [Parameter] public string? MaxSizeErrorMessage { get; set; } /// - /// When enabled, allows selecting multiple files simultaneously through the file browser dialog. + /// Whether to allow selecting multiple files simultaneously through the file browser dialog. /// [Parameter] public bool Multiple { get; set; } /// - /// The error message displayed when a file's extension is not in the allowed extensions list. - /// Defaults to "The file type is not allowed" if not specified. + /// Custom error message displayed when a file's extension is not in the allowed extensions list. + /// Defaults to "The file type is not allowed". /// [Parameter] public string? NotAllowedExtensionErrorMessage { get; set; } /// - /// Callback invoked when the file selection changes. - /// Receives an array of objects representing all selected files. + /// Callback invoked when the file selection changes, providing an array of representing all selected files. /// [Parameter] public EventCallback OnChange { get; set; } /// - /// When enabled, displays a remove button next to each file in the file list, - /// allowing users to individually remove files from the selection. + /// Whether to display a remove button next to each file in the file list, allowing individual file removal. /// [Parameter] public bool ShowRemoveButton { get; set; } /// - /// A custom Razor template for rendering individual file items in the file list. + /// Custom Razor template for rendering individual file items in the file list. /// Receives a context for each file. /// [Parameter] public RenderFragment? FileViewTemplate { get; set; } @@ -104,22 +103,21 @@ public partial class BitFileInput : BitComponentBase /// - /// Gets a read-only list of all currently selected files with their metadata and validation status. + /// A read-only list of all currently selected files with their metadata, validation status, and content. /// public IReadOnlyList Files => _files; /// - /// Gets the unique identifier of the underlying HTML file input element. + /// The unique identifier of the underlying HTML file input element. /// public string? InputId { get; private set; } /// - /// Programmatically opens the file browser dialog, allowing users to select files. - /// If is enabled, the input is reset before opening the dialog. + /// Opens the file browser dialog programmatically, allowing users to select files. + /// If is enabled, the input is reset before opening. /// - /// A task that completes when the browser dialog is opened. public async Task Browse() { if (IsEnabled is false) return; @@ -135,7 +133,6 @@ public async Task Browse() /// /// Clears all selected files and resets the file input to its initial state. /// - /// A task that completes when the reset operation finishes. public async Task Reset() { _files.Clear(); @@ -146,11 +143,22 @@ public async Task Reset() } /// - /// Removes one or more files from the selected files list. + /// Reads the content of the specified file from the browser and populates its property + /// with the byte array. Only reads valid and enabled files. /// - /// - /// The specific file to remove. If null, all files will be removed from the list. - /// + /// The file info whose content should be loaded. + public async Task ReadContentAsync(BitFileInputInfo fileInfo) + { + if (IsEnabled is false) return; + if (fileInfo.IsValid is false) return; + + fileInfo.Content = await _js.BitFileInputReadContent(UniqueId, fileInfo.FileId); + } + + /// + /// Removes a specific file from the selected files list, or clears all files when no file is specified. + /// + /// The file to remove, or null to remove all files. public void RemoveFile(BitFileInputInfo? fileInfo = null) { if (_files.Any() is false) return; @@ -234,7 +242,7 @@ private async Task HandleOnChange() _files.AddRange(newFiles); - await OnChange.InvokeAsync([.. _files]); + _ = OnChange.InvokeAsync([.. _files]); } private string GetFileElClass(bool isValid) diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInput.ts b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInput.ts index 9b7d24235d..82b73cb6de 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInput.ts +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInput.ts @@ -22,7 +22,7 @@ namespace BitBlazorUI { })); files.forEach((f) => { - const inputItem = new BitFileInputItem(id, f.file, f.index); + const inputItem = new BitFileInputItem(id, f.fileId, f.file, f.index); FileInput._fileInputs.push(inputItem); }); @@ -80,6 +80,16 @@ namespace BitBlazorUI { FileInput._fileInputs = FileInput._fileInputs.filter(f => f.id !== id); } + public static async readContent(id: string, fileId: string): Promise { + const item = FileInput._fileInputs.find(f => f.id === id && f.fileId === fileId); + if (!item) { + throw new Error(`File not found: ${fileId}`); + } + + const buffer = await item.file.arrayBuffer(); + return new Uint8Array(buffer); + } + public static reset(id: string, inputElement: HTMLInputElement) { FileInput.clear(id); inputElement.value = ''; @@ -88,11 +98,13 @@ namespace BitBlazorUI { class BitFileInputItem { id: string; + fileId: string; file: File; index: number; - constructor(id: string, file: File, index: number) { + constructor(id: string, fileId: string, file: File, index: number) { this.id = id; + this.fileId = fileId; this.file = file; this.index = index; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInputInfo.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInputInfo.cs index 7851451c5f..8426b65248 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInputInfo.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInputInfo.cs @@ -1,46 +1,52 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Bit.BlazorUI; /// -/// Represents metadata and validation information for a file selected through . +/// Represents metadata, validation state, and content of a file selected through . +/// Provides access to file properties such as name, size, and content type, as well as the file's byte array content. /// public class BitFileInputInfo { /// - /// Gets or sets the MIME content type of the selected file (e.g., "image/png", "application/pdf"). + /// The MIME content type of the file (e.g., "image/png", "application/pdf"). /// [JsonPropertyName("type")] public string ContentType { get; set; } = string.Empty; /// - /// Gets or sets the name of the selected file, including its extension. + /// The name of the file including its extension (e.g., "document.pdf"). /// [JsonPropertyName("name")] public string Name { get; set; } = string.Empty; /// - /// Gets or sets the size of the selected file in bytes. + /// The size of the file in bytes. /// [JsonPropertyName("size")] public long Size { get; set; } /// - /// Gets or sets the unique identifier (GUID) assigned to the selected file. + /// A unique identifier (GUID) assigned to the file upon selection, used to reference the file in JavaScript interop. /// [JsonPropertyName("fileId")] public string FileId { get; set; } = string.Empty; /// - /// Gets or sets the zero-based index of the file in the selection list. + /// The zero-based index of the file in the current selection list. /// [JsonPropertyName("index")] public int Index { get; set; } /// - /// Gets or sets the validation error message if the file failed validation. - /// This property is null when the file is valid. + /// The validation error message when the file has failed a validation check (e.g., size or extension). + /// This is null when the file is valid. /// [JsonIgnore] public string? Message { get; internal set; } /// - /// Gets or sets a value indicating whether the file passed all validation checks - /// (size constraints and allowed extensions). + /// Whether the file has passed all validation checks including size constraints and allowed extensions. /// [JsonIgnore] public bool IsValid { get; internal set; } = true; + + /// + /// The file content as a byte array, populated by calling . + /// This is null by default and only loaded on demand to avoid unnecessary memory usage. + /// + [JsonIgnore] public byte[]? Content { get; internal set; } } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInputJsRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInputJsRuntimeExtensions.cs index eab83735b0..e1b83cae24 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInputJsRuntimeExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/FileInput/BitFileInputJsRuntimeExtensions.cs @@ -2,36 +2,62 @@ namespace Bit.BlazorUI; +/// +/// Provides JavaScript interop extension methods for the component. +/// internal static class BitFileInputJsRuntimeExtensions { + /// + /// Initializes the file input on the JavaScript side, registers selected files, and returns their metadata. + /// [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitFileInputInfo))] internal static ValueTask BitFileInputSetup(this IJSRuntime jsRuntime, - string id, - ElementReference element, - bool append) + string id, + ElementReference element, + bool append) { - return jsRuntime.InvokeAsync("BitBlazorUI.FileInput.setup", id, element, append); + return jsRuntime.Invoke("BitBlazorUI.FileInput.setup", id, element, append); } + /// + /// Sets up drag-and-drop and paste event handlers on the drop zone element to forward files to the input element. + /// internal static ValueTask BitFileInputSetupDragDrop(this IJSRuntime jsRuntime, ElementReference dragDropZoneElement, ElementReference inputFileElement) { - return jsRuntime.InvokeAsync("BitBlazorUI.FileInput.setupDragDrop", dragDropZoneElement, inputFileElement); + return jsRuntime.Invoke("BitBlazorUI.FileInput.setupDragDrop", dragDropZoneElement, inputFileElement); } + /// + /// Programmatically triggers a click on the file input element to open the file browser dialog. + /// internal static ValueTask BitFileInputBrowse(this IJSRuntime jsRuntime, ElementReference inputFileElement) { - return jsRuntime.InvokeVoidAsync("BitBlazorUI.FileInput.browse", inputFileElement); + return jsRuntime.InvokeVoid("BitBlazorUI.FileInput.browse", inputFileElement); } + /// + /// Removes all stored file references for the given component from the JavaScript side. + /// internal static ValueTask BitFileInputClear(this IJSRuntime jsRuntime, string id) { - return jsRuntime.InvokeVoidAsync("BitBlazorUI.FileInput.clear", id); + return jsRuntime.InvokeVoid("BitBlazorUI.FileInput.clear", id); } + /// + /// Clears all stored file references and resets the file input element's value. + /// internal static ValueTask BitFileInputReset(this IJSRuntime jsRuntime, string id, ElementReference inputFileElement) { - return jsRuntime.InvokeVoidAsync("BitBlazorUI.FileInput.reset", id, inputFileElement); + return jsRuntime.InvokeVoid("BitBlazorUI.FileInput.reset", id, inputFileElement); + } + + /// + /// Reads the content of a specific file from the JavaScript file store and returns it as a byte array. + /// + internal static ValueTask BitFileInputReadContent(this IJSRuntime jsRuntime, string id, string fileId) + { + return jsRuntime.Invoke("BitBlazorUI.FileInput.readContent", id, fileId); } } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor index e605ac727d..2bae936420 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor @@ -7,18 +7,9 @@ style="@StyleBuilder.Value" class="@ClassBuilder.Value" dir="@Dir?.ToString().ToLower()"> - @if (IconName.HasValue() || Label.HasValue() || LabelTemplate is not null) + @if (Label.HasValue() || LabelTemplate is not null) {
- @if (IconName.HasValue()) - { -