reflet-sdk 0.6.0 → 0.6.2

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/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ All notable changes to `reflet-sdk` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.6.2] - 2026-10-04
9
+
10
+ ### Fixed
11
+
12
+ - The devtools Board tab no longer dead-ends when nothing points at the current page: switch between "This page" and "Whole board", or click "Show the whole board" from the empty state, so feedback filed on other routes or other tenants' URLs stays reachable.
13
+
14
+ ## [0.6.1] - 2026-10-04
15
+
16
+ ### Fixed
17
+
18
+ - Dragging the devtools bar follows the pointer directly instead of trailing behind it. The slide animation only plays when the docked bar makes room for the opening panel.
19
+
8
20
  ## [0.6.0] - 2026-09-30
9
21
 
10
22
  ### Security
package/README.md CHANGED
@@ -203,8 +203,9 @@ turn it off.
203
203
  - **Send to board** — notes become internal feedback: members see them with an
204
204
  "Internal" badge, the public board never does, and an admin can make one
205
205
  public from the dashboard.
206
- - **Board** — the board's feedback for the current route, with "Show on page",
207
- the reporter's source location, and a code search for the element's text.
206
+ - **Board** — the board's feedback for the current route, or the whole board,
207
+ with "Show on page", the reporter's source location, and a code search for
208
+ the element's text.
208
209
 
209
210
  Code view and the board go through one dev-only route that reads files from
210
211
  your repository and holds the board credential server-side.
@@ -1,5 +1,5 @@
1
1
  import { a as EDITORS, n as DEVTOOLS_REQUEST_HEADER, r as DEVTOOLS_ROUTE_BASE, t as DEVTOOLS_ENDPOINTS } from "./protocol-ClqTFzwR.js";
2
- import { A as TargetIcon, B as buildElementSelection, C as GripIcon, H as getFiberFromNode, I as DEFAULT_WIDGET_LABELS, J as releaseCapture, K as captureViewport, L as SDK_VERSION, R as collectPageContext, S as CloseIcon, U as resolveComponentStack, V as describeElement, W as shortenSourcePath, a as visibleViewport, c as deriveTitle, d as SelectionOutline, i as onViewportChange, k as Svg, m as listenToKeydown, n as isWidgetOwned, p as listenOnPageAndWidget, q as capturedFromCanvas, r as useFloatingPosition, t as ElementPicker, u as uploadImageBlob } from "./picker-C7TkZcBE.js";
2
+ import { A as TargetIcon, B as buildElementSelection, C as GripIcon, H as getFiberFromNode, I as DEFAULT_WIDGET_LABELS, J as releaseCapture, K as captureViewport, L as SDK_VERSION, R as collectPageContext, S as CloseIcon, U as resolveComponentStack, V as describeElement, W as shortenSourcePath, a as deriveTitle, c as useFloatingPosition, d as SelectionOutline, k as Svg, l as onViewportChange, m as listenToKeydown, n as isWidgetOwned, p as listenOnPageAndWidget, q as capturedFromCanvas, s as uploadImageBlob, t as ElementPicker, u as visibleViewport } from "./picker-DCoAFX5y.js";
3
3
  import { t as REFLET_Z_INDEX } from "./z-index-BL0SGZEP.js";
4
4
  import * as G$1 from "react";
5
5
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
@@ -79,12 +79,13 @@ function callReflet(apiPath, init = {}) {
79
79
  query: init.query
80
80
  });
81
81
  }
82
- async function fetchBoardFeedbackForPage(pagePath) {
83
- return (await callReflet("/api/v1/feedback/list", { query: {
82
+ function fetchBoardFeedback(pagePath) {
83
+ const query = {
84
84
  limit: String(INBOX_PAGE_SIZE),
85
- pagePath,
86
85
  sortBy: "newest"
87
- } })).items;
86
+ };
87
+ if (pagePath !== null) query.pagePath = pagePath;
88
+ return callReflet("/api/v1/feedback/list", { query });
88
89
  }
89
90
  //#endregion
90
91
  //#region src/devtools/client/copy-button.tsx
@@ -352,17 +353,26 @@ function FeedbackCard({ item, onOpenCode, onShowSelector }) {
352
353
  }
353
354
  //#endregion
354
355
  //#region src/devtools/client/inbox/inbox-panel.tsx
355
- function useBoardFeedbackForPage() {
356
+ const INBOX_SCOPES = ["page", "board"];
357
+ const SCOPE_LABELS = {
358
+ board: "Whole board",
359
+ page: "This page"
360
+ };
361
+ const EMPTY_SCOPE_MESSAGES = {
362
+ board: "The board has no feedback yet.",
363
+ page: "Nothing on the board points at this page yet."
364
+ };
365
+ function useBoardFeedback(scope) {
356
366
  const [state, setState] = useState({ kind: "loading" });
357
367
  const load = useCallback(async () => {
358
- const pagePath = window.location.pathname;
368
+ const pagePath = scope === "page" ? window.location.pathname : null;
359
369
  setState({ kind: "loading" });
360
370
  try {
361
- const items = await fetchBoardFeedbackForPage(pagePath);
371
+ const page = await fetchBoardFeedback(pagePath);
362
372
  setState({
363
- items,
364
373
  kind: "ready",
365
- pagePath
374
+ page,
375
+ place: pagePath ?? "the board"
366
376
  });
367
377
  } catch (error) {
368
378
  setState({
@@ -370,7 +380,7 @@ function useBoardFeedbackForPage() {
370
380
  message: error instanceof Error ? error.message : "Could not reach the board."
371
381
  });
372
382
  }
373
- }, []);
383
+ }, [scope]);
374
384
  useEffect(() => {
375
385
  load();
376
386
  }, [load]);
@@ -379,14 +389,14 @@ function useBoardFeedbackForPage() {
379
389
  state
380
390
  };
381
391
  }
382
- function InboxPanel({ onOpenCode, onShowSelector }) {
383
- const { load, state } = useBoardFeedbackForPage();
392
+ function BoardFeedbackList({ onOpenCode, onShowSelector, onShowWholeBoard, scope }) {
393
+ const { load, state } = useBoardFeedback(scope);
384
394
  return /* @__PURE__ */ jsxs(Fragment, { children: [
385
395
  /* @__PURE__ */ jsxs("div", {
386
396
  className: "dt-card-head",
387
397
  children: [/* @__PURE__ */ jsx("p", {
388
398
  className: "dt-status",
389
- children: state.kind === "ready" ? `${state.items.length} on ${state.pagePath}` : "Board feedback on this page"
399
+ children: state.kind === "ready" ? `${state.page.total} on ${state.place}` : "Board feedback"
390
400
  }), /* @__PURE__ */ jsx("button", {
391
401
  className: "dt-btn",
392
402
  disabled: state.kind === "loading",
@@ -403,17 +413,40 @@ function InboxPanel({ onOpenCode, onShowSelector }) {
403
413
  className: "dt-error",
404
414
  children: state.message
405
415
  }),
406
- state.kind === "ready" && state.items.length === 0 && /* @__PURE__ */ jsx("div", {
416
+ state.kind === "ready" && state.page.items.length === 0 && /* @__PURE__ */ jsxs("div", {
407
417
  className: "dt-empty",
408
- children: /* @__PURE__ */ jsx("p", { children: "Nothing on the board points at this page yet." })
418
+ children: [/* @__PURE__ */ jsx("p", { children: EMPTY_SCOPE_MESSAGES[scope] }), scope === "page" && /* @__PURE__ */ jsx("button", {
419
+ className: "dt-btn",
420
+ onClick: onShowWholeBoard,
421
+ type: "button",
422
+ children: "Show the whole board"
423
+ })]
409
424
  }),
410
- state.kind === "ready" && state.items.map((item) => /* @__PURE__ */ jsx(FeedbackCard, {
425
+ state.kind === "ready" && state.page.items.map((item) => /* @__PURE__ */ jsx(FeedbackCard, {
411
426
  item,
412
427
  onOpenCode,
413
428
  onShowSelector
414
429
  }, item.id))
415
430
  ] });
416
431
  }
432
+ function InboxPanel({ onOpenCode, onShowSelector }) {
433
+ const [scope, setScope] = useState("page");
434
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
435
+ className: "dt-tabs",
436
+ children: INBOX_SCOPES.map((option) => /* @__PURE__ */ jsx("button", {
437
+ "aria-pressed": option === scope,
438
+ className: "dt-tab",
439
+ onClick: () => setScope(option),
440
+ type: "button",
441
+ children: SCOPE_LABELS[option]
442
+ }, option))
443
+ }), /* @__PURE__ */ jsx(BoardFeedbackList, {
444
+ onOpenCode,
445
+ onShowSelector,
446
+ onShowWholeBoard: () => setScope("board"),
447
+ scope
448
+ }, scope)] });
449
+ }
417
450
  //#endregion
418
451
  //#region src/devtools/client/notices.tsx
419
452
  let notices = [];
@@ -776,7 +809,7 @@ function DevtoolsBar({ edge, noteCount, onPick, onToggleSheet, openTab, side })
776
809
  })]
777
810
  }),
778
811
  /* @__PURE__ */ jsx(BarButton, {
779
- label: "Board feedback on this page",
812
+ label: "Board feedback",
780
813
  onClick: () => onToggleSheet("inbox"),
781
814
  pressed: openTab === "inbox",
782
815
  children: /* @__PURE__ */ jsx(InboxIcon, {})
@@ -1050,8 +1083,8 @@ const DEVTOOLS_STYLES = `
1050
1083
  position: fixed; z-index: ${REFLET_Z_INDEX.devtoolsBar};
1051
1084
  display: flex; align-items: center; gap: 2px; padding: 3px;
1052
1085
  border-radius: var(--rf-pill);
1053
- transition: left 260ms var(--rf-ease), right 260ms var(--rf-ease);
1054
1086
  }
1087
+ .dt-bar[data-moved="false"] { transition: left 260ms var(--rf-ease), right 260ms var(--rf-ease); }
1055
1088
  .dt-bar[data-side="left"] { left: calc(var(--rf-viewport-left, 0px) + max(12px, var(--rf-offset))); }
1056
1089
  .dt-bar[data-side="right"] { right: calc(var(--rf-viewport-right, 0px) + max(12px, var(--rf-offset))); }
1057
1090
  .dt-bar[data-edge="bottom"] { bottom: calc(var(--rf-viewport-bottom, 0px) + env(safe-area-inset-bottom) + var(--dt-edge-gap)); }
@@ -1105,7 +1138,7 @@ const DEVTOOLS_STYLES = `
1105
1138
  .dt-tabs { display: flex; gap: 2px; margin-right: auto; }
1106
1139
  .dt-tab { height: 30px; padding: 0 11px; border-radius: var(--rf-pill); color: var(--rf-text-muted); font-weight: 500; }
1107
1140
  .dt-tab:hover { color: var(--rf-text); }
1108
- .dt-tab[aria-selected="true"] { background: var(--rf-bg-hover); color: var(--rf-text); }
1141
+ .dt-tab[aria-selected="true"], .dt-tab[aria-pressed="true"] { background: var(--rf-bg-hover); color: var(--rf-text); }
1109
1142
  .dt-sheet-body { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 8px; padding: 10px; }
1110
1143
  .dt-sheet-foot {
1111
1144
  position: sticky; bottom: -10px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
@@ -4094,4 +4127,4 @@ function DevtoolsLayer({ isWidgetOpen, position, publicKey }) {
4094
4127
  //#endregion
4095
4128
  export { DevtoolsLayer };
4096
4129
 
4097
- //# sourceMappingURL=devtools-layer-D_0UL_Wd.js.map
4130
+ //# sourceMappingURL=devtools-layer-DOECMj0S.js.map