@blocknote/core 0.1.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +99 -0
  2. package/dist/blocknote.js +4485 -0
  3. package/dist/blocknote.js.map +1 -0
  4. package/dist/blocknote.umd.cjs +90 -0
  5. package/dist/blocknote.umd.cjs.map +1 -0
  6. package/dist/style.css +1 -0
  7. package/package.json +109 -0
  8. package/src/BlockNoteExtensions.ts +90 -0
  9. package/src/EditorContent.tsx +1 -0
  10. package/src/assets/inter-v12-latin/inter-v12-latin-100.woff +0 -0
  11. package/src/assets/inter-v12-latin/inter-v12-latin-100.woff2 +0 -0
  12. package/src/assets/inter-v12-latin/inter-v12-latin-200.woff +0 -0
  13. package/src/assets/inter-v12-latin/inter-v12-latin-200.woff2 +0 -0
  14. package/src/assets/inter-v12-latin/inter-v12-latin-300.woff +0 -0
  15. package/src/assets/inter-v12-latin/inter-v12-latin-300.woff2 +0 -0
  16. package/src/assets/inter-v12-latin/inter-v12-latin-500.woff +0 -0
  17. package/src/assets/inter-v12-latin/inter-v12-latin-500.woff2 +0 -0
  18. package/src/assets/inter-v12-latin/inter-v12-latin-600.woff +0 -0
  19. package/src/assets/inter-v12-latin/inter-v12-latin-600.woff2 +0 -0
  20. package/src/assets/inter-v12-latin/inter-v12-latin-700.woff +0 -0
  21. package/src/assets/inter-v12-latin/inter-v12-latin-700.woff2 +0 -0
  22. package/src/assets/inter-v12-latin/inter-v12-latin-800.woff +0 -0
  23. package/src/assets/inter-v12-latin/inter-v12-latin-800.woff2 +0 -0
  24. package/src/assets/inter-v12-latin/inter-v12-latin-900.woff +0 -0
  25. package/src/assets/inter-v12-latin/inter-v12-latin-900.woff2 +0 -0
  26. package/src/assets/inter-v12-latin/inter-v12-latin-regular.woff +0 -0
  27. package/src/assets/inter-v12-latin/inter-v12-latin-regular.woff2 +0 -0
  28. package/src/editor.module.css +3 -0
  29. package/src/extensions/Blocks/OrderedListPlugin.ts +46 -0
  30. package/src/extensions/Blocks/PreviousBlockTypePlugin.ts +146 -0
  31. package/src/extensions/Blocks/commands/joinBackward.ts +274 -0
  32. package/src/extensions/Blocks/helpers/findBlock.ts +3 -0
  33. package/src/extensions/Blocks/helpers/setBlockHeading.ts +30 -0
  34. package/src/extensions/Blocks/index.ts +15 -0
  35. package/src/extensions/Blocks/nodes/Block.module.css +226 -0
  36. package/src/extensions/Blocks/nodes/Block.ts +390 -0
  37. package/src/extensions/Blocks/nodes/BlockGroup.ts +28 -0
  38. package/src/extensions/Blocks/nodes/Content.ts +50 -0
  39. package/src/extensions/Blocks/nodes/README.md +26 -0
  40. package/src/extensions/Blocks/rule.ts +48 -0
  41. package/src/extensions/BubbleMenu/BubbleMenuExtension.tsx +28 -0
  42. package/src/extensions/BubbleMenu/BubbleMenuPlugin.ts +245 -0
  43. package/src/extensions/BubbleMenu/component/BubbleMenu.tsx +216 -0
  44. package/src/extensions/BubbleMenu/component/DropdownBlockItem.module.css +13 -0
  45. package/src/extensions/BubbleMenu/component/DropdownBlockItem.tsx +25 -0
  46. package/src/extensions/BubbleMenu/component/LinkToolbarButton.tsx +67 -0
  47. package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +15 -0
  48. package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.tsx +266 -0
  49. package/src/extensions/DraggableBlocks/components/DragHandle.module.css +33 -0
  50. package/src/extensions/DraggableBlocks/components/DragHandle.tsx +108 -0
  51. package/src/extensions/DraggableBlocks/components/DragHandleMenu.module.css +10 -0
  52. package/src/extensions/DraggableBlocks/components/DragHandleMenu.tsx +18 -0
  53. package/src/extensions/Hyperlinks/HyperlinkMark.tsx +16 -0
  54. package/src/extensions/Hyperlinks/HyperlinkMenuPlugin.tsx +200 -0
  55. package/src/extensions/Hyperlinks/menus/HyperlinkBasicMenu.tsx +59 -0
  56. package/src/extensions/Hyperlinks/menus/HyperlinkEditMenu.tsx +72 -0
  57. package/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInput.tsx +173 -0
  58. package/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInputStyles.ts +36 -0
  59. package/src/extensions/Hyperlinks/menus/atlaskit/README.md +1 -0
  60. package/src/extensions/Hyperlinks/menus/atlaskit/ToolbarComponent.tsx +61 -0
  61. package/src/extensions/Paragraph/FixedParagraph.ts +12 -0
  62. package/src/extensions/Placeholder/PlaceholderExtension.ts +127 -0
  63. package/src/extensions/SlashMenu/SlashMenuExtension.ts +43 -0
  64. package/src/extensions/SlashMenu/SlashMenuItem.ts +56 -0
  65. package/src/extensions/SlashMenu/defaultCommands.tsx +229 -0
  66. package/src/extensions/SlashMenu/index.ts +11 -0
  67. package/src/extensions/TrailingNode/TrailingNodeExtension.ts +70 -0
  68. package/src/extensions/UniqueID/UniqueID.ts +281 -0
  69. package/src/extensions/helpers/formatKeyboardShortcut.ts +9 -0
  70. package/src/fonts-inter.css +94 -0
  71. package/src/globals.css +28 -0
  72. package/src/index.ts +5 -0
  73. package/src/lib/atlaskit/browser.ts +47 -0
  74. package/src/root.module.css +19 -0
  75. package/src/shared/components/toolbar/SimpleToolbarButton.module.css +13 -0
  76. package/src/shared/components/toolbar/SimpleToolbarButton.tsx +56 -0
  77. package/src/shared/components/toolbar/Toolbar.module.css +10 -0
  78. package/src/shared/components/toolbar/Toolbar.tsx +5 -0
  79. package/src/shared/components/toolbar/ToolbarSeparator.module.css +13 -0
  80. package/src/shared/components/toolbar/ToolbarSeparator.tsx +7 -0
  81. package/src/shared/components/tooltip/TooltipContent.module.css +15 -0
  82. package/src/shared/components/tooltip/TooltipContent.tsx +23 -0
  83. package/src/shared/hooks/useEditorForceUpdate.tsx +30 -0
  84. package/src/shared/plugins/suggestion/SuggestionItem.ts +31 -0
  85. package/src/shared/plugins/suggestion/SuggestionListReactRenderer.ts +227 -0
  86. package/src/shared/plugins/suggestion/SuggestionPlugin.ts +365 -0
  87. package/src/shared/plugins/suggestion/components/SuggestionGroup.module.css +45 -0
  88. package/src/shared/plugins/suggestion/components/SuggestionGroup.tsx +134 -0
  89. package/src/shared/plugins/suggestion/components/SuggestionList.module.css +10 -0
  90. package/src/shared/plugins/suggestion/components/SuggestionList.tsx +91 -0
  91. package/src/style.css +7 -0
  92. package/src/useEditor.ts +47 -0
  93. package/src/vite-env.d.ts +1 -0
  94. package/types/src/BlockNoteExtensions.d.ts +4 -0
  95. package/types/src/EditorContent.d.ts +1 -0
  96. package/types/src/extensions/Blocks/OrderedListPlugin.d.ts +2 -0
  97. package/types/src/extensions/Blocks/PreviousBlockTypePlugin.d.ts +13 -0
  98. package/types/src/extensions/Blocks/commands/joinBackward.d.ts +14 -0
  99. package/types/src/extensions/Blocks/helpers/findBlock.d.ts +6 -0
  100. package/types/src/extensions/Blocks/helpers/setBlockHeading.d.ts +5 -0
  101. package/types/src/extensions/Blocks/index.d.ts +1 -0
  102. package/types/src/extensions/Blocks/nodes/Block.d.ts +32 -0
  103. package/types/src/extensions/Blocks/nodes/BlockGroup.d.ts +2 -0
  104. package/types/src/extensions/Blocks/nodes/Content.d.ts +5 -0
  105. package/types/src/extensions/Blocks/rule.d.ts +16 -0
  106. package/types/src/extensions/BubbleMenu/BubbleMenuExtension.d.ts +5 -0
  107. package/types/src/extensions/BubbleMenu/BubbleMenuPlugin.d.ts +46 -0
  108. package/types/src/extensions/BubbleMenu/component/BubbleMenu.d.ts +5 -0
  109. package/types/src/extensions/BubbleMenu/component/DropdownBlockItem.d.ts +10 -0
  110. package/types/src/extensions/BubbleMenu/component/LinkToolbarButton.d.ts +11 -0
  111. package/types/src/extensions/DraggableBlocks/DraggableBlocksExtension.d.ts +7 -0
  112. package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +18 -0
  113. package/types/src/extensions/DraggableBlocks/components/DragHandle.d.ts +12 -0
  114. package/types/src/extensions/DraggableBlocks/components/DragHandleMenu.d.ts +6 -0
  115. package/types/src/extensions/Hyperlinks/HyperlinkMark.d.ts +7 -0
  116. package/types/src/extensions/Hyperlinks/HyperlinkMenuPlugin.d.ts +2 -0
  117. package/types/src/extensions/Hyperlinks/menus/HyperlinkBasicMenu.d.ts +12 -0
  118. package/types/src/extensions/Hyperlinks/menus/HyperlinkEditMenu.d.ts +10 -0
  119. package/types/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInput.d.ts +39 -0
  120. package/types/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInputStyles.d.ts +1 -0
  121. package/types/src/extensions/Hyperlinks/menus/atlaskit/ToolbarComponent.d.ts +11 -0
  122. package/types/src/extensions/Paragraph/FixedParagraph.d.ts +1 -0
  123. package/types/src/extensions/Placeholder/PlaceholderExtension.d.ts +25 -0
  124. package/types/src/extensions/SlashMenu/SlashMenuExtension.d.ts +10 -0
  125. package/types/src/extensions/SlashMenu/SlashMenuItem.d.ts +43 -0
  126. package/types/src/extensions/SlashMenu/defaultCommands.d.ts +8 -0
  127. package/types/src/extensions/SlashMenu/index.d.ts +5 -0
  128. package/types/src/extensions/TrailingNode/TrailingNodeExtension.d.ts +10 -0
  129. package/types/src/extensions/UniqueID/UniqueID.d.ts +3 -0
  130. package/types/src/extensions/helpers/formatKeyboardShortcut.d.ts +1 -0
  131. package/types/src/index.d.ts +4 -0
  132. package/types/src/lib/atlaskit/browser.d.ts +12 -0
  133. package/types/src/shared/components/toolbar/SimpleToolbarButton.d.ts +16 -0
  134. package/types/src/shared/components/toolbar/Toolbar.d.ts +4 -0
  135. package/types/src/shared/components/toolbar/ToolbarSeparator.d.ts +2 -0
  136. package/types/src/shared/components/tooltip/TooltipContent.d.ts +15 -0
  137. package/types/src/shared/hooks/useEditorForceUpdate.d.ts +2 -0
  138. package/types/src/shared/plugins/suggestion/SuggestionItem.d.ts +29 -0
  139. package/types/src/shared/plugins/suggestion/SuggestionListReactRenderer.d.ts +71 -0
  140. package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +74 -0
  141. package/types/src/shared/plugins/suggestion/components/SuggestionGroup.d.ts +23 -0
  142. package/types/src/shared/plugins/suggestion/components/SuggestionList.d.ts +26 -0
  143. package/types/src/useEditor.d.ts +8 -0
@@ -0,0 +1,274 @@
1
+ import { Fragment, Node, ResolvedPos, Slice } from "prosemirror-model";
2
+ import { EditorState, NodeSelection, Selection } from "prosemirror-state";
3
+ import {
4
+ canJoin,
5
+ liftTarget,
6
+ ReplaceAroundStep,
7
+ replaceStep,
8
+ } from "prosemirror-transform";
9
+
10
+ import { Command, TextSelection, Transaction } from "prosemirror-state";
11
+ import { ReplaceStep } from "prosemirror-transform";
12
+
13
+ /**
14
+ * Code taken from https://github.com/ProseMirror/prosemirror-commands/blob/97a8cb5fac25e697d4693ce343e2e3b020a7fa2f/src/commands.ts
15
+ * Reason for modification: https://github.com/YousefED/BlockNote/pull/11
16
+ *
17
+ * BlockA
18
+ * BlockB
19
+ * Order of behavior has been switched to make first and second blocks content
20
+ * merge before trying to add second block as child of first
21
+ *
22
+ * behavior responsible for joining BlockB as A child of BlockA moved to (line 379 - 393 original file) after
23
+ * behavior responsible for joining content of BlockA and BlockB (line 402 - 422 original file)
24
+ */
25
+ export const joinBackward: Command = (state, dispatch, view) => {
26
+ let { $cursor } = state.selection as TextSelection;
27
+ if (
28
+ !$cursor ||
29
+ (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0)
30
+ ) {
31
+ return false;
32
+ }
33
+
34
+ let $cut = findCutBefore($cursor);
35
+
36
+ // If there is no node before this, try to lift
37
+ if (!$cut) {
38
+ let range = $cursor.blockRange(),
39
+ target = range && liftTarget(range);
40
+ if (target === null) {
41
+ return false;
42
+ }
43
+ if (dispatch) {
44
+ dispatch(state.tr.lift(range!, target).scrollIntoView());
45
+ }
46
+ return true;
47
+ }
48
+
49
+ let before = $cut.nodeBefore!;
50
+ // Apply the joining algorithm
51
+ if (!before.type.spec.isolating && deleteBarrier(state, $cut, dispatch)) {
52
+ return true;
53
+ }
54
+
55
+ // If the node below has no content and the node above is
56
+ // selectable, delete the node below and select the one above.
57
+ if (
58
+ $cursor.parent.content.size === 0 &&
59
+ (textblockAt(before, "end") || NodeSelection.isSelectable(before))
60
+ ) {
61
+ let delStep = replaceStep(
62
+ state.doc,
63
+ $cursor.before(),
64
+ $cursor.after(),
65
+ Slice.empty
66
+ );
67
+ if (
68
+ delStep &&
69
+ (delStep as ReplaceStep).slice.size <
70
+ (delStep as ReplaceStep).to - (delStep as ReplaceStep).from
71
+ ) {
72
+ if (dispatch) {
73
+ let tr = state.tr.step(delStep);
74
+ tr.setSelection(
75
+ textblockAt(before, "end")
76
+ ? Selection.findFrom(
77
+ tr.doc.resolve(tr.mapping.map($cut.pos, -1)),
78
+ -1
79
+ )!
80
+ : NodeSelection.create(tr.doc, $cut.pos - before.nodeSize)
81
+ );
82
+ dispatch(tr.scrollIntoView());
83
+ }
84
+ return true;
85
+ }
86
+ }
87
+
88
+ // If the node before is an atom, delete it
89
+ if (before.isAtom && $cut.depth === $cursor.depth - 1) {
90
+ if (dispatch) {
91
+ dispatch(
92
+ state.tr.delete($cut.pos - before.nodeSize, $cut.pos).scrollIntoView()
93
+ );
94
+ }
95
+ return true;
96
+ }
97
+
98
+ return false;
99
+ };
100
+
101
+ function findCutBefore($pos: ResolvedPos): ResolvedPos | null {
102
+ if (!$pos.parent.type.spec.isolating) {
103
+ for (let i = $pos.depth - 1; i >= 0; i--) {
104
+ if ($pos.index(i) > 0) {
105
+ return $pos.doc.resolve($pos.before(i + 1));
106
+ }
107
+ if ($pos.node(i).type.spec.isolating) {
108
+ break;
109
+ }
110
+ }
111
+ }
112
+ return null;
113
+ }
114
+
115
+ function deleteBarrier(
116
+ state: EditorState,
117
+ $cut: ResolvedPos,
118
+ dispatch: ((tr: Transaction) => void) | undefined
119
+ ) {
120
+ let before = $cut.nodeBefore!,
121
+ after = $cut.nodeAfter!,
122
+ conn,
123
+ match;
124
+ if (before.type.spec.isolating || after.type.spec.isolating) {
125
+ return false;
126
+ }
127
+ if (joinMaybeClear(state, $cut, dispatch)) {
128
+ return true;
129
+ }
130
+
131
+ let canDelAfter = $cut.parent.canReplace($cut.index(), $cut.index() + 1);
132
+
133
+ let selAfter = Selection.findFrom($cut, 1);
134
+ let range = selAfter && selAfter.$from.blockRange(selAfter.$to),
135
+ target = range && liftTarget(range);
136
+ if (target != null && target >= $cut.depth) {
137
+ if (dispatch) {
138
+ dispatch(state.tr.lift(range!, target).scrollIntoView());
139
+ }
140
+ return true;
141
+ }
142
+
143
+ if (
144
+ canDelAfter &&
145
+ textblockAt(after, "start", true) &&
146
+ textblockAt(before, "end")
147
+ ) {
148
+ let at = before,
149
+ wrap = [];
150
+ for (;;) {
151
+ wrap.push(at);
152
+ if (at.isTextblock) {
153
+ break;
154
+ }
155
+ at = at.lastChild!;
156
+ }
157
+ let afterText = after,
158
+ afterDepth = 1;
159
+ for (; !afterText.isTextblock; afterText = afterText.firstChild!) {
160
+ afterDepth++;
161
+ }
162
+ if (at.canReplace(at.childCount, at.childCount, afterText.content)) {
163
+ if (dispatch) {
164
+ let end = Fragment.empty;
165
+ for (let i = wrap.length - 1; i >= 0; i--) {
166
+ end = Fragment.from(wrap[i].copy(end));
167
+ }
168
+ let tr = state.tr.step(
169
+ new ReplaceAroundStep(
170
+ $cut.pos - wrap.length,
171
+ $cut.pos + after.nodeSize,
172
+ $cut.pos + afterDepth,
173
+ $cut.pos + after.nodeSize - afterDepth,
174
+ new Slice(end, wrap.length, 0),
175
+ 0,
176
+ true
177
+ )
178
+ );
179
+ dispatch(tr.scrollIntoView());
180
+ }
181
+ return true;
182
+ }
183
+ }
184
+
185
+ if (
186
+ canDelAfter &&
187
+ (conn = (match = before.contentMatchAt(before.childCount)).findWrapping(
188
+ after.type
189
+ )) &&
190
+ match.matchType(conn[0] || after.type)!.validEnd
191
+ ) {
192
+ if (dispatch) {
193
+ let end = $cut.pos + after.nodeSize,
194
+ wrap = Fragment.empty;
195
+ for (let i = conn.length - 1; i >= 0; i--) {
196
+ wrap = Fragment.from(conn[i].create(null, wrap));
197
+ }
198
+ wrap = Fragment.from(before.copy(wrap));
199
+ let tr = state.tr.step(
200
+ new ReplaceAroundStep(
201
+ $cut.pos - 1,
202
+ end,
203
+ $cut.pos,
204
+ end,
205
+ new Slice(wrap, 1, 0),
206
+ conn.length,
207
+ true
208
+ )
209
+ );
210
+ let joinAt = end + 2 * conn.length;
211
+ if (canJoin(tr.doc, joinAt)) {
212
+ tr.join(joinAt);
213
+ }
214
+ dispatch(tr.scrollIntoView());
215
+ }
216
+ return true;
217
+ }
218
+ return false;
219
+ }
220
+
221
+ function textblockAt(node: Node, side: "start" | "end", only = false) {
222
+ for (
223
+ let scan: Node | null = node;
224
+ scan;
225
+ scan = side === "start" ? scan.firstChild : scan.lastChild
226
+ ) {
227
+ if (scan.isTextblock) {
228
+ return true;
229
+ }
230
+ if (only && scan.childCount !== 1) {
231
+ return false;
232
+ }
233
+ }
234
+ return false;
235
+ }
236
+ function joinMaybeClear(
237
+ state: EditorState,
238
+ $pos: ResolvedPos,
239
+ dispatch: ((tr: Transaction) => void) | undefined
240
+ ) {
241
+ let before = $pos.nodeBefore,
242
+ after = $pos.nodeAfter,
243
+ index = $pos.index();
244
+ if (!before || !after || !before.type.compatibleContent(after.type)) {
245
+ return false;
246
+ }
247
+ if (!before.content.size && $pos.parent.canReplace(index - 1, index)) {
248
+ if (dispatch) {
249
+ dispatch(
250
+ state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollIntoView()
251
+ );
252
+ }
253
+ return true;
254
+ }
255
+ if (
256
+ !$pos.parent.canReplace(index, index + 1) ||
257
+ !(after.isTextblock || canJoin(state.doc, $pos.pos))
258
+ ) {
259
+ return false;
260
+ }
261
+ if (dispatch) {
262
+ dispatch(
263
+ state.tr
264
+ .clearIncompatible(
265
+ $pos.pos,
266
+ before.type,
267
+ before.contentMatchAt(before.childCount)
268
+ )
269
+ .join($pos.pos)
270
+ .scrollIntoView()
271
+ );
272
+ }
273
+ return true;
274
+ }
@@ -0,0 +1,3 @@
1
+ import { findParentNode } from "@tiptap/core";
2
+
3
+ export const findBlock = findParentNode((node) => node.type.name === "tcblock");
@@ -0,0 +1,30 @@
1
+ import { Transaction } from "prosemirror-state";
2
+ import { Level } from "../nodes/Block";
3
+ import { findBlock } from "./findBlock";
4
+
5
+ type Dispatch = ((args?: any) => any) | undefined;
6
+
7
+ export function setBlockHeading(
8
+ tr: Transaction,
9
+ dispatch: Dispatch,
10
+ level?: Level
11
+ ) {
12
+ // Get parent of TextNode
13
+ const containingBlock = findBlock(tr.selection);
14
+
15
+ // Should not be possible because schema dictates
16
+ // that each text node is nested in a BlockContent
17
+ // node which is nested inside a BlockNode
18
+ if (!containingBlock) {
19
+ return false;
20
+ }
21
+
22
+ // Add heading attribute to Block
23
+ if (dispatch) {
24
+ tr.setNodeMarkup(containingBlock.pos, undefined, {
25
+ ...containingBlock.node.attrs,
26
+ headingType: level,
27
+ });
28
+ }
29
+ return true;
30
+ }
@@ -0,0 +1,15 @@
1
+ import { Node } from "@tiptap/core";
2
+ import { Block } from "./nodes/Block";
3
+ import { BlockGroup } from "./nodes/BlockGroup";
4
+ import { ContentBlock } from "./nodes/Content";
5
+
6
+ export const blocks: any[] = [
7
+ ContentBlock,
8
+ Block,
9
+ BlockGroup,
10
+ Node.create({
11
+ name: "doc",
12
+ topNode: true,
13
+ content: "blockgroup",
14
+ }),
15
+ ];
@@ -0,0 +1,226 @@
1
+ /*
2
+ BASIC STYLES
3
+ */
4
+
5
+ .blockOuter {
6
+ /* padding-bottom: 15px; */
7
+ font-size: 16px;
8
+ line-height: 1.5;
9
+ transition: all 0.2s;
10
+ font-weight: normal;
11
+ }
12
+
13
+ .block {
14
+ border-left: 2px solid white;
15
+ border-color: white;
16
+ transition: all 0.2s;
17
+ }
18
+
19
+ .block {
20
+ /* content: ""; */
21
+ transition: all 0.2s;
22
+ margin: 0px;
23
+ }
24
+
25
+ .blockContent {
26
+ padding: 3px 0;
27
+ transition: font-size 0.2s;
28
+ /* display: inline-block; */
29
+ }
30
+
31
+ /*
32
+ NESTED BLOCKS
33
+ */
34
+
35
+ .blockGroup .blockGroup {
36
+ margin-left: 1.5em;
37
+ }
38
+
39
+ .blockGroup .blockGroup > .blockOuter {
40
+ position: relative;
41
+ }
42
+
43
+ .blockGroup .blockGroup > .blockOuter:not([data-prev-depthchanged])::before {
44
+ content: " ";
45
+ display: inline;
46
+ border-left: 1px solid #ccc;
47
+ position: absolute;
48
+ left: -20px;
49
+ height: 100%;
50
+ transition: all 0.2s 0.1s;
51
+ }
52
+
53
+ .blockGroup .blockGroup > .blockOuter[data-prev-depthchange="-2"]::before {
54
+ height: 0;
55
+ }
56
+
57
+ /* NESTED BLOCK ANIMATIONS */
58
+
59
+ [data-prev-depthchange="1"] {
60
+ --x: 1;
61
+ }
62
+ [data-prev-depthchange="2"] {
63
+ --x: 2;
64
+ }
65
+ [data-prev-depthchange="3"] {
66
+ --x: 3;
67
+ }
68
+ [data-prev-depthchange="4"] {
69
+ --x: 4;
70
+ }
71
+ [data-prev-depthchange="5"] {
72
+ --x: 5;
73
+ }
74
+
75
+ [data-prev-depthchange="-1"] {
76
+ --x: -1;
77
+ }
78
+ [data-prev-depthchange="-2"] {
79
+ --x: -2;
80
+ }
81
+ [data-prev-depthchange="-3"] {
82
+ --x: -3;
83
+ }
84
+ [data-prev-depthchange="-4"] {
85
+ --x: -4;
86
+ }
87
+ [data-prev-depthchange="-5"] {
88
+ --x: -5;
89
+ }
90
+
91
+ .blockOuter[data-prev-depthchange] {
92
+ margin-left: calc(10px * var(--x));
93
+ }
94
+
95
+ .blockOuter[data-prev-depthchange] .blockOuter[data-prev-depthchange] {
96
+ margin-left: 0;
97
+ }
98
+
99
+ /* HEADINGS*/
100
+ .blockOuter[data-prev-headingtype="1"] > .block > div:first-child,
101
+ .blockOuter[data-headingtype="1"]:not([data-prev-headingtype])
102
+ > .block
103
+ > div:first-child {
104
+ font-size: 3em;
105
+ font-weight: bold;
106
+ }
107
+
108
+ .blockOuter[data-prev-headingtype="2"] > .block > div:first-child,
109
+ .blockOuter[data-headingtype="2"]:not([data-prev-headingtype])
110
+ > .block
111
+ > div:first-child {
112
+ font-size: 2em;
113
+ font-weight: bold;
114
+ }
115
+
116
+ .blockOuter[data-prev-headingtype="3"] > .block > div:first-child,
117
+ .blockOuter[data-headingtype="3"]:not([data-prev-headingtype])
118
+ > .block
119
+ > div:first-child {
120
+ font-size: 1.3em;
121
+ font-weight: bold;
122
+ }
123
+
124
+ /* LISTS */
125
+
126
+ .block > div:first-child::before {
127
+ content: "";
128
+ transition: all 0.2s;
129
+ margin-left: 0px;
130
+ }
131
+
132
+ .blockOuter[data-prev-listtype="oli"] > .block > div:first-child::before,
133
+ .blockOuter[data-listtype="oli"]:not([data-prev-listtype])
134
+ > .block
135
+ > div:first-child::before {
136
+ content: attr(data-position);
137
+ margin-right: 1.2em;
138
+ padding-left: 0px;
139
+ }
140
+
141
+ .blockOuter[data-prev-listtype="li"] > .block > div:first-child::before,
142
+ .blockOuter[data-listtype="li"]:not([data-prev-listtype])
143
+ > .block
144
+ > div:first-child::before {
145
+ content: "•";
146
+ margin-right: 1.2em;
147
+ /* display: list-item; */
148
+ /* list-style-type: circle; */
149
+ /* list-style-position: inside; */
150
+ padding-left: 0px;
151
+ /* margin-left: 0.2em; */
152
+ }
153
+
154
+ .blockOuter[data-listtype="li"]
155
+ > .block
156
+ > .blockGroup
157
+ > .blockOuter[data-prev-listtype="li"]
158
+ > .block
159
+ > div:first-child::before,
160
+ .blockOuter[data-listtype="li"]
161
+ > .block
162
+ > .blockGroup
163
+ > .blockOuter[data-listtype="li"]:not([data-prev-listtype])
164
+ > .block
165
+ > div:first-child::before {
166
+ content: "◦";
167
+ /* font-size: 1.2em; */
168
+ font-family: arial;
169
+ }
170
+
171
+ .blockOuter[data-listtype="li"]
172
+ > .block
173
+ > .blockGroup
174
+ > .blockOuter[data-listtype="li"]
175
+ > .block
176
+ > .blockGroup
177
+ .blockOuter[data-prev-listtype="li"]
178
+ > .block
179
+ > div:first-child::before,
180
+ .blockOuter[data-listtype="li"]
181
+ > .block
182
+ > .blockGroup
183
+ > .blockOuter[data-listtype="li"]
184
+ > .block
185
+ > .blockGroup
186
+ .blockOuter[data-listtype="li"]:not([data-prev-listtype])
187
+ > .block
188
+ > div:first-child::before {
189
+ content: "▪";
190
+ }
191
+
192
+ /* PLACEHOLDERS*/
193
+
194
+ .blockContent > div {
195
+ display: inline;
196
+ }
197
+
198
+ .blockContent.isEmpty div::before,
199
+ .blockContent.isFilter div::before {
200
+ /*float: left; */
201
+ content: "";
202
+ color: #aeb8c2;
203
+ pointer-events: none;
204
+ height: 0;
205
+ /* width: 0; */
206
+ position: absolute;
207
+ font-style: italic;
208
+ }
209
+
210
+ /* TODO: would be nicer if defined from code */
211
+
212
+ .blockContent.isEmpty.hasAnchor div::before {
213
+ content: "Enter text or type '/' for commands";
214
+ }
215
+
216
+ .blockContent.isFilter.hasAnchor div::before {
217
+ content: "Type to filter";
218
+ }
219
+
220
+ [data-headingtype] > .blockContent.isEmpty div::before {
221
+ content: "Heading";
222
+ }
223
+
224
+ [data-listtype] > .blockContent.isEmpty div::before {
225
+ content: "List";
226
+ }