diff --git a/packages/fluentui/CHANGELOG.md b/packages/fluentui/CHANGELOG.md index 72d332cf7a4fdf..3bf2cfb7aab142 100644 --- a/packages/fluentui/CHANGELOG.md +++ b/packages/fluentui/CHANGELOG.md @@ -66,6 +66,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Fix `Loader` component to properly pass ref to root slots @chpalac ([#20814](https://github.com/microsoft/fluentui/pull/20814)) - Fix `Label` component to properly pass ref to root slots @chpalac ([#20813](https://github.com/microsoft/fluentui/pull/20813)) - Fix `MenuItemIcon` to allow icon `size` to be in effect @yuanboxue-amber ([#20803](https://github.com/microsoft/fluentui/pull/20803)) +- Fix `PopupContent` component to properly pass ref to root slots @chpalac ([#20866](https://github.com/microsoft/fluentui/pull/20866)) - Fix `Pill` components to properly pass ref to root slots @chpalac ([#20838](https://github.com/microsoft/fluentui/pull/20838)) - Fix `MenuButton` component to properly pass ref to root slots @chpalac ([#20837](https://github.com/microsoft/fluentui/pull/20837)) - Fix `getPointerStyles` transform for RTL @chpalac ([#20915](https://github.com/microsoft/fluentui/pull/20915)) diff --git a/packages/fluentui/react-bindings/src/FocusZone/AutoFocusZone.tsx b/packages/fluentui/react-bindings/src/FocusZone/AutoFocusZone.tsx index 1697fc3a8db220..9d36024a9e736f 100644 --- a/packages/fluentui/react-bindings/src/FocusZone/AutoFocusZone.tsx +++ b/packages/fluentui/react-bindings/src/FocusZone/AutoFocusZone.tsx @@ -1,4 +1,4 @@ -import { Ref } from '@fluentui/react-component-ref'; +import { handleRef } from '@fluentui/react-component-ref'; import { callable } from '@fluentui/styles'; import * as React from 'react'; import * as PropTypes from 'prop-types'; @@ -16,6 +16,7 @@ export class AutoFocusZone extends React.Component { static propTypes = { as: PropTypes.elementType, firstFocusableSelector: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), + innerRef: PropTypes.any, }; static handledProps = _.keys(AutoFocusZone.propTypes) as any; @@ -29,9 +30,15 @@ export class AutoFocusZone extends React.Component { const ElementType = getElementType(this.props); return ( - - {this.props.children} - + { + handleRef(this.root, element); + handleRef(this.props.innerRef, element); + }} + {...unhandledProps} + > + {this.props.children} + ); } diff --git a/packages/fluentui/react-bindings/src/FocusZone/AutoFocusZone.types.tsx b/packages/fluentui/react-bindings/src/FocusZone/AutoFocusZone.types.tsx index d19e57cc9559b2..2d8ef24bf035d9 100644 --- a/packages/fluentui/react-bindings/src/FocusZone/AutoFocusZone.types.tsx +++ b/packages/fluentui/react-bindings/src/FocusZone/AutoFocusZone.types.tsx @@ -8,4 +8,6 @@ export interface AutoFocusZoneProps extends React.HTMLAttributes * Indicates the selector for first focusable item. By default, the first tabbable element will get focus. */ firstFocusableSelector?: string | (() => string); + + innerRef?: React.Ref; } diff --git a/packages/fluentui/react-bindings/src/FocusZone/FocusTrapZone.tsx b/packages/fluentui/react-bindings/src/FocusZone/FocusTrapZone.tsx index e0fea4190f9f5c..9264ab38ebfc30 100644 --- a/packages/fluentui/react-bindings/src/FocusZone/FocusTrapZone.tsx +++ b/packages/fluentui/react-bindings/src/FocusZone/FocusTrapZone.tsx @@ -16,6 +16,7 @@ import { HIDDEN_FROM_ACC_TREE, } from './focusUtilities'; import { FocusTrapZoneProps } from './FocusTrapZone.types'; +import { handleRef } from '@fluentui/react-component-ref'; /** FocusTrapZone is used to trap the focus in any html element placed in body * and hide other elements outside of Focus Trap Zone from accessibility tree. @@ -56,6 +57,7 @@ export class FocusTrapZone extends React.Component { disableFirstFocus: PropTypes.bool, focusPreviouslyFocusedInnerElement: PropTypes.bool, focusTriggerOnOutsideClick: PropTypes.bool, + innerRef: PropTypes.any, }; static defaultProps: FocusTrapZoneProps = { @@ -140,7 +142,10 @@ export class FocusTrapZone extends React.Component { { + this.createRef(element); + handleRef(this.props.innerRef, element); + }} aria-labelledby={ariaLabelledBy} onKeyDown={this._onKeyboardHandler} onFocusCapture={this._onFocusCapture} diff --git a/packages/fluentui/react-bindings/src/FocusZone/FocusTrapZone.types.tsx b/packages/fluentui/react-bindings/src/FocusZone/FocusTrapZone.types.tsx index 5b2b5ccfa9bea6..6aa07e18094306 100644 --- a/packages/fluentui/react-bindings/src/FocusZone/FocusTrapZone.types.tsx +++ b/packages/fluentui/react-bindings/src/FocusZone/FocusTrapZone.types.tsx @@ -68,4 +68,6 @@ export interface FocusTrapZoneProps extends React.HTMLAttributes * If it has never had a focused descendant before, behavior falls back to the first focused descendant. */ focusPreviouslyFocusedInnerElement?: boolean; + + innerRef?: any; } diff --git a/packages/fluentui/react-northstar/src/components/Popup/PopupContent.tsx b/packages/fluentui/react-northstar/src/components/Popup/PopupContent.tsx index b5699e922dba29..20c436999530a4 100644 --- a/packages/fluentui/react-northstar/src/components/Popup/PopupContent.tsx +++ b/packages/fluentui/react-northstar/src/components/Popup/PopupContent.tsx @@ -1,6 +1,5 @@ import { Accessibility } from '@fluentui/accessibility'; import { - ComponentWithAs, AutoFocusZone, AutoFocusZoneProps, FocusTrapZone, @@ -11,6 +10,7 @@ import { useStyles, useTelemetry, useUnhandledProps, + ForwardRefWithAs, } from '@fluentui/react-bindings'; import * as customPropTypes from '@fluentui/react-proptypes'; import * as PopperJs from '@popperjs/core'; @@ -90,8 +90,7 @@ export const popupContentSlotClassNames: PopupContentSlotClassNames = { /** * A PopupContent displays the content of a Popup component. */ -export const PopupContent: ComponentWithAs<'div', PopupContentProps> & - FluentComponentStaticProps = props => { +export const PopupContent = (React.forwardRef((props, ref) => { const context = useFluentContext(); const { setStart, setEnd } = useTelemetry(PopupContent.displayName, context.telemetry); setStart(); @@ -162,22 +161,35 @@ export const PopupContent: ComponentWithAs<'div', PopupContentProps> & ...((_.keys(trapFocus).length && trapFocus) as FocusTrapZoneProps), as: ElementType, }; - element = {popupContent}; + element = ( + + {popupContent} + + ); } else if (autoFocus) { const autoFocusZoneProps = { ...popupContentProps, ...((_.keys(autoFocus).length && autoFocus) as AutoFocusZoneProps), as: ElementType, }; - element = {popupContent}; + element = ( + + {popupContent} + + ); } else { - element = {popupContent}; + element = ( + + {popupContent} + + ); } setEnd(); return element; -}; +}) as unknown) as ForwardRefWithAs<'div', HTMLDivElement, PopupContentProps> & + FluentComponentStaticProps; PopupContent.displayName = 'PopupContent';