@blocknote/core 0.25.1 → 0.26.0

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 (65) hide show
  1. package/dist/blocknote.cjs +7 -7
  2. package/dist/blocknote.cjs.map +1 -1
  3. package/dist/blocknote.js +781 -646
  4. package/dist/blocknote.js.map +1 -1
  5. package/dist/comments.cjs +1 -1
  6. package/dist/comments.cjs.map +1 -1
  7. package/dist/comments.js +45 -44
  8. package/dist/comments.js.map +1 -1
  9. package/dist/style.css +1 -1
  10. package/dist/tsconfig.tsbuildinfo +1 -1
  11. package/dist/webpack-stats.json +1 -1
  12. package/package.json +2 -2
  13. package/src/api/nodeConversions/nodeToBlock.ts +3 -2
  14. package/src/api/parsers/html/__snapshots__/parse-2-tables.json +129 -0
  15. package/src/api/parsers/html/parseHTML.test.ts +35 -0
  16. package/src/comments/threadstore/ThreadStore.ts +1 -1
  17. package/src/comments/threadstore/yjs/YjsThreadStore.ts +1 -0
  18. package/src/comments/threadstore/yjs/yjsHelpers.ts +3 -1
  19. package/src/comments/types.ts +4 -0
  20. package/src/editor/Block.css +1 -1
  21. package/src/editor/BlockNoteEditor.ts +1 -7
  22. package/src/editor/BlockNoteTipTapEditor.ts +18 -7
  23. package/src/extensions/Comments/CommentMark.ts +0 -1
  24. package/src/extensions/Comments/CommentsPlugin.ts +79 -30
  25. package/src/extensions/SideMenu/dragging.ts +13 -0
  26. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +6 -2
  27. package/src/extensions/TableHandles/TableHandlesPlugin.ts +25 -26
  28. package/src/i18n/locales/ar.ts +4 -0
  29. package/src/i18n/locales/de.ts +15 -1
  30. package/src/i18n/locales/en.ts +4 -0
  31. package/src/i18n/locales/es.ts +15 -1
  32. package/src/i18n/locales/fr.ts +4 -0
  33. package/src/i18n/locales/hr.ts +21 -4
  34. package/src/i18n/locales/is.ts +4 -0
  35. package/src/i18n/locales/it.ts +15 -1
  36. package/src/i18n/locales/ja.ts +4 -0
  37. package/src/i18n/locales/ko.ts +4 -0
  38. package/src/i18n/locales/nl.ts +4 -0
  39. package/src/i18n/locales/no.ts +4 -0
  40. package/src/i18n/locales/pl.ts +4 -0
  41. package/src/i18n/locales/pt.ts +4 -0
  42. package/src/i18n/locales/ru.ts +4 -0
  43. package/src/i18n/locales/uk.ts +4 -0
  44. package/src/i18n/locales/vi.ts +4 -0
  45. package/src/i18n/locales/zh.ts +4 -0
  46. package/types/src/comments/threadstore/ThreadStore.d.ts +1 -1
  47. package/types/src/comments/types.d.ts +4 -0
  48. package/types/src/editor/BlockNoteTipTapEditor.d.ts +2 -1
  49. package/types/src/extensions/Comments/CommentsPlugin.d.ts +16 -1
  50. package/types/src/extensions/Comments/threadstore/DefaultThreadStoreAuth.d.ts +47 -0
  51. package/types/src/extensions/Comments/threadstore/ThreadStore.d.ts +121 -0
  52. package/types/src/extensions/Comments/threadstore/ThreadStoreAuth.d.ts +12 -0
  53. package/types/src/extensions/Comments/threadstore/TipTapThreadStore.d.ts +97 -0
  54. package/types/src/extensions/Comments/threadstore/yjs/RESTYjsThreadStore.d.ts +83 -0
  55. package/types/src/extensions/Comments/threadstore/yjs/YjsThreadStore.d.ts +79 -0
  56. package/types/src/extensions/Comments/threadstore/yjs/YjsThreadStore.test.d.ts +1 -0
  57. package/types/src/extensions/Comments/threadstore/yjs/YjsThreadStoreBase.d.ts +15 -0
  58. package/types/src/extensions/Comments/threadstore/yjs/yjsHelpers.d.ts +13 -0
  59. package/types/src/extensions/Comments/types.d.ts +109 -0
  60. package/types/src/i18n/locales/de.d.ts +2 -304
  61. package/types/src/i18n/locales/en.d.ts +4 -0
  62. package/types/src/i18n/locales/es.d.ts +2 -269
  63. package/types/src/i18n/locales/hr.d.ts +2 -266
  64. package/types/src/i18n/locales/it.d.ts +2 -269
  65. package/types/src/models/User.d.ts +5 -0
@@ -16,11 +16,6 @@ const PLUGIN_KEY = new PluginKey(`blocknote-comments`);
16
16
  const SET_SELECTED_THREAD_ID = "SET_SELECTED_THREAD_ID";
17
17
 
18
18
  type CommentsPluginState = {
19
- /**
20
- * Store the positions of all threads in the document.
21
- * this can be used later to implement a floating sidebar
22
- */
23
- threadPositions: Map<string, { from: number; to: number }>;
24
19
  /**
25
20
  * Decorations to be rendered, specifically to indicate the selected thread
26
21
  */
@@ -28,15 +23,11 @@ type CommentsPluginState = {
28
23
  };
29
24
 
30
25
  /**
31
- * Get a new state (theadPositions and decorations) from the current document state
26
+ * Calculate the thread positions from the current document state
32
27
  */
33
- function updateState(
34
- doc: Node,
35
- selectedThreadId: string | undefined,
36
- markType: string
37
- ): CommentsPluginState {
28
+ function getUpdatedThreadPositions(doc: Node, markType: string) {
38
29
  const threadPositions = new Map<string, { from: number; to: number }>();
39
- const decorations: Decoration[] = [];
30
+
40
31
  // find all thread marks and store their position + create decoration for selected thread
41
32
  doc.descendants((node, pos) => {
42
33
  node.marks.forEach((mark) => {
@@ -59,34 +50,38 @@ function updateState(
59
50
  from: Math.min(from, currentPosition.from),
60
51
  to: Math.max(to, currentPosition.to),
61
52
  });
62
-
63
- if (selectedThreadId === thisThreadId) {
64
- decorations.push(
65
- Decoration.inline(from, to, {
66
- class: "bn-thread-mark-selected",
67
- })
68
- );
69
- }
70
53
  }
71
54
  });
72
55
  });
73
- return {
74
- decorations: DecorationSet.create(doc, decorations),
75
- threadPositions,
76
- };
56
+ return threadPositions;
77
57
  }
78
58
 
79
59
  export class CommentsPlugin extends EventEmitter<any> {
80
60
  public readonly plugin: Plugin;
81
61
  public readonly userStore: UserStore<User>;
82
62
 
63
+ /**
64
+ * Whether a comment is currently being composed
65
+ */
83
66
  private pendingComment = false;
67
+
68
+ /**
69
+ * The currently selected thread id
70
+ */
84
71
  private selectedThreadId: string | undefined;
85
72
 
73
+ /**
74
+ * Store the positions of all threads in the document.
75
+ * this can be used later to implement a floating sidebar
76
+ */
77
+ private threadPositions: Map<string, { from: number; to: number }> =
78
+ new Map();
79
+
86
80
  private emitStateUpdate() {
87
81
  this.emit("update", {
88
82
  selectedThreadId: this.selectedThreadId,
89
83
  pendingComment: this.pendingComment,
84
+ threadPositions: this.threadPositions,
90
85
  });
91
86
  }
92
87
 
@@ -168,18 +163,51 @@ export class CommentsPlugin extends EventEmitter<any> {
168
163
  state: {
169
164
  init() {
170
165
  return {
171
- threadPositions: new Map<string, { from: number; to: number }>(),
172
166
  decorations: DecorationSet.empty,
173
167
  };
174
168
  },
175
169
  apply(tr, state) {
176
170
  const action = tr.getMeta(PLUGIN_KEY);
171
+
177
172
  if (!tr.docChanged && !action) {
178
173
  return state;
179
174
  }
180
175
 
181
- // The doc changed or the selected thread changed
182
- return updateState(tr.doc, self.selectedThreadId, markType);
176
+ // only update threadPositions if the doc changed
177
+ const threadPositions = tr.docChanged
178
+ ? getUpdatedThreadPositions(tr.doc, self.markType)
179
+ : self.threadPositions;
180
+
181
+ if (threadPositions.size > 0 || self.threadPositions.size > 0) {
182
+ // small optimization; don't emit event if threadPositions before / after were both empty
183
+ self.threadPositions = threadPositions;
184
+ self.emitStateUpdate();
185
+ }
186
+
187
+ // update decorations if doc or selected thread changed
188
+ const decorations = [];
189
+
190
+ if (self.selectedThreadId) {
191
+ const selectedThreadPosition = threadPositions.get(
192
+ self.selectedThreadId
193
+ );
194
+
195
+ if (selectedThreadPosition) {
196
+ decorations.push(
197
+ Decoration.inline(
198
+ selectedThreadPosition.from,
199
+ selectedThreadPosition.to,
200
+ {
201
+ class: "bn-thread-mark-selected",
202
+ }
203
+ )
204
+ );
205
+ }
206
+ }
207
+
208
+ return {
209
+ decorations: DecorationSet.create(tr.doc, decorations),
210
+ };
183
211
  },
184
212
  },
185
213
  props: {
@@ -206,7 +234,7 @@ export class CommentsPlugin extends EventEmitter<any> {
206
234
  );
207
235
 
208
236
  const threadId = commentMark?.attrs.threadId as string | undefined;
209
- self.selectThread(threadId);
237
+ self.selectThread(threadId, false);
210
238
  },
211
239
  },
212
240
  });
@@ -219,6 +247,7 @@ export class CommentsPlugin extends EventEmitter<any> {
219
247
  callback: (state: {
220
248
  pendingComment: boolean;
221
249
  selectedThreadId: string | undefined;
250
+ threadPositions: Map<string, { from: number; to: number }>;
222
251
  }) => void
223
252
  ) {
224
253
  return this.on("update", callback);
@@ -227,7 +256,7 @@ export class CommentsPlugin extends EventEmitter<any> {
227
256
  /**
228
257
  * Set the selected thread
229
258
  */
230
- public selectThread(threadId: string | undefined) {
259
+ public selectThread(threadId: string | undefined, scrollToThread = true) {
231
260
  if (this.selectedThreadId === threadId) {
232
261
  return;
233
262
  }
@@ -238,6 +267,24 @@ export class CommentsPlugin extends EventEmitter<any> {
238
267
  name: SET_SELECTED_THREAD_ID,
239
268
  })
240
269
  );
270
+
271
+ if (threadId && scrollToThread) {
272
+ const selectedThreadPosition = this.threadPositions.get(threadId);
273
+
274
+ if (!selectedThreadPosition) {
275
+ return;
276
+ }
277
+
278
+ // When a new thread is selected, scrolls the page to its reference text in
279
+ // the editor.
280
+ (
281
+ this.editor.prosemirrorView?.domAtPos(selectedThreadPosition.from)
282
+ .node as Element | undefined
283
+ )?.scrollIntoView({
284
+ behavior: "smooth",
285
+ block: "center",
286
+ });
287
+ }
241
288
  }
242
289
 
243
290
  /**
@@ -283,7 +330,9 @@ export class CommentsPlugin extends EventEmitter<any> {
283
330
  head: pmSelection.head,
284
331
  anchor: pmSelection.anchor,
285
332
  },
286
- yjs: getRelativeSelection(ystate.binding, view.state),
333
+ yjs: ystate
334
+ ? getRelativeSelection(ystate.binding, view.state)
335
+ : undefined, // if we're not using yjs
287
336
  };
288
337
 
289
338
  await this.threadStore.addThreadToDocument({
@@ -99,6 +99,19 @@ function setDragImage(view: EditorView, from: number, to = from) {
99
99
  unsetDragImage(view.root);
100
100
  dragImageElement = parentClone;
101
101
 
102
+ // Browsers may have CORS policies which prevents iframes from being
103
+ // manipulated, so better to stay on the safe side and remove them from the
104
+ // drag preview. The drag preview doesn't work with iframes anyway.
105
+ const iframes = dragImageElement.getElementsByTagName("iframe");
106
+ for (let i = 0; i < iframes.length; i++) {
107
+ const iframe = iframes[i];
108
+ const parent = iframe.parentElement;
109
+
110
+ if (parent) {
111
+ parent.removeChild(iframe);
112
+ }
113
+ }
114
+
102
115
  // TODO: This is hacky, need a better way of assigning classes to the editor so that they can also be applied to the
103
116
  // drag preview.
104
117
  const classes = view.dom.className.split(" ");
@@ -20,11 +20,15 @@ function setSelectionToNextContentEditableBlock<
20
20
  I extends InlineContentSchema,
21
21
  S extends StyleSchema
22
22
  >(editor: BlockNoteEditor<BSchema, I, S>) {
23
- let block = editor.getTextCursorPosition().block;
23
+ let block: Block<BSchema, I, S> | undefined =
24
+ editor.getTextCursorPosition().block;
24
25
  let contentType = editor.schema.blockSchema[block.type].content;
25
26
 
26
27
  while (contentType === "none") {
27
- block = editor.getTextCursorPosition().nextBlock!;
28
+ block = editor.getTextCursorPosition().nextBlock;
29
+ if (block === undefined) {
30
+ return;
31
+ }
28
32
  contentType = editor.schema.blockSchema[block.type].content as
29
33
  | "inline"
30
34
  | "table"
@@ -1,10 +1,10 @@
1
1
  import { Plugin, PluginKey, PluginView } from "prosemirror-state";
2
2
  import {
3
+ CellSelection,
3
4
  addColumnAfter,
4
5
  addColumnBefore,
5
6
  addRowAfter,
6
7
  addRowBefore,
7
- CellSelection,
8
8
  deleteColumn,
9
9
  deleteRow,
10
10
  mergeCells,
@@ -12,6 +12,7 @@ import {
12
12
  } from "prosemirror-tables";
13
13
  import { Decoration, DecorationSet, EditorView } from "prosemirror-view";
14
14
  import {
15
+ RelativeCellIndices,
15
16
  addRowsOrColumns,
16
17
  areInSameColumn,
17
18
  canColumnBeDraggedInto,
@@ -22,7 +23,6 @@ import {
22
23
  getDimensionsOfTable,
23
24
  moveColumn,
24
25
  moveRow,
25
- RelativeCellIndices,
26
26
  } from "../../api/blockManipulation/tables/tables.js";
27
27
  import { nodeToBlock } from "../../api/nodeConversions/nodeToBlock.js";
28
28
  import { getNodeById } from "../../api/nodeUtil.js";
@@ -394,9 +394,7 @@ export class TableHandlesView<
394
394
  (element) => element.tagName === "TD" || element.tagName === "TH"
395
395
  );
396
396
  if (tableCellElements.length === 0) {
397
- throw new Error(
398
- "Could not find table cell element that the mouse cursor is hovering over."
399
- );
397
+ return;
400
398
  }
401
399
  const tableCellElement = tableCellElements[0];
402
400
 
@@ -541,7 +539,12 @@ export class TableHandlesView<
541
539
 
542
540
  // Hide handles if the table block has been removed.
543
541
  this.state.block = this.editor.getBlock(this.state.block.id)!;
544
- if (!this.state.block) {
542
+ if (
543
+ !this.state.block ||
544
+ // when collaborating, the table element might be replaced and out of date
545
+ // because yjs replaces the element when for example you change the color via the side menu
546
+ !this.tableElement?.isConnected
547
+ ) {
545
548
  this.state.show = false;
546
549
  this.state.showAddOrRemoveRowsButton = false;
547
550
  this.state.showAddOrRemoveColumnsButton = false;
@@ -571,6 +574,7 @@ export class TableHandlesView<
571
574
 
572
575
  // Update bounding boxes.
573
576
  const tableBody = this.tableElement!.querySelector("tbody");
577
+
574
578
  if (!tableBody) {
575
579
  throw new Error(
576
580
  "Table block does not contain a 'tbody' HTML element. This should never happen."
@@ -658,32 +662,27 @@ export class TableHandlesProsemirrorPlugin<
658
662
  }
659
663
 
660
664
  const decorations: Decoration[] = [];
661
-
662
- if (newIndex === this.view.state.draggingState.originalIndex) {
663
- return DecorationSet.create(state.doc, decorations);
664
- } else if (
665
- this.view.state.draggingState.draggedCellOrientation === "row" &&
666
- !canRowBeDraggedInto(
667
- this.view.state.block,
668
- this.view.state.draggingState.originalIndex,
669
- newIndex
670
- )
671
- ) {
672
- return DecorationSet.create(state.doc, decorations);
673
- } else if (
674
- this.view.state.draggingState.draggedCellOrientation === "col" &&
675
- !canColumnBeDraggedInto(
676
- this.view.state.block,
677
- this.view.state.draggingState.originalIndex,
678
- newIndex
679
- )
665
+ const { block, draggingState } = this.view.state;
666
+ const { originalIndex, draggedCellOrientation } = draggingState;
667
+
668
+ // Return empty decorations if:
669
+ // - Dragging to same position
670
+ // - No block exists
671
+ // - Row drag not allowed
672
+ // - Column drag not allowed
673
+ if (
674
+ newIndex === originalIndex ||
675
+ !block ||
676
+ (draggedCellOrientation === "row" &&
677
+ !canRowBeDraggedInto(block, originalIndex, newIndex)) ||
678
+ (draggedCellOrientation === "col" &&
679
+ !canColumnBeDraggedInto(block, originalIndex, newIndex))
680
680
  ) {
681
681
  return DecorationSet.create(state.doc, decorations);
682
682
  }
683
683
 
684
684
  // Gets the table to show the drop cursor in.
685
685
  const tableResolvedPos = state.doc.resolve(this.view.tablePos + 1);
686
- const originalIndex = this.view.state.draggingState.originalIndex;
687
686
 
688
687
  if (this.view.state.draggingState.draggedCellOrientation === "row") {
689
688
  const cellsInRow = getCellsAtRowHandle(
@@ -325,6 +325,10 @@ export const ar: Dictionary = {
325
325
  reactions: {
326
326
  reacted_by: "تفاعل بواسطة",
327
327
  },
328
+ sidebar: {
329
+ marked_as_resolved: "تم وضع علامة كتم الحل",
330
+ more_replies: (count) => `${count} ردود أخرى`,
331
+ },
328
332
  },
329
333
  generic: {
330
334
  ctrl_shortcut: "Ctrl",
@@ -1,4 +1,6 @@
1
- export const de = {
1
+ import { Dictionary } from "../dictionary.js";
2
+
3
+ export const de: Dictionary = {
2
4
  slash_menu: {
3
5
  heading: {
4
6
  title: "Überschrift 1",
@@ -154,6 +156,8 @@ export const de = {
154
156
  drag_handle: {
155
157
  delete_menuitem: "Löschen",
156
158
  colors_menuitem: "Farben",
159
+ header_row_menuitem: "Kopfzeile",
160
+ header_column_menuitem: "Kopfspalte",
157
161
  },
158
162
  table_handle: {
159
163
  delete_column_menuitem: "Spalte löschen",
@@ -162,6 +166,9 @@ export const de = {
162
166
  add_right_menuitem: "Spalte rechts hinzufügen",
163
167
  add_above_menuitem: "Zeile oberhalb hinzufügen",
164
168
  add_below_menuitem: "Zeile unterhalb hinzufügen",
169
+ split_cell_menuitem: "Zelle teilen",
170
+ merge_cells_menuitem: "Zellen zusammenführen",
171
+ background_color_menuitem: "Hintergrundfarbe",
165
172
  },
166
173
  suggestion_menu: {
167
174
  no_items_title: "Keine Elemente gefunden",
@@ -276,6 +283,9 @@ export const de = {
276
283
  align_justify: {
277
284
  tooltip: "Text Blocksatz",
278
285
  },
286
+ table_cell_merge: {
287
+ tooltip: "Zellen zusammenführen",
288
+ },
279
289
  comment: {
280
290
  tooltip: "Kommentar hinzufügen",
281
291
  },
@@ -329,6 +339,10 @@ export const de = {
329
339
  reactions: {
330
340
  reacted_by: "Reagiert von",
331
341
  },
342
+ sidebar: {
343
+ marked_as_resolved: "Als gelöst markiert",
344
+ more_replies: (count) => `${count} weitere Antworten`,
345
+ },
332
346
  },
333
347
  generic: {
334
348
  ctrl_shortcut: "Strg",
@@ -340,6 +340,10 @@ export const en = {
340
340
  reactions: {
341
341
  reacted_by: "Reacted by",
342
342
  },
343
+ sidebar: {
344
+ marked_as_resolved: "Marked as resolved",
345
+ more_replies: (count: number) => `${count} more replies`,
346
+ },
343
347
  },
344
348
  generic: {
345
349
  ctrl_shortcut: "Ctrl",
@@ -1,4 +1,6 @@
1
- export const es = {
1
+ import { Dictionary } from "../dictionary.js";
2
+
3
+ export const es: Dictionary = {
2
4
  slash_menu: {
3
5
  heading: {
4
6
  title: "Encabezado 1",
@@ -153,6 +155,8 @@ export const es = {
153
155
  drag_handle: {
154
156
  delete_menuitem: "Eliminar",
155
157
  colors_menuitem: "Colores",
158
+ header_row_menuitem: "Fila de encabezado",
159
+ header_column_menuitem: "Columna de encabezado",
156
160
  },
157
161
  table_handle: {
158
162
  delete_column_menuitem: "Eliminar columna",
@@ -161,6 +165,9 @@ export const es = {
161
165
  add_right_menuitem: "Agregar columna a la derecha",
162
166
  add_above_menuitem: "Agregar fila arriba",
163
167
  add_below_menuitem: "Agregar fila abajo",
168
+ split_cell_menuitem: "Dividir celda",
169
+ merge_cells_menuitem: "Combinar celdas",
170
+ background_color_menuitem: "Color de fondo",
164
171
  },
165
172
  suggestion_menu: {
166
173
  no_items_title: "No se encontraron elementos",
@@ -275,6 +282,9 @@ export const es = {
275
282
  align_justify: {
276
283
  tooltip: "Justificar texto",
277
284
  },
285
+ table_cell_merge: {
286
+ tooltip: "Combinar celdas",
287
+ },
278
288
  comment: {
279
289
  tooltip: "Añadir comentario",
280
290
  },
@@ -328,6 +338,10 @@ export const es = {
328
338
  reactions: {
329
339
  reacted_by: "Reaccionado por",
330
340
  },
341
+ sidebar: {
342
+ marked_as_resolved: "Marcado como resuelto",
343
+ more_replies: (count) => `${count} respuestas más`,
344
+ },
331
345
  },
332
346
  generic: {
333
347
  ctrl_shortcut: "Ctrl",
@@ -364,6 +364,10 @@ export const fr: Dictionary = {
364
364
  reactions: {
365
365
  reacted_by: "Réagi par",
366
366
  },
367
+ sidebar: {
368
+ marked_as_resolved: "Marqué comme résolu",
369
+ more_replies: (count) => `${count} réponses de plus`,
370
+ },
367
371
  },
368
372
  generic: {
369
373
  ctrl_shortcut: "Ctrl",
@@ -1,4 +1,6 @@
1
- export const hr = {
1
+ import { Dictionary } from "../dictionary.js";
2
+
3
+ export const hr: Dictionary = {
2
4
  slash_menu: {
3
5
  heading: {
4
6
  title: "Naslov 1",
@@ -68,6 +70,12 @@ export const hr = {
68
70
  aliases: ["tablica"],
69
71
  group: "Napredno",
70
72
  },
73
+ code_block: {
74
+ title: "Blok koda",
75
+ subtext: "Blok koda sa sintaksnim isticanjem",
76
+ aliases: ["code", "pre"],
77
+ group: "Osnovni blokovi",
78
+ },
71
79
  page_break: {
72
80
  title: "Prijelom stranice",
73
81
  subtext: "Razdjelnik stranice",
@@ -128,9 +136,6 @@ export const hr = {
128
136
  aliases: ["emoji", "emotikon", "emocija", "lice"],
129
137
  group: "Ostalo",
130
138
  },
131
- comment: {
132
- tooltip: "Dodaj komentar",
133
- },
134
139
  },
135
140
  placeholders: {
136
141
  default: "Unesi tekst ili upiši ‘/’ za naredbe",
@@ -164,6 +169,8 @@ export const hr = {
164
169
  drag_handle: {
165
170
  delete_menuitem: "Ukloni",
166
171
  colors_menuitem: "Boje",
172
+ header_row_menuitem: "Zaglavni redak",
173
+ header_column_menuitem: "Zaglavni stupac",
167
174
  },
168
175
  table_handle: {
169
176
  delete_column_menuitem: "Ukloni stupac",
@@ -172,6 +179,9 @@ export const hr = {
172
179
  add_right_menuitem: "Dodaj stupac desno",
173
180
  add_above_menuitem: "Dodaj redak iznad",
174
181
  add_below_menuitem: "Dodaj redak ispod",
182
+ split_cell_menuitem: "Podijeli ćeliju",
183
+ merge_cells_menuitem: "Spoji ćelije",
184
+ background_color_menuitem: "Boja pozadine",
175
185
  },
176
186
  suggestion_menu: {
177
187
  no_items_title: "Stavke nisu pronađene",
@@ -287,6 +297,9 @@ export const hr = {
287
297
  align_justify: {
288
298
  tooltip: "Poravnaj tekst obostrano",
289
299
  },
300
+ table_cell_merge: {
301
+ tooltip: "Spoji ćelije",
302
+ },
290
303
  comment: {
291
304
  tooltip: "Dodaj komentar",
292
305
  },
@@ -340,6 +353,10 @@ export const hr = {
340
353
  reactions: {
341
354
  reacted_by: "Reagirao/la",
342
355
  },
356
+ sidebar: {
357
+ marked_as_resolved: "Označeno kao riješeno",
358
+ more_replies: (count) => `${count} dodatnih odgovora`,
359
+ },
343
360
  },
344
361
  generic: {
345
362
  ctrl_shortcut: "Ctrl",
@@ -332,6 +332,10 @@ export const is: Dictionary = {
332
332
  reactions: {
333
333
  reacted_by: "Brást við af",
334
334
  },
335
+ sidebar: {
336
+ marked_as_resolved: "Merkt sem leyst",
337
+ more_replies: (count) => `${count} fleiri svör`,
338
+ },
335
339
  },
336
340
  generic: {
337
341
  ctrl_shortcut: "Ctrl",
@@ -1,4 +1,6 @@
1
- export const it = {
1
+ import { Dictionary } from "../dictionary.js";
2
+
3
+ export const it: Dictionary = {
2
4
  slash_menu: {
3
5
  heading: {
4
6
  title: "Intestazione 1",
@@ -155,6 +157,8 @@ export const it = {
155
157
  drag_handle: {
156
158
  delete_menuitem: "Elimina",
157
159
  colors_menuitem: "Colori",
160
+ header_row_menuitem: "Riga intestazione",
161
+ header_column_menuitem: "Colonna intestazione",
158
162
  },
159
163
  table_handle: {
160
164
  delete_column_menuitem: "Elimina colonna",
@@ -163,6 +167,9 @@ export const it = {
163
167
  add_right_menuitem: "Aggiungi colonna a destra",
164
168
  add_above_menuitem: "Aggiungi riga sopra",
165
169
  add_below_menuitem: "Aggiungi riga sotto",
170
+ split_cell_menuitem: "Dividi cella",
171
+ merge_cells_menuitem: "Unisci celle",
172
+ background_color_menuitem: "Colore di sfondo",
166
173
  },
167
174
  suggestion_menu: {
168
175
  no_items_title: "Nessun elemento trovato",
@@ -278,6 +285,9 @@ export const it = {
278
285
  align_justify: {
279
286
  tooltip: "Giustifica testo",
280
287
  },
288
+ table_cell_merge: {
289
+ tooltip: "Unisci celle",
290
+ },
281
291
  comment: {
282
292
  tooltip: "Aggiungi commento",
283
293
  },
@@ -331,6 +341,10 @@ export const it = {
331
341
  reactions: {
332
342
  reacted_by: "Reagito da",
333
343
  },
344
+ sidebar: {
345
+ marked_as_resolved: "Contrassegnato come risolto",
346
+ more_replies: (count) => `${count} altre risposte`,
347
+ },
334
348
  },
335
349
  generic: {
336
350
  ctrl_shortcut: "Ctrl",
@@ -360,6 +360,10 @@ export const ja: Dictionary = {
360
360
  reactions: {
361
361
  reacted_by: "リアクションした人",
362
362
  },
363
+ sidebar: {
364
+ marked_as_resolved: "解決済みとしてマーク",
365
+ more_replies: (count) => `${count} 件の追加返信`,
366
+ },
363
367
  },
364
368
  generic: {
365
369
  ctrl_shortcut: "Ctrl",
@@ -353,6 +353,10 @@ export const ko: Dictionary = {
353
353
  reactions: {
354
354
  reacted_by: "반응한 사람",
355
355
  },
356
+ sidebar: {
357
+ marked_as_resolved: "해결됨으로 표시됨",
358
+ more_replies: (count) => `${count}개의 추가 답글`,
359
+ },
356
360
  },
357
361
  generic: {
358
362
  ctrl_shortcut: "Ctrl",
@@ -339,6 +339,10 @@ export const nl: Dictionary = {
339
339
  reactions: {
340
340
  reacted_by: "Gereageerd door",
341
341
  },
342
+ sidebar: {
343
+ marked_as_resolved: "Gemarkeerd als opgelost",
344
+ more_replies: (count) => `${count} extra reacties`,
345
+ },
342
346
  },
343
347
  generic: {
344
348
  ctrl_shortcut: "Ctrl",
@@ -339,6 +339,10 @@ export const no: Dictionary = {
339
339
  reactions: {
340
340
  reacted_by: "Reagert av",
341
341
  },
342
+ sidebar: {
343
+ marked_as_resolved: "Merket som løst",
344
+ more_replies: (count) => `${count} flere svar`,
345
+ },
342
346
  },
343
347
  generic: {
344
348
  ctrl_shortcut: "Ctrl",
@@ -324,6 +324,10 @@ export const pl: Dictionary = {
324
324
  reactions: {
325
325
  reacted_by: "Zareagowali",
326
326
  },
327
+ sidebar: {
328
+ marked_as_resolved: "Oznaczone jako rozwiązane",
329
+ more_replies: (count) => `${count} więcej odpowiedzi`,
330
+ },
327
331
  },
328
332
  generic: {
329
333
  ctrl_shortcut: "Ctrl",
@@ -332,6 +332,10 @@ export const pt: Dictionary = {
332
332
  reactions: {
333
333
  reacted_by: "Reagido por",
334
334
  },
335
+ sidebar: {
336
+ marked_as_resolved: "Marcado como resolvido",
337
+ more_replies: (count) => `${count} respostas a mais`,
338
+ },
335
339
  },
336
340
  generic: {
337
341
  ctrl_shortcut: "Ctrl",
@@ -367,6 +367,10 @@ export const ru: Dictionary = {
367
367
  reactions: {
368
368
  reacted_by: "Отреагировал(а)",
369
369
  },
370
+ sidebar: {
371
+ marked_as_resolved: "Отмечено как решенное",
372
+ more_replies: (count) => `${count} дополнительных ответов`,
373
+ },
370
374
  },
371
375
  generic: {
372
376
  ctrl_shortcut: "Ctrl",