diff --git a/change/@fluentui-react-58740d71-828a-4058-8da6-75706dd8794d.json b/change/@fluentui-react-58740d71-828a-4058-8da6-75706dd8794d.json new file mode 100644 index 00000000000000..ac713f6b5135a5 --- /dev/null +++ b/change/@fluentui-react-58740d71-828a-4058-8da6-75706dd8794d.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: Preventing blanket selectors from Fabric component from being applied via new preventBlanketFontInheritance prop.", + "packageName": "@fluentui/react", + "email": "humberto_makoto@hotmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react/etc/react.api.md b/packages/react/etc/react.api.md index 21b743a4200cae..5fa51df95c8522 100644 --- a/packages/react/etc/react.api.md +++ b/packages/react/etc/react.api.md @@ -5798,6 +5798,7 @@ export interface IFabricProps extends React_2.HTMLAttributes, Re // (undocumented) componentRef?: IRefObject<{}>; dir?: 'rtl' | 'ltr' | 'auto'; + preventBlanketFontInheritance?: boolean; styles?: IStyleFunctionOrObject; theme?: ITheme; } @@ -6593,6 +6594,7 @@ export interface ILayerProps extends React_2.HTMLAttributes, Rea className?: string; componentRef?: IRefObject; eventBubblingEnabled?: boolean; + fabricProps?: IFabricProps; hostId?: string; insertFirst?: boolean; onLayerDidMount?: () => void; diff --git a/packages/react/src/components/Fabric/Fabric.styles.ts b/packages/react/src/components/Fabric/Fabric.styles.ts index f89418eae03ec2..c9b73b69103a7e 100644 --- a/packages/react/src/components/Fabric/Fabric.styles.ts +++ b/packages/react/src/components/Fabric/Fabric.styles.ts @@ -14,7 +14,7 @@ export interface IFabricClassNames { } export const getStyles = (props: IFabricStyleProps): IFabricStyles => { - const { theme, className, applyTheme } = props; + const { applyTheme, className, preventBlanketFontInheritance, theme } = props; const classNames = getGlobalClassNames(GlobalClassNames, theme); return { root: [ @@ -22,11 +22,11 @@ export const getStyles = (props: IFabricStyleProps): IFabricStyles => { theme.fonts.medium, { color: theme.palette.neutralPrimary, - selectors: { - '& button': inheritFont, - '& input': inheritFont, - '& textarea': inheritFont, - }, + }, + !preventBlanketFontInheritance && { + '& button': inheritFont, + '& input': inheritFont, + '& textarea': inheritFont, }, // apply theme to only if applyTheme is true applyTheme && { diff --git a/packages/react/src/components/Fabric/Fabric.types.ts b/packages/react/src/components/Fabric/Fabric.types.ts index ee9f6b4b56098e..7031b1a1327a65 100644 --- a/packages/react/src/components/Fabric/Fabric.types.ts +++ b/packages/react/src/components/Fabric/Fabric.types.ts @@ -35,6 +35,18 @@ export interface IFabricProps extends React.HTMLAttributes, Reac * contextual theme object is set correctly so that css registered with merge-styles can be auto flipped correctly. */ dir?: 'rtl' | 'ltr' | 'auto'; + + /** + * By default, the Fabric component has children selectors for button, input and textarea elements that apply the + * style `fontFamily: 'inherit'`. This is done so the font family is consistent across all of these elements under a + * Fabric component. However, this is expensive in style recalculation scenarios and it is not the responsibility of + * the Fabric component to ensure that non-Fluent elements within it have these styles. + * Setting this prop to true prevents the Fabric component from applying these children selectors. As long as only + * v8 Fluent components are being used within it, no changes should be apparent since all Fluent components already + * set the font family in their styles. + * @defaultvalue false + */ + preventBlanketFontInheritance?: boolean; } export interface IFabricStyleProps extends IFabricProps { diff --git a/packages/react/src/components/Layer/Layer.base.tsx b/packages/react/src/components/Layer/Layer.base.tsx index 2fe4e39f530fc7..1a2df39aa09eca 100644 --- a/packages/react/src/components/Layer/Layer.base.tsx +++ b/packages/react/src/components/Layer/Layer.base.tsx @@ -6,6 +6,7 @@ import * as ReactDOM from 'react-dom'; import { Fabric } from '../../Fabric'; import { classNamesFunction, + css, getDocument, setPortalAttribute, setVirtualParent, @@ -30,26 +31,29 @@ export const LayerBase: React.FunctionComponent = React.forwardRef< const rootRef = React.useRef(null); const mergedRef = useMergedRefs(rootRef, ref); const layerRef = React.useRef(); - const fabricRef = React.useRef(null); + const fabricElementRef = React.useRef(null); // Tracks if the layer mount events need to be raised. // Required to allow the DOM to render after the layer element is added. const [needRaiseLayerMount, setNeedRaiseLayerMount] = React.useState(false); const { - eventBubblingEnabled, - styles, - theme, - className, children, + className, + eventBubblingEnabled, + fabricProps, hostId, + insertFirst, onLayerDidMount = () => undefined, // eslint-disable-next-line deprecation/deprecation onLayerMounted = () => undefined, onLayerWillUnmount, - insertFirst, + styles, + theme, } = props; + const fabricRef = useMergedRefs(fabricElementRef, fabricProps?.ref); + const classNames = getClassNames(styles!, { theme: theme!, className, @@ -166,7 +170,8 @@ export const LayerBase: React.FunctionComponent = React.forwardRef< {/* eslint-disable deprecation/deprecation */} {children} diff --git a/packages/react/src/components/Layer/Layer.types.ts b/packages/react/src/components/Layer/Layer.types.ts index daee3f207d69a6..4bd0eebb6225ea 100644 --- a/packages/react/src/components/Layer/Layer.types.ts +++ b/packages/react/src/components/Layer/Layer.types.ts @@ -1,4 +1,5 @@ import * as React from 'react'; +import type { IFabricProps } from '../../Fabric'; import type { IStyle, ITheme } from '../../Styling'; import type { IRefObject, IStyleFunctionOrObject } from '../../Utilities'; @@ -70,6 +71,11 @@ export interface ILayerProps extends React.HTMLAttributes, React * By default, the layer will be appended at the end to the host */ insertFirst?: boolean; + + /** + * Props bag to forward to the Fabric component to allow customization of its behavior. + */ + fabricProps?: IFabricProps; } /**