MaterialItem.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import Thumbnail from "@/components/Thumbnail";
  2. import { css, cx } from "@linaria/core";
  3. import { IconDelete } from "@queenjs/icons";
  4. import { View } from "@queenjs/ui";
  5. import { defineUI } from "queenjs";
  6. import { any, string } from "vue-types";
  7. const renderStatus = {
  8. succ: "",
  9. error: "渲染失败",
  10. default: "渲染中…",
  11. };
  12. export default defineUI({
  13. props: {
  14. record: any(),
  15. use: string<"show" | "select" | "task">(),
  16. },
  17. emits: ["delete", "download", "use", "preview"],
  18. setup(props, { emit }) {
  19. return () => {
  20. const { record, use } = props;
  21. const thumbnailUrl =
  22. record?.thumbnail || record?.thumbnailUrl || record.file?.url;
  23. return (
  24. <div class={cx(itemStyles, "relative")}>
  25. <View ratio={1.4} class="overflow-hidden card rounded-2px">
  26. <Thumbnail
  27. src={thumbnailUrl}
  28. class="h-1/1 w-1/1"
  29. objectContain={record.fileType == "image" ? true : false}
  30. />
  31. {use == "task" && record.status !== "succ" && (
  32. <div class="waiting absolute inset-0 z-2 flex items-center justify-center text-white">
  33. {(renderStatus as any)[record.status || "default"]}
  34. </div>
  35. )}
  36. {use !== "task" && (
  37. <div class="absolute inset-0 flex items-center justify-center z-2 opacity-0 hover:opacity-100 transition-all text-white">
  38. {use == "show" && (
  39. <IconDelete
  40. class="icon_del absolute right-5px top-5px p-3px rounded-2px text-14px cursor-pointer"
  41. onClick={() => emit("delete")}
  42. />
  43. )}
  44. <div
  45. class="rounded-1/2 text-center w-56px leading-56px cursor-pointer orange"
  46. onClick={() => emit("preview")}
  47. >
  48. 预览
  49. </div>
  50. {use == "show" && (
  51. <div
  52. class="btn_circle rounded-1/2 text-center w-56px leading-56px cursor-pointer"
  53. onClick={() => emit("download")}
  54. >
  55. 下载
  56. </div>
  57. )}
  58. {use == "select" && (
  59. <div
  60. class="btn_circle rounded-1/2 text-center w-56px leading-56px cursor-pointer"
  61. onClick={(e) => {
  62. e.stopPropagation();
  63. emit("use");
  64. }}
  65. >
  66. 使用
  67. </div>
  68. )}
  69. </div>
  70. )}
  71. </View>
  72. {record.name && (
  73. <div class="py-8px px-10px" style={{ backgroundColor: "#262626" }}>
  74. {record.name}
  75. </div>
  76. )}
  77. </div>
  78. );
  79. };
  80. },
  81. });
  82. const itemStyles = css`
  83. .card {
  84. background-color: rgba(255, 255, 255, 0.1);
  85. }
  86. .orange {
  87. background-color: rgba(232, 139, 0, 0.5);
  88. &:hover {
  89. background-color: rgba(232, 139, 0, 0.7);
  90. }
  91. }
  92. .btn_circle {
  93. background-color: rgba(0, 0, 0, 0.7);
  94. &:hover {
  95. background-color: rgba(0, 0, 0, 0.8);
  96. }
  97. &:not(:nth-of-type(1)) {
  98. margin-left: 10px;
  99. }
  100. }
  101. .icon_del {
  102. background-color: rgba(0, 0, 0, 0.5);
  103. &:hover {
  104. background-color: rgba(0, 0, 0, 0.6);
  105. }
  106. }
  107. .waiting {
  108. background-color: rgba(0, 0, 0, 0.3);
  109. }
  110. `;