├── .eslintrc.json
├── .vscode
└── settings.json
├── jsconfig.json
├── next.config.mjs
├── postcss.config.mjs
├── app
├── layout.js
├── page.js
├── globals.css
├── lib
│ └── registry.js
├── components
│ └── Editor.jsx
└── favicon.ico
├── tailwind.config.js
├── .gitignore
├── public
├── vercel.svg
└── next.svg
├── package.json
├── README.md
└── stream.txt
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "tiptap"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "#/*": ["./*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | compiler: {
4 | styledComponents: true,
5 | },
6 | };
7 |
8 | export default nextConfig;
9 |
--------------------------------------------------------------------------------
/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/app/layout.js:
--------------------------------------------------------------------------------
1 | import StyledComponentsRegistry from './lib/registry'
2 |
3 | export default function RootLayout({ children }) {
4 | return (
5 |
6 |
7 | {children}
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/app/page.js:
--------------------------------------------------------------------------------
1 | import Tiptap from "#/app/components/Editor";
2 |
3 | export default function Home() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
5 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
7 | ],
8 | theme: {
9 | extend: {
10 | backgroundImage: {
11 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
12 | "gradient-conic":
13 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | body {
20 | color: rgb(var(--foreground-rgb));
21 | background: linear-gradient(
22 | to bottom,
23 | transparent,
24 | rgb(var(--background-end-rgb))
25 | )
26 | rgb(var(--background-start-rgb));
27 | }
28 |
29 | @layer utilities {
30 | .text-balance {
31 | text-wrap: balance;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tiptap-pt",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@tiptap/extension-color": "^2.4.0",
13 | "@tiptap/extension-list-item": "^2.4.0",
14 | "@tiptap/extension-text-style": "^2.4.0",
15 | "@tiptap/pm": "^2.4.0",
16 | "@tiptap/react": "^2.4.0",
17 | "@tiptap/starter-kit": "^2.4.0",
18 | "next": "14.2.3",
19 | "react": "^18",
20 | "react-dom": "^18",
21 | "styled-components": "^6.1.11"
22 | },
23 | "devDependencies": {
24 | "eslint": "^8",
25 | "eslint-config-next": "14.2.3",
26 | "postcss": "^8",
27 | "tailwindcss": "^3.4.1"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/lib/registry.js:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import React, { useState } from 'react'
4 | import { useServerInsertedHTML } from 'next/navigation'
5 | import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
6 |
7 | export default function StyledComponentsRegistry({ children }) {
8 | // Only create stylesheet once with lazy initial state
9 | // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
10 | const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
11 |
12 | useServerInsertedHTML(() => {
13 | const styles = styledComponentsStyleSheet.getStyleElement()
14 | styledComponentsStyleSheet.instance.clearTag()
15 | return <>{styles}>
16 | })
17 |
18 | if (typeof window !== 'undefined') return <>{children}>
19 |
20 | return (
21 |
22 | {children}
23 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/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.js`. 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 |
--------------------------------------------------------------------------------
/app/components/Editor.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React, { useState } from "react";
4 | import { mergeAttributes, Node } from "@tiptap/core";
5 | import {
6 | EditorContent,
7 | useEditor,
8 | NodeViewContent,
9 | NodeViewWrapper,
10 | ReactNodeViewRenderer,
11 | useReactNodeView,
12 | } from "@tiptap/react";
13 | import StarterKit from "@tiptap/starter-kit";
14 | import styled from "styled-components";
15 |
16 | const StyledNodeViewWrapper = styled(NodeViewWrapper)`
17 | padding: 1rem;
18 | position: relative;
19 |
20 | .floating-actions {
21 | display: flex;
22 | gap: 1rem;
23 | position: absolute;
24 | z-index: 1;
25 | transition: all ease-in-out 0.5s;
26 | opacity: 0;
27 | }
28 |
29 | &:hover .floating-actions {
30 | opacity: 1;
31 | }
32 |
33 | div[data-node-view-content] > div {
34 | width: 100%;
35 | height: 100%;
36 | min-height: 200px;
37 | display: grid;
38 | place-items: center;
39 | grid-auto-rows: 1fr;
40 | grid-auto-columns: 1fr;
41 | grid-template-areas: ${({ $layout }) => {
42 | if ($layout === "center") {
43 | return `"center"`;
44 | }
45 |
46 | if ($layout === "column") {
47 | return `"image" "content"`;
48 | }
49 |
50 | if ($layout === "row") {
51 | return `"image content"`;
52 | }
53 |
54 | if ($layout === "column-reverse") {
55 | return `"content" "image"`;
56 | }
57 |
58 | if ($layout === "row-reverse") {
59 | return `"content image"`;
60 | }
61 | }};
62 |
63 | & > .react-renderer {
64 | width: 100%;
65 | height: 100%;
66 | border: solid #ececec 1px;
67 |
68 | position: ${({ $layout }) =>
69 | $layout === "center" ? "absolute" : "relative"};
70 |
71 | &:nth-child(1) {
72 | grid-area: image;
73 | }
74 |
75 | &:nth-child(2) {
76 | grid-area: content;
77 | }
78 | }
79 | }
80 | `;
81 |
82 | const LayoutWrapperRenderer = ({ updateAttributes }) => {
83 | const [layout, setLayout] = useState("row");
84 |
85 | return (
86 |
87 |
88 |
91 |
94 |
97 |
100 |
103 |
104 |
105 |
106 | );
107 | };
108 |
109 | const LayoutComponentExtension = Node.create({
110 | name: "LayoutWrapper",
111 | group: "block",
112 | content: "block+",
113 | draggable: true,
114 |
115 | parseHTML() {
116 | return [
117 | {
118 | tag: "layout-component",
119 | },
120 | ];
121 | },
122 |
123 | renderHTML({ HTMLAttributes }) {
124 | return ["div", mergeAttributes(HTMLAttributes), 0];
125 | },
126 |
127 | addNodeView() {
128 | return ReactNodeViewRenderer(LayoutWrapperRenderer);
129 | },
130 | });
131 |
132 | const LayoutChildrenRenderer = (props) => {
133 | return (
134 |
135 |
136 |
137 | );
138 | };
139 |
140 | const Layout2ComponentExtension = Node.create({
141 | name: "LayoutChildren",
142 | group: "block",
143 | content: "block+",
144 | draggable: true,
145 |
146 | parseHTML() {
147 | return [
148 | {
149 | tag: "layout-children",
150 | },
151 | ];
152 | },
153 |
154 | renderHTML({ HTMLAttributes }) {
155 | return ["div", mergeAttributes(HTMLAttributes), 0];
156 | },
157 |
158 | addNodeView() {
159 | return ReactNodeViewRenderer(LayoutChildrenRenderer);
160 | },
161 | });
162 |
163 | const extensions = [
164 | StarterKit,
165 | LayoutComponentExtension,
166 | Layout2ComponentExtension,
167 | ];
168 |
169 | const content = `
170 |
171 | image
172 | content
173 |
174 | `;
175 |
176 | const Editor = () => {
177 | const editor = useEditor({
178 | extensions,
179 | content,
180 | });
181 |
182 | return ;
183 | };
184 |
185 | export default Editor;
186 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
1 | ( F ( n 00 (- � � �F ( $ ] � � ] $ � � � � � � � � 8 � � � � � � � � � � 8 � � � � � � � � � � � � � � � � � � � � � � � � � � # � � �OOO�������������������������ggg� � � � # Y � � ��������������������������555� � � � Y � � � � �kkk��������������������� � � � � � � � � � � ������������������ � � � � � Y � � � � �JJJ���������kkk� � � � � � Y # � � � � ���������� � � � � � � # � � � � � �111�DDD� � � � � � � � � � � � � � � � � � � 8 � � � � � � � � � � 8 � � � � � � � � $ ] � � ] $ ( @ , U � � � � U , * � � � � � � � � � � � � * � � � � � � � � � � � � � � � � Q � � � � � � � � � � � � � � � � � � Q r � � � � � � � � � � � � � � � � � � � � r r � � � � � � � � � � � � � � � � � � � � � � r O � � � � � � � � � � � � � � � � � � � � � � � � O � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � ( � � � � � � � � � � � � � � � � � � � � � � � � � � � � ' � � � � � � �888���������������������������������������������������������___� � � � � � � � � � � � � � ����������������������������������������������������������SSS� � � � � � � � + � � � � � � � �hhh����������������������������������������������������� � � � � � � � � + T � � � � � � � ��������������������������������������������������,,,� � � � � � � � � T � � � � � � � � � �GGG��������������������������������������������� � � � � � � � � � � � � � � � � � � � � ������������������������������������������ � � � � � � � � � � � � � � � � � � � � �+++���������������������������������jjj� � � � � � � � � � � � � � � � � � � � � � � ���������������������������������� � � � � � � � � � � � T � � � � � � � � � � ��������������������������III� � � � � � � � � � � � T + � � � � � � � � � � � �hhh���������������������� � � � � � � � � � � � + � � � � � � � � � � � ������������������,,,� � � � � � � � � � � � � � � � � � � � � � � � � �GGG������������� � � � � � � � � � � � � � ' � � � � � � � � � � � � ���������� � � � � � � � � � � � � ( � � � � � � � � � � � � �333�___� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � O � � � � � � � � � � � � � � � � � � � � � � � � O r � � � � � � � � � � � � � � � � � � � � � � r r � � � � � � � � � � � � � � � � � � � � r Q � � � � � � � � � � � � � � � � � � Q � � � � � � � � � � � � � � � � * � � � � � � � � � � � � * , U � � � � U , ( 0 ` - ( L j � � � � j K ( V � � � � � � � � � � � � � � U % � � � � � � � � � � � � � � � � � � � � &