Skip to content

PCF Controls with FluentUI v9 – Avoid DOM id collisions

Recently, while developing a PCF control with the FluentUI React v9 library, I encountered a rather unusual and annoying runtime display bug. Its resolution ended up shedding light on an important concept that had previously escaped my attention and I thought it deserves its own blog post.

🤒The symptoms

The control I was developing is my latest community PCF control, the FluentUI Month Picker.

 🔗FluentUI Month Picker | PCF Gallery
🔗 GitHub repo : drivardxrm/FluentUI.MonthPicker.PCF

Given that FluentUI v9 (@fluentui/react-components) is the main library used by the platform to render form elements when the New Look switch is activated… see my previous blog post. I decided to use it in my project to replicate the look and feel of a native date picker.

The control functioned perfectly within the PCF test harness during development. However, upon deployment to a live Dataverse environment and integration into a form, inconsistencies surfaced in the display of the calendar pop-over.

As you can see in the image below, the styling of the calendar is off and the surface is transparent.

Calendar styles not applied

Moreover, as soon as I selected a month in the calendar, the styling magically started to be applied correctly.

Calendar styles applied after selection

The cherry on top, this display issue seemed to happen only if my PCF control was configured on the first field of the form.

🧑‍⚕️The diagnostic

After struggling to find a solution and testing various approaches in vain, I decided to be pragmatic and look at the developer logs of the browser. Turns out that the answer was right there under my nose.

I noticed this error message about conflicting DOM ids in the rendered page coming from the fluentui/react-provider library.

Interestingly, the error message provides a link to the Advanced Configuration section of the FluentUI v9 documentation. This section explains the issue and offers a comprehensive solution.

🔗Concepts / Developer / Advanced Configuration - Page ⋅ Storybook (fluentui.dev)
🔗feat: add IdPrefixProvider by layershifter · Pull Request #26496 · microsoft/fluentui (github.com)

💊The fix

One of the first thing to consider when working with FluentUI v9 is to wrap your application with a FluentProvider . This component is plays a crucial role in injecting both the theme and styles into the application.

import { Button, FluentProvider, webLightTheme } from '@fluentui/react-components'

const SimpleApp= (): JSX.Element =>     
    <FluentProvider theme={webLightTheme}>
       <Button appearance="primary">Hello FluentUI React v9</Button> 
    </FluentProvider>      

export default SimpleApp

See my previous blog post on PCF control development with FluentUI v9 for more context

🔗Develop PCF Controls with FluentUI React v9 – It Must Be Code!


Now, Since FluentUI is also used natively by the PowerPlatform and that other PCF controls on the form might also bring their own flavor of the provider, chances are that we end up with multiple instances of FluentProvider with the same DOM id on the page at runtime. When this happens, it can cause interop problems, thus the display bug encountered earlier.

To mitigate this, we need to wrap the application with another component, IdPrefixProvider and provide an APPID. This ensures that the id of the rendered html element is unique by prefixing the standard id with the given APPID.

import { Button, FluentProvider, IdPrefixProvider, webLightTheme } from '@fluentui/react-components'

const SimpleApp= (): JSX.Element =>
    <IdPrefixProvider value="APPID-">
      <FluentProvider theme={webLightTheme}>
       <Button appearance="primary">Hello FluentUI React v9</Button> 
      </FluentProvider>    
    </IdPrefixProvider>     
      

export default SimpleApp

Here is how I implemented the fix in my PCF control code. By adding a prefix that identifies the control ‘month-picker-‘ and an ‘instanceId‘ (randomly generated GUID), I can be sure that each possible instance of the control on a form will have a different prefix id.

IdPrefixProvider implementation

As you can see in the image below, the FluentProvider root html element gets prefixed accordingly.

PCF control instance with prefixed FluentProvider

As soon as I deployed the version with the prefixed FluentProvider, collision errors were resolved and my PCF controls started to render flawlessly 💪.

Takeaway

Moving forward, I will always use the IdPrefixProvider in my PCF controls that uses FluentUI v9. This simple trick not only safeguards against DOM Id collisions but also enhances the overall robustness of PCF controls implementations.

Hope this helps,

Links

Image by Marcel Langthim from Pixabay

Published inBlog

3 Comments

  1. Karthik

    Thank you!! This was very helpful when I was banging my head trying to use fluent provider with SharePoint framework web part.

  2. Zsolt Zombik

    Hello David,

    Thank you for sharing! I learned some valuable new insights about Fluent UI 9 from your article.

    I hope you don’t mind, but I have a question regarding the Fluent UI 9 Dropdown component. I developed a custom PCF control to replace an existing component in a Power Apps model-driven app. When I place the control on the form, it works fine. However, when I use the control in a Business Process Flow, I encounter an issue with the control’s width.

    Could you advise on how to set the minWidth and width values for the control?

    I tried to use this, but did not work:

    export const useStyles = makeStyles({
    root: {
    // Stack the label above the field with a gap
    display: “grid”,
    gridTemplateRows: “repeat(1fr)”,
    justifyItems: “start”,
    gap: “2px”,
    minWidth: “100px”,
    maxWidth: “100%”,
    “> div”: {
    display: “grid”,
    gridTemplateRows: “repeat(1fr)”,
    justifyItems: “start”,
    gap: “2px”,
    },

    },

    I appreciate any guidance you can provide!

    Best regards,

Leave a Reply

Your email address will not be published. Required fields are marked *