You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.1 KiB

  1. "use client";
  2. import { Route } from "@/routers/types";
  3. import Link from "next/link";
  4. import React, { ButtonHTMLAttributes, FC } from "react";
  5. export interface ButtonProps {
  6. className?: string;
  7. translate?: string;
  8. sizeClass?: string;
  9. fontSize?: string;
  10. //
  11. loading?: boolean;
  12. disabled?: boolean;
  13. type?: ButtonHTMLAttributes<HTMLButtonElement>["type"];
  14. href?: Route<string>;
  15. targetBlank?: boolean;
  16. onClick?: () => void;
  17. children?: React.ReactNode;
  18. }
  19. const Button: FC<ButtonProps> = ({
  20. className = "text-neutral-700 dark:text-neutral-200",
  21. translate = "",
  22. sizeClass = "px-4 py-3 sm:px-6",
  23. fontSize = "text-sm sm:text-base font-medium",
  24. disabled = false,
  25. href,
  26. children,
  27. targetBlank,
  28. type,
  29. loading,
  30. onClick = () => {},
  31. }) => {
  32. const CLASSES = `nc-Button relative h-auto inline-flex items-center justify-center rounded-full transition-colors ${fontSize} ${sizeClass} ${translate} ${className} `;
  33. const _renderLoading = () => {
  34. return (
  35. <svg
  36. className="animate-spin -ml-1 mr-3 h-5 w-5"
  37. xmlns="http://www.w3.org/2000/svg"
  38. fill="none"
  39. viewBox="0 0 24 24"
  40. >
  41. <circle
  42. className="opacity-25"
  43. cx="12"
  44. cy="12"
  45. r="10"
  46. stroke="currentColor"
  47. strokeWidth="3"
  48. ></circle>
  49. <path
  50. className="opacity-75"
  51. fill="currentColor"
  52. d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
  53. ></path>
  54. </svg>
  55. );
  56. };
  57. if (!!href) {
  58. return (
  59. <Link
  60. href={href}
  61. target={targetBlank ? "_blank" : undefined}
  62. className={`${CLASSES} `}
  63. onClick={onClick}
  64. rel={targetBlank ? "noopener noreferrer" : undefined}
  65. >
  66. {children || `This is Link`}
  67. </Link>
  68. );
  69. }
  70. return (
  71. <button
  72. disabled={disabled || loading}
  73. className={`${CLASSES}`}
  74. onClick={onClick}
  75. type={type}
  76. >
  77. {loading && _renderLoading()}
  78. {children || `This is Button`}
  79. </button>
  80. );
  81. };
  82. export default Button;