"use client"; import { RefObject } from "react"; import { Heading2, Heading3, Code, Quote, Image, Link, Minus, Bold, FileCode } from "lucide-react"; interface ShortcutPanelProps { textareaRef: RefObject; value: string; onChange: (value: string) => void; } export default function ShortcutPanel({ textareaRef, value, onChange }: ShortcutPanelProps) { const insert = (before: string, after: string, placeholder: string) => { const el = textareaRef.current; if (!el) { onChange(value + before + placeholder + after); return; } const start = el.selectionStart; const end = el.selectionEnd; const selected = value.slice(start, end) || placeholder; const newVal = value.slice(0, start) + before + selected + after + value.slice(end); onChange(newVal); setTimeout(() => { const pos = start + before.length + selected.length + after.length; el.setSelectionRange(start + before.length, pos); el.focus(); }, 0); }; const shortcuts = [ { label: "H2", icon: Heading2, action: () => insert("## ", "\n", "二级标题") }, { label: "H3", icon: Heading3, action: () => insert("### ", "\n", "三级标题") }, { label: "粗体", icon: Bold, action: () => insert("**", "**", "粗体文本") }, { label: "代码块", icon: FileCode, action: () => insert("```\n", "\n```\n", "代码") }, { label: "行内代码", icon: Code, action: () => insert("`", "`", "code") }, { label: "引用", icon: Quote, action: () => insert("> ", "\n", "引用内容") }, { label: "图片", icon: Image, action: () => insert("![", "]()", "描述") }, { label: "链接", icon: Link, action: () => insert("[", "]()", "链接文本") }, { label: "分割线", icon: Minus, action: () => insert("\n---\n", "", "") }, ]; return (

快捷插入

{shortcuts.map((s) => ( ))}

说明

  • 选中文字后点按钮可包裹
  • 未选中则插入模板 + 占位文字
  • 代码块自动补全语言标注
); }