Counter.jsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import React, { memo } from "react";
  2. import styled, { css } from "styled-components";
  3. const CounterPane = styled.div`
  4. ${({ color }) => css`
  5. background-color: ${color};
  6. padding: 0.2em;
  7. text-align: center;
  8. border-radius: 3px;
  9. box-shadow: 4px 4px 5px 0px rgb(0, 0, 0, 0.3);
  10. button {
  11. padding: 1rem;
  12. }
  13. input {
  14. width: 2em;
  15. }
  16. h3 {
  17. user-select: none;
  18. padding: 0;
  19. margin: 0;
  20. }
  21. div {
  22. display: flex;
  23. justify-content: space-between;
  24. flex-direction: row;
  25. align-items: center;
  26. }
  27. `}
  28. `;
  29. const Counter = ({
  30. value = 0,
  31. color = "#CCC",
  32. label = "",
  33. textColor = "#000",
  34. fontSize = "22",
  35. setState,
  36. }) => {
  37. const setValue = (e) => {
  38. let value = parseInt(e.target.value, 10);
  39. if (isNaN(value)) {
  40. value = 0;
  41. }
  42. setState((prevState) => ({
  43. ...prevState,
  44. value: value,
  45. }));
  46. };
  47. const increment = () => {
  48. setState((prevState) => ({
  49. ...prevState,
  50. value: (prevState.value || 0) + 1,
  51. }));
  52. };
  53. const decrement = () => {
  54. setState((prevState) => ({
  55. ...prevState,
  56. value: (prevState.value || 0) - 1,
  57. }));
  58. };
  59. return (
  60. <CounterPane color={color}>
  61. <h3>{label}</h3>
  62. <div>
  63. <button onClick={decrement} style={{ margin: "2px" }}>
  64. -
  65. </button>
  66. <label style={{ userSelect: "none" }}>
  67. <input
  68. style={{
  69. textColor,
  70. width: "2.5em",
  71. display: "block",
  72. textAlign: "center",
  73. border: "none",
  74. margin: "0.2em 0",
  75. padding: "0.2em 0",
  76. fontSize: fontSize + "px",
  77. userSelect: "none",
  78. }}
  79. onKeyUp={(e) => e.stopPropagation()}
  80. onKeyDown={(e) => e.stopPropagation()}
  81. value={value}
  82. onChange={setValue}
  83. />
  84. </label>
  85. <button onClick={increment} style={{ margin: "2px" }}>
  86. +
  87. </button>
  88. </div>
  89. </CounterPane>
  90. );
  91. };
  92. export default memo(Counter);