- {selectionItems.map((item) => (
+ {items.map((item) => (
@@ -32,6 +53,7 @@ export const MenuBar = () => {
size={"icon"}
onClick={() => editor.chain().focus().undo().run()}
disabled={!editor.can().chain().focus().undo().run()}
+ {...buttonProps}
>
@@ -40,6 +62,7 @@ export const MenuBar = () => {
size={"icon"}
onClick={() => editor.chain().focus().redo().run()}
disabled={!editor.can().chain().focus().redo().run()}
+ {...buttonProps}
>
diff --git a/src/components/editor/selector/selection-items.tsx b/src/components/editor/selector/selection-items.tsx
index 004ff60..eee4a16 100644
--- a/src/components/editor/selector/selection-items.tsx
+++ b/src/components/editor/selector/selection-items.tsx
@@ -26,7 +26,7 @@ export type SelectorItem = {
canRun?: (editor: EditorInstance) => boolean;
};
-export const selectionItems: SelectorItem[] = [
+export const inlineSelectorItems: SelectorItem[] = [
{
name: "bold",
isActive: (editor) => editor.isActive("bold"),
@@ -59,6 +59,10 @@ export const selectionItems: SelectorItem[] = [
inline: true,
canRun: (editor) => !editor.can().chain().focus().toggleStrike().run(),
},
+];
+
+export const selectionItems: SelectorItem[] = [
+ ...inlineSelectorItems,
// blocks
{
diff --git a/src/components/editor/styles/editor.css b/src/components/editor/styles/editor.css
new file mode 100644
index 0000000..6c1fecb
--- /dev/null
+++ b/src/components/editor/styles/editor.css
@@ -0,0 +1,49 @@
+@import url("./shared.css");
+
+.ProseMirror {
+ /* min-height: 100vh;
+ width: 100%; */
+}
+
+.tiptap ul li p,
+.tiptap ol li p {
+ margin: 0.75rem 0;
+}
+
+ul[data-type="taskList"] li > label input[type="checkbox"] {
+ @apply size-4 border border-border bg-muted;
+ -webkit-appearance: none;
+ appearance: none;
+ margin: 0;
+ margin-bottom: 0.75rem;
+ margin-top: 0.75rem;
+ cursor: pointer;
+ position: relative;
+ transform: translateY(0.17rem);
+ display: grid;
+ border-radius: 0.25rem;
+ place-content: center;
+}
+
+ul[data-type="taskList"] li > label input[type="checkbox"]::before {
+ content: "";
+ width: 0.65em;
+ height: 0.65em;
+ transform: scale(0);
+ transition: 120ms transform ease-in-out;
+ box-shadow: inset 1em 1em;
+ transform-origin: center;
+ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
+}
+ul[data-type="taskList"] li > label input[type="checkbox"]:checked::before {
+ transform: scale(1);
+}
+ul[data-type="taskList"] li[data-checked="true"] > div > p {
+ @apply text-foreground/75;
+ text-decoration: line-through;
+ text-decoration-thickness: 2px;
+}
+
+img {
+ @apply rounded-md;
+}
diff --git a/src/components/editor/styles.css b/src/components/editor/styles/shared.css
similarity index 77%
rename from src/components/editor/styles.css
rename to src/components/editor/styles/shared.css
index 1b998b4..eb44195 100644
--- a/src/components/editor/styles.css
+++ b/src/components/editor/styles/shared.css
@@ -3,54 +3,10 @@
margin-top: 0;
}
-.ProseMirror {
- min-height: 100vh;
- width: 100%;
-}
-
.ProseMirror:focus {
outline: none;
}
-.tiptap ul li p,
-.tiptap ol li p {
- margin: 0.75rem 0;
-}
-
-ul[data-type="taskList"] li > label input[type="checkbox"] {
- @apply size-4 border border-border bg-muted;
- -webkit-appearance: none;
- appearance: none;
- margin: 0;
- margin-bottom: 0.75rem;
- margin-top: 0.75rem;
- cursor: pointer;
- position: relative;
- transform: translateY(0.17rem);
- display: grid;
- border-radius: 0.25rem;
- place-content: center;
-}
-
-ul[data-type="taskList"] li > label input[type="checkbox"]::before {
- content: "";
- width: 0.65em;
- height: 0.65em;
- transform: scale(0);
- transition: 120ms transform ease-in-out;
- box-shadow: inset 1em 1em;
- transform-origin: center;
- clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
-}
-ul[data-type="taskList"] li > label input[type="checkbox"]:checked::before {
- transform: scale(1);
-}
-ul[data-type="taskList"] li[data-checked="true"] > div > p {
- @apply text-foreground/75;
- text-decoration: line-through;
- text-decoration-thickness: 2px;
-}
-
/* Heading styles */
.tiptap h1,
.tiptap h2,
@@ -97,10 +53,6 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
transition-duration: 0s;
}
-img {
- @apply rounded-md;
-}
-
.ProseMirror:not(.dragging) .ProseMirror-selectednode {
outline: none !important;
background-color: var(--novel-highlight-blue);
diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx
index 57760f2..f69596f 100644
--- a/src/components/ui/alert-dialog.tsx
+++ b/src/components/ui/alert-dialog.tsx
@@ -1,16 +1,16 @@
-"use client"
+"use client";
-import * as React from "react"
-import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
+import * as React from "react";
+import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
-import { cn } from "@/lib/utils"
-import { buttonVariants } from "@/components/ui/button"
+import { cn } from "@/lib/utils";
+import { buttonVariants } from "@/components/ui/button";
-const AlertDialog = AlertDialogPrimitive.Root
+const AlertDialog = AlertDialogPrimitive.Root;
-const AlertDialogTrigger = AlertDialogPrimitive.Trigger
+const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
-const AlertDialogPortal = AlertDialogPrimitive.Portal
+const AlertDialogPortal = AlertDialogPrimitive.Portal;
const AlertDialogOverlay = React.forwardRef<
React.ElementRef
,
@@ -19,13 +19,13 @@ const AlertDialogOverlay = React.forwardRef<
-))
-AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
+));
+AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
const AlertDialogContent = React.forwardRef<
React.ElementRef,
@@ -37,13 +37,13 @@ const AlertDialogContent = React.forwardRef<
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
- className
+ className,
)}
{...props}
/>
-))
-AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
+));
+AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
const AlertDialogHeader = ({
className,
@@ -52,12 +52,12 @@ const AlertDialogHeader = ({
-)
-AlertDialogHeader.displayName = "AlertDialogHeader"
+);
+AlertDialogHeader.displayName = "AlertDialogHeader";
const AlertDialogFooter = ({
className,
@@ -66,12 +66,12 @@ const AlertDialogFooter = ({
-)
-AlertDialogFooter.displayName = "AlertDialogFooter"
+);
+AlertDialogFooter.displayName = "AlertDialogFooter";
const AlertDialogTitle = React.forwardRef<
React.ElementRef,
@@ -82,8 +82,8 @@ const AlertDialogTitle = React.forwardRef<
className={cn("text-lg font-semibold", className)}
{...props}
/>
-))
-AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
+));
+AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
const AlertDialogDescription = React.forwardRef<
React.ElementRef,
@@ -94,9 +94,9 @@ const AlertDialogDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
-))
+));
AlertDialogDescription.displayName =
- AlertDialogPrimitive.Description.displayName
+ AlertDialogPrimitive.Description.displayName;
const AlertDialogAction = React.forwardRef<
React.ElementRef,
@@ -107,8 +107,8 @@ const AlertDialogAction = React.forwardRef<
className={cn(buttonVariants(), className)}
{...props}
/>
-))
-AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
+));
+AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
const AlertDialogCancel = React.forwardRef<
React.ElementRef,
@@ -119,12 +119,12 @@ const AlertDialogCancel = React.forwardRef<
className={cn(
buttonVariants({ variant: "outline" }),
"mt-2 sm:mt-0",
- className
+ className,
)}
{...props}
/>
-))
-AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
+));
+AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
export {
AlertDialog,
@@ -138,4 +138,4 @@ export {
AlertDialogDescription,
AlertDialogAction,
AlertDialogCancel,
-}
+};
diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx
index 5afd41d..1df0436 100644
--- a/src/components/ui/alert.tsx
+++ b/src/components/ui/alert.tsx
@@ -1,7 +1,7 @@
-import * as React from "react"
-import { cva, type VariantProps } from "class-variance-authority"
+import * as React from "react";
+import { cva, type VariantProps } from "class-variance-authority";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const alertVariants = cva(
"relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
@@ -16,8 +16,8 @@ const alertVariants = cva(
defaultVariants: {
variant: "default",
},
- }
-)
+ },
+);
const Alert = React.forwardRef<
HTMLDivElement,
@@ -29,8 +29,8 @@ const Alert = React.forwardRef<
className={cn(alertVariants({ variant }), className)}
{...props}
/>
-))
-Alert.displayName = "Alert"
+));
+Alert.displayName = "Alert";
const AlertTitle = React.forwardRef<
HTMLParagraphElement,
@@ -41,8 +41,8 @@ const AlertTitle = React.forwardRef<
className={cn("mb-1 font-medium leading-none tracking-tight", className)}
{...props}
/>
-))
-AlertTitle.displayName = "AlertTitle"
+));
+AlertTitle.displayName = "AlertTitle";
const AlertDescription = React.forwardRef<
HTMLParagraphElement,
@@ -53,7 +53,7 @@ const AlertDescription = React.forwardRef<
className={cn("text-sm [&_p]:leading-relaxed", className)}
{...props}
/>
-))
-AlertDescription.displayName = "AlertDescription"
+));
+AlertDescription.displayName = "AlertDescription";
-export { Alert, AlertTitle, AlertDescription }
+export { Alert, AlertTitle, AlertDescription };
diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx
index 51e507b..09cd14d 100644
--- a/src/components/ui/avatar.tsx
+++ b/src/components/ui/avatar.tsx
@@ -1,9 +1,9 @@
-"use client"
+"use client";
-import * as React from "react"
-import * as AvatarPrimitive from "@radix-ui/react-avatar"
+import * as React from "react";
+import * as AvatarPrimitive from "@radix-ui/react-avatar";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const Avatar = React.forwardRef<
React.ElementRef,
@@ -13,12 +13,12 @@ const Avatar = React.forwardRef<
ref={ref}
className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
- className
+ className,
)}
{...props}
/>
-))
-Avatar.displayName = AvatarPrimitive.Root.displayName
+));
+Avatar.displayName = AvatarPrimitive.Root.displayName;
const AvatarImage = React.forwardRef<
React.ElementRef,
@@ -29,8 +29,8 @@ const AvatarImage = React.forwardRef<
className={cn("aspect-square h-full w-full", className)}
{...props}
/>
-))
-AvatarImage.displayName = AvatarPrimitive.Image.displayName
+));
+AvatarImage.displayName = AvatarPrimitive.Image.displayName;
const AvatarFallback = React.forwardRef<
React.ElementRef,
@@ -40,11 +40,11 @@ const AvatarFallback = React.forwardRef<
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
- className
+ className,
)}
{...props}
/>
-))
-AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
+));
+AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
-export { Avatar, AvatarImage, AvatarFallback }
+export { Avatar, AvatarImage, AvatarFallback };
diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx
index e87d62b..f795980 100644
--- a/src/components/ui/badge.tsx
+++ b/src/components/ui/badge.tsx
@@ -1,7 +1,7 @@
-import * as React from "react"
-import { cva, type VariantProps } from "class-variance-authority"
+import * as React from "react";
+import { cva, type VariantProps } from "class-variance-authority";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const badgeVariants = cva(
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
@@ -20,8 +20,8 @@ const badgeVariants = cva(
defaultVariants: {
variant: "default",
},
- }
-)
+ },
+);
export interface BadgeProps
extends React.HTMLAttributes,
@@ -30,7 +30,7 @@ export interface BadgeProps
function Badge({ className, variant, ...props }: BadgeProps) {
return (
- )
+ );
}
-export { Badge, badgeVariants }
+export { Badge, badgeVariants };
diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx
index 60e6c96..8614cd7 100644
--- a/src/components/ui/breadcrumb.tsx
+++ b/src/components/ui/breadcrumb.tsx
@@ -1,16 +1,16 @@
-import * as React from "react"
-import { Slot } from "@radix-ui/react-slot"
-import { ChevronRight, MoreHorizontal } from "lucide-react"
+import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { ChevronRight, MoreHorizontal } from "lucide-react";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const Breadcrumb = React.forwardRef<
HTMLElement,
React.ComponentPropsWithoutRef<"nav"> & {
- separator?: React.ReactNode
+ separator?: React.ReactNode;
}
->(({ ...props }, ref) => )
-Breadcrumb.displayName = "Breadcrumb"
+>(({ ...props }, ref) => );
+Breadcrumb.displayName = "Breadcrumb";
const BreadcrumbList = React.forwardRef<
HTMLOListElement,
@@ -20,12 +20,12 @@ const BreadcrumbList = React.forwardRef<
ref={ref}
className={cn(
"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
- className
+ className,
)}
{...props}
/>
-))
-BreadcrumbList.displayName = "BreadcrumbList"
+));
+BreadcrumbList.displayName = "BreadcrumbList";
const BreadcrumbItem = React.forwardRef<
HTMLLIElement,
@@ -36,16 +36,16 @@ const BreadcrumbItem = React.forwardRef<
className={cn("inline-flex items-center gap-1.5", className)}
{...props}
/>
-))
-BreadcrumbItem.displayName = "BreadcrumbItem"
+));
+BreadcrumbItem.displayName = "BreadcrumbItem";
const BreadcrumbLink = React.forwardRef<
HTMLAnchorElement,
React.ComponentPropsWithoutRef<"a"> & {
- asChild?: boolean
+ asChild?: boolean;
}
>(({ asChild, className, ...props }, ref) => {
- const Comp = asChild ? Slot : "a"
+ const Comp = asChild ? Slot : "a";
return (
- )
-})
-BreadcrumbLink.displayName = "BreadcrumbLink"
+ );
+});
+BreadcrumbLink.displayName = "BreadcrumbLink";
const BreadcrumbPage = React.forwardRef<
HTMLSpanElement,
@@ -69,8 +69,8 @@ const BreadcrumbPage = React.forwardRef<
className={cn("font-normal text-foreground", className)}
{...props}
/>
-))
-BreadcrumbPage.displayName = "BreadcrumbPage"
+));
+BreadcrumbPage.displayName = "BreadcrumbPage";
const BreadcrumbSeparator = ({
children,
@@ -80,13 +80,13 @@ const BreadcrumbSeparator = ({
svg]:w-3.5 [&>svg]:h-3.5", className)}
+ className={cn("[&>svg]:h-3.5 [&>svg]:w-3.5", className)}
{...props}
>
{children ?? }
-)
-BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
+);
+BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
const BreadcrumbEllipsis = ({
className,
@@ -101,8 +101,8 @@ const BreadcrumbEllipsis = ({
More
-)
-BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
+);
+BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
export {
Breadcrumb,
@@ -112,4 +112,4 @@ export {
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis,
-}
+};
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 65d4fcd..d09a695 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -1,8 +1,8 @@
-import * as React from "react"
-import { Slot } from "@radix-ui/react-slot"
-import { cva, type VariantProps } from "class-variance-authority"
+import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { cva, type VariantProps } from "class-variance-authority";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
@@ -31,27 +31,27 @@ const buttonVariants = cva(
variant: "default",
size: "default",
},
- }
-)
+ },
+);
export interface ButtonProps
extends React.ButtonHTMLAttributes,
VariantProps {
- asChild?: boolean
+ asChild?: boolean;
}
const Button = React.forwardRef(
({ className, variant, size, asChild = false, ...props }, ref) => {
- const Comp = asChild ? Slot : "button"
+ const Comp = asChild ? Slot : "button";
return (
- )
- }
-)
-Button.displayName = "Button"
+ );
+ },
+);
+Button.displayName = "Button";
-export { Button, buttonVariants }
+export { Button, buttonVariants };
diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx
index c6fdd07..89148ed 100644
--- a/src/components/ui/checkbox.tsx
+++ b/src/components/ui/checkbox.tsx
@@ -1,10 +1,10 @@
-"use client"
+"use client";
-import * as React from "react"
-import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
-import { Check } from "lucide-react"
+import * as React from "react";
+import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
+import { Check } from "lucide-react";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const Checkbox = React.forwardRef<
React.ElementRef,
@@ -14,7 +14,7 @@ const Checkbox = React.forwardRef<
ref={ref}
className={cn(
"peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
- className
+ className,
)}
{...props}
>
@@ -24,7 +24,7 @@ const Checkbox = React.forwardRef<
-))
-Checkbox.displayName = CheckboxPrimitive.Root.displayName
+));
+Checkbox.displayName = CheckboxPrimitive.Root.displayName;
-export { Checkbox }
+export { Checkbox };
diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx
index 2cecd91..7657047 100644
--- a/src/components/ui/command.tsx
+++ b/src/components/ui/command.tsx
@@ -1,12 +1,12 @@
-"use client"
+"use client";
-import * as React from "react"
-import { type DialogProps } from "@radix-ui/react-dialog"
-import { Command as CommandPrimitive } from "cmdk"
-import { Search } from "lucide-react"
+import * as React from "react";
+import { type DialogProps } from "@radix-ui/react-dialog";
+import { Command as CommandPrimitive } from "cmdk";
+import { Search } from "lucide-react";
-import { cn } from "@/lib/utils"
-import { Dialog, DialogContent } from "@/components/ui/dialog"
+import { cn } from "@/lib/utils";
+import { Dialog, DialogContent } from "@/components/ui/dialog";
const Command = React.forwardRef<
React.ElementRef,
@@ -16,12 +16,12 @@ const Command = React.forwardRef<
ref={ref}
className={cn(
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
- className
+ className,
)}
{...props}
/>
-))
-Command.displayName = CommandPrimitive.displayName
+));
+Command.displayName = CommandPrimitive.displayName;
const CommandDialog = ({ children, ...props }: DialogProps) => {
return (
@@ -32,8 +32,8 @@ const CommandDialog = ({ children, ...props }: DialogProps) => {
- )
-}
+ );
+};
const CommandInput = React.forwardRef<
React.ElementRef,
@@ -45,14 +45,14 @@ const CommandInput = React.forwardRef<
ref={ref}
className={cn(
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
- className
+ className,
)}
{...props}
/>
-))
+));
-CommandInput.displayName = CommandPrimitive.Input.displayName
+CommandInput.displayName = CommandPrimitive.Input.displayName;
const CommandList = React.forwardRef<
React.ElementRef