稳定组件面板展开与移除交互
仅在组件存在性变化时自动展开面板 为移除组件增加确认并保留失败弹窗
This commit is contained in:
+45
-5
@@ -1,5 +1,5 @@
|
||||
import { ChevronDown, ChevronRight, Plus, Trash2 } from 'lucide-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { ThemedModal } from '../../../../../components/modal/ThemedModal';
|
||||
import type { Component } from '../../../../../features/ui-editor/types/Component';
|
||||
@@ -19,9 +19,15 @@ export function ComponentPanel(props: ComponentPanelProps) {
|
||||
const [expanded, setExpanded] = useState(Boolean(component));
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [replaceConfirmationOpen, setReplaceConfirmationOpen] = useState(false);
|
||||
const [removeConfirmationOpen, setRemoveConfirmationOpen] = useState(false);
|
||||
const previousComponentRef = useRef(component);
|
||||
|
||||
useEffect(() => {
|
||||
setExpanded(Boolean(component));
|
||||
const previous = previousComponentRef.current;
|
||||
previousComponentRef.current = component;
|
||||
if (Boolean(component) !== Boolean(previous)) {
|
||||
setExpanded(Boolean(component));
|
||||
}
|
||||
}, [component]);
|
||||
|
||||
function setComponent(next: Component | null) {
|
||||
@@ -48,8 +54,15 @@ export function ComponentPanel(props: ComponentPanelProps) {
|
||||
|
||||
function applyReplacement() {
|
||||
const result = setComponent(createComponent());
|
||||
if (result?.ok) setExpanded(true);
|
||||
setReplaceConfirmationOpen(false);
|
||||
if (result?.ok) {
|
||||
setExpanded(true);
|
||||
setReplaceConfirmationOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
function removeComponent() {
|
||||
const result = setComponent(null);
|
||||
if (result?.ok) setRemoveConfirmationOpen(false);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -107,7 +120,7 @@ export function ComponentPanel(props: ComponentPanelProps) {
|
||||
type="button"
|
||||
className="grid size-7 place-items-center rounded-lg border border-red-200 bg-red-50 text-red-700 disabled:cursor-not-allowed disabled:opacity-35"
|
||||
disabled={readOnly}
|
||||
onClick={() => setComponent(null)}
|
||||
onClick={() => setRemoveConfirmationOpen(true)}
|
||||
aria-label="移除组件"
|
||||
title="移除组件"
|
||||
>
|
||||
@@ -153,6 +166,33 @@ export function ComponentPanel(props: ComponentPanelProps) {
|
||||
</button>
|
||||
</div>
|
||||
</ThemedModal>
|
||||
<ThemedModal
|
||||
open={removeConfirmationOpen}
|
||||
ariaLabel="确认移除组件"
|
||||
onClose={() => setRemoveConfirmationOpen(false)}
|
||||
panelClassName="w-full max-w-sm rounded-2xl p-5"
|
||||
>
|
||||
<h2 className="m-0 text-base font-semibold">确认移除组件?</h2>
|
||||
<p className="mt-3 text-sm text-(--platform-text-soft)">
|
||||
当前组件配置将被移除。
|
||||
</p>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-lg border border-(--platform-subpanel-border) px-3 py-2 text-xs"
|
||||
onClick={() => setRemoveConfirmationOpen(false)}
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-lg bg-red-600 px-3 py-2 text-xs font-semibold text-white"
|
||||
onClick={removeComponent}
|
||||
>
|
||||
移除
|
||||
</button>
|
||||
</div>
|
||||
</ThemedModal>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user