Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ export const ar: Dictionary = {
save_button_text: "حفظ",
cancel_button_text: "إلغاء",
deleted_reference_text: "تم حذف المحتوى الأصلي",
discard_pending_comment: "هل أنت متأكد أنك تريد تجاهل هذا التعليق؟",
actions: {
add_reaction: "أضف تفاعلًا",
resolve: "حل",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ export const de: Dictionary = {
save_button_text: "Speichern",
cancel_button_text: "Abbrechen",
deleted_reference_text: "Originalinhalt gelöscht",
discard_pending_comment: "Möchten Sie diesen Kommentar wirklich verwerfen?",
actions: {
add_reaction: "Reaktion hinzufügen",
resolve: "Lösen",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ export const en = {
save_button_text: "Save",
cancel_button_text: "Cancel",
deleted_reference_text: "Original content deleted",
discard_pending_comment: "Are you sure you want to discard this comment?",
actions: {
add_reaction: "Add reaction",
resolve: "Resolve",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ export const es: Dictionary = {
save_button_text: "Guardar",
cancel_button_text: "Cancelar",
deleted_reference_text: "Contenido original eliminado",
discard_pending_comment: "¿Seguro que quieres descartar este comentario?",
actions: {
add_reaction: "Agregar reacción",
resolve: "Resolver",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/fa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ export const fa = {
save_button_text: "ذخیره",
cancel_button_text: "لغو",
deleted_reference_text: "محتوای اصلی حذف شد",
discard_pending_comment: "آیا مطمئن هستید که می‌خواهید این دیدگاه را نادیده بگیرید؟",
actions: {
add_reaction: "افزودن واکنش",
resolve: "حل کردن",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ export const fr: Dictionary = {
save_button_text: "Enregistrer",
cancel_button_text: "Annuler",
deleted_reference_text: "Contenu d'origine supprimé",
discard_pending_comment: "Voulez-vous vraiment abandonner ce commentaire ?",
actions: {
add_reaction: "Ajouter une réaction",
resolve: "Résoudre",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/he.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ export const he: Dictionary = {
save_button_text: "שמור",
cancel_button_text: "בטל",
deleted_reference_text: "התוכן המקורי נמחק",
discard_pending_comment: "האם אתה בטוח שברצונך לבטל את התגובה הזו?",
actions: {
add_reaction: "הוסף תגובה",
resolve: "סמן כפתור",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/hr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ export const hr: Dictionary = {
save_button_text: "Spremi",
cancel_button_text: "Odustani",
deleted_reference_text: "Originalni sadržaj je obrisan",
discard_pending_comment: "Jeste li sigurni da želite odbaciti ovaj komentar?",
actions: {
add_reaction: "Dodaj reakciju",
resolve: "Riješi",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ export const is: Dictionary = {
save_button_text: "Vista",
cancel_button_text: "Hætta",
deleted_reference_text: "Upprunalegu efni eytt",
discard_pending_comment: "Ertu viss um að þú viljir henda þessari athugasemd?",
actions: {
add_reaction: "Bæta við viðbrögðum",
resolve: "Leysa",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ export const it: Dictionary = {
save_button_text: "Salva",
cancel_button_text: "Annulla",
deleted_reference_text: "Contenuto originale eliminato",
discard_pending_comment: "Vuoi davvero eliminare questo commento?",
actions: {
add_reaction: "Aggiungi reazione",
resolve: "Risolvi",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ export const ja: Dictionary = {
save_button_text: "保存",
cancel_button_text: "キャンセル",
deleted_reference_text: "元のコンテンツが削除されました",
discard_pending_comment: "このコメントを破棄してもよろしいですか?",
actions: {
add_reaction: "リアクションを追加",
resolve: "解決",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ export const ko: Dictionary = {
save_button_text: "저장",
cancel_button_text: "취소",
deleted_reference_text: "원본 콘텐츠 삭제됨",
discard_pending_comment: "이 댓글을 삭제하시겠습니까?",
actions: {
add_reaction: "반응 추가",
resolve: "해결",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ export const nl: Dictionary = {
save_button_text: "Opslaan",
cancel_button_text: "Annuleren",
deleted_reference_text: "Originele inhoud verwijderd",
discard_pending_comment: "Weet je zeker dat je deze reactie wilt verwijderen?",
actions: {
add_reaction: "Reactie toevoegen",
resolve: "Oplossen",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/no.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ export const no: Dictionary = {
save_button_text: "Lagre",
cancel_button_text: "Avbryt",
deleted_reference_text: "Originalt innhold slettet",
discard_pending_comment: "Er du sikker på at du vil forkaste denne kommentaren?",
actions: {
add_reaction: "Legg til reaksjon",
resolve: "Løs",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ export const pl: Dictionary = {
save_button_text: "Zapisz",
cancel_button_text: "Anuluj",
deleted_reference_text: "Oryginalna treść usunięta",
discard_pending_comment: "Czy na pewno chcesz odrzucić ten komentarz?",
actions: {
add_reaction: "Dodaj reakcję",
resolve: "Rozwiąż",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ export const pt: Dictionary = {
save_button_text: "Salvar",
cancel_button_text: "Cancelar",
deleted_reference_text: "Conteúdo original excluído",
discard_pending_comment: "Tem certeza de que deseja descartar este comentário?",
actions: {
add_reaction: "Adicionar reação",
resolve: "Resolver",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ export const ru: Dictionary = {
save_button_text: "Сохранить",
cancel_button_text: "Отменить",
deleted_reference_text: "Исходный контент удалён",
discard_pending_comment: "Вы уверены, что хотите отменить этот комментарий?",
actions: {
add_reaction: "Добавить реакцию",
resolve: "Решить",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/sk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ export const sk = {
save_button_text: "Uložiť",
cancel_button_text: "Zrušiť",
deleted_reference_text: "Pôvodný obsah odstránený",
discard_pending_comment: "Naozaj chcete zahodiť tento komentár?",
actions: {
add_reaction: "Pridať reakciu",
resolve: "Vyriešiť",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/uk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ export const uk: Dictionary = {
save_button_text: "Зберегти",
cancel_button_text: "Скасувати",
deleted_reference_text: "Оригінальний вміст видалено",
discard_pending_comment: "Ви впевнені, що хочете відхилити цей коментар?",
actions: {
add_reaction: "Додати реакцію",
resolve: "Вирішити",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/uz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ export const uz: Dictionary = {
save_button_text: "Saqlash",
cancel_button_text: "Bekor qilish",
deleted_reference_text: "Asl tarkib o‘chirildi",
discard_pending_comment: "Haqiqatan ham bu izohni bekor qilmoqchimisiz?",
actions: {
add_reaction: "Reaksiya qo‘shish",
resolve: "Hal qilish",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ export const vi: Dictionary = {
save_button_text: "Lưu",
cancel_button_text: "Hủy",
deleted_reference_text: "Nội dung gốc đã bị xóa",
discard_pending_comment: "Bạn có chắc chắn muốn hủy bình luận này không?",
actions: {
add_reaction: "Thêm phản ứng",
resolve: "Giải quyết",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/zh-tw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ export const zhTW: Dictionary = {
save_button_text: "儲存",
cancel_button_text: "取消",
deleted_reference_text: "原始內容已刪除",
discard_pending_comment: "確定要捨棄此評論嗎?",
actions: {
add_reaction: "新增回應",
resolve: "解決",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/i18n/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ export const zh: Dictionary = {
save_button_text: "保存",
cancel_button_text: "取消",
deleted_reference_text: "原始内容已删除",
discard_pending_comment: "确定要放弃此评论吗?",
actions: {
add_reaction: "添加反应",
resolve: "解决",
Expand Down
29 changes: 12 additions & 17 deletions packages/react/src/components/Comments/FloatingComposer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
BlockNoteEditor,
BlockSchema,
DefaultBlockSchema,
DefaultInlineContentSchema,
Expand All @@ -9,19 +10,16 @@ import {
StyleSchema,
} from "@blocknote/core";
import { CommentsExtension } from "@blocknote/core/comments";
import { TextSelection } from "@tiptap/pm/state";
import { memo, useCallback } from "react";

import {
Components,
useComponentsContext,
} from "../../editor/ComponentsContext.js";
import { useCreateBlockNote } from "../../hooks/useCreateBlockNote.js";
import { useBlockNoteEditor } from "../../hooks/useBlockNoteEditor.js";
import { useExtension } from "../../hooks/useExtension.js";
import { useDictionary } from "../../i18n/dictionary.js";
import { CommentEditor } from "./CommentEditor.js";
import { defaultCommentEditorSchema } from "./defaultCommentEditorSchema.js";
import { useBlockNoteEditor } from "../../hooks/useBlockNoteEditor.js";
import { TextSelection } from "@tiptap/pm/state";

type FloatingComposerActionsProps = {
isFocused: boolean;
Expand Down Expand Up @@ -59,25 +57,22 @@ export function FloatingComposer<
B extends BlockSchema = DefaultBlockSchema,
I extends InlineContentSchema = DefaultInlineContentSchema,
S extends StyleSchema = DefaultStyleSchema,
>() {
>(props: {
/**
* The (empty) editor used to compose the new comment. Created and owned by
* the `FloatingComposerController`, so it can check for unsaved text before
* the composer is dismissed.
*/
newCommentEditor: BlockNoteEditor<any, any, any>;
}) {
Comment on lines +60 to +67

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Public API break: newCommentEditor is now required on an exported component.

Making this prop mandatory can break existing external consumers that render FloatingComposer directly. Please either preserve backward compatibility (optional prop with fallback behavior) or explicitly ship this as a semver-major change with migration guidance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react/src/components/Comments/FloatingComposer.tsx` around lines 29
- 36, The `newCommentEditor` prop on the `FloatingComposer` component has been
made required, which is a breaking change for external consumers. Either make
the prop optional by adding a `?` to the type definition and provide fallback
behavior when it is not provided, or ensure this change is documented as a
semver-major release with clear migration guidance for users currently rendering
`FloatingComposer` directly.

const editor = useBlockNoteEditor<B, I, S>();
const newCommentEditor = props.newCommentEditor;

const comments = useExtension(CommentsExtension);

const Components = useComponentsContext()!;
const dict = useDictionary();

const newCommentEditor = useCreateBlockNote({
trailingBlock: false,
dictionary: {
...dict,
placeholders: {
emptyDocument: dict.placeholders.new_comment,
},
},
schema: comments.commentEditorSchema || defaultCommentEditorSchema,
});

const onSave = useCallback(async () => {
// (later) For REST API, we should implement a loading state and error state
await comments.createThread({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import { flip, offset, shift } from "@floating-ui/react";
import { ComponentProps, FC, useMemo } from "react";

import { useBlockNoteEditor } from "../../hooks/useBlockNoteEditor.js";
import { useCreateBlockNote } from "../../hooks/useCreateBlockNote.js";
import { useEditorState } from "../../hooks/useEditorState.js";
import { useExtension, useExtensionState } from "../../hooks/useExtension.js";
import { useDictionary } from "../../i18n/dictionary.js";
import { FloatingUIOptions } from "../Popovers/FloatingUIOptions.js";
import { PositionPopover } from "../Popovers/PositionPopover.js";
import { defaultCommentEditorSchema } from "./defaultCommentEditorSchema.js";
import { FloatingComposer } from "./FloatingComposer.js";

export default function FloatingComposerController<
Expand All @@ -32,6 +35,7 @@ export default function FloatingComposerController<
portalElement?: HTMLElement | null;
}) {
const editor = useBlockNoteEditor<B, I, S>();
const dict = useDictionary();

const comments = useExtension(CommentsExtension);

Expand All @@ -40,6 +44,24 @@ export default function FloatingComposerController<
selector: (state) => state.pendingComment,
});

// The editor used to compose a new comment. We own it here (rather than in
// `FloatingComposer`) so that the dismiss handler below can check whether the
// user has typed anything before discarding it. A fresh editor is created for
// each pending comment, so it always starts empty.
const newCommentEditor = useCreateBlockNote(
{
trailingBlock: false,
dictionary: {
...dict,
placeholders: {
emptyDocument: dict.placeholders.new_comment,
},
},
schema: comments.commentEditorSchema || defaultCommentEditorSchema,
},
[pendingComment],
);

const position = useEditorState({
editor,
selector: ({ editor }) =>
Expand All @@ -60,6 +82,16 @@ export default function FloatingComposerController<
// open state.
onOpenChange: (open) => {
if (!open) {
// If the user has typed a comment that hasn't been saved yet, ask
// for confirmation before discarding it (e.g. when clicking
// outside the composer). Otherwise the unsaved comment is lost.
if (
!newCommentEditor.isEmpty &&
!window.confirm(dict.comments.discard_pending_comment)
) {
// Keep the composer open so the user can continue editing.
return;
}
comments.stopPendingComment();
editor.focus();
}
Expand All @@ -78,7 +110,14 @@ export default function FloatingComposerController<
...props.floatingUIOptions?.elementProps,
},
}),
[comments, editor, pendingComment, props.floatingUIOptions],
[
comments,
dict,
editor,
newCommentEditor,
pendingComment,
props.floatingUIOptions,
],
);

// nice to have improvements would be:
Expand All @@ -93,7 +132,7 @@ export default function FloatingComposerController<
portalElement={props.portalElement}
{...floatingUIOptions}
>
<Component />
<Component newCommentEditor={newCommentEditor} />
</PositionPopover>
);
}
Loading