Skip to content
File

Blob: src/shared/editor/schema/details.ts

typescript91 lines
1import { mergeAttributes, Node } from "@tiptap/core";
2 
3export const DEFAULT_DETAILS_SUMMARY = "Details";
4export const DETAILS_SUMMARY_PLACEHOLDER = "Summary";
5 
6export const SharedDetailsBlock = Node.create({
7 name: "details",
8 content: "detailsSummary detailsContent",
9 group: "block",
10 defining: true,
11 isolating: true,
12 
13 addAttributes() {
14 return {
15 open: {
16 default: false,
17 parseHTML: (element) => element.hasAttribute("open"),
18 renderHTML: ({ open }) => {
19 if (!open) return {};
20 return { open: "" };
21 },
22 },
23 };
24 },
25 
26 parseHTML() {
27 return [{ tag: "details" }];
28 },
29 
30 renderHTML({ HTMLAttributes }) {
31 return ["details", mergeAttributes({ class: "tiptap-details" }, HTMLAttributes), 0];
32 },
33});
34 
35export const SharedDetailsBlockSummary = Node.create({
36 name: "detailsSummary",
37 content: "text*",
38 defining: true,
39 selectable: false,
40 isolating: true,
41 
42 parseHTML() {
43 return [{ tag: "summary" }];
44 },
45 
46 renderHTML({ HTMLAttributes }) {
47 return [
48 "summary",
49 mergeAttributes(
50 {
51 class: "tiptap-details-summary",
52 "data-placeholder": DETAILS_SUMMARY_PLACEHOLDER,
53 },
54 HTMLAttributes,
55 ),
56 0,
57 ];
58 },
59});
60 
61export const SharedDetailsBlockContent = Node.create({
62 name: "detailsContent",
63 content: "block+",
64 defining: true,
65 selectable: false,
66 
67 parseHTML() {
68 return [{ tag: 'div[data-type="detailsContent"]' }];
69 },
70 
71 renderHTML({ HTMLAttributes }) {
72 return [
73 "div",
74 mergeAttributes(
75 {
76 class: "tiptap-details-content",
77 "data-type": "detailsContent",
78 },
79 HTMLAttributes,
80 ),
81 0,
82 ];
83 },
84});
85 
86export const SharedDetailsBlockExtensions = [
87 SharedDetailsBlock,
88 SharedDetailsBlockSummary,
89 SharedDetailsBlockContent,
90] as const;