@designfever/web-review-kit 0.8.2 → 0.8.3
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/README.md +3 -3
- package/dist/{chunk-ZWJNUOYV.js → chunk-FWN7RQCW.js} +41 -58
- package/dist/chunk-FWN7RQCW.js.map +1 -0
- package/dist/index.cjs +39 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -6
- package/dist/index.js.map +1 -1
- package/dist/react-shell.cjs +756 -796
- package/dist/react-shell.cjs.map +1 -1
- package/dist/react-shell.js +738 -756
- package/dist/react-shell.js.map +1 -1
- package/docs/README.md +3 -2
- package/docs/architecture.md +33 -7
- package/docs/figma-overlay.md +24 -0
- package/docs/release-notes-0.8.3.md +48 -0
- package/docs/testing.md +12 -4
- package/package.json +1 -1
- package/dist/chunk-ZWJNUOYV.js.map +0 -1
package/dist/react-shell.cjs
CHANGED
|
@@ -492,6 +492,11 @@ var reviewShellSitemapStyle = `
|
|
|
492
492
|
padding: 18px;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
+
/* \uB2EB\uC544\uB3C4 unmount \uD558\uC9C0 \uC54A\uACE0 \uC228\uAE34\uB2E4. visibility \uB294 \uB9AC\uC2A4\uD2B8 \uC2A4\uD06C\uB864 \uC704\uCE58\uB97C \uBCF4\uC874\uD55C\uB2E4. */
|
|
496
|
+
.df-review-sitemap-modal.is-hidden {
|
|
497
|
+
visibility: hidden;
|
|
498
|
+
}
|
|
499
|
+
|
|
495
500
|
.df-review-sitemap-backdrop {
|
|
496
501
|
position: absolute;
|
|
497
502
|
inset: 0;
|
|
@@ -544,7 +549,7 @@ var reviewShellSitemapStyle = `
|
|
|
544
549
|
font-weight: var(--df-review-font-weight-normal);
|
|
545
550
|
}
|
|
546
551
|
|
|
547
|
-
.df-review-sitemap-header button {
|
|
552
|
+
.df-review-sitemap-header > button {
|
|
548
553
|
display: grid;
|
|
549
554
|
place-items: center;
|
|
550
555
|
width: 34px;
|
|
@@ -558,11 +563,36 @@ var reviewShellSitemapStyle = `
|
|
|
558
563
|
font-weight: var(--df-review-font-weight-normal);
|
|
559
564
|
}
|
|
560
565
|
|
|
561
|
-
.df-review-sitemap-header button:hover {
|
|
566
|
+
.df-review-sitemap-header > button:hover {
|
|
562
567
|
border-color: var(--df-review-accent);
|
|
563
568
|
background: var(--df-review-control-hover);
|
|
564
569
|
}
|
|
565
570
|
|
|
571
|
+
/* \uD5E4\uB354 \uC694\uC57D \uCE74\uC6B4\uD2B8\uB97C \uADF8\uB300\uB85C status filter \uD1A0\uAE00\uB85C \uC4F4\uB2E4. */
|
|
572
|
+
.df-review-sitemap-summary-filter {
|
|
573
|
+
display: inline;
|
|
574
|
+
border: 0;
|
|
575
|
+
padding: 0;
|
|
576
|
+
background: none;
|
|
577
|
+
color: var(--df-review-muted);
|
|
578
|
+
font: inherit;
|
|
579
|
+
cursor: pointer;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.df-review-sitemap-summary-filter:hover,
|
|
583
|
+
.df-review-sitemap-summary-filter:focus-visible {
|
|
584
|
+
color: var(--df-review-text);
|
|
585
|
+
text-decoration: underline;
|
|
586
|
+
text-underline-offset: 3px;
|
|
587
|
+
outline: none;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.df-review-sitemap-summary-filter.is-active {
|
|
591
|
+
color: var(--df-review-accent);
|
|
592
|
+
text-decoration: underline;
|
|
593
|
+
text-underline-offset: 3px;
|
|
594
|
+
}
|
|
595
|
+
|
|
566
596
|
.df-review-sitemap-controls {
|
|
567
597
|
display: flex;
|
|
568
598
|
align-items: center;
|
|
@@ -2341,6 +2371,8 @@ var reviewShellQaPanelStyle = `
|
|
|
2341
2371
|
|
|
2342
2372
|
.df-review-qa-draft-host[data-has-draft-composer="true"] {
|
|
2343
2373
|
display: block;
|
|
2374
|
+
/* Source Tree \uD328\uB110(z 900) \uC704\uB85C \uC62C\uB824 draft composer \uAC00 \uAC00\uB824\uC9C0\uC9C0 \uC54A\uAC8C \uD55C\uB2E4. */
|
|
2375
|
+
z-index: 950;
|
|
2344
2376
|
}
|
|
2345
2377
|
|
|
2346
2378
|
.df-review-shell:not(.is-list-visible) .df-review-qa-panel,
|
|
@@ -6210,11 +6242,140 @@ function getReviewFigmaImageErrorMessage(error) {
|
|
|
6210
6242
|
return error instanceof Error ? error.message : "Figma image request failed.";
|
|
6211
6243
|
}
|
|
6212
6244
|
|
|
6213
|
-
// src/react-shell/figma/image.overlay.
|
|
6245
|
+
// src/react-shell/figma/image.overlay.state.ts
|
|
6246
|
+
var STORAGE_KEY_PREFIX = "df-review-figma-image-overlay-state:";
|
|
6247
|
+
var STORAGE_VERSION = 2;
|
|
6248
|
+
var DEFAULT_MODE = "normal";
|
|
6214
6249
|
var DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY = 0.48;
|
|
6215
|
-
var
|
|
6216
|
-
|
|
6217
|
-
|
|
6250
|
+
var DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE = {
|
|
6251
|
+
selectedImageId: null,
|
|
6252
|
+
imageStates: {},
|
|
6253
|
+
lastVisibleImageIds: []
|
|
6254
|
+
};
|
|
6255
|
+
var DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_ITEM_STATE = {
|
|
6256
|
+
isVisible: false,
|
|
6257
|
+
opacity: DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY,
|
|
6258
|
+
isLocked: false,
|
|
6259
|
+
mode: DEFAULT_MODE,
|
|
6260
|
+
offsetY: 0
|
|
6261
|
+
};
|
|
6262
|
+
function createReviewFigmaImageOverlayStorageKey(target) {
|
|
6263
|
+
return `${STORAGE_KEY_PREFIX}${createReviewFigmaImageTargetKey(target)}`;
|
|
6264
|
+
}
|
|
6265
|
+
function readStoredReviewFigmaImageOverlayState(storageKey) {
|
|
6266
|
+
if (typeof window === "undefined") {
|
|
6267
|
+
return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE;
|
|
6268
|
+
}
|
|
6269
|
+
try {
|
|
6270
|
+
const value = window.localStorage.getItem(storageKey);
|
|
6271
|
+
if (!value) return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE;
|
|
6272
|
+
return normalizeReviewFigmaImageOverlayState(JSON.parse(value));
|
|
6273
|
+
} catch {
|
|
6274
|
+
return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE;
|
|
6275
|
+
}
|
|
6276
|
+
}
|
|
6277
|
+
function writeStoredReviewFigmaImageOverlayState(storageKey, state) {
|
|
6278
|
+
if (typeof window === "undefined") return;
|
|
6279
|
+
try {
|
|
6280
|
+
if (isDefaultReviewFigmaImageOverlayState(state)) {
|
|
6281
|
+
window.localStorage.removeItem(storageKey);
|
|
6282
|
+
return;
|
|
6283
|
+
}
|
|
6284
|
+
window.localStorage.setItem(
|
|
6285
|
+
storageKey,
|
|
6286
|
+
JSON.stringify({
|
|
6287
|
+
version: STORAGE_VERSION,
|
|
6288
|
+
...state
|
|
6289
|
+
})
|
|
6290
|
+
);
|
|
6291
|
+
} catch {
|
|
6292
|
+
return;
|
|
6293
|
+
}
|
|
6294
|
+
}
|
|
6295
|
+
function normalizeReviewFigmaImageOverlayMode(value) {
|
|
6296
|
+
return value === "invert" ? "invert" : DEFAULT_MODE;
|
|
6297
|
+
}
|
|
6298
|
+
function normalizeReviewFigmaImageOverlayOffsetY(value) {
|
|
6299
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return 0;
|
|
6300
|
+
return Math.round(value);
|
|
6301
|
+
}
|
|
6302
|
+
function clampReviewFigmaImageOverlayOpacity(value) {
|
|
6303
|
+
if (!Number.isFinite(value)) return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY;
|
|
6304
|
+
return Math.min(1, Math.max(0, value));
|
|
6305
|
+
}
|
|
6306
|
+
function getReviewFigmaImageOverlayItemState(state, imageId) {
|
|
6307
|
+
return imageId ? state.imageStates[imageId] ?? DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_ITEM_STATE : DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_ITEM_STATE;
|
|
6308
|
+
}
|
|
6309
|
+
function updateSelectedReviewFigmaImageOverlayItemState(state, updater) {
|
|
6310
|
+
return state.selectedImageId ? updateReviewFigmaImageOverlayItemState(
|
|
6311
|
+
state.imageStates,
|
|
6312
|
+
state.selectedImageId,
|
|
6313
|
+
updater
|
|
6314
|
+
) : state.imageStates;
|
|
6315
|
+
}
|
|
6316
|
+
function updateReviewFigmaImageOverlayItemState(imageStates, imageId, updater) {
|
|
6317
|
+
return {
|
|
6318
|
+
...imageStates,
|
|
6319
|
+
[imageId]: updater(
|
|
6320
|
+
imageStates[imageId] ?? DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_ITEM_STATE
|
|
6321
|
+
)
|
|
6322
|
+
};
|
|
6323
|
+
}
|
|
6324
|
+
function normalizeReviewFigmaImageOverlayState(value) {
|
|
6325
|
+
if (!value || typeof value !== "object") {
|
|
6326
|
+
return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE;
|
|
6327
|
+
}
|
|
6328
|
+
const state = value;
|
|
6329
|
+
const selectedImageId = typeof state.selectedImageId === "string" ? state.selectedImageId : null;
|
|
6330
|
+
const lastVisibleImageIds = Array.isArray(state.lastVisibleImageIds) ? state.lastVisibleImageIds.filter(
|
|
6331
|
+
(imageId) => typeof imageId === "string"
|
|
6332
|
+
) : [];
|
|
6333
|
+
const imageStates = normalizeReviewFigmaImageOverlayItemStateRecord(
|
|
6334
|
+
state.imageStates
|
|
6335
|
+
);
|
|
6336
|
+
if (Object.keys(imageStates).length === 0 && selectedImageId) {
|
|
6337
|
+
imageStates[selectedImageId] = normalizeReviewFigmaImageOverlayItemState(
|
|
6338
|
+
state
|
|
6339
|
+
);
|
|
6340
|
+
}
|
|
6341
|
+
return {
|
|
6342
|
+
selectedImageId,
|
|
6343
|
+
imageStates,
|
|
6344
|
+
lastVisibleImageIds
|
|
6345
|
+
};
|
|
6346
|
+
}
|
|
6347
|
+
function normalizeReviewFigmaImageOverlayItemStateRecord(value) {
|
|
6348
|
+
if (!value || typeof value !== "object") return {};
|
|
6349
|
+
return Object.fromEntries(
|
|
6350
|
+
Object.entries(value).flatMap(([imageId, itemState]) => {
|
|
6351
|
+
if (!imageId || typeof itemState !== "object") return [];
|
|
6352
|
+
return [
|
|
6353
|
+
[
|
|
6354
|
+
imageId,
|
|
6355
|
+
normalizeReviewFigmaImageOverlayItemState(
|
|
6356
|
+
itemState
|
|
6357
|
+
)
|
|
6358
|
+
]
|
|
6359
|
+
];
|
|
6360
|
+
})
|
|
6361
|
+
);
|
|
6362
|
+
}
|
|
6363
|
+
function normalizeReviewFigmaImageOverlayItemState(value) {
|
|
6364
|
+
return {
|
|
6365
|
+
isVisible: value.isVisible === true,
|
|
6366
|
+
opacity: clampReviewFigmaImageOverlayOpacity(
|
|
6367
|
+
typeof value.opacity === "number" ? value.opacity : DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY
|
|
6368
|
+
),
|
|
6369
|
+
isLocked: value.isLocked === true,
|
|
6370
|
+
mode: normalizeReviewFigmaImageOverlayMode(value.mode),
|
|
6371
|
+
offsetY: normalizeReviewFigmaImageOverlayOffsetY(value.offsetY)
|
|
6372
|
+
};
|
|
6373
|
+
}
|
|
6374
|
+
function isDefaultReviewFigmaImageOverlayState(state) {
|
|
6375
|
+
return state.selectedImageId === null && Object.keys(state.imageStates).length === 0 && state.lastVisibleImageIds.length === 0;
|
|
6376
|
+
}
|
|
6377
|
+
|
|
6378
|
+
// src/react-shell/figma/image.overlay.controller.ts
|
|
6218
6379
|
var useReviewFigmaImageOverlayController = ({
|
|
6219
6380
|
images,
|
|
6220
6381
|
isLoading,
|
|
@@ -6233,8 +6394,12 @@ var useReviewFigmaImageOverlayController = ({
|
|
|
6233
6394
|
(updater) => {
|
|
6234
6395
|
setStateContainer((currentContainer) => {
|
|
6235
6396
|
const currentState = currentContainer.storageKey === storageKey ? currentContainer.state : readStoredReviewFigmaImageOverlayState(storageKey);
|
|
6397
|
+
const nextState = updater(currentState);
|
|
6398
|
+
if (currentContainer.storageKey === storageKey && nextState === currentState) {
|
|
6399
|
+
return currentContainer;
|
|
6400
|
+
}
|
|
6236
6401
|
return {
|
|
6237
|
-
state:
|
|
6402
|
+
state: nextState,
|
|
6238
6403
|
storageKey
|
|
6239
6404
|
};
|
|
6240
6405
|
});
|
|
@@ -6274,7 +6439,7 @@ var useReviewFigmaImageOverlayController = ({
|
|
|
6274
6439
|
const lastVisibleImageIds = currentState.lastVisibleImageIds.filter(
|
|
6275
6440
|
(imageId) => nextImageIds.has(imageId)
|
|
6276
6441
|
);
|
|
6277
|
-
if (selectedImageId === currentState.selectedImageId && imageStates === currentState.imageStates && lastVisibleImageIds.length === currentState.lastVisibleImageIds.length) {
|
|
6442
|
+
if (selectedImageId === currentState.selectedImageId && Object.keys(imageStates).length === Object.keys(currentState.imageStates).length && lastVisibleImageIds.length === currentState.lastVisibleImageIds.length) {
|
|
6278
6443
|
return currentState;
|
|
6279
6444
|
}
|
|
6280
6445
|
return {
|
|
@@ -6471,78 +6636,54 @@ var useReviewFigmaImageOverlayController = ({
|
|
|
6471
6636
|
};
|
|
6472
6637
|
});
|
|
6473
6638
|
}, [images, updateState]);
|
|
6639
|
+
const updateSelectedOverlayState = (0, import_react7.useCallback)(
|
|
6640
|
+
(updater) => {
|
|
6641
|
+
updateState((currentState) => ({
|
|
6642
|
+
...currentState,
|
|
6643
|
+
imageStates: updateSelectedReviewFigmaImageOverlayItemState(
|
|
6644
|
+
currentState,
|
|
6645
|
+
updater
|
|
6646
|
+
)
|
|
6647
|
+
}));
|
|
6648
|
+
},
|
|
6649
|
+
[updateState]
|
|
6650
|
+
);
|
|
6474
6651
|
const setOverlayOpacity = (0, import_react7.useCallback)((opacity) => {
|
|
6475
|
-
|
|
6476
|
-
...
|
|
6477
|
-
|
|
6478
|
-
currentState,
|
|
6479
|
-
(itemState) => ({
|
|
6480
|
-
...itemState,
|
|
6481
|
-
opacity: clampReviewFigmaImageOverlayOpacity(opacity)
|
|
6482
|
-
})
|
|
6483
|
-
)
|
|
6652
|
+
updateSelectedOverlayState((itemState) => ({
|
|
6653
|
+
...itemState,
|
|
6654
|
+
opacity: clampReviewFigmaImageOverlayOpacity(opacity)
|
|
6484
6655
|
}));
|
|
6485
|
-
}, [
|
|
6656
|
+
}, [updateSelectedOverlayState]);
|
|
6486
6657
|
const setOverlayLocked = (0, import_react7.useCallback)((isLocked) => {
|
|
6487
|
-
|
|
6488
|
-
...
|
|
6489
|
-
|
|
6490
|
-
currentState,
|
|
6491
|
-
(itemState) => ({
|
|
6492
|
-
...itemState,
|
|
6493
|
-
isLocked
|
|
6494
|
-
})
|
|
6495
|
-
)
|
|
6658
|
+
updateSelectedOverlayState((itemState) => ({
|
|
6659
|
+
...itemState,
|
|
6660
|
+
isLocked
|
|
6496
6661
|
}));
|
|
6497
|
-
}, [
|
|
6662
|
+
}, [updateSelectedOverlayState]);
|
|
6498
6663
|
const toggleOverlayLocked = (0, import_react7.useCallback)(() => {
|
|
6499
|
-
|
|
6500
|
-
...
|
|
6501
|
-
|
|
6502
|
-
currentState,
|
|
6503
|
-
(itemState) => ({
|
|
6504
|
-
...itemState,
|
|
6505
|
-
isLocked: !itemState.isLocked
|
|
6506
|
-
})
|
|
6507
|
-
)
|
|
6664
|
+
updateSelectedOverlayState((itemState) => ({
|
|
6665
|
+
...itemState,
|
|
6666
|
+
isLocked: !itemState.isLocked
|
|
6508
6667
|
}));
|
|
6509
|
-
}, [
|
|
6668
|
+
}, [updateSelectedOverlayState]);
|
|
6510
6669
|
const setOverlayMode = (0, import_react7.useCallback)((mode) => {
|
|
6511
|
-
|
|
6512
|
-
...
|
|
6513
|
-
|
|
6514
|
-
currentState,
|
|
6515
|
-
(itemState) => ({
|
|
6516
|
-
...itemState,
|
|
6517
|
-
mode: normalizeReviewFigmaImageOverlayMode(mode)
|
|
6518
|
-
})
|
|
6519
|
-
)
|
|
6670
|
+
updateSelectedOverlayState((itemState) => ({
|
|
6671
|
+
...itemState,
|
|
6672
|
+
mode: normalizeReviewFigmaImageOverlayMode(mode)
|
|
6520
6673
|
}));
|
|
6521
|
-
}, [
|
|
6674
|
+
}, [updateSelectedOverlayState]);
|
|
6522
6675
|
const toggleOverlayMode = (0, import_react7.useCallback)(() => {
|
|
6523
|
-
|
|
6524
|
-
...
|
|
6525
|
-
|
|
6526
|
-
currentState,
|
|
6527
|
-
(itemState) => ({
|
|
6528
|
-
...itemState,
|
|
6529
|
-
mode: itemState.mode === "invert" ? "normal" : "invert"
|
|
6530
|
-
})
|
|
6531
|
-
)
|
|
6676
|
+
updateSelectedOverlayState((itemState) => ({
|
|
6677
|
+
...itemState,
|
|
6678
|
+
mode: itemState.mode === "invert" ? "normal" : "invert"
|
|
6532
6679
|
}));
|
|
6533
|
-
}, [
|
|
6680
|
+
}, [updateSelectedOverlayState]);
|
|
6534
6681
|
const setOverlayOffsetY = (0, import_react7.useCallback)((offsetY) => {
|
|
6535
|
-
|
|
6536
|
-
...
|
|
6537
|
-
|
|
6538
|
-
currentState,
|
|
6539
|
-
(itemState) => ({
|
|
6540
|
-
...itemState,
|
|
6541
|
-
offsetY: normalizeReviewFigmaImageOverlayOffsetY(offsetY)
|
|
6542
|
-
})
|
|
6543
|
-
)
|
|
6682
|
+
updateSelectedOverlayState((itemState) => ({
|
|
6683
|
+
...itemState,
|
|
6684
|
+
offsetY: normalizeReviewFigmaImageOverlayOffsetY(offsetY)
|
|
6544
6685
|
}));
|
|
6545
|
-
}, [
|
|
6686
|
+
}, [updateSelectedOverlayState]);
|
|
6546
6687
|
const resetOverlay = (0, import_react7.useCallback)(() => {
|
|
6547
6688
|
updateState((currentState) => ({
|
|
6548
6689
|
...currentState,
|
|
@@ -6583,160 +6724,29 @@ var useReviewFigmaImageOverlayController = ({
|
|
|
6583
6724
|
toggleOverlayVisible
|
|
6584
6725
|
};
|
|
6585
6726
|
};
|
|
6586
|
-
|
|
6587
|
-
|
|
6727
|
+
|
|
6728
|
+
// src/react-shell/figma/image-panel.utils.ts
|
|
6729
|
+
var DEFAULT_FIGMA_IMAGE_LAYER_STATE = {
|
|
6730
|
+
isLocked: false,
|
|
6731
|
+
isVisible: false,
|
|
6732
|
+
mode: "normal",
|
|
6733
|
+
offsetY: 0,
|
|
6734
|
+
opacity: DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY
|
|
6735
|
+
};
|
|
6736
|
+
function getFigmaImageLabel(image, index) {
|
|
6737
|
+
return image.label?.trim() || `Image ${index + 1}`;
|
|
6588
6738
|
}
|
|
6589
|
-
function
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
try {
|
|
6594
|
-
const value = window.localStorage.getItem(storageKey);
|
|
6595
|
-
if (!value) return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE;
|
|
6596
|
-
return normalizeReviewFigmaImageOverlayState(JSON.parse(value));
|
|
6597
|
-
} catch {
|
|
6598
|
-
return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE;
|
|
6599
|
-
}
|
|
6739
|
+
function getSnappedOpacityPercent(opacity) {
|
|
6740
|
+
const opacityPercent = Math.round(opacity * 100);
|
|
6741
|
+
if (!Number.isFinite(opacityPercent)) return 0;
|
|
6742
|
+
return Math.max(0, Math.min(100, Math.round(opacityPercent / 10) * 10));
|
|
6600
6743
|
}
|
|
6601
|
-
function
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
return;
|
|
6608
|
-
}
|
|
6609
|
-
return;
|
|
6610
|
-
}
|
|
6611
|
-
try {
|
|
6612
|
-
window.localStorage.setItem(
|
|
6613
|
-
storageKey,
|
|
6614
|
-
JSON.stringify({
|
|
6615
|
-
version: REVIEW_FIGMA_IMAGE_OVERLAY_STORAGE_VERSION,
|
|
6616
|
-
...state
|
|
6617
|
-
})
|
|
6618
|
-
);
|
|
6619
|
-
} catch {
|
|
6620
|
-
return;
|
|
6621
|
-
}
|
|
6622
|
-
}
|
|
6623
|
-
var DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE = {
|
|
6624
|
-
selectedImageId: null,
|
|
6625
|
-
imageStates: {},
|
|
6626
|
-
lastVisibleImageIds: []
|
|
6627
|
-
};
|
|
6628
|
-
var DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_ITEM_STATE = {
|
|
6629
|
-
isVisible: false,
|
|
6630
|
-
opacity: DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY,
|
|
6631
|
-
isLocked: false,
|
|
6632
|
-
mode: DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_MODE,
|
|
6633
|
-
offsetY: 0
|
|
6634
|
-
};
|
|
6635
|
-
function normalizeReviewFigmaImageOverlayState(value) {
|
|
6636
|
-
if (!value || typeof value !== "object") {
|
|
6637
|
-
return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_STATE;
|
|
6638
|
-
}
|
|
6639
|
-
const state = value;
|
|
6640
|
-
const selectedImageId = typeof state.selectedImageId === "string" ? state.selectedImageId : null;
|
|
6641
|
-
const lastVisibleImageIds = Array.isArray(state.lastVisibleImageIds) ? state.lastVisibleImageIds.filter(
|
|
6642
|
-
(imageId) => typeof imageId === "string"
|
|
6643
|
-
) : [];
|
|
6644
|
-
const imageStates = normalizeReviewFigmaImageOverlayItemStateRecord(
|
|
6645
|
-
state.imageStates
|
|
6646
|
-
);
|
|
6647
|
-
if (Object.keys(imageStates).length === 0 && selectedImageId) {
|
|
6648
|
-
imageStates[selectedImageId] = normalizeReviewFigmaImageOverlayItemState(
|
|
6649
|
-
state
|
|
6650
|
-
);
|
|
6651
|
-
}
|
|
6652
|
-
return {
|
|
6653
|
-
selectedImageId,
|
|
6654
|
-
imageStates,
|
|
6655
|
-
lastVisibleImageIds
|
|
6656
|
-
};
|
|
6657
|
-
}
|
|
6658
|
-
function normalizeReviewFigmaImageOverlayItemStateRecord(value) {
|
|
6659
|
-
if (!value || typeof value !== "object") return {};
|
|
6660
|
-
return Object.fromEntries(
|
|
6661
|
-
Object.entries(value).flatMap(([imageId, itemState]) => {
|
|
6662
|
-
if (!imageId || typeof itemState !== "object") return [];
|
|
6663
|
-
return [
|
|
6664
|
-
[
|
|
6665
|
-
imageId,
|
|
6666
|
-
normalizeReviewFigmaImageOverlayItemState(
|
|
6667
|
-
itemState
|
|
6668
|
-
)
|
|
6669
|
-
]
|
|
6670
|
-
];
|
|
6671
|
-
})
|
|
6672
|
-
);
|
|
6673
|
-
}
|
|
6674
|
-
function normalizeReviewFigmaImageOverlayItemState(value) {
|
|
6675
|
-
return {
|
|
6676
|
-
isVisible: value.isVisible === true,
|
|
6677
|
-
opacity: clampReviewFigmaImageOverlayOpacity(
|
|
6678
|
-
typeof value.opacity === "number" ? value.opacity : DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY
|
|
6679
|
-
),
|
|
6680
|
-
isLocked: value.isLocked === true,
|
|
6681
|
-
mode: normalizeReviewFigmaImageOverlayMode(value.mode),
|
|
6682
|
-
offsetY: normalizeReviewFigmaImageOverlayOffsetY(value.offsetY)
|
|
6683
|
-
};
|
|
6684
|
-
}
|
|
6685
|
-
function normalizeReviewFigmaImageOverlayMode(value) {
|
|
6686
|
-
return value === "invert" ? "invert" : DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_MODE;
|
|
6687
|
-
}
|
|
6688
|
-
function normalizeReviewFigmaImageOverlayOffsetY(value) {
|
|
6689
|
-
if (typeof value !== "number" || !Number.isFinite(value)) return 0;
|
|
6690
|
-
return Math.round(value);
|
|
6691
|
-
}
|
|
6692
|
-
function clampReviewFigmaImageOverlayOpacity(value) {
|
|
6693
|
-
if (!Number.isFinite(value)) return DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY;
|
|
6694
|
-
return Math.min(1, Math.max(0, value));
|
|
6695
|
-
}
|
|
6696
|
-
function isDefaultReviewFigmaImageOverlayState(state) {
|
|
6697
|
-
return state.selectedImageId === null && Object.keys(state.imageStates).length === 0 && state.lastVisibleImageIds.length === 0;
|
|
6698
|
-
}
|
|
6699
|
-
function getReviewFigmaImageOverlayItemState(state, imageId) {
|
|
6700
|
-
return imageId ? state.imageStates[imageId] ?? DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_ITEM_STATE : DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_ITEM_STATE;
|
|
6701
|
-
}
|
|
6702
|
-
function updateSelectedReviewFigmaImageOverlayItemState(state, updater) {
|
|
6703
|
-
return state.selectedImageId ? updateReviewFigmaImageOverlayItemState(
|
|
6704
|
-
state.imageStates,
|
|
6705
|
-
state.selectedImageId,
|
|
6706
|
-
updater
|
|
6707
|
-
) : state.imageStates;
|
|
6708
|
-
}
|
|
6709
|
-
function updateReviewFigmaImageOverlayItemState(imageStates, imageId, updater) {
|
|
6710
|
-
return {
|
|
6711
|
-
...imageStates,
|
|
6712
|
-
[imageId]: updater(
|
|
6713
|
-
imageStates[imageId] ?? DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_ITEM_STATE
|
|
6714
|
-
)
|
|
6715
|
-
};
|
|
6716
|
-
}
|
|
6717
|
-
|
|
6718
|
-
// src/react-shell/figma/image-panel.utils.ts
|
|
6719
|
-
var DEFAULT_FIGMA_IMAGE_LAYER_STATE = {
|
|
6720
|
-
isLocked: false,
|
|
6721
|
-
isVisible: false,
|
|
6722
|
-
mode: "normal",
|
|
6723
|
-
offsetY: 0,
|
|
6724
|
-
opacity: DEFAULT_REVIEW_FIGMA_IMAGE_OVERLAY_OPACITY
|
|
6725
|
-
};
|
|
6726
|
-
function getFigmaImageLabel(image, index) {
|
|
6727
|
-
return image.label?.trim() || `Image ${index + 1}`;
|
|
6728
|
-
}
|
|
6729
|
-
function getSnappedOpacityPercent(opacity) {
|
|
6730
|
-
const opacityPercent = Math.round(opacity * 100);
|
|
6731
|
-
if (!Number.isFinite(opacityPercent)) return 0;
|
|
6732
|
-
return Math.max(0, Math.min(100, Math.round(opacityPercent / 10) * 10));
|
|
6733
|
-
}
|
|
6734
|
-
function getFigmaImageLayerStatusLabel(overlayState) {
|
|
6735
|
-
return [
|
|
6736
|
-
overlayState.isVisible ? "Visible" : "Hidden",
|
|
6737
|
-
overlayState.mode === "invert" ? "Invert" : "",
|
|
6738
|
-
overlayState.isLocked ? "Locked" : ""
|
|
6739
|
-
].filter(Boolean).join(" / ");
|
|
6744
|
+
function getFigmaImageLayerStatusLabel(overlayState) {
|
|
6745
|
+
return [
|
|
6746
|
+
overlayState.isVisible ? "Visible" : "Hidden",
|
|
6747
|
+
overlayState.mode === "invert" ? "Invert" : "",
|
|
6748
|
+
overlayState.isLocked ? "Locked" : ""
|
|
6749
|
+
].filter(Boolean).join(" / ");
|
|
6740
6750
|
}
|
|
6741
6751
|
function getReorderedFigmaImageIds(images, draggedImageId, dropTargetImageId) {
|
|
6742
6752
|
const currentImageIds = images.map((image) => image.id);
|
|
@@ -7571,11 +7581,19 @@ var updateShellUrl = (target, size, source) => {
|
|
|
7571
7581
|
}
|
|
7572
7582
|
url.searchParams.delete("item");
|
|
7573
7583
|
url.searchParams.delete("panel");
|
|
7574
|
-
window.history.replaceState(
|
|
7584
|
+
window.history.replaceState(
|
|
7585
|
+
null,
|
|
7586
|
+
"",
|
|
7587
|
+
`${url.pathname}${url.search}${url.hash}`
|
|
7588
|
+
);
|
|
7575
7589
|
};
|
|
7576
7590
|
var updateShellUrlForItem = (target, size, itemId, source) => {
|
|
7577
7591
|
const url = getShellUrlForItem(target, size, itemId, source);
|
|
7578
|
-
window.history.replaceState(
|
|
7592
|
+
window.history.replaceState(
|
|
7593
|
+
null,
|
|
7594
|
+
"",
|
|
7595
|
+
`${url.pathname}${url.search}${url.hash}`
|
|
7596
|
+
);
|
|
7579
7597
|
};
|
|
7580
7598
|
var getShellUrlForItem = (target, size, itemId, source) => {
|
|
7581
7599
|
const url = new URL(window.location.href);
|
|
@@ -9850,6 +9868,26 @@ var REVIEW_QA_STATUS_FILTER_VALUES = /* @__PURE__ */ new Set([
|
|
|
9850
9868
|
"hold",
|
|
9851
9869
|
"done"
|
|
9852
9870
|
]);
|
|
9871
|
+
var readStorage = (key) => {
|
|
9872
|
+
if (typeof window === "undefined") return null;
|
|
9873
|
+
try {
|
|
9874
|
+
return window.localStorage.getItem(key);
|
|
9875
|
+
} catch {
|
|
9876
|
+
return null;
|
|
9877
|
+
}
|
|
9878
|
+
};
|
|
9879
|
+
var writeStorage = (key, value) => {
|
|
9880
|
+
if (typeof window === "undefined") return;
|
|
9881
|
+
try {
|
|
9882
|
+
if (value === null) {
|
|
9883
|
+
window.localStorage.removeItem(key);
|
|
9884
|
+
} else {
|
|
9885
|
+
window.localStorage.setItem(key, value);
|
|
9886
|
+
}
|
|
9887
|
+
} catch {
|
|
9888
|
+
return;
|
|
9889
|
+
}
|
|
9890
|
+
};
|
|
9853
9891
|
var normalizeReviewTheme = (value) => value === "light" || value === "system" || value === "dark" ? value : DEFAULT_REVIEW_THEME;
|
|
9854
9892
|
var normalizeReviewSidePanel = (value) => {
|
|
9855
9893
|
if (value === "qa" || value === "source" || value === "figma-images") {
|
|
@@ -9888,100 +9926,35 @@ var normalizeStoredSourceTreeMetaVisibility = (value) => {
|
|
|
9888
9926
|
className: typeof metaVisibility.className === "boolean" ? metaVisibility.className : DEFAULT_SOURCE_TREE_META_VISIBILITY.className
|
|
9889
9927
|
};
|
|
9890
9928
|
};
|
|
9891
|
-
var getStoredFigmaToken = () =>
|
|
9892
|
-
if (typeof window === "undefined") return "";
|
|
9893
|
-
try {
|
|
9894
|
-
return window.localStorage.getItem(FIGMA_TOKEN_STORAGE_KEY) ?? "";
|
|
9895
|
-
} catch {
|
|
9896
|
-
return "";
|
|
9897
|
-
}
|
|
9898
|
-
};
|
|
9929
|
+
var getStoredFigmaToken = () => readStorage(FIGMA_TOKEN_STORAGE_KEY) ?? "";
|
|
9899
9930
|
var writeStoredFigmaToken = (token) => {
|
|
9900
|
-
|
|
9901
|
-
try {
|
|
9902
|
-
if (token) {
|
|
9903
|
-
window.localStorage.setItem(FIGMA_TOKEN_STORAGE_KEY, token);
|
|
9904
|
-
} else {
|
|
9905
|
-
window.localStorage.removeItem(FIGMA_TOKEN_STORAGE_KEY);
|
|
9906
|
-
}
|
|
9907
|
-
} catch {
|
|
9908
|
-
return;
|
|
9909
|
-
}
|
|
9931
|
+
writeStorage(FIGMA_TOKEN_STORAGE_KEY, token || null);
|
|
9910
9932
|
};
|
|
9911
9933
|
var getStoredReviewUserId = (fallback = "") => {
|
|
9912
9934
|
const normalizedFallback = fallback.trim();
|
|
9913
|
-
|
|
9914
|
-
try {
|
|
9915
|
-
return window.localStorage.getItem(REVIEW_USER_ID_STORAGE_KEY)?.trim() || normalizedFallback;
|
|
9916
|
-
} catch {
|
|
9917
|
-
return normalizedFallback;
|
|
9918
|
-
}
|
|
9935
|
+
return readStorage(REVIEW_USER_ID_STORAGE_KEY)?.trim() || normalizedFallback;
|
|
9919
9936
|
};
|
|
9920
9937
|
var writeStoredReviewUserId = (userId) => {
|
|
9921
|
-
|
|
9922
|
-
try {
|
|
9923
|
-
if (userId) {
|
|
9924
|
-
window.localStorage.setItem(REVIEW_USER_ID_STORAGE_KEY, userId);
|
|
9925
|
-
} else {
|
|
9926
|
-
window.localStorage.removeItem(REVIEW_USER_ID_STORAGE_KEY);
|
|
9927
|
-
}
|
|
9928
|
-
} catch {
|
|
9929
|
-
return;
|
|
9930
|
-
}
|
|
9931
|
-
};
|
|
9932
|
-
var getStoredReviewTheme = () => {
|
|
9933
|
-
if (typeof window === "undefined") return DEFAULT_REVIEW_THEME;
|
|
9934
|
-
try {
|
|
9935
|
-
return normalizeReviewTheme(
|
|
9936
|
-
window.localStorage.getItem(REVIEW_THEME_STORAGE_KEY)
|
|
9937
|
-
);
|
|
9938
|
-
} catch {
|
|
9939
|
-
return DEFAULT_REVIEW_THEME;
|
|
9940
|
-
}
|
|
9938
|
+
writeStorage(REVIEW_USER_ID_STORAGE_KEY, userId || null);
|
|
9941
9939
|
};
|
|
9940
|
+
var getStoredReviewTheme = () => normalizeReviewTheme(readStorage(REVIEW_THEME_STORAGE_KEY));
|
|
9942
9941
|
var writeStoredReviewTheme = (theme) => {
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
9947
|
-
} else {
|
|
9948
|
-
window.localStorage.setItem(REVIEW_THEME_STORAGE_KEY, theme);
|
|
9949
|
-
}
|
|
9950
|
-
} catch {
|
|
9951
|
-
return;
|
|
9952
|
-
}
|
|
9942
|
+
writeStorage(
|
|
9943
|
+
REVIEW_THEME_STORAGE_KEY,
|
|
9944
|
+
theme === DEFAULT_REVIEW_THEME ? null : theme
|
|
9945
|
+
);
|
|
9953
9946
|
};
|
|
9954
9947
|
var getStoredReviewTooltipsEnabled = () => {
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
const value = window.localStorage.getItem(REVIEW_TOOLTIP_STORAGE_KEY);
|
|
9958
|
-
return value === null ? DEFAULT_REVIEW_TOOLTIPS_ENABLED : value !== "false";
|
|
9959
|
-
} catch {
|
|
9960
|
-
return DEFAULT_REVIEW_TOOLTIPS_ENABLED;
|
|
9961
|
-
}
|
|
9948
|
+
const value = readStorage(REVIEW_TOOLTIP_STORAGE_KEY);
|
|
9949
|
+
return value === null ? DEFAULT_REVIEW_TOOLTIPS_ENABLED : value !== "false";
|
|
9962
9950
|
};
|
|
9963
9951
|
var writeStoredReviewTooltipsEnabled = (isEnabled) => {
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
} else {
|
|
9969
|
-
window.localStorage.setItem(REVIEW_TOOLTIP_STORAGE_KEY, "false");
|
|
9970
|
-
}
|
|
9971
|
-
} catch {
|
|
9972
|
-
return;
|
|
9973
|
-
}
|
|
9974
|
-
};
|
|
9975
|
-
var getStoredReviewSidePanel = () => {
|
|
9976
|
-
if (typeof window === "undefined") return "qa";
|
|
9977
|
-
try {
|
|
9978
|
-
return normalizeStoredReviewSidePanel(
|
|
9979
|
-
window.localStorage.getItem(REVIEW_SIDE_PANEL_STORAGE_KEY)
|
|
9980
|
-
);
|
|
9981
|
-
} catch {
|
|
9982
|
-
return "qa";
|
|
9983
|
-
}
|
|
9952
|
+
writeStorage(
|
|
9953
|
+
REVIEW_TOOLTIP_STORAGE_KEY,
|
|
9954
|
+
isEnabled === DEFAULT_REVIEW_TOOLTIPS_ENABLED ? null : "false"
|
|
9955
|
+
);
|
|
9984
9956
|
};
|
|
9957
|
+
var getStoredReviewSidePanel = () => normalizeStoredReviewSidePanel(readStorage(REVIEW_SIDE_PANEL_STORAGE_KEY));
|
|
9985
9958
|
var getInitialReviewSidePanel = () => {
|
|
9986
9959
|
if (typeof window === "undefined") return null;
|
|
9987
9960
|
try {
|
|
@@ -9993,106 +9966,49 @@ var getInitialReviewSidePanel = () => {
|
|
|
9993
9966
|
}
|
|
9994
9967
|
};
|
|
9995
9968
|
var writeStoredReviewSidePanel = (sidePanel) => {
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
normalizeStoredReviewSidePanel(sidePanel)
|
|
10001
|
-
);
|
|
10002
|
-
} catch {
|
|
10003
|
-
return;
|
|
10004
|
-
}
|
|
9969
|
+
writeStorage(
|
|
9970
|
+
REVIEW_SIDE_PANEL_STORAGE_KEY,
|
|
9971
|
+
normalizeStoredReviewSidePanel(sidePanel)
|
|
9972
|
+
);
|
|
10005
9973
|
};
|
|
10006
9974
|
var getStoredReviewSidePanelVisible = () => {
|
|
10007
|
-
|
|
10008
|
-
|
|
10009
|
-
const value = window.localStorage.getItem(
|
|
10010
|
-
REVIEW_SIDE_PANEL_VISIBLE_STORAGE_KEY
|
|
10011
|
-
);
|
|
10012
|
-
return value === null ? true : value === "true";
|
|
10013
|
-
} catch {
|
|
10014
|
-
return true;
|
|
10015
|
-
}
|
|
9975
|
+
const value = readStorage(REVIEW_SIDE_PANEL_VISIBLE_STORAGE_KEY);
|
|
9976
|
+
return value === null ? true : value === "true";
|
|
10016
9977
|
};
|
|
10017
9978
|
var writeStoredReviewSidePanelVisible = (isVisible) => {
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
isVisible ? "true" : "false"
|
|
10023
|
-
);
|
|
10024
|
-
} catch {
|
|
10025
|
-
return;
|
|
10026
|
-
}
|
|
10027
|
-
};
|
|
10028
|
-
var getStoredReviewQaStatusFilters = () => {
|
|
10029
|
-
if (typeof window === "undefined") return getDefaultReviewQaStatusFilters();
|
|
10030
|
-
try {
|
|
10031
|
-
return normalizeStoredReviewQaStatusFilters(
|
|
10032
|
-
window.localStorage.getItem(REVIEW_QA_STATUS_FILTER_STORAGE_KEY)
|
|
10033
|
-
);
|
|
10034
|
-
} catch {
|
|
10035
|
-
return getDefaultReviewQaStatusFilters();
|
|
10036
|
-
}
|
|
9979
|
+
writeStorage(
|
|
9980
|
+
REVIEW_SIDE_PANEL_VISIBLE_STORAGE_KEY,
|
|
9981
|
+
isVisible ? "true" : "false"
|
|
9982
|
+
);
|
|
10037
9983
|
};
|
|
9984
|
+
var getStoredReviewQaStatusFilters = () => normalizeStoredReviewQaStatusFilters(
|
|
9985
|
+
readStorage(REVIEW_QA_STATUS_FILTER_STORAGE_KEY)
|
|
9986
|
+
);
|
|
10038
9987
|
var writeStoredReviewQaStatusFilters = (filters) => {
|
|
10039
|
-
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
|
|
10043
|
-
|
|
10044
|
-
} else {
|
|
10045
|
-
window.localStorage.setItem(
|
|
10046
|
-
REVIEW_QA_STATUS_FILTER_STORAGE_KEY,
|
|
10047
|
-
JSON.stringify(normalizedFilters)
|
|
10048
|
-
);
|
|
10049
|
-
}
|
|
10050
|
-
} catch {
|
|
10051
|
-
return;
|
|
10052
|
-
}
|
|
10053
|
-
};
|
|
10054
|
-
var getStoredSourceTreeFilter = () => {
|
|
10055
|
-
if (typeof window === "undefined") return "";
|
|
10056
|
-
try {
|
|
10057
|
-
return window.localStorage.getItem(REVIEW_SOURCE_TREE_FILTER_STORAGE_KEY) ?? "";
|
|
10058
|
-
} catch {
|
|
10059
|
-
return "";
|
|
10060
|
-
}
|
|
9988
|
+
const normalizedFilters = normalizeReviewQaStatusFilters(filters);
|
|
9989
|
+
writeStorage(
|
|
9990
|
+
REVIEW_QA_STATUS_FILTER_STORAGE_KEY,
|
|
9991
|
+
isDefaultReviewQaStatusFilters(normalizedFilters) ? null : JSON.stringify(normalizedFilters)
|
|
9992
|
+
);
|
|
10061
9993
|
};
|
|
9994
|
+
var getStoredSourceTreeFilter = () => readStorage(REVIEW_SOURCE_TREE_FILTER_STORAGE_KEY) ?? "";
|
|
10062
9995
|
var writeStoredSourceTreeFilter = (filter) => {
|
|
10063
|
-
|
|
10064
|
-
try {
|
|
10065
|
-
if (filter) {
|
|
10066
|
-
window.localStorage.setItem(REVIEW_SOURCE_TREE_FILTER_STORAGE_KEY, filter);
|
|
10067
|
-
} else {
|
|
10068
|
-
window.localStorage.removeItem(REVIEW_SOURCE_TREE_FILTER_STORAGE_KEY);
|
|
10069
|
-
}
|
|
10070
|
-
} catch {
|
|
10071
|
-
return;
|
|
10072
|
-
}
|
|
9996
|
+
writeStorage(REVIEW_SOURCE_TREE_FILTER_STORAGE_KEY, filter || null);
|
|
10073
9997
|
};
|
|
10074
9998
|
var getStoredSourceTreeMetaVisibility = () => {
|
|
10075
|
-
|
|
9999
|
+
const value = readStorage(REVIEW_SOURCE_TREE_META_STORAGE_KEY);
|
|
10000
|
+
if (!value) return DEFAULT_SOURCE_TREE_META_VISIBILITY;
|
|
10076
10001
|
try {
|
|
10077
|
-
const value = window.localStorage.getItem(
|
|
10078
|
-
REVIEW_SOURCE_TREE_META_STORAGE_KEY
|
|
10079
|
-
);
|
|
10080
|
-
if (!value) return DEFAULT_SOURCE_TREE_META_VISIBILITY;
|
|
10081
10002
|
return normalizeStoredSourceTreeMetaVisibility(JSON.parse(value));
|
|
10082
10003
|
} catch {
|
|
10083
10004
|
return DEFAULT_SOURCE_TREE_META_VISIBILITY;
|
|
10084
10005
|
}
|
|
10085
10006
|
};
|
|
10086
10007
|
var writeStoredSourceTreeMetaVisibility = (metaVisibility) => {
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
JSON.stringify(normalizeStoredSourceTreeMetaVisibility(metaVisibility))
|
|
10092
|
-
);
|
|
10093
|
-
} catch {
|
|
10094
|
-
return;
|
|
10095
|
-
}
|
|
10008
|
+
writeStorage(
|
|
10009
|
+
REVIEW_SOURCE_TREE_META_STORAGE_KEY,
|
|
10010
|
+
JSON.stringify(normalizeStoredSourceTreeMetaVisibility(metaVisibility))
|
|
10011
|
+
);
|
|
10096
10012
|
};
|
|
10097
10013
|
var getSystemReviewTheme = () => {
|
|
10098
10014
|
if (typeof window === "undefined" || !window.matchMedia) return "dark";
|
|
@@ -11070,6 +10986,73 @@ function getAdjustedDraftSelection(selection, draft, presets) {
|
|
|
11070
10986
|
};
|
|
11071
10987
|
}
|
|
11072
10988
|
|
|
10989
|
+
// src/core/hotkey.ts
|
|
10990
|
+
var HOTKEY_KEY_ALIASES = {
|
|
10991
|
+
q: ["\u3142", "\u3143"],
|
|
10992
|
+
w: ["\u3148", "\u3149"],
|
|
10993
|
+
e: ["\u3137", "\u3138"],
|
|
10994
|
+
r: ["\u3131", "\u3132"],
|
|
10995
|
+
t: ["\u3145", "\u3146"],
|
|
10996
|
+
y: ["\u315B"],
|
|
10997
|
+
u: ["\u3155"],
|
|
10998
|
+
i: ["\u3151"],
|
|
10999
|
+
o: ["\u3150", "\u3152"],
|
|
11000
|
+
p: ["\u3154", "\u3156"],
|
|
11001
|
+
a: ["\u3141"],
|
|
11002
|
+
s: ["\u3134"],
|
|
11003
|
+
d: ["\u3147"],
|
|
11004
|
+
f: ["\u3139"],
|
|
11005
|
+
g: ["\u314E"],
|
|
11006
|
+
h: ["\u3157"],
|
|
11007
|
+
j: ["\u3153"],
|
|
11008
|
+
k: ["\u314F"],
|
|
11009
|
+
l: ["\u3163"],
|
|
11010
|
+
z: ["\u314B"],
|
|
11011
|
+
x: ["\u314C"],
|
|
11012
|
+
c: ["\u314A"],
|
|
11013
|
+
v: ["\u314D"],
|
|
11014
|
+
b: ["\u3160"],
|
|
11015
|
+
n: ["\u315C"],
|
|
11016
|
+
m: ["\u3161"]
|
|
11017
|
+
};
|
|
11018
|
+
function isEditableEventTarget(event) {
|
|
11019
|
+
const path = event.composedPath?.() ?? [];
|
|
11020
|
+
const element = path[0] ?? event.target;
|
|
11021
|
+
if (!element || typeof element.tagName !== "string") return false;
|
|
11022
|
+
const tag = element.tagName;
|
|
11023
|
+
return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || element.isContentEditable === true;
|
|
11024
|
+
}
|
|
11025
|
+
function isHotkey(event, hotkey) {
|
|
11026
|
+
const parts = hotkey.split("+").map((part) => part.trim().toLowerCase()).filter(Boolean);
|
|
11027
|
+
const key = parts.find(
|
|
11028
|
+
(part) => !["shift", "ctrl", "control", "alt", "meta", "cmd"].includes(part)
|
|
11029
|
+
);
|
|
11030
|
+
if (!key) return false;
|
|
11031
|
+
if (parts.includes("shift") !== event.shiftKey) return false;
|
|
11032
|
+
if ((parts.includes("ctrl") || parts.includes("control")) !== event.ctrlKey) {
|
|
11033
|
+
return false;
|
|
11034
|
+
}
|
|
11035
|
+
if (parts.includes("alt") !== event.altKey) return false;
|
|
11036
|
+
if ((parts.includes("meta") || parts.includes("cmd")) !== event.metaKey) {
|
|
11037
|
+
return false;
|
|
11038
|
+
}
|
|
11039
|
+
return isHotkeyKey(event, key);
|
|
11040
|
+
}
|
|
11041
|
+
function getHotkeyActionKey(event, keys) {
|
|
11042
|
+
return keys.find((key) => isHotkeyKey(event, key));
|
|
11043
|
+
}
|
|
11044
|
+
function isHotkeyKey(event, key) {
|
|
11045
|
+
const normalizedKey = key.toLowerCase();
|
|
11046
|
+
if (event.key.toLowerCase() === normalizedKey) return true;
|
|
11047
|
+
if (getHotkeyCode(normalizedKey) === event.code) return true;
|
|
11048
|
+
return HOTKEY_KEY_ALIASES[normalizedKey]?.includes(event.key) ?? false;
|
|
11049
|
+
}
|
|
11050
|
+
function getHotkeyCode(key) {
|
|
11051
|
+
if (/^[a-z]$/.test(key)) return `Key${key.toUpperCase()}`;
|
|
11052
|
+
if (/^[0-9]$/.test(key)) return `Digit${key}`;
|
|
11053
|
+
return void 0;
|
|
11054
|
+
}
|
|
11055
|
+
|
|
11073
11056
|
// src/react-shell/source.open.ts
|
|
11074
11057
|
var getSourceCandidates = (target, options) => {
|
|
11075
11058
|
const startElement = getEventElement(target);
|
|
@@ -11155,7 +11138,7 @@ function createSourceCandidate(element, source, depth, kind, context) {
|
|
|
11155
11138
|
const column = getSourcePosition(source.column);
|
|
11156
11139
|
const position = line ? `:${line}${column ? `:${column}` : ""}` : "";
|
|
11157
11140
|
return {
|
|
11158
|
-
id: `${kind}:${
|
|
11141
|
+
id: `${kind}:${getSourceCandidateDedupeKey(source)}:${repeatInfo?.index ?? 0}:${depth}`,
|
|
11159
11142
|
depth,
|
|
11160
11143
|
element,
|
|
11161
11144
|
filePath: getDisplaySourcePath(source.file) ?? fileName,
|
|
@@ -11185,16 +11168,6 @@ function takeVisibleSourceCandidates(candidates) {
|
|
|
11185
11168
|
}
|
|
11186
11169
|
return visible;
|
|
11187
11170
|
}
|
|
11188
|
-
function getSourceCandidateKey(source) {
|
|
11189
|
-
return [
|
|
11190
|
-
source.file,
|
|
11191
|
-
source.component,
|
|
11192
|
-
source.line,
|
|
11193
|
-
source.column,
|
|
11194
|
-
source.sectionId,
|
|
11195
|
-
source.sectionIndex
|
|
11196
|
-
].filter(Boolean).join("|");
|
|
11197
|
-
}
|
|
11198
11171
|
function getSourceCandidateDedupeKey(source) {
|
|
11199
11172
|
return [
|
|
11200
11173
|
source.file,
|
|
@@ -11612,11 +11585,6 @@ var getSectionDomAdjustmentKeyDelta = (event) => {
|
|
|
11612
11585
|
return null;
|
|
11613
11586
|
};
|
|
11614
11587
|
var isDomAdjustmentEmpty = (position) => position.x === 0 && position.y === 0;
|
|
11615
|
-
var isEditableKeyTarget = (target) => {
|
|
11616
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
11617
|
-
const tagName = target.tagName;
|
|
11618
|
-
return tagName === "INPUT" || tagName === "TEXTAREA" || tagName === "SELECT" || target.isContentEditable;
|
|
11619
|
-
};
|
|
11620
11588
|
var COMPONENT_SELECTION_ACTION_SELECTOR = [
|
|
11621
11589
|
"a",
|
|
11622
11590
|
"button",
|
|
@@ -11786,7 +11754,7 @@ function useReviewSectionOutline({
|
|
|
11786
11754
|
(0, import_react18.useEffect)(() => {
|
|
11787
11755
|
if (!activeDomAdjustmentEntryId) return void 0;
|
|
11788
11756
|
const handleKeyDown = (event) => {
|
|
11789
|
-
if (
|
|
11757
|
+
if (isEditableEventTarget(event)) return;
|
|
11790
11758
|
const delta = getSectionDomAdjustmentKeyDelta(event);
|
|
11791
11759
|
if (!delta) return;
|
|
11792
11760
|
const position = domAdjustmentManagerRef.current?.adjust(
|
|
@@ -13630,7 +13598,7 @@ var ReviewSettingsModal = ({
|
|
|
13630
13598
|
// src/react-shell/sitemap/modal.tsx
|
|
13631
13599
|
var import_react24 = require("react");
|
|
13632
13600
|
|
|
13633
|
-
// src/react-shell/sitemap/
|
|
13601
|
+
// src/react-shell/sitemap/count.ts
|
|
13634
13602
|
var WORKFLOW_STATUSES = [
|
|
13635
13603
|
"todo",
|
|
13636
13604
|
"doing",
|
|
@@ -13654,33 +13622,11 @@ var createEmptySitemapQaCount = () => ({
|
|
|
13654
13622
|
viewport: {}
|
|
13655
13623
|
});
|
|
13656
13624
|
var createSitemapViewportColumn = (preset, index) => ({
|
|
13625
|
+
// 크기가 같은 preset도 별도 열로 유지될 수 있게 순서를 key에 포함한다.
|
|
13657
13626
|
key: `${index}:${preset.width}x${preset.height}`,
|
|
13658
13627
|
label: preset.label,
|
|
13659
13628
|
title: `${preset.label} ${preset.width}x${preset.height}`
|
|
13660
13629
|
});
|
|
13661
|
-
var normalizeSitemapHref = (href) => {
|
|
13662
|
-
const [path = "/"] = href.split(/[?#]/);
|
|
13663
|
-
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
13664
|
-
return normalizedPath || "/";
|
|
13665
|
-
};
|
|
13666
|
-
var getSitemapSegments = (href) => normalizeSitemapHref(href).split("/").map((segment) => segment.trim()).filter(Boolean);
|
|
13667
|
-
var createSitemapNode = (href, label, isPage = false) => ({
|
|
13668
|
-
href,
|
|
13669
|
-
label,
|
|
13670
|
-
isPage,
|
|
13671
|
-
children: /* @__PURE__ */ new Map()
|
|
13672
|
-
});
|
|
13673
|
-
var mergeSitemapUsers = (users) => {
|
|
13674
|
-
const userByKey = /* @__PURE__ */ new Map();
|
|
13675
|
-
users.forEach((user) => {
|
|
13676
|
-
const key = user.sessionId || user.userId;
|
|
13677
|
-
const currentUser = userByKey.get(key);
|
|
13678
|
-
if (!currentUser || Date.parse(user.updatedAt) >= Date.parse(currentUser.updatedAt)) {
|
|
13679
|
-
userByKey.set(key, user);
|
|
13680
|
-
}
|
|
13681
|
-
});
|
|
13682
|
-
return Array.from(userByKey.values());
|
|
13683
|
-
};
|
|
13684
13630
|
var addSitemapQaCounts = (first, second) => ({
|
|
13685
13631
|
total: first.total + second.total,
|
|
13686
13632
|
remaining: first.remaining + second.remaining,
|
|
@@ -13718,9 +13664,37 @@ var addSitemapQaCounts = (first, second) => ({
|
|
|
13718
13664
|
{}
|
|
13719
13665
|
)
|
|
13720
13666
|
});
|
|
13667
|
+
|
|
13668
|
+
// src/react-shell/sitemap/tree.ts
|
|
13669
|
+
var SITEMAP_STATUS_FILTERS = ["todo", "review", "hold"];
|
|
13670
|
+
var normalizeSitemapHref = (href) => {
|
|
13671
|
+
const [path = "/"] = href.split(/[?#]/);
|
|
13672
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
13673
|
+
return normalizedPath || "/";
|
|
13674
|
+
};
|
|
13675
|
+
var getSitemapSegments = (href) => normalizeSitemapHref(href).split("/").map((segment) => segment.trim()).filter(Boolean);
|
|
13676
|
+
var createSitemapNode = (href, label, isPage = false) => ({
|
|
13677
|
+
href,
|
|
13678
|
+
label,
|
|
13679
|
+
isPage,
|
|
13680
|
+
children: /* @__PURE__ */ new Map()
|
|
13681
|
+
});
|
|
13682
|
+
var mergeSitemapUsers = (users) => {
|
|
13683
|
+
const userByKey = /* @__PURE__ */ new Map();
|
|
13684
|
+
users.forEach((user) => {
|
|
13685
|
+
const key = user.sessionId || user.userId;
|
|
13686
|
+
const currentUser = userByKey.get(key);
|
|
13687
|
+
if (!currentUser || Date.parse(user.updatedAt) >= Date.parse(currentUser.updatedAt)) {
|
|
13688
|
+
userByKey.set(key, user);
|
|
13689
|
+
}
|
|
13690
|
+
});
|
|
13691
|
+
return Array.from(userByKey.values());
|
|
13692
|
+
};
|
|
13721
13693
|
var createSitemapRows = (pages, activeRoute, pageQaCounts, pagePresenceUsers, getPageTarget, options = {}) => {
|
|
13722
13694
|
const collapsedFolderHrefs = options.collapsedFolderHrefs ?? /* @__PURE__ */ new Set();
|
|
13723
13695
|
const searchQuery = normalizeSitemapSearchQuery(options.searchQuery);
|
|
13696
|
+
const statusFilters = options.statusFilters ?? /* @__PURE__ */ new Set();
|
|
13697
|
+
const isStatusFiltering = statusFilters.size > 0;
|
|
13724
13698
|
const sortKey = options.sortKey ?? "page";
|
|
13725
13699
|
const sortDirection = options.sortDirection ?? "asc";
|
|
13726
13700
|
const root = createSitemapNode("/", "/", false);
|
|
@@ -13774,23 +13748,25 @@ var createSitemapRows = (pages, activeRoute, pageQaCounts, pagePresenceUsers, ge
|
|
|
13774
13748
|
node,
|
|
13775
13749
|
directCount,
|
|
13776
13750
|
directUsers,
|
|
13751
|
+
// folder는 하위 page 합계, 실제 page는 자신의 수치를 별도로 보존한다.
|
|
13777
13752
|
count: node.isPage ? addSitemapQaCounts(directCount, childAggregate.count) : childAggregate.count,
|
|
13778
13753
|
users: mergeSitemapUsers([...directUsers, ...childAggregate.users]),
|
|
13779
13754
|
children
|
|
13780
13755
|
};
|
|
13781
13756
|
};
|
|
13782
|
-
const
|
|
13783
|
-
if (sortKey === "page") return
|
|
13784
|
-
if (sortKey === "todo") return
|
|
13785
|
-
if (sortKey === "review") return
|
|
13786
|
-
if (sortKey === "hold") return
|
|
13787
|
-
if (sortKey === "online") return
|
|
13757
|
+
const getSortValueFor = (label, count, users) => {
|
|
13758
|
+
if (sortKey === "page") return label;
|
|
13759
|
+
if (sortKey === "todo") return count.status.todo;
|
|
13760
|
+
if (sortKey === "review") return count.status.review;
|
|
13761
|
+
if (sortKey === "hold") return count.status.hold;
|
|
13762
|
+
if (sortKey === "online") return users.length;
|
|
13788
13763
|
if (sortKey.startsWith("viewport:")) {
|
|
13789
13764
|
const viewportKey = sortKey.slice("viewport:".length);
|
|
13790
|
-
return
|
|
13765
|
+
return count.viewport[viewportKey]?.remaining ?? 0;
|
|
13791
13766
|
}
|
|
13792
13767
|
return 0;
|
|
13793
13768
|
};
|
|
13769
|
+
const getSortValue = (summary) => getSortValueFor(summary.node.label, summary.count, summary.users);
|
|
13794
13770
|
const sortSummaries = (summaries) => {
|
|
13795
13771
|
return [...summaries].sort((a, b) => {
|
|
13796
13772
|
const firstValue = getSortValue(a);
|
|
@@ -13811,6 +13787,53 @@ var createSitemapRows = (pages, activeRoute, pageQaCounts, pagePresenceUsers, ge
|
|
|
13811
13787
|
}
|
|
13812
13788
|
return summary.children.some(summaryMatchesSearch);
|
|
13813
13789
|
};
|
|
13790
|
+
const countMatchesStatusFilters = (count) => Array.from(statusFilters).some((status) => count.status[status] > 0);
|
|
13791
|
+
if (isStatusFiltering) {
|
|
13792
|
+
const flatEntries = [];
|
|
13793
|
+
const collectMatchingPages = (node) => {
|
|
13794
|
+
if (node.isPage) {
|
|
13795
|
+
const directCount = getDirectCount(node);
|
|
13796
|
+
if (countMatchesStatusFilters(directCount) && (!searchQuery || sitemapNodeMatchesSearch(node, searchQuery, getPageTarget))) {
|
|
13797
|
+
flatEntries.push({
|
|
13798
|
+
node,
|
|
13799
|
+
count: directCount,
|
|
13800
|
+
users: getDirectUsers(node)
|
|
13801
|
+
});
|
|
13802
|
+
}
|
|
13803
|
+
}
|
|
13804
|
+
node.children.forEach(collectMatchingPages);
|
|
13805
|
+
};
|
|
13806
|
+
collectMatchingPages(root);
|
|
13807
|
+
return flatEntries.sort((a, b) => {
|
|
13808
|
+
const firstValue = getSortValueFor(
|
|
13809
|
+
normalizeSitemapHref(a.node.href),
|
|
13810
|
+
a.count,
|
|
13811
|
+
a.users
|
|
13812
|
+
);
|
|
13813
|
+
const secondValue = getSortValueFor(
|
|
13814
|
+
normalizeSitemapHref(b.node.href),
|
|
13815
|
+
b.count,
|
|
13816
|
+
b.users
|
|
13817
|
+
);
|
|
13818
|
+
const valueDiff = typeof firstValue === "string" && typeof secondValue === "string" ? firstValue.localeCompare(secondValue) : Number(firstValue) - Number(secondValue);
|
|
13819
|
+
if (valueDiff !== 0) {
|
|
13820
|
+
return sortDirection === "asc" ? valueDiff : -valueDiff;
|
|
13821
|
+
}
|
|
13822
|
+
const remainingDiff = b.count.remaining - a.count.remaining;
|
|
13823
|
+
if (remainingDiff !== 0) return remainingDiff;
|
|
13824
|
+
return a.node.href.localeCompare(b.node.href);
|
|
13825
|
+
}).map((entry) => ({
|
|
13826
|
+
href: entry.node.href,
|
|
13827
|
+
label: normalizeSitemapHref(entry.node.href),
|
|
13828
|
+
depth: 0,
|
|
13829
|
+
hasChildren: false,
|
|
13830
|
+
isExpanded: false,
|
|
13831
|
+
isPage: true,
|
|
13832
|
+
isActive: getPageTarget(entry.node.href) === activeRoute,
|
|
13833
|
+
qaCount: entry.count,
|
|
13834
|
+
users: entry.users
|
|
13835
|
+
}));
|
|
13836
|
+
}
|
|
13814
13837
|
const rows = [];
|
|
13815
13838
|
const appendSummaryRows = (summary, depth) => {
|
|
13816
13839
|
const { node } = summary;
|
|
@@ -13878,8 +13901,70 @@ function sitemapNodeMatchesSearch(node, searchQuery, getPageTarget) {
|
|
|
13878
13901
|
].join(" ").toLowerCase().includes(searchQuery);
|
|
13879
13902
|
}
|
|
13880
13903
|
|
|
13904
|
+
// src/react-shell/sitemap/row.tsx
|
|
13905
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
13906
|
+
var getCountCellClassName = (status, count) => [
|
|
13907
|
+
"df-review-sitemap-cell",
|
|
13908
|
+
`is-${status}`,
|
|
13909
|
+
count === 0 ? "is-zero" : ""
|
|
13910
|
+
].filter(Boolean).join(" ");
|
|
13911
|
+
var SitemapRowContent = ({
|
|
13912
|
+
depth,
|
|
13913
|
+
hasChildren,
|
|
13914
|
+
isExpanded,
|
|
13915
|
+
isPage,
|
|
13916
|
+
label,
|
|
13917
|
+
qaCount,
|
|
13918
|
+
users,
|
|
13919
|
+
onToggleFolder
|
|
13920
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
13921
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
13922
|
+
"span",
|
|
13923
|
+
{
|
|
13924
|
+
className: "df-review-sitemap-path",
|
|
13925
|
+
style: { "--df-review-sitemap-depth": depth },
|
|
13926
|
+
children: [
|
|
13927
|
+
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
13928
|
+
"button",
|
|
13929
|
+
{
|
|
13930
|
+
"aria-expanded": isExpanded,
|
|
13931
|
+
"aria-label": `${isExpanded ? "Collapse" : "Expand"} ${label}`,
|
|
13932
|
+
className: "df-review-sitemap-tree-toggle",
|
|
13933
|
+
type: "button",
|
|
13934
|
+
onClick: (event) => {
|
|
13935
|
+
event.stopPropagation();
|
|
13936
|
+
onToggleFolder?.();
|
|
13937
|
+
},
|
|
13938
|
+
children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChevronRight, { "aria-hidden": "true" })
|
|
13939
|
+
}
|
|
13940
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-tree-spacer", "aria-hidden": "true" }),
|
|
13941
|
+
isPage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-page-label", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-label", children: label })
|
|
13942
|
+
]
|
|
13943
|
+
}
|
|
13944
|
+
),
|
|
13945
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: getCountCellClassName("todo", qaCount.status.todo), children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("strong", { children: qaCount.status.todo }) }),
|
|
13946
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: getCountCellClassName("review", qaCount.status.review), children: qaCount.status.review }),
|
|
13947
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: getCountCellClassName("hold", qaCount.status.hold), children: qaCount.status.hold }),
|
|
13948
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-cell is-online", children: users.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-users", children: users.map((user) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
13949
|
+
"span",
|
|
13950
|
+
{
|
|
13951
|
+
className: "df-review-sitemap-user",
|
|
13952
|
+
style: {
|
|
13953
|
+
"--df-review-presence-color": user.color
|
|
13954
|
+
},
|
|
13955
|
+
children: user.userId
|
|
13956
|
+
},
|
|
13957
|
+
user.sessionId
|
|
13958
|
+
)) }) : null })
|
|
13959
|
+
] });
|
|
13960
|
+
|
|
13881
13961
|
// src/react-shell/sitemap/modal.tsx
|
|
13882
|
-
var
|
|
13962
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
13963
|
+
var STATUS_FILTER_LABELS = {
|
|
13964
|
+
todo: "Todo",
|
|
13965
|
+
review: "Review",
|
|
13966
|
+
hold: "Hold"
|
|
13967
|
+
};
|
|
13883
13968
|
var getNextSortDirection = (current, key) => {
|
|
13884
13969
|
if (current.key !== key) return key === "page" ? "asc" : "desc";
|
|
13885
13970
|
return current.direction === "desc" ? "asc" : "desc";
|
|
@@ -13888,11 +13973,6 @@ var getSortIndicator = (sort, key) => {
|
|
|
13888
13973
|
if (sort.key !== key) return "";
|
|
13889
13974
|
return sort.direction === "desc" ? "\u2193" : "\u2191";
|
|
13890
13975
|
};
|
|
13891
|
-
var getCountCellClassName = (status, count) => [
|
|
13892
|
-
"df-review-sitemap-cell",
|
|
13893
|
-
`is-${status}`,
|
|
13894
|
-
count === 0 ? "is-zero" : ""
|
|
13895
|
-
].filter(Boolean).join(" ");
|
|
13896
13976
|
var mergePresenceUsers = (users) => {
|
|
13897
13977
|
const userByKey = /* @__PURE__ */ new Map();
|
|
13898
13978
|
users.forEach((user) => {
|
|
@@ -13905,6 +13985,7 @@ var mergePresenceUsers = (users) => {
|
|
|
13905
13985
|
return Array.from(userByKey.values());
|
|
13906
13986
|
};
|
|
13907
13987
|
var SitemapModal = ({
|
|
13988
|
+
isOpen,
|
|
13908
13989
|
pages,
|
|
13909
13990
|
activeRoute,
|
|
13910
13991
|
allQaCount,
|
|
@@ -13924,7 +14005,11 @@ var SitemapModal = ({
|
|
|
13924
14005
|
() => /* @__PURE__ */ new Set()
|
|
13925
14006
|
);
|
|
13926
14007
|
const [searchQuery, setSearchQuery] = (0, import_react24.useState)("");
|
|
14008
|
+
const [statusFilters, setStatusFilters] = (0, import_react24.useState)(
|
|
14009
|
+
() => /* @__PURE__ */ new Set()
|
|
14010
|
+
);
|
|
13927
14011
|
const trimmedSearchQuery = searchQuery.trim();
|
|
14012
|
+
const isFiltering = Boolean(trimmedSearchQuery) || statusFilters.size > 0;
|
|
13928
14013
|
const allQaUsers = (0, import_react24.useMemo)(
|
|
13929
14014
|
() => mergePresenceUsers(Array.from(pagePresenceUsers.values()).flat()),
|
|
13930
14015
|
[pagePresenceUsers]
|
|
@@ -13939,7 +14024,8 @@ var SitemapModal = ({
|
|
|
13939
14024
|
collapsedFolderHrefs,
|
|
13940
14025
|
searchQuery: trimmedSearchQuery,
|
|
13941
14026
|
sortKey: sort.key,
|
|
13942
|
-
sortDirection: sort.direction
|
|
14027
|
+
sortDirection: sort.direction,
|
|
14028
|
+
statusFilters
|
|
13943
14029
|
}
|
|
13944
14030
|
);
|
|
13945
14031
|
const matchingPageCount = sitemapRows.filter((row) => row.isPage).length;
|
|
@@ -13959,6 +14045,17 @@ var SitemapModal = ({
|
|
|
13959
14045
|
direction: getNextSortDirection(current, key)
|
|
13960
14046
|
}));
|
|
13961
14047
|
};
|
|
14048
|
+
const toggleStatusFilter = (status) => {
|
|
14049
|
+
setStatusFilters((currentFilters) => {
|
|
14050
|
+
const nextFilters = new Set(currentFilters);
|
|
14051
|
+
if (nextFilters.has(status)) {
|
|
14052
|
+
nextFilters.delete(status);
|
|
14053
|
+
} else {
|
|
14054
|
+
nextFilters.add(status);
|
|
14055
|
+
}
|
|
14056
|
+
return nextFilters;
|
|
14057
|
+
});
|
|
14058
|
+
};
|
|
13962
14059
|
const toggleFolder = (href) => {
|
|
13963
14060
|
setCollapsedFolderHrefs((currentHrefs) => {
|
|
13964
14061
|
const nextHrefs = new Set(currentHrefs);
|
|
@@ -13970,15 +14067,15 @@ var SitemapModal = ({
|
|
|
13970
14067
|
return nextHrefs;
|
|
13971
14068
|
});
|
|
13972
14069
|
};
|
|
13973
|
-
return /* @__PURE__ */ (0,
|
|
14070
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
13974
14071
|
"div",
|
|
13975
14072
|
{
|
|
13976
14073
|
"aria-label": "Sitemap",
|
|
13977
14074
|
"aria-modal": "true",
|
|
13978
|
-
className:
|
|
14075
|
+
className: `df-review-sitemap-modal${isOpen ? "" : " is-hidden"}`,
|
|
13979
14076
|
role: "dialog",
|
|
13980
14077
|
children: [
|
|
13981
|
-
/* @__PURE__ */ (0,
|
|
14078
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
13982
14079
|
"button",
|
|
13983
14080
|
{
|
|
13984
14081
|
"aria-label": "Close sitemap",
|
|
@@ -13987,28 +14084,39 @@ var SitemapModal = ({
|
|
|
13987
14084
|
onClick: onClose
|
|
13988
14085
|
}
|
|
13989
14086
|
),
|
|
13990
|
-
/* @__PURE__ */ (0,
|
|
13991
|
-
/* @__PURE__ */ (0,
|
|
13992
|
-
/* @__PURE__ */ (0,
|
|
13993
|
-
/* @__PURE__ */ (0,
|
|
13994
|
-
/* @__PURE__ */ (0,
|
|
14087
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "df-review-sitemap-dialog", children: [
|
|
14088
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "df-review-sitemap-header", children: [
|
|
14089
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
|
|
14090
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("strong", { children: "Sitemap" }),
|
|
14091
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
|
|
13995
14092
|
pages.length,
|
|
13996
|
-
" pages
|
|
13997
|
-
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
|
|
14003
|
-
|
|
14093
|
+
" pages",
|
|
14094
|
+
SITEMAP_STATUS_FILTERS.map((status) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react24.Fragment, { children: [
|
|
14095
|
+
" \xB7 ",
|
|
14096
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
14097
|
+
"button",
|
|
14098
|
+
{
|
|
14099
|
+
"aria-pressed": statusFilters.has(status),
|
|
14100
|
+
className: `df-review-sitemap-summary-filter${statusFilters.has(status) ? " is-active" : ""}`,
|
|
14101
|
+
title: `Show pages with ${STATUS_FILTER_LABELS[status]} QA`,
|
|
14102
|
+
type: "button",
|
|
14103
|
+
onClick: () => toggleStatusFilter(status),
|
|
14104
|
+
children: [
|
|
14105
|
+
allQaCount.status[status],
|
|
14106
|
+
" ",
|
|
14107
|
+
status
|
|
14108
|
+
]
|
|
14109
|
+
}
|
|
14110
|
+
)
|
|
14111
|
+
] }, status))
|
|
14004
14112
|
] })
|
|
14005
14113
|
] }),
|
|
14006
|
-
/* @__PURE__ */ (0,
|
|
14114
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { "aria-label": "Close sitemap", type: "button", onClick: onClose, children: "x" })
|
|
14007
14115
|
] }),
|
|
14008
|
-
/* @__PURE__ */ (0,
|
|
14009
|
-
/* @__PURE__ */ (0,
|
|
14010
|
-
/* @__PURE__ */ (0,
|
|
14011
|
-
/* @__PURE__ */ (0,
|
|
14116
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "df-review-sitemap-controls", children: [
|
|
14117
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "df-review-sitemap-search", children: [
|
|
14118
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Search, { "aria-hidden": "true" }),
|
|
14119
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
14012
14120
|
"input",
|
|
14013
14121
|
{
|
|
14014
14122
|
"aria-label": "Search sitemap",
|
|
@@ -14020,20 +14128,20 @@ var SitemapModal = ({
|
|
|
14020
14128
|
}
|
|
14021
14129
|
)
|
|
14022
14130
|
] }),
|
|
14023
|
-
trimmedSearchQuery && /* @__PURE__ */ (0,
|
|
14131
|
+
trimmedSearchQuery && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
14024
14132
|
"button",
|
|
14025
14133
|
{
|
|
14026
14134
|
"aria-label": "Clear sitemap search",
|
|
14027
14135
|
className: "df-review-sitemap-search-clear",
|
|
14028
14136
|
type: "button",
|
|
14029
14137
|
onClick: () => setSearchQuery(""),
|
|
14030
|
-
children: /* @__PURE__ */ (0,
|
|
14138
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(X, { "aria-hidden": "true" })
|
|
14031
14139
|
}
|
|
14032
14140
|
),
|
|
14033
|
-
/* @__PURE__ */ (0,
|
|
14141
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "df-review-sitemap-search-count", children: isFiltering ? `${matchingPageCount} matches` : `${pages.length} pages` })
|
|
14034
14142
|
] }),
|
|
14035
|
-
/* @__PURE__ */ (0,
|
|
14036
|
-
/* @__PURE__ */ (0,
|
|
14143
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "df-review-sitemap-list", style: gridStyle, children: [
|
|
14144
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "df-review-sitemap-table-head", role: "row", children: sortHeaders.map((header) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
14037
14145
|
"button",
|
|
14038
14146
|
{
|
|
14039
14147
|
"aria-label": `Sort sitemap by ${header.title ?? header.label}`,
|
|
@@ -14046,7 +14154,7 @@ var SitemapModal = ({
|
|
|
14046
14154
|
type: "button",
|
|
14047
14155
|
onClick: () => setSortKey(header.key),
|
|
14048
14156
|
children: [
|
|
14049
|
-
/* @__PURE__ */ (0,
|
|
14157
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
14050
14158
|
"span",
|
|
14051
14159
|
{
|
|
14052
14160
|
"aria-hidden": "true",
|
|
@@ -14054,7 +14162,7 @@ var SitemapModal = ({
|
|
|
14054
14162
|
children: getSortIndicator(sort, header.key)
|
|
14055
14163
|
}
|
|
14056
14164
|
),
|
|
14057
|
-
/* @__PURE__ */ (0,
|
|
14165
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "df-review-sitemap-sort-label", children: header.label })
|
|
14058
14166
|
]
|
|
14059
14167
|
},
|
|
14060
14168
|
header.key
|
|
@@ -14069,7 +14177,7 @@ var SitemapModal = ({
|
|
|
14069
14177
|
row.isActive ? "is-active" : "",
|
|
14070
14178
|
row.isPage ? "is-clickable" : ""
|
|
14071
14179
|
].filter(Boolean).join(" ");
|
|
14072
|
-
const rowContent = /* @__PURE__ */ (0,
|
|
14180
|
+
const rowContent = /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
14073
14181
|
SitemapRowContent,
|
|
14074
14182
|
{
|
|
14075
14183
|
depth: row.depth,
|
|
@@ -14082,7 +14190,7 @@ var SitemapModal = ({
|
|
|
14082
14190
|
onToggleFolder: () => toggleFolder(row.href)
|
|
14083
14191
|
}
|
|
14084
14192
|
);
|
|
14085
|
-
return /* @__PURE__ */ (0,
|
|
14193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
14086
14194
|
"div",
|
|
14087
14195
|
{
|
|
14088
14196
|
"aria-label": row.isPage ? `${row.href} / ${row.qaCount.status.todo} todo / ${row.qaCount.status.review} review / ${row.qaCount.status.hold} hold / ${row.users.length} online` : `${row.href} group / ${row.qaCount.status.todo} todo / ${row.qaCount.status.review} review / ${row.qaCount.status.hold} hold / ${row.users.length} online`,
|
|
@@ -14101,15 +14209,15 @@ var SitemapModal = ({
|
|
|
14101
14209
|
row.href
|
|
14102
14210
|
);
|
|
14103
14211
|
}),
|
|
14104
|
-
sitemapRows.length === 0 && /* @__PURE__ */ (0,
|
|
14105
|
-
/* @__PURE__ */ (0,
|
|
14212
|
+
sitemapRows.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "df-review-sitemap-empty", role: "status", children: "No matching pages" }),
|
|
14213
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
14106
14214
|
"button",
|
|
14107
14215
|
{
|
|
14108
14216
|
"aria-label": `All QA / ${allQaCount.status.todo} todo / ${allQaCount.status.review} review / ${allQaCount.status.hold} hold`,
|
|
14109
14217
|
className: `df-review-sitemap-row is-summary${isAllQaVisible ? " is-active" : ""}`,
|
|
14110
14218
|
type: "button",
|
|
14111
14219
|
onClick: onSelectAllQa,
|
|
14112
|
-
children: /* @__PURE__ */ (0,
|
|
14220
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
14113
14221
|
SitemapRowContent,
|
|
14114
14222
|
{
|
|
14115
14223
|
depth: 0,
|
|
@@ -14129,55 +14237,6 @@ var SitemapModal = ({
|
|
|
14129
14237
|
}
|
|
14130
14238
|
);
|
|
14131
14239
|
};
|
|
14132
|
-
var SitemapRowContent = ({
|
|
14133
|
-
depth,
|
|
14134
|
-
hasChildren,
|
|
14135
|
-
isExpanded,
|
|
14136
|
-
isPage,
|
|
14137
|
-
label,
|
|
14138
|
-
qaCount,
|
|
14139
|
-
users,
|
|
14140
|
-
onToggleFolder
|
|
14141
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
14142
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
14143
|
-
"span",
|
|
14144
|
-
{
|
|
14145
|
-
className: "df-review-sitemap-path",
|
|
14146
|
-
style: { "--df-review-sitemap-depth": depth },
|
|
14147
|
-
children: [
|
|
14148
|
-
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
14149
|
-
"button",
|
|
14150
|
-
{
|
|
14151
|
-
"aria-expanded": isExpanded,
|
|
14152
|
-
"aria-label": `${isExpanded ? "Collapse" : "Expand"} ${label}`,
|
|
14153
|
-
className: "df-review-sitemap-tree-toggle",
|
|
14154
|
-
type: "button",
|
|
14155
|
-
onClick: (event) => {
|
|
14156
|
-
event.stopPropagation();
|
|
14157
|
-
onToggleFolder?.();
|
|
14158
|
-
},
|
|
14159
|
-
children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChevronRight, { "aria-hidden": "true" })
|
|
14160
|
-
}
|
|
14161
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-tree-spacer", "aria-hidden": "true" }),
|
|
14162
|
-
isPage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-page-label", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-label", children: label })
|
|
14163
|
-
]
|
|
14164
|
-
}
|
|
14165
|
-
),
|
|
14166
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: getCountCellClassName("todo", qaCount.status.todo), children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("strong", { children: qaCount.status.todo }) }),
|
|
14167
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: getCountCellClassName("review", qaCount.status.review), children: qaCount.status.review }),
|
|
14168
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: getCountCellClassName("hold", qaCount.status.hold), children: qaCount.status.hold }),
|
|
14169
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-cell is-online", children: users.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "df-review-sitemap-users", children: users.map((user) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
14170
|
-
"span",
|
|
14171
|
-
{
|
|
14172
|
-
className: "df-review-sitemap-user",
|
|
14173
|
-
style: {
|
|
14174
|
-
"--df-review-presence-color": user.color
|
|
14175
|
-
},
|
|
14176
|
-
children: user.userId
|
|
14177
|
-
},
|
|
14178
|
-
user.sessionId
|
|
14179
|
-
)) }) : null })
|
|
14180
|
-
] });
|
|
14181
14240
|
|
|
14182
14241
|
// src/react-shell/hooks/use.review.shell.data.ts
|
|
14183
14242
|
var import_react25 = require("react");
|
|
@@ -14334,7 +14393,7 @@ var useReviewShellData = () => {
|
|
|
14334
14393
|
};
|
|
14335
14394
|
|
|
14336
14395
|
// src/react-shell/review/shell.modals.container.tsx
|
|
14337
|
-
var
|
|
14396
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
14338
14397
|
var ReviewShellModalsContainer = () => {
|
|
14339
14398
|
const { initialPrompt, pages } = useReviewShellConfig();
|
|
14340
14399
|
const {
|
|
@@ -14391,6 +14450,10 @@ var ReviewShellModalsContainer = () => {
|
|
|
14391
14450
|
(state) => state.setIsSitemapOpen
|
|
14392
14451
|
);
|
|
14393
14452
|
const showToast = useReviewToast();
|
|
14453
|
+
const [hasSitemapOpened, setHasSitemapOpened] = (0, import_react26.useState)(false);
|
|
14454
|
+
(0, import_react26.useEffect)(() => {
|
|
14455
|
+
if (isSitemapOpen) setHasSitemapOpened(true);
|
|
14456
|
+
}, [isSitemapOpen]);
|
|
14394
14457
|
const initialPromptText = initialPrompt.trim();
|
|
14395
14458
|
const copyInitialPrompt = (0, import_react26.useCallback)(
|
|
14396
14459
|
(value, key) => copyReviewPrompt({
|
|
@@ -14401,10 +14464,11 @@ var ReviewShellModalsContainer = () => {
|
|
|
14401
14464
|
}),
|
|
14402
14465
|
[setCopiedPromptKey, showToast]
|
|
14403
14466
|
);
|
|
14404
|
-
return /* @__PURE__ */ (0,
|
|
14405
|
-
|
|
14467
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
14468
|
+
hasSitemapOpened && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
14406
14469
|
SitemapModal,
|
|
14407
14470
|
{
|
|
14471
|
+
isOpen: isSitemapOpen,
|
|
14408
14472
|
activeRoute,
|
|
14409
14473
|
allQaCount,
|
|
14410
14474
|
getPageTarget,
|
|
@@ -14417,7 +14481,7 @@ var ReviewShellModalsContainer = () => {
|
|
|
14417
14481
|
onSelectPage: selectPage
|
|
14418
14482
|
}
|
|
14419
14483
|
),
|
|
14420
|
-
isFigmaSettingsOpen && /* @__PURE__ */ (0,
|
|
14484
|
+
isFigmaSettingsOpen && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
14421
14485
|
ReviewSettingsModal,
|
|
14422
14486
|
{
|
|
14423
14487
|
areTooltipsEnabledDraft,
|
|
@@ -14438,8 +14502,8 @@ var ReviewShellModalsContainer = () => {
|
|
|
14438
14502
|
onToggleFigmaTokenVisible: () => setIsFigmaTokenVisible((current) => !current)
|
|
14439
14503
|
}
|
|
14440
14504
|
),
|
|
14441
|
-
isInitialPromptOpen && /* @__PURE__ */ (0,
|
|
14442
|
-
isInitialPromptScriptOpen && /* @__PURE__ */ (0,
|
|
14505
|
+
isInitialPromptOpen && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PromptModal, { onClose: () => setIsInitialPromptOpen(false) }),
|
|
14506
|
+
isInitialPromptScriptOpen && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
14443
14507
|
InitialPromptModal,
|
|
14444
14508
|
{
|
|
14445
14509
|
copiedPromptKey,
|
|
@@ -14494,7 +14558,7 @@ var useReviewSourceInspectorState = () => {
|
|
|
14494
14558
|
};
|
|
14495
14559
|
|
|
14496
14560
|
// src/react-shell/review/shell.providers.tsx
|
|
14497
|
-
var
|
|
14561
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
14498
14562
|
var ReviewShellProviders = ({
|
|
14499
14563
|
actions,
|
|
14500
14564
|
children,
|
|
@@ -14504,17 +14568,17 @@ var ReviewShellProviders = ({
|
|
|
14504
14568
|
ruler,
|
|
14505
14569
|
settings,
|
|
14506
14570
|
sourceInspector
|
|
14507
|
-
}) => /* @__PURE__ */ (0,
|
|
14571
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ReviewShellActionsProvider, { value: actions, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ReviewRulerProvider, { value: ruler, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ReviewFigmaImagesProvider, { value: figmaImages, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ReviewSourceInspectorProvider, { value: sourceInspector, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ReviewSettingsProvider, { value: settings, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ReviewPresenceProvider, { value: presence, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ReviewFigmaOverlayProvider, { value: figmaOverlay, children }) }) }) }) }) }) });
|
|
14508
14572
|
|
|
14509
14573
|
// src/react-shell/review/source.inspector.overlay.tsx
|
|
14510
|
-
var
|
|
14574
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
14511
14575
|
var SourceInspectorOverlay = ({
|
|
14512
14576
|
componentSelectionState,
|
|
14513
14577
|
state
|
|
14514
14578
|
}) => {
|
|
14515
14579
|
const hoverState = state?.targetElement === componentSelectionState?.targetElement ? null : state;
|
|
14516
|
-
return /* @__PURE__ */ (0,
|
|
14517
|
-
componentSelectionState ? /* @__PURE__ */ (0,
|
|
14580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
14581
|
+
componentSelectionState ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
14518
14582
|
"div",
|
|
14519
14583
|
{
|
|
14520
14584
|
className: "df-review-source-outline is-component-selection",
|
|
@@ -14526,7 +14590,7 @@ var SourceInspectorOverlay = ({
|
|
|
14526
14590
|
}
|
|
14527
14591
|
}
|
|
14528
14592
|
) : null,
|
|
14529
|
-
hoverState ? /* @__PURE__ */ (0,
|
|
14593
|
+
hoverState ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
14530
14594
|
"div",
|
|
14531
14595
|
{
|
|
14532
14596
|
className: "df-review-source-outline is-hover",
|
|
@@ -14542,10 +14606,10 @@ var SourceInspectorOverlay = ({
|
|
|
14542
14606
|
};
|
|
14543
14607
|
|
|
14544
14608
|
// src/react-shell/review/source.inspector.overlay.container.tsx
|
|
14545
|
-
var
|
|
14609
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
14546
14610
|
var SourceInspectorOverlayContainer = () => {
|
|
14547
14611
|
const { componentSelectionState, sourceInspectorState } = useReviewSourceInspectorState();
|
|
14548
|
-
return /* @__PURE__ */ (0,
|
|
14612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
14549
14613
|
SourceInspectorOverlay,
|
|
14550
14614
|
{
|
|
14551
14615
|
componentSelectionState,
|
|
@@ -14558,7 +14622,7 @@ var SourceInspectorOverlayContainer = () => {
|
|
|
14558
14622
|
var import_react32 = require("react");
|
|
14559
14623
|
|
|
14560
14624
|
// src/react-shell/review/mode.toolbar.tsx
|
|
14561
|
-
var
|
|
14625
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
14562
14626
|
var ReviewModeToolbar = ({
|
|
14563
14627
|
canWriteArea,
|
|
14564
14628
|
canWriteDom,
|
|
@@ -14566,8 +14630,8 @@ var ReviewModeToolbar = ({
|
|
|
14566
14630
|
onSetReviewMode
|
|
14567
14631
|
}) => {
|
|
14568
14632
|
if (!canWriteDom && !canWriteArea) return null;
|
|
14569
|
-
return /* @__PURE__ */ (0,
|
|
14570
|
-
canWriteDom && /* @__PURE__ */ (0,
|
|
14633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "df-review-mode", "aria-label": "Add QA", children: [
|
|
14634
|
+
canWriteDom && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14571
14635
|
"button",
|
|
14572
14636
|
{
|
|
14573
14637
|
"aria-label": "Element",
|
|
@@ -14575,11 +14639,11 @@ var ReviewModeToolbar = ({
|
|
|
14575
14639
|
"data-review-tooltip": "Element QA",
|
|
14576
14640
|
type: "button",
|
|
14577
14641
|
onClick: () => onSetReviewMode("element"),
|
|
14578
|
-
children: /* @__PURE__ */ (0,
|
|
14642
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SquareMousePointer, { "aria-hidden": "true" })
|
|
14579
14643
|
}
|
|
14580
14644
|
),
|
|
14581
|
-
canWriteDom && canWriteArea && /* @__PURE__ */ (0,
|
|
14582
|
-
canWriteArea && /* @__PURE__ */ (0,
|
|
14645
|
+
canWriteDom && canWriteArea && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "df-review-mode-divider", "aria-hidden": "true", children: "|" }),
|
|
14646
|
+
canWriteArea && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14583
14647
|
"button",
|
|
14584
14648
|
{
|
|
14585
14649
|
"aria-label": "Area",
|
|
@@ -14587,14 +14651,14 @@ var ReviewModeToolbar = ({
|
|
|
14587
14651
|
"data-review-tooltip": "Area QA",
|
|
14588
14652
|
type: "button",
|
|
14589
14653
|
onClick: () => onSetReviewMode("area"),
|
|
14590
|
-
children: /* @__PURE__ */ (0,
|
|
14654
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Scan, { "aria-hidden": "true" })
|
|
14591
14655
|
}
|
|
14592
14656
|
)
|
|
14593
14657
|
] });
|
|
14594
14658
|
};
|
|
14595
14659
|
|
|
14596
14660
|
// src/react-shell/ruler/gutters.tsx
|
|
14597
|
-
var
|
|
14661
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
14598
14662
|
var RulerGutters = () => {
|
|
14599
14663
|
const size = useReviewShellStore((state) => state.size);
|
|
14600
14664
|
const {
|
|
@@ -14603,9 +14667,9 @@ var RulerGutters = () => {
|
|
|
14603
14667
|
rulerScaleY,
|
|
14604
14668
|
rulerUnit
|
|
14605
14669
|
} = useReviewRulerState();
|
|
14606
|
-
return /* @__PURE__ */ (0,
|
|
14607
|
-
/* @__PURE__ */ (0,
|
|
14608
|
-
/* @__PURE__ */ (0,
|
|
14670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
|
|
14671
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "df-review-ruler-corner", "aria-hidden": "true" }),
|
|
14672
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
14609
14673
|
"div",
|
|
14610
14674
|
{
|
|
14611
14675
|
className: "df-review-ruler-gutter is-x",
|
|
@@ -14613,15 +14677,15 @@ var RulerGutters = () => {
|
|
|
14613
14677
|
"--df-review-ruler-step-x": `${rulerScaleX * 20}px`
|
|
14614
14678
|
},
|
|
14615
14679
|
children: [
|
|
14616
|
-
/* @__PURE__ */ (0,
|
|
14617
|
-
/* @__PURE__ */ (0,
|
|
14618
|
-
/* @__PURE__ */ (0,
|
|
14680
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "df-review-ruler-frame-label", children: [
|
|
14681
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("strong", { children: size.label }),
|
|
14682
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { children: [
|
|
14619
14683
|
size.designWidth,
|
|
14620
14684
|
size.designHeight ? `x${size.designHeight}` : "",
|
|
14621
14685
|
rulerUnit
|
|
14622
14686
|
] })
|
|
14623
14687
|
] }),
|
|
14624
|
-
rulerHover && /* @__PURE__ */ (0,
|
|
14688
|
+
rulerHover && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
14625
14689
|
"div",
|
|
14626
14690
|
{
|
|
14627
14691
|
className: "df-review-ruler-coord is-x",
|
|
@@ -14632,14 +14696,14 @@ var RulerGutters = () => {
|
|
|
14632
14696
|
]
|
|
14633
14697
|
}
|
|
14634
14698
|
),
|
|
14635
|
-
/* @__PURE__ */ (0,
|
|
14699
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
14636
14700
|
"div",
|
|
14637
14701
|
{
|
|
14638
14702
|
className: "df-review-ruler-gutter is-y",
|
|
14639
14703
|
style: {
|
|
14640
14704
|
"--df-review-ruler-step-y": `${rulerScaleY * 20}px`
|
|
14641
14705
|
},
|
|
14642
|
-
children: rulerHover && /* @__PURE__ */ (0,
|
|
14706
|
+
children: rulerHover && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
14643
14707
|
"div",
|
|
14644
14708
|
{
|
|
14645
14709
|
className: "df-review-ruler-coord is-y",
|
|
@@ -14653,7 +14717,7 @@ var RulerGutters = () => {
|
|
|
14653
14717
|
};
|
|
14654
14718
|
|
|
14655
14719
|
// src/react-shell/ruler/overlay.tsx
|
|
14656
|
-
var
|
|
14720
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
14657
14721
|
var RulerOverlay = () => {
|
|
14658
14722
|
const { iframeRef } = useReviewShellRefs();
|
|
14659
14723
|
const size = useReviewShellStore((state) => state.size);
|
|
@@ -14664,7 +14728,7 @@ var RulerOverlay = () => {
|
|
|
14664
14728
|
rulerMeasureLabel,
|
|
14665
14729
|
rulerOverlayRef
|
|
14666
14730
|
} = useReviewRulerState();
|
|
14667
|
-
return /* @__PURE__ */ (0,
|
|
14731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
14668
14732
|
"div",
|
|
14669
14733
|
{
|
|
14670
14734
|
ref: rulerOverlayRef,
|
|
@@ -14678,8 +14742,8 @@ var RulerOverlay = () => {
|
|
|
14678
14742
|
);
|
|
14679
14743
|
},
|
|
14680
14744
|
children: [
|
|
14681
|
-
rulerHover && /* @__PURE__ */ (0,
|
|
14682
|
-
/* @__PURE__ */ (0,
|
|
14745
|
+
rulerHover && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
14746
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
14683
14747
|
"div",
|
|
14684
14748
|
{
|
|
14685
14749
|
className: "df-review-ruler-guide is-x",
|
|
@@ -14687,7 +14751,7 @@ var RulerOverlay = () => {
|
|
|
14687
14751
|
style: { top: `${rulerHover.y}px` }
|
|
14688
14752
|
}
|
|
14689
14753
|
),
|
|
14690
|
-
/* @__PURE__ */ (0,
|
|
14754
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
14691
14755
|
"div",
|
|
14692
14756
|
{
|
|
14693
14757
|
className: "df-review-ruler-guide is-y",
|
|
@@ -14696,8 +14760,8 @@ var RulerOverlay = () => {
|
|
|
14696
14760
|
}
|
|
14697
14761
|
)
|
|
14698
14762
|
] }),
|
|
14699
|
-
rulerMeasure && (rulerMeasure.width > 0 || rulerMeasure.height > 0) && /* @__PURE__ */ (0,
|
|
14700
|
-
/* @__PURE__ */ (0,
|
|
14763
|
+
rulerMeasure && (rulerMeasure.width > 0 || rulerMeasure.height > 0) && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
14764
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
14701
14765
|
"div",
|
|
14702
14766
|
{
|
|
14703
14767
|
className: "df-review-ruler-selection",
|
|
@@ -14710,7 +14774,7 @@ var RulerOverlay = () => {
|
|
|
14710
14774
|
}
|
|
14711
14775
|
}
|
|
14712
14776
|
),
|
|
14713
|
-
/* @__PURE__ */ (0,
|
|
14777
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
14714
14778
|
"div",
|
|
14715
14779
|
{
|
|
14716
14780
|
className: "df-review-ruler-label",
|
|
@@ -14836,13 +14900,6 @@ var setTargetFigmaSourceSelectLocked = (targetDocument, locked) => {
|
|
|
14836
14900
|
locked
|
|
14837
14901
|
);
|
|
14838
14902
|
};
|
|
14839
|
-
var isEditableEventTarget = (event) => {
|
|
14840
|
-
const path = event.composedPath?.() ?? [];
|
|
14841
|
-
const element = path[0] ?? event.target;
|
|
14842
|
-
if (!element || typeof element.tagName !== "string") return false;
|
|
14843
|
-
const tag = element.tagName;
|
|
14844
|
-
return tag === "INPUT" || tag === "TEXTAREA" || element.isContentEditable === true;
|
|
14845
|
-
};
|
|
14846
14903
|
var TRUE_STORAGE_VALUES = /* @__PURE__ */ new Set([
|
|
14847
14904
|
"1",
|
|
14848
14905
|
"true",
|
|
@@ -15894,7 +15951,7 @@ function isDomReviewItem(item) {
|
|
|
15894
15951
|
}
|
|
15895
15952
|
|
|
15896
15953
|
// src/react-shell/target/outside.markers.tsx
|
|
15897
|
-
var
|
|
15954
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
15898
15955
|
var OUTSIDE_MARKER_HEIGHT = 22;
|
|
15899
15956
|
var OUTSIDE_MARKER_CONNECTOR_TOP = 10;
|
|
15900
15957
|
var OUTSIDE_MARKER_GAP = 6;
|
|
@@ -16072,7 +16129,7 @@ var ReviewOutsideMarkers = () => {
|
|
|
16072
16129
|
size
|
|
16073
16130
|
]);
|
|
16074
16131
|
if (markers.length === 0) return null;
|
|
16075
|
-
return /* @__PURE__ */ (0,
|
|
16132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "df-review-outside-marker-layer", "aria-label": "QA markers", children: markers.map((marker) => {
|
|
16076
16133
|
const isActive = marker.item.id === selectedItemId;
|
|
16077
16134
|
const style = {
|
|
16078
16135
|
top: `${marker.top}px`,
|
|
@@ -16081,7 +16138,7 @@ var ReviewOutsideMarkers = () => {
|
|
|
16081
16138
|
"--df-review-outside-marker-connector-stem-height": `${marker.connectorStemHeight}px`,
|
|
16082
16139
|
"--df-review-outside-marker-z-index": isActive ? 2 : 1
|
|
16083
16140
|
};
|
|
16084
|
-
return /* @__PURE__ */ (0,
|
|
16141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
16085
16142
|
"button",
|
|
16086
16143
|
{
|
|
16087
16144
|
"aria-label": `Focus ${marker.label}`,
|
|
@@ -16103,7 +16160,7 @@ var ReviewOutsideMarkers = () => {
|
|
|
16103
16160
|
};
|
|
16104
16161
|
|
|
16105
16162
|
// src/react-shell/target/frame.tsx
|
|
16106
|
-
var
|
|
16163
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
16107
16164
|
var ReviewTargetFrame = () => {
|
|
16108
16165
|
const {
|
|
16109
16166
|
figmaImageOverlays,
|
|
@@ -16138,15 +16195,15 @@ var ReviewTargetFrame = () => {
|
|
|
16138
16195
|
syncTargetFigmaImageOverlays();
|
|
16139
16196
|
window.requestAnimationFrame(syncTargetFigmaImageOverlays);
|
|
16140
16197
|
};
|
|
16141
|
-
return /* @__PURE__ */ (0,
|
|
16142
|
-
/* @__PURE__ */ (0,
|
|
16198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("main", { className: "df-review-stage", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "df-review-frame", children: [
|
|
16199
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "df-review-frame-scroll", ref: frameScrollRef, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "df-review-frame-canvas", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "df-review-target-stack", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
16143
16200
|
"div",
|
|
16144
16201
|
{
|
|
16145
16202
|
className: `df-review-device-frame${showRuler ? " is-ruler" : ""}`,
|
|
16146
16203
|
children: [
|
|
16147
|
-
showRuler && /* @__PURE__ */ (0,
|
|
16148
|
-
/* @__PURE__ */ (0,
|
|
16149
|
-
/* @__PURE__ */ (0,
|
|
16204
|
+
showRuler && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(RulerGutters, {}),
|
|
16205
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ReviewOutsideMarkers, {}),
|
|
16206
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
16150
16207
|
"div",
|
|
16151
16208
|
{
|
|
16152
16209
|
className: "df-review-device",
|
|
@@ -16157,7 +16214,7 @@ var ReviewTargetFrame = () => {
|
|
|
16157
16214
|
minHeight: `${size.height}px`
|
|
16158
16215
|
},
|
|
16159
16216
|
children: [
|
|
16160
|
-
/* @__PURE__ */ (0,
|
|
16217
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
16161
16218
|
"iframe",
|
|
16162
16219
|
{
|
|
16163
16220
|
ref: iframeRef,
|
|
@@ -16169,14 +16226,14 @@ var ReviewTargetFrame = () => {
|
|
|
16169
16226
|
},
|
|
16170
16227
|
`${frameTargetSrc}:${frameNavigationVersion}`
|
|
16171
16228
|
),
|
|
16172
|
-
showRuler && /* @__PURE__ */ (0,
|
|
16229
|
+
showRuler && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(RulerOverlay, {})
|
|
16173
16230
|
]
|
|
16174
16231
|
}
|
|
16175
16232
|
)
|
|
16176
16233
|
]
|
|
16177
16234
|
}
|
|
16178
16235
|
) }) }) }),
|
|
16179
|
-
/* @__PURE__ */ (0,
|
|
16236
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "df-review-frame-actions", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
16180
16237
|
ReviewModeToolbar,
|
|
16181
16238
|
{
|
|
16182
16239
|
canWriteArea,
|
|
@@ -16192,18 +16249,18 @@ var ReviewTargetFrame = () => {
|
|
|
16192
16249
|
var import_react33 = require("react");
|
|
16193
16250
|
|
|
16194
16251
|
// src/react-shell/topbar.tsx
|
|
16195
|
-
var
|
|
16252
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
16196
16253
|
var ReviewScopeIcon2 = ({ scope }) => {
|
|
16197
|
-
if (scope === "mobile") return /* @__PURE__ */ (0,
|
|
16198
|
-
if (scope === "tablet") return /* @__PURE__ */ (0,
|
|
16199
|
-
if (scope === "wide") return /* @__PURE__ */ (0,
|
|
16200
|
-
if (scope === "dom") return /* @__PURE__ */ (0,
|
|
16201
|
-
return /* @__PURE__ */ (0,
|
|
16254
|
+
if (scope === "mobile") return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Smartphone, { "aria-hidden": "true" });
|
|
16255
|
+
if (scope === "tablet") return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RectangleHorizontal, { "aria-hidden": "true" });
|
|
16256
|
+
if (scope === "wide") return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Maximize2, { "aria-hidden": "true" });
|
|
16257
|
+
if (scope === "dom") return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SquareMousePointer, { "aria-hidden": "true" });
|
|
16258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Monitor, { "aria-hidden": "true" });
|
|
16202
16259
|
};
|
|
16203
16260
|
var ViewportPresetIcon = ({
|
|
16204
16261
|
preset
|
|
16205
16262
|
}) => {
|
|
16206
|
-
return /* @__PURE__ */ (0,
|
|
16263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReviewScopeIcon2, { scope: getViewportPresetKind(preset) });
|
|
16207
16264
|
};
|
|
16208
16265
|
var getPresetSelectValue = (preset) => `${preset.label}:${preset.width}x${preset.height}`;
|
|
16209
16266
|
function getTargetOpenHref(targetSrc) {
|
|
@@ -16240,8 +16297,8 @@ var ReviewTopbar = ({
|
|
|
16240
16297
|
);
|
|
16241
16298
|
if (nextPreset) onSizeChange(nextPreset);
|
|
16242
16299
|
};
|
|
16243
|
-
return /* @__PURE__ */ (0,
|
|
16244
|
-
/* @__PURE__ */ (0,
|
|
16300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("header", { className: "df-review-topbar", children: [
|
|
16301
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
16245
16302
|
"form",
|
|
16246
16303
|
{
|
|
16247
16304
|
className: "df-review-address",
|
|
@@ -16250,7 +16307,7 @@ var ReviewTopbar = ({
|
|
|
16250
16307
|
onApplyTarget();
|
|
16251
16308
|
},
|
|
16252
16309
|
children: [
|
|
16253
|
-
/* @__PURE__ */ (0,
|
|
16310
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16254
16311
|
"button",
|
|
16255
16312
|
{
|
|
16256
16313
|
"aria-label": "Open sitemap",
|
|
@@ -16259,10 +16316,10 @@ var ReviewTopbar = ({
|
|
|
16259
16316
|
"data-review-tooltip-placement": "bottom",
|
|
16260
16317
|
type: "button",
|
|
16261
16318
|
onClick: onOpenSitemap,
|
|
16262
|
-
children: /* @__PURE__ */ (0,
|
|
16319
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Map2, { "aria-hidden": "true" })
|
|
16263
16320
|
}
|
|
16264
16321
|
),
|
|
16265
|
-
/* @__PURE__ */ (0,
|
|
16322
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16266
16323
|
"input",
|
|
16267
16324
|
{
|
|
16268
16325
|
"aria-label": "Path",
|
|
@@ -16270,8 +16327,8 @@ var ReviewTopbar = ({
|
|
|
16270
16327
|
onChange: (event) => onDraftTargetChange(event.target.value)
|
|
16271
16328
|
}
|
|
16272
16329
|
),
|
|
16273
|
-
/* @__PURE__ */ (0,
|
|
16274
|
-
/* @__PURE__ */ (0,
|
|
16330
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "df-review-address-actions", children: [
|
|
16331
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16275
16332
|
"button",
|
|
16276
16333
|
{
|
|
16277
16334
|
"aria-label": "Refresh target",
|
|
@@ -16280,10 +16337,10 @@ var ReviewTopbar = ({
|
|
|
16280
16337
|
"data-review-tooltip-placement": "bottom",
|
|
16281
16338
|
title: "Refresh target",
|
|
16282
16339
|
type: "submit",
|
|
16283
|
-
children: /* @__PURE__ */ (0,
|
|
16340
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RefreshCw, { "aria-hidden": "true" })
|
|
16284
16341
|
}
|
|
16285
16342
|
),
|
|
16286
|
-
/* @__PURE__ */ (0,
|
|
16343
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16287
16344
|
"button",
|
|
16288
16345
|
{
|
|
16289
16346
|
"aria-label": copyLabel,
|
|
@@ -16293,10 +16350,10 @@ var ReviewTopbar = ({
|
|
|
16293
16350
|
title: copyLabel,
|
|
16294
16351
|
type: "button",
|
|
16295
16352
|
onClick: onCopyCurrentUrl,
|
|
16296
|
-
children: /* @__PURE__ */ (0,
|
|
16353
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Copy, { "aria-hidden": "true" })
|
|
16297
16354
|
}
|
|
16298
16355
|
),
|
|
16299
|
-
/* @__PURE__ */ (0,
|
|
16356
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16300
16357
|
"a",
|
|
16301
16358
|
{
|
|
16302
16359
|
"aria-label": "Open target page",
|
|
@@ -16307,30 +16364,30 @@ var ReviewTopbar = ({
|
|
|
16307
16364
|
rel: "noreferrer",
|
|
16308
16365
|
target: "_blank",
|
|
16309
16366
|
title: "Open target page",
|
|
16310
|
-
children: /* @__PURE__ */ (0,
|
|
16367
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ExternalLink, { "aria-hidden": "true" })
|
|
16311
16368
|
}
|
|
16312
16369
|
)
|
|
16313
16370
|
] })
|
|
16314
16371
|
]
|
|
16315
16372
|
}
|
|
16316
16373
|
),
|
|
16317
|
-
/* @__PURE__ */ (0,
|
|
16318
|
-
/* @__PURE__ */ (0,
|
|
16319
|
-
/* @__PURE__ */ (0,
|
|
16374
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "df-review-tools", children: [
|
|
16375
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "df-review-tool-controls", children: [
|
|
16376
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "df-review-presets", "aria-label": "Viewport presets", children: viewportPresets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
16320
16377
|
"button",
|
|
16321
16378
|
{
|
|
16322
16379
|
className: preset.label === size.label ? "is-active" : "",
|
|
16323
16380
|
type: "button",
|
|
16324
16381
|
onClick: () => onSizeChange(preset),
|
|
16325
16382
|
children: [
|
|
16326
|
-
/* @__PURE__ */ (0,
|
|
16327
|
-
/* @__PURE__ */ (0,
|
|
16328
|
-
/* @__PURE__ */ (0,
|
|
16383
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ViewportPresetIcon, { preset }),
|
|
16384
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "df-review-preset-copy", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("strong", { children: preset.label }) }),
|
|
16385
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "df-review-preset-count", children: presetScopeCounts.get(getViewportPresetKind(preset)) ?? 0 })
|
|
16329
16386
|
]
|
|
16330
16387
|
},
|
|
16331
16388
|
preset.label
|
|
16332
16389
|
)) }),
|
|
16333
|
-
/* @__PURE__ */ (0,
|
|
16390
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16334
16391
|
"select",
|
|
16335
16392
|
{
|
|
16336
16393
|
"aria-label": "Viewport preset",
|
|
@@ -16340,7 +16397,7 @@ var ReviewTopbar = ({
|
|
|
16340
16397
|
children: viewportPresets.map((preset) => {
|
|
16341
16398
|
const scope = getViewportPresetKind(preset);
|
|
16342
16399
|
const count = presetScopeCounts.get(scope) ?? 0;
|
|
16343
|
-
return /* @__PURE__ */ (0,
|
|
16400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16344
16401
|
"option",
|
|
16345
16402
|
{
|
|
16346
16403
|
value: getPresetSelectValue(preset),
|
|
@@ -16351,15 +16408,15 @@ var ReviewTopbar = ({
|
|
|
16351
16408
|
})
|
|
16352
16409
|
}
|
|
16353
16410
|
),
|
|
16354
|
-
/* @__PURE__ */ (0,
|
|
16355
|
-
/* @__PURE__ */ (0,
|
|
16411
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "df-review-tool-divider", "aria-hidden": "true", children: "|" }),
|
|
16412
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "df-review-active-size", children: [
|
|
16356
16413
|
size.width,
|
|
16357
16414
|
"x",
|
|
16358
16415
|
size.height
|
|
16359
16416
|
] })
|
|
16360
16417
|
] }),
|
|
16361
|
-
/* @__PURE__ */ (0,
|
|
16362
|
-
isRulerAvailable && /* @__PURE__ */ (0,
|
|
16418
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "df-review-overlays", "aria-label": "Target overlays", children: [
|
|
16419
|
+
isRulerAvailable && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16363
16420
|
"button",
|
|
16364
16421
|
{
|
|
16365
16422
|
"aria-label": "Toggle ruler",
|
|
@@ -16368,10 +16425,10 @@ var ReviewTopbar = ({
|
|
|
16368
16425
|
"data-review-tooltip-placement": "bottom",
|
|
16369
16426
|
type: "button",
|
|
16370
16427
|
onClick: onToggleRuler,
|
|
16371
|
-
children: /* @__PURE__ */ (0,
|
|
16428
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Ruler, { "aria-hidden": "true" })
|
|
16372
16429
|
}
|
|
16373
16430
|
),
|
|
16374
|
-
/* @__PURE__ */ (0,
|
|
16431
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16375
16432
|
"button",
|
|
16376
16433
|
{
|
|
16377
16434
|
"aria-label": "Toggle grid overlay",
|
|
@@ -16380,10 +16437,10 @@ var ReviewTopbar = ({
|
|
|
16380
16437
|
"data-review-tooltip-placement": "bottom",
|
|
16381
16438
|
type: "button",
|
|
16382
16439
|
onClick: () => onToggleTargetOverlay("grid"),
|
|
16383
|
-
children: /* @__PURE__ */ (0,
|
|
16440
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LayoutGrid, { "aria-hidden": "true" })
|
|
16384
16441
|
}
|
|
16385
16442
|
),
|
|
16386
|
-
/* @__PURE__ */ (0,
|
|
16443
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
16387
16444
|
"button",
|
|
16388
16445
|
{
|
|
16389
16446
|
"aria-disabled": !isFigmaOverlayAvailable,
|
|
@@ -16394,7 +16451,7 @@ var ReviewTopbar = ({
|
|
|
16394
16451
|
disabled: !isFigmaOverlayAvailable,
|
|
16395
16452
|
type: "button",
|
|
16396
16453
|
onClick: onToggleFigmaOverlay,
|
|
16397
|
-
children: /* @__PURE__ */ (0,
|
|
16454
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(FigmaMarkIcon, {})
|
|
16398
16455
|
}
|
|
16399
16456
|
)
|
|
16400
16457
|
] })
|
|
@@ -16403,7 +16460,7 @@ var ReviewTopbar = ({
|
|
|
16403
16460
|
};
|
|
16404
16461
|
|
|
16405
16462
|
// src/react-shell/topbar.container.tsx
|
|
16406
|
-
var
|
|
16463
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
16407
16464
|
var TopbarContainer = () => {
|
|
16408
16465
|
const {
|
|
16409
16466
|
applyTarget,
|
|
@@ -16436,7 +16493,7 @@ var TopbarContainer = () => {
|
|
|
16436
16493
|
const copyCurrentUrl = () => copyCurrentReviewUrl({
|
|
16437
16494
|
onCopyLabelChange: setCopyLabel
|
|
16438
16495
|
});
|
|
16439
|
-
return /* @__PURE__ */ (0,
|
|
16496
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
16440
16497
|
ReviewTopbar,
|
|
16441
16498
|
{
|
|
16442
16499
|
draftTarget,
|
|
@@ -16463,11 +16520,11 @@ var TopbarContainer = () => {
|
|
|
16463
16520
|
};
|
|
16464
16521
|
|
|
16465
16522
|
// src/react-shell/review/toast.container.tsx
|
|
16466
|
-
var
|
|
16523
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
16467
16524
|
var ReviewToastContainer = () => {
|
|
16468
16525
|
const toastMessage = useReviewShellStore((state) => state.toastMessage);
|
|
16469
16526
|
if (!toastMessage) return null;
|
|
16470
|
-
return /* @__PURE__ */ (0,
|
|
16527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "df-review-copy-toast", role: "status", children: toastMessage });
|
|
16471
16528
|
};
|
|
16472
16529
|
|
|
16473
16530
|
// src/react-shell/hooks/use.review.shell.runtime.ts
|
|
@@ -16837,72 +16894,21 @@ function normalizeStoredReviewItem(value) {
|
|
|
16837
16894
|
};
|
|
16838
16895
|
}
|
|
16839
16896
|
|
|
16897
|
+
// src/core/error.ts
|
|
16898
|
+
function getErrorMessage(error, fallback) {
|
|
16899
|
+
if (error instanceof Error) return error.message;
|
|
16900
|
+
if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
|
|
16901
|
+
return error.message;
|
|
16902
|
+
}
|
|
16903
|
+
return fallback;
|
|
16904
|
+
}
|
|
16905
|
+
|
|
16840
16906
|
// src/core/id.ts
|
|
16841
16907
|
function createId() {
|
|
16842
16908
|
if ("randomUUID" in crypto) return crypto.randomUUID();
|
|
16843
16909
|
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
16844
16910
|
}
|
|
16845
16911
|
|
|
16846
|
-
// src/core/hotkey.ts
|
|
16847
|
-
var HOTKEY_KEY_ALIASES = {
|
|
16848
|
-
q: ["\u3142", "\u3143"],
|
|
16849
|
-
w: ["\u3148", "\u3149"],
|
|
16850
|
-
e: ["\u3137", "\u3138"],
|
|
16851
|
-
r: ["\u3131", "\u3132"],
|
|
16852
|
-
t: ["\u3145", "\u3146"],
|
|
16853
|
-
y: ["\u315B"],
|
|
16854
|
-
u: ["\u3155"],
|
|
16855
|
-
i: ["\u3151"],
|
|
16856
|
-
o: ["\u3150", "\u3152"],
|
|
16857
|
-
p: ["\u3154", "\u3156"],
|
|
16858
|
-
a: ["\u3141"],
|
|
16859
|
-
s: ["\u3134"],
|
|
16860
|
-
d: ["\u3147"],
|
|
16861
|
-
f: ["\u3139"],
|
|
16862
|
-
g: ["\u314E"],
|
|
16863
|
-
h: ["\u3157"],
|
|
16864
|
-
j: ["\u3153"],
|
|
16865
|
-
k: ["\u314F"],
|
|
16866
|
-
l: ["\u3163"],
|
|
16867
|
-
z: ["\u314B"],
|
|
16868
|
-
x: ["\u314C"],
|
|
16869
|
-
c: ["\u314A"],
|
|
16870
|
-
v: ["\u314D"],
|
|
16871
|
-
b: ["\u3160"],
|
|
16872
|
-
n: ["\u315C"],
|
|
16873
|
-
m: ["\u3161"]
|
|
16874
|
-
};
|
|
16875
|
-
function isHotkey(event, hotkey) {
|
|
16876
|
-
const parts = hotkey.split("+").map((part) => part.trim().toLowerCase()).filter(Boolean);
|
|
16877
|
-
const key = parts.find(
|
|
16878
|
-
(part) => !["shift", "ctrl", "control", "alt", "meta", "cmd"].includes(part)
|
|
16879
|
-
);
|
|
16880
|
-
if (!key) return false;
|
|
16881
|
-
if (parts.includes("shift") !== event.shiftKey) return false;
|
|
16882
|
-
if ((parts.includes("ctrl") || parts.includes("control")) !== event.ctrlKey) {
|
|
16883
|
-
return false;
|
|
16884
|
-
}
|
|
16885
|
-
if (parts.includes("alt") !== event.altKey) return false;
|
|
16886
|
-
if ((parts.includes("meta") || parts.includes("cmd")) !== event.metaKey) {
|
|
16887
|
-
return false;
|
|
16888
|
-
}
|
|
16889
|
-
return isHotkeyKey(event, key);
|
|
16890
|
-
}
|
|
16891
|
-
function getHotkeyActionKey(event, keys) {
|
|
16892
|
-
return keys.find((key) => isHotkeyKey(event, key));
|
|
16893
|
-
}
|
|
16894
|
-
function isHotkeyKey(event, key) {
|
|
16895
|
-
const normalizedKey = key.toLowerCase();
|
|
16896
|
-
if (event.key.toLowerCase() === normalizedKey) return true;
|
|
16897
|
-
if (getHotkeyCode(normalizedKey) === event.code) return true;
|
|
16898
|
-
return HOTKEY_KEY_ALIASES[normalizedKey]?.includes(event.key) ?? false;
|
|
16899
|
-
}
|
|
16900
|
-
function getHotkeyCode(key) {
|
|
16901
|
-
if (/^[a-z]$/.test(key)) return `Key${key.toUpperCase()}`;
|
|
16902
|
-
if (/^[0-9]$/.test(key)) return `Digit${key}`;
|
|
16903
|
-
return void 0;
|
|
16904
|
-
}
|
|
16905
|
-
|
|
16906
16912
|
// src/core/location.ts
|
|
16907
16913
|
var INTERNAL_QUERY_PARAMS = ["__dfwr_target"];
|
|
16908
16914
|
function getPageUrl(environment) {
|
|
@@ -20069,13 +20075,6 @@ var WebReviewKitView = class {
|
|
|
20069
20075
|
// src/core/web.review.kit.app.ts
|
|
20070
20076
|
var ROOT_ID = "df-web-review-kit-root";
|
|
20071
20077
|
var VIEWPORT_SCROLL_OPTIONS = { capture: true, passive: true };
|
|
20072
|
-
function isEditableEventTarget2(event) {
|
|
20073
|
-
const path = event.composedPath?.() ?? [];
|
|
20074
|
-
const element = path[0] ?? event.target;
|
|
20075
|
-
if (!element || typeof element.tagName !== "string") return false;
|
|
20076
|
-
const tag = element.tagName;
|
|
20077
|
-
return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || element.isContentEditable === true;
|
|
20078
|
-
}
|
|
20079
20078
|
function createWebReviewKit(options) {
|
|
20080
20079
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
20081
20080
|
return createNoopController();
|
|
@@ -20120,7 +20119,7 @@ var WebReviewKitApp = class {
|
|
|
20120
20119
|
event.stopPropagation();
|
|
20121
20120
|
return;
|
|
20122
20121
|
}
|
|
20123
|
-
if (
|
|
20122
|
+
if (isEditableEventTarget(event) || !isHotkey(event, this.hotkey)) return;
|
|
20124
20123
|
event.preventDefault();
|
|
20125
20124
|
event.stopPropagation();
|
|
20126
20125
|
this.toggle();
|
|
@@ -20630,46 +20629,28 @@ var WebReviewKitApp = class {
|
|
|
20630
20629
|
this.root.style.display = previousDisplay;
|
|
20631
20630
|
}
|
|
20632
20631
|
}
|
|
20633
|
-
|
|
20634
|
-
|
|
20635
|
-
const environment = this.getEnvironment();
|
|
20636
|
-
const draft = this.domDraft;
|
|
20637
|
-
if (!draft) return;
|
|
20638
|
-
if (!environment?.captureViewport) {
|
|
20639
|
-
this.draftError = "Viewport capture helper is not available.";
|
|
20640
|
-
this.render();
|
|
20641
|
-
return;
|
|
20642
|
-
}
|
|
20643
|
-
const captureInput = this.createViewportCaptureInput(
|
|
20644
|
-
environment,
|
|
20632
|
+
captureDomDraft(input) {
|
|
20633
|
+
return this.captureDraft(
|
|
20645
20634
|
input,
|
|
20646
|
-
|
|
20635
|
+
() => this.domDraft,
|
|
20636
|
+
(draft) => {
|
|
20637
|
+
this.domDraft = draft;
|
|
20638
|
+
}
|
|
20639
|
+
);
|
|
20640
|
+
}
|
|
20641
|
+
captureAreaDraft(input) {
|
|
20642
|
+
return this.captureDraft(
|
|
20643
|
+
input,
|
|
20644
|
+
() => this.areaDraft,
|
|
20645
|
+
(draft) => {
|
|
20646
|
+
this.areaDraft = draft;
|
|
20647
|
+
}
|
|
20647
20648
|
);
|
|
20648
|
-
this.draftError = "";
|
|
20649
|
-
this.isCapturingViewport = true;
|
|
20650
|
-
this.render();
|
|
20651
|
-
try {
|
|
20652
|
-
const result = await environment.captureViewport(captureInput);
|
|
20653
|
-
const attachment = this.createCaptureDraftAttachment(result, captureInput);
|
|
20654
|
-
const currentDraft = this.domDraft ?? draft;
|
|
20655
|
-
this.domDraft = {
|
|
20656
|
-
...currentDraft,
|
|
20657
|
-
attachments: [...currentDraft.attachments ?? [], attachment]
|
|
20658
|
-
};
|
|
20659
|
-
} catch (error) {
|
|
20660
|
-
this.draftError = this.getErrorMessage(
|
|
20661
|
-
error,
|
|
20662
|
-
"Failed to capture viewport."
|
|
20663
|
-
);
|
|
20664
|
-
} finally {
|
|
20665
|
-
this.isCapturingViewport = false;
|
|
20666
|
-
this.render();
|
|
20667
|
-
}
|
|
20668
20649
|
}
|
|
20669
|
-
async
|
|
20650
|
+
async captureDraft(input, getDraft, setDraft) {
|
|
20670
20651
|
if (this.isCapturingViewport) return;
|
|
20671
20652
|
const environment = this.getEnvironment();
|
|
20672
|
-
const draft =
|
|
20653
|
+
const draft = getDraft();
|
|
20673
20654
|
if (!draft) return;
|
|
20674
20655
|
if (!environment?.captureViewport) {
|
|
20675
20656
|
this.draftError = "Viewport capture helper is not available.";
|
|
@@ -20687,16 +20668,13 @@ var WebReviewKitApp = class {
|
|
|
20687
20668
|
try {
|
|
20688
20669
|
const result = await environment.captureViewport(captureInput);
|
|
20689
20670
|
const attachment = this.createCaptureDraftAttachment(result, captureInput);
|
|
20690
|
-
const currentDraft =
|
|
20691
|
-
|
|
20671
|
+
const currentDraft = getDraft() ?? draft;
|
|
20672
|
+
setDraft({
|
|
20692
20673
|
...currentDraft,
|
|
20693
20674
|
attachments: [...currentDraft.attachments ?? [], attachment]
|
|
20694
|
-
};
|
|
20675
|
+
});
|
|
20695
20676
|
} catch (error) {
|
|
20696
|
-
this.draftError =
|
|
20697
|
-
error,
|
|
20698
|
-
"Failed to capture viewport."
|
|
20699
|
-
);
|
|
20677
|
+
this.draftError = getErrorMessage(error, "Failed to capture viewport.");
|
|
20700
20678
|
} finally {
|
|
20701
20679
|
this.isCapturingViewport = false;
|
|
20702
20680
|
this.render();
|
|
@@ -20835,17 +20813,10 @@ var WebReviewKitApp = class {
|
|
|
20835
20813
|
);
|
|
20836
20814
|
}
|
|
20837
20815
|
getCreateItemErrorMessage(error, wasUploadingAttachments) {
|
|
20838
|
-
const message =
|
|
20816
|
+
const message = getErrorMessage(error, "Failed to save QA.");
|
|
20839
20817
|
const reason = error && typeof error === "object" && "reason" in error && typeof error.reason === "string" ? ` (${error.reason})` : "";
|
|
20840
20818
|
return wasUploadingAttachments && reason ? `Attachment upload failed${reason}: ${message}` : message;
|
|
20841
20819
|
}
|
|
20842
|
-
getErrorMessage(error, fallback) {
|
|
20843
|
-
if (error instanceof Error) return error.message;
|
|
20844
|
-
if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
|
|
20845
|
-
return error.message;
|
|
20846
|
-
}
|
|
20847
|
-
return fallback;
|
|
20848
|
-
}
|
|
20849
20820
|
async restoreItem(item) {
|
|
20850
20821
|
this.setModeState("idle");
|
|
20851
20822
|
this.clearDrafts();
|
|
@@ -21020,7 +20991,7 @@ async function captureIframeViewport(frame, input) {
|
|
|
21020
20991
|
);
|
|
21021
20992
|
} catch (error) {
|
|
21022
20993
|
throw new Error(
|
|
21023
|
-
`Selected region capture failed: ${
|
|
20994
|
+
`Selected region capture failed: ${getCaptureErrorMessage(error)}`
|
|
21024
20995
|
);
|
|
21025
20996
|
}
|
|
21026
20997
|
}
|
|
@@ -21033,7 +21004,7 @@ async function captureIframeViewport(frame, input) {
|
|
|
21033
21004
|
input
|
|
21034
21005
|
);
|
|
21035
21006
|
} catch (error) {
|
|
21036
|
-
errors.push(`html2canvas: ${
|
|
21007
|
+
errors.push(`html2canvas: ${getCaptureErrorMessage(error)}`);
|
|
21037
21008
|
}
|
|
21038
21009
|
const svg = createViewportSvg(targetDocument, targetWindow, viewport, input);
|
|
21039
21010
|
const svgFile = new Blob([svg], { type: "image/svg+xml;charset=utf-8" });
|
|
@@ -21047,7 +21018,7 @@ async function captureIframeViewport(frame, input) {
|
|
|
21047
21018
|
input
|
|
21048
21019
|
);
|
|
21049
21020
|
} catch (error) {
|
|
21050
|
-
errors.push(`svg-canvas: ${
|
|
21021
|
+
errors.push(`svg-canvas: ${getCaptureErrorMessage(error)}`);
|
|
21051
21022
|
}
|
|
21052
21023
|
return {
|
|
21053
21024
|
file: svgFile,
|
|
@@ -21483,12 +21454,8 @@ function createMarkerSvg(x, y) {
|
|
|
21483
21454
|
function formatCaptureTimestamp(timestamp) {
|
|
21484
21455
|
return timestamp.replace(/[^0-9A-Za-z]+/g, "-").replace(/^-|-$/g, "");
|
|
21485
21456
|
}
|
|
21486
|
-
function
|
|
21487
|
-
|
|
21488
|
-
if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
|
|
21489
|
-
return error.message;
|
|
21490
|
-
}
|
|
21491
|
-
return "Capture was saved as SVG fallback.";
|
|
21457
|
+
function getCaptureErrorMessage(error) {
|
|
21458
|
+
return getErrorMessage(error, "Capture was saved as SVG fallback.");
|
|
21492
21459
|
}
|
|
21493
21460
|
|
|
21494
21461
|
// src/react-shell/hooks/review.kit.target.ts
|
|
@@ -24810,7 +24777,7 @@ var createReviewShellStore = (init) => (0, import_zustand2.createStore)()((...ar
|
|
|
24810
24777
|
}));
|
|
24811
24778
|
|
|
24812
24779
|
// src/react-shell/review/shell.tsx
|
|
24813
|
-
var
|
|
24780
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
24814
24781
|
var ReviewShell = (props) => {
|
|
24815
24782
|
const config = (0, import_react57.useMemo)(
|
|
24816
24783
|
() => createReviewShellConfig(props),
|
|
@@ -24830,23 +24797,23 @@ var ReviewShell = (props) => {
|
|
|
24830
24797
|
() => createReviewShellStore({ target: getInitialTargetSliceState(config) })
|
|
24831
24798
|
);
|
|
24832
24799
|
const [refs] = (0, import_react57.useState)(createReviewShellRefs);
|
|
24833
|
-
return /* @__PURE__ */ (0,
|
|
24800
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewShellConfigProvider, { value: config, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewShellStoreProvider, { value: store, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewShellRefsProvider, { value: refs, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewShellContent, { ...props }) }) }) });
|
|
24834
24801
|
};
|
|
24835
24802
|
var ReviewShellContent = (props) => {
|
|
24836
24803
|
const runtime = useReviewShellRuntime(props);
|
|
24837
|
-
return /* @__PURE__ */ (0,
|
|
24804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewShellProviders, { ...runtime, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
24838
24805
|
ReviewShellFrameContainer,
|
|
24839
24806
|
{
|
|
24840
24807
|
slots: {
|
|
24841
|
-
topbar: /* @__PURE__ */ (0,
|
|
24842
|
-
modals: /* @__PURE__ */ (0,
|
|
24843
|
-
toast: /* @__PURE__ */ (0,
|
|
24844
|
-
sideRail: /* @__PURE__ */ (0,
|
|
24845
|
-
qaPanel: /* @__PURE__ */ (0,
|
|
24846
|
-
figmaImagesPanel: /* @__PURE__ */ (0,
|
|
24847
|
-
sourceTreePanel: /* @__PURE__ */ (0,
|
|
24848
|
-
targetFrame: /* @__PURE__ */ (0,
|
|
24849
|
-
sourceInspector: /* @__PURE__ */ (0,
|
|
24808
|
+
topbar: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(TopbarContainer, {}),
|
|
24809
|
+
modals: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewShellModalsContainer, {}),
|
|
24810
|
+
toast: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewToastContainer, {}),
|
|
24811
|
+
sideRail: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewSideRailContainer, {}),
|
|
24812
|
+
qaPanel: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(QaPanelContainer, {}),
|
|
24813
|
+
figmaImagesPanel: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(FigmaImagesPanelContainer, {}),
|
|
24814
|
+
sourceTreePanel: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SectionOutlineContainer, {}),
|
|
24815
|
+
targetFrame: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ReviewTargetFrame, {}),
|
|
24816
|
+
sourceInspector: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SourceInspectorOverlayContainer, {})
|
|
24850
24817
|
}
|
|
24851
24818
|
}
|
|
24852
24819
|
) });
|
|
@@ -24855,7 +24822,7 @@ var ReviewShellContent = (props) => {
|
|
|
24855
24822
|
// src/react-shell/figma/dev-overlay.tsx
|
|
24856
24823
|
var import_react58 = __toESM(require("react"), 1);
|
|
24857
24824
|
var import_client = require("react-dom/client");
|
|
24858
|
-
var
|
|
24825
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
24859
24826
|
var FIGMA_DEV_OVERLAY_ROOT_ID = "df-review-figma-dev-overlay-root";
|
|
24860
24827
|
var FIGMA_DEV_OVERLAY_MOUNT_ID = "df-review-figma-dev-overlay-mount";
|
|
24861
24828
|
var mountFigmaDevOverlay = (options) => {
|
|
@@ -24876,7 +24843,7 @@ var mountFigmaDevOverlay = (options) => {
|
|
|
24876
24843
|
document.body.appendChild(host);
|
|
24877
24844
|
const root = (0, import_client.createRoot)(mountNode);
|
|
24878
24845
|
root.render(
|
|
24879
|
-
/* @__PURE__ */ (0,
|
|
24846
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react58.default.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(FigmaDevOverlayWidget, { ...options }) })
|
|
24880
24847
|
);
|
|
24881
24848
|
return {
|
|
24882
24849
|
destroy() {
|
|
@@ -24967,7 +24934,7 @@ var FigmaDevOverlayWidget = ({
|
|
|
24967
24934
|
);
|
|
24968
24935
|
(0, import_react58.useEffect)(() => {
|
|
24969
24936
|
const handleKeyDown = (event) => {
|
|
24970
|
-
if (!isHotkey(event, "Shift+F") ||
|
|
24937
|
+
if (!isHotkey(event, "Shift+F") || isEditableEventTarget(event)) {
|
|
24971
24938
|
return;
|
|
24972
24939
|
}
|
|
24973
24940
|
event.preventDefault();
|
|
@@ -24989,21 +24956,21 @@ var FigmaDevOverlayWidget = ({
|
|
|
24989
24956
|
setImageOverlayOpacity(selectedImage.id, opacityPercent / 100);
|
|
24990
24957
|
}
|
|
24991
24958
|
};
|
|
24992
|
-
return /* @__PURE__ */ (0,
|
|
24959
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
24993
24960
|
"aside",
|
|
24994
24961
|
{
|
|
24995
24962
|
"aria-label": "Figma overlay",
|
|
24996
24963
|
className: `df-review-figma-dev-widget${isPanelOpen ? " is-open" : ""}${isAnyImageOverlayVisible ? " is-active" : ""}`,
|
|
24997
24964
|
children: [
|
|
24998
|
-
isPanelOpen && /* @__PURE__ */ (0,
|
|
24999
|
-
/* @__PURE__ */ (0,
|
|
25000
|
-
/* @__PURE__ */ (0,
|
|
25001
|
-
/* @__PURE__ */ (0,
|
|
24965
|
+
isPanelOpen && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "df-review-figma-dev-panel", children: [
|
|
24966
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "df-review-figma-dev-panel-header", children: [
|
|
24967
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", { children: "Figma" }),
|
|
24968
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: matchedViewportMatch ? `${matchedViewportMatch.label} \xB7 ${matchedViewportMatch.rangeLabel}` : `${viewport.width}px` })
|
|
25002
24969
|
] }),
|
|
25003
|
-
selectedImage && /* @__PURE__ */ (0,
|
|
25004
|
-
/* @__PURE__ */ (0,
|
|
25005
|
-
/* @__PURE__ */ (0,
|
|
25006
|
-
/* @__PURE__ */ (0,
|
|
24970
|
+
selectedImage && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "df-review-figma-dev-selected-controls", children: [
|
|
24971
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("label", { className: "df-review-figma-dev-opacity-control", children: [
|
|
24972
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: "Opacity" }),
|
|
24973
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
25007
24974
|
"input",
|
|
25008
24975
|
{
|
|
25009
24976
|
"aria-label": `${selectedImageLabel} overlay opacity`,
|
|
@@ -25016,11 +24983,11 @@ var FigmaDevOverlayWidget = ({
|
|
|
25016
24983
|
onInput: (event) => updateSelectedImageOpacity(event.currentTarget.value)
|
|
25017
24984
|
}
|
|
25018
24985
|
),
|
|
25019
|
-
/* @__PURE__ */ (0,
|
|
24986
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", { children: selectedOpacityPercent })
|
|
25020
24987
|
] }),
|
|
25021
|
-
/* @__PURE__ */ (0,
|
|
25022
|
-
/* @__PURE__ */ (0,
|
|
25023
|
-
/* @__PURE__ */ (0,
|
|
24988
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("label", { className: "df-review-figma-dev-y-control", children: [
|
|
24989
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(MoveVertical, { "aria-hidden": "true" }),
|
|
24990
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
25024
24991
|
"input",
|
|
25025
24992
|
{
|
|
25026
24993
|
"aria-label": `${selectedImageLabel} overlay Y offset`,
|
|
@@ -25050,14 +25017,14 @@ var FigmaDevOverlayWidget = ({
|
|
|
25050
25017
|
)
|
|
25051
25018
|
] })
|
|
25052
25019
|
] }),
|
|
25053
|
-
error && /* @__PURE__ */ (0,
|
|
25054
|
-
!matchedViewport ? /* @__PURE__ */ (0,
|
|
25020
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "df-review-figma-dev-status", children: error }),
|
|
25021
|
+
!matchedViewport ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "df-review-figma-dev-empty", children: [
|
|
25055
25022
|
"No Figma layers for this viewport.",
|
|
25056
25023
|
viewportBoundaries ? ` Mobile ${viewportBoundaries.mobileRangeLabel} / Full width ${viewportBoundaries.fullWidthRangeLabel}` : ""
|
|
25057
|
-
] }) : isLoading ? /* @__PURE__ */ (0,
|
|
25024
|
+
] }) : isLoading ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "df-review-figma-dev-status", children: "Loading..." }) : images.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "df-review-figma-dev-empty", children: "No Figma layers for this viewport." }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "df-review-figma-dev-list", children: images.map((image, index) => {
|
|
25058
25025
|
const imageLabel = getFigmaImageLabel(image, index);
|
|
25059
25026
|
const overlayState = imageOverlayStates[image.id] ?? DEFAULT_FIGMA_IMAGE_LAYER_STATE;
|
|
25060
|
-
return /* @__PURE__ */ (0,
|
|
25027
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
25061
25028
|
"article",
|
|
25062
25029
|
{
|
|
25063
25030
|
className: `df-review-figma-dev-row${image.id === selectedImageId ? " is-active" : ""}`,
|
|
@@ -25070,7 +25037,7 @@ var FigmaDevOverlayWidget = ({
|
|
|
25070
25037
|
setSelectedImageId(image.id);
|
|
25071
25038
|
},
|
|
25072
25039
|
children: [
|
|
25073
|
-
/* @__PURE__ */ (0,
|
|
25040
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
25074
25041
|
FigmaImageLayerStateButtons,
|
|
25075
25042
|
{
|
|
25076
25043
|
imageLabel,
|
|
@@ -25082,9 +25049,9 @@ var FigmaDevOverlayWidget = ({
|
|
|
25082
25049
|
onToggleVisible: () => toggleImageOverlayVisible(image.id)
|
|
25083
25050
|
}
|
|
25084
25051
|
),
|
|
25085
|
-
/* @__PURE__ */ (0,
|
|
25086
|
-
/* @__PURE__ */ (0,
|
|
25087
|
-
/* @__PURE__ */ (0,
|
|
25052
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "df-review-figma-dev-row-main", children: [
|
|
25053
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", { children: imageLabel }),
|
|
25054
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("small", { children: formatFigmaImageDate(image.updatedAt) })
|
|
25088
25055
|
] })
|
|
25089
25056
|
]
|
|
25090
25057
|
},
|
|
@@ -25092,7 +25059,7 @@ var FigmaDevOverlayWidget = ({
|
|
|
25092
25059
|
);
|
|
25093
25060
|
}) })
|
|
25094
25061
|
] }),
|
|
25095
|
-
/* @__PURE__ */ (0,
|
|
25062
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "df-review-figma-dev-bar", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
25096
25063
|
"button",
|
|
25097
25064
|
{
|
|
25098
25065
|
"aria-expanded": isPanelOpen,
|
|
@@ -25102,8 +25069,8 @@ var FigmaDevOverlayWidget = ({
|
|
|
25102
25069
|
type: "button",
|
|
25103
25070
|
onClick: () => setIsPanelOpen((isOpen) => !isOpen),
|
|
25104
25071
|
children: [
|
|
25105
|
-
/* @__PURE__ */ (0,
|
|
25106
|
-
/* @__PURE__ */ (0,
|
|
25072
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(FigmaMarkIcon, {}),
|
|
25073
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "df-review-figma-dev-button-count", children: images.length })
|
|
25107
25074
|
]
|
|
25108
25075
|
}
|
|
25109
25076
|
) })
|
|
@@ -25128,13 +25095,6 @@ function useCurrentPageUrl(pageUrl, reviewPathPrefix) {
|
|
|
25128
25095
|
}, [pageUrl, reviewPathPrefix]);
|
|
25129
25096
|
return currentPageUrl;
|
|
25130
25097
|
}
|
|
25131
|
-
function isEditableFigmaDevOverlayEventTarget(event) {
|
|
25132
|
-
const path = event.composedPath?.() ?? [];
|
|
25133
|
-
const element = path[0] ?? event.target;
|
|
25134
|
-
if (!element || typeof element.tagName !== "string") return false;
|
|
25135
|
-
const tagName = element.tagName;
|
|
25136
|
-
return tagName === "INPUT" || tagName === "TEXTAREA" || tagName === "SELECT" || element.isContentEditable === true;
|
|
25137
|
-
}
|
|
25138
25098
|
function useCurrentViewport() {
|
|
25139
25099
|
const [viewport, setViewport] = (0, import_react58.useState)(getCurrentViewportSize);
|
|
25140
25100
|
(0, import_react58.useEffect)(() => {
|
|
@@ -25694,7 +25654,7 @@ var createSupabasePresenceAdapter = ({
|
|
|
25694
25654
|
});
|
|
25695
25655
|
|
|
25696
25656
|
// src/react-shell.tsx
|
|
25697
|
-
var
|
|
25657
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
25698
25658
|
var mountReviewShell = (options) => {
|
|
25699
25659
|
if (typeof document === "undefined" || !document.head) return;
|
|
25700
25660
|
const { rootId = "root", ...shellProps } = options;
|
|
@@ -25705,7 +25665,7 @@ var mountReviewShell = (options) => {
|
|
|
25705
25665
|
root.style.height = "100%";
|
|
25706
25666
|
root.style.margin = "0";
|
|
25707
25667
|
(0, import_client2.createRoot)(root).render(
|
|
25708
|
-
/* @__PURE__ */ (0,
|
|
25668
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react59.default.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ReviewShell, { ...shellProps }) })
|
|
25709
25669
|
);
|
|
25710
25670
|
};
|
|
25711
25671
|
// Annotate the CommonJS export names for ESM import in node:
|