Skip to content

Commit e2b820b

Browse files
committed
add popover doc example
1 parent 22d75b0 commit e2b820b

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
I using a `Dialog` without a `DialogTrigger`, it is up to the user to make sure that the focus is restored correctly
1+
When using a `Dialog` without a `DialogTrigger`, it is up to the user to make sure that the focus is restored correctly
22
when the dialog is closed. This can be done quite easily by using the `useRestoreFocusTarget` hook. The `Dialog` already
33
uses the `useRestoreFocusSource` hook directly, which will restore focus to the most recently focused target on close.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import * as React from 'react';
2+
import {
3+
makeStyles,
4+
shorthands,
5+
Button,
6+
Popover,
7+
PopoverSurface,
8+
useId,
9+
useRestoreFocusTarget,
10+
} from '@fluentui/react-components';
11+
import type { PositioningImperativeRef } from '@fluentui/react-components';
12+
const useStyles = makeStyles({
13+
container: {
14+
display: 'flex',
15+
...shorthands.gap('10px'),
16+
},
17+
18+
contentHeader: {
19+
marginTop: '0',
20+
},
21+
});
22+
23+
export const WithoutTrigger = () => {
24+
const [open, setOpen] = React.useState(false);
25+
const headerId = useId();
26+
const buttonRef = React.useRef<HTMLButtonElement>(null);
27+
const positioningRef = React.useRef<PositioningImperativeRef>(null);
28+
const styles = useStyles();
29+
const restoreFocusTargetAttribute = useRestoreFocusTarget();
30+
31+
React.useEffect(() => {
32+
if (buttonRef.current) {
33+
positioningRef.current?.setTarget(buttonRef.current);
34+
}
35+
}, [buttonRef, positioningRef]);
36+
37+
return (
38+
<div className={styles.container}>
39+
<Button {...restoreFocusTargetAttribute} ref={buttonRef} onClick={() => setOpen(s => !s)}>
40+
Toggle popover
41+
</Button>
42+
<Popover onOpenChange={(_, data) => setOpen(data.open)} trapFocus open={open} positioning={{ positioningRef }}>
43+
<PopoverSurface aria-labelledby={headerId}>
44+
<div>
45+
<h3 id={headerId} className={styles.contentHeader}>
46+
Popover content
47+
</h3>
48+
49+
<div>This is some popover content</div>
50+
</div>
51+
52+
<div>
53+
<Button>Action</Button>
54+
<Button>Action</Button>
55+
</div>
56+
</PopoverSurface>
57+
</Popover>
58+
</div>
59+
);
60+
};
61+
62+
WithoutTrigger.parameters = {
63+
docs: {
64+
description: {
65+
story: [
66+
'When using a `Popover` without a `PopoverTrigger`, it is up to the user to make sure that the focus is restored correctly',
67+
'when the popover is closed. This can be done quite easily by using the `useRestoreFocusTarget` hook. The `Popover` already',
68+
'uses the `useRestoreFocusSource` hook directly, which will restore focus to the most recently focused target on close.',
69+
].join('\n'),
70+
},
71+
},
72+
};

packages/react-components/react-popover/stories/Popover/index.stories.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export { ControllingOpenAndClose } from './PopoverControllingOpenAndClose.storie
1010
export { NestedPopovers } from './PopoverNestedPopovers.stories';
1111
export { AnchorToCustomTarget } from './PopoverAnchorToCustomTarget.stories';
1212
export { CustomTrigger } from './PopoverCustomTrigger.stories';
13+
export { WithoutTrigger } from './PopoverWithoutTrigger.stories';
1314
export { InternalUpdateContent } from './PopoverInternalUpdateContent.stories';
1415
export { Appearance } from './PopoverAppearance.stories';
1516

0 commit comments

Comments
 (0)