README
pat-tiptap
Documentation
Pattern implementation of the tiptap editor.
See:
When invoked on an element, the element is hidden and it's value is synchronized with updates in the editor.
Usage
Invokation on a textarea element
<textarea
name="text"
class="pat-tiptap">
<h1>hello</h1>
<p>I am some text content</p>
</textarea>
Invocation on a div element
<div
name="text"
class="pat-tiptap"
contenteditable>
<h1>hello</h1>
<p>I am some text content</p>
</div>
Building the user interface
The tiptap editor comes without a user interface, as does this Patternslib integration of the tiptap editor. You can build the user interface entirely using HTML and the Patterns concepts.
Adding a toolbar
Configure the options toolbar-external with a CSS selector pointing to the toolbar container:
<div id="tiptap-external-toolbar">
<button type="button" class="button-bold">Bold</button>
<button type="button" class="button-italic">Italic</button>
<button type="button" class="button-strike">Strike</button>
</div>
<textarea
name="text"
class="pat-tiptap"
data-pat-tiptap="
toolbar-external: #tiptap-external-toolbar
">
</textarea>
pat-tiptap is set up to listen to click events on HTML elements with specific classes. The classes are:
.button-blockquote.button-bold.button-code.button-code-block.button-heading-level-1.button-heading-level-2.button-heading-level-3.button-heading-level-4.button-heading-level-5.button-heading-level-6.button-horizontal-rule.button-italic.button-ordered-list.button-paragraph.button-redo.button-strike.button-table-add-column-left.button-table-add-column-right.button-table-add-row-above.button-table-add-row-below.button-table-create.button-table-header-cell.button-table-header-column.button-table-header-row.button-table-merge-cells.button-table-remove.button-table-remove-column.button-table-remove-row.button-undo.button-unordered-list
The following buttons need additional configuration to open an overlay with more user input options (See below):
.button-link.button-image.button-source.button-embed
If these buttons are not available the associated functionality is not loaded, not initialized and not available.
Adding a link overlay
The following button uses pat-modal to open a overlay, referenced by the CSS selector #modal-link in the same document.
Note: You can also load the modal contents from any URL.
<div id="tiptap-external-toolbar">
<a
class="button-link pat-modal"
href="#modal-link">Link</a>
</div>
This is the DOM structure with the overlay:
<div id="modal-link" hidden>
<form class="link-panel">
<label>
Link URL:
<input type="text" name="tiptap-href"/>
</label>
<label>
Link Text:
<input type="text" name="tiptap-text"/>
</label>
<label>
Open in new window:
<input type="checkbox" name="tiptap-target" value="_blank" />
</label>
<button class="close-panel" type="button" name="tiptap-confirm">submit</button>
<button class="close-panel" type="button" name="tiptap-remove">remove link</button>
</form>
</div>
The input[name=tiptap-href] is the only input element necessary.
You can use these elements with these names:
tiptap-href: Link URL.tiptap-text: Link text.tiptap-target: Indicates if the link should be opened in a new tab. Thevalueneeds to be set to the target name in which the link should be opened.tiptap-confirm: To save the changes back to the editor.tiptap-remove: To remove the link.
You also need to configure pat-tiptap with the link-panel option which points to the form element in the overlay.
pat-tiptap uses a MutationObserver to check for changes in the overlay's DOM structure and re-initializes the functionality once the DOM structure changes.
This way, you can use pat-inject, pat-tabs, pat-stacks or the like which changes the overlays content and always get the link panel form initlized.
This is the related pat-tiptap config:
data-pat-tiptap="
link-panel: #pat-modal .link-panel;
"
Adding a link context menu
When clicking on a editable link in the editor in edit mode you can provide a popup which allows you to open the link, edit the link or unlink it. This does not apply to non-editable links like linked mentions or tags.
You have to provide a context menu container in the same document or accessible via an URL which content's are used for the pat-tooltip popup:
<div id="context-menu-link" hidden>
<ul class="tiptap-link-context-menu">
<li>
<a
class="close-panel tiptap-open-new-link"
target="_blank"
href="">Visit linked web page</a>
</li>
<li>
<button
type="button"
class="close-panel tiptap-edit-link">Edit link</button>
</li>
<li>
<button
type="button"
class="close-panel tiptap-unlink">Unlink</button>
</li>
</ul>
</div>
None of these elements are mandatory but if you want to provide the associated functionality you need to use these class names:
tiptap-open-new-link: The<a>element wherepat-tiptapsets the URL which should be opened.tiptap-edit-link: The element which opens the edit overlay when clicking on it.tiptap-unlink: The element which will unlink the link.
This is the pattern configuration:
data-pat-tiptap="
context-menu-link: #context-menu-link;
"
context-menu-link: URL or CSS selector pointing to the context menu contents.
Adding a image selection overlay
Images are placed in a figure tag and have an optional figcaption tag.
The following button uses pat-modal to open a overlay, referenced by the CSS selector #modal-image in the same document.
Note: You can also load the modal contents from any URL.
<a
class="button-image pat-modal"
href="#modal-image">Image</a>
This is the DOM structure with the overlay:
<div id="modal-image" hidden>
<form class="image-panel">
<label>
Image URL:
<input type="text" name="tiptap-src"/>
</label>
<label>
Title:
<input type="text" name="tiptap-title"/>
</label>
<label>
Alternative text:
<input type="text" name="tiptap-alt"/>
</label>
<label>
Caption:
<textarea name="tiptap-caption"></textarea>
</label>
<button class="close-panel" type="button" name="tiptap-confirm">submit</button>
</form>
</div>
The input[name=tiptap-src] is the only input element necessary.
You can use these elements with these names:
tiptap-src: Image URL for thesrcattribute.tiptap-title: Imagetitleattribute.tiptap-alt: Imagealtattribute.tiptap-caption: Caption text placed in afigcaptiontag.tiptap-confirm: To save the changes back to the editor.
You also need to configure pat-tiptap with the image-panel option which points to the form element in the overlay.
pat-tiptap uses a MutationObserver to check for changes in the overlay's DOM structure and re-initializes the functionality once the DOM structure changes.
This way, you can use pat-inject, pat-tabs or pat-stacks which changes the overlay content and automatically get the form reinitialized.
One idea would be to use a list of styled radio buttons with name tiptap-src and as value the URL of the image. This would then serve as a image selection widget.
For an upload widget you can use a combination of pat-upload and pat-inject to upload a image and then return a form with a hidden tiptap-src input field with the value of the new image URL. If the form is then finally submitted via tiptap-confirm the image is set into the editor.
This is the related pat-tiptap config:
data-pat-tiptap="
image-panel: #pat-modal .image-panel;
"
Adding an embed overlay for videos
With the embed functionality you can add YouTube and Vimeo videos to your document.
You can use the embed URL or directly the link to the YouTube or Vimeo video page in which case the URLs are automatically changed to embed URLs.
Embed videos are placed within a figure tag and can have an optional figcaption.
The following button uses pat-modal to open a overlay, referenced by the CSS selector #modal-embed in the same document.
Note: You can also load the modal contents from any URL.
<a
class="button-embed pat-modal"
href="#modal-embed">Video</a>
This is the DOM structure with the overlay:
<div id="modal-embed" hidden>
<form class="embed-panel">
<label>
Video URL:
<input type="text" name="tiptap-src"/>
</label>
<label>
Title:
<input type="text" name="tiptap-title"/>
</label>
<label>
Caption:
<textarea name="tiptap-caption"></textarea>
</label>
<button class="close-panel" type="button" name="tiptap-confirm">submit</button>
</form>
</div>
The input[name=tiptap-src] is the only input element necessary.
You can use these elements with these names:
tiptap-src: Video URL for thesrcattribute, added to aniframetag.tiptap-title:titleattribute for theiframetag.tiptap-caption: Caption text placed in afigcaptiontag.tiptap-confirm: To save the changes back to the editor.
You also need to configure pat-tiptap with the embed-panel option which points to the form element in the overlay.
pat-tiptap uses a MutationObserver to check for changes in the overlay's DOM structure and re-initializes the functionality once the DOM structure changes.
This way, you can use pat-inject, pat-tabs or pat-stacks which changes the overlay content and automatically get the form reinitialized.
This is the related pat-tiptap config:
data-pat-tiptap="
embed-panel: #pat-modal .embed-panel;
"
Adding a source view overlay
The following button uses pat-modal to open a overlay, referenced by the CSS selector #modal-source in the same document.
Note: You can also load the modal contents from any URL.
<div id="tiptap-external-toolbar">
<a
class="button-source pat-modal"
href="#modal-source">Source</a>
</div>
This is the DOM structure with the overlay:
<div id="modal-source" hidden>
<form class="source-panel">
<label>
Source:
<textarea name="tiptap-source"></textarea>
</label>
<button class="close-panel" type="button" name="tiptap-confirm">submit</button>
</form>
</div>
The input[name=tiptap-source] is the only input element necessary.
You can use these elements with these names:
tiptap-source: Textarea for the HTML source code.tiptap-confirm: To save the changes back to the editor.
You also need to configure pat-tiptap with the source-panel option which points to the form element in the overlay.
pat-tiptap uses a MutationObserver to check for changes in the overlay's DOM structure and re-initializes the functionality once the DOM structure changes.
This way, you can use pat-inject, pat-tabs, pat-stacks or the like which changes the overlays content and always get the link panel form initlized.
This is the related pat-tiptap config:
data-pat-tiptap="
source-panel: #pat-modal .source-panel;
"
Adding @-mentions functionality
You can provide a mentioning functionality which is invoked by the @ key and references a person - or actually anything you provide in the list.
Similar to the overlays described above, the selectable items are provided via form elements, e.g. checkboxes or radiobuttons.
This form element is opened in a pat-tooltip popup.
When the form is submitted - e.g. after selecting one element and submitting via pat-autosubmit - the value of the selected element is inserted as text and the URL to a profile page is constructed using the url-scheme-mentions parameter.
This is the container with the form element which is used as content for the pat-tooltip popup:
<div id="context-menu-mentions" hidden>
<form class="pat-checklist pat-autosubmit tiptap-mentions-context-menu">
<ul>
<li>
<label>
<input
name="mention"
type="checkbox"
value="hans" />hans</label>
</li>
<li>
<label>
<input
name="mention"
type="checkbox"
value="franz" />franz</label>
</li>
<li>
<label>
<input
name="mention"
type="checkbox"
value="sepp" />sepp</label>
</li>
</ul>
</form>
</div>
The form needs include the tiptap-mentions-context-menu class.
The individual input elements which indicate a user need to have the name mention and a value which can be used to construct a URL via the url-scheme-mentions parameter explained below.
This is the pattern configuration:
data-pat-tiptap="
context-menu-mentions: #context-menu-mentions;
url-scheme-mentions: https://quaive.cornelis.amsterdam/users/{USER};
"
context-menu-mentions: CSS selector which points to a element in the current document or a URL from which the popup contents are loaded.
url-scheme-mentions: The base URL for the user profile which is opened when clicking the mentioned user. {USER} is replaced by the selected value.
Adding #-tagging functionality
Similar to the mentioning functionality you can provide a tagging functionality which is invoked by the # key and references a category or tag - or actually anything you provide in the list.
The selectable items are provided via form elements, e.g. checkboxes or radiobuttons.
This form element is opened in a pat-tooltip popup.
When the form is submitted - e.g. after selecting one element and submitting via pat-autosubmit - the value of the selected element is inserted as text and the URL to a tag-search page is constructed using the url-scheme-tags parameter.
This is the container with the form element which is used as content for the pat-tooltip popup:
<div id="context-menu-tags" hidden>
<form class="pat-checklist pat-autosubmit tiptap-tags-context-menu">
<ul>
<li>
<label><input name="tag" type="checkbox" value="I ♥ UTF-8" />I ♥ UTF-8</label>
</li>
<li>
<label><input name="tag" type="checkbox" value="music" />music</label>
</li>
<li>
<label><input name="tag" type="checkbox" value="books" />books</label>
</li>
</ul>
</form>
</div>
The form needs include the tiptap-tags-context-menu class.
The individual input elements which indicate a tag need to have the name tag and a value which can be used to construct a URL via the url-scheme-tags parameter explained below.
This is the pattern configuration:
data-pat-tiptap="
context-menu-tags: #context-menu-tags;
url-scheme-tags: https://quaive.cornelis.amsterdam/tags/{TAG}";
"
context-menu-tags: CSS selector which points to a element in the current document or a URL from which the popup contents are loaded.
url-scheme-tags: The base URL for the tagging search page which is opened when clicking the tagged item. {TAG} is replaced by the selected value.
Autofocus support
If you want the text editor to automatically get the focus after loading you can either add the pat-autofocus class to pat-tiptap element or add the autofocus attribute.
Option 1: Add the pat-autofocus class:
<textarea
name="text"
class="pat-tiptap pat-autofocus">
</textarea>
Option 2: Add the autofocus attribute:
<textarea
name="text"
class="pat-tiptap"
autofocus>
</textarea>
Placeholder support
To show a placeholder in the document add a placeholder attribute with the placeholder text to the pat-tiptap element:
<textarea
name="text"
class="pat-tiptap"
placeholder="Your poem goes here...">
</textarea>
Then on empty paragraphs are annotated with some placeholder data like: <p data-placeholder="Your poem goes here..." class="is-empty is-editor-empty"><br></p>.
To display the placeholder you need to add some CSS.
This is an CSS example to show the placeholder on top of page, if it is empty:
/* Placeholder (at the top) */
.ProseMirror p.is-editor-empty:first-child::before {
content: attr(data-placeholder);
float: left;
color: #ced4da;
pointer-events: none;
height: 0;
}
This is an CSS example to show the placeholder on any empty paragraph:
/* Placeholder (on every new line) */
.ProseMirror p.is-empty::before {
content: attr(data-placeholder);
float: left;
color: #ced4da;
pointer-events: none;
height: 0;
}
Options reference
| Property | Type | Description |
|---|---|---|
| toolbar-external | String | CSS selector pointing to a toolbar container. |
| link-panel | String | CSS selector pointing to the link form element in the overlay. |
| image-panel | String | CSS selector pointing to the image form element in the overlay. |
| source-panel | String | CSS selector pointing to the source form element in the overlay. |
| context-menu-link | String | URL or CSS selector pointing to the link context menu contents. |
| context-menu-mentions | String | URL or CSS selector pointing to the mentions context menu contents. |
| url-scheme-mentions | String | The base URL for the user profile which is opened when clicking the mentioned user. {USER} is replaced by the selected value. |
| context-menu-tags | String | URL or CSS selector pointing to the tags context menu contents. |
| url-scheme-tags | String | The base URL for the tagging search page which is opened when clicking the tagged item. {TAG} is replaced by the selected value. |