"use client"; import { useContext } from "react"; import { AnimatePresence, motion, useReducedMotion } from "motion/react"; import { NodeToolbar, Position, type NodeProps } from "@xyflow/react"; import { AlignCenter, AlignLeft, AlignRight, Bold, Italic, RotateCw, Underline } from "lucide-react"; import type { CanvasNode } from "@/lib/canvas"; import type { TextStyle } from "@/lib/canvas-elements"; import { NodeEditing, ResizeToggle } from "./transformable-node"; import styles from "./canvas.module.css"; export function NodeStyleToolbar({ id, data, selected }: NodeProps) { const reduce = useReducedMotion(); const editing = useContext(NodeEditing); const style = data.textStyle || {}; const text = data.kind === "text" || data.kind === "script" || data.kind === "plain-text"; const patch = (value: TextStyle, fontSize?: number) => editing.style(id, value, fontSize); return {selected && event.stopPropagation()} onClick={(event) => event.stopPropagation()} onDoubleClick={(event) => event.stopPropagation()} onKeyDown={(event) => { if (event.key !== "Escape") event.stopPropagation(); }}> {!(["image", "plain-image"].includes(data.kind)) && } {text && <> { const size = Number(event.target.value); if (size >= 8 && size <= 160) patch({}, size); }} /> {([["bold", Bold, "加粗"], ["italic", Italic, "斜体"], ["underline", Underline, "下划线"]] as const).map(([key, Icon, label]) => )} {([["left", AlignLeft, "左对齐"], ["center", AlignCenter, "居中"], ["right", AlignRight, "右对齐"]] as const).map(([align, Icon, label]) => )} } {!(["image", "plain-image"].includes(data.kind)) && } {!(["image", "plain-image"].includes(data.kind)) && } {data.kind !== "icon" && } } ; }