@designfever/web-review-kit 0.7.0 → 0.7.1
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/.env.sample +3 -0
- package/dist/{chunk-AB5B6O77.js → chunk-2ZLU5FTD.js} +22 -4
- package/dist/chunk-2ZLU5FTD.js.map +1 -0
- package/dist/index.cjs +21 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/react-shell.cjs +89 -26
- package/dist/react-shell.cjs.map +1 -1
- package/dist/react-shell.d.cts +2 -0
- package/dist/react-shell.d.ts +2 -0
- package/dist/react-shell.js +89 -26
- package/dist/react-shell.js.map +1 -1
- package/dist/vite.cjs +44 -16
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +46 -17
- package/dist/vite.js.map +1 -1
- package/docs/README.md +4 -2
- package/docs/adapters.md +4 -2
- package/docs/figma-image-mvp-0.7.0.md +15 -12
- package/docs/figma-overlay.md +11 -4
- package/docs/installation.md +3 -0
- package/docs/release-notes-0.7.0.md +6 -2
- package/docs/release-notes-0.7.1.md +34 -0
- package/package.json +1 -1
- package/dist/chunk-AB5B6O77.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -16,9 +16,11 @@ declare const REVIEW_WORKFLOW_STATUS_OPTIONS: Array<{
|
|
|
16
16
|
declare function normalizeReviewItemStatus(status: ReviewItemStatus | undefined): ReviewWorkflowStatus;
|
|
17
17
|
|
|
18
18
|
declare const DEFAULT_REVIEW_FIGMA_IMAGE_STORE_ENDPOINT = "/__dfwr/figma-images";
|
|
19
|
+
type ReviewFigmaImageTokenProvider = string | null | undefined | (() => string | null | undefined);
|
|
19
20
|
type ReviewFigmaImageStoreClientOptions = {
|
|
20
21
|
endpoint?: string;
|
|
21
22
|
fetch?: typeof fetch;
|
|
23
|
+
token?: ReviewFigmaImageTokenProvider;
|
|
22
24
|
clientRender?: boolean | ReviewFigmaImageClientRenderOptions;
|
|
23
25
|
};
|
|
24
26
|
type ReviewFigmaImageClientRenderOptions = {
|
package/dist/index.d.ts
CHANGED
|
@@ -16,9 +16,11 @@ declare const REVIEW_WORKFLOW_STATUS_OPTIONS: Array<{
|
|
|
16
16
|
declare function normalizeReviewItemStatus(status: ReviewItemStatus | undefined): ReviewWorkflowStatus;
|
|
17
17
|
|
|
18
18
|
declare const DEFAULT_REVIEW_FIGMA_IMAGE_STORE_ENDPOINT = "/__dfwr/figma-images";
|
|
19
|
+
type ReviewFigmaImageTokenProvider = string | null | undefined | (() => string | null | undefined);
|
|
19
20
|
type ReviewFigmaImageStoreClientOptions = {
|
|
20
21
|
endpoint?: string;
|
|
21
22
|
fetch?: typeof fetch;
|
|
23
|
+
token?: ReviewFigmaImageTokenProvider;
|
|
22
24
|
clientRender?: boolean | ReviewFigmaImageClientRenderOptions;
|
|
23
25
|
};
|
|
24
26
|
type ReviewFigmaImageClientRenderOptions = {
|
package/dist/index.js
CHANGED
package/dist/react-shell.cjs
CHANGED
|
@@ -5573,7 +5573,10 @@ var buildTargetSrc = (target) => {
|
|
|
5573
5573
|
return `${url.pathname}${url.search}${url.hash}`;
|
|
5574
5574
|
};
|
|
5575
5575
|
var getFrameRouteTarget = (targetWindow, reviewPathPrefix) => {
|
|
5576
|
-
return normalizeTarget(
|
|
5576
|
+
return normalizeTarget(
|
|
5577
|
+
`${targetWindow.location.pathname}${targetWindow.location.search}${targetWindow.location.hash}`,
|
|
5578
|
+
reviewPathPrefix
|
|
5579
|
+
);
|
|
5577
5580
|
};
|
|
5578
5581
|
var updateShellUrl = (target, size, source) => {
|
|
5579
5582
|
const url = new URL(window.location.href);
|
|
@@ -5748,7 +5751,7 @@ var ABOUT_SECTIONS = [
|
|
|
5748
5751
|
},
|
|
5749
5752
|
{
|
|
5750
5753
|
title: "Figma token",
|
|
5751
|
-
body: "
|
|
5754
|
+
body: "Project owners can set FIGMA_TOKEN on the server. Reviewers who cannot change env can add a browser-local Figma token in Settings; it is stored as figma-token and used only as an image-store fallback."
|
|
5752
5755
|
},
|
|
5753
5756
|
{
|
|
5754
5757
|
title: "User ID",
|
|
@@ -6048,12 +6051,13 @@ var writeStoredFigmaToken = (token) => {
|
|
|
6048
6051
|
return;
|
|
6049
6052
|
}
|
|
6050
6053
|
};
|
|
6051
|
-
var getStoredReviewUserId = () => {
|
|
6052
|
-
|
|
6054
|
+
var getStoredReviewUserId = (fallback = "") => {
|
|
6055
|
+
const normalizedFallback = fallback.trim();
|
|
6056
|
+
if (typeof window === "undefined") return normalizedFallback;
|
|
6053
6057
|
try {
|
|
6054
|
-
return window.localStorage.getItem(REVIEW_USER_ID_STORAGE_KEY)
|
|
6058
|
+
return window.localStorage.getItem(REVIEW_USER_ID_STORAGE_KEY)?.trim() || normalizedFallback;
|
|
6055
6059
|
} catch {
|
|
6056
|
-
return
|
|
6060
|
+
return normalizedFallback;
|
|
6057
6061
|
}
|
|
6058
6062
|
};
|
|
6059
6063
|
var writeStoredReviewUserId = (userId) => {
|
|
@@ -17547,15 +17551,18 @@ var useReviewFigmaImages = ({
|
|
|
17547
17551
|
// src/react-shell/hooks/use.review.settings.ts
|
|
17548
17552
|
var import_react20 = require("react");
|
|
17549
17553
|
var useReviewSettings = ({
|
|
17554
|
+
defaultReviewUserId = "",
|
|
17550
17555
|
onCancelReviewMode,
|
|
17551
17556
|
onCloseInitialPrompt,
|
|
17552
17557
|
onCloseSitemap,
|
|
17553
17558
|
onReloadTargetFrame
|
|
17554
17559
|
}) => {
|
|
17555
17560
|
const [figmaTokenDraft, setFigmaTokenDraft] = (0, import_react20.useState)(getStoredFigmaToken);
|
|
17556
|
-
const [reviewUserId, setReviewUserId] = (0, import_react20.useState)(
|
|
17561
|
+
const [reviewUserId, setReviewUserId] = (0, import_react20.useState)(
|
|
17562
|
+
() => getStoredReviewUserId(defaultReviewUserId)
|
|
17563
|
+
);
|
|
17557
17564
|
const [reviewUserIdDraft, setReviewUserIdDraft] = (0, import_react20.useState)(
|
|
17558
|
-
getStoredReviewUserId
|
|
17565
|
+
() => getStoredReviewUserId(defaultReviewUserId)
|
|
17559
17566
|
);
|
|
17560
17567
|
const [reviewTheme, setReviewTheme] = (0, import_react20.useState)(getStoredReviewTheme);
|
|
17561
17568
|
const [reviewThemeDraft, setReviewThemeDraft] = (0, import_react20.useState)(getStoredReviewTheme);
|
|
@@ -17576,7 +17583,7 @@ var useReviewSettings = ({
|
|
|
17576
17583
|
onCloseSitemap();
|
|
17577
17584
|
onCloseInitialPrompt();
|
|
17578
17585
|
setFigmaTokenDraft(getStoredFigmaToken());
|
|
17579
|
-
setReviewUserIdDraft(getStoredReviewUserId());
|
|
17586
|
+
setReviewUserIdDraft(getStoredReviewUserId(defaultReviewUserId));
|
|
17580
17587
|
setReviewThemeDraft(reviewTheme);
|
|
17581
17588
|
setFigmaSettingsStatus("");
|
|
17582
17589
|
setIsFigmaTokenVisible(false);
|
|
@@ -17586,6 +17593,7 @@ var useReviewSettings = ({
|
|
|
17586
17593
|
onCancelReviewMode,
|
|
17587
17594
|
onCloseInitialPrompt,
|
|
17588
17595
|
onCloseSitemap,
|
|
17596
|
+
defaultReviewUserId,
|
|
17589
17597
|
reviewTheme
|
|
17590
17598
|
]);
|
|
17591
17599
|
const saveReviewSettings = (0, import_react20.useCallback)(
|
|
@@ -17612,6 +17620,12 @@ var useReviewSettings = ({
|
|
|
17612
17620
|
},
|
|
17613
17621
|
[closeFigmaSettings, onReloadTargetFrame]
|
|
17614
17622
|
);
|
|
17623
|
+
(0, import_react20.useEffect)(() => {
|
|
17624
|
+
if (getStoredReviewUserId()) return;
|
|
17625
|
+
const nextDefaultUserId = defaultReviewUserId.trim();
|
|
17626
|
+
setReviewUserId(nextDefaultUserId);
|
|
17627
|
+
setReviewUserIdDraft(nextDefaultUserId);
|
|
17628
|
+
}, [defaultReviewUserId]);
|
|
17615
17629
|
(0, import_react20.useEffect)(() => {
|
|
17616
17630
|
if (typeof window === "undefined" || !window.matchMedia) return void 0;
|
|
17617
17631
|
const query = window.matchMedia("(prefers-color-scheme: light)");
|
|
@@ -18012,6 +18026,7 @@ function normalizeLegacyAdapterMap(adapters) {
|
|
|
18012
18026
|
statusOptions: [...REVIEW_WORKFLOW_STATUS_OPTIONS],
|
|
18013
18027
|
assigneeTitle: DEFAULT_ASSIGNEE_TITLE,
|
|
18014
18028
|
assigneeOptions: [],
|
|
18029
|
+
defaultUserId: adapters.defaultUserId?.trim() ?? "",
|
|
18015
18030
|
updateStatus: ({ id, status }) => adapters.local.update(id, { status }),
|
|
18016
18031
|
updateAssignee: ({ id, assigneeId, assigneeName }) => adapters.local.update(id, { assigneeId, assigneeName }),
|
|
18017
18032
|
syncSubmission: ({ id, patch }) => adapters.local.update(id, patch),
|
|
@@ -18026,6 +18041,7 @@ function normalizeLegacyAdapterMap(adapters) {
|
|
|
18026
18041
|
statusOptions: [...REVIEW_WORKFLOW_STATUS_OPTIONS],
|
|
18027
18042
|
assigneeTitle: DEFAULT_ASSIGNEE_TITLE,
|
|
18028
18043
|
assigneeOptions: [],
|
|
18044
|
+
defaultUserId: adapters.defaultUserId?.trim() ?? "",
|
|
18029
18045
|
updateStatus: ({ id, status }) => adapters.remote?.update(id, { status }) ?? Promise.reject(new Error("Remote adapter is not available.")),
|
|
18030
18046
|
updateAssignee: ({ id, assigneeId, assigneeName }) => adapters.remote?.update(id, { assigneeId, assigneeName }) ?? Promise.reject(new Error("Remote adapter is not available.")),
|
|
18031
18047
|
writeModes: [],
|
|
@@ -18048,6 +18064,7 @@ function normalizeShellAdapter(adapterConfig) {
|
|
|
18048
18064
|
};
|
|
18049
18065
|
const assigneeTitle = adapterConfig.assigneeTitle?.trim() || DEFAULT_ASSIGNEE_TITLE;
|
|
18050
18066
|
const assigneeOptions = [...adapterConfig.assigneeOptions ?? []];
|
|
18067
|
+
const defaultUserId = adapterConfig.defaultUserId?.trim() ?? "";
|
|
18051
18068
|
const updateAdapter = adapterConfig.update;
|
|
18052
18069
|
const updateStatus = adapterConfig.updateStatus ? adapterConfig.updateStatus : updateAdapter ? ({ id, status }) => updateAdapter(id, { status }) : void 0;
|
|
18053
18070
|
const updateAssignee = adapterConfig.updateAssignee ? adapterConfig.updateAssignee : updateAdapter ? ({ id, assigneeId, assigneeName, assigneeOption }) => updateAdapter(id, {
|
|
@@ -18064,6 +18081,7 @@ function normalizeShellAdapter(adapterConfig) {
|
|
|
18064
18081
|
statusOptions,
|
|
18065
18082
|
assigneeTitle,
|
|
18066
18083
|
assigneeOptions,
|
|
18084
|
+
defaultUserId,
|
|
18067
18085
|
updateStatus,
|
|
18068
18086
|
updateAssignee,
|
|
18069
18087
|
syncSubmission: adapterConfig.syncSubmission,
|
|
@@ -18620,8 +18638,10 @@ var ReviewShell = ({
|
|
|
18620
18638
|
});
|
|
18621
18639
|
const sourceShortcutCleanupRef = (0, import_react24.useRef)(null);
|
|
18622
18640
|
const sourceInspectorInteractionRef = (0, import_react24.useRef)(false);
|
|
18641
|
+
const sectionOutlineCountRef = (0, import_react24.useRef)(0);
|
|
18623
18642
|
const [sourceInspectorState, setSourceInspectorState] = (0, import_react24.useState)(null);
|
|
18624
18643
|
const [sectionOutline, setSectionOutline] = (0, import_react24.useState)(null);
|
|
18644
|
+
const [targetFrameLoadVersion, setTargetFrameLoadVersion] = (0, import_react24.useState)(0);
|
|
18625
18645
|
const [sectionOutlineFilter, setSectionOutlineFilter] = (0, import_react24.useState)(
|
|
18626
18646
|
() => getStoredSourceTreeFilter()
|
|
18627
18647
|
);
|
|
@@ -18723,6 +18743,9 @@ var ReviewShell = ({
|
|
|
18723
18743
|
[filteredSectionOutline]
|
|
18724
18744
|
);
|
|
18725
18745
|
const isSectionOutlineFiltering = sectionOutlineFilterTerms.length > 0;
|
|
18746
|
+
(0, import_react24.useEffect)(() => {
|
|
18747
|
+
sectionOutlineCountRef.current = sectionOutlineTotalCount;
|
|
18748
|
+
}, [sectionOutlineTotalCount]);
|
|
18726
18749
|
const {
|
|
18727
18750
|
activeItems,
|
|
18728
18751
|
activeRemainingItemCount,
|
|
@@ -18874,6 +18897,7 @@ var ReviewShell = ({
|
|
|
18874
18897
|
setReviewThemeDraft,
|
|
18875
18898
|
setReviewUserIdDraft
|
|
18876
18899
|
} = useReviewSettings({
|
|
18900
|
+
defaultReviewUserId: activeAdapterEntry.defaultUserId,
|
|
18877
18901
|
onCancelReviewMode: cancelReviewMode,
|
|
18878
18902
|
onCloseInitialPrompt: closePromptModal,
|
|
18879
18903
|
onCloseSitemap: closeSitemap,
|
|
@@ -19303,32 +19327,78 @@ var ReviewShell = ({
|
|
|
19303
19327
|
const setSectionOutlineWithDefaultCollapse = (0, import_react24.useCallback)(
|
|
19304
19328
|
(nextSectionOutline) => {
|
|
19305
19329
|
setSectionOutline(nextSectionOutline);
|
|
19330
|
+
sectionOutlineCountRef.current = getSectionOutlineEntryCount(nextSectionOutline);
|
|
19306
19331
|
setCollapsedSectionOutlineIds(
|
|
19307
19332
|
getDefaultCollapsedSectionOutlineIds(nextSectionOutline)
|
|
19308
19333
|
);
|
|
19309
19334
|
},
|
|
19310
19335
|
[]
|
|
19311
19336
|
);
|
|
19337
|
+
const refreshCurrentSectionOutline = (0, import_react24.useCallback)(
|
|
19338
|
+
(resetCollapse = false) => {
|
|
19339
|
+
const nextSectionOutline = getCurrentSectionOutline();
|
|
19340
|
+
if (!nextSectionOutline) return false;
|
|
19341
|
+
setSectionOutline(nextSectionOutline);
|
|
19342
|
+
const nextCount = getSectionOutlineEntryCount(nextSectionOutline);
|
|
19343
|
+
const shouldResetCollapse = resetCollapse || sectionOutlineCountRef.current === 0;
|
|
19344
|
+
sectionOutlineCountRef.current = nextCount;
|
|
19345
|
+
if (shouldResetCollapse) {
|
|
19346
|
+
setCollapsedSectionOutlineIds(
|
|
19347
|
+
getDefaultCollapsedSectionOutlineIds(nextSectionOutline)
|
|
19348
|
+
);
|
|
19349
|
+
}
|
|
19350
|
+
return true;
|
|
19351
|
+
},
|
|
19352
|
+
[getCurrentSectionOutline]
|
|
19353
|
+
);
|
|
19312
19354
|
(0, import_react24.useEffect)(() => {
|
|
19313
19355
|
if (sidePanel !== "source" || !isListVisible) return void 0;
|
|
19314
19356
|
const refreshSectionOutline = () => {
|
|
19315
|
-
|
|
19316
|
-
if (!nextSectionOutline) return;
|
|
19317
|
-
setSectionOutlineWithDefaultCollapse(nextSectionOutline);
|
|
19357
|
+
refreshCurrentSectionOutline(true);
|
|
19318
19358
|
};
|
|
19319
19359
|
const animationFrame = window.requestAnimationFrame(refreshSectionOutline);
|
|
19320
19360
|
const firstTimeout = window.setTimeout(refreshSectionOutline, 120);
|
|
19321
19361
|
const secondTimeout = window.setTimeout(refreshSectionOutline, 500);
|
|
19362
|
+
const thirdTimeout = window.setTimeout(refreshSectionOutline, 1200);
|
|
19322
19363
|
return () => {
|
|
19323
19364
|
window.cancelAnimationFrame(animationFrame);
|
|
19324
19365
|
window.clearTimeout(firstTimeout);
|
|
19325
19366
|
window.clearTimeout(secondTimeout);
|
|
19367
|
+
window.clearTimeout(thirdTimeout);
|
|
19326
19368
|
};
|
|
19327
19369
|
}, [
|
|
19328
|
-
getCurrentSectionOutline,
|
|
19329
19370
|
isListVisible,
|
|
19330
|
-
|
|
19371
|
+
refreshCurrentSectionOutline,
|
|
19331
19372
|
sidePanel,
|
|
19373
|
+
targetFrameLoadVersion,
|
|
19374
|
+
targetSrc
|
|
19375
|
+
]);
|
|
19376
|
+
(0, import_react24.useEffect)(() => {
|
|
19377
|
+
if (sidePanel !== "source" || !isListVisible) return void 0;
|
|
19378
|
+
const frameDocument = iframeRef.current?.contentDocument;
|
|
19379
|
+
const body = frameDocument?.body;
|
|
19380
|
+
if (!body) return void 0;
|
|
19381
|
+
let refreshTimeout = null;
|
|
19382
|
+
const scheduleRefresh = () => {
|
|
19383
|
+
if (refreshTimeout) window.clearTimeout(refreshTimeout);
|
|
19384
|
+
refreshTimeout = window.setTimeout(() => {
|
|
19385
|
+
refreshTimeout = null;
|
|
19386
|
+
refreshCurrentSectionOutline(false);
|
|
19387
|
+
}, 80);
|
|
19388
|
+
};
|
|
19389
|
+
const observer = new MutationObserver(scheduleRefresh);
|
|
19390
|
+
observer.observe(body, { childList: true, subtree: true });
|
|
19391
|
+
scheduleRefresh();
|
|
19392
|
+
return () => {
|
|
19393
|
+
if (refreshTimeout) window.clearTimeout(refreshTimeout);
|
|
19394
|
+
observer.disconnect();
|
|
19395
|
+
};
|
|
19396
|
+
}, [
|
|
19397
|
+
iframeRef,
|
|
19398
|
+
isListVisible,
|
|
19399
|
+
refreshCurrentSectionOutline,
|
|
19400
|
+
sidePanel,
|
|
19401
|
+
targetFrameLoadVersion,
|
|
19332
19402
|
targetSrc
|
|
19333
19403
|
]);
|
|
19334
19404
|
const toggleQaPanel = (0, import_react24.useCallback)(() => {
|
|
@@ -19342,16 +19412,12 @@ var ReviewShell = ({
|
|
|
19342
19412
|
return;
|
|
19343
19413
|
}
|
|
19344
19414
|
setSidePanel("source");
|
|
19345
|
-
|
|
19346
|
-
if (nextSectionOutline) {
|
|
19347
|
-
setSectionOutlineWithDefaultCollapse(nextSectionOutline);
|
|
19348
|
-
}
|
|
19415
|
+
refreshCurrentSectionOutline(true);
|
|
19349
19416
|
setIsListVisible(true);
|
|
19350
19417
|
}, [
|
|
19351
|
-
getCurrentSectionOutline,
|
|
19352
19418
|
isListVisible,
|
|
19353
19419
|
isSourceInspectorEnabled,
|
|
19354
|
-
|
|
19420
|
+
refreshCurrentSectionOutline,
|
|
19355
19421
|
setIsListVisible,
|
|
19356
19422
|
sidePanel
|
|
19357
19423
|
]);
|
|
@@ -19658,6 +19724,7 @@ var ReviewShell = ({
|
|
|
19658
19724
|
return cleanupSourceOpenShortcut;
|
|
19659
19725
|
}, [cleanupSourceOpenShortcut]);
|
|
19660
19726
|
const loadTargetFrame = (0, import_react24.useCallback)(() => {
|
|
19727
|
+
setTargetFrameLoadVersion((currentVersion) => currentVersion + 1);
|
|
19661
19728
|
initReviewKit();
|
|
19662
19729
|
refreshTargetFigmaConfig();
|
|
19663
19730
|
setTargetFigmaOverlayLocked(
|
|
@@ -19666,20 +19733,16 @@ var ReviewShell = ({
|
|
|
19666
19733
|
);
|
|
19667
19734
|
bindSourceOpenShortcut();
|
|
19668
19735
|
if (sidePanel === "source" && isListVisible) {
|
|
19669
|
-
|
|
19670
|
-
if (nextSectionOutline) {
|
|
19671
|
-
setSectionOutlineWithDefaultCollapse(nextSectionOutline);
|
|
19672
|
-
}
|
|
19736
|
+
refreshCurrentSectionOutline(true);
|
|
19673
19737
|
}
|
|
19674
19738
|
}, [
|
|
19675
19739
|
bindSourceOpenShortcut,
|
|
19676
|
-
getCurrentSectionOutline,
|
|
19677
19740
|
iframeRef,
|
|
19678
19741
|
initReviewKit,
|
|
19679
19742
|
isListVisible,
|
|
19680
19743
|
mode,
|
|
19681
19744
|
refreshTargetFigmaConfig,
|
|
19682
|
-
|
|
19745
|
+
refreshCurrentSectionOutline,
|
|
19683
19746
|
sidePanel
|
|
19684
19747
|
]);
|
|
19685
19748
|
(0, import_react24.useEffect)(() => {
|