@designfever/web-review-kit 0.4.1 → 0.5.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
@@ -92,12 +92,15 @@ Browser env must use a Supabase `anon` key only. Do not put `service_role` or Op
92
92
  ```ts
93
93
  import { createWebReviewKit, localAdapter } from '@designfever/web-review-kit';
94
94
  import { mountReviewShell } from '@designfever/web-review-kit/react-shell';
95
- import { reviewSourceLocator } from '@designfever/web-review-kit/vite';
95
+ import {
96
+ reviewDataLocator,
97
+ reviewSourceLocator,
98
+ } from '@designfever/web-review-kit/vite';
96
99
  ```
97
100
 
98
101
  - `@designfever/web-review-kit`: core API, adapters, shared types.
99
102
  - `@designfever/web-review-kit/react-shell`: review shell UI, presence adapters, page glob helper.
100
- - `@designfever/web-review-kit/vite`: dev-only JSX source locator for source file hints.
103
+ - `@designfever/web-review-kit/vite`: dev-only source/data locators for review hints.
101
104
  - `src/*` is not a public import path.
102
105
 
103
106
  ## Optional Source Locator
@@ -106,7 +109,10 @@ For local QA, add the Vite plugin to inject source hints into rendered DOM nodes
106
109
 
107
110
  ```ts
108
111
  import { defineConfig } from 'vite';
109
- import { reviewSourceLocator } from '@designfever/web-review-kit/vite';
112
+ import {
113
+ reviewDataLocator,
114
+ reviewSourceLocator,
115
+ } from '@designfever/web-review-kit/vite';
110
116
 
111
117
  export default defineConfig({
112
118
  plugins: [
@@ -115,11 +121,16 @@ export default defineConfig({
115
121
  include: ['src'],
116
122
  filePath: 'absolute',
117
123
  }),
124
+ reviewDataLocator({
125
+ enabled: true,
126
+ include: ['src/data'],
127
+ filePath: 'absolute',
128
+ }),
118
129
  ],
119
130
  });
120
131
  ```
121
132
 
122
- When source hints are available, hold `Option` over the review target to inspect source candidates from the DOM ancestry. Click the target to pin the candidate list, then choose a file to open. DOM QA cards also show a source action when the saved item has source hints. Keep this plugin disabled for production builds because it writes source paths into the DOM.
133
+ When source hints are available, hold `Option` over the review target to inspect source candidates from the DOM ancestry. Click the target to pin the candidate list, then choose a file to open. The side rail can also open a Source Tree panel with section/source/data links. DOM QA cards show a source action when the saved item has source hints. Keep these plugins disabled for production builds because they write source paths into the DOM.
123
134
 
124
135
  ```tsx
125
136
  mountReviewShell({
@@ -129,6 +140,10 @@ mountReviewShell({
129
140
  sourceRoot: import.meta.env.VITE_REVIEW_SOURCE_ROOT,
130
141
  sourceInspector: {
131
142
  editor: 'cursor', // 'vscode' | 'cursor' | 'webstorm' | 'custom'
143
+ maxDepth: 9,
144
+ hoverOutline: true,
145
+ includePlacer: false,
146
+ ignore: ['core.section', 'control.render'],
132
147
  // urlTemplate: 'my-editor://open?file={encodedPath}&line={line}&column={column}',
133
148
  },
134
149
  });
@@ -400,6 +400,20 @@ function getDomAnchorFromPoint(point, configuredAttribute = "data-qa-id", enviro
400
400
  source: getDomSourceHint(target)
401
401
  };
402
402
  }
403
+ function getDomAnchorFromElement(target, configuredAttribute = "data-qa-id", environment) {
404
+ if (target.ownerDocument !== environment.document) return void 0;
405
+ const candidates = createAnchorCandidates(target, configuredAttribute);
406
+ const primary = candidates[0];
407
+ if (!primary) return void 0;
408
+ return {
409
+ ...primary,
410
+ candidates,
411
+ htmlSnippet: getElementHtmlSnippet(
412
+ getAnchorSourceElement(target, primary, configuredAttribute) ?? target
413
+ ),
414
+ source: getDomSourceHint(target)
415
+ };
416
+ }
403
417
  function getElementViewportSelection(anchor, environment, preferredSelection) {
404
418
  const element = getAnchorElement(anchor, environment, preferredSelection);
405
419
  if (!element) return void 0;
@@ -1836,6 +1850,12 @@ function createStyleElement() {
1836
1850
  outline-offset: 1px;
1837
1851
  }
1838
1852
 
1853
+ @media (hover: none) and (pointer: coarse) {
1854
+ .dfwr-textarea {
1855
+ font-size: 16px;
1856
+ }
1857
+ }
1858
+
1839
1859
  .dfwr-adjust-panel {
1840
1860
  display: grid;
1841
1861
  gap: 4px;
@@ -3542,6 +3562,7 @@ function createWebReviewKit(options) {
3542
3562
  close: () => app.close(),
3543
3563
  toggle: () => app.toggle(),
3544
3564
  setMode: (mode) => app.setMode(mode),
3565
+ startElementReview: (element, comment) => app.startElementReview(element, comment),
3545
3566
  getMode: () => app.getMode(),
3546
3567
  highlightItem: (itemId) => app.highlightItem(itemId),
3547
3568
  setHiddenItemIds: (itemIds) => app.setHiddenItemIds(itemIds),
@@ -3672,6 +3693,16 @@ var WebReviewKitApp = class {
3672
3693
  this.areaDraft = void 0;
3673
3694
  this.render();
3674
3695
  }
3696
+ async startElementReview(element, comment) {
3697
+ if (!this.isOpen) {
3698
+ this.isOpen = true;
3699
+ }
3700
+ this.setModeState("element");
3701
+ this.noteDraft = void 0;
3702
+ this.areaDraft = void 0;
3703
+ this.isSelectingArea = false;
3704
+ await this.bindElementDraftToElement(element, comment);
3705
+ }
3675
3706
  getMode() {
3676
3707
  return this.mode;
3677
3708
  }
@@ -3880,6 +3911,47 @@ var WebReviewKitApp = class {
3880
3911
  this.noteDraft = draft;
3881
3912
  this.render();
3882
3913
  }
3914
+ async bindElementDraftToElement(element, comment) {
3915
+ const environment = this.getEnvironment();
3916
+ if (!environment || element.ownerDocument !== environment.document) return;
3917
+ const viewport = getViewportSize(environment);
3918
+ const draft = await this.withOverlayHidden(() => {
3919
+ const rect = element.getBoundingClientRect();
3920
+ if (rect.width <= 0 || rect.height <= 0) return void 0;
3921
+ const selection = {
3922
+ left: rect.left,
3923
+ top: rect.top,
3924
+ width: rect.width,
3925
+ height: rect.height
3926
+ };
3927
+ const anchor = getDomAnchorFromElement(
3928
+ element,
3929
+ this.options.anchors?.attribute,
3930
+ environment
3931
+ );
3932
+ const markerPoint = { x: selection.left, y: selection.top };
3933
+ const marker = {
3934
+ viewport: roundPoint(markerPoint),
3935
+ relative: anchor ? getRelativePoint(markerPoint, anchor, environment) : void 0
3936
+ };
3937
+ const reviewSelection = {
3938
+ viewport: toPublicSelection(selection),
3939
+ relative: anchor ? getRelativeSelection(selection, anchor, environment) : void 0
3940
+ };
3941
+ const previewElement = "style" in element ? element : void 0;
3942
+ return {
3943
+ viewport,
3944
+ anchor,
3945
+ marker,
3946
+ selection: reviewSelection,
3947
+ comment,
3948
+ previewElement
3949
+ };
3950
+ });
3951
+ if (!draft) return;
3952
+ this.noteDraft = draft;
3953
+ this.render();
3954
+ }
3883
3955
  async createAreaDraft(selection) {
3884
3956
  const environment = this.getEnvironment();
3885
3957
  if (!environment) return;
@@ -3984,6 +4056,8 @@ function createNoopController() {
3984
4056
  },
3985
4057
  setMode() {
3986
4058
  },
4059
+ async startElementReview() {
4060
+ },
3987
4061
  getMode() {
3988
4062
  return "idle";
3989
4063
  },
@@ -4006,12 +4080,14 @@ export {
4006
4080
  REVIEW_WORKFLOW_STATUS_OPTIONS,
4007
4081
  normalizeReviewItemStatus,
4008
4082
  localAdapter,
4083
+ clamp,
4009
4084
  DEFAULT_REVIEW_VIEWPORTS,
4010
4085
  findReviewViewportPreset,
4011
4086
  getReviewViewportScope,
4012
4087
  getReviewItemScope,
4013
4088
  getReviewItemScopeLabel,
4014
4089
  getNumberedReviewItems,
4090
+ runWithAutoScrollBehavior,
4015
4091
  createWebReviewKit
4016
4092
  };
4017
- //# sourceMappingURL=chunk-6L2KJ7XL.js.map
4093
+ //# sourceMappingURL=chunk-TWCSIBMY.js.map