26 lines
1.7 KiB
TypeScript
26 lines
1.7 KiB
TypeScript
/**
|
||
* 分区成员拖放的展示上下文。提供名称、成员计数与当前候选归属变化,供节点显示提示;不负责执行成员迁移。
|
||
*/
|
||
"use client";
|
||
|
||
import { createContext, useContext } from "react";
|
||
import { Frame } from "lucide-react";
|
||
import type { frameDropFeedback } from "@/lib/canvas-frames";
|
||
import styles from "./canvas.module.css";
|
||
|
||
/** 缺少Provider时使用空展示数据;drops是frameDropFeedback产生的当前预览,不能代替持久归属。 */
|
||
export const FrameFeedback = createContext({ names: new Map<string, string>(), counts: new Map<string, number>(), drops: [] as ReturnType<typeof frameDropFeedback> });
|
||
|
||
/** 优先展示拖动候选to,否则使用既有frameId;只有被选中或有拖放变化时才考虑显示徽标。 */
|
||
export function MembershipBadge({ id, frameId, selected }: { id: string; frameId?: string; selected: boolean }) {
|
||
const { names, drops } = useContext(FrameFeedback);
|
||
const drop = drops.find((item) => item.id === id);
|
||
// drop.to可能为空,表示准备移出;不能用“drop.to || frameId”退回原分区,否则会隐藏移出意图。
|
||
const target = drop ? drop.to : frameId;
|
||
const name = target ? names.get(target) : undefined;
|
||
if (!drop && !selected) return null;
|
||
// 目标有名称时区分“松开加入”与“属于”;没有目标且原来有归属则提示移出,否则不绘制。
|
||
const label = name ? `${drop && drop.to !== drop.from ? "松开加入" : "属于"}:${name}` : drop?.from ? `松开移出:${names.get(drop.from) || "分区"}` : null;
|
||
return label && <div className={styles.membershipBadge} title={label}><Frame size={11} />{label}</div>;
|
||
}
|