diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj b/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj
index e7bb3e709a..24c07171ed 100644
--- a/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj
+++ b/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj
@@ -31,7 +31,6 @@
-
diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj b/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj
index 8b21c9d076..30b863a642 100644
--- a/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj
+++ b/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj
@@ -29,7 +29,13 @@
-
+
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfRenderMode.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfRenderMode.cs
index 96ac3692a5..259df816f9 100644
--- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfRenderMode.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfRenderMode.cs
@@ -15,7 +15,7 @@ public enum BitPdfRenderMode
/// a display list produced by the C# engine (the pdf.js model). Far fewer DOM
/// nodes; selection, search and links still work through the DOM text layer,
/// and zoom changes re-rasterize the canvases so text stays crisp. Requires
- /// JavaScript — a prerendered page shows a blank canvas until the client
+ /// JavaScript - a prerendered page shows a blank canvas until the client
/// loads.
///
Canvas,
diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.razor.cs
index a2bb262bb9..fafdf634cd 100644
--- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.razor.cs
+++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.razor.cs
@@ -134,7 +134,7 @@ public partial class BitPdfViewer : BitComponentBase
///
/// How painted text is emitted. merges
- /// same-line, same-style runs into one span per visual line — far fewer DOM
+ /// same-line, same-style runs into one span per visual line - far fewer DOM
/// nodes on per-glyph PDFs, with small intra-line position drift (explicit
/// kerning between runs is approximated). Rotated text always stays exact.
/// Default is .
@@ -1555,7 +1555,7 @@ private async Task RunSearchAsync()
// Search a per-page extracted-text index (built lazily) rather than the
// rendered DOM, so we only render the pages that actually contain matches
- // — a 500-page document with matches on 3 pages renders 3, not 500.
+ // - a 500-page document with matches on 3 pages renders 3, not 500.
_pageText ??= new string?[_document.PageCount];
string needle = _searchQuery;
int pageCount = _document.PageCount; // captured so the loop condition never reads a nulled _document
diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.scss
index cf2b6eac9f..44f5ea1324 100644
--- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.scss
+++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.scss
@@ -374,7 +374,7 @@
pointer-events: auto;
}
-/* Selection spans (data-bit-pdv-sel) hold the real Unicode but paint nothing — keep
+/* Selection spans (data-bit-pdv-sel) hold the real Unicode but paint nothing - keep
them transparent even while selected so only the highlight box shows and the
painted glyphs beneath stay visible through it. Without this the browser paints
the selected substitute glyphs opaque, stacking a wrong-font copy over the
diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.ts b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.ts
index 30e4afbbc8..c1a543311c 100644
--- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.ts
+++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.ts
@@ -23,7 +23,7 @@
}
}
- // Scrolls `target` into view by scrolling ONLY `container` — unlike
+ // Scrolls `target` into view by scrolling ONLY `container` - unlike
// scrollIntoView, which also scrolls every scrollable ancestor (including
// the hosting page, yanking the whole document around when the viewer is
// embedded mid-page).
@@ -468,7 +468,7 @@
clone.style.transformOrigin = "top left";
// A cloned
-
-
-
-
diff --git a/src/BlazorUI/Bit.BlazorUI.slnx b/src/BlazorUI/Bit.BlazorUI.slnx
index 85e580ac17..c2fbf75417 100644
--- a/src/BlazorUI/Bit.BlazorUI.slnx
+++ b/src/BlazorUI/Bit.BlazorUI.slnx
@@ -25,6 +25,7 @@
+
diff --git a/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj b/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj
index 61ef6e0f69..18dac2d8be 100644
--- a/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj
+++ b/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj
@@ -32,7 +32,13 @@
-
+
+
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj
index b7e47c30a0..bb31ffc5c1 100644
--- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj
@@ -2,11 +2,24 @@
net10.0
+ fcf350f4-eef5-430b-a5cb-144713a68932
+
+
+ true
+ false
+ $(DefineConstants);INCLUDE_WASM
+
+
+ truetruetrue
- fcf350f4-eef5-430b-a5cb-144713a68932
@@ -45,7 +58,8 @@
-
+
+
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor
index d385554583..4b0c25829e 100644
--- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor
@@ -1,9 +1,25 @@
@using Bit.BlazorUI.Demo.Client.Core.Shared
-@using Bit.BlazorUI.Demo.Client.Web.Components
+@using Bit.BlazorUI.Demo.Client.Web.Shared.Components
@{
+#if INCLUDE_WASM
+ var includeWasm = true;
+#else
+ var includeWasm = false;
+#endif
+#if DEBUG
+ // While debugging, boot from the framework-served blazor.web.js instead of the ES2019-transpiled
+ // bit.blazor.web.es2019.js variant, which is only needed to support legacy (non-ES2019+) browsers.
+ var blazorWebScript = "_framework/blazor.web.js";
+#else
+ var blazorWebScript = "_framework/bit.blazor.web.es2019.js";
+#endif
var noPrerender = HttpContext.Request.Query["no-prerender"].Count > 0;
- var renderMode = noPrerender ? AppRenderMode.NoPrerenderBlazorWebAssembly : AppRenderMode.Current;
+ // Without the WASM client in the build, WebAssembly render modes can't boot, so fall back to Blazor Server
+ // even where AppRenderMode.Current would pick WebAssembly (e.g. Release with IncludeWasm=false).
+ var renderMode = noPrerender
+ ? (includeWasm ? AppRenderMode.NoPrerenderBlazorWebAssembly : AppRenderMode.NoPrerenderBlazorServer)
+ : (includeWasm ? AppRenderMode.Current : AppRenderMode.BlazorServer);
}
@@ -71,9 +87,13 @@
-
-
-
+ @if (includeWasm)
+ {
+ @* These files live in the Client.Web project's wwwroot, so they only exist when the WASM client is part of the build. *@
+
+
+ }
+
@@ -95,10 +115,19 @@
@if (HttpContext.Request.IsLightHouseRequest() is false)
{
-
-
-
-
+ @if (includeWasm)
+ {
+
+
+
+
+ }
+ else
+ {
+ @* No WASM client in this build (Debug renders in Blazor Server mode), so boot blazor directly without Bswup/service-worker.
+ Uses the framework-served blazor.web.js (always available) rather than the ES2019 variant, which only ships in the WASM build. *@
+
+ }
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Extensions/IServiceCollectionExtensions.cs b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Extensions/IServiceCollectionExtensions.cs
index de2431e089..79f037c397 100644
--- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Extensions/IServiceCollectionExtensions.cs
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Extensions/IServiceCollectionExtensions.cs
@@ -23,9 +23,12 @@ public static void AddBlazor(this IServiceCollection services, IConfiguration co
};
});
- services.AddRazorComponents()
- .AddInteractiveServerComponents()
- .AddInteractiveWebAssemblyComponents();
+ var razorComponentsBuilder = services.AddRazorComponents()
+ .AddInteractiveServerComponents();
+
+#if INCLUDE_WASM
+ razorComponentsBuilder.AddInteractiveWebAssemblyComponents();
+#endif
services.AddClientWebServices();
}
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Program.cs b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Program.cs
index 6e567f2935..a9e82f87ee 100644
--- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Program.cs
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Program.cs
@@ -21,4 +21,10 @@
Bit.BlazorUI.Demo.Server.Startup.Middlewares.Use(app, builder.Environment, builder.Configuration);
-app.Run();
+// Start the host first so startup failures propagate immediately, then await the
+// SCSS watcher alongside shutdown (the watcher ties its own lifetime to app shutdown).
+await app.StartAsync();
+
+await Task.WhenAll(
+ app.WaitForShutdownAsync(),
+ Bit.BlazorUI.Demo.Server.Services.ScssCompilerService.WatchScssFiles(app) /* Development-only, no-op otherwise */);
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Properties/launchSettings.json b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Properties/launchSettings.json
index a92c102458..6bc92281cc 100644
--- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Properties/launchSettings.json
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Properties/launchSettings.json
@@ -10,17 +10,6 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
- },
- // This configuration allows debugging the Blazor Web Assembly
- "Bit.BlazorUI.Demo.Server-BlazorWebAssembly": {
- "commandName": "Project",
- "dotnetRunMessages": true,
- "launchBrowser": true,
- "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
- "applicationUrl": "http://localhost:5000;https://localhost:5001",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
}
}
}
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Services/ScssCompilerService.cs b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Services/ScssCompilerService.cs
new file mode 100644
index 0000000000..e06de5db37
--- /dev/null
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Services/ScssCompilerService.cs
@@ -0,0 +1,150 @@
+using System.Diagnostics;
+
+namespace Bit.BlazorUI.Demo.Server.Services;
+
+///
+/// Compiles SCSS files into CSS in real-time during development, no extensions required.
+/// Combined with the Watch items of the client/library csproj files, this lets dotnet watch
+/// hot-apply style changes to the browser without a rebuild.
+/// (Mirrors the ScssCompilerService of the bit Boilerplate template.)
+///
+public static class ScssCompilerService
+{
+ internal static async Task WatchScssFiles(WebApplication app)
+ {
+ if (app.Environment.IsDevelopment() is false)
+ return;
+
+ // A static type can't be an ILogger category, so create the logger by name via the factory.
+ var logger = app.Services.GetRequiredService().CreateLogger(nameof(ScssCompilerService));
+
+ var clientCorePath = Path.GetFullPath(Path.Combine(app.Environment.ContentRootPath, "../Client/Bit.BlazorUI.Demo.Client.Core"));
+
+ // The npm-installed dart-sass shim: sass.cmd on Windows, the sass shell script elsewhere.
+ var toolPath = Path.Combine(clientCorePath, OperatingSystem.IsWindows() ? "node_modules/.bin/sass.cmd" : "node_modules/.bin/sass");
+
+ if (File.Exists(toolPath) is false)
+ {
+ logger.LogWarning("{SassTool} not found. Run a build of Bit.BlazorUI.Demo.Client.Core once (npm install) to enable real-time scss compilation.", toolPath);
+ return;
+ }
+
+ // The sass process operates from the Client.Core directory. Folder:Folder pairs compile the
+ // isolated .razor.scss files in place; file:file pairs compile the global style bundles.
+ // The BlazorUI library styles are included as well, so editing a component's scss
+ // (e.g. BitButton.scss) instantly refreshes _content/Bit.BlazorUI/styles/*.css.
+ var sassPathsToWatch = new List
+ {
+ "Pages:Pages", "Components:Components", "Shared:Shared",
+ "Styles/app.scss:wwwroot/styles/app.css",
+ "../../../Bit.BlazorUI/Styles/bit.blazorui.scss:../../../Bit.BlazorUI/wwwroot/styles/bit.blazorui.css",
+ "../../../Bit.BlazorUI/Styles/Fluent/bit.blazorui.fluent.scss:../../../Bit.BlazorUI/wwwroot/styles/bit.blazorui.fluent.css",
+ "../../../Bit.BlazorUI/Styles/Fluent/bit.blazorui.fluent-dark.scss:../../../Bit.BlazorUI/wwwroot/styles/bit.blazorui.fluent-dark.css",
+ "../../../Bit.BlazorUI/Styles/Fluent/bit.blazorui.fluent-light.scss:../../../Bit.BlazorUI/wwwroot/styles/bit.blazorui.fluent-light.css",
+ "../../../Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss:../../../Bit.BlazorUI.Extras/wwwroot/styles/bit.blazorui.extras.css",
+ "../../../Bit.BlazorUI.Icons/Styles/bit.blazorui.icons.scss:../../../Bit.BlazorUI.Icons/wwwroot/styles/bit.blazorui.icons.css",
+ "../../../Bit.BlazorUI.Assets/Styles/bit.blazorui.assets.scss:../../../Bit.BlazorUI.Assets/wwwroot/styles/bit.blazorui.assets.css",
+ };
+
+ // dart-sass --watch only watches files that live under a watched root: the directory of each
+ // compiled entry point plus every --load-path directory. The library bundle entry points sit in
+ // each project's Styles/ folder, but their component partials are imported from a sibling
+ // Components/ tree (e.g. bit.blazorui.scss -> ... -> Styles/components.scss -> ../Components/Buttons/
+ // ActionButton/BitActionButton.scss). Those partials are outside every watched root, so editing one
+ // would NOT retrigger a compile and the css would go stale on hot reload. Adding each Components/
+ // folder as a load-path brings it under a watched root. Do not remove these: without them, editing a
+ // component's scss (BitButton.scss, etc.) silently stops hot-reloading its styles.
+ var loadPaths = new List
+ {
+ "--load-path=.",
+ "--load-path=../../../Bit.BlazorUI/Components",
+ "--load-path=../../../Bit.BlazorUI.Extras/Components",
+ };
+
+ // --no-source-map is required for style hot reload to work. dart-sass emits a *.css.map next to
+ // every *.css; dotnet watch watches those too and pushes each change to the browser. The injected
+ // aspnetcore-browser-refresh.js only does a live, in-place stylesheet swap for paths ending in
+ // ".css" - for any other static file (including ".css.map") it falls back to a full location.reload().
+ // With source maps on, every scss edit therefore fires a burst of full-page reloads that race with
+ // (and clobber) the clean css swaps, so the page never reliably shows the change. Dropping the maps
+ // leaves only ".css" updates, which hot-swap cleanly without reloading the page.
+ var command = $"{string.Join(" ", sassPathsToWatch)} {string.Join(" ", loadPaths)} --style compressed --no-source-map --silence-deprecation=import --update --watch --color";
+
+ // Scss watching is best-effort development tooling: any failure below must not fault this task,
+ // which would otherwise surface as an unobserved error in Program.cs's Task.WhenAll at shutdown.
+ Process? watchScssFilesProcess = null;
+ try
+ {
+ watchScssFilesProcess = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ WorkingDirectory = clientCorePath,
+ FileName = toolPath,
+ Arguments = command,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ CreateNoWindow = true
+ }
+ };
+
+ // Pass the sass output as a logging argument, not as the message template: scss snippets in
+ // sass's error output contain braces that ILogger would parse as format placeholders.
+ watchScssFilesProcess.OutputDataReceived += (_, e) => { if (string.IsNullOrEmpty(e.Data) is false) logger.LogInformation("{SassOutput}", e.Data); };
+ watchScssFilesProcess.ErrorDataReceived += (_, e) => { if (string.IsNullOrEmpty(e.Data) is false) logger.LogError("{SassError}", e.Data); };
+
+ logger.LogInformation("Running {toolPath} for {ProjectDirectory}", toolPath, clientCorePath);
+ if (watchScssFilesProcess.Start() is false)
+ {
+ logger.LogError("Failed to start {toolPath} for {ProjectDirectory}", toolPath, clientCorePath);
+ return;
+ }
+
+ watchScssFilesProcess.BeginOutputReadLine();
+ watchScssFilesProcess.BeginErrorReadLine();
+
+ // dart-sass --watch runs until killed, so tie its lifetime to the server: park until the
+ // host begins shutting down (dotnet watch restart, Ctrl+C), then the finally kills the whole
+ // process tree so no orphaned sass watcher survives - Program.cs awaits this task, so the
+ // cleanup always completes before the process exits. Waiting on ApplicationStopping (instead
+ // of app.WaitForShutdownAsync, which itself calls host.StopAsync) keeps Program.cs's
+ // WaitForShutdownAsync as the single code path that drives host shutdown.
+ try
+ {
+ await Task.Delay(Timeout.Infinite, app.Lifetime.ApplicationStopping);
+ }
+ catch (OperationCanceledException)
+ {
+ // The normal shutdown signal, not a failure.
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "Failed to watch scss files with {toolPath}", toolPath);
+ }
+ finally
+ {
+ KillSassProcess(watchScssFilesProcess, logger);
+ watchScssFilesProcess?.Dispose();
+ }
+ }
+
+ private static void KillSassProcess(Process? process, ILogger logger)
+ {
+ try
+ {
+ if (process is not null && process.HasExited is false)
+ {
+ process.Kill(entireProcessTree: true);
+ }
+ }
+ catch (InvalidOperationException)
+ {
+ // The process never started or is already disposed - nothing to terminate.
+ }
+ catch (Exception ex)
+ {
+ logger.LogWarning(ex, "Failed to terminate the scss watch process.");
+ }
+ }
+}
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Startup/Middlewares.cs b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Startup/Middlewares.cs
index 8f2d45d65a..8a5507a76b 100644
--- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Startup/Middlewares.cs
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Startup/Middlewares.cs
@@ -32,7 +32,9 @@ public static void Use(WebApplication app, IWebHostEnvironment env, IConfigurati
if (env.IsDevelopment())
{
+#if INCLUDE_WASM
app.UseWebAssemblyDebugging();
+#endif
}
else
{
@@ -107,7 +109,9 @@ public static void Use(WebApplication app, IWebHostEnvironment env, IConfigurati
// Handle the rest of requests with blazor
app.MapRazorComponents()
.AddInteractiveServerRenderMode()
+#if INCLUDE_WASM
.AddInteractiveWebAssemblyRenderMode()
+#endif
.AddAdditionalAssemblies(AssemblyLoadContext.Default.Assemblies.Where(asm => asm.GetName().Name?.Contains("Bit.BlazorUI.Demo") is true).Except([Assembly.GetExecutingAssembly()]).ToArray());
}
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj
index aaa56e0924..81c1d91d22 100644
--- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj
+++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj
@@ -39,7 +39,14 @@
-
+
+
+
@@ -90,7 +97,7 @@
-
+
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Services/AppRenderMode.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Services/AppRenderMode.cs
index 8f6ad26ba7..b85305a211 100644
--- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Services/AppRenderMode.cs
+++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Services/AppRenderMode.cs
@@ -9,10 +9,11 @@ public static class AppRenderMode
// .NET 10 resolves the earlier prerendering issues, so this is enabled to serve fully-formed HTML.
public static readonly bool PrerenderEnabled = true;
- private static IComponentRenderMode Auto => new InteractiveAutoRenderMode(PrerenderEnabled);
- private static IComponentRenderMode BlazorWebAssembly => new InteractiveWebAssemblyRenderMode(PrerenderEnabled);
- private static IComponentRenderMode BlazorServer => new InteractiveServerRenderMode(PrerenderEnabled);
- public static IComponentRenderMode NoPrerenderBlazorWebAssembly => new InteractiveWebAssemblyRenderMode(prerender: false);
+ public static IComponentRenderMode Auto { get; } = new InteractiveAutoRenderMode(PrerenderEnabled);
+ public static IComponentRenderMode BlazorWebAssembly { get; } = new InteractiveWebAssemblyRenderMode(PrerenderEnabled);
+ public static IComponentRenderMode BlazorServer { get; } = new InteractiveServerRenderMode(PrerenderEnabled);
+ public static IComponentRenderMode NoPrerenderBlazorWebAssembly { get; } = new InteractiveWebAssemblyRenderMode(prerender: false);
+ public static IComponentRenderMode NoPrerenderBlazorServer { get; } = new InteractiveServerRenderMode(prerender: false);
public static IComponentRenderMode Current => BuildConfiguration.IsDebug()
? BlazorServer /*For better development experience*/
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Bit.BlazorUI.Demo.Client.Web.Shared.csproj b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Bit.BlazorUI.Demo.Client.Web.Shared.csproj
new file mode 100644
index 0000000000..6c3e038796
--- /dev/null
+++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Bit.BlazorUI.Demo.Client.Web.Shared.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+
+ net10.0
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Components/AppBswupProgressBar.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Components/AppBswupProgressBar.razor
similarity index 94%
rename from src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Components/AppBswupProgressBar.razor
rename to src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Components/AppBswupProgressBar.razor
index 1b46bed028..ae9127dbae 100644
--- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Components/AppBswupProgressBar.razor
+++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Components/AppBswupProgressBar.razor
@@ -63,8 +63,8 @@