UNPKG

1.93 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 { ButtonOptions, ButtonHTMLProps, useButton } from "../Button/Button";
6import { unstable_FormStateReturn } from "./FormState";
7import { getFirstInvalidInput } from "./__utils/getFirstInvalidInput";
8import { FORM_SUBMIT_BUTTON_KEYS } from "./__keys";
9
10export type unstable_FormSubmitButtonOptions = ButtonOptions &
11 Pick<Partial<unstable_FormStateReturn<any>>, "submitting"> &
12 Pick<unstable_FormStateReturn<any>, "baseId" | "submit">;
13
14export type unstable_FormSubmitButtonHTMLProps = ButtonHTMLProps;
15
16export type unstable_FormSubmitButtonProps = unstable_FormSubmitButtonOptions &
17 unstable_FormSubmitButtonHTMLProps;
18
19export const unstable_useFormSubmitButton = createHook<
20 unstable_FormSubmitButtonOptions,
21 unstable_FormSubmitButtonHTMLProps
22>({
23 name: "FormSubmitButton",
24 compose: useButton,
25 keys: FORM_SUBMIT_BUTTON_KEYS,
26
27 useOptions(options) {
28 return { disabled: options.submitting, ...options };
29 },
30
31 useProps(options, { onClick: htmlOnClick, ...htmlProps }) {
32 const onClickRef = useLiveRef(htmlOnClick);
33
34 const onClick = React.useCallback(
35 (event: React.MouseEvent) => {
36 onClickRef.current?.(event);
37 if (event.defaultPrevented) return;
38
39 const element = event.currentTarget;
40
41 window.requestAnimationFrame(() => {
42 const input = getFirstInvalidInput(options.baseId, element);
43 input?.focus();
44 if (input && "select" in input) {
45 input.select();
46 }
47 });
48 },
49 [options.baseId]
50 );
51
52 return { type: "submit", onClick, ...htmlProps };
53 },
54});
55
56export const unstable_FormSubmitButton = createComponent({
57 as: "button",
58 memo: true,
59 useHook: unstable_useFormSubmitButton,
60});