index.tsx 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import React from "react";
  2. import styled, { DefaultTheme } from "styled-components";
  3. enum ButtonType {
  4. PRIMARY = "PRIMARY",
  5. SECONDARY = "BLURPLE",
  6. TERTIARY = "PURPLE",
  7. DANGER = "DANGER",
  8. SUCCESS = "SEAGREEN",
  9. WARNING = "ORANGE",
  10. }
  11. interface ButtonProps {
  12. status?: keyof typeof ButtonType;
  13. block?: boolean;
  14. }
  15. type ConditionalProps =
  16. | ({
  17. link?: boolean;
  18. } & React.ComponentPropsWithoutRef<"a">)
  19. | ({
  20. link?: never;
  21. } & React.ComponentPropsWithoutRef<"button">);
  22. function getButtonStatus(status: keyof typeof ButtonType, theme: DefaultTheme) {
  23. return theme[ButtonType[status]];
  24. }
  25. const StyledButton = styled.button<{
  26. status: keyof typeof ButtonType;
  27. block: boolean;
  28. }>`
  29. display: inline-flex;
  30. align-items: center;
  31. background: ${({ status, theme }) => getButtonStatus(status, theme)};
  32. color: #ffffff;
  33. padding: 8px 16px;
  34. min-width: 70px;
  35. min-height: 32px;
  36. border-radius: 3px;
  37. font-size: 14px;
  38. font-weight: 500;
  39. width: ${({ block }) => (block ? "100%" : "fit-content")};
  40. height: 40px;
  41. background-image: none;
  42. :disabled {
  43. cursor: not-allowed;
  44. opacity: 0.5;
  45. }
  46. div {
  47. white-space: normal;
  48. margin: 0 auto;
  49. text-overflow: ellipsis;
  50. overflow: hidden;
  51. }
  52. &:hover {
  53. background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
  54. }
  55. @media only screen and (max-width: 768px) {
  56. font-size: 14px;
  57. }
  58. `;
  59. const StyledButtonContent = styled.div`
  60. display: flex;
  61. justify-content: center;
  62. align-items: center;
  63. gap: 8px;
  64. white-space: nowrap;
  65. text-overflow: ellipsis;
  66. font-weight: 600;
  67. `;
  68. export const Button: React.FC<ButtonProps & ConditionalProps> = ({
  69. children,
  70. status,
  71. block = false,
  72. link = false,
  73. ...props
  74. }) => {
  75. return (
  76. <StyledButton
  77. as={link ? "a" : "button"}
  78. type="button"
  79. status={status ?? "PRIMARY"}
  80. block={block}
  81. {...props}
  82. >
  83. <StyledButtonContent>{children}</StyledButtonContent>
  84. </StyledButton>
  85. );
  86. };