github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/public/src/components/DynamicButton.tsx (about)

     1  import React, { useState } from "react"
     2  import { Color } from "../Helpers"
     3  import { ButtonType } from "./admin/Button"
     4  
     5  
     6  export type DynamicButtonProps = {
     7      text: string,
     8      onClick: () => Promise<unknown>,
     9      color: Color,
    10      type: ButtonType,
    11      className?: string,
    12  }
    13  
    14  /** DynamicButton will display a spinner while the onClick function is running.
    15   *  This is useful for buttons that perform an action that takes a while to complete.
    16   *  The button will be disabled while the onClick function is running.
    17   */
    18  const DynamicButton = ({ text, onClick, color, type, className }: DynamicButtonProps) => {
    19      const [isPending, setIsPending] = useState<boolean>(false)
    20  
    21      const handleClick = async () => {
    22          if (isPending) {
    23              // Disable double clicks
    24              return
    25          }
    26          setIsPending(true)
    27          await onClick()
    28          setIsPending(false)
    29      }
    30  
    31      const buttonClass = `${type}-${isPending ? Color.GRAY : color} ${className ?? ""}`
    32      const content = isPending
    33          ? <span className="spinner-border spinner-border-sm" role="status" aria-hidden="true" />
    34          : text
    35  
    36      return (
    37          <button type="button" disabled={isPending} className={buttonClass} onClick={handleClick}>
    38              {content}
    39          </button>
    40      )
    41  }
    42  
    43  export default DynamicButton