├── .env.example ├── .gitignore ├── README.md ├── next.config.mjs ├── package.json ├── pnpm-lock.yaml ├── public ├── next.svg └── vercel.svg ├── src ├── app │ ├── favicon.ico │ ├── globals.css │ ├── layout.tsx │ └── page.tsx └── components │ └── Editor │ ├── Editor.tsx │ └── EditorClient.tsx └── tsconfig.json /.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_GIPHY_API_KEY= 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | .env 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | # or 12 | pnpm dev 13 | # or 14 | bun dev 15 | ``` 16 | 17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 18 | 19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. 20 | 21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 22 | 23 | ## Learn More 24 | 25 | To learn more about Next.js, take a look at the following resources: 26 | 27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 29 | 30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 31 | 32 | ## Deploy on Vercel 33 | 34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 35 | 36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 37 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | eslint: { 4 | ignoreDuringBuilds: true, 5 | }, 6 | typescript: { 7 | ignoreBuildErrors: true, 8 | }, 9 | }; 10 | 11 | export default nextConfig; 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-tiptap", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev -p 3003", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "next": "15.3.0", 13 | "react": "^19.1.0", 14 | "react-dom": "^19.1.0", 15 | "reactjs-tiptap-editor": "^0.3.1" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "^20", 19 | "@types/react": "^19", 20 | "@types/react-dom": "^19", 21 | "eslint": "^9", 22 | "eslint-config-next": "15.2.1", 23 | "typescript": "^5" 24 | }, 25 | "packageManager": "pnpm@8.15.9" 26 | } 27 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hunghg255/reactjs-tiptap-editor-demo/251b4bc1616e100398fe76b56fea4b2fce77f5af/src/app/favicon.ico -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --max-width: 1100px; 3 | --border-radius: 12px; 4 | --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", 5 | "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", 6 | "Fira Mono", "Droid Sans Mono", "Courier New", monospace; 7 | 8 | --foreground-rgb: 0, 0, 0; 9 | --background-start-rgb: 214, 219, 220; 10 | --background-end-rgb: 255, 255, 255; 11 | 12 | --primary-glow: conic-gradient( 13 | from 180deg at 50% 50%, 14 | #16abff33 0deg, 15 | #0885ff33 55deg, 16 | #54d6ff33 120deg, 17 | #0071ff33 160deg, 18 | transparent 360deg 19 | ); 20 | --secondary-glow: radial-gradient( 21 | rgba(255, 255, 255, 1), 22 | rgba(255, 255, 255, 0) 23 | ); 24 | 25 | --tile-start-rgb: 239, 245, 249; 26 | --tile-end-rgb: 228, 232, 233; 27 | --tile-border: conic-gradient( 28 | #00000080, 29 | #00000040, 30 | #00000030, 31 | #00000020, 32 | #00000010, 33 | #00000010, 34 | #00000080 35 | ); 36 | 37 | --callout-rgb: 238, 240, 241; 38 | --callout-border-rgb: 172, 175, 176; 39 | --card-rgb: 180, 185, 188; 40 | --card-border-rgb: 131, 134, 135; 41 | } 42 | 43 | @media (prefers-color-scheme: dark) { 44 | :root { 45 | --foreground-rgb: 255, 255, 255; 46 | --background-start-rgb: 0, 0, 0; 47 | --background-end-rgb: 0, 0, 0; 48 | 49 | --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); 50 | --secondary-glow: linear-gradient( 51 | to bottom right, 52 | rgba(1, 65, 255, 0), 53 | rgba(1, 65, 255, 0), 54 | rgba(1, 65, 255, 0.3) 55 | ); 56 | 57 | --tile-start-rgb: 2, 13, 46; 58 | --tile-end-rgb: 2, 5, 19; 59 | --tile-border: conic-gradient( 60 | #ffffff80, 61 | #ffffff40, 62 | #ffffff30, 63 | #ffffff20, 64 | #ffffff10, 65 | #ffffff10, 66 | #ffffff80 67 | ); 68 | 69 | --callout-rgb: 20, 20, 20; 70 | --callout-border-rgb: 108, 108, 108; 71 | --card-rgb: 100, 100, 100; 72 | --card-border-rgb: 200, 200, 200; 73 | } 74 | } 75 | 76 | * { 77 | box-sizing: border-box; 78 | padding: 0; 79 | margin: 0; 80 | } 81 | 82 | html, 83 | body { 84 | max-width: 100vw; 85 | overflow-x: hidden; 86 | } 87 | 88 | 89 | .buttonWrap { 90 | display: flex; 91 | justify-content: center; 92 | align-items: center; 93 | margin-top: 20px; 94 | } 95 | 96 | .buttonWrap button { 97 | padding: 10px 20px; 98 | border: none; 99 | border-radius: 5px; 100 | background-color: #d1d2d2; 101 | color: rgb(0, 0, 0); 102 | cursor: pointer; 103 | } 104 | 105 | .dark body { 106 | background-color: #0a0b0b; 107 | } 108 | 109 | .textarea { 110 | border: 1px solid #ccc; 111 | background: #f9f9f9; 112 | color: #333; 113 | } 114 | 115 | .dark .textarea { 116 | border: 1px solid #666; 117 | background: #0a0b0b; 118 | color: #fff; 119 | } 120 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Inter } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const inter = Inter({ subsets: ["latin"] }); 6 | 7 | export const metadata: Metadata = { 8 | title: "Create Next App", 9 | description: "Generated by create next app", 10 | }; 11 | 12 | export default function RootLayout({ 13 | children, 14 | }: Readonly<{ 15 | children: React.ReactNode; 16 | }>) { 17 | return ( 18 | 19 |
{children} 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import EditorClient from "@/components/Editor/EditorClient"; 2 | 3 | 4 | export default function Home() { 5 | return ( 6 | <> 7 |A modern WYSIWYG rich text editor based on tiptap and shadcn ui for Reactjs
👉Demo
Use shadcn ui components
Markdown support
TypeScript support
I18n support (vi, en, zh, pt)
React support
Slash Commands
Multi Column
TailwindCss
Support emoji
Support iframe
Support mermaid
pnpm install reactjs-tiptap-editor
`
214 |
215 | function debounce(func: any, wait: number) {
216 | let timeout: NodeJS.Timeout
217 | return function (...args: any[]) {
218 | clearTimeout(timeout)
219 | // @ts-ignore
220 | timeout = setTimeout(() => func.apply(this, args), wait)
221 | }
222 | }
223 |
224 | function Editor() {
225 | const [content, setContent] = useState(DEFAULT)
226 | const [theme, setTheme] = useState('light')
227 | const [disable, setDisable] = useState(false)
228 |
229 | const onValueChange = useCallback(
230 | debounce((value: any) => {
231 | setContent(value)
232 | }, 300),
233 | [],
234 | )
235 |
236 | return (
237 | Loading...
, 9 | }); 10 | 11 | const EditorClient = () => { 12 | return ( 13 | <> 14 |