@designfever/web-review-kit 0.4.1 → 0.6.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/dist/index.cjs CHANGED
@@ -558,6 +558,20 @@ function getDomAnchorFromPoint(point, configuredAttribute = "data-qa-id", enviro
558
558
  source: getDomSourceHint(target)
559
559
  };
560
560
  }
561
+ function getDomAnchorFromElement(target, configuredAttribute = "data-qa-id", environment) {
562
+ if (target.ownerDocument !== environment.document) return void 0;
563
+ const candidates = createAnchorCandidates(target, configuredAttribute);
564
+ const primary = candidates[0];
565
+ if (!primary) return void 0;
566
+ return {
567
+ ...primary,
568
+ candidates,
569
+ htmlSnippet: getElementHtmlSnippet(
570
+ getAnchorSourceElement(target, primary, configuredAttribute) ?? target
571
+ ),
572
+ source: getDomSourceHint(target)
573
+ };
574
+ }
561
575
  function getElementViewportSelection(anchor, environment, preferredSelection) {
562
576
  const element = getAnchorElement(anchor, environment, preferredSelection);
563
577
  if (!element) return void 0;
@@ -1506,6 +1520,14 @@ function createStyleElement() {
1506
1520
  cursor: default;
1507
1521
  }
1508
1522
 
1523
+ .dfwr-shell.is-docked-composer {
1524
+ position: relative;
1525
+ inset: auto;
1526
+ z-index: auto;
1527
+ padding: 0;
1528
+ pointer-events: auto;
1529
+ }
1530
+
1509
1531
  .dfwr-panel {
1510
1532
  position: fixed;
1511
1533
  right: 16px;
@@ -2006,6 +2028,20 @@ function createStyleElement() {
2006
2028
  border-color: rgba(99, 215, 199, 0.56);
2007
2029
  }
2008
2030
 
2031
+ .dfwr-shell.is-docked-composer .dfwr-note-popover.is-docked-composer,
2032
+ .dfwr-shell.is-docked-composer .dfwr-area-draft.is-docked-composer {
2033
+ position: relative;
2034
+ left: auto;
2035
+ right: auto;
2036
+ top: auto;
2037
+ z-index: auto;
2038
+ max-height: none;
2039
+ }
2040
+
2041
+ .dfwr-shell.is-docked-composer .dfwr-textarea {
2042
+ min-height: 184px;
2043
+ }
2044
+
2009
2045
  .dfwr-note-popover.is-dragging,
2010
2046
  .dfwr-area-draft.is-dragging {
2011
2047
  user-select: none;
@@ -2054,6 +2090,50 @@ function createStyleElement() {
2054
2090
  padding: 0;
2055
2091
  }
2056
2092
 
2093
+ .dfwr-actions.has-leading {
2094
+ align-items: center;
2095
+ justify-content: space-between;
2096
+ gap: 12px;
2097
+ }
2098
+
2099
+ .dfwr-actions-leading,
2100
+ .dfwr-actions-primary {
2101
+ display: flex;
2102
+ align-items: center;
2103
+ gap: 8px;
2104
+ min-width: 0;
2105
+ }
2106
+
2107
+ .dfwr-actions-primary {
2108
+ margin-left: auto;
2109
+ }
2110
+
2111
+ .dfwr-shell.is-docked-composer .dfwr-actions.has-leading {
2112
+ align-items: stretch;
2113
+ }
2114
+
2115
+ .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-button,
2116
+ .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-adjust-toggle {
2117
+ height: var(--df-review-control-height-md);
2118
+ min-height: var(--df-review-control-height-md);
2119
+ border-radius: var(--df-review-radius-sm);
2120
+ }
2121
+
2122
+ .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-button {
2123
+ min-width: 96px;
2124
+ padding: 0 12px;
2125
+ font-size: var(--df-review-font-size-sm);
2126
+ }
2127
+
2128
+ .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-adjust-toggle {
2129
+ width: var(--df-review-control-height-md);
2130
+ }
2131
+
2132
+ .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-adjust-toggle svg {
2133
+ width: 18px;
2134
+ height: 18px;
2135
+ }
2136
+
2057
2137
  .dfwr-note-actions {
2058
2138
  justify-content: flex-end;
2059
2139
  }
@@ -2090,6 +2170,12 @@ function createStyleElement() {
2090
2170
  outline-offset: 1px;
2091
2171
  }
2092
2172
 
2173
+ @media (hover: none) and (pointer: coarse) {
2174
+ .dfwr-textarea {
2175
+ font-size: 16px;
2176
+ }
2177
+ }
2178
+
2093
2179
  .dfwr-adjust-panel {
2094
2180
  display: grid;
2095
2181
  gap: 4px;
@@ -2372,10 +2458,12 @@ function createStyleElement() {
2372
2458
 
2373
2459
  @media (max-width: 520px) {
2374
2460
  .dfwr-panel {
2461
+ left: 8px;
2375
2462
  right: 8px;
2376
- top: 8px;
2377
- width: calc(100vw - 16px);
2378
- max-height: calc(100vh - 16px);
2463
+ top: auto;
2464
+ bottom: 8px;
2465
+ width: auto;
2466
+ max-height: min(70vh, calc(100vh - 16px));
2379
2467
  }
2380
2468
  }
2381
2469
  `;
@@ -2455,6 +2543,7 @@ var WebReviewKitView = class {
2455
2543
  }
2456
2544
  clearDraftPreview() {
2457
2545
  this.restoreDraftPreview();
2546
+ this.clearShellComposer();
2458
2547
  }
2459
2548
  render(shadow, hiddenItemsStyle) {
2460
2549
  const state = this.state;
@@ -2465,11 +2554,13 @@ var WebReviewKitView = class {
2465
2554
  shadow.append(createStyleElement());
2466
2555
  shadow.append(hiddenItemsStyle);
2467
2556
  const hasDismissableDraft = Boolean(state.noteDraft || state.areaDraft);
2557
+ const shouldDockComposer = this.config.options.ui?.panel === false && hasDismissableDraft && Boolean(this.getShellComposerHost());
2558
+ let dockedComposer;
2468
2559
  const shell = document.createElement("div");
2469
2560
  shell.className = [
2470
2561
  "dfwr-shell",
2471
2562
  state.isOpen ? "is-open" : "",
2472
- hasDismissableDraft ? "has-dismissible-draft" : ""
2563
+ hasDismissableDraft && !shouldDockComposer ? "has-dismissible-draft" : ""
2473
2564
  ].filter(Boolean).join(" ");
2474
2565
  shell.setAttribute("aria-hidden", state.isOpen ? "false" : "true");
2475
2566
  if (this.config.options.ui?.panel !== false) {
@@ -2486,13 +2577,21 @@ var WebReviewKitView = class {
2486
2577
  shell.append(panel);
2487
2578
  }
2488
2579
  shell.append(this.createMarkerLayer());
2489
- if (state.isOpen && hasDismissableDraft) {
2580
+ if (state.isOpen && hasDismissableDraft && !shouldDockComposer) {
2490
2581
  shell.append(this.createDraftCancelLayer());
2491
2582
  }
2492
2583
  if (state.isOpen && (state.mode === "note" || state.mode === "element")) {
2493
- shell.append(
2494
- state.noteDraft ? this.createNotePopover(state.noteDraft) : state.mode === "element" ? this.createElementLayer() : this.createNoteLayer()
2495
- );
2584
+ if (state.noteDraft) {
2585
+ const noteDraft = this.createNotePopover(state.noteDraft, {
2586
+ dockComposer: shouldDockComposer
2587
+ });
2588
+ shell.append(noteDraft.layer);
2589
+ dockedComposer = noteDraft.composer;
2590
+ } else {
2591
+ shell.append(
2592
+ state.mode === "element" ? this.createElementLayer() : this.createNoteLayer()
2593
+ );
2594
+ }
2496
2595
  }
2497
2596
  if (state.isOpen && state.mode === "area" && !state.areaDraft) {
2498
2597
  shell.append(this.createAreaLayer());
@@ -2501,32 +2600,73 @@ var WebReviewKitView = class {
2501
2600
  if (state.areaDraft.selection) {
2502
2601
  shell.append(this.createAreaDraftOverlay(state.areaDraft));
2503
2602
  }
2504
- shell.append(this.createAreaDraftPopover(state.areaDraft));
2603
+ const areaComposer = this.createAreaDraftPopover(state.areaDraft, {
2604
+ dockComposer: shouldDockComposer
2605
+ });
2606
+ if (shouldDockComposer) {
2607
+ dockedComposer = areaComposer;
2608
+ } else {
2609
+ shell.append(areaComposer);
2610
+ }
2505
2611
  }
2506
2612
  shadow.append(shell);
2613
+ this.renderShellComposer(dockedComposer);
2507
2614
  }
2508
2615
  get state() {
2509
2616
  return this.config.getState();
2510
2617
  }
2618
+ getShellComposerHost() {
2619
+ const environment = this.config.getEnvironment();
2620
+ if (this.config.options.ui?.panel !== false) return void 0;
2621
+ return environment?.composerHost ?? void 0;
2622
+ }
2623
+ renderShellComposer(composer) {
2624
+ const host = composer ? this.getShellComposerHost() : void 0;
2625
+ if (!host || !composer) {
2626
+ this.clearShellComposer();
2627
+ return;
2628
+ }
2629
+ if (this.shellComposerHost && this.shellComposerHost !== host) {
2630
+ this.clearShellComposer();
2631
+ }
2632
+ this.shellComposerHost = host;
2633
+ host.dataset.hasDraftComposer = "true";
2634
+ if (host.parentElement) {
2635
+ host.parentElement.dataset.hasDraftComposer = "true";
2636
+ }
2637
+ const shell = document.createElement("div");
2638
+ shell.className = "dfwr-shell is-open is-shell-draft is-docked-composer";
2639
+ shell.append(composer);
2640
+ host.replaceChildren(createStyleElement(), shell);
2641
+ }
2642
+ clearShellComposer() {
2643
+ const host = this.shellComposerHost;
2644
+ host?.replaceChildren();
2645
+ if (host) {
2646
+ delete host.dataset.hasDraftComposer;
2647
+ delete host.parentElement?.dataset.hasDraftComposer;
2648
+ }
2649
+ this.shellComposerHost = void 0;
2650
+ }
2511
2651
  createDraftCancelLayer() {
2512
2652
  const layer = document.createElement("div");
2513
2653
  layer.className = "dfwr-draft-cancel-layer";
2514
2654
  layer.setAttribute("aria-hidden", "true");
2515
- const cancel = (event) => {
2516
- event.preventDefault();
2517
- event.stopPropagation();
2518
- event.stopImmediatePropagation();
2519
- this.config.actions.setModeState("idle");
2520
- this.config.actions.clearDrafts();
2521
- this.config.actions.setSelectingArea(false);
2522
- this.config.actions.render();
2523
- };
2524
2655
  layer.addEventListener("pointerdown", (event) => {
2525
2656
  if (event.button !== 0) return;
2526
- cancel(event);
2657
+ this.cancelDraft(event);
2527
2658
  });
2528
2659
  return layer;
2529
2660
  }
2661
+ cancelDraft(event) {
2662
+ event?.preventDefault();
2663
+ event?.stopPropagation();
2664
+ event?.stopImmediatePropagation();
2665
+ this.config.actions.setModeState("idle");
2666
+ this.config.actions.clearDrafts();
2667
+ this.config.actions.setSelectingArea(false);
2668
+ this.config.actions.render();
2669
+ }
2530
2670
  getDraftAdjustmentMetrics(draft) {
2531
2671
  const adjustment = draft.adjustment;
2532
2672
  const x = adjustment?.x ?? 0;
@@ -2920,11 +3060,11 @@ ${adjustment}` : adjustment;
2920
3060
  empty.textContent = this.state.noteDraft ? "Write the note in the page box." : this.state.mode === "element" ? "Click an element to add QA." : "Click on the page to place a note.";
2921
3061
  return empty;
2922
3062
  }
2923
- createNotePopover(draft) {
3063
+ createNotePopover(draft, options = {}) {
2924
3064
  const environment = this.config.getEnvironment();
2925
3065
  const group = document.createElement("div");
2926
3066
  group.className = "dfwr-note-draft";
2927
- if (!environment) return group;
3067
+ if (!environment) return { layer: group, composer: void 0 };
2928
3068
  const isElementDraft = this.state.mode === "element" && Boolean(draft.selection);
2929
3069
  const hostPoint = toHostPoint(
2930
3070
  isElementDraft ? this.getAdjustedDraftPoint(draft.marker.viewport, draft) : draft.marker.viewport,
@@ -2948,8 +3088,14 @@ ${adjustment}` : adjustment;
2948
3088
  pin.style.top = `${hostPoint.y}px`;
2949
3089
  const popover = document.createElement("div");
2950
3090
  const position = getPopoverPosition(hostPoint, environment);
2951
- popover.className = `dfwr-note-popover${isElementDraft ? " is-composer" : ""}`;
2952
- if (isElementDraft) {
3091
+ popover.className = [
3092
+ "dfwr-note-popover",
3093
+ isElementDraft ? "is-composer" : "",
3094
+ options.dockComposer ? "is-docked-composer" : ""
3095
+ ].filter(Boolean).join(" ");
3096
+ if (options.dockComposer) {
3097
+ popover.style.width = "100%";
3098
+ } else if (isElementDraft) {
2953
3099
  const selection = draft.selection ? toHostSelection(
2954
3100
  this.getAdjustedDraftSelection(
2955
3101
  toViewportSelection(draft.selection.viewport),
@@ -3008,18 +3154,27 @@ ${adjustment}` : adjustment;
3008
3154
  pin,
3009
3155
  popover,
3010
3156
  selectionHighlight,
3011
- textarea
3157
+ textarea,
3158
+ dockToggle: options.dockComposer
3012
3159
  }) : void 0;
3013
- const actions = this.createFormActions("Save note", saveDraft);
3160
+ const actions = this.createFormActions("Save note", saveDraft, {
3161
+ leading: adjustmentControls?.actionButton ? [adjustmentControls.actionButton] : void 0
3162
+ });
3014
3163
  form.append(
3015
3164
  ...meta ? [meta] : [],
3016
3165
  ...adjustmentControls ? [adjustmentControls.panel] : [],
3017
3166
  textarea,
3018
3167
  actions
3019
3168
  );
3020
- const dragHandle = isElementDraft ? this.createDraftDragHandle("Move DOM composer") : void 0;
3021
- popover.append(...dragHandle ? [dragHandle] : [], form);
3022
- group.append(pin, popover);
3169
+ const dragHandle = isElementDraft && !options.dockComposer ? this.createDraftDragHandle("Move DOM composer") : void 0;
3170
+ popover.append(
3171
+ ...dragHandle ? [dragHandle] : [],
3172
+ form
3173
+ );
3174
+ group.append(pin);
3175
+ if (!options.dockComposer) {
3176
+ group.append(popover);
3177
+ }
3023
3178
  if (dragHandle) {
3024
3179
  this.attachDraftComposerDrag(popover, dragHandle, (composerPosition) => {
3025
3180
  const noteDraft = this.state.noteDraft ?? draft;
@@ -3032,18 +3187,23 @@ ${adjustment}` : adjustment;
3032
3187
  }
3033
3188
  this.attachDraftPinDrag(
3034
3189
  pin,
3035
- isElementDraft ? void 0 : popover,
3190
+ isElementDraft || options.dockComposer ? void 0 : popover,
3036
3191
  meta,
3037
3192
  textarea
3038
3193
  );
3039
- window.setTimeout(() => {
3040
- if (draft.adjustment?.isActive) {
3041
- adjustmentControls?.focusTarget.focus();
3042
- return;
3043
- }
3044
- textarea.focus();
3045
- }, 0);
3046
- return group;
3194
+ if (!options.dockComposer) {
3195
+ window.setTimeout(() => {
3196
+ if (draft.adjustment?.isActive) {
3197
+ adjustmentControls?.focusTarget.focus();
3198
+ return;
3199
+ }
3200
+ textarea.focus();
3201
+ }, 0);
3202
+ }
3203
+ return {
3204
+ layer: group,
3205
+ composer: options.dockComposer ? popover : void 0
3206
+ };
3047
3207
  }
3048
3208
  createDraftDragHandle(label) {
3049
3209
  const handle = document.createElement("button");
@@ -3135,7 +3295,8 @@ ${adjustment}` : adjustment;
3135
3295
  pin,
3136
3296
  popover,
3137
3297
  selectionHighlight,
3138
- textarea
3298
+ textarea,
3299
+ dockToggle
3139
3300
  }) {
3140
3301
  const panel = document.createElement("div");
3141
3302
  panel.className = "dfwr-adjust-panel is-dom-adjust-panel";
@@ -3211,12 +3372,16 @@ ${adjustment}` : adjustment;
3211
3372
  }
3212
3373
  }));
3213
3374
  });
3214
- header.append(help, adjust);
3375
+ header.append(help);
3376
+ if (!dockToggle) {
3377
+ header.append(adjust);
3378
+ }
3215
3379
  panel.append(header, xyStatus, scaleStatus);
3216
3380
  syncControls(draft);
3217
3381
  return {
3218
3382
  panel,
3219
- focusTarget: adjust
3383
+ focusTarget: adjust,
3384
+ actionButton: dockToggle ? adjust : void 0
3220
3385
  };
3221
3386
  }
3222
3387
  getAdjustmentKeyDelta(event) {
@@ -3342,11 +3507,17 @@ ${adjustment}` : adjustment;
3342
3507
  }
3343
3508
  return layer;
3344
3509
  }
3345
- createAreaDraftPopover(draft) {
3510
+ createAreaDraftPopover(draft, options = {}) {
3346
3511
  const environment = this.config.getEnvironment();
3347
3512
  const popover = document.createElement("div");
3348
- popover.className = "dfwr-area-draft is-composer";
3349
- if (environment && draft.selection) {
3513
+ popover.className = [
3514
+ "dfwr-area-draft",
3515
+ "is-composer",
3516
+ options.dockComposer ? "is-docked-composer" : ""
3517
+ ].filter(Boolean).join(" ");
3518
+ if (options.dockComposer) {
3519
+ popover.style.width = "100%";
3520
+ } else if (environment && draft.selection) {
3350
3521
  const selection = toHostSelection(
3351
3522
  toViewportSelection(draft.selection.viewport),
3352
3523
  environment
@@ -3362,15 +3533,20 @@ ${adjustment}` : adjustment;
3362
3533
  popover.style.width = `${composer.width}px`;
3363
3534
  popover.style.right = "auto";
3364
3535
  }
3365
- const dragHandle = this.createDraftDragHandle("Move area composer");
3366
- popover.append(dragHandle, this.createAreaForm());
3367
- this.attachDraftComposerDrag(popover, dragHandle, (composerPosition) => {
3368
- const areaDraft = this.state.areaDraft ?? draft;
3369
- this.config.actions.setAreaDraft({
3370
- ...areaDraft,
3371
- composerPosition
3536
+ const dragHandle = options.dockComposer ? void 0 : this.createDraftDragHandle("Move area composer");
3537
+ popover.append(
3538
+ ...dragHandle ? [dragHandle] : [],
3539
+ this.createAreaForm()
3540
+ );
3541
+ if (dragHandle) {
3542
+ this.attachDraftComposerDrag(popover, dragHandle, (composerPosition) => {
3543
+ const areaDraft = this.state.areaDraft ?? draft;
3544
+ this.config.actions.setAreaDraft({
3545
+ ...areaDraft,
3546
+ composerPosition
3547
+ });
3372
3548
  });
3373
- });
3549
+ }
3374
3550
  return popover;
3375
3551
  }
3376
3552
  createFormActions(saveLabel, onSave, options) {
@@ -3390,12 +3566,19 @@ ${adjustment}` : adjustment;
3390
3566
  cancel.type = "button";
3391
3567
  cancel.textContent = "Cancel";
3392
3568
  cancel.addEventListener("click", (event) => {
3393
- event.preventDefault();
3394
- event.stopPropagation();
3395
- this.config.actions.setModeState("idle");
3396
- this.config.actions.clearDrafts();
3397
- this.config.actions.render();
3569
+ this.cancelDraft(event);
3398
3570
  });
3571
+ if (options?.leading?.length) {
3572
+ actions.classList.add("has-leading");
3573
+ const leading = document.createElement("div");
3574
+ leading.className = "dfwr-actions-leading";
3575
+ leading.append(...options.leading);
3576
+ const primary = document.createElement("div");
3577
+ primary.className = "dfwr-actions-primary";
3578
+ primary.append(save, cancel);
3579
+ actions.append(leading, primary);
3580
+ return actions;
3581
+ }
3399
3582
  if (options?.beforeSave?.length || options?.className) {
3400
3583
  actions.append(cancel, ...options.beforeSave ?? [], save);
3401
3584
  return actions;
@@ -3796,6 +3979,7 @@ function createWebReviewKit(options) {
3796
3979
  close: () => app.close(),
3797
3980
  toggle: () => app.toggle(),
3798
3981
  setMode: (mode) => app.setMode(mode),
3982
+ startElementReview: (element, comment) => app.startElementReview(element, comment),
3799
3983
  getMode: () => app.getMode(),
3800
3984
  highlightItem: (itemId) => app.highlightItem(itemId),
3801
3985
  setHiddenItemIds: (itemIds) => app.setHiddenItemIds(itemIds),
@@ -3823,9 +4007,10 @@ var WebReviewKitApp = class {
3823
4007
  this.toggle();
3824
4008
  };
3825
4009
  this.handleViewportChange = () => {
3826
- if (!this.isOpen || this.renderFrame) return;
4010
+ if (!this.isOpen || this.renderFrame || this.isDraftComposerFocused()) return;
3827
4011
  this.renderFrame = window.requestAnimationFrame(() => {
3828
4012
  this.renderFrame = void 0;
4013
+ if (this.isDraftComposerFocused()) return;
3829
4014
  this.render();
3830
4015
  });
3831
4016
  };
@@ -3926,6 +4111,16 @@ var WebReviewKitApp = class {
3926
4111
  this.areaDraft = void 0;
3927
4112
  this.render();
3928
4113
  }
4114
+ async startElementReview(element, comment) {
4115
+ if (!this.isOpen) {
4116
+ this.isOpen = true;
4117
+ }
4118
+ this.setModeState("element");
4119
+ this.noteDraft = void 0;
4120
+ this.areaDraft = void 0;
4121
+ this.isSelectingArea = false;
4122
+ await this.bindElementDraftToElement(element, comment);
4123
+ }
3929
4124
  getMode() {
3930
4125
  return this.mode;
3931
4126
  }
@@ -3992,6 +4187,14 @@ var WebReviewKitApp = class {
3992
4187
  this.render();
3993
4188
  return true;
3994
4189
  }
4190
+ isDraftComposerFocused() {
4191
+ if (!this.noteDraft && !this.areaDraft) return false;
4192
+ const composerHost = this.getEnvironment()?.composerHost;
4193
+ const activeElement = composerHost?.ownerDocument.activeElement;
4194
+ return Boolean(
4195
+ composerHost && activeElement && composerHost.contains(activeElement)
4196
+ );
4197
+ }
3995
4198
  getEnvironment() {
3996
4199
  const target = typeof this.options.target === "function" ? this.options.target() : this.options.target;
3997
4200
  if (!target) {
@@ -4020,6 +4223,7 @@ var WebReviewKitApp = class {
4020
4223
  height: target.window.innerHeight
4021
4224
  };
4022
4225
  const overlayRect = target.getOverlayRect?.() ?? rect;
4226
+ const composerHost = target.getComposerHost?.();
4023
4227
  return {
4024
4228
  window: target.window,
4025
4229
  document: target.document,
@@ -4034,7 +4238,8 @@ var WebReviewKitApp = class {
4034
4238
  top: overlayRect.top,
4035
4239
  width: overlayRect.width,
4036
4240
  height: overlayRect.height
4037
- }
4241
+ },
4242
+ composerHost
4038
4243
  };
4039
4244
  } catch {
4040
4245
  return void 0;
@@ -4134,6 +4339,47 @@ var WebReviewKitApp = class {
4134
4339
  this.noteDraft = draft;
4135
4340
  this.render();
4136
4341
  }
4342
+ async bindElementDraftToElement(element, comment) {
4343
+ const environment = this.getEnvironment();
4344
+ if (!environment || element.ownerDocument !== environment.document) return;
4345
+ const viewport = getViewportSize(environment);
4346
+ const draft = await this.withOverlayHidden(() => {
4347
+ const rect = element.getBoundingClientRect();
4348
+ if (rect.width <= 0 || rect.height <= 0) return void 0;
4349
+ const selection = {
4350
+ left: rect.left,
4351
+ top: rect.top,
4352
+ width: rect.width,
4353
+ height: rect.height
4354
+ };
4355
+ const anchor = getDomAnchorFromElement(
4356
+ element,
4357
+ this.options.anchors?.attribute,
4358
+ environment
4359
+ );
4360
+ const markerPoint = { x: selection.left, y: selection.top };
4361
+ const marker = {
4362
+ viewport: roundPoint(markerPoint),
4363
+ relative: anchor ? getRelativePoint(markerPoint, anchor, environment) : void 0
4364
+ };
4365
+ const reviewSelection = {
4366
+ viewport: toPublicSelection(selection),
4367
+ relative: anchor ? getRelativeSelection(selection, anchor, environment) : void 0
4368
+ };
4369
+ const previewElement = "style" in element ? element : void 0;
4370
+ return {
4371
+ viewport,
4372
+ anchor,
4373
+ marker,
4374
+ selection: reviewSelection,
4375
+ comment,
4376
+ previewElement
4377
+ };
4378
+ });
4379
+ if (!draft) return;
4380
+ this.noteDraft = draft;
4381
+ this.render();
4382
+ }
4137
4383
  async createAreaDraft(selection) {
4138
4384
  const environment = this.getEnvironment();
4139
4385
  if (!environment) return;
@@ -4238,6 +4484,8 @@ function createNoopController() {
4238
4484
  },
4239
4485
  setMode() {
4240
4486
  },
4487
+ async startElementReview() {
4488
+ },
4241
4489
  getMode() {
4242
4490
  return "idle";
4243
4491
  },