Skip to content

Conversation

@rbertels
Copy link
Contributor

@rbertels rbertels commented Jan 17, 2026

Hey Andrew,

This PR adds a binding to 'createFluentIcon`. (https://github.com/microsoft/fluentui-system-icons/blob/main/packages/react-icons/src/utils/createFluentIcon.ts)

It allows you to define your own icons based on SVG paths as such:

type [<Erase>] CustomIcons =
    static member inline microsoft (props : IIconProp list) =
        createElement (Fui.icon.createIconType("microsoft", "1em", [|
            "M1.0 1.0h7.5v7.5H1.0V1.0m9.0 0.0h7.5v7.5h-7.5V1.0m-9.0 9.0h7.5v7.5H1.0v-7.5m9.0 0.0h7.5v7.5h-7.5v-7.5"
        |])) props

The icon is then available to be used and customized like any other icon that is already available in the catalog.
Example usage:

navItem.icon (CustomIcons.microsoft [icon.size.``20``])
image

I just threw this function in Fui.icon but if you'd prefer it to be located somewhere else I'd be happy to move it around!
For the comments I tried to stay consistent with import.

Let me know what you think!

Have a nice day,

Rob

@rbertels rbertels marked this pull request as ready for review January 17, 2026 16:11
@sydsutton
Copy link
Owner

sydsutton commented Jan 20, 2026

@rbertels Thanks for the PR! How would you feel about this instead? I think it's slightly more in-line with the original TS usage:

        /// Use this function to create new icons from SVG paths. <br/>
        /// See <link>https://github.com/microsoft/fluentui-system-icons/blob/main/packages/react-icons/src/utils/createFluentIcon.ts</link.
        ///
        /// Example:
        /// <code>
        ///     let microsoftIcon =
        ///         Fui.icon.createIconType(
        ///             "microsoft",
        ///             "1em",
        ///              [| "M1.0 1.0h7.5v7.5H1.0V1.0m9.0 0.0h7.5v7.5h-7.5V1.0m-9.0 9.0h7.5v7.5H1.0v-7.5m9.0 0.0h7.5v7.5h-7.5v-7.5" |],
        ///             [ icon.size.``20`` ]
        ///         )
        /// </code>
        static member inline createFluentIcon (displayName : string, width : string, paths : string array, props: IIconProp list) =
                        let icon = JSTuple.from3Args (displayName, width, paths) |> import "createFluentIcon" FluentIcons
                        createElement icon props
    let microsoftIcon (iconProps: IIconProp list) =
        Fui.icon.createFluentIcon (
            "microsoft",
            "1em",
            [| "M1.0 1.0h7.5v7.5H1.0V1.0m9.0 0.0h7.5v7.5h-7.5V1.0m-9.0 9.0h7.5v7.5H1.0v-7.5m9.0 0.0h7.5v7.5h-7.5v-7.5" |],
            iconProps
        )

    Fui.navItem [
        navItem.href ""
        navItem.icon (microsoftIcon [icon.size.``28``])
        navItem.value "1"
        navItem.children [
            Html.text "Dashboard"
        ]
    ]

@rbertels
Copy link
Contributor Author

Hey Andrew,

Yeah that looks good to me, I have no strong opinions on it. Happy to update the code to reflect your suggestion.

Just to be safe: will we not be redundantly creating these icons over and over every render?
I'm using Fable exactly because I have very little front-end experience and I don't want to introduce anything bad to your project. 😅

@sydsutton
Copy link
Owner

Alright, I added lazy so that the React component type is only created once. Could try this code out in your environment and let me know if it gives you any issues?

        static member inline createFluentIcon (displayName : string, width : string, paths : string array, props: IIconProp list) =
                        let icon = lazy (JSTuple.from3Args (displayName, width, paths) |> import "createFluentIcon" FluentIcons)
                        createElement icon.Value props

@rbertels
Copy link
Contributor Author

Hey Andrew,

Thanks for the feedback. I have also discussed this with an acquaintance that is well versed in React.
The way I interpreted his explanation, we should regard the output of createFluentIcon as a ReactElementType that should be initiated only once. For each icon we create the type as such:

module CustomIcons =
    let MicrosoftRegular =
        Fui.icon.createFluentIcon ("microsoft", "1em", [|
            "M1.0 1.0h7.5v7.5H1.0V1.0m9.0 0.0h7.5v7.5h-7.5V1.0m-9.0 9.0h7.5v7.5H1.0v-7.5m9.0 0.0h7.5v7.5h-7.5v-7.5"
        |])

Then we can create a function to instantiate this type in the following way:

let inline microsoftRegular (props : IIconProp list) = createElement MicrosoftRegular props   

This signature is pretty much identical to the ones of the built-in icons.

The updated PR code reflects these changes and also aligns with your suggestions.
I have removed the comments though as they became quite long. Perhaps the usage of this feature is best described in the wiki?

All the best and have a nice day!

Rob

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants