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.
Moreover, as soon as I selected a month in the calendar, the styling magically started to be applied correctly.
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.
As you can see in the image below, the FluentProvider root html element gets prefixed accordingly.
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
This PR implements IdPrefixProvider for @fluentui/react-components. This feature allows to better control automatically generated IDs:
/* All ids in a scope will start with “scope-” */…
Image by Marcel Langthim from Pixabay
Very helpful!
Thank you!! This was very helpful when I was banging my head trying to use fluent provider with SharePoint framework web part.
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,