|
1 | 1 | import { SaleorThrobber } from "@dashboard/components/Throbber"; |
2 | 2 | import { buttonMessages } from "@dashboard/intl"; |
3 | 3 | import { Button, type ButtonProps, sprinkles } from "@saleor/macaw-ui-next"; |
| 4 | +import clsx from "clsx"; |
4 | 5 | import { Check } from "lucide-react"; |
5 | 6 | import { useEffect, useRef, useState } from "react"; |
6 | 7 | import { defineMessages, useIntl } from "react-intl"; |
7 | 8 |
|
| 9 | +import styles from "./ConfirmButton.module.css"; |
| 10 | + |
8 | 11 | const DEFAULT_NOTIFICATION_SHOW_TIME = 3000; |
9 | 12 |
|
10 | 13 | const messages = defineMessages({ |
@@ -38,13 +41,18 @@ export const ConfirmButton = ({ |
38 | 41 | disabled, |
39 | 42 | children, |
40 | 43 | variant, |
| 44 | + className, |
41 | 45 | ...props |
42 | 46 | }: ConfirmButtonProps) => { |
43 | 47 | const intl = useIntl(); |
44 | 48 | const [displayCompletedActionState, setDisplayCompletedActionState] = useState(false); |
45 | 49 | const timeout = useRef<number>(); |
| 50 | + const isLoading = transitionState === "loading"; |
46 | 51 | const isCompleted = noTransition ? transitionState !== "default" : displayCompletedActionState; |
| 52 | + const isSaveDisabled = !isCompleted && !!disabled; |
| 53 | + const isSuccess = transitionState === "success" && isCompleted; |
47 | 54 | const isError = transitionState === "error" && isCompleted; |
| 55 | + const isInteractionLocked = isLoading || isSuccess; |
48 | 56 | const defaultLabels: ConfirmButtonLabels = { |
49 | 57 | confirm: intl.formatMessage(buttonMessages.save), |
50 | 58 | error: intl.formatMessage(messages.tryAgain), |
@@ -122,9 +130,12 @@ export const ConfirmButton = ({ |
122 | 130 | return ( |
123 | 131 | <Button |
124 | 132 | {...props} |
| 133 | + className={clsx(className, isInteractionLocked && styles.noInteraction)} |
125 | 134 | variant={isError ? "error" : variant} |
126 | | - disabled={!isCompleted && disabled} |
127 | | - onClick={transitionState === "loading" ? undefined : onClick} |
| 135 | + disabled={isSaveDisabled} |
| 136 | + aria-busy={isLoading} |
| 137 | + tabIndex={isInteractionLocked ? -1 : undefined} |
| 138 | + onClick={isInteractionLocked ? undefined : onClick} |
128 | 139 | data-test-state={isCompleted ? transitionState : "default"} |
129 | 140 | > |
130 | 141 | {renderContent()} |
|
0 commit comments