DEV Community

Cover image for [3][DEV NOTE] Create a form with tiptap and react-textarea-autosize
CodeForStartUp
CodeForStartUp

Posted on

6 1 1 2 1

[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

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay