[3][DEV NOTE] Create a form with tiptap and react-textarea-autosize
CodeForStartUp
Posted on September 4, 2023
This is dev note for this project: turbo - nextjs - prisma - postgres blog
Target of this part:
- Integrate shadcn-ui
- Minor update for postcss and tailwindcss
- Create a form with react-textarea-autosize and tiptap
Install
Integrate shadcn-ui
shadcn-ui
is one of the most famous UI libraries now. So that I decide to integrate with my project.
Just a simple command we can integrate shadcn as follow:
cd app/web
npx shadcn-ui@latest init
After initial shadcn-ui, we can see a lot of changes as this commit: Initial shadcn-ui
.
These are some important changes:
-
tailwind.config.js
andglobals.css
are overrided - folded
@/
is added
Install react-textarea-autosize
and tiptap
In the root folder, we will install: react-textarea-autosize
, and tip-tap
as follow:
pnpm add react-textarea-autosize --filter web
pnpm add @tiptap/extension-character-count @tiptap/extension-highlight @tiptap/extension-placeholder @tiptap/extension-task-item @tiptap/extension-task-list @tiptap/pm @tiptap/react @tiptap/starter-kit --filter web
I aslo will use remixicon
for icons:
pnpm add remixicon --filter web
Update post-css and tailwindcss
PostCss for build-time imports and postcss-nesting for nested declarations:
pnpm add -D postcss-nesting postcss-import
Add Input title with react-textarea-autosize
apps/web/@/molecules/InputTitle.tsx
"use client";
import TextareaAutosize from "react-textarea-autosize";
type InputTitleProps = {
title?: string;
placeholder?: string;
};
const InputTitle: React.FunctionComponent<InputTitleProps> = ({
title = "",
placeholder = "",
}) => {
return (
<div className="w-full">
<TextareaAutosize
autoFocus
value={title}
placeholder={placeholder}
className="w-full h-16 px-3 py-2 text-4xl font-bold text-gray-700 border-none placeholder-gray-500 border border-gray-300 rounded-md focus:outline-none"
/>
</div>
);
};
export default InputTitle;
Add tiptap
to nextjs
To integrate tip to nextjs we need to have many step, you can refer in apps/web/@/molecules/Editor
folder,
apps/web/@/molecules/Editor/index.tsx
"use client";
import React from "react";
import CharacterCount from "@tiptap/extension-character-count";
import { EditorContent, useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Placeholder from "@tiptap/extension-placeholder";
import "./index.css";
import MenuBar from "./MenuBar";
type EditorProps = {
content?: string;
placeholder?: string;
};
export default ({ content = "", placeholder = "" }: EditorProps) => {
const editor = useEditor({
extensions: [
StarterKit,
CharacterCount.configure({
limit: 10000,
}),
Placeholder.configure({
placeholder,
}),
],
content,
});
return (
<div className="w-full editor p-3 h-full">
{editor && <MenuBar editor={editor} />}
<EditorContent editor={editor} />
</div>
);
};
Create post page
apps/web/app/user/post/create/page.tsx
"use client";
import React from "react";
import CharacterCount from "@tiptap/extension-character-count";
import { EditorContent, useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Placeholder from "@tiptap/extension-placeholder";
import "./index.css";
import MenuBar from "./MenuBar";
type EditorProps = {
content?: string;
placeholder?: string;
};
export default ({ content = "", placeholder = "" }: EditorProps) => {
const editor = useEditor({
extensions: [
StarterKit,
CharacterCount.configure({
limit: 10000,
}),
Placeholder.configure({
placeholder,
}),
],
content,
});
return (
<div className="w-full editor p-3 h-full">
{editor && <MenuBar editor={editor} />}
<EditorContent editor={editor} />
</div>
);
};
Reference:
[1] Tiptap: I follow this example collaborative-editing
[2] react-textarea-autosize: Quite simple, just follow the example here
[3] Post css preprocessor
You can find the result in this PR: [feat][UI] Create post page
Posted on September 4, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.