2
0

CheckboxList.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import React, { useEffect } from "react";
  2. import styled from "styled-components";
  3. type PropsType = {
  4. label?: string;
  5. options: { disabled?: boolean; value: any; label: string }[];
  6. selected: { value: any; label: string }[];
  7. setSelected: (x: { value: any; label: string }[]) => void;
  8. };
  9. const arraysEqual = (a: any, b: any) => {
  10. if (a === b) return true;
  11. if (a == null || b == null) return false;
  12. if (a.length !== b.length) return false;
  13. // If you don't care about the order of the elements inside
  14. // the array, you should sort both arrays here.
  15. // Please note that calling sort on an array will modify that array.
  16. // you might want to clone your array first.
  17. for (var i = 0; i < a.length; ++i) {
  18. if (a[i] !== b[i]) return false;
  19. }
  20. return true;
  21. };
  22. const CheckboxList = ({ label, options, selected, setSelected }: PropsType) => {
  23. let onSelectOption = (option: { value: any; label: string }) => {
  24. const tmp = [...selected];
  25. if (
  26. tmp.filter(
  27. (e) => e.value === option.value || arraysEqual(e.value, option.value)
  28. ).length === 0
  29. ) {
  30. setSelected([...tmp, option]);
  31. } else {
  32. tmp.forEach((x, i) => {
  33. if (x.value === option.value || arraysEqual(x.value, option.value)) {
  34. tmp.splice(i, 1);
  35. }
  36. });
  37. setSelected(tmp);
  38. }
  39. };
  40. return (
  41. <StyledCheckboxList>
  42. {label && <Label>{label}</Label>}
  43. {options.map((option: { value: any; label: string }, i: number) => {
  44. return (
  45. <CheckboxOption
  46. isLast={i === options.length - 1}
  47. onClick={() => onSelectOption(option)}
  48. key={i}
  49. >
  50. <Checkbox
  51. checked={
  52. selected.filter(
  53. (e) =>
  54. e.value === option.value ||
  55. arraysEqual(e.value, option.value)
  56. ).length > 0
  57. }
  58. >
  59. <i className="material-icons">done</i>
  60. </Checkbox>
  61. <Text>{option.label}</Text>
  62. </CheckboxOption>
  63. );
  64. })}
  65. </StyledCheckboxList>
  66. );
  67. };
  68. export default CheckboxList;
  69. const Text = styled.div`
  70. overflow: hidden;
  71. white-space: nowrap;
  72. text-overflow: ellipsis;
  73. word-break: anywhere;
  74. margin-right: 10px;
  75. `;
  76. const Checkbox = styled.div`
  77. width: 14px;
  78. height: 14px;
  79. min-width: 14px;
  80. border: 1px solid #ffffff55;
  81. margin: 1px 10px 0px 1px;
  82. border-radius: 3px;
  83. background: ${(props: { checked: boolean }) =>
  84. props.checked ? "#ffffff22" : "#ffffff11"};
  85. display: flex;
  86. align-items: center;
  87. justify-content: center;
  88. > i {
  89. font-size: 12px;
  90. padding-left: 0px;
  91. display: ${(props: { checked: boolean }) => (props.checked ? "" : "none")};
  92. }
  93. `;
  94. const CheckboxOption = styled.div<{ isLast: boolean }>`
  95. width: 100%;
  96. height: 35px;
  97. padding-left: 10px;
  98. display: flex;
  99. cursor: pointer;
  100. align-items: center;
  101. font-size: 13px;
  102. :hover {
  103. background: #ffffff18;
  104. }
  105. `;
  106. const Label = styled.div`
  107. color: #ffffff;
  108. margin-bottom: 10px;
  109. `;
  110. const StyledCheckboxList = styled.div`
  111. border-radius: 3px;
  112. padding: 0;
  113. `;