apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Popup.mdx
import { Meta } from '@storybook/addon-docs/blocks';
<Meta title="Concepts/Migration/from v0/Components/Popup Migration" />Before:
import { Popup, Button } from '@fluentui/react-northstar';
const Component = () => <Popup trigger={<Button>trigger</Button>} content="content" />;
After:
import { Popover, PopoverTrigger, PopoverSurface, Button } from '@fluentui/react-components';
const Component = () => (
// v0 Popup has default position/align above/start, while v9 has default above/center. Therefore adding `positioning` prop here
// v0 Popup no arrow by default, while v9 has. Therefore adding `noArrow` prop here
<Popover positioning={'above-start'} noArrow>
<PopoverTrigger>
<Button>trigger</Button>
</PopoverTrigger>
<PopoverSurface>content</PopoverSurface>
</Popover>
);
| Popup props | migrate guide |
|---|---|
| defaultOpen, closeOnScroll, inline, open, onOpenChange, mountNode, mouseLeaveDelay, trapFocus | keep it as is |
| content, contentRef | see Migrate content and contentRef in this document |
| trigger | Move `trigger` to JSX children of `PopoverTrigger` component |
| pointing | Replace with `withArrow={true}` |
| on | Replace `on='hover'` with `openOnHover`; `on='content'` with `openOnContext` |
align, autoSize, flipBoundary, offset,overflowBoundary,popperRef,position,positionFixed,target, unstable_disableTether, unstable_pinned are now attributes of the positioning prop.
v9 positioning shorthand is recommended when only positon or/and align is used: <Popup position="below" align="end" /> can be migrated to a string like <Popover positioning="below-end" />.
See Migrate positioning props for more.
accessibility - so far there is no usage of custom accessibility on Popup in TMP. Please consult with fluent team on how to migrate custom accessibility if you're using any.
renderContent - please use JSX children as content. updatePosition can be replaced with popperRef.current.updatePosition() (codesandbox example RenderContentExample.jsx)
tabbableTrigger - by default v0 has tabbableTrigger=true. When tabbableTrigger=false is specified, popup trigger will not have aria-haspopup="dialog". If this is desired, it can be achieved by adding aria-haspopup=undefined on popup trigger (codesandbox example)
autoFocus - can be achieved by setting focus manually on popover content (codesandbox example AutoFocusExample.jsx)
Here's a codesandbox comparing v0 Popup and v9 Popover.
contentRef can be replaced by React ref on PopoverSurface.
When content value is JSX, move it to children of PopoverSurface component.
When content value is shorthand object, for example
content = { content: 'hi', variables: { someVariable: true } };
Migrate variables to use makeStyles API. Before:
// in COMPONENT_NAME.tsx
import { Popup } from '@fluentui/react-northstar';
export const Component = props => (
<Popup
content={{
content: props.content,
variables: { isCustomPopup: true },
}}
trigger={props.trigger}
/>
);
// in popup-content-styles.ts
export const popupContentStyles = {
root: ({ variables: { isCustomPopup } }) => ({
...(isCustomPopup && {
backgroundColor: colorSchemeBrand.background,
}),
}),
};
After:
// in COMPONENT_NAME.tsx
import { Popover, PopoverTrigger, PopoverSurface } from '@fluentui/react-components';
import { useStyles } from './COMPONENT_NAME.styles.ts';
export const Component = () => {
const classes = useStyles();
return (
<Popover positioning={'above-start'} noArrow>
<PopoverTrigger>{props.trigger}</PopoverTrigger>
<PopoverSurface className={classes.customPopup}>{props.content}</PopoverSurface>
</Popover>
);
};
// in COMPONENT_NAME.styles.ts
import { makeStyles, tokens } from '@fluentui/react-components';
export const useStyles = makeStyles({
customPopup: {
backgroundColor: tokens.colorBrandBackground,
},
});
⚠️ If this is your first time migrating style overrides, please read the general guide on how to migrate styles.
If you have nested popups, and migrate to v9 inner popup first, you might have a problem with handling of Escape key.
To prevent this problem you can use onKeyDown prop on PopoverSurface to prevent Escape key from bubbling up to the outer popup.
<PopoverSurface
onKeyDown={e => {
if (e.key === 'Escape') {
e.stopPropagation();
}
}}
/>
You can check out this codesandbox for an example.
Note: this workaround is not needed if you migrate outer popup first or if you migrate both popups at the same time.