Skip to content

Commit 80aaabe

Browse files
authored
Merge pull request #8164 from primefaces/v11-popover
New Component: Popover
2 parents d75ea14 + 6584f8e commit 80aaabe

37 files changed

Lines changed: 1431 additions & 0 deletions
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { InputText } from 'primereact/inputtext';
2+
import { Label } from 'primereact/label';
3+
import { Popover } from 'primereact/popover';
4+
5+
export default function BasicDemo() {
6+
return (
7+
<div className="card flex items-center justify-center">
8+
<Popover>
9+
<Popover.Trigger>Show Popover</Popover.Trigger>
10+
<Popover.Portal>
11+
<Popover.Content>
12+
<div className="flex flex-col gap-2 p-2 max-w-xs">
13+
<p className="text-lg font-semibold mb-0.5">Dimensions</p>
14+
<div className="grid grid-cols-2 items-center">
15+
<Label htmlFor="width">Width</Label>
16+
<InputText id="width" fluid />
17+
</div>
18+
<div className="grid grid-cols-2 items-center">
19+
<Label htmlFor="maxWidth">Max. width</Label>
20+
<InputText id="maxWidth" fluid />
21+
</div>
22+
<div className="grid grid-cols-2 items-center">
23+
<Label htmlFor="height">Height</Label>
24+
<InputText id="height" fluid />
25+
</div>
26+
<div className="grid grid-cols-2 items-center">
27+
<Label htmlFor="maxHeight">Max. height</Label>
28+
<InputText id="maxHeight" fluid />
29+
</div>
30+
</div>
31+
<Popover.Close className="absolute top-4 right-4" />
32+
</Popover.Content>
33+
</Popover.Portal>
34+
</Popover>
35+
</div>
36+
);
37+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { usePopoverOpenChangeEvent } from '@primereact/types/shared/popover';
2+
import { Button } from 'primereact/button';
3+
import { InputText } from 'primereact/inputtext';
4+
import { Label } from 'primereact/label';
5+
import { Popover } from 'primereact/popover';
6+
import React from 'react';
7+
8+
function ControlledDemo() {
9+
const [open, setOpen] = React.useState(false);
10+
11+
return (
12+
<div className="card flex gap-4 justify-center items-center">
13+
<Button onClick={() => setOpen(!open)}>Show Popover</Button>
14+
15+
<Popover open={open} onOpenChange={(e: usePopoverOpenChangeEvent) => setOpen(e.value)}>
16+
<Popover.Trigger>Popover Trigger</Popover.Trigger>
17+
<Popover.Portal>
18+
<Popover.Content>
19+
<div className="flex flex-col gap-2 p-2 max-w-xs">
20+
<p className="text-lg font-semibold mb-0.5">Dimensions</p>
21+
<div className="grid grid-cols-2 items-center">
22+
<Label htmlFor="width">Width</Label>
23+
<InputText id="width" fluid />
24+
</div>
25+
<div className="grid grid-cols-2 items-center">
26+
<Label htmlFor="maxWidth">Max. width</Label>
27+
<InputText id="maxWidth" fluid />
28+
</div>
29+
<div className="grid grid-cols-2 items-center">
30+
<Label htmlFor="height">Height</Label>
31+
<InputText id="height" fluid />
32+
</div>
33+
<div className="grid grid-cols-2 items-center">
34+
<Label htmlFor="maxHeight">Max. height</Label>
35+
<InputText id="maxHeight" fluid />
36+
</div>
37+
</div>
38+
<Popover.Close className="absolute top-4 right-4" />
39+
</Popover.Content>
40+
</Popover.Portal>
41+
</Popover>
42+
</div>
43+
);
44+
}
45+
46+
export default ControlledDemo;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { usePopoverOpenChangeEvent } from '@primereact/types/shared/popover';
2+
import { Popover } from 'primereact/popover';
3+
import React from 'react';
4+
5+
const members = [
6+
{ name: 'Amy Elsner', image: 'amyelsner.png', email: 'amy@email.com', role: 'Owner' },
7+
{ name: 'Bernardo Dominic', image: 'bernardodominic.png', email: 'bernardo@email.com', role: 'Editor' },
8+
{ name: 'Ioni Bowcher', image: 'ionibowcher.png', email: 'ioni@email.com', role: 'Viewer' }
9+
];
10+
11+
function SelectDataDemo() {
12+
const [selectedMember, setSelectedMember] = React.useState<(typeof members)[0] | null>(members[0]);
13+
const [open, setOpen] = React.useState(false);
14+
15+
return (
16+
<div className="card flex justify-center">
17+
<Popover open={open} onOpenChange={(e: usePopoverOpenChangeEvent) => setOpen(e.value)}>
18+
<Popover.Trigger className="min-w-48">{selectedMember?.name}</Popover.Trigger>
19+
<Popover.Portal>
20+
<Popover.Content>
21+
<div className="flex flex-col gap-4">
22+
<div>
23+
<span className="font-medium block mb-2">Team Members</span>
24+
<ul className="list-none p-0 m-0 flex flex-col">
25+
{members.map((member) => (
26+
<li
27+
key={member.name}
28+
className="flex items-center gap-2 px-2 py-3 hover:bg-emphasis cursor-pointer rounded-border"
29+
onClick={() => {
30+
setSelectedMember(member);
31+
setOpen(false);
32+
}}
33+
>
34+
<img src={`https://primefaces.org/cdn/primevue/images/avatar/${member.image}`} style={{ width: '32px' }} />
35+
<div>
36+
<span className="font-medium">{member.name}</span>
37+
<div className="text-sm text-surface-500 dark:text-surface-400">{member.email}</div>
38+
</div>
39+
</li>
40+
))}
41+
</ul>
42+
</div>
43+
</div>
44+
</Popover.Content>
45+
</Popover.Portal>
46+
</Popover>
47+
</div>
48+
);
49+
}
50+
51+
export default SelectDataDemo;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
---
2+
title: Popover API
3+
description: API documentation for Popover component
4+
component: popover
5+
---
6+
7+
## Popover
8+
9+
### Props
10+
11+
<DocTable name="Popover" category="api" type="props" />
12+
13+
### State
14+
15+
<DocTable name="Popover" category="api" type="state" />
16+
17+
### Exposes
18+
19+
<DocTable name="Popover" category="api" type="exposes" />
20+
21+
### Interfaces
22+
23+
<DocTable name="Popover" category="api" type="interfaces" />
24+
25+
### Types
26+
27+
<DocTable name="Popover" category="api" type="types" />
28+
29+
## PopoverTrigger
30+
31+
### Props
32+
33+
<DocTable name="PopoverTrigger" category="api" type="props" />
34+
35+
### Exposes
36+
37+
<DocTable name="PopoverTrigger" category="api" type="exposes" />
38+
39+
### Interfaces
40+
41+
<DocTable name="PopoverTrigger" category="api" type="interfaces" />
42+
43+
### Types
44+
45+
<DocTable name="PopoverTrigger" category="api" type="types" />
46+
47+
## PopoverPortal
48+
49+
### Props
50+
51+
<DocTable name="PopoverPortal" category="api" type="props" />
52+
53+
### Exposes
54+
55+
<DocTable name="PopoverPortal" category="api" type="exposes" />
56+
57+
### Interfaces
58+
59+
<DocTable name="PopoverPortal" category="api" type="interfaces" />
60+
61+
### Types
62+
63+
<DocTable name="PopoverPortal" category="api" type="types" />
64+
65+
## PopoverContent
66+
67+
### Props
68+
69+
<DocTable name="PopoverContent" category="api" type="props" />
70+
71+
### Exposes
72+
73+
<DocTable name="PopoverContent" category="api" type="exposes" />
74+
75+
### Interfaces
76+
77+
<DocTable name="PopoverContent" category="api" type="interfaces" />
78+
79+
### Types
80+
81+
<DocTable name="PopoverContent" category="api" type="types" />
82+
83+
## PopoverClose
84+
85+
### Props
86+
87+
<DocTable name="PopoverClose" category="api" type="props" />
88+
89+
### Exposes
90+
91+
<DocTable name="PopoverClose" category="api" type="exposes" />
92+
93+
### Interfaces
94+
95+
<DocTable name="PopoverClose" category="api" type="interfaces" />
96+
97+
### Types
98+
99+
<DocTable name="PopoverClose" category="api" type="types" />
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: Popover
3+
description: Popover is a container component that can overlay other components on page.
4+
component: popover
5+
---
6+
7+
## Import
8+
9+
```tsx
10+
import { Popover } from 'primereact/popover';
11+
```
12+
13+
```tsx
14+
<Popover>
15+
<Popover.Trigger></Popover.Trigger>
16+
<Popover.Portal>
17+
<Popover.Content>
18+
<Popover.Close />
19+
</Popover.Content>
20+
</Popover.Portal>
21+
</Popover>
22+
```
23+
24+
## Basic
25+
26+
<DocDemoViewer name="popover:basic-demo" />
27+
28+
## Controlled
29+
30+
Use the `open` and `onOpenChange` props to control the popover state.
31+
32+
<DocDemoViewer name="popover:controlled-demo" />
33+
34+
## Select Data
35+
36+
<DocDemoViewer name="popover:select-data-demo" />
37+
38+
## Accessibility
39+
40+
### Screen Reader
41+
42+
Popover component uses dialog role and since any attribute is passed to the root element you may define attributes like aria-label or aria-labelledby to describe the popup contents. In addition aria-modal is added since focus is kept within the popup.
43+
44+
Popover adds aria-expanded state attribute and aria-controls to the trigger so that the relation between the trigger and the popup is defined.
45+
46+
### Popover Keyboard Support
47+
48+
When the popup gets opened, the first focusable element receives the focus and this can be customized by adding autofocus to an element within the popup.
49+
50+
| Key | Function |
51+
| ------------- | ------------------------------------------------------------------- |
52+
| `tab` | Moves focus to the next the focusable element within the popup. |
53+
| `shift + tab` | Moves focus to the previous the focusable element within the popup. |
54+
| `escape` | Closes the popup and moves focus to the trigger. |
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: Popover Pass Through
3+
description: Pass Through documentation for Popover component
4+
component: popover
5+
---
6+
7+
## Viewer
8+
9+
Some sections may not be visible due to the availability of the particular feature.
10+
11+
<DocPTViewer name="popover-pt" components={['Popover']} />
12+
13+
## Popover PT Options
14+
15+
<DocTable name="Popover" category="pt" />
16+
17+
## PopoverTrigger PT Options
18+
19+
<DocTable name="PopoverTrigger" category="pt" />
20+
21+
## PopoverPortal PT Options
22+
23+
<DocTable name="PopoverPortal" category="pt" />
24+
25+
## PopoverContent PT Options
26+
27+
<DocTable name="PopoverContent" category="pt" />
28+
29+
## PopoverClose PT Options
30+
31+
<DocTable name="PopoverClose" category="pt" />
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: Popover Theming
3+
description: Theming documentation for Popover component
4+
component: popover
5+
---
6+
7+
## Styled
8+
9+
### CSS Classes
10+
11+
List of class names used in the styled mode.
12+
13+
<DocTable name="Popover" category="style" />
14+
15+
### Design Tokens
16+
17+
List of design tokens.
18+
19+
<DocTable name="Popover" category="token" />
20+
21+
## Unstyled
22+
23+
Theming is implemented with the pass through properties in unstyled mode.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './usePopover';
2+
export * from './usePopover.props';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { usePopoverProps } from '@primereact/types/shared/popover';
2+
3+
export const defaultProps: usePopoverProps = {
4+
dismissable: true,
5+
appendTo: 'body',
6+
baseZIndex: 0,
7+
autoZIndex: true,
8+
breakpoints: {},
9+
closeOnEscape: true,
10+
defaultOpen: undefined,
11+
open: undefined,
12+
onOpenChange: undefined,
13+
triggerRef: undefined,
14+
containerRef: undefined
15+
};

packages/headless/src/popover/usePopover.test.ts

Whitespace-only changes.

0 commit comments

Comments
 (0)