diff --git a/src/components/EditorCanvas/Table.jsx b/src/components/EditorCanvas/Table.jsx
deleted file mode 100644
index 1e656f9a..00000000
--- a/src/components/EditorCanvas/Table.jsx
+++ /dev/null
@@ -1,376 +0,0 @@
-import { useState } from "react";
-import {
-  Tab,
-  ObjectType,
-  tableFieldHeight,
-  tableHeaderHeight,
-  tableColorStripHeight,
-} from "../../data/constants";
-import {
-  IconEdit,
-  IconMore,
-  IconMinus,
-  IconDeleteStroked,
-  IconKeyStroked,
-} from "@douyinfe/semi-icons";
-import { Popover, Tag, Button, SideSheet } from "@douyinfe/semi-ui";
-import { useLayout, useSettings, useDiagram, useSelect } from "../../hooks";
-import TableInfo from "../EditorSidePanel/TablesTab/TableInfo";
-import { useTranslation } from "react-i18next";
-import { dbToTypes } from "../../data/datatypes";
-import { isRtl } from "../../i18n/utils/rtl";
-import i18n from "../../i18n/i18n";
-
-export default function Table(props) {
-  const [hoveredField, setHoveredField] = useState(-1);
-  const { database } = useDiagram();
-  const {
-    tableData,
-    onPointerDown,
-    setHoveredTable,
-    handleGripField,
-    setLinkingLine,
-  } = props;
-  const { layout } = useLayout();
-  const { deleteTable, deleteField } = useDiagram();
-  const { settings } = useSettings();
-  const { t } = useTranslation();
-  const { selectedElement, setSelectedElement } = useSelect();
-
-  const height =
-    tableData.fields.length * tableFieldHeight + tableHeaderHeight + 7;
-  const openEditor = () => {
-    if (!layout.sidebar) {
-      setSelectedElement((prev) => ({
-        ...prev,
-        element: ObjectType.TABLE,
-        id: tableData.id,
-        open: true,
-      }));
-    } else {
-      setSelectedElement((prev) => ({
-        ...prev,
-        currentTab: Tab.TABLES,
-        element: ObjectType.TABLE,
-        id: tableData.id,
-        open: true,
-      }));
-      if (selectedElement.currentTab !== Tab.TABLES) return;
-      document
-        .getElementById(`scroll_table_${tableData.id}`)
-        .scrollIntoView({ behavior: "smooth" });
-    }
-  };
-
-  return (
-    <>
-      <foreignObject
-        key={tableData.id}
-        x={tableData.x}
-        y={tableData.y}
-        width={settings.tableWidth}
-        height={height}
-        className="group drop-shadow-lg rounded-md cursor-move"
-        onPointerDown={onPointerDown}
-      >
-        <div
-          onDoubleClick={openEditor}
-          className={`border-2 hover:border-dashed hover:border-blue-500
-               select-none rounded-lg w-full ${
-                 settings.mode === "light"
-                   ? "bg-zinc-100 text-zinc-800"
-                   : "bg-zinc-800 text-zinc-200"
-               } ${
-                 selectedElement.id === tableData.id &&
-                 selectedElement.element === ObjectType.TABLE
-                   ? "border-solid border-blue-500"
-                   : "border-zinc-500"
-               }`}
-          style={{ direction: "ltr" }}
-        >
-          <div
-            className="h-[10px] w-full rounded-t-md"
-            style={{ backgroundColor: tableData.color }}
-          />
-          <div
-            className={`overflow-hidden font-bold h-[40px] flex justify-between items-center border-b border-gray-400 ${
-              settings.mode === "light" ? "bg-zinc-200" : "bg-zinc-900"
-            }`}
-          >
-            <div className=" px-3 overflow-hidden text-ellipsis whitespace-nowrap">
-              {tableData.name}
-            </div>
-            <div className="hidden group-hover:block">
-              <div className="flex justify-end items-center mx-2">
-                <Button
-                  icon={<IconEdit />}
-                  size="small"
-                  theme="solid"
-                  style={{
-                    backgroundColor: "#2f68adb3",
-                    marginRight: "6px",
-                  }}
-                  onClick={openEditor}
-                />
-                <Popover
-                  key={tableData.key}
-                  content={
-                    <div className="popover-theme">
-                      <div className="mb-2">
-                        <strong>{t("comment")}:</strong>{" "}
-                        {tableData.comment === "" ? (
-                          t("not_set")
-                        ) : (
-                          <div>{tableData.comment}</div>
-                        )}
-                      </div>
-                      <div>
-                        <strong
-                          className={`${
-                            tableData.indices.length === 0 ? "" : "block"
-                          }`}
-                        >
-                          {t("indices")}:
-                        </strong>{" "}
-                        {tableData.indices.length === 0 ? (
-                          t("not_set")
-                        ) : (
-                          <div>
-                            {tableData.indices.map((index, k) => (
-                              <div
-                                key={k}
-                                className={`flex items-center my-1 px-2 py-1 rounded ${
-                                  settings.mode === "light"
-                                    ? "bg-gray-100"
-                                    : "bg-zinc-800"
-                                }`}
-                              >
-                                <i className="fa-solid fa-thumbtack me-2 mt-1 text-slate-500"></i>
-                                <div>
-                                  {index.fields.map((f) => (
-                                    <Tag color="blue" key={f} className="me-1">
-                                      {f}
-                                    </Tag>
-                                  ))}
-                                </div>
-                              </div>
-                            ))}
-                          </div>
-                        )}
-                      </div>
-                      <Button
-                        icon={<IconDeleteStroked />}
-                        type="danger"
-                        block
-                        style={{ marginTop: "8px" }}
-                        onClick={() => deleteTable(tableData.id)}
-                      >
-                        {t("delete")}
-                      </Button>
-                    </div>
-                  }
-                  position="rightTop"
-                  showArrow
-                  trigger="click"
-                  style={{ width: "200px", wordBreak: "break-word" }}
-                >
-                  <Button
-                    icon={<IconMore />}
-                    type="tertiary"
-                    size="small"
-                    style={{
-                      backgroundColor: "#808080b3",
-                      color: "white",
-                    }}
-                  />
-                </Popover>
-              </div>
-            </div>
-          </div>
-          {tableData.fields.map((e, i) => {
-            return settings.showFieldSummary ? (
-              <Popover
-                key={i}
-                content={
-                  <div className="popover-theme">
-                    <div
-                      className="flex justify-between items-center pb-2"
-                      style={{ direction: "ltr" }}
-                    >
-                      <p className="me-4 font-bold">{e.name}</p>
-                      <p className="ms-4">
-                        {e.type +
-                          ((dbToTypes[database][e.type].isSized ||
-                            dbToTypes[database][e.type].hasPrecision) &&
-                          e.size &&
-                          e.size !== ""
-                            ? "(" + e.size + ")"
-                            : "")}
-                      </p>
-                    </div>
-                    <hr />
-                    {e.primary && (
-                      <Tag color="blue" className="me-2 my-2">
-                        {t("primary")}
-                      </Tag>
-                    )}
-                    {e.unique && (
-                      <Tag color="amber" className="me-2 my-2">
-                        {t("unique")}
-                      </Tag>
-                    )}
-                    {e.notNull && (
-                      <Tag color="purple" className="me-2 my-2">
-                        {t("not_null")}
-                      </Tag>
-                    )}
-                    {e.increment && (
-                      <Tag color="green" className="me-2 my-2">
-                        {t("autoincrement")}
-                      </Tag>
-                    )}
-                    <p>
-                      <strong>{t("default_value")}: </strong>
-                      {e.default === "" ? t("not_set") : e.default}
-                    </p>
-                    <p>
-                      <strong>{t("comment")}: </strong>
-                      {e.comment === "" ? t("not_set") : e.comment}
-                    </p>
-                  </div>
-                }
-                position="right"
-                showArrow
-                style={
-                  isRtl(i18n.language)
-                    ? { direction: "rtl" }
-                    : { direction: "ltr" }
-                }
-              >
-                {field(e, i)}
-              </Popover>
-            ) : (
-              field(e, i)
-            );
-          })}
-        </div>
-      </foreignObject>
-      <SideSheet
-        title={t("edit")}
-        size="small"
-        visible={
-          selectedElement.element === ObjectType.TABLE &&
-          selectedElement.id === tableData.id &&
-          selectedElement.open &&
-          !layout.sidebar
-        }
-        onCancel={() =>
-          setSelectedElement((prev) => ({
-            ...prev,
-            open: !prev.open,
-          }))
-        }
-        style={{ paddingBottom: "16px" }}
-      >
-        <div className="sidesheet-theme">
-          <TableInfo data={tableData} />
-        </div>
-      </SideSheet>
-    </>
-  );
-
-  function field(fieldData, index) {
-    return (
-      <div
-        className={`${
-          index === tableData.fields.length - 1
-            ? ""
-            : "border-b border-gray-400"
-        } group h-[36px] px-2 py-1 flex justify-between items-center gap-1 w-full overflow-hidden`}
-        onPointerEnter={(e) => {
-          if (!e.isPrimary) return;
-
-          setHoveredField(index);
-          setHoveredTable({
-            tableId: tableData.id,
-            field: index,
-          });
-        }}
-        onPointerLeave={(e) => {
-          if (!e.isPrimary) return;
-
-          setHoveredField(-1);
-        }}
-        onPointerDown={(e) => {
-          // Required for onPointerLeave to trigger when a touch pointer leaves
-          // https://stackoverflow.com/a/70976017/1137077
-          e.target.releasePointerCapture(e.pointerId);
-        }}
-      >
-        <div
-          className={`${
-            hoveredField === index ? "text-zinc-400" : ""
-          } flex items-center gap-2 overflow-hidden`}
-        >
-          <button
-            className="flex-shrink-0 w-[10px] h-[10px] bg-[#2f68adcc] rounded-full"
-            onPointerDown={(e) => {
-              if (!e.isPrimary) return;
-
-              handleGripField(index);
-              setLinkingLine((prev) => ({
-                ...prev,
-                startFieldId: index,
-                startTableId: tableData.id,
-                startX: tableData.x + 15,
-                startY:
-                  tableData.y +
-                  index * tableFieldHeight +
-                  tableHeaderHeight +
-                  tableColorStripHeight +
-                  12,
-                endX: tableData.x + 15,
-                endY:
-                  tableData.y +
-                  index * tableFieldHeight +
-                  tableHeaderHeight +
-                  tableColorStripHeight +
-                  12,
-              }));
-            }}
-          />
-          <span className="overflow-hidden text-ellipsis whitespace-nowrap">
-            {fieldData.name}
-          </span>
-        </div>
-        <div className="text-zinc-400">
-          {hoveredField === index ? (
-            <Button
-              theme="solid"
-              size="small"
-              style={{
-                backgroundColor: "#d42020b3",
-              }}
-              icon={<IconMinus />}
-              onClick={() => deleteField(fieldData, tableData.id)}
-            />
-          ) : (
-            <div className="flex gap-1 items-center">
-              {fieldData.primary && <IconKeyStroked />}
-              {!fieldData.notNull && <span>?</span>}
-              <span>
-                {fieldData.type +
-                  ((dbToTypes[database][fieldData.type].isSized ||
-                    dbToTypes[database][fieldData.type].hasPrecision) &&
-                  fieldData.size &&
-                  fieldData.size !== ""
-                    ? "(" + fieldData.size + ")"
-                    : "")}
-              </span>
-            </div>
-          )}
-        </div>
-      </div>
-    );
-  }
-}
diff --git a/src/components/EditorCanvas/Table/components/TableField.jsx b/src/components/EditorCanvas/Table/components/TableField.jsx
new file mode 100644
index 00000000..e96ce7b8
--- /dev/null
+++ b/src/components/EditorCanvas/Table/components/TableField.jsx
@@ -0,0 +1,133 @@
+import React, { forwardRef } from "react";
+import { dbToTypes } from "../../../../data/datatypes";
+import { useDiagram } from "../../../../hooks";
+import { Button } from "@douyinfe/semi-ui";
+import { IconMinus, IconKeyStroked } from "@douyinfe/semi-icons";
+
+const TableField = forwardRef((props, ref) => {
+  const {
+    tableData,
+    fieldData,
+    index,
+    setHoveredTable,
+    handleGripField,
+    setLinkingLine,
+    setHoveredField,
+    hoveredField,
+    tableFieldHeight,
+    tableHeaderHeight,
+    tableColorStripHeight,
+  } = props;
+  const { database, deleteField } = useDiagram();
+
+  const FieldSize = React.memo(({ field }) => {
+    let hasSize =
+      dbToTypes[database][field.type].isSized ||
+      dbToTypes[database][field.type].hasPrecision;
+    let sizeValid = field.size && field.size !== "";
+
+    if (hasSize && sizeValid) {
+      return field.type + `(${field.size})`;
+    } else {
+      return field.type;
+    }
+  });
+
+  FieldSize.displayName = "FieldSize";
+
+  return (
+    <div
+      // Popover children needs forwardRef and props destructuring to work with
+      // Functiona Components (https://semi.design/en-US/show/popover#Cautions)
+      ref={ref}
+      {...props}
+      className={`${
+        index === tableData.fields.length - 1 ? "" : "border-b border-gray-400"
+      } group h-[36px] px-2 py-1 flex justify-between items-center gap-1 w-full overflow-hidden`}
+      onPointerEnter={(e) => {
+        if (!e.isPrimary) return;
+
+        setHoveredField(index);
+        setHoveredTable({
+          tableId: tableData.id,
+          field: index,
+        });
+      }}
+      onPointerLeave={(e) => {
+        if (!e.isPrimary) return;
+
+        setHoveredField(-1);
+      }}
+      onPointerDown={(e) => {
+        // Required for onPointerLeave to trigger when a touch pointer leaves
+        // https://stackoverflow.com/a/70976017/1137077
+        e.target.releasePointerCapture(e.pointerId);
+      }}
+    >
+      <div
+        className={`${
+          hoveredField === index ? "text-zinc-400" : ""
+        } flex items-center gap-2 overflow-hidden`}
+      >
+        <button
+          className="flex-shrink-0 w-[10px] h-[10px] bg-[#2f68adcc] rounded-full"
+          onPointerDown={(e) => {
+            if (!e.isPrimary) return;
+
+            handleGripField(index);
+            setLinkingLine((prev) => ({
+              ...prev,
+              startFieldId: index,
+              startTableId: tableData.id,
+              startX: tableData.x + 15,
+              startY:
+                tableData.y +
+                index * tableFieldHeight +
+                tableHeaderHeight +
+                tableColorStripHeight +
+                12,
+              endX: tableData.x + 15,
+              endY:
+                tableData.y +
+                index * tableFieldHeight +
+                tableHeaderHeight +
+                tableColorStripHeight +
+                12,
+            }));
+          }}
+        />
+        <span className="overflow-hidden text-ellipsis whitespace-nowrap">
+          {fieldData.name}
+        </span>
+      </div>
+
+      <div className="text-zinc-400">
+        {hoveredField === index ? (
+          <Button
+            theme="solid"
+            size="small"
+            style={{
+              backgroundColor: "#d42020b3",
+            }}
+            icon={<IconMinus />}
+            onClick={() => {
+              deleteField(fieldData, tableData.id);
+            }}
+          />
+        ) : (
+          <div className="flex gap-1 items-center">
+            {fieldData.primary && <IconKeyStroked />}
+            {!fieldData.notNull && <span>?</span>}
+            <span>
+              <FieldSize field={fieldData} />
+            </span>
+          </div>
+        )}
+      </div>
+    </div>
+  );
+});
+
+TableField.displayName = "TableField";
+
+export default TableField;
diff --git a/src/components/EditorCanvas/Table/components/TableFieldPopover.jsx b/src/components/EditorCanvas/Table/components/TableFieldPopover.jsx
new file mode 100644
index 00000000..00d19bee
--- /dev/null
+++ b/src/components/EditorCanvas/Table/components/TableFieldPopover.jsx
@@ -0,0 +1,83 @@
+import React from "react";
+import { useTranslation } from "react-i18next";
+import i18n from "../../../../i18n/i18n";
+import { isRtl } from "../../../../i18n/utils/rtl";
+import { Popover, Tag } from "@douyinfe/semi-ui";
+import { dbToTypes } from "../../../../data/datatypes";
+import { useDiagram } from "../../../../hooks";
+
+export default function TableFieldPopover({ fieldData, children, visible }) {
+  const { database } = useDiagram();
+  const { t } = useTranslation();
+
+  if (!visible) {
+    return <React.Fragment>{children}</React.Fragment>;
+  }
+
+  const FieldSize = React.memo(({ field }) => {
+    let hasSize =
+      dbToTypes[database][field.type].isSized ||
+      dbToTypes[database][field.type].hasPrecision;
+    let sizeValid = field.size && field.size !== "";
+
+    if (hasSize && sizeValid) {
+      return `(${field.size})`;
+    } else {
+      return "";
+    }
+  });
+
+  FieldSize.displayName = "FieldSize";
+
+  return (
+    <Popover
+      content={
+        <div className="popover-theme">
+          <div
+            className="flex justify-between items-center pb-2"
+            style={{ direction: "ltr" }}
+          >
+            <p className="me-4 font-bold">{fieldData.name}</p>
+            <p className="ms-4">{<FieldSize field={fieldData} />}</p>
+          </div>
+
+          <hr />
+
+          {fieldData.primary && (
+            <Tag color="blue" className="me-2 my-2">
+              {t("primary")}
+            </Tag>
+          )}
+          {fieldData.unique && (
+            <Tag color="amber" className="me-2 my-2">
+              {t("unique")}
+            </Tag>
+          )}
+          {fieldData.notNull && (
+            <Tag color="purple" className="me-2 my-2">
+              {t("not_null")}
+            </Tag>
+          )}
+          {fieldData.increment && (
+            <Tag color="green" className="me-2 my-2">
+              {t("autoincrement")}
+            </Tag>
+          )}
+          <p>
+            <strong>{t("default_value")}: </strong>
+            {fieldData.default === "" ? t("not_set") : fieldData.default}
+          </p>
+          <p>
+            <strong>{t("comment")}: </strong>
+            {fieldData.comment === "" ? t("not_set") : fieldData.comment}
+          </p>
+        </div>
+      }
+      position="right"
+      showArrow
+      style={isRtl(i18n.language) ? { direction: "rtl" } : { direction: "ltr" }}
+    >
+      {children}
+    </Popover>
+  );
+}
diff --git a/src/components/EditorCanvas/Table/components/TableHeader.jsx b/src/components/EditorCanvas/Table/components/TableHeader.jsx
new file mode 100644
index 00000000..7d214ac5
--- /dev/null
+++ b/src/components/EditorCanvas/Table/components/TableHeader.jsx
@@ -0,0 +1,105 @@
+import { IconEdit, IconMore, IconDeleteStroked } from "@douyinfe/semi-icons";
+import { Popover, Tag, Button } from "@douyinfe/semi-ui";
+import { useDiagram } from "../../../../hooks";
+
+export default function TableHeader({ tableData, settings, openEditor, t }) {
+  const { deleteTable } = useDiagram();
+
+  return (
+    <div
+      className={`overflow-hidden font-bold h-[40px] flex justify-between items-center border-b border-gray-400 ${
+        settings.mode === "light" ? "bg-zinc-200" : "bg-zinc-900"
+      }`}
+    >
+      <div className="px-3 overflow-hidden text-ellipsis whitespace-nowrap">
+        {tableData.name}
+      </div>
+      <div className="hidden group-hover:block">
+        <div className="flex justify-end items-center mx-2">
+          <Button
+            icon={<IconEdit />}
+            size="small"
+            theme="solid"
+            style={{
+              backgroundColor: "#2f68adb3",
+              marginRight: "6px",
+            }}
+            onClick={openEditor}
+          />
+          <Popover
+            key={tableData.key}
+            content={
+              <div className="popover-theme">
+                <div className="mb-2">
+                  <strong>{t("comment")}:</strong>{" "}
+                  {tableData.comment === "" ? (
+                    t("not_set")
+                  ) : (
+                    <div>{tableData.comment}</div>
+                  )}
+                </div>
+                <div>
+                  <strong
+                    className={`${
+                      tableData.indices.length === 0 ? "" : "block"
+                    }`}
+                  >
+                    {t("indices")}:
+                  </strong>{" "}
+                  {tableData.indices.length === 0 ? (
+                    t("not_set")
+                  ) : (
+                    <div>
+                      {tableData.indices.map((index, k) => (
+                        <div
+                          key={k}
+                          className={`flex items-center my-1 px-2 py-1 rounded ${
+                            settings.mode === "light"
+                              ? "bg-gray-100"
+                              : "bg-zinc-800"
+                          }`}
+                        >
+                          <i className="fa-solid fa-thumbtack me-2 mt-1 text-slate-500"></i>
+                          <div>
+                            {index.fields.map((f) => (
+                              <Tag color="blue" key={f} className="me-1">
+                                {f}
+                              </Tag>
+                            ))}
+                          </div>
+                        </div>
+                      ))}
+                    </div>
+                  )}
+                </div>
+                <Button
+                  icon={<IconDeleteStroked />}
+                  type="danger"
+                  block
+                  style={{ marginTop: "8px" }}
+                  onClick={() => deleteTable(tableData.id)}
+                >
+                  {t("delete")}
+                </Button>
+              </div>
+            }
+            position="rightTop"
+            showArrow
+            trigger="click"
+            style={{ width: "200px", wordBreak: "break-word" }}
+          >
+            <Button
+              icon={<IconMore />}
+              type="tertiary"
+              size="small"
+              style={{
+                backgroundColor: "#808080b3",
+                color: "white",
+              }}
+            />
+          </Popover>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/src/components/EditorCanvas/Table/index.jsx b/src/components/EditorCanvas/Table/index.jsx
new file mode 100644
index 00000000..69bc5208
--- /dev/null
+++ b/src/components/EditorCanvas/Table/index.jsx
@@ -0,0 +1,156 @@
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { SideSheet } from "@douyinfe/semi-ui";
+import { useLayout, useSettings, useSelect } from "../../../hooks";
+
+import {
+  Tab,
+  ObjectType,
+  tableFieldHeight,
+  tableHeaderHeight,
+  tableColorStripHeight,
+} from "../../../data/constants";
+
+import TableFieldPopover from "./components/TableFieldPopover";
+import TableField from "./components/TableField";
+import TableHeader from "./components/TableHeader";
+
+import TableInfo from "../../EditorSidePanel/TablesTab/TableInfo";
+
+export default function Table(props) {
+  const [hoveredField, setHoveredField] = useState(-1);
+  const {
+    tableData,
+    onPointerDown,
+    setHoveredTable,
+    handleGripField,
+    setLinkingLine,
+  } = props;
+  const { layout } = useLayout();
+  const { settings } = useSettings();
+  const { t } = useTranslation();
+  const { selectedElement, setSelectedElement } = useSelect();
+
+  const height =
+    tableData.fields.length * tableFieldHeight + tableHeaderHeight + 7;
+
+  const openEditor = () => {
+    if (!layout.sidebar) {
+      setSelectedElement((prev) => ({
+        ...prev,
+        element: ObjectType.TABLE,
+        id: tableData.id,
+        open: true,
+      }));
+    } else {
+      setSelectedElement((prev) => ({
+        ...prev,
+        currentTab: Tab.TABLES,
+        element: ObjectType.TABLE,
+        id: tableData.id,
+        open: true,
+      }));
+      if (selectedElement.currentTab !== Tab.TABLES) return;
+      document
+        .getElementById(`scroll_table_${tableData.id}`)
+        .scrollIntoView({ behavior: "smooth" });
+    }
+  };
+
+  const TableHeaderBand = React.memo(({ color }) => {
+    return (
+      <div
+        className="h-[10px] w-full rounded-t-md"
+        style={{ backgroundColor: color }}
+      />
+    );
+  });
+
+  TableHeaderBand.displayName = "TableHeaderBand";
+
+  return (
+    <>
+      <foreignObject
+        key={tableData.id}
+        x={tableData.x}
+        y={tableData.y}
+        width={settings.tableWidth}
+        height={height}
+        className="group drop-shadow-lg rounded-md cursor-move"
+        onPointerDown={onPointerDown}
+      >
+        <div
+          onDoubleClick={openEditor}
+          className={`border-2 hover:border-dashed hover:border-blue-500
+               select-none rounded-lg w-full ${
+                 settings.mode === "light"
+                   ? "bg-zinc-100 text-zinc-800"
+                   : "bg-zinc-800 text-zinc-200"
+               } ${
+                 selectedElement.id === tableData.id &&
+                 selectedElement.element === ObjectType.TABLE
+                   ? "border-solid border-blue-500"
+                   : "border-zinc-500"
+               }`}
+          style={{ direction: "ltr" }}
+        >
+          <TableHeaderBand color={tableData.color} />
+
+          <TableHeader
+            tableData={tableData}
+            settings={settings}
+            openEditor={openEditor}
+            t={t}
+          />
+
+          {tableData.fields.map((fieldData, index) => {
+            return (
+              <TableFieldPopover
+                key={index}
+                visible={settings.showFieldSummary}
+                fieldData={fieldData}
+              >
+                <TableField
+                  key={index}
+                  tableData={tableData}
+                  fieldData={fieldData}
+                  index={index}
+                  setHoveredTable={setHoveredTable}
+                  handleGripField={handleGripField}
+                  setLinkingLine={setLinkingLine}
+                  setHoveredField={setHoveredField}
+                  hoveredField={hoveredField}
+                  tableFieldHeight={tableFieldHeight}
+                  tableHeaderHeight={tableHeaderHeight}
+                  tableColorStripHeight={tableColorStripHeight}
+                />
+              </TableFieldPopover>
+            );
+          })}
+        </div>
+      </foreignObject>
+
+      <SideSheet
+        title={t("edit")}
+        size="small"
+        visible={
+          selectedElement.element === ObjectType.TABLE &&
+          selectedElement.id === tableData.id &&
+          selectedElement.open &&
+          !layout.sidebar
+        }
+        onCancel={() =>
+          setSelectedElement((prev) => ({
+            ...prev,
+            open: !prev.open,
+          }))
+        }
+        style={{ paddingBottom: "16px" }}
+      >
+        <div className="sidesheet-theme">
+          <TableInfo data={tableData} />
+        </div>
+      </SideSheet>
+    </>
+  );
+}