From 4c9c4357043458879ebb511381f07bb9ebb3b0d0 Mon Sep 17 00:00:00 2001 From: "priyanshu.c" Date: Tue, 17 Mar 2026 14:34:21 +0530 Subject: [PATCH 1/5] feature: chnages for canvas commenting --- lib/block-reactions/BlockReactionButton.tsx | 587 ++++++++++++++++++ lib/block-reactions/block-reaction-button.css | 147 +++++ lib/block-reactions/main.ts | 2 + lib/main.ts | 9 + 4 files changed, 745 insertions(+) create mode 100644 lib/block-reactions/BlockReactionButton.tsx create mode 100644 lib/block-reactions/block-reaction-button.css create mode 100644 lib/block-reactions/main.ts diff --git a/lib/block-reactions/BlockReactionButton.tsx b/lib/block-reactions/BlockReactionButton.tsx new file mode 100644 index 0000000..e8732a7 --- /dev/null +++ b/lib/block-reactions/BlockReactionButton.tsx @@ -0,0 +1,587 @@ +import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react'; +import { createPortal } from 'react-dom'; +import type { BlockNoteEditor } from '@blocknote/core'; +import EmojiPicker, { EmojiStyle } from 'emoji-picker-react'; +import * as Popover from '@radix-ui/react-popover'; +import type { EmojiClickData } from 'emoji-picker-react'; +import { SmilePlus, MessageCircle } from 'lucide-react'; +import './block-reaction-button.css'; + +// Utility function to combine class names +const cn = (...classes: (string | undefined | null | false)[]): string => { + return classes.filter(Boolean).join(' '); +}; + +// Button component using basic HTML +const Button = React.forwardRef< + HTMLButtonElement, + React.ButtonHTMLAttributes & { variant?: string } +>(({ className, variant, ...props }, ref) => { + const variants: Record = { + ghost: 'bg-transparent hover:bg-transparent text-muted-foreground', + default: 'bg-primary text-primary-foreground', + }; + + return ( + + ); + })} + + {/* Comments - only show if no reactions (mutually exclusive) */} + {hasComments && !hasReactions && threads && threads.length > 1 ? ( + // Multiple threads: show popover with list + + + + + + +
+ {threads.map((thread) => ( + + ))} +
+
+
+
+ ) : hasComments && !hasReactions ? ( + // Single thread: open directly + + ) : null} + + {/* Add reaction button - only show if no comments (mutually exclusive) */} + {!hasComments && ( + + + + + + + { + const emojiName = emoji.isCustom + ? `custom:${emoji.emoji}:${emoji.names[0] || 'custom'}` + : emoji.emoji; + onToggleReaction(emojiName); + }} + searchPlaceholder='Search emoji...' + /> + + + + )} + , + document.body, + ); +}; + +// Hover buttons for blocks without activity +interface HoverActivityButtonProps { + blockId: string; + onReactionButtonHover: () => void; + onReactionButtonLeave: () => void; + onEmojiSelect: (emoji: string) => void; + onCommentClick: () => void; + emojiPickerOpen: boolean; + onEmojiPickerOpenChange: (open: boolean) => void; + isCommentPanelOpen?: boolean | undefined; +} + +const HoverActivityButton = React.forwardRef( + ( + { + blockId, + onReactionButtonHover, + onReactionButtonLeave, + onEmojiSelect, + onCommentClick, + emojiPickerOpen, + onEmojiPickerOpenChange, + isCommentPanelOpen, + }, + ref, + ) => { + const [position, setPosition] = useState<{ top: number; left: number } | null>(null); + + useEffect(() => { + const updatePosition = () => { + const blockElement = document.querySelector(`[data-id="${blockId}"]`) as HTMLElement | null; + if (blockElement) { + const rect = blockElement.getBoundingClientRect(); + const buttonHeight = 36; + const padding = 12; + + // Always position to the right of the block + let left = rect.right + padding; + + // Center vertically relative to block + let top = rect.top + rect.height / 2 - buttonHeight / 2; + + setPosition({ top, left }); + } + }; + + // Initial update + updatePosition(); + + // When panel state changes, we need multiple updates during the CSS transition + // slideIn is 0.2s, slideOut is 0.3s - update several times during this period + const transitionTimeouts: NodeJS.Timeout[] = []; + if (isCommentPanelOpen !== undefined) { + [50, 150, 300, 400].forEach(delay => { + transitionTimeouts.push(setTimeout(updatePosition, delay)); + }); + } + + window.addEventListener('scroll', updatePosition, true); + window.addEventListener('resize', updatePosition); + + // Only update position periodically if emoji picker is not open + const interval = setInterval(() => { + if (!emojiPickerOpen) { + updatePosition(); + } + }, 100); + + return () => { + transitionTimeouts.forEach(clearTimeout); + window.removeEventListener('scroll', updatePosition, true); + window.removeEventListener('resize', updatePosition); + clearInterval(interval); + }; + }, [blockId, isCommentPanelOpen, emojiPickerOpen]); + + if (!position) return null; + + return createPortal( +
+ {/* Reaction button with emoji picker */} + + + + + + + { + const emojiName = emoji.isCustom + ? `custom:${emoji.emoji}:${emoji.names[0] || 'custom'}` + : emoji.emoji; + onEmojiSelect(emojiName); + }} + searchPlaceholder='Search emoji...' + /> + + + + + {/* Comment button */} + +
, + document.body, + ); + }, +); + +HoverActivityButton.displayName = 'HoverActivityButton'; diff --git a/lib/block-reactions/block-reaction-button.css b/lib/block-reactions/block-reaction-button.css new file mode 100644 index 0000000..afa8f75 --- /dev/null +++ b/lib/block-reactions/block-reaction-button.css @@ -0,0 +1,147 @@ +.bn-block-activity-button { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 2px 4px; + background: transparent; + border: none; + border-radius: 4px; + box-shadow: none; +} + +.bn-block-hover-buttons { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 2px 4px; + background: transparent; + border: none; + border-radius: 4px; + box-shadow: none; +} + +.bn-activity-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 4px; + padding: 2px 4px; + min-width: 28px; + height: 24px; + border-radius: 4px; + background: transparent; + border: none; + color: #9ca3af; + cursor: pointer; + transition: all 0.15s ease; + font-size: 14px; + font-weight: 500; +} + +.bn-activity-btn:hover { + background: transparent; + color: #6b7280; + transform: scale(1.05); +} + +/* Reactions have border and background when active (user has reacted) */ +.bn-reaction-btn-with-count { + border: 1px solid transparent; +} + +.bn-reaction-btn-with-count.bn-activity-btn--active { + background: #f0f9ff; + border: 1px solid #3b82f6; + color: #3b82f6; +} + +.bn-reaction-btn-with-count.bn-activity-btn--active:hover { + background: #e0f2fe; + border-color: #0284c7; + color: #0284c7; +} + +.bn-activity-btn:active { + transform: scale(0.95); +} + +.bn-activity-btn--active { + background: #f0f9ff; + border: 1px solid #3b82f6; + color: #3b82f6; +} + +.bn-activity-btn--active:hover { + background: #e0f2fe; + border-color: #0284c7; + color: #0284c7; +} + +.bn-activity-btn .emoji { + font-size: 16px; + line-height: 1; +} + +.bn-activity-btn .count { + font-size: 12px; + font-weight: 500; + min-width: 14px; + color: #9ca3af; + padding: 0; + line-height: 1; +} + +.bn-reaction-btn-with-count { + flex-shrink: 0; +} + +.bn-comment-btn-with-count { + flex-shrink: 0; +} + +/* Threads list popover */ +.bn-threads-list { + display: flex; + flex-direction: column; + gap: 2px; + min-width: 100px; + max-width: 120px; +} + +.bn-thread-item { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 6px 8px; + text-align: center; + border: none; + border-radius: 3px; + background: #f9fafb; + color: #374151; + cursor: pointer; + font-size: 12px; + transition: all 0.15s ease; +} + +.bn-thread-item:hover { + background: #f3f4f6; + color: #1f2937; +} + +.bn-thread-count { + flex-shrink: 0; + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 16px; + height: 16px; + padding: 0 3px; + background: #dbeafe; + color: #1e40af; + border-radius: 8px; + font-size: 10px; + font-weight: 600; +} diff --git a/lib/block-reactions/main.ts b/lib/block-reactions/main.ts new file mode 100644 index 0000000..b739e4a --- /dev/null +++ b/lib/block-reactions/main.ts @@ -0,0 +1,2 @@ +export { BlockReactionButton } from './BlockReactionButton'; +export type { BlockReactionButtonProps } from './BlockReactionButton'; diff --git a/lib/main.ts b/lib/main.ts index d7d5812..2f3d9b8 100644 --- a/lib/main.ts +++ b/lib/main.ts @@ -101,6 +101,15 @@ export { insertGroupMention, } from "./mentions/main.js"; +// Block reactions exports +export { + BlockReactionButton, +} from "./block-reactions/main.js"; + +export type { + BlockReactionButtonProps, +} from "./block-reactions/main.js"; + // Common utilities exports export { asBlockNoteEditorForView, From b0aa5eaa29fe8d9c99fb0a2b0da948f5d8360468 Mon Sep 17 00:00:00 2001 From: "priyanshu.c" Date: Wed, 18 Mar 2026 10:50:25 +0530 Subject: [PATCH 2/5] feature: changes in ui --- lib/block-reactions/BlockReactionButton.tsx | 327 ++++++++++++-------- 1 file changed, 205 insertions(+), 122 deletions(-) diff --git a/lib/block-reactions/BlockReactionButton.tsx b/lib/block-reactions/BlockReactionButton.tsx index e8732a7..d7bb367 100644 --- a/lib/block-reactions/BlockReactionButton.tsx +++ b/lib/block-reactions/BlockReactionButton.tsx @@ -43,6 +43,8 @@ export interface BlockReactionButtonProps { onThreadClick?: (blockId: string, threadId: string) => void; isCommentPanelOpen?: boolean; user?: any; // Optional user object with id property + users?: Array<{ id: string; name: string }> | undefined; // Users list for tooltip display + TooltipComponent?: React.ComponentType<{ content: string; side?: 'top'; delayDuration?: number; children: React.ReactNode }>; } export const BlockReactionButton: React.FC = ({ @@ -56,6 +58,8 @@ export const BlockReactionButton: React.FC = ({ onThreadClick, isCommentPanelOpen, user, + users, + TooltipComponent, }) => { const [hoveredBlockId, setHoveredBlockId] = useState(null); const [isHoveringButton, setIsHoveringButton] = useState(false); @@ -177,16 +181,12 @@ export const BlockReactionButton: React.FC = ({ reactions={blockReactionData} commentCount={commentCount} user={user} - onToggleReaction={(emoji) => handleToggleReaction(blockId, emoji)} onCommentClick={() => onCommentClick(blockId)} threads={blockThreads?.[blockId] || []} onThreadClick={onThreadClick} - emojiPickerOpen={emojiPickerOpen === blockId} - onEmojiPickerOpenChange={(open) => { - setEmojiPickerOpen(open ? blockId : null); - if (open) clearHideTimeout(); - }} isCommentPanelOpen={isCommentPanelOpen} + users={users} + TooltipComponent={TooltipComponent} /> ); })} @@ -213,6 +213,7 @@ export const BlockReactionButton: React.FC = ({ if (open) clearHideTimeout(); }} isCommentPanelOpen={isCommentPanelOpen} + TooltipComponent={TooltipComponent} ref={buttonRef} /> )} @@ -220,6 +221,61 @@ export const BlockReactionButton: React.FC = ({ ); }; +// Simple reaction display showing all emojis used and total count +interface ReactionButtonsProps { + reactionEmojis: string[]; + reactions: Record; + usersById: Map; + TooltipComponent?: React.ComponentType<{ content: string; side?: 'top'; delayDuration?: number; children: React.ReactNode }>; +} + +const ReactionButtons: React.FC = React.memo(({ + reactionEmojis, + reactions, + usersById, + TooltipComponent, +}) => { + // Calculate total reaction count + let totalCount = 0; + const allUserIds = new Set(); + + reactionEmojis.forEach(emoji => { + const userIds = reactions[emoji] || []; + totalCount += userIds.length; + userIds.forEach(id => allUserIds.add(id)); + }); + + // Build tooltip with all user names + const userNames = Array.from(allUserIds).map(id => usersById.get(id)?.name || 'Unknown').join(', '); + const verb = allUserIds.size === 1 ? 'has' : 'have'; + const tooltipTitle = `${userNames} ${verb} reacted`; + + const display = ( +
+ {reactionEmojis.map(emoji => ( + {emoji} + ))} + {totalCount > 0 && {totalCount}} +
+ ); + + // Use custom Tooltip component if provided, otherwise use native title + if (TooltipComponent) { + return ( + + {display} + + ); + } + + return React.cloneElement(display, { title: tooltipTitle }); +}); + +ReactionButtons.displayName = 'ReactionButtons'; + // Persistent button showing reactions and comments with counts interface PersistentActivityButtonProps { blockId: string; @@ -228,12 +284,11 @@ interface PersistentActivityButtonProps { commentCount: number; threads?: Array<{ threadId: string; threadData: any; commentCount: number }>; user: any; - onToggleReaction: (emoji: string) => void; onCommentClick: () => void; onThreadClick?: ((blockId: string, threadId: string) => void) | undefined; - emojiPickerOpen: boolean; - onEmojiPickerOpenChange: (open: boolean) => void; isCommentPanelOpen?: boolean | undefined; + users?: Array<{ id: string; name: string }> | undefined; + TooltipComponent?: React.ComponentType<{ content: string; side?: 'top'; delayDuration?: number; children: React.ReactNode }>; } const PersistentActivityButton: React.FC = ({ @@ -242,17 +297,25 @@ const PersistentActivityButton: React.FC = ({ reactions, commentCount, threads = [], - user, - onToggleReaction, + user: _user, onCommentClick, onThreadClick, - emojiPickerOpen, - onEmojiPickerOpenChange, isCommentPanelOpen, + users, + TooltipComponent, }) => { const [position, setPosition] = useState<{ top: number; left: number } | null>(null); const [threadsPopoverOpen, setThreadsPopoverOpen] = useState(false); + const usersById = useMemo(() => { + const map = new Map(); + for (const u of users || []) { + map.set(u.id, { name: u.name }); + } + return map; + }, [users]); + + useEffect(() => { const updatePosition = () => { const blockElement = document.querySelector(`[data-id="${blockId}"]`) as HTMLElement | null; @@ -261,19 +324,26 @@ const PersistentActivityButton: React.FC = ({ const buttonHeight = 36; const padding = 12; + // Check if block is visible in viewport + const isVisible = rect.top < window.innerHeight && rect.bottom > 0; + + if (!isVisible) { + // Hide button when block is out of view + setPosition(null); + return; + } + // Always position to the right of the block let left = rect.right + padding; // Center vertically relative to block let top = rect.top + rect.height / 2 - buttonHeight / 2; - // Check bottom bounds - if (top + buttonHeight > window.innerHeight) { - top = window.innerHeight - buttonHeight - padding; - } - // Check top bounds - if (top < 0) { - top = padding; + const margin = 100; // Hide when within 100px of viewport edge + + if (rect.top < margin || rect.bottom > window.innerHeight - margin) { + setPosition(null); + return; } setPosition({ top, left }); @@ -292,23 +362,32 @@ const PersistentActivityButton: React.FC = ({ }); } - window.addEventListener('scroll', updatePosition, true); - window.addEventListener('resize', updatePosition); + // Use requestAnimationFrame for smooth updates during scroll + let rafId: number | null = null; + let lastUpdate = 0; + const throttledUpdate = () => { + const now = Date.now(); + if (now - lastUpdate < 16) return; // Max ~60fps + lastUpdate = now; - // Only update position periodically if emoji picker is not open - const interval = setInterval(() => { - if (!emojiPickerOpen) { - updatePosition(); - } - }, 100); + if (rafId) cancelAnimationFrame(rafId); + rafId = requestAnimationFrame(updatePosition); + }; + + window.addEventListener('scroll', throttledUpdate, { capture: true, passive: true }); + window.addEventListener('resize', updatePosition, { passive: true }); + + // Also update periodically as a fallback + const interval = setInterval(updatePosition, 50); return () => { transitionTimeouts.forEach(clearTimeout); window.removeEventListener('scroll', updatePosition, true); window.removeEventListener('resize', updatePosition); + if (rafId) cancelAnimationFrame(rafId); clearInterval(interval); }; - }, [blockId, isCommentPanelOpen, emojiPickerOpen]); + }, [blockId, isCommentPanelOpen]); if (!position) return null; @@ -325,43 +404,43 @@ const PersistentActivityButton: React.FC = ({ zIndex: 999, }} > - {/* Reactions */} - {hasReactions && - reactionEmojis.map(emoji => { - const userIds = reactions[emoji] || []; - const hasUserReacted = user?.id ? userIds.includes(user.id) : false; - - return ( - - ); - })} + {/* Reactions - display only, click on markText to interact */} + {hasReactions && ( + + )} {/* Comments - only show if no reactions (mutually exclusive) */} {hasComments && !hasReactions && threads && threads.length > 1 ? ( // Multiple threads: show popover with list - + {TooltipComponent ? ( + 1 ? 's' : ''}`} side='top' delayDuration={100}> + + + ) : ( + + )} = ({ ) : hasComments && !hasReactions ? ( // Single thread: open directly - + TooltipComponent ? ( + 1 ? 's' : ''}`} side='top' delayDuration={100}> + + + ) : ( + + ) ) : null} - {/* Add reaction button - only show if no comments (mutually exclusive) */} - {!hasComments && ( - - - - - - - { - const emojiName = emoji.isCustom - ? `custom:${emoji.emoji}:${emoji.names[0] || 'custom'}` - : emoji.emoji; - onToggleReaction(emojiName); - }} - searchPlaceholder='Search emoji...' - /> - - - - )} , document.body, ); @@ -454,6 +511,7 @@ interface HoverActivityButtonProps { emojiPickerOpen: boolean; onEmojiPickerOpenChange: (open: boolean) => void; isCommentPanelOpen?: boolean | undefined; + TooltipComponent?: React.ComponentType<{ content: string; side?: 'top'; delayDuration?: number; children: React.ReactNode }>; } const HoverActivityButton = React.forwardRef( @@ -467,6 +525,7 @@ const HoverActivityButton = React.forwardRef { @@ -537,16 +596,28 @@ const HoverActivityButton = React.forwardRef {/* Reaction button with emoji picker */} - - - + {TooltipComponent ? ( + + + + + + ) : ( + + + + )} {/* Comment button */} - + {TooltipComponent ? ( + + + + ) : ( + + )} , document.body, ); From a0e48055c39ae0cd399fdae2eeabc2ad4ae29cd6 Mon Sep 17 00:00:00 2001 From: "priyanshu.c" Date: Wed, 18 Mar 2026 10:52:10 +0530 Subject: [PATCH 3/5] feature: push package.json --- package.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package.json b/package.json index 6246bad..dd9cd41 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,10 @@ "types": "./dist/main.d.ts", "import": "./dist/main.js" }, + "./block-reactions": { + "types": "./dist/block-reactions/main.d.ts", + "import": "./dist/block-reactions/main.js" + }, "./multicolumn": { "types": "./dist/multicolumn/main.d.ts", "import": "./dist/multicolumn/main.js" @@ -105,8 +109,10 @@ "@handsontable/react": "^16.2.0", "echarts": "^6.0.0", "echarts-for-react": "^3.0.5", + "emoji-picker-react": "^4.18.0", "handsontable": "^16.2.0", "hyperformula": "^3.1.0", + "lucide-react": "^0.577.0", "pyodide": "^0.29.0", "recharts": "^3.6.0", "reveal.js": "^5.1.0" From 483e8ce1c48b7dc1416607e5226b64dfb54537aa Mon Sep 17 00:00:00 2001 From: "priyanshu.c" Date: Wed, 18 Mar 2026 14:06:22 +0530 Subject: [PATCH 4/5] feature: push package-lock.json --- package-lock.json | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/package-lock.json b/package-lock.json index b98bc25..9bf4e77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,8 +22,10 @@ "@handsontable/react": "^16.2.0", "echarts": "^6.0.0", "echarts-for-react": "^3.0.5", + "emoji-picker-react": "^4.18.0", "handsontable": "^16.2.0", "hyperformula": "^3.1.0", + "lucide-react": "^0.577.0", "pyodide": "^0.29.0", "recharts": "^3.6.0", "reveal.js": "^5.1.0" @@ -5432,6 +5434,21 @@ "dev": true, "license": "MIT" }, + "node_modules/emoji-picker-react": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.18.0.tgz", + "integrity": "sha512-vLTrLfApXAIciguGE57pXPWs9lPLBspbEpPMiUq03TIli2dHZBiB+aZ0R9/Wat0xmTfcd4AuEzQgSYxEZ8C88Q==", + "license": "MIT", + "dependencies": { + "flairup": "1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -5863,6 +5880,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/flairup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flairup/-/flairup-1.0.0.tgz", + "integrity": "sha512-IKlE+pNvL2R+kVL1kEhUYqRxVqeFnjiIvHWDMLFXNaqyUdFXQM2wte44EfMYJNHkW16X991t2Zg8apKkhv7OBA==", + "license": "MIT" + }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", @@ -7008,6 +7031,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.577.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz", + "integrity": "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", From 344ae88116bab5db30faa54f2602678c2a06d591 Mon Sep 17 00:00:00 2001 From: "priyanshu.c" Date: Wed, 18 Mar 2026 14:12:04 +0530 Subject: [PATCH 5/5] feature: push rename files --- lib/block-reactions/main.ts | 2 -- .../CanvasCommentButton.tsx} | 6 +++--- .../canvas-comment-button.css} | 0 lib/canvas-comments/main.ts | 2 ++ lib/main.ts | 10 +++++----- package.json | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 lib/block-reactions/main.ts rename lib/{block-reactions/BlockReactionButton.tsx => canvas-comments/CanvasCommentButton.tsx} (99%) rename lib/{block-reactions/block-reaction-button.css => canvas-comments/canvas-comment-button.css} (100%) create mode 100644 lib/canvas-comments/main.ts diff --git a/lib/block-reactions/main.ts b/lib/block-reactions/main.ts deleted file mode 100644 index b739e4a..0000000 --- a/lib/block-reactions/main.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { BlockReactionButton } from './BlockReactionButton'; -export type { BlockReactionButtonProps } from './BlockReactionButton'; diff --git a/lib/block-reactions/BlockReactionButton.tsx b/lib/canvas-comments/CanvasCommentButton.tsx similarity index 99% rename from lib/block-reactions/BlockReactionButton.tsx rename to lib/canvas-comments/CanvasCommentButton.tsx index d7bb367..ed0754b 100644 --- a/lib/block-reactions/BlockReactionButton.tsx +++ b/lib/canvas-comments/CanvasCommentButton.tsx @@ -5,7 +5,7 @@ import EmojiPicker, { EmojiStyle } from 'emoji-picker-react'; import * as Popover from '@radix-ui/react-popover'; import type { EmojiClickData } from 'emoji-picker-react'; import { SmilePlus, MessageCircle } from 'lucide-react'; -import './block-reaction-button.css'; +import './canvas-comment-button.css'; // Utility function to combine class names const cn = (...classes: (string | undefined | null | false)[]): string => { @@ -32,7 +32,7 @@ const Button = React.forwardRef< }); Button.displayName = 'Button'; -export interface BlockReactionButtonProps { +export interface CanvasCommentButtonProps { editor: BlockNoteEditor; blockReactions: Record>; // blockId -> emoji -> userIds[] commentCounts: Record; // blockId -> count @@ -47,7 +47,7 @@ export interface BlockReactionButtonProps { TooltipComponent?: React.ComponentType<{ content: string; side?: 'top'; delayDuration?: number; children: React.ReactNode }>; } -export const BlockReactionButton: React.FC = ({ +export const CanvasCommentButton: React.FC = ({ editor: _editor, blockReactions, commentCounts, diff --git a/lib/block-reactions/block-reaction-button.css b/lib/canvas-comments/canvas-comment-button.css similarity index 100% rename from lib/block-reactions/block-reaction-button.css rename to lib/canvas-comments/canvas-comment-button.css diff --git a/lib/canvas-comments/main.ts b/lib/canvas-comments/main.ts new file mode 100644 index 0000000..d6f771c --- /dev/null +++ b/lib/canvas-comments/main.ts @@ -0,0 +1,2 @@ +export { CanvasCommentButton } from './CanvasCommentButton'; +export type { CanvasCommentButtonProps } from './CanvasCommentButton'; diff --git a/lib/main.ts b/lib/main.ts index 2f3d9b8..975014f 100644 --- a/lib/main.ts +++ b/lib/main.ts @@ -101,14 +101,14 @@ export { insertGroupMention, } from "./mentions/main.js"; -// Block reactions exports +// Canvas comments exports export { - BlockReactionButton, -} from "./block-reactions/main.js"; + CanvasCommentButton, +} from "./canvas-comments/main.js"; export type { - BlockReactionButtonProps, -} from "./block-reactions/main.js"; + CanvasCommentButtonProps, +} from "./canvas-comments/main.js"; // Common utilities exports export { diff --git a/package.json b/package.json index dd9cd41..e36f3b4 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,9 @@ "types": "./dist/main.d.ts", "import": "./dist/main.js" }, - "./block-reactions": { - "types": "./dist/block-reactions/main.d.ts", - "import": "./dist/block-reactions/main.js" + "./canvas-comments": { + "types": "./dist/canvas-comments/main.d.ts", + "import": "./dist/canvas-comments/main.js" }, "./multicolumn": { "types": "./dist/multicolumn/main.d.ts",