index.tsx 1.9 KB

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