Shadcn Tiptap
blockstarter-kitsource: ok · refreshed
Starter Kit
npx shadcn add "https://tiptap.niazmorshed.dev/r/starter-kit.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · mediumrich-text@tiptap/starter-kit
Files11
toolbars/bold.tsx
"use client";
import { BoldIcon } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
import type { Extension } from "@tiptap/core";
import type { StarterKitOptions } from "@tiptap/starter-kit";
type StarterKitExtensions = Extension<StarterKitOptions, any>;
const BoldToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
"h-8 w-8",
editor?.isActive("bold") && "bg-accent",
className,
)}
onClick={(e) => {
editor?.chain().focus().toggleBold().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().toggleBold().run()}
ref={ref}
{...props}
>
{children || <BoldIcon className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Bold</span>
<span className="ml-1 text-xs text-gray-11">(cmd + b)</span>
</TooltipContent>
</Tooltip>
);
},
);
BoldToolbar.displayName = "BoldToolbar";
export { BoldToolbar };
toolbars/blockquote.tsx
"use client";
import { TextQuote } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const BlockquoteToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
"h-8 w-8",
editor?.isActive("blockquote") && "bg-accent",
className,
)}
onClick={(e) => {
editor?.chain().focus().toggleBlockquote().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().toggleBlockquote().run()}
ref={ref}
{...props}
>
{children || <TextQuote className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Blockquote</span>
</TooltipContent>
</Tooltip>
);
},
);
BlockquoteToolbar.displayName = "BlockquoteToolbar";
export { BlockquoteToolbar };
toolbars/bullet-list.tsx
"use client";
import { List } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const BulletListToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
"h-8 w-8",
editor?.isActive("bulletList") && "bg-accent",
className,
)}
onClick={(e) => {
editor?.chain().focus().toggleBulletList().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().toggleBulletList().run()}
ref={ref}
{...props}
>
{children || <List className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Bullet list</span>
</TooltipContent>
</Tooltip>
);
},
);
BulletListToolbar.displayName = "BulletListToolbar";
export { BulletListToolbar };
toolbars/code.tsx
"use client";
import { Code2 } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const CodeToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
"h-8 w-8",
editor?.isActive("code") && "bg-accent",
className,
)}
onClick={(e) => {
editor?.chain().focus().toggleCode().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().toggleCode().run()}
ref={ref}
{...props}
>
{children || <Code2 className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Code</span>
</TooltipContent>
</Tooltip>
);
},
);
CodeToolbar.displayName = "CodeToolbar";
export { CodeToolbar };
toolbars/code-block.tsx
"use client";
import { Code, Code2 } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const CodeBlockToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
"h-8 w-8",
editor?.isActive("codeBlock") && "bg-accent",
className,
)}
onClick={(e) => {
editor?.chain().focus().toggleCodeBlock().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().toggleCodeBlock().run()}
ref={ref}
{...props}
>
{children || <Code className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Code Block</span>
</TooltipContent>
</Tooltip>
);
},
);
CodeBlockToolbar.displayName = "CodeBlockToolbar";
export { CodeBlockToolbar };
toolbars/hard-break.tsx
"use client";
import { WrapText } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const HardBreakToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn("h-8 w-8", className)}
onClick={(e) => {
editor?.chain().focus().setHardBreak().run();
onClick?.(e);
}}
ref={ref}
{...props}
>
{children || <WrapText className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Hard break</span>
</TooltipContent>
</Tooltip>
);
},
);
HardBreakToolbar.displayName = "HardBreakToolbar";
export { HardBreakToolbar };
toolbars/horizontal-rule.tsx
"use client";
import { SeparatorHorizontal } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const HorizontalRuleToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn("h-8 w-8", className)}
onClick={(e) => {
editor?.chain().focus().setHorizontalRule().run();
onClick?.(e);
}}
ref={ref}
{...props}
>
{children || <SeparatorHorizontal className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Horizontal Rule</span>
</TooltipContent>
</Tooltip>
);
},
);
HorizontalRuleToolbar.displayName = "HorizontalRuleToolbar";
export { HorizontalRuleToolbar };
toolbars/italic.tsx
"use client";
import { ItalicIcon } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const ItalicToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
"h-8 w-8",
editor?.isActive("italic") && "bg-accent",
className,
)}
onClick={(e) => {
editor?.chain().focus().toggleItalic().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().toggleItalic().run()}
ref={ref}
{...props}
>
{children || <ItalicIcon className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Italic</span>
<span className="ml-1 text-xs text-gray-11">(cmd + i)</span>
</TooltipContent>
</Tooltip>
);
},
);
ItalicToolbar.displayName = "ItalicToolbar";
export { ItalicToolbar };
toolbars/ordered-list.tsx
"use client";
import { ListOrdered } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const OrderedListToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
"h-8 w-8",
editor?.isActive("orderedList") && "bg-accent",
className,
)}
onClick={(e) => {
editor?.chain().focus().toggleOrderedList().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().toggleOrderedList().run()}
ref={ref}
{...props}
>
{children || <ListOrdered className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Ordered list</span>
</TooltipContent>
</Tooltip>
);
},
);
OrderedListToolbar.displayName = "OrderedListToolbar";
export { OrderedListToolbar };
toolbars/redo.tsx
"use client";
import { CornerUpRight } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const RedoToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn("h-8 w-8", className)}
onClick={(e) => {
editor?.chain().focus().redo().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().redo().run()}
ref={ref}
{...props}
>
{children || <CornerUpRight className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Redo</span>
</TooltipContent>
</Tooltip>
);
},
);
RedoToolbar.displayName = "RedoToolbar";
export { RedoToolbar };
toolbars/strikethrough.tsx
"use client";
import { Strikethrough } from "lucide-react";
import React from "react";
import { Button, type ButtonProps } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { useToolbar } from "@/components/toolbars/toolbar-provider";
const StrikeThroughToolbar = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, onClick, children, ...props }, ref) => {
const { editor } = useToolbar();
return (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
"h-8 w-8",
editor?.isActive("strike") && "bg-accent",
className,
)}
onClick={(e) => {
editor?.chain().focus().toggleStrike().run();
onClick?.(e);
}}
disabled={!editor?.can().chain().focus().toggleStrike().run()}
ref={ref}
{...props}
>
{children || <Strikethrough className="h-4 w-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Strikethrough</span>
<span className="ml-1 text-xs text-gray-11">(cmd + shift + x)</span>
</TooltipContent>
</Tooltip>
);
},
);
StrikeThroughToolbar.displayName = "StrikeThroughToolbar";
export { StrikeThroughToolbar };