@agentprojectcontext/apx 1.53.5 → 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.
@@ -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-DJpij6dQ.js"></script>
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
- if (ref.current && !ref.current.contains(e.target as Node)) onClose();
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
- className="absolute right-0 top-full z-50 mt-1 w-64 rounded-md border border-border bg-popover shadow-lg"
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