[3][DEV NOTE] Create a form with tiptap and react-textarea-autosize

codeforstartup

CodeForStartUp

Posted on September 4, 2023

[3][DEV NOTE] Create a form with tiptap and react-textarea-autosize

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
Enter fullscreen mode Exit fullscreen mode

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 and globals.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
Enter fullscreen mode Exit fullscreen mode

I aslo will use remixicon for icons:

pnpm add remixicon --filter web
Enter fullscreen mode Exit fullscreen mode

Update post-css and tailwindcss

PostCss for build-time imports and postcss-nesting for nested declarations:

pnpm add -D postcss-nesting postcss-import
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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>
  );
};
Enter fullscreen mode Exit fullscreen mode

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>
  );
};
Enter fullscreen mode Exit fullscreen mode

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

💖 💪 🙅 🚩
codeforstartup
CodeForStartUp

Posted on September 4, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related