UNPKG

2.61 kBPlain TextView Raw
1import * as React from "react";
2import { createComponent } from "reakit-system/createComponent";
3import { createHook } from "reakit-system/createHook";
4import { useForkRef } from "reakit-utils/useForkRef";
5import { useLiveRef } from "reakit-utils/useLiveRef";
6import { RoleOptions, RoleHTMLProps, useRole } from "../Role/Role";
7import { TooltipStateReturn } from "./TooltipState";
8import { TOOLTIP_REFERENCE_KEYS } from "./__keys";
9
10export type TooltipReferenceOptions = RoleOptions &
11 Pick<Partial<TooltipStateReturn>, "unstable_referenceRef" | "baseId"> &
12 Pick<TooltipStateReturn, "show" | "hide">;
13
14export type TooltipReferenceHTMLProps = RoleHTMLProps;
15
16export type TooltipReferenceProps = TooltipReferenceOptions &
17 TooltipReferenceHTMLProps;
18
19export const useTooltipReference = createHook<
20 TooltipReferenceOptions,
21 TooltipReferenceHTMLProps
22>({
23 name: "TooltipReference",
24 compose: useRole,
25 keys: TOOLTIP_REFERENCE_KEYS,
26
27 useProps(
28 options,
29 {
30 ref: htmlRef,
31 onFocus: htmlOnFocus,
32 onBlur: htmlOnBlur,
33 onMouseEnter: htmlOnMouseEnter,
34 onMouseLeave: htmlOnMouseLeave,
35 ...htmlProps
36 }
37 ) {
38 const onFocusRef = useLiveRef(htmlOnFocus);
39 const onBlurRef = useLiveRef(htmlOnBlur);
40 const onMouseEnterRef = useLiveRef(htmlOnMouseEnter);
41 const onMouseLeaveRef = useLiveRef(htmlOnMouseLeave);
42
43 const onFocus = React.useCallback(
44 (event: React.FocusEvent) => {
45 onFocusRef.current?.(event);
46 if (event.defaultPrevented) return;
47 options.show?.();
48 },
49 [options.show]
50 );
51
52 const onBlur = React.useCallback(
53 (event: React.FocusEvent) => {
54 onBlurRef.current?.(event);
55 if (event.defaultPrevented) return;
56 options.hide?.();
57 },
58 [options.hide]
59 );
60
61 const onMouseEnter = React.useCallback(
62 (event: React.MouseEvent) => {
63 onMouseEnterRef.current?.(event);
64 if (event.defaultPrevented) return;
65 options.show?.();
66 },
67 [options.show]
68 );
69
70 const onMouseLeave = React.useCallback(
71 (event: React.MouseEvent) => {
72 onMouseLeaveRef.current?.(event);
73 if (event.defaultPrevented) return;
74 options.hide?.();
75 },
76 [options.hide]
77 );
78
79 return {
80 ref: useForkRef(options.unstable_referenceRef, htmlRef),
81 tabIndex: 0,
82 onFocus,
83 onBlur,
84 onMouseEnter,
85 onMouseLeave,
86 "aria-describedby": options.baseId,
87 ...htmlProps,
88 };
89 },
90});
91
92export const TooltipReference = createComponent({
93 as: "div",
94 useHook: useTooltipReference,
95});