Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,107 +2,119 @@
@using Microsoft.FluentUI.AspNetCore.Components.Extensions
@inject IDialogService DialogService

<h3>NavDefault</h3>

<FluentStack Orientation="Orientation.Horizontal" HorizontalGap="15">
<FluentNav @ref="@nav"
UseHeader="@_useHeader"
UseIcons="@_useIcons"
UseSingleExpanded="@(!_useMultipleExpanded)"
AppTitle="Contoso"
AppIcon="@(new Icons.Regular.Size32.Person())"
Density="@_density">
<FluentNavItem Href="/Nav" Icon="@(new Icons.Regular.Size20.Board())">Dashboard</FluentNavItem>
<FluentNavItem OnClick="@ShowInformationAsync" Icon="@(new Icons.Regular.Size20.MegaphoneLoud())">Announcements</FluentNavItem>
<FluentNavItem Disabled="true" Href="@_link">Employee Spotlight</FluentNavItem>
<FluentNavItem OnClick="@ShowInformationAsync" Icon="@(new Icons.Regular.Size20.PersonSearch())">Profile Search</FluentNavItem>
<FluentNavItem Href="@_link" Icon="@(new Icons.Regular.Size20.PersonMoney())">Performance Reviews</FluentNavItem>

<FluentNavSectionHeader Title="Employee Management" />

<FluentNavCategory Title="Job Postings" Icon="@(new Icons.Regular.Size20.NotePin())">

<FluentNavItem OnClick="@ShowInformationAsync">Openings</FluentNavItem>
<FluentNavItem OnClick="@ShowInformationAsync">Submissions</FluentNavItem>

</FluentNavCategory>
<FluentNavItem Href="@_link" Icon="@(new Icons.Regular.Size20.People())">Interviews</FluentNavItem>

<FluentNavSectionHeader Title="Benefits" />
<FluentNavItem Href="@_link" Icon="@(new Icons.Regular.Size20.HeartPulse())">Health Plans</FluentNavItem>

<FluentNavCategory Id="retirement" Title="Retirement" Icon="@(new Icons.Regular.Size20.Person())">

<FluentNavItem>Plan Information</FluentNavItem>
<FluentNavItem>Fund Performance</FluentNavItem>

</FluentNavCategory>

<FluentDivider />

<FluentNavItem Href="@_link" Icon="@(new Icons.Regular.Size20.BoxMultiple())">Training Programs</FluentNavItem>

<FluentNavCategory Title="Career Development" Icon="@(new Icons.Regular.Size20.PeopleStar())">

<FluentNavItem>Openings</FluentNavItem>
<FluentNavItem>Submissions</FluentNavItem>

</FluentNavCategory>

<FluentNavItem Href="@_link" Icon="@(new Icons.Regular.Size20.ArrowTrendingLines())">Workforce Data</FluentNavItem>
<FluentNavItem Href="@_link" Icon="@(new Icons.Regular.Size20.DocumentBulletListMultiple())">Reports</FluentNavItem>
</FluentNav>

<FluentStack Orientation="Orientation.Vertical" VerticalGap="5">
<FluentRadioGroup @bind-Value="@_density" Label="Density" Wrap="true">
<FluentRadio Label="Medium" Value="NavDensity.Medium" />
<FluentRadio Label="Small" Value="NavDensity.Small" />
</FluentRadioGroup>

<FluentSwitch @bind-Value="@_useIcons" Label="Use Icons" />
<FluentSwitch @bind-Value="@_useMultipleExpanded" Label="Allow multiple expanded categories" />
<FluentSwitch @bind-Value="@_useHeader" Label="Use Header" />

<FluentButton Disabled="@(!nav!.UseHeader)" OnClick="ToggleNavAsync">Toggle Navigation</FluentButton>

<FluentText>Programmatically control expanded/collapsed state</FluentText>
<span>
<FluentButton OnClick="ExpandRetirementAsync">Expand 'Retirement'</FluentButton>
<FluentButton OnClick="CollapseRetirementAsync">Collapse 'Retirement'</FluentButton>
</span>
</FluentStack>
<FluentNav @ref="@nav"
UseIcons="@UseIcons"
UseSingleExpanded="@(!UseMultipleExpanded)"
OnItemClick="@(e => Console.WriteLine($"NavItem clicked: Icon '{e.Icon?.Name}'."))"
Width="260px"
Density="@Density">

<!-- Navigation Items -->
<FluentNavItem Href="/Nav" Icon="@(new Icons.Regular.Size20.Board())">
Dashboard
</FluentNavItem>
<FluentNavItem OnClick="@ShowInformationAsync" Icon="@(new Icons.Regular.Size20.MegaphoneLoud())">
Announcements
</FluentNavItem>
<FluentNavItem Disabled="true" Href="@FluentUIBlazor_Url">Employee Spotlight</FluentNavItem>
<FluentNavItem OnClick="@ShowInformationAsync" Icon="@(new Icons.Regular.Size20.PersonSearch())">
Profile Search
</FluentNavItem>
<FluentNavItem Href="@FluentUIBlazor_Url" Icon="@(new Icons.Regular.Size20.PersonMoney())">
Performance Reviews
</FluentNavItem>

<!-- Employee Management -->
<FluentNavSectionHeader Title="Employee Management" />

<FluentNavCategory Title="Job Postings" Icon="@(new Icons.Regular.Size20.NotePin())">
<FluentNavItem OnClick="@ShowInformationAsync">Openings</FluentNavItem>
<FluentNavItem OnClick="@ShowInformationAsync">Submissions</FluentNavItem>
</FluentNavCategory>

<FluentNavItem Href="@FluentUIBlazor_Url" Icon="@(new Icons.Regular.Size20.People())">
Interviews
</FluentNavItem>

<!-- Benefits -->
<FluentNavSectionHeader Title="Benefits" />

<FluentNavItem Href="@FluentUIBlazor_Url" Icon="@(new Icons.Regular.Size20.HeartPulse())">
Health Plans
</FluentNavItem>

<FluentNavCategory Id="retirement" Title="Retirement" Icon="@(new Icons.Regular.Size20.Person())">
<FluentNavItem>
Plan Information
</FluentNavItem>
<FluentNavItem>
Fund Performance
</FluentNavItem>
</FluentNavCategory>

<!-- Divider -->
<FluentDivider />

<!-- Training Programs -->
<FluentNavItem Href="@FluentUIBlazor_Url" Icon="@(new Icons.Regular.Size20.BoxMultiple())">
Training Programs
</FluentNavItem>

<FluentNavCategory Title="Career Development" Icon="@(new Icons.Regular.Size20.PeopleStar())">
<FluentNavItem>Openings</FluentNavItem>
<FluentNavItem>Submissions</FluentNavItem>
</FluentNavCategory>

<FluentNavItem Href="@FluentUIBlazor_Url" Icon="@(new Icons.Regular.Size20.ArrowTrendingLines())">
Workforce Data
</FluentNavItem>
<FluentNavItem Href="@FluentUIBlazor_Url" Icon="@(new Icons.Regular.Size20.DocumentBulletListMultiple())">
Reports
</FluentNavItem>
</FluentNav>

<FluentStack Orientation="Orientation.Vertical" VerticalGap="5" Wrap="true">
<FluentRadioGroup @bind-Value="@Density" Label="Density" Wrap="true">
<FluentRadio Label="Medium" Value="NavDensity.Medium" />
<FluentRadio Label="Small" Value="NavDensity.Small" />
</FluentRadioGroup>

<FluentSwitch @bind-Value="@UseIcons" Label="Use Icons" />

<FluentSwitch @bind-Value="@UseMultipleExpanded" Label="Allow multiple expanded categories" />

<FluentText>Programmatically control expanded/collapsed state</FluentText>
<FluentStack Orientation="Orientation.Horizontal">
<FluentButton OnClick="ExpandRetirementAsync">Expand 'Retirement'</FluentButton>
<FluentButton OnClick="CollapseRetirementAsync">Collapse 'Retirement'</FluentButton>
</FluentStack>
</FluentStack>

</FluentStack>

@code
{
private FluentNav nav = default!;
NavDensity _density;
bool _useHeader = false;
bool _useIcons = true;
bool _useMultipleExpanded = true;
private readonly string? _link = "https://fluentui-blazor-v5.azurewebsites.net/";

private async Task ShowInformationAsync()
{
await DialogService.ShowInfoAsync("This is a message");
}

private async Task ToggleNavAsync()
{
if (nav.UseHeader)
{
await nav.ToggleNavAsync();
}
}

private async Task ExpandRetirementAsync()
{
await nav.ExpandCategoryAsync("retirement");
}

private async Task CollapseRetirementAsync()
{
await nav.CollapseCategoryAsync("retirement");
}
const string FluentUIBlazor_Url = "https://fluentui-blazor-v5.azurewebsites.net/";
FluentNav nav = default!;

NavDensity Density;
bool UseIcons = true;
bool UseMultipleExpanded = true;

async Task ShowInformationAsync()
{
await DialogService.ShowInfoAsync("This is a message");
}

async Task ExpandRetirementAsync()
{
await nav.ExpandCategoryAsync("retirement");
}

async Task CollapseRetirementAsync()
{
await nav.CollapseCategoryAsync("retirement");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,49 @@ icon: Navigation

# Nav

Nav, or navigation, provides a list of links that lets people move through the main sections of an app or site. It’s a high-level wayfinding component that’s always easily accessible but can be minimized to free up space.
Nav, or navigation, provides a list of links that lets people move through the main sections of an app or site.
It's a high-level wayfinding component that's always easily accessible but can be minimized to free up space.

Nav only supports one level of nesting and might not show all available items.

## Selection
The selection indicator tells people at a glance which page is active. If a nav sub-item is the active page and the category is closed, the selection indicator will display on the nav category.
The selection indicator tells people at a glance which page is active. If a nav sub-item is the active page and the category is closed,
the selection indicator will display on the nav category.

## Grouping
Navs can be organized with up to two levels of hierarchy. Simple navs list the spaces in a site or app as links on the same level. For more complex navs, links can be grouped into categories for easier interaction.
Navs can be organized with up to two levels of hierarchy. Simple navs list the spaces in a site or app as links on the same level.
For more complex navs, links can be grouped into categories for easier interaction.

Create a simple nav using nav items. These are first-level links that give people a quick understanding of the main parts of an experience.

Create a complex nav using nav categories and sub-items. Nav categories expand and collapse so people only see the information they need. Nav sub-items group related links within that category and let people navigate to those sub-pages. Nav categories act as accordions and show or hide information; they’re not links and won’t lead to site or app locations.
Create a complex nav using nav categories and sub-items. Nav categories expand and collapse so people only see the information they need.
Nav sub-items group related links within that category and let people navigate to those sub-pages. Nav categories act as accordions and
show or hide information;
they're not links and won't lead to site or app locations.

By using the `UseSingleExpanded` parameter, you can ensure that only one nav category is expanded at a time. When a new category is expanded, any previously expanded category will automatically collapse.
By using the `UseSingleExpanded` parameter, you can ensure that only one nav category is expanded at a time. When a new category
is expanded, any previously expanded category will automatically collapse.

## Divider
Use the `FluentDivider` to separate groups of nav items. This helps people scan and find what they need more quickly. The right styling will automatically be applied when using the divider inside the `FluentNav`
Use the `FluentDivider` to separate groups of nav items. This helps people scan and find what they need more quickly.
The right styling will automatically be applied when using the divider inside the `FluentNav`

## Icons
Whenever possible, use icons with nav category labels. They create additional visual emphasis and differentiate nav categories from the nav subitems within them. Use simple and recognizable icons that are easy to understand.
Whenever possible, use icons with nav category labels. They create additional visual emphasis and differentiate nav categories
from the nav subitems within them. Use simple and recognizable icons that are easy to understand.

If icons aren’t technically possible or difficult to pick due to an overwhelming number of nav items, remove them. If nav categories don’t include an icon, subitems are indented to maintain a clear hierarchy.
If icons aren't technically possible or difficult to pick due to an overwhelming number of nav items, remove them.
If nav categories don't include an icon, subitems are indented to maintain a clear hierarchy.

## Items
Nav doesn’t support an icon-only layout.
Nav doesn't support an icon-only layout.

A `NavItem` can contain either an `Href` or an `OnClick` handler.

When a `NavItem` is used inside a `NavCategory`, the `Icon` parameter is ignored. No icon will be displayed.

In the example below, the first (and third and fifth) item has an `Href` that navigates to an external site, while the second (and fourth) item has an `OnClick` handler that triggers a method in the component.
In the example below, the first (and third and fifth) item has an `Href` that navigates to an external site, while the second
(and fourth) item has an `OnClick` handler that triggers a method in the component.

{{ NavDefault }}

Expand All @@ -56,6 +67,7 @@ In the example below, the first (and third and fifth) item has an `Href` that na
{{ API Type=FluentNavSectionHeader }}

## Migrating to v5

There is no direct migration path for the `FluentNavMenu` from v4
to the `FluentNav` in v5. This is due to the fact that in the v4 component
it was possible to have multiple levels of nesting, while in v5 only one level is supported.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<FluentLayoutItem Area="@LayoutArea.Header" Height="44px">
<FluentStack VerticalAlignment="@VerticalAlignment.Center" HorizontalGap="4px" Height="100%" >
@* Hamburger on Mobile *@
<FluentLayoutHamburger @ref="@_hamburger" Style="margin: 2px 12px;" PanelHeader="Fluent UI Blazor" Display="HamburgerDisplay.DesktopMobile" />
<FluentLayoutHamburger Style="margin: 2px 12px;" PanelHeader="Fluent UI Blazor" Display="HamburgerDisplay.DesktopMobile" />

@* Microsoft Logo *@
<MicrosoftLogo />
Expand Down Expand Up @@ -52,8 +52,8 @@
@* ------------------- *@

<FluentLayoutItem Area="@LayoutArea.Navigation" Width="262px" Sticky="true" Height="var(--layout-body-height)"
Style="overflow-y: hidden; padding: 0px; border-right: var(--strokeWidthThin) solid var(--colorNeutralStroke1);">
<DemoNav/>
Style="overflow-y: auto; padding: 0px; border-right: var(--strokeWidthThin) solid var(--colorNeutralStroke1);">
<DemoNav />
</FluentLayoutItem>

@* ------------------- *@
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace FluentUI.Demo.Client.Layout;

public partial class DemoMainLayout
{
private FluentLayoutHamburger _hamburger = default!;
private bool _consoleLogOpened;
private bool _useReboot;

Expand Down
63 changes: 38 additions & 25 deletions examples/Demo/FluentUI.Demo.Client/Layout/DemoNav.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,46 @@
@inject FluentUI.Demo.DocViewer.Services.DocViewerService DocViewerService

<FluentNav Style="padding-top:10px;"
UseSingleExpanded="false"
Density="@NavDensity.Medium">
UseSingleExpanded="false"
Density="@NavDensity.Medium">

<FluentNavItem Href="/" Match="NavLinkMatch.All" Icon="@(new Icons.Regular.Size20.Home())">Home</FluentNavItem>
@foreach (var category in NavItems)
{
<FluentNavItem Href="/"
Match="NavLinkMatch.All"
Icon="@(new Icons.Regular.Size20.Home())">
Home
</FluentNavItem>

<FluentNavSectionHeader Title="@category.Title" />
@foreach (var category in NavItems)
{
<FluentNavSectionHeader Title="@category.Title" />

@foreach (var s in category.Items)
{
var sitePage = s;
@foreach (var s in category.Items)
{
var sitePage = s;

@if (!sitePage.Items.Any())
{
<FluentNavItem Href="@sitePage.Route" Icon="@(GetIconFromName(sitePage.Icon))">@sitePage.Title</FluentNavItem>
}
else
{
<FluentNavCategory Title="@sitePage.Title" Icon="@(GetIconFromName(sitePage.Icon))">
<FluentNavItem Href="@sitePage.Route" Match="NavLinkMatch.All">Overview</FluentNavItem>
@foreach (var subPage in sitePage.Items)
{
<FluentNavItem Href="@subPage.Route">@(subPage.Title)</FluentNavItem>
}
</FluentNavCategory>
}
}
}
@if (!sitePage.Items.Any())
{
<FluentNavItem Href="@sitePage.Route"
Icon="@(GetIconFromName(sitePage.Icon))">
@sitePage.Title
</FluentNavItem>
}
else
{
<FluentNavCategory Title="@sitePage.Title" Icon="@(GetIconFromName(sitePage.Icon))">
<FluentNavItem Href="@sitePage.Route"
Match="NavLinkMatch.All">
Overview
</FluentNavItem>

@foreach (var subPage in sitePage.Items)
{
<FluentNavItem Href="@subPage.Route">
@(subPage.Title)
</FluentNavItem>
}
</FluentNavCategory>
}
}
}
</FluentNav>
Loading
Loading