feat: nested toggle block (#671)

* feat: nested toggle block

* fix: md export

* fix detailsButton icon alignment

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
This commit is contained in:
fuscodev
2025-04-04 14:01:39 +02:00
committed by GitHub
parent 7ca2b437d4
commit 8aa604637e
4 changed files with 26 additions and 23 deletions

View File

@ -247,7 +247,7 @@ const CommandGroups: SlashMenuGroupedItemsType = {
searchTerms: ["collapsible", "block", "toggle", "details", "expand"], searchTerms: ["collapsible", "block", "toggle", "details", "expand"],
icon: IconCaretRightFilled, icon: IconCaretRightFilled,
command: ({ editor, range }: CommandProps) => command: ({ editor, range }: CommandProps) =>
editor.chain().focus().deleteRange(range).toggleDetails().run(), editor.chain().focus().deleteRange(range).setDetails().run(),
}, },
{ {
title: "Callout", title: "Callout",

View File

@ -53,24 +53,22 @@
padding: 4px; padding: 4px;
word-break: break-word; word-break: break-word;
overflow-wrap: break-word; overflow-wrap: break-word;
}
}
[data-type="detailsContent"] { [data-type="details"] > [data-type="detailsContainer"] > [data-type="detailsContent"]{
display: none; display: none;
} }
}
&[open] { [data-type="details"][open] > [data-type="detailsContainer"] > [data-type="detailsContent"]{
[data-type="detailsButton"] {
.ProseMirror-icon {
transform: rotateZ(90deg);
}
}
[data-type="detailsContainer"] {
[data-type="detailsContent"] {
display: block; display: block;
} }
[data-type="details"][open] > [data-type="detailsButton"] {
align-items: start;
} }
}
[data-type="details"][open] > [data-type="detailsButton"] .ProseMirror-icon{
transform: rotateZ(90deg);
} }
} }

View File

@ -79,16 +79,18 @@ function preserveDetail(turndownService: TurndownService) {
return node.nodeName === 'DETAILS'; return node.nodeName === 'DETAILS';
}, },
replacement: function (content: any, node: HTMLInputElement) { replacement: function (content: any, node: HTMLInputElement) {
// TODO: preserve summary of nested details
const summary = node.querySelector(':scope > summary'); const summary = node.querySelector(':scope > summary');
let detailSummary = ''; let detailSummary = '';
if (summary) { if (summary) {
detailSummary = `<summary>${turndownService.turndown(summary.innerHTML)}</summary>`; detailSummary = `<summary>${turndownService.turndown(summary.innerHTML)}</summary>`;
summary.remove();
} }
const detailsContent = turndownService.turndown(node.innerHTML); const detailsContent = Array.from(node.childNodes)
.filter(child => child.nodeName !== 'SUMMARY')
.map(child => (child.nodeType === 1 ? turndownService.turndown((child as HTMLElement).outerHTML) : child.textContent))
.join('');
return `\n<details>\n${detailSummary}\n\n${detailsContent}\n\n</details>\n`; return `\n<details>\n${detailSummary}\n\n${detailsContent}\n\n</details>\n`;
}, },
}); });

View File

@ -132,6 +132,9 @@ export const Details = Node.create<DetailsOptions>({
} }
const slice = state.doc.slice(range.start, range.end); const slice = state.doc.slice(range.start, range.end);
if(slice.content.firstChild.type.name === "detailsSummary") return false;
if ( if (
!state.schema.nodes.detailsContent.contentMatch.matchFragment( !state.schema.nodes.detailsContent.contentMatch.matchFragment(
slice.content, slice.content,