108 lines
2.3 KiB
TypeScript
108 lines
2.3 KiB
TypeScript
import { Node, mergeAttributes, Command } from '@tiptap/core'
|
||
|
||
export interface DetailsOptions {
|
||
HTMLAttributes: {
|
||
[key: string]: any
|
||
},
|
||
}
|
||
|
||
declare module '@tiptap/core' {
|
||
interface Commands {
|
||
details: {
|
||
/**
|
||
* Set a details node
|
||
*/
|
||
setDetails: () => Command,
|
||
/**
|
||
* Toggle a details node
|
||
*/
|
||
toggleDetails: () => Command,
|
||
/**
|
||
* Unset a details node
|
||
*/
|
||
unsetDetails: () => Command,
|
||
}
|
||
}
|
||
}
|
||
|
||
export default Node.create<DetailsOptions>({
|
||
name: 'details',
|
||
|
||
content: 'detailsSummary block+',
|
||
|
||
group: 'block',
|
||
|
||
// defining: true,
|
||
|
||
defaultOptions: {
|
||
HTMLAttributes: {},
|
||
},
|
||
|
||
parseHTML() {
|
||
return [
|
||
{
|
||
tag: 'details',
|
||
},
|
||
{
|
||
tag: 'div[data-type="details"]',
|
||
},
|
||
]
|
||
},
|
||
|
||
renderHTML({ HTMLAttributes }) {
|
||
return ['details', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]
|
||
},
|
||
|
||
addNodeView() {
|
||
return ({ HTMLAttributes }) => {
|
||
const item = document.createElement('div')
|
||
item.setAttribute('data-type', 'details')
|
||
|
||
const toggle = document.createElement('div')
|
||
toggle.setAttribute('data-type', 'detailsToggle')
|
||
item.append(toggle)
|
||
|
||
const content = document.createElement('div')
|
||
content.setAttribute('data-type', 'detailsContent')
|
||
item.append(content)
|
||
|
||
toggle.addEventListener('click', () => {
|
||
if (item.hasAttribute('open')) {
|
||
item.removeAttribute('open')
|
||
} else {
|
||
item.setAttribute('open', 'open')
|
||
}
|
||
})
|
||
|
||
Object.entries(HTMLAttributes).forEach(([key, value]) => {
|
||
item.setAttribute(key, value)
|
||
})
|
||
|
||
return {
|
||
dom: item,
|
||
contentDOM: content,
|
||
ignoreMutation: (mutation: MutationRecord) => {
|
||
return !item.contains(mutation.target) || item === mutation.target
|
||
},
|
||
}
|
||
}
|
||
},
|
||
|
||
addCommands() {
|
||
return {
|
||
setDetails: () => ({ commands }) => {
|
||
// TODO: Doesn’t work
|
||
return commands.wrapIn('details')
|
||
},
|
||
toggleDetails: () => ({ commands }) => {
|
||
// TODO: Doesn’t work
|
||
return commands.toggleWrap('details')
|
||
},
|
||
unsetDetails: () => ({ commands }) => {
|
||
// TODO: Doesn’t work
|
||
return commands.lift('details')
|
||
},
|
||
}
|
||
},
|
||
})
|