diff --git a/web/RichText.tsx b/web/RichText.tsx index 5322f7b..697201f 100644 --- a/web/RichText.tsx +++ b/web/RichText.tsx @@ -5,6 +5,7 @@ import Link from '@tiptap/extension-link'; import TextAlign from '@tiptap/extension-text-align'; import { AlignCenter, + AlignJustify, AlignLeft, AlignRight, Bold, @@ -30,7 +31,7 @@ import { * * ── The toolbar is what the site can actually render ── * - * Bold, italic, strike, a heading, two lists, three alignments, a link. Not because tiptap cannot do + * Bold, italic, strike, a heading, two lists, four alignments, a link. Not because tiptap cannot do * more, but because anything offered here that the site's stylesheet has no rule for produces copy that * looks right while editing and wrong when published — the worst kind of editor, since the person only * finds out after saying it is done. @@ -75,6 +76,19 @@ const Tool = ({ ); +/** + * The alignments the toolbar offers. + * + * The same four the site's sanitiser accepts — ALIGN_CLASSES in src/rich-text.ts. A fifth offered here + * would be stripped on save, silently, leaving somebody pressing a button that appears to do nothing. + */ +const ALIGNMENTS = [ + { value: 'left' as const, Icon: AlignLeft }, + { value: 'center' as const, Icon: AlignCenter }, + { value: 'right' as const, Icon: AlignRight }, + { value: 'justify' as const, Icon: AlignJustify }, +]; + const Toolbar = ({ editor }: { editor: Editor }) => (
editor.chain().focus().toggleBold().run()} active={editor.isActive('bold')}> @@ -117,20 +131,21 @@ const Toolbar = ({ editor }: { editor: Editor }) => ( - {(['left', 'center', 'right'] as const).map((align) => ( + {/* + Four alignments, justify included. + + The site has always been able to render it: `rt-justify` is in the sanitiser's allowlist and + styles.css gives it `text-align: justify` with `hyphens: auto` — hyphenation being what stops + justified text opening rivers of white space between words. Only the toolbar was missing. + */} + {ALIGNMENTS.map(({ value, Icon }) => ( editor.chain().focus().setTextAlign(align).run()} - active={editor.isActive({ textAlign: align })} + key={value} + label={`Align ${value}`} + onClick={() => editor.chain().focus().setTextAlign(value).run()} + active={editor.isActive({ textAlign: value })} > - {align === 'left' ? ( - - ) : align === 'center' ? ( - - ) : ( - - )} + ))}