Skip to content

Instantly share code, notes, and snippets.

@pootsbook
Last active March 15, 2025 19:17
Show Gist options
  • Save pootsbook/9f5c47da34449511d399c071593e1f20 to your computer and use it in GitHub Desktop.
Save pootsbook/9f5c47da34449511d399c071593e1f20 to your computer and use it in GitHub Desktop.
Variable Placeholders for TipTap
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<style>
.variable-placeholder {
background: #ffeb3b;
color: #333;
padding: 0 5px;
border-radius: 4px;
display: inline-block;
}
</style>
</head>
<body>
<select id="variable-selector">
<option value="member_first_name" data-label="Member > First Name">Member > First Name</option>
<option value="member_last_name" data-label="Member > Last Name">Member > Last Name</option>
<option value="member_contact_email" data-label="Member > Contact Email">Member > Email</option>
</select>
<button id="insert-variable-placeholder">Insert Variable Placeholder</button>
<div class="element"></div>
<script type="module">
import { Node } from "https://esm.sh/@tiptap/core";
export const VariablePlaceholder = Node.create({
name: "variablePlaceholder",
inline: true, // Make it behave like inline text
group: "inline",
atom: true, // Treat it as a single, uneditable unit
addAttributes() {
return {
key: { default: null }, // Unique identifier (e.g., "member_first_name")
label: { default: null } // Display label (e.g., "Member > First Name")
};
},
parseHTML() {
return [{ tag: "span[data-variable-placeholder]" }];
},
renderHTML({ node }) {
return [
"span",
{
"data-variable-placeholder": node.attrs.key,
class: "variable-placeholder"
},
node.attrs.label
];
},
addCommands() {
return {
insertVariablePlaceholder:
(key, label) =>
({ chain }) => {
return chain()
.focus()
.insertContent({
type: "variablePlaceholder",
attrs: { key, label }
})
.run();
}
};
}
});
import { Editor } from 'https://esm.sh/@tiptap/core'
import { Document } from 'https://esm.sh/@tiptap/extension-document'
import { Paragraph } from 'https://esm.sh/@tiptap/extension-paragraph'
import { Text } from 'https://esm.sh/@tiptap/extension-text'
import { CharacterCount } from 'https://esm.sh/@tiptap/extension-character-count'
const editor = new Editor({
element: document.querySelector('.element'),
extensions: [Document, Paragraph, Text, VariablePlaceholder],
content: '<p><q>Hello</q> World!</p>',
})
window.editor = editor;
document.getElementById("insert-variable-placeholder").addEventListener("click", () => {
const select = document.getElementById("variable-selector");
const key = select.value;
const label = select.options[select.selectedIndex].getAttribute("data-label");
editor.chain().focus().insertVariablePlaceholder(key, label).run();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment