sp-dev-docs icon indicating copy to clipboard operation
sp-dev-docs copied to clipboard

Rendering issue of Fluent UI Dialog and Drawer caused by issue in SharePoint

Open jcoolsen opened this issue 1 year ago • 6 comments

Target SharePoint environment

SharePoint Online

What SharePoint development model, framework, SDK or API is this about?

💥 SharePoint Framework

Developer environment

Windows

What browser(s) / client(s) have you tested

  • [ ] 💥 Internet Explorer
  • [X] 💥 Microsoft Edge
  • [X] 💥 Google Chrome
  • [X] 💥 FireFox
  • [ ] 💥 Safari
  • [ ] mobile (iOS/iPadOS)
  • [ ] mobile (Android)
  • [ ] not applicable
  • [ ] other (enter in the "Additional environment details" area below)

Additional environment details

  • browser version: Newest
  • SPFx version: 1.18
  • Node.js version 18
  • etc

Describe the bug / error

When rendering the Fluent UI 9 components Drawer or Dialog the styling becomes messed up. I made a report with the Fluent UI team here: https://github.com/microsoft/fluentui/issues/32253 They pointed to this being a bug in SharePoint and this is why I post here. Something about mismatch of context versions. The issue only happens in SharePoint context, like the workbench. I have made a simple reproduction here based on the Hello World getting started web part: https://github.com/jcoolsen/SampleForStylingIssue

Below information is copied in from the other issue: Actual Behavior When using the Drawer or Dialog components in a SharePoint Online context, like a web part in a site or in the workbench, they are missing their base styling variable definitions. This appears to be because they refer to the wrong fui-FluentProvider# class. Often they refer to "fui-FluentProvider1" but should point to a different number in the class attribute. As far as I can see, this is not caused by any change in the Fluent UI components themselves, but rather by some unknown (recent?) change in the SharePoint Online platform that somehow breaks compatibility. The effect is that the rendering becomes bad, nearly unreadable.

This is what we see: image Underlying HTML from above: image

Steps to reproduce

  1. Run the referenced reproduction: "npm i" and "gulp serve"
  2. Click button "Open Drawer" or "Open Dialog".
  3. Note how the styling breaks because fui-FluentProvider# numbering does not match the proper element id in the rendered HTML.

Expected behavior

Below information is copied in from the other issue: Expected Behavior I expect the components to display properly.

This is what we want: image (the thick black border is caused by the Windows snipping tool) Underlying HTML from above: image

jcoolsen avatar Aug 08 '24 07:08 jcoolsen

I can reproduce the issue on SPO.

image

  "dependencies": {
    "@fluentui/font-icons-mdl2": "^8.5.50",
    "@fluentui/react": "^8.120.9",
    "@fluentui/react-components": "^9.54.15",
    "@microsoft/applicationinsights-react-js": "17.3.2",
    "@microsoft/applicationinsights-shims": "3.0.1",
    "@microsoft/applicationinsights-web": "3.3.2",
    "@microsoft/sp-adaptive-card-extension-base": "1.19.0",
    "@microsoft/sp-core-library": "1.19.0",
    "@microsoft/sp-http": "1.19.0",
    "@microsoft/sp-lodash-subset": "1.19.0",
    "@microsoft/sp-office-ui-fabric-core": "1.19.0",
    "@microsoft/sp-property-pane": "1.19.0",
    "@microsoft/sp-webpart-base": "1.19.0",
    "@pnp/common": "^2.13.0",
    "@pnp/graph": "^2.13.0",
    "@pnp/logging": "^2.13.0",
    "@pnp/odata": "^2.13.0",
    "@pnp/sp": "^2.13.0",
    "@pnp/spfx-property-controls": "^3.18.0",
    "@types/sharepoint": "^2016.1.10",
    "natives": "^1.1.6",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-jsonschema-form": "^1.8.1",
    "store": "^2.0.12",
    "tslib": "2.3.1"
  },

Nodejs 18.20.1

jpalo avatar Sep 17 '24 09:09 jpalo

Hello @jcoolsen, Thank you for bringing this issue to our attention. We will look into it and get back to you shortly.

Ashlesha-MSFT avatar Apr 29 '25 04:04 Ashlesha-MSFT

@jcoolsen, We suggest adding the targetDocument setting to the FluentProvider, so it knows exactly where to place its styles on the page.

Please let us know if this works for you

Ashlesha-MSFT avatar Apr 29 '25 06:04 Ashlesha-MSFT

@jcoolsen The SP's FluentUIProvider will collides with your own because of some Ids that are generated and which won't be unique across the page.

The workaround is to isolate your own FluentUIProvider context by specifying a unique ID using something similar to:

return <IdPrefixProvider value="someuniqueid">
      <FluentProvider theme={someTheme}>
         <YourComponent />
      </FluentProvider>

The issue is that you have to bring a theme when using a FluentUIProvider. If you want to follow the SP branding, which can be either SP itself of Teams hosted, you will have to convert the SP Theme (FluentUI8) a Fluent UI 9 theme.

I suggest you to follow how pnp spfx controls react teams handled the issue:

export const UserPicker: React.FunctionComponent<IUserPickerProps> = (
  props: React.PropsWithChildren<IUserPickerProps>
) => {
  const { theme: themeV8, context } = props;
  const [theme, setTheme] = React.useState<Theme>();
  const currentSPTheme = useTheme();
  const [isInitialized, setIsInitialized] = React.useState<boolean>(false);


  React.useEffect(() => {
    (async () => {
      if (has(context, "sdks.microsoftTeams.teamsJs.app.getContext")) {
        const teamsContext = await (context as WebPartContext).sdks.microsoftTeams?.teamsJs.app.getContext();
        const teamsTheme = teamsContext.app.theme || "default";
        switch (teamsTheme) {
          case "dark":
            setTheme(teamsDarkTheme);
            break;
          case "contrast":
            setTheme(teamsHighContrastTheme);
            break;
          case "default":
            setTheme(teamsLightTheme);
            break;
          default:
            setTheme(teamsLightTheme);
            break;
        }
      } else {
        setTheme(createV9Theme(currentSPTheme));
      }
      setIsInitialized(true);
    })();
  }, [context, currentSPTheme]);

  if (!isInitialized) return <></>;

  return (
    <>
      <IdPrefixProvider value="userPicker-">
      <FluentProvider theme={theme}>
        <Provider>
          <UserPickerControl {...props} />
        </Provider>
      </FluentProvider>
      </IdPrefixProvider>
    </>
  );
};

stevebeauge avatar Apr 29 '25 07:04 stevebeauge

Thank you @stevebeauge . This is also the solution/workaround (https://github.com/microsoft/fluentui/issues/32253#issuecomment-2283158405) that https://github.com/emmayjiang suggested in the linked issue and we have been using it since August 2024. And yes, we also attempt to convert the SP theme to Fluent theme, which is a difficult and error prone task. How this all connects with targetDocument, I don't know, but maybe there is another edge case if one is working with iframes, @Ashlesha-MSFT ?

jcoolsen avatar Apr 29 '25 07:04 jcoolsen

@jcoolsen, We were able to reproduce the issue. We have logged this as a bug, and our engineering team will look into it. Thank you for your patience!

Image

Ashlesha-MSFT avatar May 08 '25 16:05 Ashlesha-MSFT