SingleLibraryItem.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import oc from "open-color";
  2. import { useEffect, useRef } from "react";
  3. import { t } from "../i18n";
  4. import { exportToSvg } from "../packages/utils";
  5. import { AppState, LibraryItem } from "../types";
  6. import { CloseIcon } from "./icons";
  7. import "./SingleLibraryItem.scss";
  8. import { ToolButton } from "./ToolButton";
  9. const SingleLibraryItem = ({
  10. libItem,
  11. appState,
  12. index,
  13. onChange,
  14. onRemove,
  15. }: {
  16. libItem: LibraryItem;
  17. appState: AppState;
  18. index: number;
  19. onChange: (val: string, index: number) => void;
  20. onRemove: (id: string) => void;
  21. }) => {
  22. const svgRef = useRef<HTMLDivElement | null>(null);
  23. const inputRef = useRef<HTMLInputElement | null>(null);
  24. useEffect(() => {
  25. const node = svgRef.current;
  26. if (!node) {
  27. return;
  28. }
  29. (async () => {
  30. const svg = await exportToSvg({
  31. elements: libItem.elements,
  32. appState: {
  33. ...appState,
  34. viewBackgroundColor: oc.white,
  35. exportBackground: true,
  36. },
  37. files: null,
  38. });
  39. node.innerHTML = svg.outerHTML;
  40. })();
  41. }, [libItem.elements, appState]);
  42. return (
  43. <div className="single-library-item">
  44. {libItem.status === "published" && (
  45. <span className="single-library-item-status">
  46. {t("labels.statusPublished")}
  47. </span>
  48. )}
  49. <div ref={svgRef} className="single-library-item__svg" />
  50. <ToolButton
  51. aria-label={t("buttons.remove")}
  52. type="button"
  53. icon={CloseIcon}
  54. className="single-library-item--remove"
  55. onClick={onRemove.bind(null, libItem.id)}
  56. title={t("buttons.remove")}
  57. />
  58. <div
  59. style={{
  60. display: "flex",
  61. margin: "0.8rem 0",
  62. width: "100%",
  63. fontSize: "14px",
  64. fontWeight: 500,
  65. flexDirection: "column",
  66. }}
  67. >
  68. <label
  69. style={{
  70. display: "flex",
  71. justifyContent: "space-between",
  72. flexDirection: "column",
  73. }}
  74. >
  75. <div style={{ padding: "0.5em 0" }}>
  76. <span style={{ fontWeight: 500, color: oc.gray[6] }}>
  77. {t("publishDialog.itemName")}
  78. </span>
  79. <span aria-hidden="true" className="required">
  80. *
  81. </span>
  82. </div>
  83. <input
  84. type="text"
  85. ref={inputRef}
  86. style={{ width: "80%", padding: "0.2rem" }}
  87. defaultValue={libItem.name}
  88. placeholder="Item name"
  89. onChange={(event) => {
  90. onChange(event.target.value, index);
  91. }}
  92. />
  93. </label>
  94. <span className="error">{libItem.error}</span>
  95. </div>
  96. </div>
  97. );
  98. };
  99. export default SingleLibraryItem;