Skip to content

Commit

Permalink
feat: adds mountNode to DialogSurface and Toaster (#29003)
Browse files Browse the repository at this point in the history
  • Loading branch information
bsunderhus committed Aug 29, 2023
1 parent 3162ff5 commit 3ef92a4
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "feat: adds mountNode to DialogSurface API",
"packageName": "@fluentui/react-dialog",
"email": "bernardo.sunderhus@gmail.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "feat: adds mountNode to Toaster API",
"packageName": "@fluentui/react-toast",
"email": "bernardo.sunderhus@gmail.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { ComponentProps } from '@fluentui/react-utilities';
import type { ComponentState } from '@fluentui/react-utilities';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
import { JSXElementConstructor } from 'react';
import type { PortalProps } from '@fluentui/react-portal';
import * as React_2 from 'react';
import { ReactElement } from 'react';
import type { Slot } from '@fluentui/react-utilities';
Expand Down Expand Up @@ -129,7 +130,7 @@ export const dialogSurfaceClassNames: SlotClassNames<DialogSurfaceSlots>;
export type DialogSurfaceElement = HTMLElement;

// @public
export type DialogSurfaceProps = ComponentProps<DialogSurfaceSlots>;
export type DialogSurfaceProps = ComponentProps<DialogSurfaceSlots> & Pick<PortalProps, 'mountNode'>;

// @public (undocumented)
export type DialogSurfaceSlots = {
Expand All @@ -138,7 +139,7 @@ export type DialogSurfaceSlots = {
};

// @public
export type DialogSurfaceState = ComponentState<DialogSurfaceSlots>;
export type DialogSurfaceState = ComponentState<DialogSurfaceSlots> & Pick<PortalProps, 'mountNode'>;

// @public
export const DialogTitle: ForwardRefComponent<DialogTitleProps>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';
import type { PortalProps } from '@fluentui/react-portal';
import { DialogSurfaceContextValue } from '../../contexts';

export type DialogSurfaceSlots = {
Expand All @@ -21,7 +22,7 @@ export type DialogSurfaceElement = HTMLElement;
/**
* DialogSurface Props
*/
export type DialogSurfaceProps = ComponentProps<DialogSurfaceSlots>;
export type DialogSurfaceProps = ComponentProps<DialogSurfaceSlots> & Pick<PortalProps, 'mountNode'>;

export type DialogSurfaceContextValues = {
dialogSurface: DialogSurfaceContextValue;
Expand All @@ -30,4 +31,4 @@ export type DialogSurfaceContextValues = {
/**
* State used in rendering DialogSurface
*/
export type DialogSurfaceState = ComponentState<DialogSurfaceSlots>;
export type DialogSurfaceState = ComponentState<DialogSurfaceSlots> & Pick<PortalProps, 'mountNode'>;
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const renderDialogSurface_unstable = (state: DialogSurfaceState, contextV
assertSlots<DialogSurfaceSlots>(state);

return (
<Portal>
<Portal mountNode={state.mountNode}>
{state.backdrop && <state.backdrop />}
<DialogSurfaceProvider value={contextValues.dialogSurface}>
<state.root />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const useDialogSurface_unstable = (
return {
components: { backdrop: 'div', root: 'div' },
backdrop,
mountNode: props.mountNode,
root: slot.always(
getNativeElementProps(props.as ?? 'div', {
tabIndex: -1, // https://github.com/microsoft/fluentui/issues/25150
Expand Down
5 changes: 3 additions & 2 deletions packages/react-components/react-toast/etc/react-toast.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { ComponentProps } from '@fluentui/react-utilities';
import type { ComponentState } from '@fluentui/react-utilities';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
import { JSXElementConstructor } from 'react';
import type { PortalProps } from '@fluentui/react-portal';
import * as React_2 from 'react';
import { ReactElement } from 'react';
import type { Slot } from '@fluentui/react-utilities';
Expand Down Expand Up @@ -70,7 +71,7 @@ export const Toaster: React_2.FC<ToasterProps>;
export const toasterClassNames: SlotClassNames<ToasterSlots>;

// @public
export type ToasterProps = Omit<ComponentProps<ToasterSlots>, 'children'> & Partial<ToasterOptions> & {
export type ToasterProps = Omit<ComponentProps<ToasterSlots>, 'children'> & Partial<ToasterOptions> & Pick<PortalProps, 'mountNode'> & {
announce?: Announce;
};

Expand All @@ -80,7 +81,7 @@ export type ToasterSlots = {
};

// @public
export type ToasterState = ComponentState<ToasterSlotsInternal> & Pick<AriaLiveProps, 'announceRef'> & Pick<Required<ToasterProps>, 'announce'> & {
export type ToasterState = ComponentState<ToasterSlotsInternal> & Pick<AriaLiveProps, 'announceRef'> & Pick<PortalProps, 'mountNode'> & Pick<Required<ToasterProps>, 'announce'> & {
offset: ToasterOptions['offset'] | undefined;
renderAriaLive: boolean;
dir: 'rtl' | 'ltr';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';
import type { PortalProps } from '@fluentui/react-portal';
import { ToasterOptions } from '../../state/types';
import { Announce, AriaLiveProps } from '../AriaLive';

Expand All @@ -21,7 +22,8 @@ export type ToasterSlotsInternal = ToasterSlots & {
* Toaster Props
*/
export type ToasterProps = Omit<ComponentProps<ToasterSlots>, 'children'> &
Partial<ToasterOptions> & {
Partial<ToasterOptions> &
Pick<PortalProps, 'mountNode'> & {
/**
* User override API for aria-live narration for toasts
*/
Expand All @@ -33,6 +35,7 @@ export type ToasterProps = Omit<ComponentProps<ToasterSlots>, 'children'> &
*/
export type ToasterState = ComponentState<ToasterSlotsInternal> &
Pick<AriaLiveProps, 'announceRef'> &
Pick<PortalProps, 'mountNode'> &
Pick<Required<ToasterProps>, 'announce'> & {
offset: ToasterOptions['offset'] | undefined;
renderAriaLive: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const renderToaster_unstable = (state: ToasterState) => {
<>
{renderAriaLive ? <AriaLive announceRef={announceRef} /> : null}
{hasToasts ? (
<Portal>
<Portal mountNode={state.mountNode}>
{state.bottomStart ? <state.bottomStart /> : null}
{state.bottomEnd ? <state.bottomEnd /> : null}
{state.topStart ? <state.topStart /> : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { useToastAnnounce } from './useToastAnnounce';
* @param props - props from this instance of Toaster
*/
export const useToaster_unstable = (props: ToasterProps): ToasterState => {
const { offset, announce: announceProp, ...rest } = props;
const { offset, announce: announceProp, mountNode, ...rest } = props;
const announceRef = React.useRef<Announce>(() => null);
const { toastsToRender, isToastVisible, pauseAllToasts, playAllToasts, tryRestoreFocus, closeAllToasts } =
useToaster<HTMLDivElement>(rest);
Expand Down Expand Up @@ -71,6 +71,7 @@ export const useToaster_unstable = (props: ToasterProps): ToasterState => {
};
return {
dir,
mountNode,
components: { root: 'div', bottomStart: 'div', bottomEnd: 'div', topStart: 'div', topEnd: 'div' },
root: slot.always(rootProps, { elementType: 'div' }),
bottomStart: usePositionSlot(TOAST_POSITIONS.bottomStart),
Expand Down

0 comments on commit 3ef92a4

Please sign in to comment.