- 作者:老汪软件技巧
- 发表时间:2024-09-22 15:00
- 浏览量:
项目地址:tiptap-editor
效果展示:lify.app/
持续更新中
技术栈实现功能操作准备工作初始化Nextjs
为了能快速的看到效果,先在Nextjs项目中直接开发编辑器
初始化一个Nextjs项目,命名为tiptap-editor
初始化时配置使用ts、tailwindcss、app router、alias为@/、使用src目录
之后删除page.tsx,layout.tsx,global.css中无用的部分,获得一个干净的项目。
安装Shadcn/ui
按照Shadcn/ui官网指示,使用以下命令初始化
pnpm dlx shadcn@latest init
Shadcn/ui配置如下
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}
安装 lucide-icon
pnpm install lucide-react
安装tiptap
按照tiptap官网,安装命令如下
pnpm install @tiptap/react @tiptap/pm @tiptap/starter-kit
之后在src目录下新建components/editor目录,新建index.tsx文件,存放编辑器组件
'use client'
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
const TiptapEditor = () => {
const editor = useEditor({
extensions: [StarterKit],
content: 'Hello World! ️
',
})
return <EditorContent editor={editor} />
}
export default TiptapEditor
之后在page.tsx中引入组件并编写一些样式
import TiptapEditor from '@/components/editor'
export default function Home() {
return (
<main>
<div className="max-w-2xl mx-auto py-16 px-12">
<TiptapEditor />
div>
main>
)
}
这样启动项目后就可以看到编辑器了
至此,准备工作就完成了,之后就该实现各类功能了。
配置样式
由于Tiptap是一个无头的编辑器,所以所有的内容样式都要由我们自己编写,随着内置功能的增加,我们的样式也会逐渐增加,所以我们在添加插件的时候同步添加样式,这里先配置好样式的文件。
新建文件src/components/editor/index.css
.tiptap {
@apply focus-visible:outline-none;
}
.tiptap :first-child {
margin-top: 0;
}
在Editor组件中引入
import './index.css'
Tiptap的内容都是由.tiptap类包括的,所以在编写样式的时候都要在前面添加.tiptap,这样的样式才会只作用于编辑器内容,而不会影响页面其他元素。
/* Scoped to the editor */
.tiptap p {
margin: 1em 0;
}
由于我们要用的是tailwindcss,并且用了TailwindCSS Intellisense插件,所以可以在.vscode/setting.json中添加下面的配置,以在配置tiptap的时候使用到插件的自动提示功能(tiptap在配置插件的时候可以给内容块添加自定义类)
"tailwindCSS.experimental.classRegex": [
"class:\\s*?[\"'`]([^\"'`]*).*?,"
]
Tiptap的插件
插件是Tiptap的核心功能,基本上所有的功能和内容都是由插件提供,甚至最基础的段落都是由插件提供,可以说没有插件,tiptap就没有任何功能。
tiptap官方提供了大量的插件供开发者使用,其中有一些可以直接用的插件和一些Pro插件,但是这个Pro插件不是付费才可以使用,而是注册tiptap的应用就可以使用。
starter-kit
对于一些基础的插件,tiptap封装了一个包供开发者快速使用@tiptap/starter-kit
这个插件在上面我们初始化编辑器的时候已经添加了,之后就是配置对应的样式
.tiptap {
@apply focus-visible:outline-none;
}
.tiptap :first-child {
margin-top: 0;
}
.tiptap blockquote {
@apply border-l-2 border-gray-300 pl-4 my-4;
}
.tiptap pre {
@apply bg-gray-600 p-4 my-4 rounded-md text-white;
}
.tiptap pre code {
@apply bg-gray-600 p-1 my-1 rounded-md text-white;
}
.tiptap h1,
h2,
h3,
h4,
h5,
h6 {
@apply my-4 font-bold leading-tight;
}
.tiptap h1 {
@apply text-4xl;
}
.tiptap h2 {
@apply text-3xl;
}
.tiptap h3 {
@apply text-2xl;
}
.tiptap h4,
h5,
h6 {
@apply text-xl;
}
.tiptap hr {
@apply my-6 border-t border-gray-300;
}
.tiptap ul,
ol {
@apply mx-4 mt-4 mb-4;
}
.tiptap ul {
@apply list-disc;
}
.tiptap ul ul {
@apply m-0 ml-5 list-[circle];
}
.tiptap ul ul ul {
@apply m-0 ml-5 list-[square];
}
.tiptap ol {
@apply list-decimal;
}
.tiptap ol ol {
@apply m-0 ml-5;
}
.tiptap ul p,
ol p {
@apply my-0;
}
.tiptap code {
@apply bg-gray-600 px-1 my-1 mx-1 rounded-md text-white text-sm;
}
.tiptap p {
@apply my-2;
}
这样不同内容的样式就可以展示出来了
这里包括了
下划线
需要安装@tiptap/extension-underline插件
pnpm install @tiptap/extension-underline
之后在编辑器中安装插件
const editor = useEditor({
extensions: [StarterKit, Underline],
// ...
})
todo列表
需要安装@tiptap/extension-task-list和@tiptap/extension-task-item插件
pnpm install @tiptap/extension-task-list @tiptap/extension-task-item
之后在编辑器中安装插件
const editor = useEditor({
extensions: [
StarterKit,
Underline,
TaskList,
TaskItem.configure({
nested: true,
}),
],
// ...
})
这样还不够,因为任务列表的实现是基于ul的,必须设置额外的样式
在index.css中添加
.tiptap ul[data-type="taskList"] {
@apply list-none ml-0 p-0;
}
.tiptap ul[data-type="taskList"] li {
@apply items-start flex;
}
.tiptap ul[data-type="taskList"] li>label {
@apply flex-shrink-0 mr-2 select-none;
}
.tiptap ul[data-type="taskList"] li>div {
@apply flex-auto;
}
.tiptap ul[data-type="taskList"] input[type="checkbox"] {
@apply cursor-pointer;
}
.tiptap ul[data-type="taskList"] ul[data-type="taskList"] {
@apply m-0;
}
超链接
实现超链接需要安装@tiptap/extension-link
pnpm install @tiptap/extension-link
之后添加插件,并自定义插件的配置
const editor = useEditor({
extensions: [
StarterKit,
Underline,
TaskList,
TaskItem.configure({
nested: true,
}),
Link.configure({
openOnClick: true,
autolink: true,
defaultProtocol: 'https',
}),
// ...
],
})
之后需要添加超链接的样式
.tiptap a {
@apply text-blue-500 underline cursor-pointer;
}
.tiptap a:hover {
@apply text-blue-600;
}
总结
通过上文的配置,我们就得到了一个可以展示和编辑一些常用元素的富文本编辑器,接下来就是对编辑器继续优化,添加更多的内容支持,包括公式、图片等;以及添加编辑内容时用到的控件,让使用者可以方便地编辑内容。