You can find the sample source-code of the above video
- here.
+ here.
Supported browsers
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Besql/Besql02InstallPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Besql/Besql02InstallPage.razor
index ac71c883d29..4b78b5f5ca4 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Besql/Besql02InstallPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Besql/Besql02InstallPage.razor
@@ -3,10 +3,10 @@
+ Description="Install the Bit.Besql NuGet package to use Entity Framework Core with SQLite in your Blazor WebAssembly apps." />
- Install bit Besql
+ Install bit Besql
How to install the bit Besql?
@@ -28,7 +28,7 @@
Open your Visual Studio's Manage NuGet Packages window and install the Bit.Besql package:
-
+
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Besql/Besql03UsagePage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Besql/Besql03UsagePage.razor
index ef908a5c779..183323cb81e 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Besql/Besql03UsagePage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Besql/Besql03UsagePage.razor
@@ -3,10 +3,10 @@
+ Description="Use bit Besql in three steps: add the script tag, register the services, then use EF Core's SQLite provider with IDbContextFactory in the browser." />
- Using bit Besql
+ Using bit Besql
How to use the bit Besql?
@@ -38,4 +38,4 @@
- Bswup
-
- Blazor Service Worker Update Progress utilities
-
-
- bit Bswup is a set of tools that assists developers in making the most out of the
- Service Worker when building PWAs with Blazor.
- It utilizes the Service Worker's events to handle Installing and Updating the app
- as fast and smooth as possible while minimizing the download size.
-
- This unique tool harnesses the power of Progressive Web Apps (PWA) within the innovative
- new structure of dotnet 8. By amalgamating pre-rendering techniques reminiscent of renowned
- platforms like GitHub, Reddit, and Facebook, Bswup ensures an exceptional user experience.
-
-
-
- Note: Currently, bit Bswup is the only tool that can enable complete PWA solution for the new Blazor web app
- project template that introduced in .NET 8 which has different render mode (Auto, Server, WebAssembly).
-
-
-
-
- You can watch this step by step walkthrough video to see bit Bswup in action:
-
-
-
-
-
-
-
- You can find the sample source-code of the above video
- here.
-
-
-
-
-
-
-
-
-
-
-
-
- Supported browsers
-
-
-
-
- Blazor is supported in the browsers shown in the following list on both mobile and desktop platforms.
-
-
- Scripts
-
-
- How to setup the bit Bswup's scripts?
-
-
-
-
- Blazor script
-
- Since Bswup is taking care of the lifecycle of the application, we need to disable
- the autostart of the Blazor by adding autostart=false to the Blazor script tag:
-
- <script src="_framework/blazor.web.js" autostart="false"></script>
- Or for the standalone template:
- <script src="_framework/blazor.webassembly.js" autostart="false"></script>
-
-
-
-
- Bswup script
-
-
- The next step is to add and configure the bit Bswup's script tag itself:
-
- <script src="_content/Bit.Bswup/bit-bswup.js"
- scope="/"
- log="verbose"
- sw="service-worker.js"
- handler="bitBswupHandler"
- blazorScript="_framework/blazor.webassembly.js"></script>
-
-
-
- This script tag as shown above, has some options:
-
- scope: The scope of the service-worker
- (read more).
-
- log: The log level of the Bswup logger. available options are: info, verbose, debug, and error (coming soon).
-
- sw: The file path of the service-worker file.
-
- handler: The name of the handler function for the service-worker events that explained here.
-
- blazorScript: The file path of the Blazor's js script file.
-
-
- Note: You can remove any of these attributes which makes the bit Bswup to use the default values mentioned above.
-
- Note: The most important line here is the last line which is the only mandatory config in this file
- that imports the Bswup service-worker file:
-
- self.importScripts('_content/Bit.Bswup/bit-bswup.sw.js');
-
-
- These available configurations are explained below:
-
- assetsInclude: The list of file names from the assets list to include when the Bswup
- tries to store them in the cache storage (regex supported).
-
- assetsExclude: The list of file names from the assets list to exclude when the Bswup
- tries to store them in the cache storage (regex supported).
-
- externalAssets: The list of external assets to cache that are not included in the auto-generated assets file.
- For example, if you're not using index.html (like _host.cshtml), then you should add { "url": "/" }.
-
- defaultUrl: The default page URL. Use / when using _Host.cshtml.
-
- assetsUrl: The file path of the service-worker assets file generated at compile time
- (the default file name is service-worker-assets.js).
-
- prohibitedUrls: The list of file names that should not be accessed (regex supported).
-
- caseInsensitiveUrl: Enables the case insensitivity in the URL checking of the cache process.
-
- serverHandledUrls: The list of URLs that do not enter the service-worker offline process and
- will be handled only by server (regex supported). such as /api, /swagger, ...
-
- serverRenderedUrls: The list of URLs that should be rendered by the server and not
- client while navigating (regex supported). such as /about.html, /privacy, ...
-
- noPrerenderQuery: The query string attached to the default document request to disable
- the prerendering from the server so an unwanted prerendered result not be cached.
-
- ignoreDefaultInclude: Ignores the default asset includes array which is provided by the
- Bswup itself which is like this:
- [/\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/, /\.svg$/, /\.woff2$/, /\.ttf$/, /\.webp$/]
-
- ignoreDefaultExclude: Ignores the default asset excludes array which is provided by the Bswup
- itself which is like this:
- [/^_content\/Bit\.Bswup\/bit-bswup\.sw\.js$/, /^service-worker\.js$/]"
-
- Note: Keep in mind that caching service-worker related files will corrupt the update cycle of the service-worker.
- Only the browser should handle these files.
-
- isPassive: Enables the Bswup's passive mode. In this mode, the assets won't be
- cached in advance but rather upon initial request.
-
- disablePassiveFirstBoot: Disables downloading the Blazor's boot files in first time of Passive mode.
-
- enableIntegrityCheck: Enables the default integrity check available in browsers by setting
- the integrity attribute of the request object created in the service-worker to fetch the assets.
-
- enableDiagnostics: Enables diagnostics by pushing service-worker logs to the browser console.
-
- enableFetchDiagnostics: Enables fetch event diagnostics by pushing service-worker
- fetch event logs to the browser console.
-
-
- Progress component
-
-
- bit Bswup has its own Progress component to simplify the process of implementing a sophisticated UI widget to show the update progress.
-
-
-
-
- BswupProgress
-
- The BswupProgress component can be used to implement a customizable update progress easily.
- In order to use this component first add its script tag to the default document of your app:
-
- <script src="_content/Bit.Bswup/bit-bswup.progress.js"></script>
-
- Then you can use it in your app like this:
-
- <div>
- <BswupProgress AppContainer="#app-container" AutoReload=false>
- <div class="bswup-progress-text" />
- <svg class="bswup-container">
- <circle r="40%" cx="50%" cy="50%" />
- <circle r="40%" cx="50%" cy="50%" />
- </svg>
- </BswupProgress>
- <button id="bit-bswup-reload">Update available, Click to Reload</button>
-</div>
-
-
-
- Butil
-
- Blazor utils for Browser APIs
-
- Embracing Blazor because of your love for C#?
-
-
-
-
-
- What is bit Butil?
-
- Butil enables you to stay true to that sentiment by providing essential Browser APIs in C#,
- eliminating the need to revert to JavaScript for any functionality.
-
- bit Butil helps C# developers to access the browser APIs that are only accessible through JavaScript in C#.
-
-
-
-
-
-
- Supported browsers
-
- Blazor is supported in the browsers shown in the following list on both mobile and desktop platforms:
-
-
-
Apple Safari (Current version)
-
Google Chrome (Current version)
-
Microsoft Edge (Current version)
-
Mozilla Firefox (Current version)
-
-
-
-
-
-
-
- Supported platforms
-
- Blazor Hybrid apps have the following additional platform requirements:
-
-
- Setup Butil
-
-
- How to setup bit Butil?
-
-
-
-
- Script
-
- Add the following script tag to your default document:
- <script src="_content/Bit.Butil/bit-butil.js"></script>
-
-
-
-
- Service
-
- Add the following line to register the bit Butil services:
- builder.Services.AddBitButilServices();
- Now you can inject its classes to use the bit Butil tools.
-
- Crypto
- Cryptography API (Encryption/Decryption)
-
-
- How to use the Crypto class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser crypto features you need to inject the Bit.Butil.Crypto class and use it like this:
-
-@@inject Bit.Butil.Crypto crypto
-
-@@code {
- await crypto.Encrypt(...);
-}
-
-
-
-
- Methods
-
-
- Encrypt:
- The Encrypt method of the Crypto interface that encrypts data
- (MDN).
-
- WebAuthn
- Web Authentication API (Password-less/Passkey)
-
-
- How to use the WebAuthn class of the bit Butil?
-
-
-
-
- Usage
-
- To use the WebAuthn api of Butil you need to inject the Bit.Butil.WebAuthn class and use it like this:
-
-@@inject Bit.Butil.WebAuthn webAuthn
-
-@@code {
- var result = await webAuthn.CreateCredential(new { ... });
-}
-
-
-
-
- Note: For optimal security, it is advisable to implement Web Authentication alongside a server-side counterpart
- that securely stores essential data for future verification. This approach, similar to our existing integration with
- the FIDO2 infrastructure,
- ensures robust authentication and safeguards against potential threats.
-
- You can check it out in action in the Passwordless tab on the settings page of
- bit Boilerplate project template
-
-
-
-
- Methods
-
-
- CreateCredential:
- Creates a new credential using the provided options.
- (MDN).
-
- Clipboard
-
-
- How to use the Clipboard class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser Clipboard features you need to inject the Bit.Butil.Clipboard class and use it like this:
-
-@@inject Bit.Butil.Clipboard clipboard
-
-@@code {
- var text = await clipboard.ReadText();
-}
-
-
-
-
- Methods
-
-
- ReadText:
- Requests text from the system clipboard, returning a Promise that is fulfilled with
- a string containing the clipboard's text once it's available
- (MDN).
-
-
- WriteText:
- Requests text from the system clipboard, returning a Promise that is fulfilled with
- a string containing the clipboard's text once it's available
- (MDN).
-
- Read:
- Requests arbitrary data (such as images) from the clipboard, returning a Promise that
- resolves with an array of ClipboardItem objects containing the clipboard's contents
- (MDN).
-
- Keyboard
-
-
- How to use the Keyboard class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser Keyboard features you need to inject the Bit.Butil.Keyboard class and use it like this:
-
-@@inject Bit.Butil.Keyboard keyboard
-
-@@code {
- await keyboard.Add(ButilKeyCodes.F10, args => { ... }, , ButilModifiers.Alt | ButilModifiers.Ctrl);
- await keyboard.Remove(ButilKeyCodes.F10, handler);
-}
-
-
-
-
- Methods
-
-
- Add, Remove:
- Adds/Removes a handler to a keyboard key combination.
-
- Console
-
-
- How to use the Console class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser console features you need to inject the Bit.Butil.Console class and use it like this:
-
-@@inject Bit.Butil.Console console
-
-@@code {
- console.Log("This is a test log:", value);
- console.Error("This is a test error:", value);
- console.Assert(condition, "The condition failed!", value);
-}
-
-
-
-
- Methods
-
-
- Assert:
- Log a message and stack trace to console if the first argument is false
- (MDN).
-
-
-
-
-
- @assertExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Assert
-
-
-
-
-
-
- Count:
- Log the number of times this line has been called with the given label
- (MDN).
-
-
-
-
-
- @countExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Count
-
-
-
-
-
-
- CountReset:
- Resets the value of the counter with the given label
- (MDN).
-
-
-
-
-
- @countResetExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- CountReset
-
-
-
-
-
-
- Debug:
- Outputs a message to the console with the log level debug
- (MDN).
-
-
-
-
-
- @debugExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Debug
-
-
-
-
-
-
- Dir:
- Displays an interactive listing of the properties of a specified JavaScript object
- (MDN).
-
-
-
-
-
- @dirExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Dir
-
-
-
-
-
-
- Dirxml:
- Displays an XML/HTML Element representation of the specified object if possible or the JavaScript Object view if it is not possible
- (MDN).
-
-
-
-
-
- @dirxmlExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Dirxml
-
-
-
-
-
-
- Error:
- Outputs an error message. You may use string substitution and additional arguments with this method
- (MDN).
-
-
-
-
-
- @errorExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Error
-
-
-
-
-
-
- Group:
- Creates a new inline group, indenting all following output by another level. To move back out a level, call console.groupEnd()
- (MDN).
-
-
-
-
-
- @groupExampleCode
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Create group logs
-
-
-
-
-
-
- GroupCollapsed:
- Creates a new inline group, indenting all following output by another level. However, unlike console.group() this starts with the inline group collapsed requiring the use of a disclosure button to expand it. To move back out a level, call console.groupEnd()
- (MDN).
-
-
-
-
-
- @groupExampleCode
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Create group logs
-
-
-
-
-
-
- GroupEnd:
- Exits the current inline group
- (MDN).
-
-
-
-
-
- @groupExampleCode
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Create group logs
-
-
-
-
-
-
- Info:
- Informative logging of information. You may use string substitution and additional arguments with this method
- (MDN).
-
-
-
-
-
- @infoExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Info
-
-
-
-
-
-
- Log:
- For general output of logging information. You may use string substitution and additional arguments with this method
- (MDN).
-
-
-
-
-
- @logExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
Open the DevTools console and start clicking on the button
-
- Warn
-
-
-
-
-
-
- Table:
- Displays tabular data as a table
- (MDN).
-
-
-
-
-
- @tableExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Table
-
-
-
-
-
-
- Profile:
- Starts the browser's built-in profiler (for example, the Firefox performance tool). You can specify an optional name for the profile
- (MDN).
-
-
-
-
-
- @profileExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Profile
-
-
-
-
-
-
- ProfileEnd:
- Stops the profiler. You can see the resulting profile in the browser's performance tool (for example, the Firefox performance tool)
- (MDN).
-
-
-
-
-
- @profileEndExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- ProfileEnd
-
-
-
-
-
-
- Time:
- Starts a timer with a name specified as an input parameter. Up to 10,000 simultaneous timers can run on a given page
- (MDN).
-
-
-
-
-
- @timeExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- Time
-
-
-
-
-
-
- TimeLog:
- Logs the value of the specified timer to the console
- (MDN).
-
-
-
-
-
- @timeLogExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- TimeLog
-
-
-
-
-
-
- TimeEnd:
- Stops the specified timer and logs the elapsed time in milliseconds since it started
- (MDN).
-
-
-
-
-
- @timeEndExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
-
- TimeEnd
-
-
-
-
-
-
- TimeStamp:
- Adds a marker to the browser performance tool's timeline
- (MDN).
-
-
-
-
-
- @timeStampExampleCode
-
-
-
-
-
-
-
Open the DevTools console and start clicking on the button
- Notification
-
-
- How to use the Notification class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser notification features you need to inject the Bit.Butil.Notification class and use it like this:
-
-@@inject Bit.Butil.Notification notification
-
-@@code {
- await notification.IsSupported();
- await notification.Show("title", new() { Body = "this is body." });
-}
-
-
-
-
- Methods
-
-
- IsSupported:
- Checks if the runtime (browser or web-view) is supporting the Web Notification API.
-
-
- Show:
- Requests a native notification to show to the user.
- (MDN).
-
- Note: The Notification api has some limitation on Android and for it to work properly a
- Service Worker needs to be registered first.
-
- Storage
-
-
- How to use the Storage class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser storage features you need to inject the Bit.Butil.Storage class and use it like this:
-
-@@inject Bit.Butil.LocalStorage localStorage
-@@inject Bit.Butil.SessionStorage sessionStorage
-
-@@code {
- await localStorage.SetItem("my-key", "my-value");
- await sessionStorage.SetItem("my-key2", "my-value2");
-}
-
-
-
-
- Methods
-
-
- GetLength:
- Returns an integer representing the number of data items stored in the Storage object
- (MDN).
-
- Cookie
-
-
- How to use the Cookie class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser cookie features you need to inject the Bit.Butil.Cookie class and use it like this:
-
-@@inject Bit.Butil.Cookie cookie
-
-@@code {
- await cookie.Remove("cookie-name");
-}
-
-
-
-
- Methods
-
-
- Set, Get:
- Gets/Sets a cookie by providing the cookie name
- (MDN).
-
- History
-
-
- How to use the History class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser history features you need to inject the Bit.Butil.History class and use it like this:
-
-@@inject Bit.Butil.History history
-
-@@code {
- await history.GoBack();
-}
-
-
-
-
- Methods
-
-
- GetLength:
- Returns an Integer representing the number of elements in the session history, including the currently loaded page
- (MDN).
-
-
- SetScrollRestoration, GetScrollRestoration:
- Gets/Sets default scroll restoration behavior on history navigation. This property can be either auto or manual
- (MDN).
-
-
- GetState: Returns an any value representing the state at the top of the history stack
- (MDN).
-
-
- GoBack:
- This asynchronous method goes to the previous page in session history, the same action as when the user clicks the browser's Back button.
- Calling this method to go back beyond the first page in the session history has no effect and doesn't raise an exception
- (MDN).
-
-
- GoForward:
- This asynchronous method goes to the next page in session history, the same action as when the user clicks the browser's Forward button.
- Calling this method to go forward beyond the most recent page in the session history has no effect and doesn't raise an exception
- (MDN).
-
-
- Go:
- Asynchronously loads a page from the session history, identified by its relative location to the current page, for example -1 for the previous page or 1 for the next page.
- Calling this method without parameters or a value of 0 reloads the current page
- (MDN).
-
-
- AddPopState, RemovePopState:
- The popstate event of the Window interface is fired when the active history entry changes while the user navigates the session history
- (MDN).
-
- Element
-
-
- How to use the Element class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser Element features you need to just use the Bit.Butil namesapce and utilize its extension methods like this:
-
-@@using Bit.Butil
-
-<div @@ref="elementRef">Element</div>
-
-@@code {
- private ElementReference elementRef;
-
- var rect = await elementRef.GetBoundingClientRect();
-}
-
-
-
-
- Methods
-
-
- GetAttribute:
- Retrieves the value of the named attribute from the current node and returns it as a string
- (MDN).
-
-
-
-
-
- @getAttributeExampleCode
-
-
-
-
-
- Element
-
-
-
-
- GetAttribute
-
-
-
Attribute: @currentAttribute
-
-
-
-
-
-
- GetAttributeNames:
- Returns an array of attribute names from the current element
- (MDN).
-
-
-
-
-
- @getAttributeNamesExampleCode
-
-
-
-
-
- Element
-
-
- GetAttributeNames
-
-
-
Attribute names: @currentAttributeNames
-
-
-
-
-
-
- GetBoundingClientRect:
- Returns the size of an element and its position relative to the viewport
- (MDN).
-
-
- HasAttribute:
- Returns a boolean value indicating if the element has the specified attribute or not
- (MDN).
-
-
-
-
-
- @hasAttributeExampleCode
-
-
-
-
-
- Element
-
-
-
-
- GetHasAttribute
-
-
-
Has attribute: @hasAttribute
-
-
-
-
-
-
- HasAttributes:
- Returns a boolean value indicating if the element has one or more HTML attributes present
- (MDN).
-
-
-
-
-
- @hasAttributesExampleCode
-
-
-
-
-
- Element
-
-
- GetHasAttributes
-
-
-
Has attributes: @hasAttributes
-
-
-
-
-
-
- SetPointerCapture:
- Designates a specific element as the capture target of future pointer events
- (MDN).
-
-
- HasPointerCapture:
- Indicates whether the element on which it is invoked has pointer capture for the pointer identified by the given pointer ID
- (MDN).
-
-
- ReleasePointerCapture:
- Releases (stops) pointer capture that was previously set for a specific pointer event
- (MDN).
-
-
- RequestPointerLock:
- Allows to asynchronously ask for the pointer to be locked on the given element
- (MDN).
-
-
- RemoveAttribute:
- Removes the named attribute from the current node
- (MDN).
-
-
-
-
-
- @removeAttributeExampleCode
-
-
-
-
-
- Element
-
-
-
-
- RemoveAttribute
-
-
-
-
-
-
- SetAttribute:
- Sets the value of a named attribute of the current node
- (MDN).
-
-
-
-
-
- @setAttributeExampleCode
-
-
-
-
-
- Element
-
-
-
-
-
-
- SetAttribute
-
-
-
-
-
-
- ToggleAttribute:
- Toggles a boolean attribute, removing it if it is present and adding it if it is not present, on the specified element
- (MDN).
-
-
-
-
-
- @toggleAttributeExampleCode
-
-
-
-
-
- Element
-
-
-
-
-
-
- ToggleAttribute
-
-
-
-
-
-
- SetAccessKey, GetAccessKey:
- Gets/Sets a string representing the access key assigned to the element
- (MDN).
-
-
-
-
-
- @accessKeyExampleCode
-
-
-
-
-
- Element
-
-
-
-
- SetAccessKey
-
- GetAccessKey
-
-
-
Access key: @currentAccessKey
-
-
-
-
-
-
- SetClassName, GetClassName:
- Gets/Sets a string representing the class of the element
- (MDN).
-
-
-
-
-
- @classNameExampleCode
-
-
-
-
-
- Element
-
-
-
-
- SetClassName
-
- GetClassName
-
-
-
ClassName: @currentClassName
-
-
-
-
-
-
- GetClientHeight:
- Returns a number representing the inner height of the element in px
- (MDN).
-
-
-
-
-
- @getClientHeightExampleCode
-
-
-
-
-
- Element
-
-
- GetClientHeight
-
-
-
ClientHeight: @currentClientHeight
-
-
-
-
-
-
- GetClientLeft:
- Returns a number representing the width of the left border of the element in px
- (MDN).
-
-
-
-
-
- @getClientLeftExampleCode
-
-
-
-
-
- Element
-
-
- GetClientLeft
-
-
-
ClientLeft: @currentClientLeft
-
-
-
-
-
-
- GetClientTop:
- Returns a number representing the width of the top border of the element in px
- (MDN).
-
-
-
-
-
- @getClientTopExampleCode
-
-
-
-
-
- Element
-
-
- GetClientTop
-
-
-
ClientTop: @currentClientTop
-
-
-
-
-
-
- GetClientWidth:
- Returns a number representing the inner width of the element in px
- (MDN).
-
-
-
-
-
- @getClientWidthExampleCode
-
-
-
-
-
- Element
-
-
- GetClientWidth
-
-
-
ClientWidth: @currentClientWidth
-
-
-
-
-
-
- SetId, GetId:
- Gets/Sets a string representing the id of the element
- (MDN).
-
-
-
-
-
- @idExampleCode
-
-
-
-
-
- Element
-
-
-
-
- SetId
-
- GetId
-
-
-
Id: @currentId
-
-
-
-
-
-
- SetInnerHTML, GetInnerHTML:
- Gets/Sets a string representing the markup of the element's content
- (MDN).
-
-
-
-
-
- @innerHTMLExampleCode
-
-
-
-
-
- Element
-
-
-
-
- SetInnerHTML
-
- GetInnerHTML
-
-
-
InnerHTML: @currentInnerHTML
-
-
-
-
-
-
- SetOuterHtml, GetOuterHtml:
- Gets/Sets a string representing the markup of the element including its content. When used as a setter, replaces the element with nodes parsed from the given string
- (MDN).
-
-
-
-
-
- @outerHTMLExampleCode
-
-
-
-
-
- Element
-
-
- GetOuterHTML
-
-
-
OuterHTML: @currentOuterHTML
-
-
-
-
-
-
- GetScrollHeight:
- Returns a number representing the scroll view height of an element
- (MDN).
-
-
-
-
-
- @getScrollHeightExampleCode
-
-
-
-
-
-
Element
-
-
- GetScrollHeight
-
-
-
ScrollHeight: @currentScrollHeight
-
-
-
-
-
-
- GetScrollLeft:
- A number representing the left scroll offset of the element
- (MDN).
-
-
-
-
-
- @getScrollLeftExampleCode
-
-
-
-
-
-
Element
-
-
- GetScrollLeft
-
-
-
ScrollLeft: @currentScrollLeft
-
-
-
-
-
-
- GetScrollTop:
- A number representing number of pixels the top of the element is scrolled vertically
- (MDN).
-
-
-
-
-
- @getScrollTopExampleCode
-
-
-
-
-
-
Element
-
-
- GetScrollTop
-
-
-
ScrollTop: @currentScrollTop
-
-
-
-
-
-
- GetScrollWidth:
- Returns a number representing the scroll view width of the element
- (MDN).
-
-
-
-
-
- @getScrollWidthExampleCode
-
-
-
-
-
-
Element
-
-
- GetScrollWidth
-
-
-
ScrollWidth: @currentScrollWidth
-
-
-
-
-
-
- GetTagName:
- Returns a string with the name of the tag for the given element
- (MDN).
-
-
-
-
-
- @getTagNameExampleCode
-
-
-
-
-
- Element
-
-
- GetTagName
-
-
-
TagName: @currentTagName
-
-
-
-
-
-
- IsContentEditable:
- Returns a boolean value indicating whether or not the content of the element can be edited
- (MDN).
-
-
-
-
-
- @isContentEditableExampleCode
-
-
-
-
-
- Element
-
-
- GetIsContentEditable
-
-
-
Is content editable: @isContentEditable
-
-
-
-
-
-
- SetContentEditable, GetContentEditable:
- Gets/Sets the contentEditable property, which specifies whether or not the element is editable
- (MDN).
-
-
- SetDir, GetDir:
- Gets/Sets the text writing directionality of the content of the current element
- (MDN).
-
-
-
-
-
- @dirExampleCode
-
-
-
-
-
- Element
-
-
-
-
-
-
-
-
-
- SetDir
-
- GetDir
-
-
-
Dir: @currentDir
-
-
-
-
-
-
- SetEnterKeyHint, GetEnterKeyHint:
- Gets/Sets the enterKeyHint property, which is an enumerated property defining what action label (or icon) to present for the enter key on virtual keyboards
- (MDN).
-
-
- SetHidden, GetHidden:
- Gets/Sets the hidden property, which reflects the value of the element's hidden attribute
- (MDN).
-
-
- SetInert, GetInert:
- Gets/Sets the inert property, which reflects the value of the element's inert attribute. It is a boolean value that, when present, makes the browser "ignore" user input events for the element, including focus events and events from assistive technologies
- (MDN).
-
-
-
-
-
- @inertExampleCode
-
-
-
-
-
-
Element
-
-
-
-
- SetInert
-
- GetInert
-
-
-
Inert: @currentInert
-
-
-
-
-
-
- SetInnerText, GetInnerText:
- Gets/Sets the innerText property, which represents the rendered text content of a node and its descendants
- (MDN).
-
-
-
-
-
- @innerTextExampleCode
-
-
-
-
-
- Element
-
-
-
-
- SetInnerText
-
- GetInnerText
-
-
-
InnerText: @currentInnerText
-
-
-
-
-
-
- SetInputMode, GetInputMode:
- Gets/Sets the inputMode property, which reflects the value of the element's inputmode attribute
- (MDN).
-
-
- SetTabIndex, GetTabIndex:
- Gets/Sets a number representing the position of the element in the tabbing order
- (MDN).
-
-
-
-
-
- @tabIndexExampleCode
-
-
-
-
-
- Element
-
-
-
-
- SetTabIndex
-
- GetTabIndex
-
-
-
TabIndex: @currentTabIndex
-
-
-
-
-
-
- GetOffsetHeight:
- Returns the height of an element, including vertical padding and borders in px
- (MDN).
-
-
-
-
-
- @getOffsetHeightExampleCode
-
-
-
-
-
- Element
-
-
- GetOffsetHeight
-
-
-
OffsetHeight: @currentOffsetHeight
-
-
-
-
-
-
- GetOffsetLeft:
- Returns the number of pixels that the upper left corner of the current element is offset to the left within the offsetParent node
- (MDN).
-
-
-
-
-
- @getOffsetLeftExampleCode
-
-
-
-
-
- Element
-
-
- GetOffsetLeft
-
-
-
OffsetLeft: @currentOffsetLeft
-
-
-
-
-
-
- GetOffsetTop:
- Returns the distance from the outer border of the current element (including its margin) to the top padding edge of the offsetParent, the closest positioned ancestor element
- (MDN).
-
-
-
-
-
- @getOffsetTopExampleCode
-
-
-
-
-
- Element
-
-
- GetOffsetTop
-
-
-
OffsetTop: @currentOffsetTop
-
-
-
-
-
-
- GetOffsetWidth:
- The layout width of an element in px
- (MDN).
-
-
-
-
-
- @getOffsetWidthExampleCode
-
-
-
-
-
- Element
-
-
- GetOffsetWidth
-
-
-
OffsetWidth: @currentOffsetWidth
-
-
-
-
-
-
- Blur:
- Removes keyboard focus from the currently focused element
- (MDN).
-
- Window
-
-
- How to use the Window class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser window features you need to inject the Bit.Butil.Window class and use it like this:
-
-@@inject Bit.Butil.Window window
-
-@@code {
- await window.AddEventListener(ButilEvents.KeyDown, args => { ... });
- await window.Alert("Alert from C#");
-}
-
-
-
-
- Methods
-
-
- AddBeforeUnload, RemoveBeforeUnload:
- The beforeunload event is fired when the current window,
- contained document, and associated resources are about to be unloaded. The main use case for this event is to
- trigger a browser-generated confirmation dialog that asks users to confirm if they really want to leave the page
- when they try to close or reload it, or navigate somewhere else. This is intended to help prevent loss of unsaved data
- (MDN).
-
-
- AddEventListener, RemoveEventListener:
- Sets up a function that will be called whenever the specified event is delivered to the window
- (MDN).
-
-
- GetInnerHeight:
- Gets the height of the content area of the browser window in px including, if rendered, the horizontal scrollbar
- (MDN).
-
-
- IsSecureContext:
- Returns a boolean indicating whether the current context is secure (true) or not (false)
- (MDN).
-
-
- GetLocationBar:
- Returns the locationbar object. For privacy and interoperability reasons, the value of the visible property is now false if this Window is a popup, and true otherwise
- (MDN).
-
-
- SetName, GetName:
- Gets/Sets the name of the window's browsing context
- (MDN).
-
-
- GetOrigin:
- Returns the global object's origin, serialized as a string
- (MDN).
-
- Document
-
-
- How to use the Document class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser document features you need to inject the Bit.Butil.Document class and use it like this:
-
-@@inject Bit.Butil.Document document
-
-@@code {
- await document.AddEventListener(ButilEvents.Click, args => { ... });
- await document.SetTitle("New shinny title");
-}
-
-
-
-
- Methods
-
-
- AddEventListener, RemoveEventListener:
- Sets up a function that will be called whenever the specified event is delivered to the document
- (MDN).
-
-
- GetCharacterSet:
- Returns the character set being used by the document
- (MDN).
-
-
- GetCompatMode:
- Indicates whether the document is rendered in quirks or strict mode
- (MDN).
-
-
- GetContentType:
- Returns the Content-Type from the MIME Header of the current document
- (MDN).
-
-
- GetDocumentURI:
- Returns the document location as a string
- (MDN).
-
-
- SetDesignMode, GetDesignMode:
- Gets/Sets ability to edit the whole document
- (MDN).
-
- Navigator
-
-
- How to use the Navigator class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser navigator features you need to inject the Bit.Butil.Navigator class and use it like this:
-
-@@inject Bit.Butil.Navigator navigator
-
-@@code {
- var userAgent = await navigator.GetUserAgent();
-}
-
-
-
-
- Methods
-
-
- GetDeviceMemory:
- Returns the amount of device memory in gigabytes. This value is an approximation given by rounding to the nearest power of 2 and dividing that number by 1024
- (MDN).
-
-
- GetLanguage:
- Returns a string representing the preferred language of the user, usually the language of the browser UI. The null value is returned when this is unknown
- (MDN).
-
- Location
-
-
- How to use the Location class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser location features you need to inject the Bit.Butil.Location class and use it like this:
-
-@@inject Bit.Butil.Location location
-
-@@code {
- await location.Reload();
-}
-
-
-
-
- Methods
-
-
- SetHref, GetHref:
- Gets/Sets the href of the location and then the associated document navigates to the new page
- (MDN).
-
-
- SetPathname, GetPathname:
- Gets/Sets a string containing an initial '/' followed by the path of the URL, not including the query string or fragment
- (MDN).
-
- Screen
-
-
- How to use the Screen class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser screen features you need to inject the Bit.Butil.Screen class and use it like this:
-
-@@inject Bit.Butil.Screen screen
-
-@@code {
- var screenWidth = await screen.GetWidth();
-}
-
-
-
-
- Methods
-
-
- GetAvailableHeight:
- Specifies the height of the screen, in pixels, minus permanent or semipermanent user interface features displayed by the operating system, such as the Taskbar on Windows
- (MDN).
-
-
- AddChange, RemoveChange:
- Fired on a specific screen when it changes in some way - width or height, available width or height, color depth, or orientation
- (MDN).
-
- VisualViewport
-
-
- How to use the VisualViewport class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser VisualViewport features you need to inject the Bit.Butil.VisualViewport class and use it like this:
-
-@@inject Bit.Butil.VisualViewport visualViewport
-
-@@code {
- var offsetLeft = await VisualViewport.GetOffsetLeft();
-}
-
-
-
-
- Methods
-
-
- GetOffsetLeft:
- Returns the offset of the left edge of the visual viewport from the left edge of
- the layout viewport in CSS pixels, or 0 if current document is not fully active.
- (MDN).
-
-
- GetOffsetTop:
- Returns the offset of the top edge of the visual viewport from the top edge of
- the layout viewport in CSS pixels, or 0 if current document is not fully active.
- (MDN).
-
-
- GetPageLeft:
- Returns the x coordinate of the left edge of the visual viewport relative to the
- initial containing block origin, in CSS pixels, or 0 if current document is not fully active.
- (MDN).
-
-
- GetPageTop:
- Returns the y coordinate of the top edge of the visual viewport relative to the
- initial containing block origin, in CSS pixels, or 0 if current document is not fully active.
- (MDN).
-
-
- GetScale:
- Returns the pinch-zoom scaling factor applied to the visual viewport, or 0 if current
- document is not fully active, or 1 if there is no output device.
- (MDN).
-
- ScreenOrientation
-
-
- How to use the ScreenOrientation class of the bit Butil?
-
-
-
-
- Usage
-
- To use the browser ScreenOrientation features you need to inject the Bit.Butil.ScreenOrientation class and use it like this:
-
-@@inject Bit.Butil.ScreenOrientation screenOrientation
-
-@@code {
- var angle = await screenOrientation.GetAngle();
-}
-
-
-
-
- Methods
-
-
- GetOrientationType:
- Returns the document's current orientation type.
- (MDN).
-
-
- Lock:
- Locks the orientation of the containing document to the specified orientation.
- Typically orientation locking is only enabled on mobile devices, and when the browser context is full screen.
- (MDN).
-
-
- Unlock:
- Unlocks the orientation of the containing document from its default orientation.
- (MDN).
-
-
- AddChange, RemoveChange:
- The change event of the ScreenOrientation interface fires when the orientation of the
- screen has changed, for example when a user rotates their mobile phone.
- (MDN).
-
- UserAgent
-
-
- How to use the UserAgent class of the bit Butil?
-
-
-
-
- Usage
-
- To use the UserAgent api of Butil you need to inject the Bit.Butil.UserAgent class and use it like this:
-
-@@inject Bit.Butil.UserAgent userAgent
-
-@@code {
- var props = await userAgent.Extract();
-}
-
-
-
-
-
- Methods
-
-
- Extract:
- Returns an instance of the Bit.Butil.UserAgentProperties class containing all possible data that extracted from the client's browser.
-
- Device
-
-
- How to use the device sensor classes of the bit Butil?
-
-
-
-
- Usage
-
- The device sensor features are spread across a few classes. Inject the ones you need and use them like this:
-
-@@inject Bit.Butil.Battery battery
-@@inject Bit.Butil.NetworkInformation networkInformation
-@@inject Bit.Butil.WakeLock wakeLock
-@@inject Bit.Butil.IdleDetector idleDetector
-
-@@code {
- var status = await battery.GetStatus();
- var net = await networkInformation.GetStatus();
-}
-
- The WakeLock class wraps the
- Screen Wake Lock API,
- which prevents the screen from dimming while the app is active.
-
-
- Request / Release:
- Acquires or releases a screen wake lock. RequestPersistent keeps the lock re-acquired automatically when the page becomes visible again.
-
- Geolocation
-
-
- How to use the Geolocation class of the bit Butil?
-
-
-
-
- Usage
-
- To read the device's position you need to inject the Bit.Butil.Geolocation class and use it like this:
-
-@@inject Bit.Butil.Geolocation geolocation
-
-@@code {
- var position = await geolocation.GetCurrentPosition();
- await using var sub = await geolocation.SubscribeWatch(p => { /* ... */ });
-}
-
-
-
-
- Methods
-
- The Geolocation class wraps the
- Geolocation API
- (navigator.geolocation).
-
-
- IsSupported:
- Returns whether the Geolocation API (navigator.geolocation) is available in the current browser
- (MDN).
-
- MediaDevices
-
-
- How to use the MediaDevices class of the bit Butil?
-
-
-
-
- Usage
-
- Inject the MediaDevices class, enumerate the available cameras and microphones,
- request a live stream, and attach it to a video element:
-
-@@inject Bit.Butil.MediaDevices mediaDevices
-
-@@code {
- var devices = await mediaDevices.EnumerateDevices();
- var stream = await mediaDevices.GetUserMedia(audio: true, video: true);
- await stream.AttachTo(videoElement);
-}
-
-
- EnumerateDevices:
- Lists all input/output media devices. Labels may be empty until the user has granted
- permission to a matching input
- (MDN).
-
-
- GetUserMedia / AttachTo / SetEnabled:
- Requests camera and/or microphone access and returns a MediaStreamHandle (or null when
- the user denies the prompt). Attach the stream to a video element with AttachTo,
- pause or resume its tracks with SetEnabled, and stop the stream by disposing the handle
- (MDN).
-
- Permissions
-
-
- How to use the Permissions class of the bit Butil?
-
-
-
-
- Usage
-
- To query the browser's permission state you need to inject the Bit.Butil.Permissions class and use it like this:
-
-@@inject Bit.Butil.Permissions permissions
-
-@@code {
- var state = await permissions.Query("geolocation");
-}
-
-
-
-
- Methods
-
-
- IsSupported:
- Returns whether the Permissions API (navigator.permissions) is available in the current browser
- (MDN).
-
-
- Query:
- Returns the current state (granted, denied, prompt or unknown) for a given permission descriptor name, without triggering a prompt
- (MDN).
-
- Fetch
-
-
- How to use the Fetch class of the bit Butil?
-
-
-
-
- Usage
-
- The Fetch class wraps the browser's
- Fetch API
- with progress reporting and an abortable handle. Prefer HttpClient for normal API calls;
- reach for this when you need progress for big downloads or fetch-only semantics. Inject it and use it like this:
-
-@@inject Bit.Butil.Fetch fetch
-
-@@code {
- var response = await fetch.Send(new FetchRequest { Url = "https://..." },
- onProgress: p => { /* bytes received */ });
-}
-
-
-
-
- Methods
-
- Send:
- Sends the request and returns the full FetchResponse (status, headers and body bytes).
-
- Files
-
-
- How to use the file related classes of the bit Butil?
-
-
-
-
- Usage
-
- The file features live in two classes. Inject the ones you need and use them like this:
-
-@@inject Bit.Butil.FileReader fileReader
-@@inject Bit.Butil.ObjectUrls objectUrls
-
-@@code {
- var text = await fileReader.ReadAsText(fileInput);
- var url = await objectUrls.Create(bytes, "image/png");
-}
-
-
-
-
- FileReader
-
- The FileReader class wraps the
- FileReader API
- to read files selected in an <input type="file"> element as metadata, text, bytes or data URLs.
-
-
- GetFileInfos:
- Returns metadata (Name, Size and Type) for every file selected in the given input element
- (MDN).
-
-
-
-
- @getFileInfosExampleCode
-
-
-
-
-
- GetFileInfos
-
-
@fileInfos
-
-
-
-
-
-
- ReadAsText:
- Reads the first selected file as UTF-8 text
- (MDN).
-
-
-
-
- @readAsTextExampleCode
-
-
-
-
-
- ReadAsText
-
-
@fileText
-
-
-
-
-
-
- ReadAsBytes:
- Reads the first selected file as raw bytes
- (MDN).
-
-
-
-
- @readAsBytesExampleCode
-
-
-
-
-
- ReadAsBytes
-
-
@fileBytes
-
-
-
-
-
-
- ReadAsDataUrl:
- Reads the first selected file as a base-64 data URL, convenient for image previews
- (MDN).
-
-
-
-
- @readAsDataUrlExampleCode
-
-
-
-
-
- ReadAsDataUrl
-
-
@fileDataUrl
- @if (imagePreviewUrl is not null)
- {
-
-
- }
-
-
-
-
-
-
- Clear:
- Clears the input's selection (resets its files list)
- (MDN).
-
- Speech
-
-
- How to use the speech classes of the bit Butil?
-
-
-
-
- Usage
-
- The speech features are split across two classes. Inject the ones you need and use them like this:
-
-@@inject Bit.Butil.SpeechSynthesis speechSynthesis
-@@inject Bit.Butil.SpeechRecognition speechRecognition
-
-@@code {
- await speechSynthesis.Speak("Hello from Butil!");
- await using var rec = await speechRecognition.Start(options, onResult: r => { /* ... */ });
-}
-
-
-
-
- SpeechSynthesis
-
- The SpeechSynthesis class wraps the
- SpeechSynthesis API
- for text-to-speech.
-
-
- GetVoices:
- Returns the list of voices the platform makes available
- (MDN).
-
-
-
-
- @getVoicesExampleCode
-
-
-
- GetVoices
-
-
Voices count: @voices.Length
-
@getVoicesResult
-
-
-
-
-
-
- Speak:
- Speaks the configured utterance with an optional voice, rate and pitch
- (MDN).
-
-
-
-
- @speakExampleCode
-
-
-
-
-
-
-
- Speak
-
-
-
-
-
-
- Pause / Resume / Cancel:
- Pauses the current utterance, resumes a paused utterance, or cancels all pending utterances
- (MDN).
-
- The SpeechRecognition class wraps the
- SpeechRecognition API
- for speech-to-text (Chromium-based browsers).
-
-
- Start:
- Captures microphone input and reports interim and final transcripts through the onResult callback.
- The Continuous and InterimResults options control the stream, and onError / onEnd surface errors and completion.
- Returns an IAsyncDisposable handle that stops recognition when disposed
- (MDN).
-
- Observers
-
-
- How to use the observers and async browser APIs of the bit Butil?
-
-
-
-
- Usage
-
- These reactive and async browser APIs are spread across a few classes and element extension methods.
- Inject the ones you need (the element observers take the injected IJSRuntime) and use them like this:
-
-@@inject Bit.Butil.Performance performance
-@@inject Bit.Butil.StorageManager storageManager
-@@inject Bit.Butil.NetworkInformation networkInformation
-@@inject Bit.Butil.BroadcastChannel broadcastChannel
-@@inject Bit.Butil.IndexedDb indexedDb
-@@inject IJSRuntime js
-
-@@code {
- var sub = await element.ObserveIntersection(js, entries => { /* ... */ });
- await using var db = await indexedDb.Open("my-db", 1, [new IndexedDbStoreSchema { Name = "items", KeyPath = "id" }]);
-}
-
-
-
-
- Element observers
-
- The ObserveIntersection, ObserveResize and ObserveMutations extension methods wire the
- matching browser observers onto an ElementReference. Each returns a ButilSubscription you
- dispose to stop observing. The samples below all watch this shared target element:
-
-
- target
-
-
-
- ObserveIntersection:
- Fires when the target enters or leaves the viewport, reporting the intersection ratio and visibility
- (MDN).
-
- The Performance class wraps the
- Performance
- timing and marker API.
-
-
- Mark / Measure / GetEntries:
- Adds named marks to the timeline, measures the elapsed time between them, and reads back the recorded entries
- (MDN).
-
-
- Estimate:
- Reports an estimate of the storage quota and current usage for the origin
- (MDN).
-
-
-
-
- @storageExampleCode
-
-
-
- Estimate
-
-
@storageResult
-
-
-
-
-
-
- GetStatus:
- Returns the online flag, effective connection type, downlink and round-trip-time estimates
- (MDN).
-
-
-
-
- @networkExampleCode
-
-
-
- GetStatus
-
-
@networkResult
-
-
-
-
-
-
-
-
- BroadcastChannel
-
- The BroadcastChannel class wraps the
- BroadcastChannel
- API for cross-tab pub/sub on the same origin.
-
-
- Subscribe / Post:
- Subscribes to a named channel and posts messages to every other listener on that channel in the same origin
- (the sender does not receive its own message). Open a second tab to see messages arrive
- (MDN).
-
-
-@code {
- private string? indexedDbResult;
-
- private class DemoIdbItem
- {
- public string Id { get; set; } = """";
- public string Value { get; set; } = """";
- }
-
- private async Task IndexedDbRoundTrip()
- {
- await using var db = await indexedDb.Open(""butil-demo-db"", 1,
- [
- new IndexedDbStoreSchema { Name = ""items"", KeyPath = ""id"" }
- ]);
-
- var item = new DemoIdbItem { Id = ""demo-1"", Value = ""stored at "" + DateTime.Now.ToString(""HH:mm:ss"") };
- await db.Put(""items"", item);
- var read = await db.Get(""items"", ""demo-1"");
- indexedDbResult = read?.Value ?? ""(null)"";
- }
-}";
-}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Butil/Butil29ObserversPage.razor.scss b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Butil/Butil29ObserversPage.razor.scss
deleted file mode 100644
index dc4b53c541b..00000000000
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Butil/Butil29ObserversPage.razor.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-@import '../../Styles/abstracts/_colors.scss';
-@import '../../Styles/abstracts/_mixins.scss';
-@import '../../Styles/abstracts/_functions.scss';
-@import '../../Styles/abstracts/_media-queries.scss';
-
-.page-container {
- @include PageContainer;
-}
-
-.section-card {
- @include SectionCard;
-}
-
-.section-card-txt {
- @include SectionCardText;
-}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/ContactUsPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/ContactUsPage.razor
index ae7d7c6b357..19ab9a585fc 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/ContactUsPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/ContactUsPage.razor
@@ -2,8 +2,8 @@
@inherits AppComponentBase
+ Title="Contact us"
+ Description="Get in touch with the bit platform team for questions, feedback, or project inquiries." />
@@ -45,6 +45,13 @@
Placeholder="Enter your message" />
+ @if (isSent)
+ {
+
+ Thank you! Your message has been sent. We will get back to you soon.
+
+ }
+
Send
@@ -54,7 +61,7 @@
Color="BitColor.Tertiary"
Variant="BitVariant.Text"
ButtonType="BitButtonType.Button"
- OnClick="() => contactUsModel = new()">
+ OnClick="ResetForm">
Reset
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/ContactUsPage.razor.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/ContactUsPage.razor.cs
index 264588f2b75..5e433b971ea 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/ContactUsPage.razor.cs
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/ContactUsPage.razor.cs
@@ -4,21 +4,30 @@ namespace Bit.Websites.Platform.Client.Pages;
public partial class ContactUsPage
{
- private ContactUsDto contactUsModel { get; set; } = new();
+ private bool isSent;
+ private bool isSending;
+ private ContactUsDto contactUsModel = new();
- private bool isSending { get; set; }
+ private void ResetForm()
+ {
+ isSent = false;
+ contactUsModel = new();
+ }
private async Task SendMessage()
{
if (isSending) return;
isSending = true;
+ isSent = false;
try
{
+ // ExceptionDelegatingHandler in the HttpClient pipeline throws a typed exception on any
+ // non-success response; WrapHandled on the form's OnValidSubmit surfaces its message.
await HttpClient.PostAsJsonAsync("api/ContactUs/SendMessage", contactUsModel, AppJsonContext.Default.ContactUsDto);
- contactUsModel.Email = "";
- contactUsModel.Message = "";
+ contactUsModel = new();
+ isSent = true;
}
finally
{
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/CustomerCarousel.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/CustomerCarousel.razor
index 597b52675e5..2fde8368de4 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/CustomerCarousel.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/CustomerCarousel.razor
@@ -2,7 +2,7 @@
-
+ RIGID Robotics
Offers a unified and scalable Cloud Platform and Applications that gather Data in Real-time from its Sensors
@@ -12,7 +12,7 @@
-
+ CrystaCode
CrystaCode lets anyone create a real, working AI agent just by talking. No coding, no setup,
@@ -22,7 +22,7 @@
-
+ Antargyan
Serving over 450,000 students and 500+ educators, Antargyan is known for its innovative RioPlay platform.
@@ -32,7 +32,7 @@
-
+ Functionland
Want to own your files, literally? This is something that will not happen ever on traditional cloud services.
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/CustomerCarousel.razor.scss b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/CustomerCarousel.razor.scss
index 92191f378ea..5910865a165 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/CustomerCarousel.razor.scss
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/CustomerCarousel.razor.scss
@@ -21,6 +21,7 @@
}
.text-subtitle {
+ line-height: 1.5;
font-size: 2.25rem;
text-align: center;
color: $bit-color-foreground-secondary;
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/DemosPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/DemosPage.razor
index f65b8ae5a98..0051ad56eb4 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/DemosPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/DemosPage.razor
@@ -27,7 +27,7 @@
- Open source❤️
+ Open source ❤️Full stackCross platformMulti-Tenant
@@ -68,7 +68,7 @@
-
+
From active shovels in Canadian mines to logistics drivers in Sweden, over 450K students in India,
platform to maintain 3D information of 4M house units, these are just a few of the groundbreaking software
projects built on the bitplatform!
@@ -77,34 +77,29 @@
-
+
Boilerplate
-
+
The bit Boilerplate is a feature-packed project template that accelerates your development.
-
- @*
-
-
*@
-
+
The source code is yours to explore and modify! Deploy it on your own server or any cloud platform you choose.
Check out the following fully functional demo apps to see the Boilerplate in action across various platforms.
@@ -114,7 +109,7 @@
- AdminPanel
+ AdminPanel
Need a robust back-office or admin panel?
@@ -123,64 +118,64 @@
-
+
Platform website
-
+
Experience the blazing speed of bitplatform.dev.
This site was built using our own product, showcasing the exceptional performance you can achieve for your projects.
@@ -188,40 +183,40 @@
-
+
BlazorUI
-
+
A lightweight yet powerful component library for C# developers.
- It’s ideal for building consumer-facing apps and websites that are fast, responsive, and optimized for both desktop and mobile.
+ It's ideal for building consumer-facing apps and websites that are fast, responsive, and optimized for both desktop and mobile.
+
+@code {
+ private readonly ProductAccordionItem[] products =
+ [
+ new()
+ {
+ Title = "Boilerplate",
+ Subtitle = "Feature-rich .NET project template",
+ LinkUrl = Urls.Templates,
+ IsExpanded = true,
+ Body = @
- bit Boilerplate is a Visual studio and .NET project template that enables high-quality, speedy cross-platform development
+ bit Boilerplate is a Visual Studio and .NET project template that enables high-quality, speedy cross-platform development
for PWA/SSR enabled websites and Android, iOS, macOS, Windows apps.
- Butil
-
- Blazor utilities to use browser JS APIs in C#
-
-
-
-
-
-
+
+ },
+ new()
+ {
+ Title = "Butil",
+ Subtitle = "Blazor utilities to use browser JS APIs in C#",
+ LinkUrl = Urls.Butil,
+ External = true,
+ Body = @
bit Butil helps C# developers to access the browser APIs that are only accessible through JavaScript in C#.
@@ -57,79 +73,85 @@
var encryptedBytes = await crypto.Encrypt(CryptoAlgorithm.AesCbc, key, textAsUtf8Bytes, iv: iv);
}
+
+ },
+ new()
+ {
+ Title = "Bswup",
+ Subtitle = "Blazor PWA on steroids",
+ LinkUrl = Urls.Bswup,
+ External = true,
+ Body = @
bit Bswup is a set of tools that assists developers in making the most out of the Service Worker when building apps with Blazor.
+
+ },
+ new()
+ {
+ Title = "Besql",
+ Subtitle = "Blazor Entity Framework SQLite",
+ LinkUrl = Urls.Besql,
+ Body = @
bit Besql facilitates the use of Entity Framework and SQLite in web browsers with Blazor WebAssembly.
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/NotFoundPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/NotFoundPage.razor
index 8d51e4efc13..a9d2f6f5880 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/NotFoundPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/NotFoundPage.razor
@@ -2,11 +2,23 @@
@inherits AppComponentBase
-
+
+
+404
- There is nothing here: [@Url]
+ There is nothing here: [@Url]
+ Here are some helpful links instead:
+
+ Home
+ Boilerplate
+ Demos
+ Pricing
+ Contact us
+
@code {
[SupplyParameterFromQuery(Name = "url")] public string? Url { get; set; }
-}
\ No newline at end of file
+}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor
index f2e145aefc8..3ef34e569bb 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor
@@ -3,7 +3,7 @@
+ Description="bit platform is free and open source. Optional paid support packages give your team direct access to the bit core developers." />
@@ -45,23 +45,23 @@
-
+ MIT License
-
+ Unlimited commercial apps
-
+ Access to all components
-
+ Access to all project templates
-
+ Open-source support (GitHub issues)
@@ -81,27 +81,27 @@
-
+ Expert-Led Workshops
-
+ Focused Code Reviews
-
+ Performance / Security Consultation
-
+ Custom feature Development
-
+ Implement Design System / Theme
-
+ Priority support
@@ -128,7 +128,7 @@
else
{
-
+ Contact sale teamBuying the commercial package
@@ -151,4 +151,4 @@
}
-
\ No newline at end of file
+
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor.cs
index 06a4f6ad0f8..ef88091fb4a 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor.cs
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor.cs
@@ -30,12 +30,14 @@ private async Task SendMessage()
try
{
+ // ExceptionDelegatingHandler in the HttpClient pipeline throws a typed exception on any
+ // non-success response; WrapHandled on the submit button surfaces its message.
await HttpClient.PostAsJsonAsync("api/SupportPackage/BuyPackage", buyPackageModel, AppJsonContext.Default.BuyPackageDto);
+ isSent = true;
}
finally
{
isSending = false;
- isSent = true;
}
}
}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor.scss b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor.scss
index 8eb86dad7e7..d68eb3c1aef 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor.scss
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/PricingPage.razor.scss
@@ -40,9 +40,6 @@
padding-bottom: rem2(80px);
}
-.main-section {
-}
-
.mid-section {
background: $bit-color-background-secondary;
@@ -112,6 +109,11 @@
display: flex;
text-align: left;
align-items: baseline;
+
+ ::deep .plan-check-icon {
+ font-size: rem2(18px);
+ color: $bit-color-primary;
+ }
}
}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates01OverviewPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates01OverviewPage.razor
index ddb892fef8c..bdeb7d6e088 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates01OverviewPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates01OverviewPage.razor
@@ -1,15 +1,15 @@
-@page "/templates"
+@page "/templates"
@page "/templates/overview"
@page "/boilerplate"
@page "/boilerplate/overview"
@inherits AppComponentBase
-
+ Description="The bit Boilerplate project template is a production-ready .NET & Blazor foundation for building web, Android, iOS, Windows, and macOS apps from a single C# codebase." />
- bit Boilerplate
+ bit Boilerplate
If our efforts in providing modern tooling have piqued your interest, dive into the Bit Boilerplate project template.
@@ -23,7 +23,7 @@
-
@@ -106,7 +106,7 @@
Features: Business-related code organized by domain (e.g., Identity, Products, Dashboard).
-
Components: Features Client-side UI & Logic, implemented by razor, razor.csss and razor.cs (e.g., DashboardPage).
+
Components: Features Client-side UI & Logic, implemented by .razor, .razor.scss and .razor.cs (e.g., DashboardPage).
Infrastructure: Technical cross-cutting concerns not tied to a specific business domain (e.g., DbContext, Services, Middleware).
@@ -128,11 +128,11 @@
Running this project will make the features mentioned in Server.Api section available on port 5000 as well as server components for Blazor pre-rendering and Blazor Server.
- Server.AppHost: This is the app host for ASP.NET Aspire, which is optional to use.
+ Server.AppHost: This is the app host for ASP.NET Aspire, which is optional to use.
Server.Shared: The Server.Shared project includes code shared between the Server.Api and Server.Web projects.
- Optionally, it may contain code for use within ASP.NET Aspire, similar to the Aspire's `ServiceDefaults` project.
+ Optionally, it may contain code for use within ASP.NET Aspire, similar to the Aspire's ServiceDefaults project.
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04ProjectStructurePage.razor.scss b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates03ProjectStructurePage.razor.scss
similarity index 92%
rename from src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04ProjectStructurePage.razor.scss
rename to src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates03ProjectStructurePage.razor.scss
index d9635d6ca5b..cb5b8bb171e 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04ProjectStructurePage.razor.scss
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates03ProjectStructurePage.razor.scss
@@ -36,6 +36,10 @@
.row-section-container{
display:flex;
+
+ @include sm {
+ flex-direction: column;
+ }
}
.image {
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor
similarity index 88%
rename from src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor
rename to src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor
index 1e3fcefd33b..0fa32f52eaf 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor
@@ -1,20 +1,20 @@
-@page "/templates/create-project"
+@page "/templates/create-project"
@page "/boilerplate/create-project"
@inherits AppComponentBase
+ Description="Create a new project from the bit Boilerplate template and customize it with parameters like database, authentication, and CI/CD pipeline." />
- Create Project
+ Create Project
Let's make our next cross platform project a success with Bit.Boilerplate.
-
+
@GetFinalCommand()
@@ -56,20 +56,20 @@
Supported options include SqlServer, PostgreSQL, MySQL and Other.
You can use Sql Server LocalDb 2025 for development purposes.
- It gets installed within Visual Studio by default, but you can either download it from here or install it using PowerShell:
+ It gets installed within Visual Studio by default, but you can either download it from here or install it using PowerShell:
$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://download.microsoft.com/download/3/8/d/38de7036-2433-4207-8eae-06e247e17b25/SqlLocalDB.msi -OutFile SqlLocalDB.msi; msiexec /i SqlLocalDB.msi /quiet
break;
case "PostgreSQL":
- Download and install @database.Value here.
+ Download and install @database.Value here.
Alternatively, use the following command:
winget install --id=PostgreSQL.PostgreSQL.18
@@ -77,12 +77,12 @@
break;
case "MySQL":
- Both MariaDB and MySql are supported.
+ Both MariaDB and MySql are supported.
break;
case "Other":
- Add the desired database package and configure it in the AddDbContextPool method which is located in the Program.Services.cs file within the Server.Api project.
+ Add the desired database package and configure it in the AddDbContextPool method which is located in the Program.Services.cs file within the Server.Api project.
break;
}
@@ -97,7 +97,7 @@
@GetMultiTenantCommand()
- You can experience the Multi-tenancy feature instantly by logging into adminpanel.bitplatform.dev using store-user@bitplatform.dev (Password: 123456). This gives you access to a demo tenant ("Store") where you can explore the Dashboard, Products, and Categories.
+ You can experience the Multi-tenancy feature instantly by logging into adminpanel.bitplatform.dev using store-user@bitplatform.dev (Password: 123456). This gives you access to a demo tenant ("Store") where you can explore the Dashboard, Products, and Categories.
Alternatively, you can sign in using your regular Google/Gmail account to automatically create your own isolated tenant. Once inside your personal tenant, you will also gain access to advanced Identity Management features, including User and Role administration pages.
@@ -121,7 +121,7 @@
case "Local":
The API project includes an Attachment Controller responsible for handling user images,
- including resizing and saving them in the WebP format using FluentStorage
+ including resizing and saving them in the WebP format using FluentStorage
Local option stores files on local hard drive.
@@ -134,13 +134,13 @@
break;
case "S3":
- Install and configure FluentStorage.AWS, which supports Amazon S3.
+ Install and configure FluentStorage.AWS, which supports Amazon S3.
This allows you to use any file storage solution compatible with S3, such as AWS, DigitalOcean Spaces, MinIO, Hetzner, Contabo etc.
Ensure a rapid and reliable deployment by utilizing a pipeline.
- By selecting GitHub, CI/ CD pipelines will be set up using Github Actions.
+ By selecting GitHub, CI/ CD pipelines will be set up using Github Actions.
break;
case "Azure":
- By selecting Azure, CI/ CD pipelines will be set up using Azure Devops.
+ By selecting Azure, CI/ CD pipelines will be set up using Azure Devops.
break;
}
@@ -218,9 +218,9 @@
@GetAspireCommand()
- Aspire helps you build, test, and deploy distributed applications with ease. Learn more at ASP.NET Core Aspire.
+ Aspire helps you build, test, and deploy distributed applications with ease. Learn more at ASP.NET Core Aspire.
dotnet tool install -g Aspire.Cli
- Aspire requires Docker Desktop to be installed and running. Download and install Docker Desktop from here.
+ Aspire requires Docker Desktop to be installed and running. Download and install Docker Desktop from here.
@@ -243,7 +243,7 @@
-
+
}
else
@@ -253,7 +253,7 @@
-
+
}
@@ -269,7 +269,7 @@
@GetModuleCommand()
Use this parameter to initialize the project with a module.
- The two available options are Admin Panel and Sales.
+ The two available options are Admin Panel and Sales.
@@ -292,8 +292,8 @@
else
{
- To integrate Google reCAPTCHA into
- the app, include --captcha reCaptcha in the dotnet new command. Live demo
+ To integrate Google reCAPTCHA into
+ the app, include --captcha reCaptcha in the dotnet new command. Live demo
}
@@ -321,7 +321,7 @@
@GetSampleCommand()
Use this parameter to initialize the project with a sample pages.
- Checkout demo sample at Todo.
+ Checkout demo sample at Todo.
@@ -405,7 +405,7 @@
@GetGoogleAdsCommand()
- Helps you earn money by displaying reward-based Google ads. Demo
+ Helps you earn money by displaying reward-based Google ads. Demo
@@ -432,12 +432,12 @@
-
+
-
+
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor.cs
similarity index 99%
rename from src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor.cs
rename to src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor.cs
index 77a87d7a461..1c6b4260ecc 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor.cs
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor.cs
@@ -1,8 +1,8 @@
-using System.Text;
+using System.Text;
namespace Bit.Websites.Platform.Client.Pages.Templates;
-public partial class Templates05CreateProjectPage
+public partial class Templates04CreateProjectPage
{
private string name = "MyFirstProject";
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor.scss b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor.scss
similarity index 84%
rename from src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor.scss
rename to src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor.scss
index 5f1dafec353..6c57ead00ac 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05CreateProjectPage.razor.scss
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates04CreateProjectPage.razor.scss
@@ -29,7 +29,14 @@
.image {
@include Image;
+
+ // The Image mixin's fixed 85% height distorts these diagrams inside the 350px-tall
+ // .api-image-container; scale the height from the intrinsic ratio instead and cap both axes
+ // (the max-height leaves room for the mixin's 25px vertical margins).
+ height: auto;
width: rem2(600px);
+ max-width: 100%;
+ max-height: calc(100% - #{rem2(50px)});
}
::deep a {
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06RunProjectPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05RunProjectPage.razor
similarity index 90%
rename from src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06RunProjectPage.razor
rename to src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05RunProjectPage.razor
index c44558c1e2a..2127596f579 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06RunProjectPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05RunProjectPage.razor
@@ -1,13 +1,13 @@
-@page "/templates/run-project"
+@page "/templates/run-project"
@page "/boilerplate/run-project"
@inherits AppComponentBase
+ Description="Build and run your bit Boilerplate project on web, Android, iOS, Windows, and macOS." />
- Project Run
+ Run project
@@ -45,12 +45,12 @@
Development Environment
The project is configured to use Blazor Server as the default mode to enhance the development experience,
- enabling features such as Visual Studio .NET Hot Reload
- and dotnet watch. To utilize the Hot Reload feature,
+ enabling features such as Visual Studio .NET Hot Reload
+ and dotnet watch. To utilize the Hot Reload feature,
ensure that you have the latest versions of Visual Studio and the .NET SDK.
This setup allows for automatic application of changes made to .razor,
.scss, or .cs files without the need to rebuild the project. If any changes to these files do not take effect without a rebuild, please feel free to create an issue
- here.
+ here.
@@ -88,7 +88,7 @@
If you're developing on Windows, it is recommended to run bash ./Clean.sh inside container the first time you open the project.
-
+
@@ -112,11 +112,11 @@
"ServerAddress": "https://r3c136gg-5030.euw.devtunnels.ms"
- For additional details about dev tunnels, please refer to the following video and docs.
+ For additional details about dev tunnels, please refer to the following video and docs.
-
@@ -143,7 +143,7 @@
-
@@ -160,7 +160,7 @@
-
@@ -170,7 +170,7 @@
-
@@ -180,7 +180,7 @@
-
@@ -194,7 +194,7 @@
Run MAUI in Visual Studio for iOS, Android
Running your project on Android, Windows, and Web using Visual Studio is straightforward. However, testing a macOS version with Visual Studio isn't possible.
For iOS, if you have a Mac connected to the same network as your Windows PC, you can follow
- this documentation
+ this documentation
to connect your Visual Studio to the mac device and run the iOS project using Visual Studio while coding on Windows.
@@ -204,7 +204,7 @@
-
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05RunProjectPage.razor.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05RunProjectPage.razor.cs
new file mode 100644
index 00000000000..a7a2d20d1cc
--- /dev/null
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05RunProjectPage.razor.cs
@@ -0,0 +1,5 @@
+namespace Bit.Websites.Platform.Client.Pages.Templates;
+
+public partial class Templates05RunProjectPage
+{
+}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06RunProjectPage.razor.scss b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05RunProjectPage.razor.scss
similarity index 100%
rename from src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06RunProjectPage.razor.scss
rename to src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates05RunProjectPage.razor.scss
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06RunProjectPage.razor.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06RunProjectPage.razor.cs
deleted file mode 100644
index 18d155bdef7..00000000000
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06RunProjectPage.razor.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace Bit.Websites.Platform.Client.Pages.Templates;
-
-public partial class Templates06RunProjectPage
-{
-}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates07Wiki.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06Wiki.razor
similarity index 79%
rename from src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates07Wiki.razor
rename to src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06Wiki.razor
index 54f930e05db..c18978c18f7 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates07Wiki.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06Wiki.razor
@@ -4,10 +4,10 @@
+ Description="Deep-dive articles in the bit Boilerplate wiki: architecture, authentication, deployment, and more." />
- Wiki
+ Wiki
@@ -22,7 +22,7 @@
-
+
@@ -42,7 +42,7 @@
Stage 2: DTOs, Mappers, and Mapperly
-
Explore Data Transfer Objects, `AppJsonContext`, and how Mapperly simplifies object mapping. Learn the difference between Project() and Map() methods, and how Patch() updates client-side objects.
+
Explore Data Transfer Objects, AppJsonContext, and how Mapperly simplifies object mapping. Learn the difference between Project() and Map() methods, and how Patch() updates client-side objects.
@@ -57,12 +57,12 @@
Stage 5: Localization and Multi-language Support
-
Master resource files (resx), `DtoResourceType` attribute, `AppDataAnnotationsValidator`, IStringLocalizer usage, and the `bit-resx` tool for managing translations.
+
Master resource files (resx), DtoResourceType attribute, AppDataAnnotationsValidator, IStringLocalizer usage, and the bit-resx tool for managing translations.
Stage 6: Exception Handling and Error Management
-
Learn about Known vs Unknown exceptions, safe exception throwing, `WithData()` and `WithExtensionData()` methods, automatic exception handling in Blazor, and `WrapHandled()` for event handlers.
+
Learn about Known vs Unknown exceptions, safe exception throwing, WithData() and WithExtensionData() methods, automatic exception handling in Blazor, and WrapHandled() for event handlers.
Understand the three-file structure (.razor, .razor.cs, .razor.scss), isolated component styles, global styles, ::deep selector, Bit.BlazorUI components, and navigation with `PageUrls`.
+
Understand the three-file structure (.razor, .razor.cs, .razor.scss), isolated component styles, global styles, ::deep selector, Bit.BlazorUI components, and navigation with PageUrls.
Stage 9: Dependency Injection & Service Registration
-
Explore service registration patterns across different projects, `AddSessioned` method for session-scoped services, and appropriate service lifetimes (Singleton, Scoped, Transient, `Sessioned`).
+
Explore service registration patterns across different projects, AddSessioned method for session-scoped services, and appropriate service lifetimes (Singleton, Scoped, Transient, Sessioned).
@@ -87,27 +87,27 @@
Stage 11: TypeScript, Build Process & JavaScript Interop
-
Understand TypeScript integration, MSBuild targets for JavaScript compilation, `IJSRuntimeExtensions` for C#-to-JS calls, and how to add npm packages with type definitions.
+
Understand TypeScript integration, MSBuild targets for JavaScript compilation, IJSRuntimeExtensions for C#-to-JS calls, and how to add npm packages with type definitions.
Stage 12: Blazor Modes, PreRendering & PWA
-
Explore Blazor Server, WebAssembly, and Auto modes, pre-rendering configuration for SEO and performance, PWA capabilities, service workers, and `IPrerenderStateService`.
+
Explore Blazor Server, WebAssembly, and Auto modes, pre-rendering configuration for SEO and performance, PWA capabilities, service workers, and IPrerenderStateService.
Stage 13: Force Update System
-
Learn how `ForceUpdateMiddleware` validates app versions on every request, supports platform-specific update behaviors (auto-update for web/Windows, store redirect for mobile), and ensures all users run supported versions.
+
Learn how ForceUpdateMiddleware validates app versions on every request, supports platform-specific update behaviors (auto-update for web/Windows, store redirect for mobile), and ensures all users run supported versions.
Stage 14: Response Caching System
-
Master multi-layer caching: client-side memory cache, browser HTTP cache, CDN edge cache, and ASP.NET Core Output Cache. Learn about `AppResponseCache` attribute, cache purging with `ResponseCacheService`, and optimizing performance.
+
Master multi-layer caching: client-side memory cache, browser HTTP cache, CDN edge cache, and ASP.NET Core Output Cache. Learn about AppResponseCache attribute, cache purging with ResponseCacheService, and optimizing performance.
Stage 15: Logging, OpenTelemetry and Health Checks
-
Understand ILogger for logging, `ActivitySource` and `Meter` for tracking operations, in-app Diagnostic Modal, integration with Sentry and Azure App Insights, Aspire Dashboard, and built-in health checks.
+
Understand ILogger for logging, ActivitySource and Meter for tracking operations, in-app Diagnostic Modal, integration with Sentry and Azure App Insights, Aspire Dashboard, and built-in health checks.
@@ -137,12 +137,12 @@
Stage 21: .NET MAUI / Blazor Hybrid
-
Explore native platform capabilities on Android, iOS, macOS, and Windows. Learn about Deep Links/Universal Links, `ApplicationVersion` for app stores, Windows project advantages, and WebView considerations.
+
Explore native platform capabilities on Android, iOS, macOS, and Windows. Learn about Deep Links/Universal Links, ApplicationVersion for app stores, Windows project advantages, and WebView considerations.
Stage 22: Messaging
-
Master in-app messaging with `PubSubService`, JavaScript-to-C# communication with `AppJsBridge`, real-time server-to-client messaging with SignalR, and push notifications with deep linking.
+
Master in-app messaging with PubSubService, JavaScript-to-C# communication with AppJsBridge, real-time server-to-client messaging with SignalR, and push notifications with deep linking.
@@ -164,25 +164,19 @@
AI-Powered Wiki
- You can also visit wiki.bitplatform.dev anytime to ask questions about bit Boilerplate and the entire bitplatform ecosystem.
+ You can also visit wiki.bitplatform.dev anytime to ask questions about bit Boilerplate and the entire bitplatform ecosystem.
To enhance the understanding of our Open Source Project Repository, all documentation is maintained within a single mono repo. This approach ensures that the AI Wiki can cohesively analyze the entire set of documents, README files, in-code comments, and source code to provide comprehensive insights when queried.
What is the optimal way to load page data using StateHasChanged in conjunction with a Skeleton UI or Shimmer? Link
-
-
How can I remove google reCAPTCHA from a project I created from bit Boilerplate? Link
-
-
What is the difference between Patch and Map, and what is their relationship with Entity Framework Core and Blazor change tracking? Link
-
-
How can I implement a Grid System and layout using BitGrid and BitStack components, especially if I'm familiar with the Bootstrap grid system? Link
-
-
How does a refresh token function in a Boilerplate project template? Link
-
-
How does passwordless authentication work in Boilerplate, particularly in Blazor Hybrid versions of the app, given that this feature is browser-only? Link
-
-
How does using embeddings with the PostgreSQL vector extension enable product search functionality via LINQ and Entity Framework Core? Link
+
What is the optimal way to load page data using StateHasChanged in conjunction with a Skeleton UI or Shimmer? Link
+
How can I remove google reCAPTCHA from a project I created from bit Boilerplate? Link
+
What is the difference between Patch and Map, and what is their relationship with Entity Framework Core and Blazor change tracking? Link
+
How can I implement a Grid System and layout using BitGrid and BitStack components, especially if I'm familiar with the Bootstrap grid system? Link
+
How does a refresh token function in a Boilerplate project template? Link
+
How does passwordless authentication work in Boilerplate, particularly in Blazor Hybrid versions of the app, given that this feature is browser-only? Link
+
How does using embeddings with the PostgreSQL vector extension enable product search functionality via LINQ and Entity Framework Core? Link
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06Wiki.razor.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06Wiki.razor.cs
new file mode 100644
index 00000000000..08ace6fae6e
--- /dev/null
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06Wiki.razor.cs
@@ -0,0 +1,5 @@
+namespace Bit.Websites.Platform.Client.Pages.Templates;
+
+public partial class Templates06Wiki
+{
+}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates07Wiki.razor.scss b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06Wiki.razor.scss
similarity index 100%
rename from src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates07Wiki.razor.scss
rename to src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates06Wiki.razor.scss
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates07Wiki.razor.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates07Wiki.razor.cs
deleted file mode 100644
index 24174b51fa4..00000000000
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates07Wiki.razor.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace Bit.Websites.Platform.Client.Pages.Templates;
-
-public partial class Templates07Wiki
-{
-}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Program.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Program.cs
index 7b5b7e71994..a9ca5e8934c 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Program.cs
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Program.cs
@@ -12,7 +12,7 @@
apiServerAddress = new Uri($"{builder.HostEnvironment.BaseAddress}{apiServerAddress}");
}
-builder.Services.AddSingleton(sp => new HttpClient(sp.GetRequiredService()) { BaseAddress = apiServerAddress });
+builder.Services.AddSingleton(sp => new HttpClient(sp.GetRequiredService()) { BaseAddress = apiServerAddress });
builder.Services.AddClientSharedServices();
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Scripts/app.ts b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Scripts/app.ts
index d5d28313e8a..1d32c22be01 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Scripts/app.ts
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Scripts/app.ts
@@ -12,21 +12,31 @@ function goToTop() {
window.scrollTo({ top: 0 });
}
-declare class BitTheme { static init(options: any): void; };
+// Closes CSS :hover/:focus-within driven popups (e.g. the header products menu) from C#: after a tap
+// or an Escape press the trigger keeps focus, so the popup would stay open until focus moves away.
+function blurActiveElement() {
+ (document.activeElement as HTMLElement | null)?.blur?.();
+}
+
+declare namespace BitBlazorUI {
+ class Theme { static init(options: any): void; }
+}
-BitTheme.init({
- //system: true,
- default: 'dark',
+// Theme-dependent styling keys off the bit-theme attribute the library script keeps on the document
+// element (:root[bit-theme=...] selectors in the stylesheets), so this callback only has to maintain
+// what CSS cannot reach: the browser chrome color.
+BitBlazorUI.Theme.init({
+ system: true,
persist: true,
- onChange: (newTheme: string, oldThem: string) => {
- if (newTheme === 'dark') {
- document.body.classList.add('bit-platform-dark-theme');
- document.body.classList.remove('bit-platform-light-theme');
- document.querySelector("meta[name=theme-color]")?.setAttribute('content', '#060E2D');
- } else {
- document.body.classList.add('bit-platform-light-theme');
- document.body.classList.remove('bit-platform-dark-theme');
- document.querySelector("meta[name=theme-color]")?.setAttribute('content', '#FFFFFF');
- }
+ // Mirror every theme change into the bit-theme-preference cookie so the server can paint the
+ // right theme into the prerendered markup (see App.razor). Without it the server would fall back
+ // to guessing and the page would flash the wrong theme for visitors who picked one.
+ persistCookie: true,
+ onChange: (newTheme: string, oldTheme: string) => {
+ // Same dark-name predicate and hex values (--bit-clr-bg-pri of each palette) as the
+ // first-paint bootstrap in the server's App.razor - keep the two in sync.
+ const name = (newTheme ?? '').toLowerCase();
+ const isDark = name === 'dark' || name.endsWith('-dark');
+ document.querySelector("meta[name=theme-color]")?.setAttribute('content', isDark ? '#060E2D' : '#FFFFFF');
}
-});
\ No newline at end of file
+});
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/HttpMessageHandlers/RetryDelegatingHandler.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/HttpMessageHandlers/RetryDelegatingHandler.cs
index 40376916f88..bb08b792f3f 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/HttpMessageHandlers/RetryDelegatingHandler.cs
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/HttpMessageHandlers/RetryDelegatingHandler.cs
@@ -6,6 +6,13 @@ public class RetryDelegatingHandler(ExceptionDelegatingHandler handler)
protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
+ if (request.Method != HttpMethod.Get)
+ {
+ // Retrying a non-idempotent request that already reached the server would repeat its
+ // side effect (e.g. re-delivering a contact-us message on a transient failure).
+ return await base.SendAsync(request, cancellationToken);
+ }
+
var delays = GetDelays(scaleFirstTry: TimeSpan.FromSeconds(3), maxRetries: 3).ToArray();
Exception? lastExp = null;
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/NavManuService.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/NavManuService.cs
deleted file mode 100644
index dfb28f71791..00000000000
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/NavManuService.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Bit.Websites.Platform.Client.Services;
-
-public class NavManuService
-{
- public event Func OnToggleMenu = default!;
-
- public void ToggleMenu()
- {
- OnToggleMenu.Invoke();
- }
-}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/NavMenuService.cs b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/NavMenuService.cs
new file mode 100644
index 00000000000..c33d3f84730
--- /dev/null
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Services/NavMenuService.cs
@@ -0,0 +1,54 @@
+namespace Bit.Websites.Platform.Client.Services;
+
+///
+/// Owns the docs nav menu toggle and the URL-derived route flags, so Header (which renders the docs
+/// hamburger trigger) and MainLayout (which mounts the NavMenu it toggles) can never disagree about
+/// which routes count as docs routes.
+///
+public class NavMenuService
+{
+ public event Func? OnToggleMenu;
+
+ ///
+ /// No-ops when NavMenu is not mounted (Header renders the trigger on docs routes before
+ /// NavMenu subscribes), and awaits the handler so its exceptions surface instead of being lost.
+ ///
+ public Task ToggleMenu()
+ {
+ return OnToggleMenu?.Invoke() ?? Task.CompletedTask;
+ }
+
+
+ /// Current base-relative path, without query or fragment, with a leading slash.
+ public string CurrentUrl { get; private set; } = "/";
+
+ public bool IsTemplateDocRoute { get; private set; }
+ public bool IsBesqlDocRoute { get; private set; }
+ public bool IsLcncDocRoute { get; private set; }
+
+ ///
+ /// Docs routes get the docs nav menu (hamburger); Lcnc has no docs yet, so it is excluded here,
+ /// but it still counts as a product route for highlighting the Products menu trigger.
+ ///
+ public bool IsDocsRoute => IsTemplateDocRoute || IsBesqlDocRoute;
+
+ public bool IsProductsRoute => IsDocsRoute || IsLcncDocRoute;
+
+ ///
+ /// Idempotent; called by every component that reacts to LocationChanged, whichever fires first.
+ ///
+ public void UpdateRouteFlags(string currentUrl)
+ {
+ var fragmentIndex = currentUrl.IndexOfAny(['?', '#']);
+ if (fragmentIndex >= 0)
+ {
+ currentUrl = currentUrl[..fragmentIndex];
+ }
+
+ CurrentUrl = currentUrl;
+
+ IsTemplateDocRoute = currentUrl.Contains("/templates") || currentUrl.Contains("/boilerplate");
+ IsBesqlDocRoute = currentUrl.Contains("/besql");
+ IsLcncDocRoute = currentUrl.Contains("/lowcode-nocode");
+ }
+}
diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Shared/AppAiChatPanel.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Shared/AppAiChatPanel.razor
index 8cdaa33d0a5..b244921017a 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Shared/AppAiChatPanel.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Shared/AppAiChatPanel.razor
@@ -1,4 +1,4 @@
-@using Bit.Websites.Platform.Shared.Dtos.AiChat
+@using Bit.Websites.Platform.Shared.Dtos.AiChat
@inherits AppComponentBase
@@ -72,7 +72,7 @@
@if (chatMessages.Count == 1)
{
-
+
-
+
Oops, something went wrong...
@if (showException)
@@ -19,8 +19,8 @@ else if (ErrorContent is null)
+
+ @* The mouseenter handler is attached only while force-closed is set (it just lifts that
+ flag), so the common hover path stays pure CSS with no interop roundtrip or re-render. *@
+
(HandleProductsMenuKeyDown)">
+
+
+ @foreach (var column in productMenuColumns)
+ {
+