Creating A Custom Horizontal Nav Component Using React Office UI Fabric

I assume that you are working in Office UI Fabric React components and you wanted to create a horizontal menu component in your react solution. Unfortunately, the normal Nav component in the Office UI Fabric doesn’t give you this option. And somehow you reached here by searching for a solution to implement the horizontal menu. You are in the right place then.

Introduction

Welcome to my blog. I assume that you are working in Office UI Fabric React components and you want to create a horizontal menu component in your React solution. Unfortunately, the normal Nav component in the Office UI Fabric doesn’t give you this option. And somehow you reached this post by searching for a solution to implement the horizontal menu. You are in the right place then. Let’s skip the talking and jump into the code. I hope you will like this article. Let’s start coding.

Background

As I mentioned in the introduction, there is no option to make a horizontal menu if you are using UI Fabric Nav component. And I also ended up in spending some time playing with the Nav component to make it horizontal, but it wasn’t working as expected. And I found a different way to achieve the same, hereby I am sharing it as I couldn’t find such a solution on the internet.

Creating A Custom Horizontal Nav Component Using React Office UI Fabric
Nav menu vertical
 
Creating Horizontal Nav component

I believe that you have already created your solution and you are just trying to create a new Menu web part in the existing solution. If you haven’t created a solution, you can create one using the below command.

yo @microsoft/sharepoint

MenuWebPart.ts

Once you have created a new web part, you can see that there is a file called MenuWebPart.ts. This is the file we are going to edit first. You can see the content of that file below.

  1. import * as React from 'react';  
  2. import * as ReactDom from 'react-dom';  
  3. import {  
  4.     Version  
  5. } from '@microsoft/sp-core-library';  
  6. import {  
  7.     BaseClientSideWebPart,  
  8.     IPropertyPaneConfiguration,  
  9.     PropertyPaneTextField  
  10. } from '@microsoft/sp-webpart-base';  
  11. import * as strings from 'MenuWebPartStrings';  
  12. import Menu from './components/Menu';  
  13. import {  
  14.     IMenuProps  
  15. } from './components/IMenuProps';  
  16. export interface IMenuWebPartProps {  
  17.     description: string;  
  18. }  
  19. export default class MenuWebPart extends BaseClientSideWebPart < IMenuWebPartProps > {  
  20.     public render(): void {  
  21.         const element: React.ReactElement < IMenuProps > = React.createElement(Menu, {  
  22.             items: [{  
  23.                 name: 'Home',  
  24.                 url: '',  
  25.                 key: 'key3'  
  26.             }, {  
  27.                 name: 'Admin',  
  28.                 key: 'key4'  
  29.             }]  
  30.         });  
  31.         ReactDom.render(element, this.domElement);  
  32.     }  
  33.     protected onDispose(): void {  
  34.         ReactDom.unmountComponentAtNode(this.domElement);  
  35.     }  
  36.     protected get dataVersion(): Version {  
  37.         return Version.parse('1.0');  
  38.     }  
  39.     protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {  
  40.         return {  
  41.             pages: [{  
  42.                 header: {  
  43.                     description: strings.PropertyPaneDescription  
  44.                 },  
  45.                 groups: [{  
  46.                     groupName: strings.BasicGroupName,  
  47.                     groupFields: [  
  48.                         PropertyPaneTextField('description', {  
  49.                             label: strings.DescriptionFieldLabel  
  50.                         })  
  51.                     ]  
  52.                 }]  
  53.             }]  
  54.         };  
  55.     }  
  56. }  

As you can see I am calling the Menu component here with the property items, this is where you need to mention the contents of your menu.

Menu.tsx

Now let’s start editing the code in Menu.tsx file.

  1. import * as React from 'react';  
  2. import { IMenuProps } from './IMenuProps';  
  3. import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar';  
  4. export default class Menu extends React.Component<IMenuProps, {}> {  
  5.    constructor(props: IMenuProps) {  
  6.    super(props);  
  7. }  
  8. public render(): React.ReactElement<IMenuProps> {  
  9.    const { items } = this.props;  
  10.    return (  
  11.    <div>  
  12.       <CommandBar items={items} />  
  13.    </div>  
  14.    );  
  15.    }  
  16. }  

As you can see I am using CommandBar here which accepts the item property which we have set before.

IMenuProps.ts

You would also need to add the item property in the IMenuProps.ts file.

  1. import {  
  2.     IContextualMenuItem  
  3. } from "office-ui-fabric-react/lib/ContextualMenu";  
  4. export interface IMenuProps {  
  5.     items: IContextualMenuItem[];  
  6. }  
Output

If you have configured the CommandBar component in an above-mentioned way, you would have seen a horizontal menu by now. Please keep in mind that there are some limitations in using  CommandBar. I would use this until Microsoft introduces a new property in the existing Nav component to make it horizontal.

Creating A Custom Horizontal Nav Component Using React Office UI Fabric
Nav horizontal
Conclusion

Thanks a lot for reading. Did I miss anything that you may think is needed? Did you find this post useful? I hope you liked this article. Please share with me your valuable suggestions and feedback.

Source Code

The source code can be found here

Your turn. What do you think?

A blog isn’t a blog without comments, but do try to stay on topic. If you have a question unrelated to this post, you’re better off posting it on C# Corner, Code Project, Stack Overflow, or Asp.Net Forum instead of commenting here. Tweet or email me a link to your question there and I’ll definitely try to help if I can.