UNPKG

1.7 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 { isButton } from "reakit-utils/isButton";
6import { warning } from "reakit-warning";
7import {
8 ClickableOptions,
9 ClickableHTMLProps,
10 useClickable,
11} from "../Clickable/Clickable";
12import { BUTTON_KEYS } from "./__keys";
13
14export const useButton = createHook<ButtonOptions, ButtonHTMLProps>({
15 name: "Button",
16 compose: useClickable,
17 keys: BUTTON_KEYS,
18
19 useProps(_, { ref: htmlRef, ...htmlProps }) {
20 const ref = React.useRef<HTMLElement>(null);
21 const [role, setRole] = React.useState<"button" | undefined>(undefined);
22 const [type, setType] = React.useState<"button" | undefined>("button");
23
24 React.useEffect(() => {
25 const element = ref.current;
26 if (!element) {
27 warning(
28 true,
29 "Can't determine whether the element is a native button because `ref` wasn't passed to the component",
30 "See https://reakit.io/docs/button"
31 );
32 return;
33 }
34 if (!isButton(element)) {
35 if (element.tagName !== "A") {
36 setRole("button");
37 }
38 setType(undefined);
39 }
40 }, []);
41
42 return {
43 ref: useForkRef(ref, htmlRef),
44 role,
45 type,
46 ...htmlProps,
47 };
48 },
49});
50
51export const Button = createComponent({
52 as: "button",
53 memo: true,
54 useHook: useButton,
55});
56
57export type ButtonOptions = ClickableOptions;
58
59export type ButtonHTMLProps = ClickableHTMLProps &
60 React.ButtonHTMLAttributes<any>;
61
62export type ButtonProps = ButtonOptions & ButtonHTMLProps;