review-lens-react 0.1.2 → 0.2.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.
package/README.md CHANGED
@@ -11,6 +11,10 @@ The package is intended to be mounted by the host app only when review mode is n
11
11
  - Prefer stable selectors such as `data-review-id`, `data-testid`, `id`, `aria-label`, and `name`.
12
12
  - Fall back to a generated CSS path when no stable attribute exists.
13
13
  - Save feedback with selector, URL, content id, author, status, timestamps, CSS snapshot, and element fingerprint.
14
+ - Triage feedback by status, severity, type, assignee, viewport, threaded replies, and summary groups.
15
+ - Detect target drift by comparing the stored fingerprint and CSS snapshot with the current DOM.
16
+ - Show accessibility hints and host-configured design token mismatches for the selected element.
17
+ - Store screenshot metadata and URLs when the host app provides capture and upload hooks.
14
18
  - Match feedback across localhost and production by `projectKey`, `contentId`, and normalized path.
15
19
  - Use Google OAuth in the browser and Google Sheets as the feedback store.
16
20
  - Support panel placement in all four corners.
@@ -94,6 +98,9 @@ Config:
94
98
  | `contentId` | yes | Stable content key shared by localhost and production. |
95
99
  | `currentUrl` | no | URL to store and normalize. Defaults to `window.location.href`. |
96
100
  | `normalizeUrl` | no | Custom URL normalization function. |
101
+ | `designTokens` | no | Allowed spacing, font size, line height, color, and radius values for advisory token checks. |
102
+ | `captureScreenshot` | no | Optional hook that captures a screenshot for a selected target. |
103
+ | `uploadAttachment` | no | Optional hook that stores screenshots and returns attachment URLs. |
97
104
  | `adapter` | no | Custom storage adapter for tests, demos, or a future backend. |
98
105
 
99
106
  ### `ReviewLensOverlay`
@@ -106,6 +113,7 @@ Render this when review mode should be available.
106
113
  onOpenChange={setReviewOpen}
107
114
  placement="bottom-left"
108
115
  showResolved={false}
116
+ syncSelectionToUrl={true}
109
117
  />
110
118
  ```
111
119
 
@@ -117,6 +125,8 @@ Props:
117
125
  | `onOpenChange` | no | Called when the overlay requests closing. |
118
126
  | `placement` | no | `top-left`, `top-right`, `bottom-left`, or `bottom-right`. Defaults to `top-right`. |
119
127
  | `showResolved` | no | Shows resolved comments when true. Defaults to false. |
128
+ | `syncSelectionToUrl` | no | Writes `reviewLensFeedback=<id>` into the URL and opens matching shared links. |
129
+ | `responsivePresets` | no | Viewport preset labels stored with new feedback. |
120
130
 
121
131
  ## Google Setup
122
132
 
@@ -191,12 +201,20 @@ Share the Sheet with every reviewer/developer who should use the overlay. Users
191
201
  Create a tab named `Feedback` with this exact header row:
192
202
 
193
203
  ```csv
194
- id,projectKey,contentId,normalizedPath,originalUrl,selector,selectorStrategy,elementFingerprintJson,cssSnapshotJson,comment,status,authorEmail,createdAt,updatedAt,resolvedAt,resolvedBy
204
+ id,projectKey,contentId,normalizedPath,originalUrl,selector,selectorStrategy,elementFingerprintJson,createdCssSnapshotJson,comment,status,severity,category,assigneeEmail,viewportWidth,viewportHeight,viewportPreset,screenshotUrl,screenshotThumbnailUrl,attachmentJson,authorEmail,createdAt,updatedAt,fixedCssSnapshotJson,fixedAt,fixedBy,resolvedAt,resolvedBy
195
205
  ```
196
206
 
197
- The library appends new feedback rows and updates existing rows when feedback is resolved.
207
+ The library appends new feedback rows and updates existing rows when status, assignment, screenshot metadata, or fixed-state snapshots change.
198
208
 
199
- ### 7. Add the `Users` tab
209
+ ### 7. Add the `Messages` tab
210
+
211
+ Create a tab named `Messages` with this header row:
212
+
213
+ ```csv
214
+ id,feedbackId,body,authorEmail,createdAt
215
+ ```
216
+
217
+ ### 8. Add the `Users` tab
200
218
 
201
219
  Create a tab named `Users` with this header row:
202
220
 
@@ -216,9 +234,9 @@ Roles:
216
234
 
217
235
  | Role | Permissions |
218
236
  | --- | --- |
219
- | `designer` | Read and create feedback. |
220
- | `developer` | Read feedback and resolve it. |
221
- | `admin` | Read, create, and resolve feedback. |
237
+ | `designer` | Read, create, and reply. |
238
+ | `developer` | Read, reply, update status, and assign. |
239
+ | `admin` | Read, create, reply, update status, and assign. |
222
240
 
223
241
  If `projectKey` is empty, the user role applies to every project using the Sheet. If `active` is `false`, the row is ignored.
224
242
 
@@ -277,7 +295,7 @@ const adapter = {
277
295
  return { email: "designer@example.com" };
278
296
  },
279
297
  async getPermissions() {
280
- return ["create", "read", "resolve"];
298
+ return ["create", "read", "reply", "update", "assign"];
281
299
  },
282
300
  async listFeedback(params) {
283
301
  return [];
@@ -286,13 +304,23 @@ const adapter = {
286
304
  return {
287
305
  ...input,
288
306
  id: crypto.randomUUID(),
289
- status: "open",
307
+ attachments: [],
290
308
  createdAt: new Date().toISOString(),
291
309
  updatedAt: new Date().toISOString()
292
310
  };
293
311
  },
294
- async resolveFeedback(id, resolvedBy) {
295
- throw new Error("Implement resolveFeedback");
312
+ async updateFeedback(id, patch) {
313
+ throw new Error("Implement updateFeedback");
314
+ },
315
+ async listMessages(feedbackId) {
316
+ return [];
317
+ },
318
+ async createMessage(input) {
319
+ return {
320
+ ...input,
321
+ id: crypto.randomUUID(),
322
+ createdAt: new Date().toISOString()
323
+ };
296
324
  }
297
325
  };
298
326
  ```
@@ -349,4 +377,3 @@ data-testid="registration-form"
349
377
  ```
350
378
 
351
379
  Generated CSS paths work, but they are more likely to break when DOM structure changes.
352
-
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import "./styles.css";
2
2
  export { ReviewLensProvider, useReviewLens } from "./review-lens-provider";
3
3
  export { ReviewLensOverlay } from "./review-lens-overlay";
4
- export type { ReviewLensOverlayPlacement } from "./review-lens-overlay";
4
+ export type { ReviewLensOverlayPlacement, ReviewLensViewportOption } from "./review-lens-overlay";
5
5
  export { createGoogleSheetsAdapter } from "./sheets/google-sheets-adapter";
6
6
  export { buildElementTarget } from "./selectors/build-element-target";
7
7
  export { normalizeReviewUrl } from "./url/normalize-review-url";
8
- export type { CssSnapshot, CreateFeedbackInput, ElementFingerprint, FeedbackStatus, ReviewLensAdapter, ReviewLensConfig, ReviewLensFeedback, ReviewLensPermission, ReviewLensRole, ReviewLensTarget } from "./types";
8
+ export type { CssSnapshot, CreateAttachmentInput, CreateFeedbackInput, CreateMessageInput, ElementFingerprint, FeedbackCategory, FeedbackSeverity, FeedbackStatus, ReviewLensAttachment, ReviewLensAdapter, ReviewLensConfig, ReviewLensDesignTokens, ReviewLensFeedback, ReviewLensPermission, ReviewLensRole, ReviewLensTarget, ReviewLensThreadMessage, ReviewLensViewportPreset, UpdateFeedbackInput } from "./types";
@@ -1,9 +1,16 @@
1
+ import type { ReviewLensViewportPreset } from "./types";
1
2
  type ReviewLensOverlayProps = {
2
3
  open: boolean;
3
4
  onOpenChange?: (open: boolean) => void;
4
5
  placement?: ReviewLensOverlayPlacement;
5
6
  showResolved?: boolean;
7
+ syncSelectionToUrl?: boolean;
8
+ responsivePresets?: ReviewLensViewportOption[];
6
9
  };
7
10
  export type ReviewLensOverlayPlacement = "top-left" | "top-right" | "bottom-left" | "bottom-right";
8
- export declare function ReviewLensOverlay({ open, onOpenChange, placement, showResolved }: ReviewLensOverlayProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export type ReviewLensViewportOption = {
12
+ label: string;
13
+ value: ReviewLensViewportPreset;
14
+ };
15
+ export declare function ReviewLensOverlay({ open, onOpenChange, placement, showResolved, syncSelectionToUrl, responsivePresets }: ReviewLensOverlayProps): import("react/jsx-runtime").JSX.Element | null;
9
16
  export {};
@@ -1,4 +1,4 @@
1
- import type { CreateFeedbackInput, ReviewLensAdapter, ReviewLensConfig, ReviewLensFeedback, ReviewLensPermission, ReviewLensProviderProps } from "./types";
1
+ import type { CreateAttachmentInput, CreateFeedbackInput, CreateMessageInput, ReviewLensAdapter, ReviewLensAttachment, ReviewLensConfig, ReviewLensFeedback, ReviewLensPermission, ReviewLensProviderProps, ReviewLensThreadMessage, UpdateFeedbackInput } from "./types";
2
2
  type ReviewLensContextValue = {
3
3
  config: ReviewLensConfig;
4
4
  adapter: ReviewLensAdapter;
@@ -10,7 +10,10 @@ type ReviewLensContextValue = {
10
10
  normalizedPath: string;
11
11
  refreshFeedback: () => Promise<void>;
12
12
  createFeedback: (input: CreateFeedbackInput) => Promise<ReviewLensFeedback>;
13
- resolveFeedback: (id: string) => Promise<ReviewLensFeedback>;
13
+ updateFeedback: (id: string, patch: UpdateFeedbackInput) => Promise<ReviewLensFeedback>;
14
+ listMessages: (feedbackId: string) => Promise<ReviewLensThreadMessage[]>;
15
+ createMessage: (input: CreateMessageInput) => Promise<ReviewLensThreadMessage>;
16
+ uploadAttachment: (feedbackId: string, input: CreateAttachmentInput) => Promise<ReviewLensAttachment>;
14
17
  };
15
18
  export declare function ReviewLensProvider({ config, children }: ReviewLensProviderProps): import("react/jsx-runtime").JSX.Element;
16
19
  export declare function useReviewLens(): ReviewLensContextValue;