rule-item.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import {
  2. Box,
  3. IconButton,
  4. ListItem,
  5. ListItemText,
  6. alpha,
  7. styled,
  8. } from "@mui/material";
  9. import { DeleteForeverRounded, UndoRounded } from "@mui/icons-material";
  10. import { useSortable } from "@dnd-kit/sortable";
  11. import { CSS } from "@dnd-kit/utilities";
  12. interface Props {
  13. type: "prepend" | "original" | "delete" | "append";
  14. ruleRaw: string;
  15. onDelete: () => void;
  16. }
  17. export const RuleItem = (props: Props) => {
  18. let { type, ruleRaw, onDelete } = props;
  19. const sortable = type === "prepend" || type === "append";
  20. const rule = ruleRaw.replace(",no-resolve", "").split(",");
  21. const { attributes, listeners, setNodeRef, transform, transition } = sortable
  22. ? useSortable({ id: ruleRaw })
  23. : {
  24. attributes: {},
  25. listeners: {},
  26. setNodeRef: null,
  27. transform: null,
  28. transition: null,
  29. };
  30. return (
  31. <ListItem
  32. dense
  33. sx={({ palette }) => ({
  34. background:
  35. type === "original"
  36. ? palette.mode === "dark"
  37. ? alpha(palette.background.paper, 0.3)
  38. : alpha(palette.grey[400], 0.3)
  39. : type === "delete"
  40. ? alpha(palette.error.main, 0.3)
  41. : alpha(palette.success.main, 0.3),
  42. height: "100%",
  43. margin: "8px 0",
  44. borderRadius: "8px",
  45. transform: CSS.Transform.toString(transform),
  46. transition,
  47. })}
  48. >
  49. <ListItemText
  50. {...attributes}
  51. {...listeners}
  52. ref={setNodeRef}
  53. sx={{ cursor: sortable ? "move" : "" }}
  54. primary={
  55. <StyledPrimary
  56. sx={{ textDecoration: type === "delete" ? "line-through" : "" }}
  57. >
  58. {rule.length === 3 ? rule[1] : "-"}
  59. </StyledPrimary>
  60. }
  61. secondary={
  62. <ListItemTextChild
  63. sx={{
  64. width: "62%",
  65. overflow: "hidden",
  66. display: "flex",
  67. justifyContent: "space-between",
  68. pt: "2px",
  69. }}
  70. >
  71. <Box sx={{ marginTop: "2px" }}>
  72. <StyledTypeBox>{rule[0]}</StyledTypeBox>
  73. </Box>
  74. <StyledSubtitle sx={{ color: "text.secondary" }}>
  75. {rule.length === 3 ? rule[2] : rule[1]}
  76. </StyledSubtitle>
  77. </ListItemTextChild>
  78. }
  79. secondaryTypographyProps={{
  80. sx: {
  81. display: "flex",
  82. alignItems: "center",
  83. color: "#ccc",
  84. },
  85. }}
  86. />
  87. <IconButton onClick={onDelete}>
  88. {type === "delete" ? <UndoRounded /> : <DeleteForeverRounded />}
  89. </IconButton>
  90. </ListItem>
  91. );
  92. };
  93. const StyledPrimary = styled("span")`
  94. font-size: 15px;
  95. font-weight: 700;
  96. line-height: 1.5;
  97. overflow: hidden;
  98. text-overflow: ellipsis;
  99. white-space: nowrap;
  100. `;
  101. const StyledSubtitle = styled("span")`
  102. font-size: 13px;
  103. overflow: hidden;
  104. color: text.secondary;
  105. text-overflow: ellipsis;
  106. white-space: nowrap;
  107. `;
  108. const ListItemTextChild = styled("span")`
  109. display: block;
  110. `;
  111. const StyledTypeBox = styled(ListItemTextChild)(({ theme }) => ({
  112. display: "inline-block",
  113. border: "1px solid #ccc",
  114. borderColor: alpha(theme.palette.primary.main, 0.5),
  115. color: alpha(theme.palette.primary.main, 0.8),
  116. borderRadius: 4,
  117. fontSize: 10,
  118. padding: "0 4px",
  119. lineHeight: 1.5,
  120. marginRight: "8px",
  121. }));