@proveanything/smartlinks-utils-ui 0.12.14 → 0.12.16

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.
@@ -1908,8 +1908,10 @@ interface Props$9 {
1908
1908
  children: ReactNode;
1909
1909
  /** Which edge of the anchor the pill should hug. Defaults to `right`. */
1910
1910
  side?: 'left' | 'right';
1911
+ /** Which vertical position of the anchor the pill should hug. Defaults to `center`. */
1912
+ vAlign?: 'top' | 'center' | 'bottom';
1911
1913
  }
1912
- declare function PreviewReopenPill({ anchorRef, onClick, ariaLabel, title, children, side, }: Props$9): React$1.ReactPortal | null;
1914
+ declare function PreviewReopenPill({ anchorRef, onClick, ariaLabel, title, children, side, vAlign, }: Props$9): React$1.ReactPortal | null;
1913
1915
 
1914
1916
  declare const ScopeBreadcrumb: ({ scope }: {
1915
1917
  scope: ParsedRef;
@@ -179,6 +179,19 @@ function patchRecordStatusInCaches(queryClient, ctx, recordId, status) {
179
179
  });
180
180
  }
181
181
  }
182
+ function markScopeCountsStale(queryClient, ctx) {
183
+ const all = queryClient.getQueriesData({
184
+ queryKey: SCOPE_COUNTS_QK
185
+ });
186
+ for (const [key, cache] of all) {
187
+ if (!cache || !Array.isArray(cache.records)) continue;
188
+ if (!matchesScopeCountsCtx(key, ctx)) continue;
189
+ queryClient.invalidateQueries({
190
+ queryKey: key,
191
+ refetchType: "none"
192
+ });
193
+ }
194
+ }
182
195
  function removeRecordFromCaches(queryClient, ctx, recordId) {
183
196
  if (!recordId) return;
184
197
  const all = [
@@ -8818,15 +8831,18 @@ function PreviewReopenPill({
8818
8831
  ariaLabel,
8819
8832
  title,
8820
8833
  children,
8821
- side = "right"
8834
+ side = "right",
8835
+ vAlign = "center"
8822
8836
  }) {
8823
8837
  const [pos, setPos] = useState(null);
8824
8838
  const rafRef = useRef(null);
8825
8839
  useLayoutEffect(() => {
8826
8840
  const el = anchorRef.current;
8827
8841
  if (typeof window === "undefined") return;
8842
+ const TOP_INSET = 14;
8843
+ const fallbackTop = () => vAlign === "top" ? TOP_INSET : vAlign === "bottom" ? Math.max(0, window.innerHeight - TOP_INSET) : window.innerHeight / 2;
8828
8844
  if (!el) {
8829
- setPos({ top: window.innerHeight / 2, right: 8, left: 8 });
8845
+ setPos({ top: fallbackTop(), right: 8, left: 8 });
8830
8846
  return;
8831
8847
  }
8832
8848
  const measure = () => {
@@ -8834,11 +8850,11 @@ function PreviewReopenPill({
8834
8850
  rafRef.current = requestAnimationFrame(() => {
8835
8851
  const rect = el.getBoundingClientRect();
8836
8852
  if (rect.width === 0 && rect.height === 0) {
8837
- setPos({ top: window.innerHeight / 2, right: 8, left: 8 });
8838
8853
  return;
8839
8854
  }
8855
+ const top = vAlign === "top" ? rect.top + TOP_INSET : vAlign === "bottom" ? rect.bottom - TOP_INSET : rect.top + rect.height / 2;
8840
8856
  setPos({
8841
- top: rect.top + rect.height / 2,
8857
+ top,
8842
8858
  right: Math.max(0, window.innerWidth - rect.right),
8843
8859
  left: Math.max(0, rect.left)
8844
8860
  });
@@ -8856,13 +8872,14 @@ function PreviewReopenPill({
8856
8872
  window.removeEventListener("scroll", measure, true);
8857
8873
  if (rafRef.current != null) cancelAnimationFrame(rafRef.current);
8858
8874
  };
8859
- }, [anchorRef]);
8875
+ }, [anchorRef, vAlign]);
8860
8876
  if (typeof document === "undefined") return null;
8861
8877
  const effectivePos = pos ?? {
8862
- top: typeof window !== "undefined" ? window.innerHeight / 2 : 200,
8878
+ top: typeof window !== "undefined" ? vAlign === "top" ? 14 : vAlign === "bottom" ? window.innerHeight - 14 : window.innerHeight / 2 : 200,
8863
8879
  right: 8,
8864
8880
  left: 8
8865
8881
  };
8882
+ const translateY = vAlign === "center" ? "-50%" : "0";
8866
8883
  return createPortal(
8867
8884
  /* @__PURE__ */ jsx(
8868
8885
  "button",
@@ -8878,7 +8895,7 @@ function PreviewReopenPill({
8878
8895
  ...side === "right" ? { right: effectivePos.right } : { left: effectivePos.left },
8879
8896
  // Pull half the pill width out into the gutter so it visually
8880
8897
  // anchors *to* the editor edge rather than sitting inside it.
8881
- transform: side === "right" ? "translate(50%, -50%)" : "translate(-50%, -50%)"
8898
+ transform: side === "right" ? `translate(50%, ${translateY})` : `translate(-50%, ${translateY})`
8882
8899
  },
8883
8900
  children
8884
8901
  }
@@ -9361,9 +9378,7 @@ function RecordsAdminShellInner(props) {
9361
9378
  } else {
9362
9379
  removeRecordFromCaches(queryClient, notice.ctx, notice.recordId);
9363
9380
  }
9364
- queryClient.invalidateQueries({
9365
- queryKey: scopeCountsQueryKey(notice.ctx.collectionId, notice.ctx.appId, notice.ctx.recordType)
9366
- });
9381
+ markScopeCountsStale(queryClient, notice.ctx);
9367
9382
  };
9368
9383
  return () => {
9369
9384
  recordChangeRef.current = null;
@@ -10068,9 +10083,7 @@ function RecordsAdminShellInner(props) {
10068
10083
  try {
10069
10084
  const updated = await SL.app.records.update(collectionId, appId, record.id, { status: next }, true);
10070
10085
  patchRecordStatusInCaches(queryClient, ctx, record.id, next);
10071
- queryClient.invalidateQueries({
10072
- queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
10073
- });
10086
+ markScopeCountsStale(queryClient, ctx);
10074
10087
  if (updated) {
10075
10088
  patchRecordIntoCaches(queryClient, ctx, updated);
10076
10089
  }
@@ -10189,9 +10202,7 @@ function RecordsAdminShellInner(props) {
10189
10202
  i18n,
10190
10203
  onChanged: (_next, updated) => {
10191
10204
  patchRecordStatusInCaches(queryClient, ctx, selectedSummary.id, _next);
10192
- queryClient.invalidateQueries({
10193
- queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
10194
- });
10205
+ markScopeCountsStale(queryClient, ctx);
10195
10206
  if (updated) {
10196
10207
  patchRecordIntoCaches(queryClient, ctx, updated);
10197
10208
  }
@@ -10219,9 +10230,7 @@ function RecordsAdminShellInner(props) {
10219
10230
  }),
10220
10231
  onChanged: (_next, updated) => {
10221
10232
  patchRecordStatusInCaches(queryClient, ctx, selectedSummary.id, _next);
10222
- queryClient.invalidateQueries({
10223
- queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
10224
- });
10233
+ markScopeCountsStale(queryClient, ctx);
10225
10234
  if (updated) {
10226
10235
  patchRecordIntoCaches(queryClient, ctx, updated);
10227
10236
  }
@@ -11294,9 +11303,7 @@ function RecordsAdminShellInner(props) {
11294
11303
  try {
11295
11304
  const updated = await SL.app.records.update(collectionId, appId, id, { status: archivedStatusValue }, true);
11296
11305
  patchRecordStatusInCaches(queryClient, ctx, id, archivedStatusValue);
11297
- queryClient.invalidateQueries({
11298
- queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
11299
- });
11306
+ markScopeCountsStale(queryClient, ctx);
11300
11307
  if (updated) patchRecordIntoCaches(queryClient, ctx, updated);
11301
11308
  onTelemetry?.({
11302
11309
  type: "recordAction.invoke",
@@ -11308,9 +11315,7 @@ function RecordsAdminShellInner(props) {
11308
11315
  console.warn("[RecordsAdminShell] archive-duplicate failed", id, err);
11309
11316
  }
11310
11317
  }
11311
- queryClient.invalidateQueries({
11312
- queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
11313
- });
11318
+ markScopeCountsStale(queryClient, ctx);
11314
11319
  } : void 0,
11315
11320
  onDeleteDuplicates: enableDeleteDuplicates ? async () => {
11316
11321
  const ids = singletonConflicts.flatMap((c) => c.duplicates.map((d) => d.id)).filter((id) => !!id);
@@ -11328,9 +11333,7 @@ function RecordsAdminShellInner(props) {
11328
11333
  console.warn("[RecordsAdminShell] delete-duplicate failed", id, err);
11329
11334
  }
11330
11335
  }
11331
- queryClient.invalidateQueries({
11332
- queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
11333
- });
11336
+ markScopeCountsStale(queryClient, ctx);
11334
11337
  } : void 0,
11335
11338
  i18n: {
11336
11339
  title: i18n.conflictBannerTitle,
@@ -11416,6 +11419,7 @@ function RecordsAdminShellInner(props) {
11416
11419
  {
11417
11420
  anchorRef: railReopenAnchorRef,
11418
11421
  side: "left",
11422
+ vAlign: "top",
11419
11423
  onClick: () => setRailOpen(true),
11420
11424
  ariaLabel: i18n.openList,
11421
11425
  title: i18n.openList,