@plannotator/ui 0.46.0 → 0.46.1
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/HANDOFF.md +2 -1
- package/README.md +1 -1
- package/hooks/useVimSelection.ts +28 -7
- package/package.json +1 -1
package/HANDOFF.md
CHANGED
|
@@ -1527,6 +1527,7 @@ The guide chain's engine plumbing (Claude/Codex/marker commands, output parsing,
|
|
|
1527
1527
|
|
|
1528
1528
|
## Publishing & versioning
|
|
1529
1529
|
|
|
1530
|
+
- **ui 0.46.1 (fix, ui only, core pin unchanged at `0.25.6`):** `useVimSelection` (mounted by every `Viewer`) now only clears a page selection whose anchor or focus lies inside the viewer's own container; with vim off it used to clear the WHOLE page's selection on every mount and `contentVersion` change, so a selection in another host panel vanished whenever the document behind it loaded or changed.
|
|
1530
1531
|
- **ui 0.45.0 (annotation card header slot + mentions on the card's edit box): `@plannotator/ui` only — `@plannotator/core` is UNCHANGED at `0.25.5`, so this publishes alone** (core 0.25.5 must already be published). Purely additive over 0.44.0, both props on `AnnotationPanel`: `renderCardHeader` (the header-row twin of `renderCardFooter`, wrapper `[data-annotation-card-header]`, renders under `readOnly`, open-document cards only in the All-files view) and `mentionSource` (the 0.43.0 type, applied to the card's EDIT box, saving `onEdit(id, { text, mentions })` only when a source was supplied and a pick survived). Nothing is removed, no new supported imports (`components/MentionAutocomplete` is internal glue), no export-, share- or archive-visible change, and Plannotator passes neither — `packages/editor` and `packages/review-editor` have zero source diff, and the panel is byte-identical to 0.44.0. Known difference from `CommentPopover`: no chips in the card's edit box (follow-up named in the section). See "Annotation card header slot and mentions on the edit box (0.45.0)".
|
|
1531
1532
|
- **ui 0.44.0 (mention token chips in the composer): `@plannotator/ui` only — `@plannotator/core` is UNCHANGED at `0.25.5`, so this publishes alone** (core 0.25.5 must already be published). Purely additive over 0.43.2: the `@Label` tokens a `mentionSource` composer inserted render as chips in the composer's existing highlight overlay, `MentionSource.tokenClassName?` lets a host restyle them (under the metric rule), `useMentionAutocomplete` also returns the surviving `mentions`, and `utils/composerTokens` joins the supported-import list. Nothing is removed, no export-, share- or archive-visible change, and Plannotator passes none of it — with neither `mentionSource` nor `skillReferences` the composer is byte-identical to 0.43.2. See "Mention token chips in the composer (0.44.0)".
|
|
1532
1533
|
- **ui 0.43.1 (`mentionSource` on the viewers): `@plannotator/ui` only — `@plannotator/core` is UNCHANGED at `0.25.5`, so this publishes alone** (core 0.25.5 must already be published). Purely additive over 0.43.0: `mentionSource` on `Viewer` and `HtmlViewer` (forwarded to every comment composer each mounts) and the optional `Annotation.mentions` field the picked ids land on, set only when a source was supplied and a token survived. Nothing is removed, no new modules, no export-, share- or archive-visible change, and Plannotator passes none of it. See "`mentionSource` on the viewers (0.43.1)".
|
|
@@ -1548,7 +1549,7 @@ The guide chain's engine plumbing (Claude/Codex/marker commands, output parsing,
|
|
|
1548
1549
|
|
|
1549
1550
|
---
|
|
1550
1551
|
|
|
1551
|
-
## `Settings` `annotateParity` (
|
|
1552
|
+
## `Settings` `annotateParity` (shipped in 0.46.0)
|
|
1552
1553
|
|
|
1553
1554
|
`<Settings mode="annotate">` takes a new optional `annotateParity?: boolean`,
|
|
1554
1555
|
default `false`. **A host that omits it sees exactly the annotate Settings it
|
package/README.md
CHANGED
|
@@ -367,7 +367,7 @@ npm install @plannotator/ui @plannotator/core
|
|
|
367
367
|
- `@plannotator/core` — pure utils + types, zero deps, browser-safe (CI enforces no `node:` imports). Published.
|
|
368
368
|
- `@plannotator/ui` — React components/hooks + theme + `configure()`. Depends on an exact published `@plannotator/core` version. Published.
|
|
369
369
|
- `@plannotator/shared`, `@plannotator/ai` — stay private to the monorepo; `shared` re-exports `core`'s modules via shims so Plannotator's internals are untouched.
|
|
370
|
-
- Currently `@plannotator/ui` 0.46.
|
|
370
|
+
- Currently `@plannotator/ui` 0.46.1 depends exactly on `@plannotator/core` 0.25.6. `core` is bumped only when something under `packages/core` changes, so `ui` can advance alone. Keep the published core version exact in `packages/ui/package.json`; do not use a `workspace:` protocol there, because a directly published manifest must remain installable outside this monorepo. Bun still links the matching local workspace during development. When both packages change, publish `core` first, then build and publish the UI tarball. See HANDOFF.md "Publishing & versioning" for the verification command.
|
|
371
371
|
|
|
372
372
|
## The one rule
|
|
373
373
|
|
package/hooks/useVimSelection.ts
CHANGED
|
@@ -227,6 +227,27 @@ function applyVisualBlockSelection(
|
|
|
227
227
|
if (points) applyNativeTextSelection(graph.container, points.cursor, points.anchor);
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Clear the page selection only when it touches the viewer's own document.
|
|
232
|
+
*
|
|
233
|
+
* A page has ONE selection, so an unconditional `removeAllRanges()` also kills
|
|
234
|
+
* a selection the user just made somewhere else (another panel of a host app,
|
|
235
|
+
* the annotation sidebar). A selection belongs to the viewer when its anchor or
|
|
236
|
+
* focus lies inside the container; with no container nothing is cleared.
|
|
237
|
+
*/
|
|
238
|
+
function clearSelectionWithin(container: HTMLElement | null | undefined): void {
|
|
239
|
+
if (!container) return;
|
|
240
|
+
const selection = window.getSelection();
|
|
241
|
+
if (!selection || selection.rangeCount === 0) return;
|
|
242
|
+
const { anchorNode, focusNode } = selection;
|
|
243
|
+
if (
|
|
244
|
+
(anchorNode && container.contains(anchorNode))
|
|
245
|
+
|| (focusNode && container.contains(focusNode))
|
|
246
|
+
) {
|
|
247
|
+
selection.removeAllRanges();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
230
251
|
/**
|
|
231
252
|
* Own semantic block navigation and precise text selection while the rendered
|
|
232
253
|
* document has focus.
|
|
@@ -291,7 +312,7 @@ export function useVimSelection({
|
|
|
291
312
|
if (!initial) return null;
|
|
292
313
|
const next: VimBlockState = { phase: 'block', targetKey: initial.key };
|
|
293
314
|
setState(next);
|
|
294
|
-
|
|
315
|
+
clearSelectionWithin(container);
|
|
295
316
|
scrollVimTargetIntoView(initial.element, scrollViewportRef.current);
|
|
296
317
|
return next;
|
|
297
318
|
}, [containerRef, setState]);
|
|
@@ -302,7 +323,7 @@ export function useVimSelection({
|
|
|
302
323
|
setFocused(false);
|
|
303
324
|
setHelpOpen(false);
|
|
304
325
|
setHudCommand(null);
|
|
305
|
-
|
|
326
|
+
clearSelectionWithin(containerRef.current);
|
|
306
327
|
return;
|
|
307
328
|
}
|
|
308
329
|
if (!focused) return;
|
|
@@ -366,9 +387,9 @@ export function useVimSelection({
|
|
|
366
387
|
|
|
367
388
|
const setSemanticTarget = useCallback((target: SemanticTarget) => {
|
|
368
389
|
setState(semanticStateForTarget(target));
|
|
369
|
-
|
|
390
|
+
clearSelectionWithin(containerRef.current);
|
|
370
391
|
scrollVimTargetIntoView(target.element, scrollViewportRef.current);
|
|
371
|
-
}, [setState]);
|
|
392
|
+
}, [containerRef, setState]);
|
|
372
393
|
|
|
373
394
|
const updateTextState = useCallback((
|
|
374
395
|
graph: SemanticTargetGraph,
|
|
@@ -816,13 +837,13 @@ export function useVimSelection({
|
|
|
816
837
|
setSemanticTarget(parent);
|
|
817
838
|
} else {
|
|
818
839
|
setState(createInitialVimSelectionState());
|
|
819
|
-
|
|
840
|
+
clearSelectionWithin(graph.container);
|
|
820
841
|
}
|
|
821
842
|
return;
|
|
822
843
|
}
|
|
823
844
|
case 'block':
|
|
824
845
|
setState(createInitialVimSelectionState());
|
|
825
|
-
|
|
846
|
+
clearSelectionWithin(graph.container);
|
|
826
847
|
}
|
|
827
848
|
}, [setSemanticTarget, setState, updateTextState]);
|
|
828
849
|
|
|
@@ -1041,7 +1062,7 @@ export function useVimSelection({
|
|
|
1041
1062
|
const onMouseDown = useCallback((event: ReactMouseEvent<HTMLElement>) => {
|
|
1042
1063
|
if (!enabled || isDocumentKeyboardControl(event.target)) return;
|
|
1043
1064
|
setState(createInitialVimSelectionState());
|
|
1044
|
-
|
|
1065
|
+
clearSelectionWithin(event.currentTarget);
|
|
1045
1066
|
if (document.activeElement !== event.currentTarget) {
|
|
1046
1067
|
pointerFocusRef.current = true;
|
|
1047
1068
|
event.currentTarget.focus({ preventScroll: true });
|