Skip to content

Commit e1b2531

Browse files
authored
Merge pull request #174 from microsoft/fluenticon
feat: Add FluentIcon component
2 parents 31406c1 + 17ad6eb commit e1b2531

File tree

11,906 files changed

+12556
-88
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

11,906 files changed

+12556
-88
lines changed

Microsoft.Fast.sln

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,27 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentUI.Demo.Server", "exa
1313
EndProject
1414
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentUI.Demo.Shared", "examples\FluentUI.Demo.Shared\FluentUI.Demo.Shared.csproj", "{CEE536EE-1F7E-4B50-8397-27E8C287C7A1}"
1515
EndProject
16-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentUI.Demo.Client", "examples\FluentUI.Demo.Client\FluentUI.Demo.Client.csproj", "{57790DB9-2EE1-4D78-BA73-9F63D8466F02}"
16+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentUI.Demo.Client", "examples\FluentUI.Demo.Client\FluentUI.Demo.Client.csproj", "{57790DB9-2EE1-4D78-BA73-9F63D8466F02}"
17+
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".additional files", ".additional files", "{B5536EE9-65A8-46B8-94CD-469364C83F8B}"
19+
ProjectSection(SolutionItems) = preProject
20+
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
21+
CONTRIBUTING.md = CONTRIBUTING.md
22+
LICENSE = LICENSE
23+
README.md = README.md
24+
SECURITY.md = SECURITY.md
25+
EndProjectSection
26+
EndProject
27+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".workflows", ".workflows", "{A958098A-B900-4D41-9DEF-32545802D22B}"
28+
ProjectSection(SolutionItems) = preProject
29+
.github\workflows\ci-validate.yml = .github\workflows\ci-validate.yml
30+
.github\workflows\cicd_publish.yml = .github\workflows\cicd_publish.yml
31+
.github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
32+
EndProjectSection
33+
EndProject
34+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Fast.Templates.FluentUI", "templates\Microsoft.Fast.Templates.FluentUI.csproj", "{86B789BF-DC71-4B5F-A530-B7CDF17BD293}"
35+
EndProject
36+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Fast.Components.FluentUI.Generators", "src\Microsoft.Fast.Components.FluentUI.Generators\Microsoft.Fast.Components.FluentUI.Generators.csproj", "{D767E0CA-86FF-4152-B731-762458CB5A5D}"
1737
EndProject
1838
Global
1939
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -73,6 +93,30 @@ Global
7393
{57790DB9-2EE1-4D78-BA73-9F63D8466F02}.Release|x64.Build.0 = Release|Any CPU
7494
{57790DB9-2EE1-4D78-BA73-9F63D8466F02}.Release|x86.ActiveCfg = Release|Any CPU
7595
{57790DB9-2EE1-4D78-BA73-9F63D8466F02}.Release|x86.Build.0 = Release|Any CPU
96+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
97+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Debug|Any CPU.Build.0 = Debug|Any CPU
98+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Debug|x64.ActiveCfg = Debug|Any CPU
99+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Debug|x64.Build.0 = Debug|Any CPU
100+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Debug|x86.ActiveCfg = Debug|Any CPU
101+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Debug|x86.Build.0 = Debug|Any CPU
102+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Release|Any CPU.ActiveCfg = Release|Any CPU
103+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Release|Any CPU.Build.0 = Release|Any CPU
104+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Release|x64.ActiveCfg = Release|Any CPU
105+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Release|x64.Build.0 = Release|Any CPU
106+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Release|x86.ActiveCfg = Release|Any CPU
107+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293}.Release|x86.Build.0 = Release|Any CPU
108+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
109+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
110+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Debug|x64.ActiveCfg = Debug|Any CPU
111+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Debug|x64.Build.0 = Debug|Any CPU
112+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Debug|x86.ActiveCfg = Debug|Any CPU
113+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Debug|x86.Build.0 = Debug|Any CPU
114+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
115+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Release|Any CPU.Build.0 = Release|Any CPU
116+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Release|x64.ActiveCfg = Release|Any CPU
117+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Release|x64.Build.0 = Release|Any CPU
118+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Release|x86.ActiveCfg = Release|Any CPU
119+
{D767E0CA-86FF-4152-B731-762458CB5A5D}.Release|x86.Build.0 = Release|Any CPU
76120
EndGlobalSection
77121
GlobalSection(SolutionProperties) = preSolution
78122
HideSolutionNode = FALSE
@@ -82,6 +126,8 @@ Global
82126
{1E1FFAAA-063F-47F8-A2C2-18AB6432994D} = {71623095-9CCB-40BA-A0A7-4A739DA8E913}
83127
{CEE536EE-1F7E-4B50-8397-27E8C287C7A1} = {71623095-9CCB-40BA-A0A7-4A739DA8E913}
84128
{57790DB9-2EE1-4D78-BA73-9F63D8466F02} = {71623095-9CCB-40BA-A0A7-4A739DA8E913}
129+
{86B789BF-DC71-4B5F-A530-B7CDF17BD293} = {30F6D568-0EFB-479D-8D69-C51CE5CABC22}
130+
{D767E0CA-86FF-4152-B731-762458CB5A5D} = {30F6D568-0EFB-479D-8D69-C51CE5CABC22}
85131
EndGlobalSection
86132
GlobalSection(ExtensibilityGlobals) = postSolution
87133
SolutionGuid = {0A3E27AA-91CB-4D3F-9C1E-390E3AA8DEC1}

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ Copy this to your `wwwroot/script` folder and reference it with a script tag as
6161
>
6262
> 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](/aspnet/core/mvc/views/razor).
6363
64+
In your Program.cs file you need to add the following:
65+
```csharp
66+
builder.Services.AddFluentUIComponents();
67+
```
68+
69+
if you are using Blazor Server, you need to make sure the `HttpClient` service is added:
70+
71+
```csharp
72+
builder.Services.AddHttpClient();
73+
```
74+
6475
### Using the FluentUI Web Components
6576

6677
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:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
using FluentUI.Demo.Shared;
22
using Microsoft.AspNetCore.Components.Web;
33
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
4+
using Microsoft.Fast.Components.FluentUI;
45

56
var builder = WebAssemblyHostBuilder.CreateDefault(args);
67
builder.RootComponents.Add<App>("#app");
78
builder.RootComponents.Add<HeadOutlet>("head::after");
89

910
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
11+
builder.Services.AddFluentUIComponents();
1012

1113
await builder.Build().RunAsync();
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"navigationFallback": {
3-
"rewrite": "/index.html"
3+
"rewrite": "/index.html",
4+
"exclude": [ "_content/Microsoft.Fast.Components.FluentUI/icons/*" ]
45
}
56
}

examples/FluentUI.Demo.Server/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
using Microsoft.Fast.Components.FluentUI;
2+
13
var builder = WebApplication.CreateBuilder(args);
24

35
// Add services to the container.
46
builder.Services.AddRazorPages();
7+
builder.Services.AddHttpClient();
58
builder.Services.AddServerSideBlazor();
9+
builder.Services.AddFluentUIComponents();
610

711

812
var app = builder.Build();
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
@page "/IconPage"
2+
@using System.ComponentModel.DataAnnotations
3+
@using System.Text.RegularExpressions
4+
@using Microsoft.Fast.Components.FluentUI
5+
6+
<style>
7+
.preview {
8+
margin: 10px;
9+
--card-width: 120px;
10+
--card-height: 120px;
11+
--elevation: 6;
12+
}
13+
14+
.preview:hover {
15+
--elevation: 12;
16+
}
17+
18+
.preview .inner {
19+
text-align: center;
20+
padding: 10px 10px 0;
21+
color: var(--neutral-foreground-rest);
22+
}
23+
24+
.preview .inner svg {
25+
height: 80px;
26+
}
27+
28+
.label {
29+
text-align: center;
30+
padding: 2px 5px;
31+
font-size: 10px;
32+
font-family: Monaco, monospace;
33+
white-space: nowrap;
34+
overflow: hidden;
35+
background: var(--neutral-stroke-rest);
36+
}
37+
</style>
38+
39+
<h1>Icons</h1>
40+
<h2>Overview</h2>
41+
<p>
42+
<dl>
43+
<dt>Icon using 'accent-fill-rest' color:<br />
44+
<code>&lt;FluentIcon Name=@@FluentIcons.Accessibility Size=IconSize.Size32 Filled=true /&gt;</code></dt>
45+
<dd><FluentIcon Name=@FluentIcons.Accessibility Size=IconSize.Size32 Filled=true /></dd>
46+
<dt>Icon without accent color: <br />
47+
<code>&lt;FluentIcon Name=@@FluentIcons.AccessibilityCheckmark Size=IconSize.Size24 Filled=true UseAccentColor=false /&gt;</code></dt>
48+
<dd><FluentIcon Name=@FluentIcons.AccessibilityCheckmark Size=IconSize.Size24 Filled=true UseAccentColor=false /></dd>
49+
</dl>
50+
51+
52+
</p>
53+
<h2>Culture Aware</h2>
54+
<p>
55+
Some icons offer alternatives for specific languages (neutral cultures). You can specify a language to use for the icon by using the <code>NeutralCultureName</code> parameter and giving it the two letter ISO code of the culture.
56+
If a language version of an icon is not found, the original neutral version will be used.
57+
<dl>
58+
<dt>Neutral @@FluentIcons.TextBold icons</dt>
59+
<dd style="line-height: 30px; display: flex; align-items: center; margin: 10px 40px;">Filled: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=true /> Regular: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=false /></dd>
60+
<dt>French @@FluentIcons.TextBold icons (<code>NeutralCultureName="fr"</code>)</dt>
61+
<dd style="line-height: 30px; display: flex; align-items: center; margin: 10px 40px;">Filled: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=true NeutralCultureName="fr" /> Regular: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=false NeutralCultureName="fr"/></dd>
62+
<dt>German @@FluentIcons.TextBold icons (<code>NeutralCultureName="de"</code>)</dt>
63+
<dd style="line-height: 30px; display: flex; align-items: center; margin: 10px 40px;">Filled: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=true NeutralCultureName="de" /> Regular: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=false NeutralCultureName="de"/></dd>
64+
<dt>Greek @@FluentIcons.TextBold icons (<code>NeutralCultureName="el"</code>) (does not exist, fall back to original)</dt>
65+
<dd style="line-height: 30px; display: flex; align-items: center; margin: 10px 40px;">Filled: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=true NeutralCultureName="el" /> Regular: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=false NeutralCultureName="el"/></dd>
66+
<dt>Spanish @@FluentIcons.TextBold icons (<code>NeutralCultureName="es"</code>)</dt>
67+
<dd style="line-height: 30px; display: flex; align-items: center; margin: 10px 40px;">Filled: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=true NeutralCultureName="es" /> Regular: <FluentIcon Name=@FluentIcons.TextBold Size=IconSize.Size24 Filled=false NeutralCultureName="es"/></dd>
68+
</dl>
69+
</p>
70+
<h2>Explore Icons</h2>
71+
<p>
72+
<EditForm EditContext="@editContext" >
73+
<div style="display: flex; flex-wrap: wrap; width: 90%;height: 100px;align-items: center;justify-content: space-between;">
74+
<div style="display: flex;align-content: center;align-items: center;">
75+
<p style="padding-right: 10px;"><label for="Searchterm">Search term</label></p>
76+
<FluentTextField Name="Searchterm" @bind-Value="Form.Searchterm" Placeholder="Search.."></FluentTextField>
77+
</div>
78+
<div style="display: flex;align-content: center;align-items: center;">
79+
<p style="padding-right: 10px;"><label for="Size">Select Size</label></p>
80+
<FluentSelect TValue="IconSize" Name="Size" @bind-Value="Form.Size" @onchange="@(x => HandleSize(x))">
81+
@foreach (IconSize size in Enum.GetValues<IconSize>())
82+
{
83+
<FluentOption Value=@size>@((int)size)</FluentOption>
84+
}
85+
</FluentSelect>
86+
</div>
87+
88+
<div style="display: flex;align-content: center;align-items: center;">
89+
<FluentCheckbox @bind-Value="Form.Filled" @onclick="HandleStyle">Filled</FluentCheckbox>
90+
<FluentCheckbox @bind-Value="Form.Regular" @onclick="HandleStyle">Regular</FluentCheckbox>
91+
</div>
92+
<FluentButton @onclick="HandleSearch"><FluentIcon Name="@FluentIcons.Search" Size="@IconSize.Size16" Filled=false Slot="start"></FluentIcon> Search</FluentButton>
93+
</div>
94+
</EditForm>
95+
</p>
96+
<div id="filled" data-is-scrollable="true" style="overflow-y:auto;height:600px;">
97+
<div style="display:flex;flex-flow: row wrap;">
98+
@foreach (IconModel icon in icons)
99+
{
100+
<FluentCard class="preview">
101+
<div class="inner">
102+
<FluentIcon Name=@icon.Name Size=@icon.Size Filled=@icon.Filled />
103+
</div>
104+
<div class="label">@icon.Name</div>
105+
</FluentCard>
106+
}
107+
@if (icons.Count == 0)
108+
{
109+
<div style="display: flex;align-content: center;align-items: center;">
110+
<p style="padding-right: 10px;">No icons found</p>
111+
</div>
112+
}
113+
</div>
114+
</div>
115+
116+
@code {
117+
private EditContext? editContext;
118+
119+
List<IconModel> icons = new();
120+
121+
public void HandleStyle()
122+
{
123+
if (Form.Filled && Form.Regular || !Form.Filled && !Form.Regular)
124+
{
125+
Form.Style = null;
126+
}
127+
else if (Form.Filled && !Form.Regular)
128+
{
129+
Form.Style = true;
130+
}
131+
else if (!Form.Filled && Form.Regular)
132+
{
133+
Form.Style = false;
134+
}
135+
HandleSearch();
136+
}
137+
138+
public void HandleSize(ChangeEventArgs args)
139+
{
140+
if (!string.IsNullOrEmpty(args.Value?.ToString()))
141+
{
142+
Form.Size = Enum.Parse<IconSize>((string)args.Value);
143+
HandleSearch();
144+
}
145+
146+
HandleSearch();
147+
}
148+
149+
public void HandleSearchterm()
150+
{
151+
HandleSearch();
152+
}
153+
154+
public void HandleSearch()
155+
{
156+
if (Form.Searchterm is not null && Form.Searchterm.Trim().Length > 2)
157+
{
158+
icons = FluentIcons.GetFilteredIcons(searchterm: Form.Searchterm.Trim(), size: Form.Size, filled: Form.Style);
159+
}
160+
StateHasChanged();
161+
return;
162+
}
163+
164+
public class FormModel
165+
{
166+
public IconSize Size { get; set; }
167+
168+
public string? Searchterm { get; set; }
169+
170+
public bool? Style { get; set; }
171+
172+
public bool Filled { get; set; }
173+
174+
public bool Regular { get; set; }
175+
176+
}
177+
178+
private FormModel Form = new()
179+
{
180+
Size = IconSize.Size24,
181+
Searchterm = "",
182+
Style = null,
183+
};
184+
185+
protected override void OnInitialized()
186+
{
187+
editContext = new EditContext(Form);
188+
}
189+
}

examples/FluentUI.Demo.Shared/Shared/NavMenu.razor

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
<li>
5050
<FluentAnchor Href="HorizontalScrollPage" Appearance=@SetAppearance("HorizontalScrollPage")>Horizontal Scroll</FluentAnchor>
5151
</li>
52+
<li>
53+
<FluentAnchor Href="IconPage" Appearance=@SetAppearance("IconPage")>Icon</FluentAnchor>
54+
</li>
5255
<li>
5356
<FluentAnchor Href="ListboxOptionPage" Appearance=@SetAppearance("ListboxOptionPage")>Listbox Option</FluentAnchor>
5457
</li>

0 commit comments

Comments
 (0)