Library
React Components / v9 (@fluentui/react-components)
Describe the feature that you would like added
FluentProvider provider is unaware of shadow DOM and therefore does not inject styles in a way that is 100% compatible with shadow DOM (examples below).
Currently workarounds exist for this issue but we should explore options for something like a "ShadowDomFluentProvider" to provide a simple experience for users that "just works".
Have you discussed this feature with our team
Sean Monahan (@spmonahan)
Additional context
Consider the following JSX snippet:
<shadow-dom>
<FluentProvider theme={webLightTheme}>
<FluentControls/>
</FluentProvider>
</shadow-dom>
This renders the following HTML snippet:
<div>
#shadow-root
<div class="fui-FluentProvider fui-FluentProvider1 ...">
<!-- ... -->
</div>
</div>
Internally FluentProvider takes the theme prop and generates a CSS style declaration of CSS vars and inserts this style into document.head as a <style> tag. The style targets the provider by class name. That is it looks something like:
.fui-FluentProvider1 {
--var-1 ...
}
Because a shadow boundary exists between the targeted DOM node and the style definition the styles do not apply and Fluent controls within the shadow DOM do not get access to the CSS vars despite the fact the CSS vars pierce the shadow boundary.
This can be handled in a couple ways today.
- Put
FluentProvider in the light DOM
- Use
createCSSRuleFromTheme() and insert the styles into the shadow DOM.
Examples of each are here: https://stackblitz.com/@spmonahan/collections/fluent-ui-react-styling-with-shadow-dom
Both of these require fairly detailed knowledge of how Fluent theming works, which is fine, but not necessarily a nice developer experience. We should consider other options to make FluentProvider "just work" with these other options as "advanced options".
With that, a couple ideas:
Make FluentProvider aware of the shadow DOM
By using Node.getRootNode() FluentProvider can know whether it is rendered within a shadow root and conditionally insert its styles into the shadow root (or use constructable stylesheets).
Discarded. See comment for details.
Make a "themeless" Provider
Similar in concept to HeadlessProvider but rather than omit a DOM element this provider will attach no styles by default, instead relying on users to provide them. FluentProvider provides more than just the theme so we'd like to continue to use these other features without the theme.
Make a simple "shadow dom aware" component for injecting styles
This would be used alongside ThemelessProvider to inject styles when necessary.
Validations
Priority
High
Library
React Components / v9 (@fluentui/react-components)
Describe the feature that you would like added
FluentProviderprovider is unaware of shadow DOM and therefore does not inject styles in a way that is 100% compatible with shadow DOM (examples below).Currently workarounds exist for this issue but we should explore options for something like a "ShadowDomFluentProvider" to provide a simple experience for users that "just works".
Have you discussed this feature with our team
Sean Monahan (@spmonahan)
Additional context
Consider the following JSX snippet:
This renders the following HTML snippet:
Internally
FluentProvidertakes the theme prop and generates a CSS style declaration of CSS vars and inserts this style intodocument.headas a<style>tag. The style targets the provider by class name. That is it looks something like:Because a shadow boundary exists between the targeted DOM node and the style definition the styles do not apply and Fluent controls within the shadow DOM do not get access to the CSS vars despite the fact the CSS vars pierce the shadow boundary.
This can be handled in a couple ways today.
FluentProviderin the light DOMcreateCSSRuleFromTheme()and insert the styles into the shadow DOM.Examples of each are here: https://stackblitz.com/@spmonahan/collections/fluent-ui-react-styling-with-shadow-dom
Both of these require fairly detailed knowledge of how Fluent theming works, which is fine, but not necessarily a nice developer experience. We should consider other options to make
FluentProvider"just work" with these other options as "advanced options".With that, a couple ideas:
Make
FluentProvideraware of the shadow DOMBy usingNode.getRootNode()FluentProvidercan know whether it is rendered within a shadow root and conditionally insert its styles into the shadow root (or use constructable stylesheets).Discarded. See comment for details.
Make a "themeless" Provider
Similar in concept to
HeadlessProviderbut rather than omit a DOM element this provider will attach no styles by default, instead relying on users to provide them.FluentProviderprovides more than just the theme so we'd like to continue to use these other features without the theme.Make a simple "shadow dom aware" component for injecting styles
This would be used alongside
ThemelessProviderto inject styles when necessary.Validations
Priority
High