UNPKG

1.57 kBPlain TextView Raw
1import { useWarning } from "reakit-warning";
2import { createComponent } from "reakit-system/createComponent";
3import { useCreateElement } from "reakit-system/useCreateElement";
4import { createHook } from "reakit-system/createHook";
5import { useForkRef } from "reakit-utils/useForkRef";
6import { DialogOptions, DialogHTMLProps, useDialog } from "../Dialog/Dialog";
7import { PopoverStateReturn } from "./PopoverState";
8import { POPOVER_KEYS } from "./__keys";
9
10export type PopoverOptions = DialogOptions &
11 Pick<
12 Partial<PopoverStateReturn>,
13 "unstable_popoverRef" | "unstable_popoverStyles"
14 >;
15
16export type PopoverHTMLProps = DialogHTMLProps;
17
18export type PopoverProps = PopoverOptions & PopoverHTMLProps;
19
20export const usePopover = createHook<PopoverOptions, PopoverHTMLProps>({
21 name: "Popover",
22 compose: useDialog,
23 keys: POPOVER_KEYS,
24
25 useOptions({ modal = false, ...options }) {
26 return { modal, ...options };
27 },
28
29 useProps(options, { ref: htmlRef, style: htmlStyle, ...htmlProps }) {
30 return {
31 ref: useForkRef(options.unstable_popoverRef, htmlRef),
32 style: { ...options.unstable_popoverStyles, ...htmlStyle },
33 ...htmlProps,
34 };
35 },
36});
37
38export const Popover = createComponent({
39 as: "div",
40 useHook: usePopover,
41 useCreateElement: (type, props, children) => {
42 useWarning(
43 !props["aria-label"] && !props["aria-labelledby"],
44 "You should provide either `aria-label` or `aria-labelledby` props.",
45 "See https://reakit.io/docs/popover"
46 );
47 return useCreateElement(type, props, children);
48 },
49});