@blocknote/core 0.2.3 → 0.2.4-alpha.7

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 (44) hide show
  1. package/dist/blocknote.js +753 -633
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +1 -1
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/package.json +19 -28
  7. package/src/BlockNoteExtensions.ts +10 -0
  8. package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +61 -0
  9. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +62 -0
  10. package/src/extensions/Blocks/PreviousBlockTypePlugin.ts +107 -97
  11. package/src/extensions/Blocks/nodes/Block.module.css +91 -6
  12. package/src/extensions/Blocks/nodes/BlockContainer.ts +39 -26
  13. package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +4 -4
  14. package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +8 -0
  15. package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +80 -35
  16. package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +16 -0
  17. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +34 -3
  18. package/src/extensions/Placeholder/PlaceholderExtension.ts +1 -1
  19. package/src/extensions/SlashMenu/SlashMenuExtension.ts +1 -1
  20. package/src/extensions/SlashMenu/SlashMenuItem.ts +3 -28
  21. package/src/extensions/SlashMenu/defaultCommands.tsx +14 -32
  22. package/src/extensions/SlashMenu/index.ts +1 -6
  23. package/src/extensions/TextAlignment/TextAlignmentExtension.ts +75 -0
  24. package/src/extensions/TextColor/TextColorExtension.ts +54 -0
  25. package/src/extensions/TextColor/TextColorMark.ts +62 -0
  26. package/src/shared/plugins/suggestion/SuggestionItem.ts +0 -9
  27. package/src/shared/plugins/suggestion/SuggestionPlugin.ts +191 -228
  28. package/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts +1 -1
  29. package/types/src/api/Document.d.ts +5 -0
  30. package/types/src/extensions/BackgroundColor/BackgroundColorExtension.d.ts +9 -0
  31. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +9 -0
  32. package/types/src/extensions/Blocks/PreviousBlockTypePlugin.d.ts +3 -2
  33. package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +4 -0
  34. package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +4 -9
  35. package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +10 -0
  36. package/types/src/extensions/SlashMenu/SlashMenuItem.d.ts +2 -19
  37. package/types/src/extensions/SlashMenu/defaultSlashCommands.d.ts +5 -0
  38. package/types/src/extensions/SlashMenu/index.d.ts +1 -2
  39. package/types/src/extensions/TextAlignment/TextAlignmentExtension.d.ts +9 -0
  40. package/types/src/extensions/TextColor/TextColorExtension.d.ts +9 -0
  41. package/types/src/extensions/TextColor/TextColorMark.d.ts +9 -0
  42. package/types/src/shared/plugins/suggestion/SuggestionItem.d.ts +0 -6
  43. package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +9 -23
  44. package/types/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.d.ts +1 -1
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "homepage": "https://github.com/yousefed/blocknote",
4
4
  "private": false,
5
5
  "license": "MPL-2.0",
6
- "version": "0.2.3",
6
+ "version": "0.2.4-alpha.7",
7
7
  "files": [
8
8
  "dist",
9
9
  "types",
@@ -49,33 +49,24 @@
49
49
  "@emotion/cache": "^11.10.5",
50
50
  "@emotion/serialize": "^1.1.1",
51
51
  "@emotion/utils": "^1.2.0",
52
- "@tiptap/core": "2.0.0-beta.209",
53
- "@tiptap/extension-bold": "2.0.0-beta.209",
54
- "@tiptap/extension-code": "2.0.0-beta.209",
55
- "@tiptap/extension-collaboration": "2.0.0-beta.209",
56
- "@tiptap/extension-collaboration-cursor": "2.0.0-beta.209",
57
- "@tiptap/extension-dropcursor": "2.0.0-beta.209",
58
- "@tiptap/extension-gapcursor": "2.0.0-beta.209",
59
- "@tiptap/extension-hard-break": "2.0.0-beta.209",
60
- "@tiptap/extension-history": "2.0.0-beta.209",
61
- "@tiptap/extension-horizontal-rule": "2.0.0-beta.209",
62
- "@tiptap/extension-italic": "2.0.0-beta.209",
63
- "@tiptap/extension-link": "2.0.0-beta.209",
64
- "@tiptap/extension-paragraph": "2.0.0-beta.209",
65
- "@tiptap/extension-strike": "2.0.0-beta.209",
66
- "@tiptap/extension-text": "2.0.0-beta.209",
67
- "@tiptap/extension-underline": "2.0.0-beta.209",
52
+ "@tiptap/core": "2.0.0-beta.217",
53
+ "@tiptap/extension-bold": "2.0.0-beta.217",
54
+ "@tiptap/extension-code": "2.0.0-beta.217",
55
+ "@tiptap/extension-collaboration": "2.0.0-beta.217",
56
+ "@tiptap/extension-collaboration-cursor": "2.0.0-beta.217",
57
+ "@tiptap/extension-dropcursor": "2.0.0-beta.217",
58
+ "@tiptap/extension-gapcursor": "2.0.0-beta.217",
59
+ "@tiptap/extension-hard-break": "2.0.0-beta.217",
60
+ "@tiptap/extension-history": "2.0.0-beta.217",
61
+ "@tiptap/extension-horizontal-rule": "2.0.0-beta.217",
62
+ "@tiptap/extension-italic": "2.0.0-beta.217",
63
+ "@tiptap/extension-link": "2.0.0-beta.217",
64
+ "@tiptap/extension-paragraph": "2.0.0-beta.217",
65
+ "@tiptap/extension-strike": "2.0.0-beta.217",
66
+ "@tiptap/extension-text": "2.0.0-beta.217",
67
+ "@tiptap/extension-underline": "2.0.0-beta.217",
68
+ "@tiptap/pm": "2.0.0-beta.217",
68
69
  "lodash": "^4.17.21",
69
- "prosemirror-commands": "^1.5.0",
70
- "prosemirror-dropcursor": "1.5.0",
71
- "prosemirror-gapcursor": "^1.3.1",
72
- "prosemirror-history": "^1.3.0",
73
- "prosemirror-keymap": "^1.2.0",
74
- "prosemirror-model": "~1.18.3",
75
- "prosemirror-schema-list": "^1.2.2",
76
- "prosemirror-state": "^1.4.2",
77
- "prosemirror-transform": "^1.7.1",
78
- "prosemirror-view": "^1.30.0",
79
70
  "uuid": "^8.3.2",
80
71
  "y-prosemirror": "1.0.20",
81
72
  "y-protocols": "1.0.5",
@@ -104,5 +95,5 @@
104
95
  "access": "public",
105
96
  "registry": "https://registry.npmjs.org/"
106
97
  },
107
- "gitHead": "04fb17b9fd76a5a9a5a3476c0a1d441848110ea9"
98
+ "gitHead": "d1d1756de514dedd5ef9c0d297b45db9b5ba8d02"
108
99
  }
@@ -25,6 +25,11 @@ import { SuggestionsMenuFactory } from "./shared/plugins/suggestion/SuggestionsM
25
25
  import { BlockSideMenuFactory } from "./extensions/DraggableBlocks/BlockSideMenuFactoryTypes";
26
26
  import { Link } from "@tiptap/extension-link";
27
27
  import { SlashMenuItem } from "./extensions/SlashMenu/SlashMenuItem";
28
+ import { BackgroundColorMark } from "./extensions/BackgroundColor/BackgroundColorMark";
29
+ import { TextColorMark } from "./extensions/TextColor/TextColorMark";
30
+ import { BackgroundColorExtension } from "./extensions/BackgroundColor/BackgroundColorExtension";
31
+ import { TextColorExtension } from "./extensions/TextColor/TextColorExtension";
32
+ import { TextAlignmentExtension } from "./extensions/TextAlignment/TextAlignmentExtension";
28
33
 
29
34
  export type UiFactories = Partial<{
30
35
  formattingToolbarFactory: FormattingToolbarFactory;
@@ -70,6 +75,11 @@ export const getBlockNoteExtensions = (uiFactories: UiFactories) => {
70
75
  Italic,
71
76
  Strike,
72
77
  Underline,
78
+ TextColorMark,
79
+ TextColorExtension,
80
+ BackgroundColorMark,
81
+ BackgroundColorExtension,
82
+ TextAlignmentExtension,
73
83
 
74
84
  // custom blocks:
75
85
  ...blocks,
@@ -0,0 +1,61 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { getBlockInfoFromPos } from "../Blocks/helpers/getBlockInfoFromPos";
3
+
4
+ declare module "@tiptap/core" {
5
+ interface Commands<ReturnType> {
6
+ blockBackgroundColor: {
7
+ setBlockBackgroundColor: (
8
+ posInBlock: number,
9
+ color: string
10
+ ) => ReturnType;
11
+ };
12
+ }
13
+ }
14
+
15
+ export const BackgroundColorExtension = Extension.create({
16
+ name: "blockBackgroundColor",
17
+
18
+ addGlobalAttributes() {
19
+ return [
20
+ {
21
+ types: ["blockContainer"],
22
+ attributes: {
23
+ backgroundColor: {
24
+ default: "default",
25
+ parseHTML: (element) =>
26
+ element.hasAttribute("data-background-color")
27
+ ? element.getAttribute("data-background-color")
28
+ : "default",
29
+ renderHTML: (attributes) =>
30
+ attributes.backgroundColor !== "default" && {
31
+ "data-background-color": attributes.backgroundColor,
32
+ },
33
+ },
34
+ },
35
+ },
36
+ ];
37
+ },
38
+
39
+ addCommands() {
40
+ return {
41
+ setBlockBackgroundColor:
42
+ (posInBlock, color) =>
43
+ ({ state, view }) => {
44
+ const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);
45
+ if (blockInfo === undefined) {
46
+ return false;
47
+ }
48
+
49
+ state.tr.setNodeAttribute(
50
+ blockInfo.startPos - 1,
51
+ "backgroundColor",
52
+ color
53
+ );
54
+
55
+ view.focus();
56
+
57
+ return true;
58
+ },
59
+ };
60
+ },
61
+ });
@@ -0,0 +1,62 @@
1
+ import { Mark } from "@tiptap/core";
2
+
3
+ declare module "@tiptap/core" {
4
+ interface Commands<ReturnType> {
5
+ backgroundColor: {
6
+ setBackgroundColor: (color: string) => ReturnType;
7
+ };
8
+ }
9
+ }
10
+
11
+ export const BackgroundColorMark = Mark.create({
12
+ name: "backgroundColor",
13
+
14
+ addAttributes() {
15
+ return {
16
+ color: {
17
+ default: undefined,
18
+ parseHTML: (element) => element.getAttribute("data-background-color"),
19
+ renderHTML: (attributes) => ({
20
+ "data-background-color": attributes.color,
21
+ }),
22
+ },
23
+ };
24
+ },
25
+
26
+ parseHTML() {
27
+ return [
28
+ {
29
+ tag: "span",
30
+ getAttrs: (element) => {
31
+ if (typeof element === "string") {
32
+ return false;
33
+ }
34
+
35
+ if (element.hasAttribute("data-background-color")) {
36
+ return { color: element.getAttribute("data-background-color") };
37
+ }
38
+
39
+ return false;
40
+ },
41
+ },
42
+ ];
43
+ },
44
+
45
+ renderHTML({ HTMLAttributes }) {
46
+ return ["span", HTMLAttributes, 0];
47
+ },
48
+
49
+ addCommands() {
50
+ return {
51
+ setBackgroundColor:
52
+ (color) =>
53
+ ({ commands }) => {
54
+ if (color !== "default") {
55
+ return commands.setMark(this.name, { color: color });
56
+ }
57
+
58
+ return commands.unsetMark(this.name);
59
+ },
60
+ };
61
+ },
62
+ });
@@ -1,8 +1,4 @@
1
- import {
2
- combineTransactionSteps,
3
- findChildren,
4
- getChangedRanges,
5
- } from "@tiptap/core";
1
+ import { findChildren } from "@tiptap/core";
6
2
  import { Plugin, PluginKey } from "prosemirror-state";
7
3
  import { Decoration, DecorationSet } from "prosemirror-view";
8
4
 
@@ -33,7 +29,7 @@ export const PreviousBlockTypePlugin = () => {
33
29
  view(_editorView) {
34
30
  return {
35
31
  update: async (view, _prevState) => {
36
- if (this.key?.getState(view.state).needsUpdate) {
32
+ if (this.key?.getState(view.state).updatedBlocks.size > 0) {
37
33
  // use setTimeout 0 to clear the decorations so that at least
38
34
  // for one DOM-render the decorations have been applied
39
35
  setTimeout(() => {
@@ -48,111 +44,122 @@ export const PreviousBlockTypePlugin = () => {
48
44
  state: {
49
45
  init() {
50
46
  return {
51
- prevBlockAttrs: {} as any,
52
- needsUpdate: false,
47
+ // Block attributes, by block ID, from just before the previous transaction.
48
+ prevTransactionOldBlockAttrs: {} as any,
49
+ // Block attributes, by block ID, from just before the current transaction.
50
+ currentTransactionOldBlockAttrs: {} as any,
51
+ // Set of IDs of blocks whose attributes changed from the current transaction.
52
+ updatedBlocks: new Set<string>(),
53
53
  };
54
54
  },
55
55
 
56
56
  apply(transaction, prev, oldState, newState) {
57
- prev.needsUpdate = false;
58
- prev.prevBlockAttrs = {};
57
+ prev.currentTransactionOldBlockAttrs = {};
58
+ prev.updatedBlocks.clear();
59
+
59
60
  if (!transaction.docChanged || oldState.doc.eq(newState.doc)) {
60
61
  return prev;
61
62
  }
62
63
 
63
- const transform = combineTransactionSteps(oldState.doc, [transaction]);
64
- // const { mapping } = transform;
65
- const changes = getChangedRanges(transform);
66
-
67
- // TODO: instead of iterating through the entire document, only check nodes affected by the transactions
64
+ // TODO: Instead of iterating through the entire document, only check nodes affected by the transactions. Will
65
+ // also probably require checking nodes affected by the previous transaction too.
68
66
  // We didn't get this to work yet:
67
+ // const transform = combineTransactionSteps(oldState.doc, [transaction]);
68
+ // // const { mapping } = transform;
69
+ // const changes = getChangedRanges(transform);
70
+ //
69
71
  // changes.forEach(({ oldRange, newRange }) => {
70
72
  // const oldNodes = findChildrenInRange(
71
73
  // oldState.doc,
72
74
  // oldRange,
73
75
  // (node) => node.attrs.id
74
76
  // );
75
-
77
+ //
76
78
  // const newNodes = findChildrenInRange(
77
79
  // newState.doc,
78
80
  // newRange,
79
81
  // (node) => node.attrs.id
80
82
  // );
81
83
 
82
- changes.forEach(() => {
83
- const oldNodes = findChildren(oldState.doc, (node) => node.attrs.id);
84
- const oldNodesById = new Map(
85
- oldNodes.map((node) => [node.node.attrs.id, node])
86
- );
87
-
88
- const newNodes = findChildren(newState.doc, (node) => node.attrs.id);
89
-
90
- for (let node of newNodes) {
91
- const oldNode = oldNodesById.get(node.node.attrs.id);
92
- const oldContentNode = oldNode?.node.firstChild;
93
- const newContentNode = node.node.firstChild;
94
- if (oldNode && oldContentNode && newContentNode) {
95
- const newAttrs = {
96
- index: newContentNode.attrs.index,
97
- level: newContentNode.attrs.level,
98
- type: newContentNode.type.name,
99
- depth: newState.doc.resolve(node.pos).depth,
100
- };
101
-
102
- const oldAttrs = {
103
- index: oldContentNode.attrs.index,
104
- level: oldContentNode.attrs.level,
105
- type: oldContentNode.type.name,
106
- depth: oldState.doc.resolve(oldNode.pos).depth,
107
- };
108
-
109
- // Hacky fix to avoid processing certain transactions created by the numbered list indexing plugin.
110
-
111
- // True when an existing numbered list item is assigned an index for the first time, which happens
112
- // immediately after it's created. Using this condition to start an animation ensures it's not
113
- // immediately overridden by a different transaction created by the numbered list indexing plugin.
114
- const indexInitialized =
115
- oldAttrs.index === null && newAttrs.index !== null;
116
-
117
- // True when an existing numbered list item changes nesting levels, before its index is updated by the
118
- // numbered list indexing plugin. This condition ensures that animations for indentation still work with
119
- // numbered list items, while preventing unnecessary animations being done when dragging/dropping them.
120
- const depthChanged =
121
- oldAttrs.index !== null &&
122
- newAttrs.index !== null &&
123
- oldAttrs.index === newAttrs.index;
124
-
125
- // Only false for transactions in which the block remains a numbered list item before & after, but neither
126
- // of the previous conditions apply.
127
- const shouldUpdate =
128
- oldAttrs.type === "numberedListItem" &&
129
- newAttrs.type === "numberedListItem"
130
- ? indexInitialized || depthChanged
131
- : true;
132
-
133
- if (
134
- JSON.stringify(oldAttrs) !== JSON.stringify(newAttrs) && // TODO: faster deep equal?
135
- shouldUpdate
136
- ) {
137
- (oldAttrs as any)["depth-change"] =
138
- oldAttrs.depth - newAttrs.depth;
139
- prev.prevBlockAttrs[node.node.attrs.id] = oldAttrs;
140
-
141
- // for debugging:
142
- console.log(
143
- "id:",
144
- node.node.attrs.id,
145
- "previousBlockTypePlugin changes detected, oldAttrs",
146
- oldAttrs,
147
- "new",
148
- newAttrs
149
- );
150
-
151
- prev.needsUpdate = true;
84
+ const currentTransactionOriginalOldBlockAttrs = {} as any;
85
+
86
+ const oldNodes = findChildren(oldState.doc, (node) => node.attrs.id);
87
+ const oldNodesById = new Map(
88
+ oldNodes.map((node) => [node.node.attrs.id, node])
89
+ );
90
+ const newNodes = findChildren(newState.doc, (node) => node.attrs.id);
91
+
92
+ // Traverses all block containers in the new editor state.
93
+ for (let node of newNodes) {
94
+ const oldNode = oldNodesById.get(node.node.attrs.id);
95
+
96
+ const oldContentNode = oldNode?.node.firstChild;
97
+ const newContentNode = node.node.firstChild;
98
+
99
+ if (oldNode && oldContentNode && newContentNode) {
100
+ const newAttrs = {
101
+ index: newContentNode.attrs.index,
102
+ level: newContentNode.attrs.level,
103
+ type: newContentNode.type.name,
104
+ depth: newState.doc.resolve(node.pos).depth,
105
+ };
106
+
107
+ let oldAttrs = {
108
+ index: oldContentNode.attrs.index,
109
+ level: oldContentNode.attrs.level,
110
+ type: oldContentNode.type.name,
111
+ depth: oldState.doc.resolve(oldNode.pos).depth,
112
+ };
113
+
114
+ currentTransactionOriginalOldBlockAttrs[node.node.attrs.id] =
115
+ oldAttrs;
116
+
117
+ // Whenever a transaction is appended by the OrderedListItemIndexPlugin, it's given the metadata:
118
+ // { "orderedListIndexing": true }
119
+ // These appended transactions happen immediately after any transaction which causes ordered list item
120
+ // indices to require updating, including those which trigger animations. Therefore, these animations are
121
+ // immediately overridden when the PreviousBlockTypePlugin processes the appended transaction, despite only
122
+ // the listItemIndex attribute changing. To solve this, oldAttrs must be edited for transactions with the
123
+ // "orderedListIndexing" metadata, so the correct animation can be re-triggered.
124
+ if (transaction.getMeta("numberedListIndexing")) {
125
+ // If the block existed before the transaction, gets the attributes from before the previous transaction
126
+ // (i.e. the transaction that caused list item indices to need updating).
127
+ if (node.node.attrs.id in prev.prevTransactionOldBlockAttrs) {
128
+ oldAttrs =
129
+ prev.prevTransactionOldBlockAttrs[node.node.attrs.id];
130
+ }
131
+
132
+ // Stops list item indices themselves being animated (looks smoother), unless the block's content type is
133
+ // changing from a numbered list item to something else.
134
+ if (newAttrs.type === "numberedListItem") {
135
+ oldAttrs.index = newAttrs.index;
152
136
  }
153
137
  }
138
+
139
+ prev.currentTransactionOldBlockAttrs[node.node.attrs.id] = oldAttrs;
140
+
141
+ // TODO: faster deep equal?
142
+ if (JSON.stringify(oldAttrs) !== JSON.stringify(newAttrs)) {
143
+ (oldAttrs as any)["depth-change"] =
144
+ oldAttrs.depth - newAttrs.depth;
145
+
146
+ // for debugging:
147
+ // console.log(
148
+ // "id:",
149
+ // node.node.attrs.id,
150
+ // "previousBlockTypePlugin changes detected, oldAttrs",
151
+ // oldAttrs,
152
+ // "new",
153
+ // newAttrs
154
+ // );
155
+
156
+ prev.updatedBlocks.add(node.node.attrs.id);
157
+ }
154
158
  }
155
- });
159
+ }
160
+
161
+ prev.prevTransactionOldBlockAttrs =
162
+ currentTransactionOriginalOldBlockAttrs;
156
163
 
157
164
  return prev;
158
165
  },
@@ -160,7 +167,7 @@ export const PreviousBlockTypePlugin = () => {
160
167
  props: {
161
168
  decorations(state) {
162
169
  const pluginState = (this as Plugin).getState(state);
163
- if (!pluginState.needsUpdate) {
170
+ if (pluginState.updatedBlocks.size === 0) {
164
171
  return undefined;
165
172
  }
166
173
 
@@ -170,25 +177,28 @@ export const PreviousBlockTypePlugin = () => {
170
177
  if (!node.attrs.id) {
171
178
  return;
172
179
  }
173
- const prevAttrs = pluginState.prevBlockAttrs[node.attrs.id];
174
- if (!prevAttrs) {
180
+
181
+ if (!pluginState.updatedBlocks.has(node.attrs.id)) {
175
182
  return;
176
183
  }
177
184
 
178
- const decorationAttributes: any = {};
185
+ const prevAttrs =
186
+ pluginState.currentTransactionOldBlockAttrs[node.attrs.id];
187
+ const decorationAttrs: any = {};
188
+
179
189
  for (let [nodeAttr, val] of Object.entries(prevAttrs)) {
180
- decorationAttributes["data-prev-" + nodeAttributes[nodeAttr]] =
190
+ decorationAttrs["data-prev-" + nodeAttributes[nodeAttr]] =
181
191
  val || "none";
182
192
  }
183
193
 
184
194
  // for debugging:
185
- console.log(
186
- "previousBlockTypePlugin committing decorations",
187
- decorationAttributes
188
- );
195
+ // console.log(
196
+ // "previousBlockTypePlugin committing decorations",
197
+ // decorationAttrs
198
+ // );
189
199
 
190
200
  const decoration = Decoration.node(pos, pos + node.nodeSize, {
191
- ...decorationAttributes,
201
+ ...decorationAttrs,
192
202
  });
193
203
 
194
204
  decorations.push(decoration);
@@ -10,12 +10,6 @@ BASIC STYLES
10
10
  font-weight: normal;
11
11
  }
12
12
 
13
- .block {
14
- border-left: 2px solid white;
15
- border-color: white;
16
- transition: all 0.2s;
17
- }
18
-
19
13
  .block {
20
14
  /* content: ""; */
21
15
  transition: all 0.2s;
@@ -268,3 +262,94 @@ NESTED BLOCKS
268
262
  > :first-child:before {
269
263
  content: "List";
270
264
  }
265
+
266
+ /* TEXT COLORS */
267
+ [data-text-color="gray"] {
268
+ color: #9b9a97;
269
+ }
270
+
271
+ [data-text-color="brown"] {
272
+ color: #64473a;
273
+ }
274
+
275
+ [data-text-color="red"] {
276
+ color: #e03e3e;
277
+ }
278
+
279
+ [data-text-color="orange"] {
280
+ color: #d9730d;
281
+ }
282
+
283
+ [data-text-color="yellow"] {
284
+ color: #dfab01;
285
+ }
286
+
287
+ [data-text-color="green"] {
288
+ color: #4d6461;
289
+ }
290
+
291
+ [data-text-color="blue"] {
292
+ color: #0b6e99;
293
+ }
294
+
295
+ [data-text-color="purple"] {
296
+ color: #6940a5;
297
+ }
298
+
299
+ [data-text-color="pink"] {
300
+ color: #ad1a72;
301
+ }
302
+
303
+ /* BACKGROUND COLORS */
304
+ [data-background-color="gray"] {
305
+ background-color: #ebeced;
306
+ }
307
+
308
+ [data-background-color="brown"] {
309
+ background-color: #e9e5e3;
310
+ }
311
+
312
+ [data-background-color="red"] {
313
+ background-color: #fbe4e4;
314
+ }
315
+
316
+ [data-background-color="orange"] {
317
+ background-color: #faebdd;
318
+ }
319
+
320
+ [data-background-color="yellow"] {
321
+ background-color: #fbf3db;
322
+ }
323
+
324
+ [data-background-color="green"] {
325
+ background-color: #ddedea;
326
+ }
327
+
328
+ [data-background-color="blue"] {
329
+ background-color: #ddebf1;
330
+ }
331
+
332
+ [data-background-color="purple"] {
333
+ background-color: #eae4f2;
334
+ }
335
+
336
+ [data-background-color="pink"] {
337
+ background-color: #f4dfeb;
338
+ }
339
+
340
+ /* TEXT ALIGNMENT */
341
+ [data-text-alignment="left"] {
342
+ text-align: left;
343
+ }
344
+
345
+ [data-text-alignment="center"] {
346
+ text-align: center;
347
+ }
348
+
349
+ [data-text-alignment="right"] {
350
+ text-align: right;
351
+ }
352
+
353
+ [data-text-alignment="justify"] {
354
+ text-align: justify;
355
+ }