UNPKG

1.6 kBPlain TextView Raw
1import * as React from "react";
2import { createComponent } from "reakit-system/createComponent";
3import { createHook } from "reakit-system/createHook";
4import { useLiveRef } from "reakit-utils/useLiveRef";
5import { useButton, ButtonOptions, ButtonHTMLProps } from "../Button/Button";
6import { DisclosureStateReturn } from "./DisclosureState";
7import { DISCLOSURE_KEYS } from "./__keys";
8
9export type DisclosureOptions = ButtonOptions &
10 Pick<Partial<DisclosureStateReturn>, "visible"> &
11 Pick<DisclosureStateReturn, "toggle" | "baseId">;
12
13export type DisclosureHTMLProps = ButtonHTMLProps;
14
15export type DisclosureProps = DisclosureOptions & DisclosureHTMLProps;
16
17export const useDisclosure = createHook<DisclosureOptions, DisclosureHTMLProps>(
18 {
19 name: "Disclosure",
20 compose: useButton,
21 keys: DISCLOSURE_KEYS,
22
23 useProps(
24 options,
25 { onClick: htmlOnClick, "aria-controls": ariaControls, ...htmlProps }
26 ) {
27 const onClickRef = useLiveRef(htmlOnClick);
28
29 const controls = ariaControls
30 ? `${ariaControls} ${options.baseId}`
31 : options.baseId;
32
33 const onClick = React.useCallback(
34 (event: React.MouseEvent) => {
35 onClickRef.current?.(event);
36 if (event.defaultPrevented) return;
37 options.toggle?.();
38 },
39 [options.toggle]
40 );
41
42 return {
43 "aria-expanded": !!options.visible,
44 "aria-controls": controls,
45 onClick,
46 ...htmlProps,
47 };
48 },
49 }
50);
51
52export const Disclosure = createComponent({
53 as: "button",
54 memo: true,
55 useHook: useDisclosure,
56});