interface: fix stateless async clickables

This commit is contained in:
Liam Fitzgerald 2020-10-07 11:09:19 +10:00
parent 5f3e96566d
commit 7a90f04a06
4 changed files with 17 additions and 45 deletions

View File

@ -64,7 +64,6 @@ export default class LaunchApp extends React.Component {
<Tile
bg={sigilColor}
to="/~profile"
borderRadius="3"
>
<Center height="100%">
<Sigil ship={`~${window.ship}`} size={80} color={sigilColor} />

View File

@ -30,6 +30,7 @@ textarea, select, input, button { outline: none; }
button {
background-color: transparent;
cursor: pointer;
}

View File

@ -1,4 +1,5 @@
import React, { ReactNode, useState, useEffect, useCallback } from "react";
import { useStatelessAsyncClickable } from '~/logic/lib/useStatelessAsyncClickable';
import { Button, LoadingSpinner, Action } from "@tlon/indigo-react";
@ -6,35 +7,20 @@ import { useFormikContext } from "formik";
interface AsyncActionProps {
children: ReactNode;
name: string;
onClick: (e: React.MouseEvent) => Promise<void>;
}
type ButtonState = "waiting" | "error" | "loading" | "success";
export function StatelessAsyncAction({
loadingText,
children,
onClick,
name = '',
...rest
}: AsyncActionProps & Parameters<typeof Action>[0]) {
const [state, setState] = useState<ButtonState>("waiting");
const handleClick = useCallback(
async (e: React.MouseEvent) => {
try {
setState("loading");
await onClick(e);
setState("success");
} catch (e) {
console.error(e);
setState("error");
} finally {
setTimeout(() => {
setState("waiting");
}, 3000);
}
},
[onClick, setState]
);
const {
onClick: handleClick,
buttonState: state,
} = useStatelessAsyncClickable(onClick, name);
return (
<Action onClick={handleClick} {...rest}>
@ -42,7 +28,7 @@ export function StatelessAsyncAction({
"Error"
) : state === "loading" ? (
<LoadingSpinner
foreground={rest.primary ? "white" : "black"}
foreground={rest.destructive ? "red" : "black"}
background="transparent"
/>
) : state === "success" ? (

View File

@ -1,40 +1,26 @@
import React, { ReactNode, useState, useEffect, useCallback } from "react";
import { Button, LoadingSpinner } from "@tlon/indigo-react";
import { useFormikContext } from "formik";
import { useStatelessAsyncClickable } from "~/logic/lib/useStatelessAsyncClickable";
interface AsyncButtonProps {
children: ReactNode;
name: string;
onClick: (e: React.MouseEvent) => Promise<void>;
}
type ButtonState = "waiting" | "error" | "loading" | "success";
export function StatelessAsyncButton({
loadingText,
children,
onClick,
name = "",
...rest
}: AsyncButtonProps & Parameters<typeof Button>[0]) {
const [state, setState] = useState<ButtonState>("waiting");
const handleClick = useCallback(
async (e: React.MouseEvent) => {
try {
setState("loading");
await onClick(e);
setState("success");
} catch (e) {
console.error(e);
setState("error");
} finally {
setTimeout(() => {
setState("waiting");
}, 3000);
}
},
[onClick, setState]
);
const {
onClick: handleClick,
buttonState: state,
} = useStatelessAsyncClickable(onClick, name);
return (
<Button onClick={handleClick} {...rest}>