diff --git a/README.md b/README.md index 725b5d48c9..eb4c06bd75 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ## Introduction -The `Microsoft.Fast.Components.FluentUI` package provides a lightweight set of [Blazor](https://blazor.net) component wrappers around Microsoft's official FluentUI Web Components. The FluentUI Web Components are built on [FAST](https://www.fast.design/) and work in every major browser. To get up and running with `Microsoft.Fast.Components.FluentUI` see the Getting Started section below. +The `Microsoft.Fast.Components.FluentUI` package provides a set of [Blazor](https://blazor.net) component wrappers around Microsoft's official FluentUI Web Components. The FluentUI Web Components are built on [FAST](https://www.fast.design/) and work in every major browser. To get up and running with `Microsoft.Fast.Components.FluentUI` see the Getting Started section below. The source for `@fluentui/web-components` is hosted in the [Fluent UI](https://github.com/microsoft/fluentui/tree/master/packages/web-components) mono-repository. Documentation on the components is available on [docs.microsoft.com](https://docs.microsoft.com/en-us/fluent-ui/web-components/). @@ -36,6 +36,9 @@ To add the script from CDN use the following markup: ```html ``` +> :notebook: **Note** +> +> If you prefer to use another CDN, that is entirely possible. Just make sure it is offering the Fluent UI package and you are getting the right `web-components.min.js` file) The markup above always references the latest release of the components. When deploying to production, you will want to ship with a specific version. Here's an example of the markup for that: @@ -43,7 +46,7 @@ The markup above always references the latest release of the components. When de ``` -The best place to put the script tag is typically in your `index.html` (`_Layout.cshtml` for blazor server project) file in the script section at the bottom of the ``. +The best place to put the script tag is typically in your `index.html` (`_Layout.cshtml` for Blazor server project) file in the script section at the bottom of the ``. If you wish to leverage NPM instead, run the following command: @@ -64,27 +67,25 @@ Copy this to your `wwwroot/script` folder and reference it with a script tag as > If you are setting up Fluent UI Web Components on a Blazor Server project, you will need to escape the `@` character by repeating it in the source link. For more information check out the [Razor Pages syntax documentation](https://docs.microsoft.com/aspnet/core/mvc/views/razor). ### Styles -In order for this library to work as expected, you will need to add to your `index.html` or `_Layout.cshtml` a line that includes the composed scoped CSS for the components. This can be done by adding the following line to the `` section of your `index.html` or `_Layout.cshtml` file: +In order for this library to work as expected, you will need to add to your `index.html` or `_Layout.cshtml` a line that includes the composed scoped CSS for the components. This can be done by adding the following line to the `` section: ```html - + ``` -It is possible that the line is already there (but commented out) if you used the Blazor WebAssembly template. If you are using the Blazor Server template, you will need to add it yourself. +It is possible that the line is already in place (but commented out). #### Reboot +Reboot is a collection of element-specific CSS changes in a single file to help kick-start building a site with the Fluent UI Web Components for Blazor. It provides an elegant, consistent, and simple baseline to build upon. - Reboot is a collection of element-specific CSS changes in a single file to help kickstart building a site with the Fluent UI Web - components for Blazor. It provides an elegant, consistent, and simple baseline to build upon. - -If you want to use Reboot, you'll need to include it in your `index.html` or `_Layout.cshtml` file like this: +If you want to use Reboot, you'll need to add to your `index.html` or `_Layout.cshtml` file a line that includes the stylesheet (`.css` file). This can be done by adding the following line to the `` section: ```html ``` It is entirely possible to build a site without using Reboot. If you choose not to use it, please do add the `variables.css` file (which is otherwise imported through the `reboot.css` file) -to your `index.html` or `_Layout.cshtml` file like this: +to your `index.html` or `_Layout.cshtml` file in the `` section like this: ```html @@ -94,18 +95,15 @@ The file contains a number of CSS variables that are required to be defined for ### Code - In your Program.cs file you need to add the following: ```csharp builder.Services.AddFluentUIComponents(); ``` -This addition makes sure a `HttpClient` is set up for when you are using the library in Blazor Server. - +This addition makes sure all the necessary services the library uses are setup in a correct way. ### Using the FluentUI Web Components - With the package installed and the script configured, you can begin using the Fluent UI Web Components in the same way as any other Blazor component. Just be sure to add the following using statement to your views: ```razor @@ -124,12 +122,11 @@ Here's a small example of a `FluentCard` with a `FluentButton` that uses the Flu ``` > :bulb: **Tip** > -> You can add `@using Microsoft.Fast.Components.FluentUI` to the namespace collection in `_Imports.razor`, so that you can avoid repeating it in every single razor page. +> You can add `@using Microsoft.Fast.Components.FluentUI` to the namespace collection in `_Imports.razor`, so that you can avoid having to repeat it in every single razor page. ### Configuring the Design System - -The Fluent UI Web Components are built on FAST's Adaptive UI technology, which enables design customization and personalization, while automatically maintaining accessibility. This is accomplished through setting various "Design Tokens". As of version 1.4 you can use all of the (160) individual Design Tokens, both from code as in a declarative way in your `.razor` pages. See https://docs.microsoft.com/en-us/fluent-ui/web-components/design-system/design-tokens for more information on how Design Tokens work +The Fluent UI Web Components are built on FAST's Adaptive UI technology, which enables design customization and personalization, while automatically maintaining accessibility. This is accomplished through setting various "Design Tokens". The library exposes all of the (over 160) Design Tokens, which you can use both from code as in a declarative way in your `.razor` pages. See https://docs.microsoft.com/en-us/fluent-ui/web-components/design-system/design-tokens for more information on how Design Tokens work #### Option 1: Using Design Tokens from C# code @@ -184,7 +181,6 @@ protected override async Task OnAfterRenderAsync(bool firstRender) StateHasChanged(); } - } public async Task OnClick() @@ -193,7 +189,7 @@ public async Task OnClick() await StrokeWidth.DeleteValueFor(ref4!.Element); } ``` -As can be seen in the code above (with the `ref4.Element`), it is posible to apply multiple tokens to the same component. +As can be seen in the code above (with the `ref4.Element`), it is possible to apply multiple tokens to the same component. For Design Tokens that work with a color value, you must call the `ToSwatch()` extension method on a string value or use one of the `Swatch` constructors. This makes sure the color is using a format that Design Tokens can handle. A `Swatch` has a lot of commonality with the `System.Drawing.Color` struct. Instead of the values of the components being between 0 and 255, in a `Swatch` they are expressed as a value between 0 and 1. @@ -226,7 +222,7 @@ To make this work, a link needs to be created between the Design Token component #### Option 3: Using the `` -The third way to customize the design in Blazor is to wrap the entire block you want to manipulate in a ``. This special element has a number of properties you can set to configure a subset of the tokens. **Not all tokens are available/supported** and we recommend this to only be used as a fall-back mechanism. The preferred mehod of working with the desgn tokens is to manipulate them from code as described in option 1. +The third way to customize the design in Blazor is to wrap the entire block you want to manipulate in a ``. This special element has a number of properties you can set to configure a subset of the tokens. **Not all tokens are available/supported** and we recommend this to only be used as a fall-back mechanism. The preferred method of working with the design tokens is to manipulate them from code as described in option 1. Here's an example of changing the "accent base color" and switching the system into dark mode (in the file `app.razor`): @@ -266,57 +262,88 @@ Product | AccentBaseColor For a list of all available token attributes, [see here](https://github.com/microsoft/fast-blazor/blob/main/src/Microsoft.Fast.Components.FluentUI/Components/FluentDesignSystemProvider.razor#L69). More examples for other components can be found in the `examples` folder [of this repository](https://github.com/microsoft/fast-blazor). +## Blazor Hybrid +Starting with the 2.0 release, you can also use this library in your Blazor Hybrid projects. Setup is almost the same as described in the "Getting started" section above, but to get everything to work you'll need to take two extra steps: +1. You need to add a MAUI specific IStaticAssetService implementation. + Due to some issues, this file can't be part of the library (yet) so this needs to be added manually to your MAUI Blazor project. +Create a new class in you project called `FileBasedStaticAssetService.cs` Replace it's contents with the following: +```csharp +using System.Net; +using Microsoft.Fast.Components.FluentUI.Infrastructure; + +namespace Microsoft.Fast.Components.FluentUI; + +public class FileBasedStaticAssetService : IStaticAssetService +{ + private readonly CacheStorageAccessor _cacheStorageAccessor; + + public FileBasedStaticAssetService(CacheStorageAccessor cacheStorageAccessor) + { + _cacheStorageAccessor = cacheStorageAccessor; + } + + public async Task GetAsync(string assetUrl, bool useCache = true) + { + string result = null; + + HttpRequestMessage message = CreateMessage(assetUrl); + + + if (useCache) + { + // Get the result from the cache + result = await _cacheStorageAccessor.GetAsync(message); + } + + if (string.IsNullOrEmpty(result)) + { + //It not in the cache (or cache not used), read the asset from disk + result = await ReadData(assetUrl); + + if (!string.IsNullOrEmpty(result)) + { + if (useCache) + { + // If successful, create the response and store in the cache (when used) + HttpResponseMessage response = new() + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(result) + }; + + await _cacheStorageAccessor.PutAsync(message, response); + } + } + } + + return result; + } + + private static HttpRequestMessage CreateMessage(string url) => new(HttpMethod.Get, url); + + private static async Task ReadData(string file) + { + using var stream = await FileSystem.OpenAppPackageFileAsync($"wwwroot/{file}"); + using var reader = new StreamReader(stream); + + return await reader.ReadToEndAsync(); + } +} +``` -## Web components / Blazor components mapping, implementation status and remarks -Web component | Blazor component | Status | Remarks ------------------ | -------------- | ------ | ------- -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/accordion)|``|✔️|-| -|``|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/anchor)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/anchored-region)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/badge)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/breadcrumb)|``|✔️|-| -|``|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/button)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/card)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/checkbox)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/combobox)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/data-grid)|``|✔️|-| -|``|``|✔️|-| -|``|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/provider)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/dialog)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/divider)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/flipper)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/horizontal-scroll)|``|✔️|-| -|No web component|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/listbox)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/menu)|``|✔️|-| -|``|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/number-field)|``|✔️|-| -|``|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/progress)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/progress-ring)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/radio-group)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/radio-group)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/select)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/skeleton)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/slider)|``|✔️|-| -|``|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/switch)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/tabs)|``|✔️|-| -|``|``|✔️|-| -|``|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/text-area)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/text-field)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/toolbar)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/tooltip)|``|✔️|-| -|[``](https://docs.microsoft.com/en-us/fluent-ui/web-components/components/tree-view)|``|✔️|-| -|``|``|✔️|-| +2. You need to make some changes in your `MauiProgram.cs` file +Make sure the following is added before the `return builder.Build()` line: +```csharp +builder.Services.AddFluentUIComponents(options => +{ + options.HostingModel = BlazorHostingModel.Hybrid; +}); +builder.Services.AddScoped(); +``` ## Joining the Community -Looking to get answers to questions or engage with us in realtime? Our community is most active [on Discord](https://discord.gg/FcSNfg4). Submit requests and issues on [GitHub](https://github.com/dotnet/blazor-fluentui/issues/new/choose), or join us by contributing on [some good first issues via GitHub](https://github.com/dotnet/blazor-fluentui/labels/community:good-first-issue). +Looking to get answers to questions or engage with us in real-time? Our community is most active [on Discord](https://discord.gg/FcSNfg4). Submit requests and issues on [GitHub](https://github.com/dotnet/blazor-fluentui/issues/new/choose), or join us by contributing on [some good first issues via GitHub](https://github.com/dotnet/blazor-fluentui/labels/community:good-first-issue). If you don't find a component you're looking for, it's best to create the issue in our FAST repo [here](https://github.com/microsoft/fast) and limit issues on this repo to bugs in the Blazor component wrappers or Blazor-specific features. diff --git a/examples/FluentUI.Demo.Shared/Pages/Index/Index.razor b/examples/FluentUI.Demo.Shared/Pages/Index/Index.razor index 46a8989591..d75b25b8ca 100644 --- a/examples/FluentUI.Demo.Shared/Pages/Index/Index.razor +++ b/examples/FluentUI.Demo.Shared/Pages/Index/Index.razor @@ -7,7 +7,7 @@

Welcome to the Fluent UI Web Components for Blazor library

Introduction

-

The Microsoft.Fast.Components.FluentUI package provides a lightweight set of Blazor component wrappers around Microsoft's official Fluent UI Web Components. The Fluent UI Web Components are built on FAST and work in every major browser. To get up and running with Microsoft.Fast.Components.FluentUI see the Getting Started section below.

+

The Microsoft.Fast.Components.FluentUI package provides a set of Blazor component wrappers around Microsoft's official Fluent UI Web Components. The Fluent UI Web Components are built on FAST and work in every major browser. To get up and running with Microsoft.Fast.Components.FluentUI see the Getting Started section below.

The source for @@fluentui/web-components is hosted in the Fluent UI mono-repository. Documentation on the components is available on docs.microsoft.com.

Getting Started

@@ -19,6 +19,11 @@

To add the script from CDN use the following markup:

<script type="module" src="https://cdn.jsdelivr.net/npm/@@fluentui/web-components/dist/web-components.min.js"></script> +
+

Note

+

If you prefer to use another CDN, that is entirely possible. Just make sure it is offering the Fluent UI package and you are getting the right web-components.min.js file)

+
+

The markup above always references the latest release of the components. When deploying to production, you will want to ship with a specific version. Here’s an example of the markup for that:

<script type="module" src="https://cdn.jsdelivr.net/npm/@@fluentui/web-components@2.0.2/dist/web-components.min.js"></script> @@ -43,7 +48,7 @@

<link href="{PROJECT_NAME}.styles.css" rel="stylesheet" />

- It is possible that the line is already there (but commented out) if you used the Blazor WebAssembly template. If you are using the Blazor Server template, you will need to add it yourself. + It is possible that the line is already there (but commented out).

Reboot

@@ -52,12 +57,12 @@ components for Blazor. It provides an elegant, consistent, and simple baseline to build upon.

- If you want to use Reboot, you'll need to include it in your index.html or _Layout.cshtml file like this: + If you want to use Reboot, you'll need to add to your index.html or _Layout.cshtml file a line that includes the stylesheet (.css file). This can be done by adding the following line to the <head> section: <link href="_content/Microsoft.Fast.Components.FluentUI/css/reboot.css" rel="stylesheet" />

It is entirely possible to build a site without using Reboot. If you choose not to use it, please do add the variables.css file (which is otherwise imported through the reboot.css file) - to your index.html or _Layout.cshtml file like this: + to your index.html or _Layout.cshtml file in the <head> section like this: <link href="_content/Microsoft.Fast.Components.FluentUI/css/variables.css" rel="stylesheet" /> The file contains a number of CSS variables that are required to be defined for the components to work correctly.

@@ -65,7 +70,7 @@

In your Program.cs file you need to add the following:

builder.Services.AddFluentUIComponents(); -

This addition makes sure a HttpClient is set up for when you are using the library in Blazor Server.

+

This addition makes sure all the necessary services the library uses are setup in a correct way.

Using the Fluent UI Web Components

@@ -89,7 +94,7 @@

Configuring the Design System

The Fluent UI Web Components are built on FAST’s Adaptive UI technology, which enables design customization and personalization, while automatically maintaining accessibility. This is accomplished through setting various “Design Tokens”. - You can use all of the (~160) individual Design Tokens, both from code as in a declarative way in your .razor pages. See https://docs.microsoft.com/en-us/fluent-ui/web-components/design-system/design-tokens for more information on how Design Tokens work + The library exposes all of the (over 160) Design Tokens, which you can use both from code as in a declarative way in your .razor pages. See https://docs.microsoft.com/en-us/fluent-ui/web-components/design-system/design-tokens for more information on how Design Tokens work

@@ -188,6 +193,91 @@

The result looks like this when applied to a <FluentButton>:

+

Blazor Hybrid

+

+ Starting with the 2.0 release, you can also use this library in your Blazor Hybrid projects. Setup is almost the same as described in the "Getting started" section above, but to get everything to work you'll need to take two extra steps: +

+
    +
  1. + You need to add a MAUI specific IStaticAssetService implementation.
    + Due to some issues, this file can't be part of the library (yet) so this needs to be added manually to your MAUI Blazor project.
    + Create a new class in you project called FileBasedStaticAssetService.cs Replace it's contents with the following: +
  2. +
+using System.Net; +using Microsoft.Fast.Components.FluentUI.Infrastructure; + +namespace Microsoft.Fast.Components.FluentUI; + +public class FileBasedStaticAssetService : IStaticAssetService +{ + private readonly CacheStorageAccessor _cacheStorageAccessor; + + public FileBasedStaticAssetService(CacheStorageAccessor cacheStorageAccessor) + { + _cacheStorageAccessor = cacheStorageAccessor; + } + + public async Task<string> GetAsync(string assetUrl, bool useCache = true) + { + string result = null; + + HttpRequestMessage message = CreateMessage(assetUrl); + + + if (useCache) + { + // Get the result from the cache + result = await _cacheStorageAccessor.GetAsync(message); + } + + if (string.IsNullOrEmpty(result)) + { + //It not in the cache (or cache not used), read the asset from disk + result = await ReadData(assetUrl); + + if (!string.IsNullOrEmpty(result)) + { + if (useCache) + { + // If successful, create the response and store in the cache (when used) + HttpResponseMessage response = new() + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(result) + }; + + await _cacheStorageAccessor.PutAsync(message, response); + } + } + } + + return result; + } + + private static HttpRequestMessage CreateMessage(string url) => new(HttpMethod.Get, url); + + private static async Task<string> ReadData(string file) + { + using var stream = await FileSystem.OpenAppPackageFileAsync($"wwwroot/{file}"); + using var reader = new StreamReader(stream); + + return await reader.ReadToEndAsync(); + } +} + +
    +
  1. + You need to make some changes in your MauiProgram.cs file
    + Make sure the following is added before the return builder.Build() line: +
  2. +
+builder.Services.AddFluentUIComponents(options => +{ + options.HostingModel = BlazorHostingModel.Hybrid; +}); +builder.Services.AddSingleton<IStaticAssetService, FileBasedStaticAssetService>(); +

Joining the Community

Looking to get answers to questions or engage with us in realtime? Our community is most active on Discord. Submit requests and issues on GitHub, or join us by contributing on some good first issues via GitHub.