Checkbox.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import React, { FC } from "react";
  2. import styled, { css, keyframes } from "styled-components";
  3. import { ifProp } from "styled-tools";
  4. import { Flex, BoxProps } from "reflexbox/styled-components";
  5. import { Span } from "./Text";
  6. interface InputProps {
  7. checked: boolean;
  8. id?: string;
  9. name: string;
  10. onChange: any;
  11. }
  12. const Input = styled(Flex).attrs({
  13. as: "input",
  14. type: "checkbox",
  15. m: 0,
  16. p: 0,
  17. width: 0,
  18. height: 0,
  19. opacity: 0
  20. })<InputProps>`
  21. position: relative;
  22. opacity: 0;
  23. `;
  24. const Box = styled(Flex).attrs({
  25. alignItems: "center",
  26. justifyContent: "center"
  27. })<{ checked: boolean }>`
  28. position: relative;
  29. transition: color 0.3s ease-out;
  30. border-radius: 4px;
  31. background-color: white;
  32. box-shadow: 0 2px 4px rgba(50, 50, 50, 0.2);
  33. cursor: pointer;
  34. input:focus + & {
  35. outline: 3px solid rgba(65, 164, 245, 0.5);
  36. }
  37. ${ifProp(
  38. "checked",
  39. css`
  40. box-shadow: 0 3px 5px rgba(50, 50, 50, 0.4);
  41. :after {
  42. content: "";
  43. position: absolute;
  44. width: 80%;
  45. height: 80%;
  46. display: block;
  47. border-radius: 2px;
  48. background-color: #9575cd;
  49. box-shadow: 0 2px 4px rgba(50, 50, 50, 0.2);
  50. cursor: pointer;
  51. animation: ${keyframes`
  52. from {
  53. opacity: 0;
  54. transform: scale(0, 0);
  55. }
  56. to {
  57. opacity: 1;
  58. transform: scale(1, 1);
  59. }
  60. `} 0.1s ease-in;
  61. }
  62. `
  63. )}
  64. `;
  65. interface Props extends InputProps, BoxProps {
  66. label: string;
  67. }
  68. const Checkbox: FC<Props> = ({
  69. checked,
  70. height,
  71. id,
  72. label,
  73. name,
  74. width,
  75. onChange,
  76. ...rest
  77. }) => {
  78. return (
  79. <Flex
  80. flex="0 0 auto"
  81. as="label"
  82. alignItems="center"
  83. style={{ cursor: "pointer" }}
  84. {...(rest as any)}
  85. >
  86. <Input onChange={onChange} name={name} id={id} checked={checked} />
  87. <Box checked={checked} width={width} height={height} />
  88. <Span ml={12} color="#555">
  89. {label}
  90. </Span>
  91. </Flex>
  92. );
  93. };
  94. Checkbox.defaultProps = {
  95. width: [18],
  96. height: [18]
  97. };
  98. export default Checkbox;