From 37387f80fcf3d6d2230669cfeb05bac6ba57f0a3 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sat, 14 Feb 2026 14:57:02 +0900 Subject: [PATCH 1/8] =?UTF-8?q?=E9=87=8D=E6=9E=84=20DraggableEntry=20?= =?UTF-8?q?=E3=80=81=E4=BF=AE=E6=AD=A3=E5=8D=A1=E7=89=87=E9=AB=98=E5=BA=A6?= =?UTF-8?q?=E5=AF=B9=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../options/routes/ScriptList/ScriptCard.tsx | 387 +++++++++--------- 1 file changed, 189 insertions(+), 198 deletions(-) diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index 41f151e52..a9a77c284 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -33,49 +33,42 @@ import type { SearchType } from "@App/app/service/service_worker/types"; type DragCtx = Pick, "listeners" | "setActivatorNodeRef"> | null; const SortableDragCtx = createContext(null); -function composeRefs(...refs: React.Ref[]): (node: T | null) => void { - return (node) => { - for (const ref of refs) { - if (typeof ref === "function") { - ref(node); - } else if (ref) { - (ref as React.MutableRefObject).current = node; - } - } - }; -} - -type DraggableEntryProps = { recordUUID: string } & React.HTMLAttributes; +type DraggableEntryProps = { + recordUUID: string; + children: React.ReactElement; +}; -const DraggableEntry = React.forwardRef(({ recordUUID, ...rest }, ref) => { - const sortable = useSortable({ id: recordUUID }); - const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging } = sortable; +const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { + const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging, attributes } = useSortable({ + id: recordUUID, + }); const style = { - // ScriptCard 移位渉及多个元件上下左右移动,DragEnd时不要使用 dnd-kit 提供的效果 + ...children.props.style, // Merge existing styles transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, zIndex: isDragging ? 10 : "auto", }; - const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); - const ctxValue = useMemo( () => ({ - listeners: listeners, - setActivatorNodeRef: setActivatorNodeRef, + listeners, + setActivatorNodeRef, }), [listeners, setActivatorNodeRef] ); return ( -
+ {React.cloneElement(children, { + ref: setNodeRef, + style, + ...attributes, + })} ); -}); -DraggableEntry.displayName = "DraggableEntry"; +}; const DragHandle = () => { const sortable = useContext(SortableDragCtx); @@ -162,205 +155,203 @@ export const ScriptCardItem = React.memo( return ( -
- -
-
-
-
- -
- - - {i18nName(item)} - -
- - {tags.length > 0 && ( - - {tags.map((tag) => ( - - {tag} - - ))} - - )} -
-
- { - updateScripts([item.uuid], { enableLoading: true }); - requestEnableScript({ uuid: item.uuid, enable: checked }); - }} - /> -
- + +
+
+
+
+ +
+ + + {i18nName(item)} +
+ + {tags.length > 0 && ( + + {tags.map((tag) => ( + + {tag} + + ))} + + )} +
+
+ { + updateScripts([item.uuid], { enableLoading: true }); + requestEnableScript({ uuid: item.uuid, enable: checked }); + }} + /> +
+
+
- {/* 版本和更新时间 */} -
- {item.metadata.version?.[0] && ( -
- - {t("version")} - {": "} - - {item.metadata.version[0]} -
- )} -
+ {/* 版本和更新时间 */} +
+ {item.metadata.version?.[0] && ( +
- {t("last_updated")} + {t("version")} {": "} - + {item.metadata.version[0]}
+ )} +
+ + {t("last_updated")} + {": "} + +
+
- {/* 运行状态 */} -
- {item.type !== SCRIPT_TYPE_NORMAL && ( -
- + {item.type !== SCRIPT_TYPE_NORMAL && ( +
+ + } + color="blue" + bordered + style={{ cursor: "pointer" }} + onClick={toLogger} > - } - color="blue" - bordered - style={{ cursor: "pointer" }} - onClick={toLogger} - > - {item.runStatus === SCRIPT_RUN_STATUS_RUNNING ? t("running") : t("completed")} - - -
- )} - -
+ {item.runStatus === SCRIPT_RUN_STATUS_RUNNING ? t("running") : t("completed")} + + +
+ )} + +
-
- {item.type === SCRIPT_TYPE_NORMAL && ( - - {favoriteMemo.trimmed.map((fav) => ( - { - if (fav.website) { - window.open(fav.website, "_blank"); - } - }} - /> - ))} - {favoriteMemo.originalLen > 8 && {"..."}} - +
+ {item.type === SCRIPT_TYPE_NORMAL && ( + + {favoriteMemo.trimmed.map((fav) => ( + { + if (fav.website) { + window.open(fav.website, "_blank"); + } + }} + /> + ))} + {favoriteMemo.originalLen > 8 && {"..."}} + + )} + +
+
+ {/* 操作按钮 */} +
+ +
+
+ {item.type !== SCRIPT_TYPE_NORMAL && ( + )} -
-
- {/* 操作按钮 */} -
- -
-
- {item.type !== SCRIPT_TYPE_NORMAL && ( +
+ + + + + {item.config && ( )} -
-
- - - - - {item.config && ( - - )} - {item.metadata.cloudcat && ( - - )} - } + size="mini" + onClick={() => setCloudScript(item)} + > + {t("cloud")} + + )} + } + onOk={() => handleDelete(item)} + > + - - -
+ {t("delete")} + + +
- -
+
+ ); }, From 117a092d529b4455fb2247f0bb3868065f751678 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Mon, 16 Feb 2026 17:16:14 +0900 Subject: [PATCH 2/8] Update src/pages/options/routes/ScriptList/ScriptCard.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/pages/options/routes/ScriptList/ScriptCard.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index a9a77c284..c04def3ad 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -70,6 +70,7 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { ); }; +DraggableEntry.displayName = "DraggableEntry"; const DragHandle = () => { const sortable = useContext(SortableDragCtx); From df0c8b1a8aea9f7669525c6c1ec7b593df68d251 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Mon, 16 Feb 2026 17:43:29 +0900 Subject: [PATCH 3/8] =?UTF-8?q?=E6=A0=B9=E6=8D=AEAI=E6=8C=87=E7=A4=BA?= =?UTF-8?q?=EF=BC=8C=E8=BF=98=E5=8E=9F=E8=87=B3=E5=8E=9F=E6=9C=89=E7=9A=84?= =?UTF-8?q?=20composeRefs=20/=20mergeRefs=20=E5=81=9A=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../options/routes/ScriptList/ScriptCard.tsx | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index c04def3ad..192ba1869 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -38,6 +38,18 @@ type DraggableEntryProps = { children: React.ReactElement; }; +function composeRefs(...refs: React.Ref[]): (node: T | null) => void { + return (node) => { + for (const ref of refs) { + if (typeof ref === "function") { + ref(node); + } else if (ref) { + (ref as React.MutableRefObject).current = node; + } + } + }; +} + const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging, attributes } = useSortable({ id: recordUUID, @@ -51,6 +63,9 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { zIndex: isDragging ? 10 : "auto", }; + // Extract the child's existing ref and compose it with dnd-kit + const composedRefs = composeRefs((children as any).ref, setNodeRef); + const ctxValue = useMemo( () => ({ listeners, @@ -62,9 +77,10 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { return ( {React.cloneElement(children, { - ref: setNodeRef, - style, ...attributes, + ...children.props, + ref: composedRefs, + style, })} ); From 2a95b9629c43da92815f087338dd1652637fe546 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Mon, 16 Feb 2026 17:48:10 +0900 Subject: [PATCH 4/8] =?UTF-8?q?=E8=BF=98=E5=8E=9F=E8=87=B3=E5=8E=9F?= =?UTF-8?q?=E6=9C=AC=E7=9A=84mergedRef?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/options/routes/ScriptList/ScriptCard.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index 192ba1869..5132ca0d8 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -63,8 +63,9 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { zIndex: isDragging ? 10 : "auto", }; + const ref = (children as any).ref; // Extract the child's existing ref and compose it with dnd-kit - const composedRefs = composeRefs((children as any).ref, setNodeRef); + const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); const ctxValue = useMemo( () => ({ @@ -79,7 +80,7 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { {React.cloneElement(children, { ...attributes, ...children.props, - ref: composedRefs, + ref: mergedRef, style, })} From 55377c3f6bcb01afa47ae5aa53292bb4256e26d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Tue, 17 Feb 2026 20:31:43 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E4=BD=BF=E7=94=A8React.forwardRef?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/options/routes/ScriptList/ScriptCard.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index 5132ca0d8..3dc9901b5 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -50,7 +50,7 @@ function composeRefs(...refs: React.Ref[]): (node: T | null) => void { }; } -const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { +const DraggableEntry = React.forwardRef(({ recordUUID, children }, ref) => { const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging, attributes } = useSortable({ id: recordUUID, }); @@ -63,7 +63,6 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { zIndex: isDragging ? 10 : "auto", }; - const ref = (children as any).ref; // Extract the child's existing ref and compose it with dnd-kit const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); @@ -85,7 +84,7 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { })} ); -}; +}); DraggableEntry.displayName = "DraggableEntry"; const DragHandle = () => { From f583ba80a12ace1677cf2a705cf5e358f404d821 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 18 Feb 2026 07:13:40 +0900 Subject: [PATCH 6/8] =?UTF-8?q?Revert=20"=E4=BD=BF=E7=94=A8React.forwardRe?= =?UTF-8?q?f"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 55377c3f6bcb01afa47ae5aa53292bb4256e26d4. --- src/pages/options/routes/ScriptList/ScriptCard.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index 3dc9901b5..5132ca0d8 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -50,7 +50,7 @@ function composeRefs(...refs: React.Ref[]): (node: T | null) => void { }; } -const DraggableEntry = React.forwardRef(({ recordUUID, children }, ref) => { +const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging, attributes } = useSortable({ id: recordUUID, }); @@ -63,6 +63,7 @@ const DraggableEntry = React.forwardRef(({ zIndex: isDragging ? 10 : "auto", }; + const ref = (children as any).ref; // Extract the child's existing ref and compose it with dnd-kit const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); @@ -84,7 +85,7 @@ const DraggableEntry = React.forwardRef(({ })} ); -}); +}; DraggableEntry.displayName = "DraggableEntry"; const DragHandle = () => { From 26d0745b3a8fbf507dc46d16e3cd3ff9256cd6cf Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 18 Feb 2026 07:25:26 +0900 Subject: [PATCH 7/8] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=8F=8A=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../options/routes/ScriptList/ScriptCard.tsx | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index 5132ca0d8..cf9271779 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -35,11 +35,13 @@ const SortableDragCtx = createContext(null); type DraggableEntryProps = { recordUUID: string; - children: React.ReactElement; + children: React.ReactElement & { + ref?: React.Ref; + }; }; -function composeRefs(...refs: React.Ref[]): (node: T | null) => void { - return (node) => { +function composeRefs(...refs: (React.Ref | undefined)[]): (node: T | null) => void { + return (node: T | null) => { for (const ref of refs) { if (typeof ref === "function") { ref(node); @@ -50,22 +52,34 @@ function composeRefs(...refs: React.Ref[]): (node: T | null) => void { }; } -const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { +/** + * DraggableInjector 不会转发自身的 ref。 + * + * 相反,它会读取子元素已有的 ref, + * 并将其与 dnd-kit 的 `setNodeRef` 进行合并, + * 然后通过 cloneElement 将合并后的 ref 注入回子元素。 + * + * 这个组件是一个行为包装器,而不是 DOM 包装器。 + */ +const DraggableInjector = ({ recordUUID, children }: DraggableEntryProps) => { + // 有意不使用 forwardRef。 + // 可拖拽的 ref 必须绑定在子元素本身, + // 而不是绑定在这个包装组件上。 const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging, attributes } = useSortable({ id: recordUUID, }); const style = { - ...children.props.style, // Merge existing styles + ...children.props.style, // 合并已有样式 transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, zIndex: isDragging ? 10 : "auto", }; - const ref = (children as any).ref; - // Extract the child's existing ref and compose it with dnd-kit - const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); + const ref = children.ref; + // 提取子元素原有的 ref,并与 dnd-kit 的 ref 进行合并 + const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); const ctxValue = useMemo( () => ({ @@ -79,7 +93,6 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { {React.cloneElement(children, { ...attributes, - ...children.props, ref: mergedRef, style, })} @@ -87,7 +100,6 @@ const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { ); }; -DraggableEntry.displayName = "DraggableEntry"; const DragHandle = () => { const sortable = useContext(SortableDragCtx); @@ -172,7 +184,7 @@ export const ScriptCardItem = React.memo( // console.log("Rendered - " + item.name); // 用于检查垃圾React有否过度更新 return ( - +
- + ); }, (prevProps, nextProps) => { @@ -419,10 +431,10 @@ const ScriptCard = ({ }: ScriptCardProps) => { const { t } = useTranslation(); - // Sensors — move them here (or even higher in parent) so they're stable + // 传感器 —— 放在这里(或更高层父组件)以保持稳定引用 const sensors = useSensors( useSensor(PointerSensor, { - activationConstraint: { distance: 3 }, // ← prevents accidental drag on click + activationConstraint: { distance: 3 }, // 防止点击时误触发拖拽 }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, From 82cc186c4e5c0f96b40163f57902b32fcafbf2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Wed, 18 Feb 2026 12:20:35 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E7=BB=84=E4=BB=B6ref=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../options/routes/ScriptList/ScriptCard.tsx | 40 +++---------------- .../options/routes/ScriptList/ScriptTable.tsx | 28 ++++--------- 2 files changed, 13 insertions(+), 55 deletions(-) diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index cf9271779..5aa5a17b0 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -35,36 +35,10 @@ const SortableDragCtx = createContext(null); type DraggableEntryProps = { recordUUID: string; - children: React.ReactElement & { - ref?: React.Ref; - }; + children: React.ReactElement; }; -function composeRefs(...refs: (React.Ref | undefined)[]): (node: T | null) => void { - return (node: T | null) => { - for (const ref of refs) { - if (typeof ref === "function") { - ref(node); - } else if (ref) { - (ref as React.MutableRefObject).current = node; - } - } - }; -} - -/** - * DraggableInjector 不会转发自身的 ref。 - * - * 相反,它会读取子元素已有的 ref, - * 并将其与 dnd-kit 的 `setNodeRef` 进行合并, - * 然后通过 cloneElement 将合并后的 ref 注入回子元素。 - * - * 这个组件是一个行为包装器,而不是 DOM 包装器。 - */ -const DraggableInjector = ({ recordUUID, children }: DraggableEntryProps) => { - // 有意不使用 forwardRef。 - // 可拖拽的 ref 必须绑定在子元素本身, - // 而不是绑定在这个包装组件上。 +const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging, attributes } = useSortable({ id: recordUUID, }); @@ -77,10 +51,6 @@ const DraggableInjector = ({ recordUUID, children }: DraggableEntryProps) => { zIndex: isDragging ? 10 : "auto", }; - const ref = children.ref; - // 提取子元素原有的 ref,并与 dnd-kit 的 ref 进行合并 - const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); - const ctxValue = useMemo( () => ({ listeners, @@ -93,7 +63,7 @@ const DraggableInjector = ({ recordUUID, children }: DraggableEntryProps) => { {React.cloneElement(children, { ...attributes, - ref: mergedRef, + ref: setNodeRef, style, })} @@ -184,7 +154,7 @@ export const ScriptCardItem = React.memo( // console.log("Rendered - " + item.name); // 用于检查垃圾React有否过度更新 return ( - +
- + ); }, (prevProps, nextProps) => { diff --git a/src/pages/options/routes/ScriptList/ScriptTable.tsx b/src/pages/options/routes/ScriptList/ScriptTable.tsx index d9d64a5b3..f9982ba81 100644 --- a/src/pages/options/routes/ScriptList/ScriptTable.tsx +++ b/src/pages/options/routes/ScriptList/ScriptTable.tsx @@ -104,22 +104,11 @@ const DraggableContainer = React.forwardRef(...refs: React.Ref[]): (node: T | null) => void { - return (node) => { - for (const ref of refs) { - if (typeof ref === "function") { - ref(node); - } else if (ref) { - (ref as React.MutableRefObject).current = node; - } - } - }; -} - -const DraggableRow = React.forwardRef< - HTMLTableRowElement, - { record: ScriptLoading; index: number } & React.HTMLAttributes ->(({ record, index: _index, ...rest }, ref) => { +const DraggableRow = ({ + record, + index: _index, + ...rest +}: { record: ScriptLoading; index: number } & React.HTMLAttributes) => { const sortable = useSortable({ id: record.uuid }); const { setNodeRef, transform, transition, listeners, setActivatorNodeRef } = sortable; @@ -128,8 +117,6 @@ const DraggableRow = React.forwardRef< transition, }; - const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); - const ctxValue = useMemo( () => ({ listeners: listeners, @@ -140,10 +127,11 @@ const DraggableRow = React.forwardRef< return ( - + ); -}); +}; + DraggableRow.displayName = "DraggableRow"; const DragHandle = () => {