feat(i18n): Hebrew locale + full RTL support
This commit is contained in:
@@ -8,6 +8,7 @@ import Heading from "@tiptap/extension-heading";
|
||||
import Underline from "@tiptap/extension-underline";
|
||||
import Link from "@tiptap/extension-link";
|
||||
import TextAlign from "@tiptap/extension-text-align";
|
||||
import { TextDirection } from "@/components/email/text-direction";
|
||||
import { TextStyle } from "@tiptap/extension-text-style";
|
||||
import Color from "@tiptap/extension-color";
|
||||
import { ResizableImage } from "@/components/email/resizable-image";
|
||||
@@ -19,6 +20,7 @@ import { TableCell } from "@tiptap/extension-table-cell";
|
||||
import { QuotedHtml, serializeEditorContent } from "@/components/email/quoted-html";
|
||||
import { SignatureBlock } from "@/components/email/signature-block";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useSettingsStore } from "@/stores/settings-store";
|
||||
import {
|
||||
Bold,
|
||||
Italic,
|
||||
@@ -29,6 +31,7 @@ import {
|
||||
AlignLeft,
|
||||
AlignCenter,
|
||||
AlignRight,
|
||||
ArrowLeftRight,
|
||||
Link as LinkIcon,
|
||||
Undo,
|
||||
Redo,
|
||||
@@ -183,6 +186,7 @@ export function RichTextEditor({
|
||||
hasError,
|
||||
onEditorReady,
|
||||
}: RichTextEditorProps) {
|
||||
const rtlEditingSupport = useSettingsStore((st) => st.rtlEditingSupport);
|
||||
const onImageUploadRef = React.useRef(onImageUpload);
|
||||
onImageUploadRef.current = onImageUpload;
|
||||
const onEditorReadyRef = React.useRef(onEditorReady);
|
||||
@@ -240,6 +244,7 @@ export function RichTextEditor({
|
||||
// rich/branded signatures keep their inline styling in the editor and
|
||||
// in the sent mail (see signature-block.ts).
|
||||
SignatureBlock,
|
||||
TextDirection,
|
||||
],
|
||||
content,
|
||||
editorProps: {
|
||||
@@ -454,6 +459,22 @@ export function RichTextEditor({
|
||||
<AlignRight className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
|
||||
{rtlEditingSupport && (
|
||||
<ToolbarButton
|
||||
active={
|
||||
(editor.getAttributes("paragraph").dir || editor.getAttributes("heading").dir) === "rtl"
|
||||
}
|
||||
onClick={() => {
|
||||
const cur =
|
||||
editor.getAttributes("paragraph").dir || editor.getAttributes("heading").dir;
|
||||
editor.chain().focus().setTextDirection(cur === "rtl" ? "ltr" : "rtl").run();
|
||||
}}
|
||||
title="Text direction (RTL/LTR)"
|
||||
>
|
||||
<ArrowLeftRight className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
)}
|
||||
|
||||
<ToolbarSeparator />
|
||||
|
||||
<ToolbarButton
|
||||
@@ -478,28 +499,28 @@ export function RichTextEditor({
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-left"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-start"
|
||||
onClick={() => { editor.chain().focus().addRowBefore().run(); setTableMenuOpen(false); }}
|
||||
>
|
||||
<Rows3 className="w-4 h-4" /> Add row above
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-left"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-start"
|
||||
onClick={() => { editor.chain().focus().addRowAfter().run(); setTableMenuOpen(false); }}
|
||||
>
|
||||
<Rows3 className="w-4 h-4" /> Add row below
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-left"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-start"
|
||||
onClick={() => { editor.chain().focus().addColumnBefore().run(); setTableMenuOpen(false); }}
|
||||
>
|
||||
<Columns3 className="w-4 h-4" /> Add column before
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-left"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-start"
|
||||
onClick={() => { editor.chain().focus().addColumnAfter().run(); setTableMenuOpen(false); }}
|
||||
>
|
||||
<Columns3 className="w-4 h-4" /> Add column after
|
||||
@@ -507,21 +528,21 @@ export function RichTextEditor({
|
||||
<div className="h-px bg-border my-1" />
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-left"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-start"
|
||||
onClick={() => { editor.chain().focus().deleteRow().run(); setTableMenuOpen(false); }}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" /> Delete row
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-left"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-start"
|
||||
onClick={() => { editor.chain().focus().deleteColumn().run(); setTableMenuOpen(false); }}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" /> Delete column
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-left"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-start"
|
||||
onClick={() => { editor.chain().focus().toggleHeaderRow().run(); setTableMenuOpen(false); }}
|
||||
>
|
||||
<Rows3 className="w-4 h-4" /> Toggle header row
|
||||
@@ -529,7 +550,7 @@ export function RichTextEditor({
|
||||
<div className="h-px bg-border my-1" />
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-left text-red-600 dark:text-red-400"
|
||||
className="flex items-center gap-2 px-2 py-1.5 text-sm rounded hover:bg-accent text-start text-red-600 dark:text-red-400"
|
||||
onClick={() => { editor.chain().focus().deleteTable().run(); setTableMenuOpen(false); }}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" /> Delete table
|
||||
|
||||
Reference in New Issue
Block a user