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
25 changes: 25 additions & 0 deletions packages/react-grab/src/components/comments-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ const getCommentItemDisplayName = (item: CommentItem): string => {
return item.componentName ?? item.tagName;
};

const getCommentItemUrlLabel = (item: CommentItem): string | undefined => {
if (!item.url) return undefined;
try {
const parsed = new URL(item.url);
const currentHost = typeof window !== "undefined" ? window.location.host : "";
const pathAndQuery = `${parsed.pathname}${parsed.search}`;
if (parsed.host && parsed.host !== currentHost) {
return `${parsed.host}${pathAndQuery}`;
}
return pathAndQuery || "/";
} catch {
return item.url;
}
};

export const CommentsDropdown: Component<CommentsDropdownProps> = (props) => {
let containerRef: HTMLDivElement | undefined;
const {
Expand Down Expand Up @@ -284,6 +299,16 @@ export const CommentsDropdown: Component<CommentsDropdownProps> = (props) => {
{item.commentText}
</span>
</Show>
<Show when={getCommentItemUrlLabel(item)}>
{(urlLabel) => (
<span
class="text-[10px] leading-3 font-sans text-black/30 truncate mt-0.5"
title={item.url}
>
{urlLabel()}
</span>
)}
</Show>
</span>
<span class="shrink-0 text-[10px] font-sans text-black/25 flex items-center justify-end">
{formatRelativeTime(item.timestamp)}
Expand Down
1 change: 0 additions & 1 deletion packages/react-grab/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ export const ZOOM_DETECTION_THRESHOLD = 0.01;

export const MOUNT_ROOT_RECHECK_DELAY_MS = 1000;

export const MAX_COMMENT_ITEMS = 20;
export const MAX_SESSION_STORAGE_SIZE_BYTES = 2 * 1024 * 1024;
// Must match the CSS exit transition on dropdown components or the DOM
// unmounts mid-animation.
Expand Down
12 changes: 9 additions & 3 deletions packages/react-grab/src/core/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,7 @@ export const init = (rawOptions?: Options): ReactGrabAPI => {
previewBounds: copiedElements.map((copiedElement) => createElementBounds(copiedElement)),
elementSelectors,
commentText: extraPrompt,
url: typeof window !== "undefined" ? window.location.href : undefined,
timestamp: Date.now(),
});
setCommentItems(updatedCommentItems);
Expand Down Expand Up @@ -3341,8 +3342,11 @@ export const init = (rawOptions?: Options): ReactGrabAPI => {
}
};

const decorateContentWithUrl = (content: string, url: string | undefined): string =>
url ? `${content}\n at ${url}` : content;

const copyCommentItemContent = (item: CommentItem) => {
copyContent(item.content, {
copyContent(decorateContentWithUrl(item.content, item.url), {
tagName: item.tagName,
componentName: item.componentName ?? item.elementName,
commentText: item.commentText,
Expand Down Expand Up @@ -3386,7 +3390,9 @@ export const init = (rawOptions?: Options): ReactGrabAPI => {
if (currentCommentItems.length === 0) return;

const combinedContent = joinSnippets(
currentCommentItems.map((commentItem) => commentItem.content),
currentCommentItems.map((commentItem) =>
decorateContentWithUrl(commentItem.content, commentItem.url),
),
);

const firstItem = currentCommentItems[0];
Expand All @@ -3395,7 +3401,7 @@ export const init = (rawOptions?: Options): ReactGrabAPI => {
entries: currentCommentItems.map((commentItem) => ({
tagName: commentItem.tagName,
componentName: commentItem.componentName ?? commentItem.elementName,
content: commentItem.content,
content: decorateContentWithUrl(commentItem.content, commentItem.url),
commentText: commentItem.commentText,
})),
});
Expand Down
1 change: 1 addition & 0 deletions packages/react-grab/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ export interface CommentItem {
previewBounds?: OverlayBounds[];
elementSelectors?: string[];
commentText?: string;
url?: string;
timestamp: number;
}

Expand Down
6 changes: 2 additions & 4 deletions packages/react-grab/src/utils/comment-storage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MAX_COMMENT_ITEMS, MAX_SESSION_STORAGE_SIZE_BYTES } from "../constants.js";
import { MAX_SESSION_STORAGE_SIZE_BYTES } from "../constants.js";
import type { CommentItem } from "../types.js";
import { generateId } from "./generate-id.js";
import { logRecoverableError } from "./log-recoverable-error.js";
Expand Down Expand Up @@ -76,9 +76,7 @@ if (typeof window !== "undefined") {
export const loadComments = (): CommentItem[] => commentItems;

export const addCommentItem = (item: Omit<CommentItem, "id">): CommentItem[] =>
persistCommentItems(
[{ ...item, id: generateId("comment") }, ...commentItems].slice(0, MAX_COMMENT_ITEMS),
);
persistCommentItems([{ ...item, id: generateId("comment") }, ...commentItems]);

export const removeCommentItem = (itemId: string): void => {
persistCommentItems(commentItems.filter((innerItem) => innerItem.id !== itemId));
Expand Down