mirror of
https://github.com/Mail-0/Zero.git
synced 2026-03-03 02:27:00 +00:00
Ran oxc (https://oxc.rs/docs/guide/usage/linter.html#vscode-extension) and fixed all the issues that came up, set it up to run as a PR check and added steps to the README.md asking users to use it. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced JavaScript linting using oxlint in development guidelines and CI workflow for improved code quality. * Added oxlint configuration and dependencies to the project. * **Bug Fixes** * Improved error logging in various components and utilities for better debugging. * Enhanced React list rendering by updating keys to use unique values instead of array indices, reducing rendering issues. * Replaced browser alerts with toast notifications for a smoother user experience. * **Refactor** * Simplified component logic and state management by removing unused code, imports, props, and components across multiple files. * Updated function and component signatures for clarity and maintainability. * Improved efficiency of certain operations by switching from arrays to sets for membership checks. * **Chores** * Cleaned up and reorganized import statements throughout the codebase. * Removed deprecated files, components, and middleware to streamline the codebase. * **Documentation** * Updated contribution guidelines to include linting requirements for code submissions. * **Style** * Minor formatting and readability improvements in JSX and code structure. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
243 lines
9.6 KiB
TypeScript
243 lines
9.6 KiB
TypeScript
import {
|
|
Bold,
|
|
Italic,
|
|
Strikethrough,
|
|
Underline,
|
|
List,
|
|
ListOrdered,
|
|
Heading1,
|
|
Heading2,
|
|
Heading3,
|
|
Undo2,
|
|
Redo2,
|
|
TextQuote,
|
|
} from 'lucide-react';
|
|
|
|
import { TooltipContent, TooltipProvider, TooltipTrigger, Tooltip } from '../ui/tooltip';
|
|
import { Separator } from '@/components/ui/separator';
|
|
import { Button } from '../ui/button';
|
|
|
|
import type { Editor } from '@tiptap/core';
|
|
import { m } from '@/paraglide/messages';
|
|
|
|
export const Toolbar = ({ editor }: { editor: Editor | null }) => {
|
|
if (!editor) return null;
|
|
|
|
return (
|
|
<div className="flex gap-2 rounded border p-2 text-sm">
|
|
<TooltipProvider>
|
|
<div className="control-group overflow-x-auto">
|
|
<div className="button-group ml-0 flex flex-wrap gap-1">
|
|
<div className="mr-2 flex items-center gap-1">
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().undo().run()}
|
|
disabled={!editor.can().undo()}
|
|
className={`bg-muted disabled:bg-background h-auto w-auto rounded p-1.5`}
|
|
>
|
|
<Undo2 className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>Undo</TooltipContent>
|
|
</Tooltip>
|
|
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().redo().run()}
|
|
disabled={!editor.can().redo()}
|
|
className={`bg-muted disabled:bg-background h-auto w-auto rounded p-1.5`}
|
|
>
|
|
<Redo2 className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>Redo</TooltipContent>
|
|
</Tooltip>
|
|
</div>
|
|
|
|
<div className="mr-2 flex items-center gap-1">
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('heading', { level: 1 }) ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<Heading1 className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>H1</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('heading', { level: 2 }) ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<Heading2 className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>H2</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('heading', { level: 3 }) ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<Heading3 className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>H3</TooltipContent>
|
|
</Tooltip>
|
|
</div>
|
|
<Separator orientation="vertical" className="relative right-1 top-0.5 h-6" />
|
|
<div className="mr-2 flex items-center gap-1">
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleBold().run()}
|
|
disabled={!editor.can().chain().focus().toggleBold().run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('bold') ? 'bg-muted font-medium' : 'bg-background'}`}
|
|
title="Bold"
|
|
>
|
|
<Bold className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>{m['pages.createEmail.editor.menuBar.bold']()}</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleItalic().run()}
|
|
disabled={!editor.can().chain().focus().toggleItalic().run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('italic') ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<Italic className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>{m['pages.createEmail.editor.menuBar.italic']()}</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleStrike().run()}
|
|
disabled={!editor.can().chain().focus().toggleStrike().run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('strike') ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<Strikethrough className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
{m['pages.createEmail.editor.menuBar.strikethrough']()}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleUnderline().run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('underline') ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<Underline className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>{m['pages.createEmail.editor.menuBar.underline']()}</TooltipContent>
|
|
</Tooltip>
|
|
</div>
|
|
|
|
<Separator orientation="vertical" className="relative right-1 top-0.5 h-6" />
|
|
|
|
<div className="flex items-center gap-1">
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleBulletList().run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('bulletList') ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<List className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
{m['pages.createEmail.editor.menuBar.bulletList']()}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleOrderedList().run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('orderedList') ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<ListOrdered className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
{m['pages.createEmail.editor.menuBar.orderedList']()}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
type="button"
|
|
tabIndex={-1}
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => editor.chain().focus().toggleBlockquote().run()}
|
|
className={`h-auto w-auto rounded p-1.5 ${editor.isActive('blockquote') ? 'bg-muted' : 'bg-background'}`}
|
|
>
|
|
<TextQuote className="h-4 w-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>Block Quote</TooltipContent>
|
|
</Tooltip>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</TooltipProvider>
|
|
</div>
|
|
);
|
|
};
|