apostil 0.1.6 → 0.2.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.js CHANGED
@@ -427,7 +427,11 @@ function OverlayPin({
427
427
  useEffect2(() => {
428
428
  updatePos();
429
429
  window.addEventListener("resize", updatePos);
430
- return () => window.removeEventListener("resize", updatePos);
430
+ document.addEventListener("scroll", updatePos, true);
431
+ return () => {
432
+ window.removeEventListener("resize", updatePos);
433
+ document.removeEventListener("scroll", updatePos, true);
434
+ };
431
435
  }, [updatePos]);
432
436
  if (!pos) return null;
433
437
  return /* @__PURE__ */ jsx2(
@@ -460,6 +464,7 @@ function CommentPin({
460
464
  index,
461
465
  overlayRef
462
466
  }) {
467
+ if (thread.resolved) return null;
463
468
  if (thread.targetId) {
464
469
  return /* @__PURE__ */ jsx2(TargetedPin, { thread, index }, `targeted-${thread.id}`);
465
470
  }
@@ -544,9 +549,10 @@ function CommentComposer({
544
549
  const inputRef = useRef3(null);
545
550
  useEffect3(() => {
546
551
  if (autoFocus) {
547
- requestAnimationFrame(() => {
552
+ const timer = setTimeout(() => {
548
553
  inputRef.current?.focus();
549
- });
554
+ }, 50);
555
+ return () => clearTimeout(timer);
550
556
  }
551
557
  }, [autoFocus]);
552
558
  const handleSubmit = () => {
@@ -570,7 +576,7 @@ function CommentComposer({
570
576
  },
571
577
  placeholder,
572
578
  rows: 1,
573
- className: "flex-1 resize-none rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm\n placeholder:text-neutral-400 focus:outline-none focus:ring-2 focus:ring-neutral-300\n min-h-[36px] max-h-[120px]"
579
+ className: "flex-1 resize-none rounded-lg border border-neutral-200 bg-white px-3 py-1.5 text-sm\n placeholder:text-neutral-400 focus:outline-none focus:ring-2 focus:ring-neutral-300\n min-h-[36px] max-h-[120px]"
574
580
  }
575
581
  ),
576
582
  /* @__PURE__ */ jsx4(
@@ -578,7 +584,7 @@ function CommentComposer({
578
584
  {
579
585
  onClick: handleSubmit,
580
586
  disabled: !value.trim(),
581
- className: "flex items-center justify-center w-8 h-8 rounded-lg\n text-white disabled:opacity-30\n transition-colors shrink-0",
587
+ className: "flex items-center justify-center w-9 h-9 rounded-lg\n text-white disabled:opacity-30\n transition-colors shrink-0",
582
588
  style: { backgroundColor: brandColor },
583
589
  children: /* @__PURE__ */ jsx4(Send, { className: "w-3.5 h-3.5" })
584
590
  }
@@ -906,7 +912,7 @@ function findCommentTarget(el, boundary) {
906
912
  };
907
913
  }
908
914
  function CommentOverlay() {
909
- const { threads, commentMode, setCommentMode, user, addThread, setActiveThreadId, brandColor } = useApostil();
915
+ const { threads, commentMode, setCommentMode, user, addThread, activeThreadId, setActiveThreadId, brandColor } = useApostil();
910
916
  const overlayRef = useRef5(null);
911
917
  const [pendingPin, setPendingPin] = useState6(null);
912
918
  const [pendingPixel, setPendingPixel] = useState6(null);
@@ -917,9 +923,15 @@ function CommentOverlay() {
917
923
  if (!commentMode || !overlayRef.current) return;
918
924
  const overlayRect = overlayRef.current.getBoundingClientRect();
919
925
  const overlay = overlayRef.current;
920
- overlay.style.pointerEvents = "none";
921
- const elementBelow = document.elementFromPoint(e.clientX, e.clientY);
922
- overlay.style.pointerEvents = "";
926
+ const elements = document.elementsFromPoint(e.clientX, e.clientY);
927
+ let elementBelow = null;
928
+ for (const el of elements) {
929
+ if (el === overlay || overlay.contains(el)) continue;
930
+ if (el instanceof HTMLElement) {
931
+ elementBelow = el;
932
+ break;
933
+ }
934
+ }
923
935
  debug.log(" click at", { clientX: e.clientX, clientY: e.clientY });
924
936
  debug.log(" element below overlay:", elementBelow);
925
937
  if (elementBelow) {
@@ -983,34 +995,28 @@ function CommentOverlay() {
983
995
  },
984
996
  [pendingPin, addThread]
985
997
  );
986
- const cancelPending = useCallback4(() => {
987
- setPendingPin(null);
988
- setPendingPixel(null);
989
- setCommentMode(false);
990
- }, [setCommentMode]);
991
998
  useEffect5(() => {
992
- if (!pendingPin || !pendingRef.current) return;
993
- requestAnimationFrame(() => {
994
- if (!pendingRef.current) return;
995
- const rect = pendingRef.current.getBoundingClientRect();
996
- setPendingFlip({
997
- x: rect.right > window.innerWidth,
998
- y: rect.bottom > window.innerHeight
999
- });
999
+ if (!pendingPixel || !overlayRef.current) return;
1000
+ const overlayRect = overlayRef.current.getBoundingClientRect();
1001
+ const clickX = overlayRect.left + pendingPixel.left;
1002
+ const clickY = overlayRect.top + pendingPixel.top;
1003
+ setPendingFlip({
1004
+ x: clickX + 308 > window.innerWidth,
1005
+ y: clickY + 200 > window.innerHeight
1000
1006
  });
1001
- }, [pendingPin]);
1007
+ }, [pendingPixel, overlayRef]);
1002
1008
  useEffect5(() => {
1003
1009
  const hash = window.location.hash;
1004
- console.log("[apostil] hash check:", hash, "threads:", threads.length, threads.map((t) => t.id));
1010
+ debug.log("hash check:", hash, "threads:", threads.length);
1005
1011
  if (!hash.startsWith("#apostil-")) return;
1006
1012
  const threadId = hash.replace("#apostil-", "");
1007
- console.log("[apostil] looking for thread:", threadId);
1013
+ debug.log("looking for thread:", threadId);
1008
1014
  if (threads.length === 0) {
1009
- console.log("[apostil] no threads loaded yet, waiting...");
1015
+ debug.log("no threads loaded yet, waiting...");
1010
1016
  return;
1011
1017
  }
1012
1018
  const found = threads.find((t) => t.id === threadId);
1013
- console.log("[apostil] found thread:", found ? "yes" : "no");
1019
+ debug.log("found thread:", found ? "yes" : "no");
1014
1020
  if (found) {
1015
1021
  setActiveThreadId(threadId);
1016
1022
  window.history.replaceState(null, "", window.location.pathname);
@@ -1024,6 +1030,8 @@ function CommentOverlay() {
1024
1030
  setPendingPin(null);
1025
1031
  setPendingPixel(null);
1026
1032
  setCommentMode(false);
1033
+ } else if (activeThreadId) {
1034
+ setActiveThreadId(null);
1027
1035
  } else if (commentMode) {
1028
1036
  setCommentMode(false);
1029
1037
  }
@@ -1045,11 +1053,8 @@ function CommentOverlay() {
1045
1053
  };
1046
1054
  document.addEventListener("keydown", handler);
1047
1055
  return () => document.removeEventListener("keydown", handler);
1048
- }, [commentMode, pendingPin, setCommentMode, setActiveThreadId]);
1049
- const sortedThreads = [...threads].sort((a, b) => {
1050
- if (a.resolved !== b.resolved) return a.resolved ? 1 : -1;
1051
- return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
1052
- });
1056
+ }, [commentMode, pendingPin, activeThreadId, setCommentMode, setActiveThreadId]);
1057
+ const visibleThreads = threads.filter((t) => !t.resolved).sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
1053
1058
  const showingUserPrompt = commentMode && !user;
1054
1059
  return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1055
1060
  /* @__PURE__ */ jsxs6(
@@ -1060,7 +1065,7 @@ function CommentOverlay() {
1060
1065
  style: { zIndex: commentMode ? getHighestZIndex() + 10 : 55 },
1061
1066
  onMouseDown: handleClick,
1062
1067
  children: [
1063
- sortedThreads.map((thread, i) => /* @__PURE__ */ jsxs6("div", { className: "pointer-events-auto", children: [
1068
+ visibleThreads.map((thread, i) => /* @__PURE__ */ jsxs6("div", { className: "pointer-events-auto", children: [
1064
1069
  /* @__PURE__ */ jsx7(CommentPin, { thread, index: i, overlayRef }),
1065
1070
  /* @__PURE__ */ jsx7(ApostilThreadPopover, { thread, overlayRef })
1066
1071
  ] }, thread.id)),