group | package | title | order | slug | description | props | import | source | docs | installation | license | styles | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Other packages |
@mantine/tiptap |
Rich text editor |
1 |
/others/tiptap/ |
Tiptap based rich text editor |
|
import { RichTextEditor } from '@mantine/tiptap'; |
mantine-tiptap/src |
others/tiptap.mdx |
@mantine/tiptap |
MIT |
|
import { TipTapDemos } from '@mantine/demos';
Install with yarn:
yarn add @mantine/tiptap @mantine/core @mantine/hooks @tabler/icons @tiptap/react @tiptap/extension-link @tiptap/starter-kit
Install with npm:
npm install @mantine/tiptap @mantine/core @mantine/hooks @tabler/icons @tiptap/react @tiptap/extension-link @tiptap/starter-kit
@mantine/tiptap
provides a UI for Tiptap. RichTextEditor
component
works with Editor instance of tiptap.
This means that you have full control over the editor state and configuration
with useEditor hook.
In other words, RichTextEditor
component does not manage state for you,
controls just execute operations on the Editor
instance. If you want to
implement something that is related to state or component value (e.g. controlled mode, value transforms to HTML/Markdown),
you should look for documentation on tiptap.dev website.
Some controls require installation of additional Tiptap extensions.
For example, if you want to use RichTextEditor.Underline
control, you will need to install @tiptap/extension-underline
package:
yarn add @tiptap/extension-underline
npm install @tiptap/extension-underline
Included with @tiptap/starter-kit
(should be installed by default):
RichTextEditor.H1
RichTextEditor.H2
RichTextEditor.H3
RichTextEditor.H4
RichTextEditor.H5
RichTextEditor.H6
RichTextEditor.BulletList
RichTextEditor.OrderedList
RichTextEditor.Bold
RichTextEditor.Italic
RichTextEditor.Strikethrough
RichTextEditor.ClearFormatting
RichTextEditor.Blockquote
RichTextEditor.Code
RichTextEditor.CodeBlock
RichTextEditor.Hr
Controls that require @tiptap/extension-link extension:
RichTextEditor.Link
RichTextEditor.Unlink
Controls that require @tiptap/extension-text-align extension:
RichTextEditor.AlignLeft
RichTextEditor.AlignRight
RichTextEditor.AlignCenter
RichTextEditor.AlignJustify
Controls that require @tiptap/extension-color and @tiptap/extension-text-style extensions:
RichTextEditor.ColorPicker
RichTextEditor.Color
RichTextEditor.UnsetColor
Other controls with required extensions:
RichTextEditor.Underline
requires @tiptap/extension-underlineRichTextEditor.Superscript
requires @tiptap/extension-superscriptRichTextEditor.Subscript
requires @tiptap/extension-subscriptRichTextEditor.Highlight
requires @tiptap/extension-highlight
@mantine/tiptap
provides custom Link
extension that is required to be used instead of
@tiptap/extension-link
in order for Ctrl + K
keyboard shortcut to work:
// Use Link extension exported from the @mantine/tiptap package
import { RichTextEditor, Link } from '@mantine/tiptap';
import { useEditor } from '@tiptap/react';
function Demo() {
const editor = useEditor({
extensions: [
Link,
// ... other extensions
],
});
return <RichTextEditor editor={editor}>{/* content */}</RichTextEditor>;
}
To use text color you will need to install additional packages:
yarn add @tiptap/extension-color @tiptap/extension-text-style
npm install @tiptap/extension-color @tiptap/extension-text-style
You can use the following controls to change text color:
RichTextEditor.ColorPicker
– allows to pick colors from given predefined color swatches and with ColorPicker componentRichTextEditor.Color
– allows to apply given color with one clickRichTextEditor.UnsetColor
– clears color styles
To use code highlight you will need to install additional packages:
yarn add lowlight @tiptap/extension-code-block-lowlight
npm install lowlight @tiptap/extension-code-block-lowlight
You can change code highlight styles using Styles API:
<Demo data={TipTapDemos.codeHighlightStyles} demoProps={{ toggle: true }} />
By default, RichTextEditor
renders content with TypographyStylesProvider and some additional styles.
You can disable these styles by setting withTypographyStyles={false}
:
import { RichTextEditor } from '@mantine/tiptap';
import { useEditor } from '@tiptap/react';
function Demo() {
const editor = useEditor({
extensions: [
// ... your extensions
],
});
return (
<RichTextEditor editor={editor} withTypographyStyles={false}>
{/* content */}
</RichTextEditor>
);
}
Then you will be able to add your own styles either with global styles or with Styles API:
// ...
<RichTextEditor
editor={editor}
withTypographyStyles={false}
styles={{
content: {
'& p': {
color: 'silver',
},
},
}}
>
{/* content */}
</RichTextEditor>
You can use BubbleMenu component
with any RichTextEditor
controls. Bubble menu will appear near a selection of text:
You can use FloatingMenu component
with any RichTextEditor
controls. Floating menu will appear in an empty line:
Set sticky
prop on RichTextEditor.Toolbar
component to make toolbar sticky,
control top
property with stickyOffset
. For example, on mantine.dev documentation
website there is a header with 60px
height, in this case we will need to
set stickyOffset={60}
to make sticky position correctly with fixed positioned element.
<Demo data={TipTapDemos.usage} demoProps={{ toggle: true }} />
Use useRichTextEditorContext
hook to get Editor from
the context. This hook can be used to create custom control or run any operations supported
by the Tiptap editor API.
import { useRichTextEditorContext } from '@mantine/tiptap';
import { Button } from '@mantine/core';
function Demo() {
const { editor } = useRichTextEditorContext();
return <Button onClick={() => editor?.chain().focus().toggleBold().run()}>Make bold</Button>;
}
Use RichTextEditor.Control
component to create custom controls. It supports all
props supported by button
element and has active
prop to indicate active state.
Note that you will need to set aria-label
attribute to make control visible for screen readers.
You can change icon of control by setting icon
prop. It accepts a component
that must handle size
prop:
RichTextEditor
supports changing labels for all controls with labels
prop:
import { RichTextEditor } from '@mantine/tiptap';
import { useEditor } from '@tiptap/react';
function Demo() {
const editor = useEditor({
extensions: [
// ... your extensions
],
});
return (
<RichTextEditor
editor={editor}
labels={{
boldControlLabel: 'Make text bold',
italicControlLabel: 'Make text bold',
// ...other labels
}}
>
{/* content */}
</RichTextEditor>
);
}
Most labels are used to add aria-label
and title
attributes to controls, some of the labels
can be a function that returns string. If you do not provide all labels, then they will be merged with
the default labels.
All available labels:
export interface RichTextEditorLabels {
/** RichTextEditor.Bold control aria-label */
boldControlLabel: string;
/** RichTextEditor.Italic control aria-label */
italicControlLabel: string;
/** RichTextEditor.Underline control aria-label */
underlineControlLabel: string;
/** RichTextEditor.Strike control aria-label */
strikeControlLabel: string;
/** RichTextEditor.ClearFormatting control aria-label */
clearFormattingControlLabel: string;
/** RichTextEditor.Link control aria-label */
linkControlLabel: string;
/** RichTextEditor.Unlink control aria-label */
unlinkControlLabel: string;
/** RichTextEditor.BulletList control aria-label */
bulletListControlLabel: string;
/** RichTextEditor.OrderedList control aria-label */
orderedListControlLabel: string;
/** RichTextEditor.H1 control aria-label */
h1ControlLabel: string;
/** RichTextEditor.H2 control aria-label */
h2ControlLabel: string;
/** RichTextEditor.H3 control aria-label */
h3ControlLabel: string;
/** RichTextEditor.H4 control aria-label */
h4ControlLabel: string;
/** RichTextEditor.H5 control aria-label */
h5ControlLabel: string;
/** RichTextEditor.H6 control aria-label */
h6ControlLabel: string;
/** RichTextEditor.Blockquote control aria-label */
blockquoteControlLabel: string;
/** RichTextEditor.AlignLeft control aria-label */
alignLeftControlLabel: string;
/** RichTextEditor.AlignCenter control aria-label */
alignCenterControlLabel: string;
/** RichTextEditor.AlignRight control aria-label */
alignRightControlLabel: string;
/** RichTextEditor.AlignJustify control aria-label */
alignJustifyControlLabel: string;
/** RichTextEditor.Code control aria-label */
codeControlLabel: string;
/** RichTextEditor.CodeBlock control aria-label */
codeBlockControlLabel: string;
/** RichTextEditor.Subscript control aria-label */
subscriptControlLabel: string;
/** RichTextEditor.Superscript control aria-label */
superscriptControlLabel: string;
/** RichTextEditor.ColorPicker control aria-label */
colorPickerControlLabel: string;
/** RichTextEditor.UnsetColor control aria-label */
unsetColorControlLabel: string;
/** RichTextEditor.Highlight control aria-label */
highlightControlLabel: string;
/** A function go get RichTextEditor.Color control aria-label based on color that control applies */
colorControlLabel(color: string): string;
/** aria-label for link editor url input */
linkEditorInputLabel: string;
/** placeholder for link editor url input */
linkEditorInputPlaceholder: string;
/** Content of external button tooltip in link editor when the link was chosen to open in a new tab */
linkEditorExternalLink: string;
/** Content of external button tooltip in link editor when the link was chosen to open in the same tab */
linkEditorInternalLink: string;
/** Save button content in link editor */
linkEditorSave: string;
/** Cancel button title text in color picker control */
colorPickerCancel: string;
/** Clear button title text in color picker control */
colorPickerClear: string;
/** Color picker button title text in color picker control */
colorPickerColorPicker: string;
/** Palette button title text in color picker control */
colorPickerPalette: string;
/** Save button title text in color picker control */
colorPickerSave: string;
/** aria-label for color palette colors */
colorPickerColorLabel(color: string): string;
}
Default labels (can be imported from @mantine/tiptap
package):
export const DEFAULT_LABELS: RichTextEditorLabels = {
// Controls labels
linkControlLabel: 'Link',
colorPickerControlLabel: 'Text color',
highlightControlLabel: 'Highlight text',
colorControlLabel: (color) => `Set text color ${color}`,
boldControlLabel: 'Bold',
italicControlLabel: 'Italic',
underlineControlLabel: 'Underline',
strikeControlLabel: 'Strikethrough',
clearFormattingControlLabel: 'Clear formatting',
unlinkControlLabel: 'Remove link',
bulletListControlLabel: 'Bullet list',
orderedListControlLabel: 'Ordered list',
h1ControlLabel: 'Heading 1',
h2ControlLabel: 'Heading 2',
h3ControlLabel: 'Heading 3',
h4ControlLabel: 'Heading 4',
h5ControlLabel: 'Heading 5',
h6ControlLabel: 'Heading 6',
blockquoteControlLabel: 'Blockquote',
alignLeftControlLabel: 'Align text: left',
alignCenterControlLabel: 'Align text: center',
alignRightControlLabel: 'Align text: right',
alignJustifyControlLabel: 'Align text: justify',
codeControlLabel: 'Code',
codeBlockControlLabel: 'Code block',
subscriptControlLabel: 'Subscript',
superscriptControlLabel: 'Superscript',
unsetColorControlLabel: 'Unset color',
// Link editor
linkEditorInputLabel: 'Enter URL',
linkEditorInputPlaceholder: 'https://example.com/',
linkEditorExternalLink: 'Open link in a new tab',
linkEditorInternalLink: 'Open link in the same tab',
linkEditorSave: 'Save',
// Color picker control
colorPickerCancel: 'Cancel',
colorPickerClear: 'Clear color',
colorPickerColorPicker: 'Color picker',
colorPickerPalette: 'Color palette',
colorPickerSave: 'Save',
colorPickerColorLabel: (color) => `Set text color ${color}`,
};