Quellcode durchsuchen

refactor: inline `SingleLibraryItem` into `PublishLibrary` (#6462

refactor: inline `SingleLibraryItem` into `PublishLibrary` to reduce api surface area
David Luzar vor 2 Jahren
Ursprung
Commit
e31230f78c

+ 76 - 0
src/components/PublishLibrary.scss

@@ -93,4 +93,80 @@
       display: block;
     }
   }
+
+  .single-library-item {
+    position: relative;
+
+    &-status {
+      position: absolute;
+      top: 0.3rem;
+      left: 0.3rem;
+      font-size: 0.7rem;
+      color: $oc-red-7;
+      background: rgba(255, 255, 255, 0.9);
+      padding: 0.1rem 0.2rem;
+      border-radius: 0.2rem;
+    }
+
+    &__svg {
+      background-color: $oc-white;
+      padding: 0.3rem;
+      width: 7.5rem;
+      height: 7.5rem;
+      border: 1px solid var(--button-gray-2);
+      svg {
+        width: 100%;
+        height: 100%;
+      }
+    }
+
+    .ToolIcon__icon {
+      background-color: $oc-white;
+      width: auto;
+      height: auto;
+      margin: 0 0.5rem;
+    }
+    .ToolIcon,
+    .ToolIcon_type_button:hover {
+      background-color: white;
+    }
+    .required,
+    .error {
+      color: $oc-red-8;
+      font-weight: bold;
+      font-size: 1rem;
+      margin: 0.2rem;
+    }
+    .error {
+      font-weight: 500;
+      margin: 0;
+      padding: 0.3em 0;
+    }
+
+    &--remove {
+      position: absolute;
+      top: 0.2rem;
+      right: 1rem;
+
+      .ToolIcon__icon {
+        margin: 0;
+      }
+      .ToolIcon__icon {
+        background-color: $oc-red-6;
+        &:hover {
+          background-color: $oc-red-7;
+        }
+        &:active {
+          background-color: $oc-red-8;
+        }
+      }
+      svg {
+        color: $oc-white;
+        padding: 0.26rem;
+        border-radius: 0.3em;
+        width: 1rem;
+        height: 1rem;
+      }
+    }
+  }
 }

+ 99 - 5
src/components/PublishLibrary.tsx

@@ -1,11 +1,11 @@
-import { ReactNode, useCallback, useEffect, useState } from "react";
+import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
 import OpenColor from "open-color";
 
 import { Dialog } from "./Dialog";
 import { t } from "../i18n";
 
 import { AppState, LibraryItems, LibraryItem } from "../types";
-import { exportToCanvas } from "../packages/utils";
+import { exportToCanvas, exportToSvg } from "../packages/utils";
 import {
   EXPORT_DATA_TYPES,
   EXPORT_SOURCE,
@@ -13,12 +13,13 @@ import {
   VERSIONS,
 } from "../constants";
 import { ExportedLibraryData } from "../data/types";
-
-import "./PublishLibrary.scss";
-import SingleLibraryItem from "./SingleLibraryItem";
 import { canvasToBlob, resizeImageFile } from "../data/blob";
 import { chunk } from "../utils";
 import DialogActionButton from "./DialogActionButton";
+import { CloseIcon } from "./icons";
+import { ToolButton } from "./ToolButton";
+
+import "./PublishLibrary.scss";
 
 interface PublishLibraryDataParams {
   authorName: string;
@@ -126,6 +127,99 @@ const generatePreviewImage = async (libraryItems: LibraryItems) => {
   );
 };
 
+const SingleLibraryItem = ({
+  libItem,
+  appState,
+  index,
+  onChange,
+  onRemove,
+}: {
+  libItem: LibraryItem;
+  appState: AppState;
+  index: number;
+  onChange: (val: string, index: number) => void;
+  onRemove: (id: string) => void;
+}) => {
+  const svgRef = useRef<HTMLDivElement | null>(null);
+  const inputRef = useRef<HTMLInputElement | null>(null);
+
+  useEffect(() => {
+    const node = svgRef.current;
+    if (!node) {
+      return;
+    }
+    (async () => {
+      const svg = await exportToSvg({
+        elements: libItem.elements,
+        appState: {
+          ...appState,
+          viewBackgroundColor: OpenColor.white,
+          exportBackground: true,
+        },
+        files: null,
+      });
+      node.innerHTML = svg.outerHTML;
+    })();
+  }, [libItem.elements, appState]);
+
+  return (
+    <div className="single-library-item">
+      {libItem.status === "published" && (
+        <span className="single-library-item-status">
+          {t("labels.statusPublished")}
+        </span>
+      )}
+      <div ref={svgRef} className="single-library-item__svg" />
+      <ToolButton
+        aria-label={t("buttons.remove")}
+        type="button"
+        icon={CloseIcon}
+        className="single-library-item--remove"
+        onClick={onRemove.bind(null, libItem.id)}
+        title={t("buttons.remove")}
+      />
+      <div
+        style={{
+          display: "flex",
+          margin: "0.8rem 0",
+          width: "100%",
+          fontSize: "14px",
+          fontWeight: 500,
+          flexDirection: "column",
+        }}
+      >
+        <label
+          style={{
+            display: "flex",
+            justifyContent: "space-between",
+            flexDirection: "column",
+          }}
+        >
+          <div style={{ padding: "0.5em 0" }}>
+            <span style={{ fontWeight: 500, color: OpenColor.gray[6] }}>
+              {t("publishDialog.itemName")}
+            </span>
+            <span aria-hidden="true" className="required">
+              *
+            </span>
+          </div>
+          <input
+            type="text"
+            ref={inputRef}
+            style={{ width: "80%", padding: "0.2rem" }}
+            defaultValue={libItem.name}
+            placeholder="Item name"
+            onChange={(event) => {
+              onChange(event.target.value, index);
+            }}
+          />
+        </label>
+        <span className="error">{libItem.error}</span>
+      </div>
+    </div>
+  );
+};
+
 const PublishLibrary = ({
   onClose,
   libraryItems,

+ 0 - 79
src/components/SingleLibraryItem.scss

@@ -1,79 +0,0 @@
-@import "../css/variables.module";
-
-.excalidraw {
-  .single-library-item {
-    position: relative;
-
-    &-status {
-      position: absolute;
-      top: 0.3rem;
-      left: 0.3rem;
-      font-size: 0.7rem;
-      color: $oc-red-7;
-      background: rgba(255, 255, 255, 0.9);
-      padding: 0.1rem 0.2rem;
-      border-radius: 0.2rem;
-    }
-
-    &__svg {
-      background-color: $oc-white;
-      padding: 0.3rem;
-      width: 7.5rem;
-      height: 7.5rem;
-      border: 1px solid var(--button-gray-2);
-      svg {
-        width: 100%;
-        height: 100%;
-      }
-    }
-
-    .ToolIcon__icon {
-      background-color: $oc-white;
-      width: auto;
-      height: auto;
-      margin: 0 0.5rem;
-    }
-    .ToolIcon,
-    .ToolIcon_type_button:hover {
-      background-color: white;
-    }
-    .required,
-    .error {
-      color: $oc-red-8;
-      font-weight: bold;
-      font-size: 1rem;
-      margin: 0.2rem;
-    }
-    .error {
-      font-weight: 500;
-      margin: 0;
-      padding: 0.3em 0;
-    }
-
-    &--remove {
-      position: absolute;
-      top: 0.2rem;
-      right: 1rem;
-
-      .ToolIcon__icon {
-        margin: 0;
-      }
-      .ToolIcon__icon {
-        background-color: $oc-red-6;
-        &:hover {
-          background-color: $oc-red-7;
-        }
-        &:active {
-          background-color: $oc-red-8;
-        }
-      }
-      svg {
-        color: $oc-white;
-        padding: 0.26rem;
-        border-radius: 0.3em;
-        width: 1rem;
-        height: 1rem;
-      }
-    }
-  }
-}

+ 0 - 104
src/components/SingleLibraryItem.tsx

@@ -1,104 +0,0 @@
-import oc from "open-color";
-import { useEffect, useRef } from "react";
-import { t } from "../i18n";
-import { exportToSvg } from "../packages/utils";
-import { AppState, LibraryItem } from "../types";
-import { CloseIcon } from "./icons";
-
-import "./SingleLibraryItem.scss";
-import { ToolButton } from "./ToolButton";
-
-const SingleLibraryItem = ({
-  libItem,
-  appState,
-  index,
-  onChange,
-  onRemove,
-}: {
-  libItem: LibraryItem;
-  appState: AppState;
-  index: number;
-  onChange: (val: string, index: number) => void;
-  onRemove: (id: string) => void;
-}) => {
-  const svgRef = useRef<HTMLDivElement | null>(null);
-  const inputRef = useRef<HTMLInputElement | null>(null);
-
-  useEffect(() => {
-    const node = svgRef.current;
-    if (!node) {
-      return;
-    }
-    (async () => {
-      const svg = await exportToSvg({
-        elements: libItem.elements,
-        appState: {
-          ...appState,
-          viewBackgroundColor: oc.white,
-          exportBackground: true,
-        },
-        files: null,
-      });
-      node.innerHTML = svg.outerHTML;
-    })();
-  }, [libItem.elements, appState]);
-
-  return (
-    <div className="single-library-item">
-      {libItem.status === "published" && (
-        <span className="single-library-item-status">
-          {t("labels.statusPublished")}
-        </span>
-      )}
-      <div ref={svgRef} className="single-library-item__svg" />
-      <ToolButton
-        aria-label={t("buttons.remove")}
-        type="button"
-        icon={CloseIcon}
-        className="single-library-item--remove"
-        onClick={onRemove.bind(null, libItem.id)}
-        title={t("buttons.remove")}
-      />
-      <div
-        style={{
-          display: "flex",
-          margin: "0.8rem 0",
-          width: "100%",
-          fontSize: "14px",
-          fontWeight: 500,
-          flexDirection: "column",
-        }}
-      >
-        <label
-          style={{
-            display: "flex",
-            justifyContent: "space-between",
-            flexDirection: "column",
-          }}
-        >
-          <div style={{ padding: "0.5em 0" }}>
-            <span style={{ fontWeight: 500, color: oc.gray[6] }}>
-              {t("publishDialog.itemName")}
-            </span>
-            <span aria-hidden="true" className="required">
-              *
-            </span>
-          </div>
-          <input
-            type="text"
-            ref={inputRef}
-            style={{ width: "80%", padding: "0.2rem" }}
-            defaultValue={libItem.name}
-            placeholder="Item name"
-            onChange={(event) => {
-              onChange(event.target.value, index);
-            }}
-          />
-        </label>
-        <span className="error">{libItem.error}</span>
-      </div>
-    </div>
-  );
-};
-
-export default SingleLibraryItem;