Search code examples
reactjssvgfluent-uifluentui-reactcommandbar

Adding custom SVG Icon to Fluent UI Command Bar Items


I have multiple command bar items that need custom SVG Icons, but no matter what I do, I cannot get the icons to work for my life.

Here is the SVG I am registering as an icon:

registerIcons({
    icons: {
        'Assigned-svg': (
            <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25.9995 32">
                <path class="cls-1" d="M25.9995,8.5781v23.4219H0V0h17.4214l8.5781,8.5781ZM23.9995,30V10h-8V2H2v28h21.9995ZM4,4h2v2h-2v-2ZM4,8h2v2h-2v-2ZM4,12h2v2h-2v-2ZM20.9995,14h1v14h-2v-4h-6.5776l-4,4h-2.4219l13.9995-14ZM19.9995,17.4219l-4.5781,4.5781h4.5781v-4.5781ZM17.9995,8h4.5781l-4.5781-4.5781v4.5781Z" />
            </svg>
        )
    }
}); 

Here are the command bar items, the first item is where the icon should go to:

    const _items: ICommandBarItemProps[] = [
        {
          key: 'assigned',
          text: 'Assigned',
          cacheKey: 'myCacheKey', 
          //iconProps: { iconName: 'Assign' },
          iconProps: {iconName: 'AssignedIcon'},
         
          className: filterType == 'assigned'? 'selectedView': '',
          onClick: () => handleFilterChange('assigned')
        },
        {
          key: 'overdue',
          text: 'Overdue',
          iconProps: { iconName: 'EventInfo' },
          className: filterType == 'overdue'? 'selectedView': '',
          onClick: () => handleFilterChange('overdue')
        },
        {
          key: 'submitted',
          text: 'Submitted',
          iconProps: { iconName: 'Share' },
          className: filterType == 'submitted'? 'selectedView': '',
          onClick: () => handleFilterChange('submitted')
        },
        {
          key: 'reviewed',
          text: 'Reviewed',
          iconProps: { iconName: 'ReviewSolid' },
          className: filterType == 'reviewed'? 'selectedView': '',
          onClick: () => handleFilterChange('reviewed')
        },{
          key: 'all',
          text: 'All',
          iconProps: { iconName: 'ViewAll' },
          className: filterType == 'all'? 'selectedView': '',
          onClick: () => handleFilterChange('all')
        }
      ];

Interestingly, the icon works perfectly when loaded as a FontIcon, but doesn't work as an icon of a command bar item:

return (
   <>
   <FontIcon
      iconName="Assigned-svg"
      aria-hidden={undefined}
      className={mergeStyles(iconClass, {
        width: 50,
        height: 50,
     
      })}
    />
    <AssignedIcon>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25.9995 32">
          <path d="M25.9995,8.5781v23.4219H0V0h17.4214l8.5781,8.5781ZM23.9995,30V10h-8V2H2v28h21.9995ZM4,4h2v2h-2v-2ZM4,8h2v2h-2v-2ZM4,12h2v2h-2v-2ZM20.9995,14h1v14h-2v-4h-6.5776l-4,4h-2.4219l13.9995-14ZM19.9995,17.4219l-4.5781,4.5781h4.5781v-4.5781ZM17.9995,8h4.5781l-4.5781-4.5781v4.5781Z" />
        </svg>
      </AssignedIcon>
      <CommandBar
        items={_items}
        ariaLabel="Inbox actions"
        styles={{root: {backgroundColor: ''}}}
     
      />   
      </>
  );

I have tried adding the SVG manually and as a string to the iconProps of the item, but nothing worked.

Please help.


Solution

  • I found a way to do this, the onRenderIcon function works, but it only works if iconProps is provided with a fluent UI-registered icon name.

    So first provide iconProps with an iconName that Fluent UI contains by default, then use the onRenderIcon method and provide either an image through img tag or a FontIcon/DefaultIcon/IconButton component accepting the SVG.

    const _items: ICommandBarItemProps[] = [
        {
          key: 'assigned',
          text: 'Assigned',
          //cacheKey: 'myCacheKey', 
          iconProps: { iconName: 'Assign' },
          onRenderIcon: () => (<img style={{ height: "20px", width: "20px" }} src={AssignmentIcons.Assigned} />),
          className: filterType == 'assigned' ? 'selectedView' : '',
          onClick: () => handleFilterChange('assigned')
        },
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>