@agentprojectcontext/apx 1.53.4 → 1.53.6
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/package.json +1 -1
- package/src/interfaces/web/dist/assets/{index-Cy355-jV.js → index-Bks35ks-.js} +24 -24
- package/src/interfaces/web/dist/assets/{index-Cy355-jV.js.map → index-Bks35ks-.js.map} +1 -1
- package/src/interfaces/web/dist/index.html +1 -1
- package/src/interfaces/web/src/components/inputs/VarTokenInput.tsx +53 -6
- package/src/interfaces/web/src/components/ui.tsx +4 -2
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<link rel="apple-touch-icon" href="/favicon/dark/apple-touch-icon.png" media="(prefers-color-scheme: dark)" />
|
|
19
19
|
<link rel="manifest" href="/favicon/white/site.webmanifest" media="(prefers-color-scheme: light)" />
|
|
20
20
|
<link rel="manifest" href="/favicon/dark/site.webmanifest" media="(prefers-color-scheme: dark)" />
|
|
21
|
-
<script type="module" crossorigin src="/assets/index-
|
|
21
|
+
<script type="module" crossorigin src="/assets/index-Bks35ks-.js"></script>
|
|
22
22
|
<link rel="stylesheet" crossorigin href="/assets/index-BwnMDZaD.css">
|
|
23
23
|
</head>
|
|
24
24
|
<body class="bg-background text-foreground antialiased">
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type CSSProperties,
|
|
2
3
|
forwardRef,
|
|
4
|
+
type RefObject,
|
|
3
5
|
useCallback,
|
|
4
6
|
useEffect,
|
|
5
7
|
useImperativeHandle,
|
|
8
|
+
useLayoutEffect,
|
|
6
9
|
useRef,
|
|
7
10
|
useState,
|
|
8
11
|
} from "react";
|
|
12
|
+
import { createPortal } from "react-dom";
|
|
9
13
|
import { Plus } from "lucide-react";
|
|
10
14
|
import { cn } from "../../lib/cn";
|
|
11
15
|
import { Tip } from "../ui/tip";
|
|
@@ -133,6 +137,7 @@ interface VarTokenInputProps {
|
|
|
133
137
|
export const VarTokenInput = forwardRef<VarTokenInputHandle, VarTokenInputProps>(
|
|
134
138
|
function VarTokenInput({ value, onChange, placeholder, className, varNames = [], onCreateVar }, ref) {
|
|
135
139
|
const editorRef = useRef<HTMLDivElement>(null);
|
|
140
|
+
const pickerAnchorRef = useRef<HTMLDivElement>(null);
|
|
136
141
|
const savedRange = useRef<Range | null>(null);
|
|
137
142
|
const [pickerOpen, setPickerOpen] = useState(false);
|
|
138
143
|
const [pickerQuery, setPickerQuery] = useState("");
|
|
@@ -285,7 +290,7 @@ export const VarTokenInput = forwardRef<VarTokenInputHandle, VarTokenInputProps>
|
|
|
285
290
|
</span>
|
|
286
291
|
)}
|
|
287
292
|
</div>
|
|
288
|
-
<div className="relative flex">
|
|
293
|
+
<div ref={pickerAnchorRef} className="relative flex">
|
|
289
294
|
<Tip content={t("chat_ui.insert_variable")}>
|
|
290
295
|
<button
|
|
291
296
|
type="button"
|
|
@@ -308,6 +313,7 @@ export const VarTokenInput = forwardRef<VarTokenInputHandle, VarTokenInputProps>
|
|
|
308
313
|
</Tip>
|
|
309
314
|
{pickerOpen && (
|
|
310
315
|
<VarPickerPopover
|
|
316
|
+
anchorRef={pickerAnchorRef}
|
|
311
317
|
query={pickerQuery}
|
|
312
318
|
onQuery={setPickerQuery}
|
|
313
319
|
varNames={filtered}
|
|
@@ -330,6 +336,7 @@ export const VarTokenInput = forwardRef<VarTokenInputHandle, VarTokenInputProps>
|
|
|
330
336
|
);
|
|
331
337
|
|
|
332
338
|
function VarPickerPopover({
|
|
339
|
+
anchorRef,
|
|
333
340
|
query,
|
|
334
341
|
onQuery,
|
|
335
342
|
varNames,
|
|
@@ -337,6 +344,7 @@ function VarPickerPopover({
|
|
|
337
344
|
onClose,
|
|
338
345
|
onCreateVar,
|
|
339
346
|
}: {
|
|
347
|
+
anchorRef: RefObject<HTMLElement | null>;
|
|
340
348
|
query: string;
|
|
341
349
|
onQuery: (s: string) => void;
|
|
342
350
|
varNames: string[];
|
|
@@ -346,6 +354,40 @@ function VarPickerPopover({
|
|
|
346
354
|
}) {
|
|
347
355
|
const ref = useRef<HTMLDivElement>(null);
|
|
348
356
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
357
|
+
const [rect, setRect] = useState<CSSProperties | null>(null);
|
|
358
|
+
|
|
359
|
+
const updatePosition = useCallback(() => {
|
|
360
|
+
const anchor = anchorRef.current;
|
|
361
|
+
if (!anchor) return;
|
|
362
|
+
const r = anchor.getBoundingClientRect();
|
|
363
|
+
const width = 256;
|
|
364
|
+
const gap = 4;
|
|
365
|
+
const margin = 8;
|
|
366
|
+
const maxLeft = window.innerWidth - width - margin;
|
|
367
|
+
const left = Math.max(margin, Math.min(r.right - width, maxLeft));
|
|
368
|
+
const below = r.bottom + gap;
|
|
369
|
+
const popoverHeight = ref.current?.offsetHeight ?? 260;
|
|
370
|
+
const top =
|
|
371
|
+
below + popoverHeight <= window.innerHeight - margin
|
|
372
|
+
? below
|
|
373
|
+
: Math.max(margin, r.top - popoverHeight - gap);
|
|
374
|
+
setRect({ left, top, width });
|
|
375
|
+
}, [anchorRef]);
|
|
376
|
+
|
|
377
|
+
useLayoutEffect(() => {
|
|
378
|
+
updatePosition();
|
|
379
|
+
}, [updatePosition, query, varNames.length]);
|
|
380
|
+
|
|
381
|
+
useEffect(() => {
|
|
382
|
+
updatePosition();
|
|
383
|
+
window.addEventListener("resize", updatePosition);
|
|
384
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
385
|
+
return () => {
|
|
386
|
+
window.removeEventListener("resize", updatePosition);
|
|
387
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
388
|
+
};
|
|
389
|
+
}, [updatePosition]);
|
|
390
|
+
|
|
349
391
|
// Focus the search field once on open, then never again — re-focus on every
|
|
350
392
|
// render is what made the editor click "bounce" back to the picker.
|
|
351
393
|
useEffect(() => {
|
|
@@ -353,15 +395,19 @@ function VarPickerPopover({
|
|
|
353
395
|
}, []);
|
|
354
396
|
useEffect(() => {
|
|
355
397
|
function onDoc(e: MouseEvent) {
|
|
356
|
-
|
|
398
|
+
const target = e.target as Node;
|
|
399
|
+
if (ref.current?.contains(target) || anchorRef.current?.contains(target)) return;
|
|
400
|
+
onClose();
|
|
357
401
|
}
|
|
358
402
|
document.addEventListener("mousedown", onDoc);
|
|
359
403
|
return () => document.removeEventListener("mousedown", onDoc);
|
|
360
|
-
}, [onClose]);
|
|
361
|
-
return
|
|
404
|
+
}, [anchorRef, onClose]);
|
|
405
|
+
if (!rect) return null;
|
|
406
|
+
return createPortal(
|
|
362
407
|
<div
|
|
363
408
|
ref={ref}
|
|
364
|
-
|
|
409
|
+
style={rect}
|
|
410
|
+
className="fixed z-[1000] rounded-md border border-border bg-popover shadow-lg"
|
|
365
411
|
>
|
|
366
412
|
<div className="border-b border-border p-2">
|
|
367
413
|
<input
|
|
@@ -405,7 +451,8 @@ function VarPickerPopover({
|
|
|
405
451
|
</button>
|
|
406
452
|
</div>
|
|
407
453
|
)}
|
|
408
|
-
</div
|
|
454
|
+
</div>,
|
|
455
|
+
document.body,
|
|
409
456
|
);
|
|
410
457
|
}
|
|
411
458
|
|
|
@@ -84,8 +84,10 @@ export function Field({
|
|
|
84
84
|
badge?: string;
|
|
85
85
|
children: ReactNode;
|
|
86
86
|
}) {
|
|
87
|
+
// Do not wrap controls in <label>: complex fields (contentEditable +
|
|
88
|
+
// buttons/popovers) can redirect clicks to the wrong nested control.
|
|
87
89
|
return (
|
|
88
|
-
<
|
|
90
|
+
<div className="block space-y-1">
|
|
89
91
|
<span className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
|
|
90
92
|
{label}
|
|
91
93
|
{badge && (
|
|
@@ -94,7 +96,7 @@ export function Field({
|
|
|
94
96
|
</span>
|
|
95
97
|
{children}
|
|
96
98
|
{hint && <span className="block text-[11px] text-muted-foreground/70">{hint}</span>}
|
|
97
|
-
</
|
|
99
|
+
</div>
|
|
98
100
|
);
|
|
99
101
|
}
|
|
100
102
|
|