Attributes UX: Key (type) labels, filter, Overlay without field target.
CE-WP-0010: rename form vocabulary in user-facing strings to attributes, show type next to keys, filter attributes at ≥3 characters, and allow card→highlight guide lines when no attribute is focused.
This commit is contained in:
parent
c07e369bdb
commit
32c5a2ede4
5 changed files with 137 additions and 53 deletions
|
|
@ -11,10 +11,10 @@
|
|||
* `useSyncExternalStore` subscription via `useRectRegistryVersion` picks
|
||||
* up that single tick and React re-renders once per frame.
|
||||
*
|
||||
* Active-only: only the currently active triple is drawn. If any leg's
|
||||
* rect is missing (e.g. the viewer hasn't reported a highlight rect for
|
||||
* the active annotation yet), that leg is omitted but the other one
|
||||
* still renders.
|
||||
* Active-only: draws legs for the active evidence card. Attribute→card
|
||||
* when a Capture attribute is focused; card→highlight whenever the
|
||||
* highlight rect is available (Annotate or Capture). Missing legs are
|
||||
* omitted independently.
|
||||
*
|
||||
* MVP-sufficient. Future polish: easing the curve direction by source
|
||||
* type, animating the transition between active states, dimming
|
||||
|
|
@ -33,14 +33,6 @@ function rectCenter(rect: DOMRect): { x: number; y: number } {
|
|||
return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
|
||||
}
|
||||
|
||||
function rectBottomCenter(rect: DOMRect): { x: number; y: number } {
|
||||
return { x: rect.left + rect.width / 2, y: rect.bottom };
|
||||
}
|
||||
|
||||
function rectTopCenter(rect: DOMRect): { x: number; y: number } {
|
||||
return { x: rect.left + rect.width / 2, y: rect.top };
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a quadratic bezier from `a` to `b` whose control point bulges
|
||||
* horizontally between them. The horizontal-bulge style is right for a
|
||||
|
|
@ -72,18 +64,24 @@ export function Overlay({
|
|||
const version = useRectRegistryVersion();
|
||||
|
||||
const paths = useMemo<readonly string[]>(() => {
|
||||
if (!state.activeTarget || !state.activeEvidenceItemId) return [];
|
||||
const fieldRect = registry.getRect("field", state.activeTarget.targetId);
|
||||
// CE-WP-0010: card → highlight is enough for Annotate mode (no attribute
|
||||
// target). Field → card still draws when Capture has an active target.
|
||||
if (!state.activeEvidenceItemId) return [];
|
||||
const fieldRect = state.activeTarget
|
||||
? registry.getRect("field", state.activeTarget.targetId)
|
||||
: null;
|
||||
const cardRect = registry.getRect("evidence-card", state.activeEvidenceItemId);
|
||||
const highlightRect = state.activeAnnotationId
|
||||
? registry.getRect("highlight", state.activeAnnotationId)
|
||||
: null;
|
||||
const out: string[] = [];
|
||||
if (fieldRect && cardRect) {
|
||||
out.push(bezierPath(rectBottomCenter(fieldRect), rectTopCenter(cardRect)));
|
||||
// Horizontal layout (Evidence | Attributes): centre-to-centre reads better
|
||||
// than the old bottom-strip geometry.
|
||||
out.push(bezierPath(rectCenter(fieldRect), rectCenter(cardRect)));
|
||||
}
|
||||
if (cardRect && highlightRect) {
|
||||
out.push(bezierPath(rectTopCenter(cardRect), rectCenter(highlightRect)));
|
||||
out.push(bezierPath(rectCenter(cardRect), rectCenter(highlightRect)));
|
||||
}
|
||||
void version; // memo invalidator
|
||||
return out;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue