添加链接弹出框 UI 组件
Available for free
用于创建和编辑链接的弹出框。
安装
您可以通过 Tiptap CLI(适用于 Vite 或 Next.js)添加组件:
npx @tiptap/cli@latest add link-popover手动集成
对于 Vite 或 Next.js 以外的框架,请从 开源仓库 手动添加组件。
导入样式
此组件需要您导入我们的样式,这些样式已添加到 styles/keyframe-animation.scss 和 styles/_variables.scss 中。
使用
<LinkPopover />
一个为 Tiptap 编辑器提供完整链接编辑界面的预制 React 组件,带有弹出框。用户友好的弹出界面支持键盘快捷键和灵活的自定义选项,可轻松添加、编辑和删除链接。
使用范例
import { EditorContent, EditorContext, useEditor } from '@tiptap/react'
import { StarterKit } from '@tiptap/starter-kit'
import { Link } from '@/components/tiptap-extension/link-extension'
import { LinkPopover } from '@/components/tiptap-ui/link-popover'
import '@/components/tiptap-node/paragraph-node/paragraph-node.scss'
export default function MyEditor() {
const editor = useEditor({
immediatelyRender: false,
extensions: [StarterKit, Link.configure({ openOnClick: false })],
content: `
<p>点击按钮打开链接弹出框。</p>
<p><a href="https://www.tiptap.dev">Tiptap</a></p>
`,
})
return (
<EditorContext.Provider value={{ editor }}>
<LinkPopover
editor={editor}
hideWhenUnavailable={true}
autoOpenOnLinkActive={true}
onSetLink={() => console.log('Link set!')}
onOpenChange={(isOpen) => console.log('Popover opened:', isOpen)}
/>
<EditorContent editor={editor} role="presentation" />
</EditorContext.Provider>
)
}参数说明
| 名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| editor | Editor | null | null | Tiptap 编辑器实例 |
| hideWhenUnavailable | boolean | false | 链接功能不可用时是否隐藏按钮 |
| onSetLink | () => void | - | 成功设置链接后的回调 |
| onOpenChange | (isOpen: boolean) => void | - | 弹出框打开状态改变时的回调 |
| autoOpenOnLinkActive | boolean | true | 链接激活时是否自动打开弹出框 |
<LinkButton />
一个独立的链接按钮组件,用以触发链接相关功能。
使用范例
<LinkButton onClick={handleClick} aria-label="添加链接">
自定义链接内容
</LinkButton><LinkContent />
一个独立组件,渲染链接编辑界面,但不包含弹出框包装。
使用范例
<LinkContent editor={editor} />Hooks
useLinkPopover()
自定义钩子,可构建自定义链接界面,全面控制渲染及行为。
使用范例
function MyLinkButton() {
const { isVisible, canSet, isActive, url, setUrl, setLink, removeLink, label, Icon } =
useLinkPopover({
editor: myEditor,
hideWhenUnavailable: true,
onSetLink: () => console.log('Link set!'),
})
if (!isVisible) return null
return (
<div>
<button onClick={setLink} disabled={!canSet} aria-label={label} aria-pressed={isActive}>
<Icon />
{label}
</button>
<input
type="url"
value={url}
onChange={(e) => setUrl(e.target.value)}
placeholder="请输入 URL..."
/>
<button onClick={removeLink}>移除</button>
</div>
)
}参数说明
| 名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| editor | Editor | null | - | Tiptap 编辑器实例 |
| hideWhenUnavailable | boolean | false | 链接不能应用时是否隐藏功能 |
| onSetLink | () => void | - | 设置链接后的回调 |
返回值说明
| Name | Type | Description |
|---|---|---|
isVisible | boolean | Whether the link functionality should be rendered |
canSet | boolean | If a link can be set in the current context |
isActive | boolean | If a link is currently active/selected |
url | string | Current URL value for the link |
setUrl | React.Dispatch<React.SetStateAction<string | null>> | Function to update the URL state |
setLink | () => void | Function to apply the link in the editor |
removeLink | () => void | Function to remove the link from the editor |
label | string | Accessible label text for the button |
Icon | React.FC | Icon component for the link button |
useLinkHandler()
专注于处理链接操作的钩子,不包含 UI 状态管理。
使用范例
function MyCustomLinkInterface() {
const { url, setUrl, setLink, removeLink } = useLinkHandler({
editor: myEditor,
onSetLink: () => console.log('链接已应用!'),
})
return (
<div>
<input
value={url}
onChange={(e) => setUrl(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && setLink()}
/>
<button onClick={setLink}>应用</button>
<button onClick={removeLink}>移除</button>
</div>
)
}参数说明
| Name | Type | Default | Description |
|---|---|---|---|
editor | Editor | null | undefined | The Tiptap editor instance |
onSetLink | () => void | undefined | Callback fired after setting a link |
返回值说明
| Name | Type | Description |
|---|---|---|
url | string | Current URL value for the link |
setUrl | React.Dispatch<React.SetStateAction<string | null>> | Function to update the URL state |
setLink | () => void | Function to apply the link in the editor |
removeLink | () => void | Function to remove the link from the editor |
工具函数
canSetLink(editor)
判断当前编辑器状态是否允许设置链接。
import { canSetLink } from '@/components/tiptap-ui/link-popover'
const canSet = canSetLink(editor)
if (canSet) {
console.log('当前选区可应用链接')
}isLinkActive(editor)
判断编辑器中是否当前处于链接激活状态。
import { isLinkActive } from '@/components/tiptap-ui/link-popover'
const isActive = isLinkActive(editor)
if (isActive) {
console.log('当前已选中链接')
}键盘快捷键
链接弹出框支持以下键盘操作:
- Enter:应用当前输入框中 URL 作为链接(当焦点在 URL 输入框时)
- Escape:关闭弹出框(标准弹出框行为)
需求
依赖
@tiptap/react- Tiptap React 核心集成@tiptap/extension-link- 链接功能扩展
使用到的参考组件
use-tiptap-editor(钩子)use-mobile(钩子)use-link-popover(钩子)button(原语)popover(原语)card(原语)input(原语)separator(原语)tiptap-utils(库)corner-down-left-icon(图标)external-link-icon(图标)link-icon(图标)trash-icon(图标)